mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-16 01:21:20 -04:00
slop
This commit is contained in:
@@ -178,6 +178,9 @@ kinect:
|
|||||||
captureCooldownMs: 10000
|
captureCooldownMs: 10000
|
||||||
|
|
||||||
balanceBoard:
|
balanceBoard:
|
||||||
|
# After enabling this feature, rerun install_server.sh. The installer then
|
||||||
|
# configures BlueZ's Wii-compatible HID mode, persistent hid-wiimote loading,
|
||||||
|
# and the restricted evdev permission automatically.
|
||||||
enabled: false
|
enabled: false
|
||||||
# A load must reach this weight before stability timing begins. Keeping the
|
# A load must reach this weight before stability timing begins. Keeping the
|
||||||
# threshold above sensor drift prevents an empty board from capturing itself.
|
# threshold above sensor drift prevents an empty board from capturing itself.
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ SNAPSHOT_DIR="/var/lib/rover-snapshots"
|
|||||||
REPLAY_SEGMENT_DIR="/var/lib/replay-segments"
|
REPLAY_SEGMENT_DIR="/var/lib/replay-segments"
|
||||||
KINECT_UDEV_RULE="/etc/udev/rules.d/99-kinect-world.rules"
|
KINECT_UDEV_RULE="/etc/udev/rules.d/99-kinect-world.rules"
|
||||||
BALANCE_BOARD_UDEV_RULE="/etc/udev/rules.d/99-multirover-balance-board.rules"
|
BALANCE_BOARD_UDEV_RULE="/etc/udev/rules.d/99-multirover-balance-board.rules"
|
||||||
|
BALANCE_BOARD_MODULES_LOAD="/etc/modules-load.d/multirover-balance-board.conf"
|
||||||
|
BLUEZ_INPUT_CONFIG="/etc/bluetooth/input.conf"
|
||||||
|
|
||||||
if [[ $EUID -ne 0 ]]; then
|
if [[ $EUID -ne 0 ]]; then
|
||||||
echo "This installer must be run with sudo/root." >&2
|
echo "This installer must be run with sudo/root." >&2
|
||||||
@@ -139,6 +141,7 @@ dnf install -y \
|
|||||||
libfreenect-devel \
|
libfreenect-devel \
|
||||||
libusb1-devel \
|
libusb1-devel \
|
||||||
bluez \
|
bluez \
|
||||||
|
crudini \
|
||||||
libcap >/dev/null
|
libcap >/dev/null
|
||||||
NODE_BIN="$(command -v node)"
|
NODE_BIN="$(command -v node)"
|
||||||
|
|
||||||
@@ -201,6 +204,52 @@ if [[ ! -f "$CONFIG_PATH" ]]; then
|
|||||||
echo "Copied config.example.yaml to config.yaml; edit it before exposing the service."
|
echo "Copied config.example.yaml to config.yaml; edit it before exposing the service."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Use the same YAML library as the server instead of approximating nested YAML
|
||||||
|
# with grep. This makes system configuration follow the exact explicit boolean
|
||||||
|
# feature flag that the running Node service will use.
|
||||||
|
BALANCE_BOARD_ENABLED=$(SERVER_DIR="$SERVER_DIR" CONFIG_PATH="$CONFIG_PATH" "$NODE_BIN" <<'NODE'
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const yaml = require(path.join(process.env.SERVER_DIR, 'node_modules', 'js-yaml'));
|
||||||
|
const config = yaml.load(fs.readFileSync(process.env.CONFIG_PATH, 'utf8')) || {};
|
||||||
|
process.stdout.write(config.balanceBoard?.enabled === true ? 'true' : 'false');
|
||||||
|
NODE
|
||||||
|
)
|
||||||
|
|
||||||
|
if [[ "$BALANCE_BOARD_ENABLED" == "true" ]]; then
|
||||||
|
echo " Configuring BlueZ for the Wii Balance Board"
|
||||||
|
if ! modinfo hid-wiimote >/dev/null 2>&1; then
|
||||||
|
echo "The running kernel does not provide hid-wiimote; install a Fedora kernel with that module before enabling balanceBoard." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
install -d -m 0755 /etc/bluetooth /etc/modules-load.d
|
||||||
|
touch "$BLUEZ_INPUT_CONFIG"
|
||||||
|
chmod 0644 "$BLUEZ_INPUT_CONFIG"
|
||||||
|
# Modern BlueZ defaults Classic HID devices to userspace UHID and enforces a
|
||||||
|
# security mode that breaks the Wii family's unusual legacy HID handshake.
|
||||||
|
# crudini changes only these two keys, preserving every unrelated Bluetooth
|
||||||
|
# input option an operator may already have configured on the server.
|
||||||
|
crudini --set "$BLUEZ_INPUT_CONFIG" General UserspaceHID false
|
||||||
|
crudini --set "$BLUEZ_INPUT_CONFIG" General ClassicBondedOnly false
|
||||||
|
|
||||||
|
# The service consumes the calibrated evdev axes created specifically by the
|
||||||
|
# kernel hid-wiimote driver. Load it now and on every future boot so the brief
|
||||||
|
# board wake window is never lost waiting for manual module setup.
|
||||||
|
cat > "$BALANCE_BOARD_MODULES_LOAD" <<'EOF'
|
||||||
|
# MultiRoombaRover Wii Balance Board support.
|
||||||
|
hid-wiimote
|
||||||
|
EOF
|
||||||
|
chmod 0644 "$BALANCE_BOARD_MODULES_LOAD"
|
||||||
|
modprobe hid-wiimote
|
||||||
|
|
||||||
|
# BlueZ reads input.conf only at daemon startup. Restart it during the
|
||||||
|
# installer, before multirover is restarted below, so the new HID mode is
|
||||||
|
# guaranteed to be active without requiring a reboot or another command.
|
||||||
|
systemctl enable --now bluetooth.service
|
||||||
|
systemctl restart bluetooth.service
|
||||||
|
fi
|
||||||
|
|
||||||
tmpdir=$(mktemp -d)
|
tmpdir=$(mktemp -d)
|
||||||
trap 'rm -rf "$tmpdir"' EXIT
|
trap 'rm -rf "$tmpdir"' EXIT
|
||||||
|
|
||||||
@@ -295,8 +344,8 @@ EOF
|
|||||||
cat > "$MULTIROVER_SERVICE" <<EOF
|
cat > "$MULTIROVER_SERVICE" <<EOF
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=Multi-Roomba Rover control server
|
Description=Multi-Roomba Rover control server
|
||||||
After=network-online.target mediamtx.service
|
After=network-online.target mediamtx.service bluetooth.service
|
||||||
Wants=network-online.target
|
Wants=network-online.target bluetooth.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
User=$TARGET_USER
|
User=$TARGET_USER
|
||||||
@@ -333,5 +382,9 @@ echo
|
|||||||
echo "Update $CONFIG_PATH to set admins, lockdown settings, and media parameters."
|
echo "Update $CONFIG_PATH to set admins, lockdown settings, and media parameters."
|
||||||
echo "Kinect/libfreenect packages and udev permissions were installed."
|
echo "Kinect/libfreenect packages and udev permissions were installed."
|
||||||
echo "If a Kinect is already plugged in, unplug/replug its USB/power before testing so the new udev rule applies."
|
echo "If a Kinect is already plugged in, unplug/replug its USB/power before testing so the new udev rule applies."
|
||||||
echo "Wii Balance Board Bluetooth support and the restricted input rule were installed."
|
if [[ "$BALANCE_BOARD_ENABLED" == "true" ]]; then
|
||||||
echo "Enable balanceBoard in config.yaml, then press the red Sync button once to commission it."
|
echo "Wii Balance Board BlueZ compatibility, kernel driver, bridge, and restricted input rule were installed."
|
||||||
|
echo "Press the red Sync button once to commission it; later wakes use the front power button."
|
||||||
|
else
|
||||||
|
echo "Wii Balance Board bridge and restricted input rule were installed but system Bluetooth compatibility was left unchanged because balanceBoard is disabled."
|
||||||
|
fi
|
||||||
|
|||||||
@@ -7,19 +7,28 @@ Balance Board input device.
|
|||||||
|
|
||||||
## Commissioning on the real server
|
## Commissioning on the real server
|
||||||
|
|
||||||
1. Run `sudo ./install_server.sh` from the `server` directory.
|
1. Set `balanceBoard.enabled: true` in `server/config.yaml`.
|
||||||
2. Set `balanceBoard.enabled: true` in `server/config.yaml` and restart
|
2. Run `sudo ./install_server.sh` from the `server` directory. The installer
|
||||||
`multirover.service`.
|
configures BlueZ's Wii-compatible kernel HID mode, loads `hid-wiimote` now
|
||||||
3. Open the Activities tab. While it says **Pairing setup**, press the red Sync
|
and at boot, and restarts Bluetooth and the rover server automatically.
|
||||||
button under the board's battery cover.
|
3. Open the Activities tab. When it says **Waiting for red Sync**, press the red
|
||||||
4. Wait for the card to change to **Sleeping** or **Ready**. BlueZ retains the
|
Sync button under the board's battery cover.
|
||||||
bond and the service also stores the selected board address in
|
4. Wait for the card to report a paired bond and then **Ready**. BlueZ retains
|
||||||
|
the bond and the service also stores the selected board address in
|
||||||
`server/data/balance-board.json`.
|
`server/data/balance-board.json`.
|
||||||
5. For ordinary use, press only the front power button. The board should connect
|
5. For ordinary use, press only the front power button. The board should connect
|
||||||
to the server without another Sync operation.
|
to the server without another Sync operation.
|
||||||
|
|
||||||
The bridge intentionally uses short Bluetooth Classic discovery windows only
|
The bridge keeps Bluetooth Classic discovery active while no board is
|
||||||
while no board is commissioned. It stops scanning after a successful bond.
|
commissioned and stops scanning after a successful bond. Once commissioned, it
|
||||||
|
actively retries the saved address while disconnected so a front-button wake is
|
||||||
|
caught even when the adapter does not accept the board's incoming reconnect.
|
||||||
|
|
||||||
|
Wii-family HID compatibility requires `UserspaceHID=false` and
|
||||||
|
`ClassicBondedOnly=false` in BlueZ's `input.conf`. The installer applies only
|
||||||
|
those two keys with an INI-aware tool and preserves unrelated Bluetooth input
|
||||||
|
settings. The latter relaxes BlueZ's global Classic HID bonding restriction;
|
||||||
|
this is limited to servers where Balance Board support is explicitly enabled.
|
||||||
|
|
||||||
## Physical station
|
## Physical station
|
||||||
|
|
||||||
|
|||||||
@@ -418,7 +418,23 @@ std::string command_error_summary(const std::string& raw, const std::string& fal
|
|||||||
std::string summary;
|
std::string summary;
|
||||||
summary.reserve(std::min<std::size_t>(raw.size(), 400));
|
summary.reserve(std::min<std::size_t>(raw.size(), 400));
|
||||||
bool previous_was_space = false;
|
bool previous_was_space = false;
|
||||||
|
int ansi_state = 0;
|
||||||
for (unsigned char ch : raw) {
|
for (unsigned char ch : raw) {
|
||||||
|
// bluetoothctl emits terminal color CSI sequences even when its output is
|
||||||
|
// captured by a pipe. Drop the entire ESC ... final-byte sequence so the UI
|
||||||
|
// never exposes fragments such as `[[0;93mCHG[0m]` as hardware diagnostics.
|
||||||
|
if (ch == 0x1b) {
|
||||||
|
ansi_state = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ansi_state == 1) {
|
||||||
|
ansi_state = ch == '[' ? 2 : 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ansi_state == 2) {
|
||||||
|
if (ch >= 0x40 && ch <= 0x7e) ansi_state = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const bool is_space = ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r';
|
const bool is_space = ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r';
|
||||||
if (is_space) {
|
if (is_space) {
|
||||||
if (!summary.empty() && !previous_was_space) summary.push_back(' ');
|
if (!summary.empty() && !previous_was_space) summary.push_back(' ');
|
||||||
|
|||||||
Reference in New Issue
Block a user