From 35561495b44b2ad5b7539329c748de35b0bbf8fc Mon Sep 17 00:00:00 2001 From: legop3 Date: Thu, 16 Jul 2026 22:35:07 -0400 Subject: [PATCH] slop --- server/config.example.yaml | 3 + server/install_server.sh | 61 +++++++++++++++++-- .../services/balanceBoardService/README.md | 27 +++++--- .../native/balance_board_worker.cpp | 16 +++++ 4 files changed, 94 insertions(+), 13 deletions(-) diff --git a/server/config.example.yaml b/server/config.example.yaml index 4ba8a680..d0d61378 100644 --- a/server/config.example.yaml +++ b/server/config.example.yaml @@ -178,6 +178,9 @@ kinect: captureCooldownMs: 10000 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 # A load must reach this weight before stability timing begins. Keeping the # threshold above sensor drift prevents an empty board from capturing itself. diff --git a/server/install_server.sh b/server/install_server.sh index cef6c35b..35dc904f 100755 --- a/server/install_server.sh +++ b/server/install_server.sh @@ -17,6 +17,8 @@ SNAPSHOT_DIR="/var/lib/rover-snapshots" REPLAY_SEGMENT_DIR="/var/lib/replay-segments" 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_MODULES_LOAD="/etc/modules-load.d/multirover-balance-board.conf" +BLUEZ_INPUT_CONFIG="/etc/bluetooth/input.conf" if [[ $EUID -ne 0 ]]; then echo "This installer must be run with sudo/root." >&2 @@ -139,6 +141,7 @@ dnf install -y \ libfreenect-devel \ libusb1-devel \ bluez \ + crudini \ libcap >/dev/null 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." 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) trap 'rm -rf "$tmpdir"' EXIT @@ -295,8 +344,8 @@ EOF cat > "$MULTIROVER_SERVICE" <(raw.size(), 400)); bool previous_was_space = false; + int ansi_state = 0; 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'; if (is_space) { if (!summary.empty() && !previous_was_space) summary.push_back(' ');