From 84ec93543b2895b66b44970b45e15746cddd7b03 Mon Sep 17 00:00:00 2001 From: PitresAli Date: Thu, 27 Aug 2026 19:39:12 +0200 Subject: [PATCH] Shorten README to essential setup and controls --- README.md | 183 +++++------------------------------------- SUB Control/README.md | 183 +++++------------------------------------- 2 files changed, 40 insertions(+), 326 deletions(-) diff --git a/README.md b/README.md index 8174a2a..37343e8 100644 --- a/README.md +++ b/README.md @@ -1,173 +1,30 @@ # SUB Control -A deliberately small, low-bandwidth MAVLink controller for bench-testing an -ArduSub vehicle over a USB serial connection. It sends no parameter-list -request and no telemetry-stream request. +A lightweight Windows controller for ArduSub ROVs over USB/MAVLink. ![SUB Control V2 interface in Demo mode](docs/sub-control-v2.jpg) -The desktop window uses a local HTML/CSS/JavaScript interface rendered by the -Windows WebView. Python remains the only launcher and owns the MAVLink worker, -arming, logging, output limiting, and parameter writes. It does not run a web -server, open a browser tab, or require an internet connection. +## Quick start -The WebView is frameless and uses the compact title bar drawn by the interface. -The vehicle rail includes a local STL viewer: choose **Load STL** to start with -an orthographic top-view silhouette, then drag to orbit or use the mouse wheel -to zoom. A cached STL copy is stored locally under the ignored `runtime/` -directory so the model can be restored on the next launch. -STEP/STP CAD solids must first be tessellated/exported as STL because the -embedded renderer intentionally does not include a full CAD kernel. -Binary and ASCII STL faces are preserved in full; large assemblies are not -rendered by skipping triangles. Imports are limited to 30 MB to keep startup -and interactive orbiting responsive. - -## Safety first - -- Remove propellers for initial tests and restrain the vehicle. -- Verify the ArduSub frame and `SERVOx_FUNCTION`, motor direction, ESC range, - leak/failsafe, and emergency-stop arrangements before arming. -- The application starts disarmed and limits pilot demand to 20% by default. - Once armed, control movement is sent directly with no additional gate. -- Closing or disconnecting sends neutral controls and a disarm request, but a - physical power cutoff is still required. - -The controls are pilot-demand axes, not direct PWM values. ArduSub performs -the frame mixing and generates the configured ESC outputs. For ArduSub, -`MANUAL_CONTROL.z = 500` is neutral vertical thrust. - -## Run on Windows - -1. Install Python 3.11 or newer. A virtual environment installs packages, but - it does not install Python itself. -2. Open PowerShell in this folder and run `./run.ps1` (or right-click it and - choose **Run with PowerShell**). -3. Select the autopilot's COM port, then click **Connect**. Baud and control-rate - settings are under the small `•••` link button (normally 57600 baud / 20 Hz). -4. Confirm `ArduSub` and a live heartbeat are shown. -5. Click **Set MANUAL**, then **ARM** only when the bench is safe. -6. Move the controls. Once armed, no additional enable button is needed. - -`run.ps1` automatically creates a private `.venv` on the first run, installs -the versions declared in `requirements.txt`, and starts SUB Control. Later runs -reuse the same environment and update missing dependencies when necessary. -The `.venv` directory is intentionally ignored by Git: virtual environments -contain machine-specific executables and can be recreated from -`requirements.txt`. - -## Repository layout - -The Gitea repository is named `argo`. `SUB Control` is a normal directory inside -that repository containing this application. A Gitea **Project** is a planning -board for issues and tasks; source code is not attached to a Project board. -Git tracks the folder automatically because its files are committed on the -repository's `main` branch. - -Keyboard controls for SimpleROV-3: W/S forward/back, A/D yaw left/right, -Q/E alternative yaw control, and R/F rise/dive. -Releasing movement keys eases their controls back to neutral. - -## Three-thruster limitation - -The common ArduSub `SimpleROV-3` arrangement controls forward, yaw, and depth. -It cannot independently control lateral, roll, or pitch. Accordingly, the main -pad is mapped to forward/yaw, while the vertical slider controls depth thrust. - -## Link behavior - -- MAVLink GCS heartbeat: 1 Hz -- `MANUAL_CONTROL`: selectable 10 or 20 Hz (default 20 Hz). Lower rates are - intentionally excluded because they make short return ramps become abrupt - steps at the flight controller. -- No full parameter download -- On connection, inherited bulk telemetry streams are stopped. Only - `SYS_STATUS` at 1 Hz and `SERVO_OUTPUT_RAW` / `RC_CHANNELS` at 2 Hz are - requested, in addition to the normal heartbeat and event-driven status text. -- Arm/disarm uses `MAV_CMD_COMPONENT_ARM_DISARM` and displays `COMMAND_ACK` -- Link health is based on received autopilot heartbeats -- Battery voltage is read from `SYS_STATUS` at 1 Hz and shown as pack voltage, - estimated per-cell voltage, and a voltage-only percentage. Cell count, - capacity, C rating, full/empty cell voltages, and warning percentage are - configurable and saved locally in `battery_settings.json`. Capacity consumed - cannot be measured without a current sensor. -- Servo configuration scans `SERVO1_FUNCTION` through `SERVO16_FUNCTION` and - ArduSub's `MOT_1_DIRECTION` through `MOT_12_DIRECTION` one at a time, waiting - for each response and retrying missed replies. A selected output can be - assigned to Motor 1–12 or set unassigned. Motor direction is toggled with the - corresponding `MOT_n_DIRECTION` value while disarmed; `SERVOx_REVERSED` is - intentionally not used for Motor functions. It never downloads the full - parameter list. - The diagnostic scan also reads `SERVO1`–`SERVO3` MIN/TRIM/MAX and ArduSub's - joystick gain values into the local session log; these values remain - read-only in the application. -- Every session creates a local text log under `logs/`, including operator - actions, outgoing manual-control values and commands, acknowledgements, - status text, and all received MAVLink messages. This does not use ArduPilot's - onboard logger or add any link traffic. - -The car-style virtual joystick maps only to forward/reverse and continuous -differential turning; it never sends lateral motion. The joystick and vertical -slider ease back to center over 400 ms after mouse/key release, so neither can -be left commanding motion. -Focus loss, stale telemetry, disconnect, and disarm clear commanded inputs -without easing. This is a neutral-command request, **not proof that motors have -stopped** when the communication link is unavailable. - -In addition, transmitted pilot demands have a small 4% input deadband and a -0.25-second full-range slew limit. This makes both acceleration and deceleration -arrive at the flight controller as a sequence of stable intermediate values. -Forward and yaw are normalized as a SimpleROV-3 motor pair before the output -limit is applied, preventing their mixer contributions from adding beyond the -selected horizontal limit. - -ArduPilot may ignore manual input when `MAV_GCS_SYSID` does not match this -application's system ID (default 255), or when `MAV_OPTIONS` does not allow -MAVLink input. Those parameters must already be correctly configured. - -## Engage, confirmation, and interruption handling - -The compact window opens at 1100 × 650. Empty sidebar areas drag the window; -the STL viewer, buttons, and sliders are separate interactive regions. Output -limit and Motor setup sit below the main controls. Recent activity retains the -last three events, oldest at the top and newest emphasized at the bottom. -Routine hold instructions are kept in tooltips; -pending confirmations and safety warnings still appear above the controls. -The full-width text control displays `engage` / `disengage`; disengage sends the -same immediate disarm request described below. - -- Hold **ENGAGE** for 1.4 seconds (or hold F2). Early release, leaving the - button, interrupted touch, and focus loss cancel the hold without sending arm. -- **ENGAGING…** means a request is pending. A send result or accepted command - ACK alone does not prove that the vehicle armed: a fresh autopilot heartbeat - reporting the requested state is the final confirmation. A heartbeat can - confirm state even if the ACK packet was lost. -- **DISARM** is one tap or F3, with no long hold. While confirmation is pending, - **DISARMING…** stays red and driving is disabled. Disarm can also interrupt a - pending Engage request. No forced-arm/disarm bypass is used. -- Confirmation timeout: 5 seconds in the backend (6-second UI fallback). - Rejection and timeout remain visible. Late heartbeat updates still determine - the displayed state; the UI never substitutes an animation state for telemetry. -- A heartbeat older than 3 seconds is stale. A missing bridge reply after - 1.5 seconds shows **STATE UNKNOWN**, preserving the last-known state without - claiming disarm. Battery readings older than 5 seconds are marked stale. -- The web frontend renews an input lease locally every 250 ms. If it stops for - 1 second, the worker clears stored demands and sends neutral at its configured - control rate. This adds no MAVLink stream or parameter download. Focus loss - clears both captured touch pointers and queued input; reconnect never replays - the old joystick position. Normal release still eases back to center. -- Link loss cannot deliver a stop over a broken tether. Verify the vehicle's - own failsafe and use independent physical power isolation for bench tests. - -### Regression checks (no hardware) - -Run from this project folder after setting up the Python environment: +Install Python 3.11+ with the Python launcher, then run: ```powershell -.venv\Scripts\python.exe -m unittest discover -s tests -v -node --test tests/control_ui.test.cjs +./run.ps1 ``` -Node is needed only for the frontend regression tests, not to run the app. -The tests use mocked transport and synthetic pointer events, including independent -joystick/vertical pointers. Validate physical multi-touch on the intended screen -and FC failsafes on a restrained, propeller-free setup before powered operation. +The script creates a virtual environment and installs dependencies automatically. +Select a COM port and **Connect**, or choose **Demo Mode** to try it without hardware. +Connection settings are under **•••**. + +## Controls + +- Joystick: forward/back and turning. Vertical slider: rise/dive. +- Keyboard: **W/S** forward/back, **A/D** or **Q/E** turn, **R/F** rise/dive. +- Hold **engage** for 1.4 seconds to request arming; tap **disengage** to request disarming. The app waits for vehicle confirmation. +- Movement controls ease back to neutral when released. + +Includes adjustable output limit, motor setup, voltage-based battery status, an STL viewer, and session logs in `logs/`. + +## Safety + +Verify motor direction, ESC settings, and vehicle failsafes before use. Remove propellers for initial bench tests and keep a physical power cutoff available. A lost connection cannot guarantee the motors stop. diff --git a/SUB Control/README.md b/SUB Control/README.md index 8174a2a..37343e8 100644 --- a/SUB Control/README.md +++ b/SUB Control/README.md @@ -1,173 +1,30 @@ # SUB Control -A deliberately small, low-bandwidth MAVLink controller for bench-testing an -ArduSub vehicle over a USB serial connection. It sends no parameter-list -request and no telemetry-stream request. +A lightweight Windows controller for ArduSub ROVs over USB/MAVLink. ![SUB Control V2 interface in Demo mode](docs/sub-control-v2.jpg) -The desktop window uses a local HTML/CSS/JavaScript interface rendered by the -Windows WebView. Python remains the only launcher and owns the MAVLink worker, -arming, logging, output limiting, and parameter writes. It does not run a web -server, open a browser tab, or require an internet connection. +## Quick start -The WebView is frameless and uses the compact title bar drawn by the interface. -The vehicle rail includes a local STL viewer: choose **Load STL** to start with -an orthographic top-view silhouette, then drag to orbit or use the mouse wheel -to zoom. A cached STL copy is stored locally under the ignored `runtime/` -directory so the model can be restored on the next launch. -STEP/STP CAD solids must first be tessellated/exported as STL because the -embedded renderer intentionally does not include a full CAD kernel. -Binary and ASCII STL faces are preserved in full; large assemblies are not -rendered by skipping triangles. Imports are limited to 30 MB to keep startup -and interactive orbiting responsive. - -## Safety first - -- Remove propellers for initial tests and restrain the vehicle. -- Verify the ArduSub frame and `SERVOx_FUNCTION`, motor direction, ESC range, - leak/failsafe, and emergency-stop arrangements before arming. -- The application starts disarmed and limits pilot demand to 20% by default. - Once armed, control movement is sent directly with no additional gate. -- Closing or disconnecting sends neutral controls and a disarm request, but a - physical power cutoff is still required. - -The controls are pilot-demand axes, not direct PWM values. ArduSub performs -the frame mixing and generates the configured ESC outputs. For ArduSub, -`MANUAL_CONTROL.z = 500` is neutral vertical thrust. - -## Run on Windows - -1. Install Python 3.11 or newer. A virtual environment installs packages, but - it does not install Python itself. -2. Open PowerShell in this folder and run `./run.ps1` (or right-click it and - choose **Run with PowerShell**). -3. Select the autopilot's COM port, then click **Connect**. Baud and control-rate - settings are under the small `•••` link button (normally 57600 baud / 20 Hz). -4. Confirm `ArduSub` and a live heartbeat are shown. -5. Click **Set MANUAL**, then **ARM** only when the bench is safe. -6. Move the controls. Once armed, no additional enable button is needed. - -`run.ps1` automatically creates a private `.venv` on the first run, installs -the versions declared in `requirements.txt`, and starts SUB Control. Later runs -reuse the same environment and update missing dependencies when necessary. -The `.venv` directory is intentionally ignored by Git: virtual environments -contain machine-specific executables and can be recreated from -`requirements.txt`. - -## Repository layout - -The Gitea repository is named `argo`. `SUB Control` is a normal directory inside -that repository containing this application. A Gitea **Project** is a planning -board for issues and tasks; source code is not attached to a Project board. -Git tracks the folder automatically because its files are committed on the -repository's `main` branch. - -Keyboard controls for SimpleROV-3: W/S forward/back, A/D yaw left/right, -Q/E alternative yaw control, and R/F rise/dive. -Releasing movement keys eases their controls back to neutral. - -## Three-thruster limitation - -The common ArduSub `SimpleROV-3` arrangement controls forward, yaw, and depth. -It cannot independently control lateral, roll, or pitch. Accordingly, the main -pad is mapped to forward/yaw, while the vertical slider controls depth thrust. - -## Link behavior - -- MAVLink GCS heartbeat: 1 Hz -- `MANUAL_CONTROL`: selectable 10 or 20 Hz (default 20 Hz). Lower rates are - intentionally excluded because they make short return ramps become abrupt - steps at the flight controller. -- No full parameter download -- On connection, inherited bulk telemetry streams are stopped. Only - `SYS_STATUS` at 1 Hz and `SERVO_OUTPUT_RAW` / `RC_CHANNELS` at 2 Hz are - requested, in addition to the normal heartbeat and event-driven status text. -- Arm/disarm uses `MAV_CMD_COMPONENT_ARM_DISARM` and displays `COMMAND_ACK` -- Link health is based on received autopilot heartbeats -- Battery voltage is read from `SYS_STATUS` at 1 Hz and shown as pack voltage, - estimated per-cell voltage, and a voltage-only percentage. Cell count, - capacity, C rating, full/empty cell voltages, and warning percentage are - configurable and saved locally in `battery_settings.json`. Capacity consumed - cannot be measured without a current sensor. -- Servo configuration scans `SERVO1_FUNCTION` through `SERVO16_FUNCTION` and - ArduSub's `MOT_1_DIRECTION` through `MOT_12_DIRECTION` one at a time, waiting - for each response and retrying missed replies. A selected output can be - assigned to Motor 1–12 or set unassigned. Motor direction is toggled with the - corresponding `MOT_n_DIRECTION` value while disarmed; `SERVOx_REVERSED` is - intentionally not used for Motor functions. It never downloads the full - parameter list. - The diagnostic scan also reads `SERVO1`–`SERVO3` MIN/TRIM/MAX and ArduSub's - joystick gain values into the local session log; these values remain - read-only in the application. -- Every session creates a local text log under `logs/`, including operator - actions, outgoing manual-control values and commands, acknowledgements, - status text, and all received MAVLink messages. This does not use ArduPilot's - onboard logger or add any link traffic. - -The car-style virtual joystick maps only to forward/reverse and continuous -differential turning; it never sends lateral motion. The joystick and vertical -slider ease back to center over 400 ms after mouse/key release, so neither can -be left commanding motion. -Focus loss, stale telemetry, disconnect, and disarm clear commanded inputs -without easing. This is a neutral-command request, **not proof that motors have -stopped** when the communication link is unavailable. - -In addition, transmitted pilot demands have a small 4% input deadband and a -0.25-second full-range slew limit. This makes both acceleration and deceleration -arrive at the flight controller as a sequence of stable intermediate values. -Forward and yaw are normalized as a SimpleROV-3 motor pair before the output -limit is applied, preventing their mixer contributions from adding beyond the -selected horizontal limit. - -ArduPilot may ignore manual input when `MAV_GCS_SYSID` does not match this -application's system ID (default 255), or when `MAV_OPTIONS` does not allow -MAVLink input. Those parameters must already be correctly configured. - -## Engage, confirmation, and interruption handling - -The compact window opens at 1100 × 650. Empty sidebar areas drag the window; -the STL viewer, buttons, and sliders are separate interactive regions. Output -limit and Motor setup sit below the main controls. Recent activity retains the -last three events, oldest at the top and newest emphasized at the bottom. -Routine hold instructions are kept in tooltips; -pending confirmations and safety warnings still appear above the controls. -The full-width text control displays `engage` / `disengage`; disengage sends the -same immediate disarm request described below. - -- Hold **ENGAGE** for 1.4 seconds (or hold F2). Early release, leaving the - button, interrupted touch, and focus loss cancel the hold without sending arm. -- **ENGAGING…** means a request is pending. A send result or accepted command - ACK alone does not prove that the vehicle armed: a fresh autopilot heartbeat - reporting the requested state is the final confirmation. A heartbeat can - confirm state even if the ACK packet was lost. -- **DISARM** is one tap or F3, with no long hold. While confirmation is pending, - **DISARMING…** stays red and driving is disabled. Disarm can also interrupt a - pending Engage request. No forced-arm/disarm bypass is used. -- Confirmation timeout: 5 seconds in the backend (6-second UI fallback). - Rejection and timeout remain visible. Late heartbeat updates still determine - the displayed state; the UI never substitutes an animation state for telemetry. -- A heartbeat older than 3 seconds is stale. A missing bridge reply after - 1.5 seconds shows **STATE UNKNOWN**, preserving the last-known state without - claiming disarm. Battery readings older than 5 seconds are marked stale. -- The web frontend renews an input lease locally every 250 ms. If it stops for - 1 second, the worker clears stored demands and sends neutral at its configured - control rate. This adds no MAVLink stream or parameter download. Focus loss - clears both captured touch pointers and queued input; reconnect never replays - the old joystick position. Normal release still eases back to center. -- Link loss cannot deliver a stop over a broken tether. Verify the vehicle's - own failsafe and use independent physical power isolation for bench tests. - -### Regression checks (no hardware) - -Run from this project folder after setting up the Python environment: +Install Python 3.11+ with the Python launcher, then run: ```powershell -.venv\Scripts\python.exe -m unittest discover -s tests -v -node --test tests/control_ui.test.cjs +./run.ps1 ``` -Node is needed only for the frontend regression tests, not to run the app. -The tests use mocked transport and synthetic pointer events, including independent -joystick/vertical pointers. Validate physical multi-touch on the intended screen -and FC failsafes on a restrained, propeller-free setup before powered operation. +The script creates a virtual environment and installs dependencies automatically. +Select a COM port and **Connect**, or choose **Demo Mode** to try it without hardware. +Connection settings are under **•••**. + +## Controls + +- Joystick: forward/back and turning. Vertical slider: rise/dive. +- Keyboard: **W/S** forward/back, **A/D** or **Q/E** turn, **R/F** rise/dive. +- Hold **engage** for 1.4 seconds to request arming; tap **disengage** to request disarming. The app waits for vehicle confirmation. +- Movement controls ease back to neutral when released. + +Includes adjustable output limit, motor setup, voltage-based battery status, an STL viewer, and session logs in `logs/`. + +## Safety + +Verify motor direction, ESC settings, and vehicle failsafes before use. Remove propellers for initial bench tests and keep a physical power cutoff available. A lost connection cannot guarantee the motors stop.