Files
argo/SUB Control/docs/V2.md
T
PitresAli 8ccd7689f7 Build Argo V2 control mappings and telemetry dashboard
Add configurable Xbox motion and action bindings, frame-aware six-axis MAVLink controls, sensor logging, camera viewing and recording, and a faster startup path. Synchronize both app copies and document companion hardware setup and verification limits.
2026-10-22 20:22:05 +02:00

128 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Argo V2
V2 separates controller mapping, vehicle motion, ArduSub motor allocation, and camera transport. The pre-V2 app is preserved in commit `5e91c28` on `main`; development is on `v2`. A portable Git bundle was also saved locally. The checkpoint is also uploaded as `checkpoint/pre-v2-20261022`.
## Try it
1. Run `run.ps1`, select **Demo Mode**, and connect.
2. Open **Vehicle**, select a **Preview frame**, and save. This changes the demo, never the connected FC's `FRAME_TYPE`.
3. Open **Mapping**, choose **Triggers · 3** or **Six axes**, and save.
4. Open **Dashboard** and press **Start** to see the simulated inspection camera. **Record** produces a WebM clip. The camera badge and sensor status identify demo data.
No physical port is opened in Demo Mode. Real TCP and UDP endpoints now connect to MAVLink instead of silently entering the demo.
## Xbox controls
| Motion | Triggers · 3 | Six axes |
| --- | --- | --- |
| Forward / back | RT / LT | RT / LT |
| Rise / dive | B / A | B / A |
| Turn | Left stick X | Left stick X |
| Sideways | Unassigned | Right stick X |
| Pitch | Unassigned | Left stick Y |
| Roll | Unassigned | RB / LB |
| Lights | X | X |
| View stream | Y | Y |
| Record | View | View |
Each motion has separate negative and positive bindings. Either direction can use a stick half, an analog trigger, a D-pad direction, or a button. Opposite commands cancel. Each motion has a limit; the profile also has dead zone and exponential response. The reverse arrow swaps its bindings. The **Buttons** disclosure configures optional accessory and media actions. Buttons do not arm the ROV.
Profiles are stored by controller ID in `controller_profiles.json`; **Xbox · offline** supplies a default before connecting a controller. Browser preview uses local storage. Existing stick mappings are migrated. Configuration is locked while armed or while the FC state is uncertain. Controls must return to neutral after input mode changes, reconnects, focus changes, or interruption. Accessory buttons also have to be released before they can trigger again.
Keyboard movement remains W/S, A/D (or Q/E), R/F. Additional axes use J/L for strafe, I/K for pitch, U/O for roll. The extra on-screen sliders return to center when released. F2 retains the 0.6-second engage hold; F3 requests disarm.
## Six thrusters and six axes
Your proposed arrangement can provide full control when the paired thrusters have useful moment arms:
| Pair | Shared thrust | Differential thrust |
| --- | --- | --- |
| Port / starboard, pointing forward | Surge | Yaw |
| Front / rear, pointing vertically | Heave | Pitch |
| Top / bottom, pointing sideways | Sway | Roll |
Translation uses the pair in the same direction; rotation uses opposite directions. Thruster directions, lever arms, balance and saturation still determine the result. The allocation matrix, whose columns are force direction and its moment `r × f`, must have rank six. Motor count alone does not establish this.
V2 sends body-motion demands to the FC. The autopilot owns its mixer and stabilization. Select/configure a firmware frame that matches the physical vehicle before using it. The app reads `FRAME_TYPE`; it does not infer a mixer from connected outputs or write a new frame automatically. Your orthogonal-pair design may require a custom firmware mixer if no stock frame matches its geometry.
| ArduSub frame | Motors | Available motion |
| --- | --- | --- |
| SimpleROV-3 (4) | 3 | Forward, vertical, yaw |
| SimpleROV-4 (5) | 4 | Forward, vertical, yaw, roll |
| SimpleROV-5 (6) | 5 | Forward, lateral, vertical, yaw, roll |
| BlueROV1 (0) | 6 | All six axes |
| Vectored (1) | 6 | All except pitch |
| Vectored 6DOF (2, 3) | 8 | All six axes |
The verified six-axis wire mapping is ArduSub's `MANUAL_CONTROL`: X forward, Y lateral, Z vertical (500 neutral), R yaw, S pitch, T roll. Some generic joystick documentation describes S/T differently; this implementation follows ArduSub source. Firmware version is requested at connection; pitch/roll remain unavailable until compatible firmware is identified. ArduSub 4.5 uses S/T as ±400 PWM offsets; the current 4.8 development implementation scales normalized S/T. These encodings have automated checks; physical behavior is unverified.
The shared output limit applies to all motion axes. Full-frame demands use a conservative shared envelope before the FC mixer. This is an input-demand limit, not a calibrated thrust or electrical-current limit. The earlier independent motor-scale reconstruction is specific to SimpleROV-3 and is unavailable on other frames; applying it to a general mixer would be incorrect. Motor names, assignments, and direction controls remain available for active outputs.
References: [ArduSub frame configurations](https://ardupilot.org/sub/docs/sub-frames.html), [ArduSub 4.5 joystick source](https://github.com/ArduPilot/ardupilot/blob/Sub-4.5/ArduSub/joystick.cpp), [current joystick source](https://github.com/ArduPilot/ardupilot/blob/master/ArduSub/joystick.cpp), [Cockpit mapping and vehicle-version support](https://blueos.cloud/cockpit/docs/latest/usage/advanced/).
## Companion computer and tether
```mermaid
flowchart LR
PC[Argo V2 on Windows] <-- Ethernet --> TOP[Topside media converter]
TOP <-- Fibre tether --> ROV[Onboard media converter]
ROV <-- Ethernet --> PI[Raspberry Pi / BlueOS]
PI <-- USB or UART / MAVLink --> FC[ArduSub FC]
CAM[USB or CSI camera] --> PI
SENSOR[Pressure and power sensors] --> FC
FC --> ESC[ESCs / thrusters]
```
This is a proposed architecture, not installed hardware. Use a compatible Ethernet-to-fibre interface at each end, with optics, cable, terminations and housings selected for the tether length and environment. Fibre carries the data link; onboard power or a separate power path is still required. Ethernet lets telemetry and compressed video share a network while remaining separate application streams.
BlueOS is the researched companion option. It routes the FC's MAVLink traffic and manages cameras on supported Raspberry Pi hardware. In BlueOS, configure a MAVLink UDP output to the topside computer's tether-interface IP on port 14550. In Argo, choose **Network · UDP 14550**, or enter an explicit endpoint in Link settings. The listener uses `udpin:0.0.0.0:14550`; choose an interface-specific address with a custom endpoint if needed. The PC and Pi must be reachable on the same tether network.
Video uses an independent browser media connection. This release accepts **WebRTC · WHEP**, a browser-playable **HTTP video** URL, or **MJPEG**. It does not directly decode RTSP or raw UDP H.264. BlueOS's camera service has its own signaling interface, so entering its normal web-dashboard address as a WHEP URL will not work. Use a compatible WHEP endpoint, such as MediaMTX connected to the Pi camera or an RTSP source. Integrating BlueOS's native camera discovery/signaling is a separate follow-up.
Example MediaMTX path for a supported Pi camera:
```yaml
paths:
cam:
source: rpiCamera
```
With the server configured on the tether network, a typical WHEP endpoint is `http://<pi-address>:8889/cam/whep`. Verify it against your MediaMTX configuration. The browser needs CORS permission for the local Argo origin, and the negotiated WebRTC media ports must be reachable. Use a browser-compatible codec. No firewall, authentication, or origin policy is changed automatically by Argo.
**Start/Stop** controls viewing. **Camera power** is a separate optional relay action. **Record** records the incoming browser video; desktop clips are written incrementally to `runtime/recordings/`, and browser-preview clips download as WebM. MJPEG playback has no video recording control. For recordings that must survive tether loss, configure recording on the Pi as well.
References: [BlueOS companion hardware](https://blueos.cloud/docs/latest/integrations/hardware/required/onboard-computer/), [tether overview](https://blueos.cloud/docs/latest/integrations/hardware/required/tether/), [BlueOS endpoints and video services](https://blueos.cloud/docs/latest/usage/advanced/), [MediaMTX Pi cameras](https://mediamtx.org/docs/static-sources/raspberry-pi-cameras), [browser playback](https://mediamtx.org/docs/read/web-browsers).
## Sensors and electricity
The dashboard displays FC telemetry only when its group is fresh. Missing or stale values show a dash. Demo values are explicitly marked.
| Reading | Source | Units |
| --- | --- | --- |
| Pitch, roll, heading and angular rates | ATTITUDE | degrees, degrees/s |
| Depth estimate relative to surface/home | GLOBAL_POSITION_INT.relative_alt | m, positive down |
| Acceleration, gyroscope, magnetic field | SCALED_IMU | m/s², rad/s, gauss |
| External pressure / temperature | SCALED_PRESSURE2 | hPa, °C |
| Battery voltage, current and charge | SYS_STATUS / battery 0 BATTERY_STATUS | V, A, mAh |
Depth needs a correctly configured and calibrated external pressure sensor. Raw accelerometer values include gravity; they are not speed or a gravity-compensated acceleration estimate. Heading is FC-estimated yaw, not a separately read compass bearing.
Current is measured in **amps (A)** at the present moment. Power is **watts (W) = V × A**. Consumption is charge integrated over time, displayed as **mAh**; it is not amps per second. Use a correctly sized, calibrated voltage/current power monitor connected to the FC. Voltage alone cannot measure current. The app prefers reported consumption and otherwise integrates fresh current as a session estimate; source information is in Battery settings. A voltage update does not make an old current reading fresh.
**Log data** writes received normalized sensor values to `logs/sensors_<timestamp>.csv`. Existing raw MAVLink session logs remain in `logs/`. Rates for attitude, depth, IMU and pressure are independently configurable. Begin with low rates on RS-485; use a higher-bandwidth tether for video and increased telemetry.
Lights and camera power require configured, separate FC relay outputs. Configure relay assignments on the FC, then select their zero-based relay numbers in **Vehicle**. Buttons wait for command acknowledgement and expose timeout/rejection status. An accepted command confirms FC acceptance, not measured physical illumination or camera power.
Reference: [ArduSub battery monitor calibration](https://ardupilot.org/sub/docs/common-power-module-configuration-in-mission-planner.html), [MAVLink message definitions](https://mavlink.io/en/messages/common.html).
## Performance and verification
- The launcher only installs dependencies when the requirements fingerprint changes.
- The production path launches `web_ui.py` directly. The old Tk frontend is loaded lazily from `legacy_ui.py`.
- The asset server is threaded. Video frames stay in the browser's media pipeline.
- Network MAVLink skips the redundant packet-leading heartbeat needed by the existing serial modules.
- V2 controller input has one command ramp in the worker, avoiding the previous additional browser smoothing delay.
- V2 controller-profile and station files are validated and replaced atomically. Existing input sequence, stale-bridge and heartbeat watchdogs cover all six motion axes.
Automated checks use synthetic gamepads, mock MAVLink transports, temporary configuration files and telemetry fixtures. Browser checks use Demo Mode and the actual rendered app. No live vehicle has been armed or commanded during development. Real controller hardware, Pi streaming, FC accessories, sensor calibration and water performance still need physical verification.