29 KiB
Argonaut 3 — UI Design Specification
Version: 2.0
Date: 9 July 2026
Status: ⚠ SAFETY-CRITICAL FINDING — W1 does not see the vehicle. With the flight controller
unreachable, W1 displayed GREEN / "Systems nominal". Every widget reflects the RPi5 autonomy
stack, not the vehicle. In AUV mode W1 is the pre-dive GO/NO-GO gate (health_role: gate) — as
built it would pass a dive with a dead FC. See §W1 and DIR-7 / DIR-12. OPEN.
This session: rov_api /mode endpoints (GET/POST) built, deployed, tested (9109439).
W8 Mode Indicator built and validated live — render + data (87000e6) — the first widget
beyond W0/W1 confirmed with real data. Chronic "widgets show no data" fault root-caused:
cockpit_bridge had no respawn, so a boot-time race left the data-lake feed permanently dead
(c099c00); fixed and verified across a cold stack restart.
Prior status (v1.9): FastAPI backend (rov_api) core deployed and verified on RPi5:8081. W3 backend
(/abort) now LIVE and confirmed end-to-end (button path → failsafe_monitor FSM). Mission
start/stop endpoints available. W3 widget label decision "RETURN TO SAFE" stands; widget code
update + FASTAPI_HOST config still pending. W6 committed as w6_altitude.json. Stage 2b
endpoints (return budget, backup, mission upload) deferred. Production data path confirmed as
cockpit_bridge WebSocket.
Version History
| Version | Date | Changes |
|---|---|---|
| 2.0 | 9 Jul 2026 | ⚠ SAFETY-CRITICAL: W1 does not see the vehicle. With the FC unreachable, W1 showed GREEN / "Systems nominal". failsafe_monitor does not gate on FC connectivity; absence of data is being read as good data. In AUV mode W1 is the pre-dive GO/NO-GO gate — as built it would pass a dive with a dead flight controller. W1 spec rewritten with required fixes; status line promoted from debug affordance to operational element carrying cause text. See DIR-7, DIR-12. OPEN. W8 Mode Indicator added — read-only active-profile display, colour-coded by base mode; validated live (render + data), the first widget beyond W0/W1 so confirmed (87000e6). Mode switching explicitly excluded from W8 (belongs to the setup wizard, POST /mode); ArduSub arm/vehicle mode excluded (Cockpit shows it natively). Widget testing status corrected — "renders" and "works" are now explicitly distinguished throughout: validated with live data = W0, W1, W8; render-only = W2–W6; not built = W7. Prior wording conflated the two. rov_api /mode endpoints (GET/POST) built, deployed, tested incl. rejection path (9109439). Chronic "widgets show no data" root-caused: cockpit_bridge was launched but had no respawn; a boot-time race left it permanently dead, killing the whole data-lake feed. Fixed (c099c00), verified across a cold stack restart. This — not the widgets — was why W1 "sometimes" worked. |
| 1.9 | July 2026 | FastAPI backend (rov_api) core deployed on RPi5:8081 (commit 66a18ef). W3 backend /abort now LIVE — verified end-to-end (POST /abort → Bool /rov/mission/abort → failsafe_monitor flag_manual_abort → FSM NORMAL→HOLD_AND_RECOVER). Mission endpoints /mission/start and /mission/stop available and tested. /health returns live mission/recording/failsafe. W6 committed to Gitea as w6_altitude.json (underscore convention); probe widget removed. W3 widget code update (label + FASTAPI_HOST) still pending. Stage 2b deferred: /return_budget (W5), /backup/* (W7), /mission/upload. FastAPI runs as argonaut-api.service (manual-start). |
| 1.8 | July 2026 | W6 Altitude Widget built and deployed (w6_altitude.json). NO SONAR state confirmed — correct baseline with no Ping2. cockpit_bridge updated to 8 variables: rov-recording and rov-altitude added. W3 button label decided: "RETURN TO SAFE" (assessed vehicle return-to-safe per DIR-5, not emergency hard-stop; widget code update pending). Widget testing status clarified: W0 confirmed live, W1–W5 visual confirmed only, W7 not built. Production data path: cockpit_bridge WebSocket is confirmed production path — NAMED_VALUE bridge node not required. |
| 1.7 | June 2026 | W7 (Backup Due Notice) added to widget scope — operator-facing reminder that a device backup is due, with delay options. Depends on RPi5:8081 FastAPI backend. See W7 spec and DIR-11. |
| 1.6 | June 2026 | Cockpit v1.18.2 DIY widget API confirmed via probe widget. Full window.cockpit surface (17 keys) enumerated. Confirmed: getDataLakeVariableData(id) returns live value. W1–W5 can now be built. |
| 1.5 | June 2026 | Production data path confirmed as cockpit_bridge ROS2 node (port 9001, in rov_mission, commit 12b5161) — all 6 vars live in data lake as external/rov-*. W0 working with scroll fix. |
| 1.4 | May 2026 | Data injection architecture fully documented with confirmed working path (Generic WebSocket) and all failed approaches. Widget variable names corrected. |
| 1.3 | May 2026 | Cockpit native app confirmed required. JSON import format confirmed. CSS rules established. All 6 widgets complete and committed to Gitea. |
| 1.2 | May 2026 | Confirmed DIY widget approach, Data Lake Inspector as W0, build status added. |
| 1.1 | May 2026 | Added Mission Setup button widget. |
| 1.0 | May 2026 | Initial UI design specification. |
1. Approach — Cockpit DIY Widgets (Confirmed)
Widgets are Cockpit DIY widgets — JSON files containing html, css, js, and
inheritCockpitStyles fields, imported via the gear icon on a placed DIY widget panel.
Cockpit native desktop app v1.18.2 is required. The BlueOS browser extension version is "Lite" and does not support DIY widgets. DIY widget support was added in v1.9.0. Generic WebSocket data injection was added in v1.18.0. Download: https://github.com/bluerobotics/cockpit/releases
Import Format
Each widget is a .json file with this exact structure:
{
"html": "...",
"css": "...",
"js": "...",
"inheritCockpitStyles": false
}
CSS Rules — Hard Constraints (Do Not Break)
These were discovered through testing. Violating any of them crashes or corrupts the Cockpit renderer:
| Rule | Reason |
|---|---|
No body {} or :root {} blocks |
Bleed into Cockpit's own styles — causes renderer crash |
No @keyframes animations |
Cause renderer instability |
| No unicode characters in JS strings | Use plain ASCII only (-- not —, ... not …) |
No position: fixed elements |
Use display: block/none toggling instead |
No async/await |
Use .then()/.catch() for all fetch calls |
No global tag selectors (e.g. div {}) |
Use ID and class selectors only, scoped to widget root |
What DIY Widgets Can Do
| Capability | Mechanism |
|---|---|
| Read all variable metadata | window.cockpit.getAllDataLakeVariablesInfo() — returns array of {id, name, type, description} ONLY, not values |
| Read a single live value | window.cockpit.getDataLakeVariableData(variableId) — CONFIRMED working in v1.18.2. Returns live numeric/string value. Use this in all widgets. |
| Read single variable metadata | window.cockpit.getDataLakeVariableInfo(variableId) |
| Set a variable | window.cockpit.setDataLakeVariableData(variableId, value) — available (not tested) |
| Call external REST endpoints | fetch() with .then()/.catch() |
| Open a new browser tab | window.open('URL', '_blank') |
NOT available in DIY widget scope (confirmed absent by probe):
getDataLakeValue()— undefined in v1.18.2listenToDatalakeVariable()— undefined (postMessage iframe External API only)
Full window.cockpit surface (17 keys, confirmed v1.18.2):
dataLakeVariableData [object], getDataLakeVariableData [function], listenDataLakeVariable [function], unlistenDataLakeVariable [function], getAllDataLakeVariablesInfo [function], getDataLakeVariableInfo [function], setDataLakeVariableData [function], createDataLakeVariable [function], updateDataLakeVariableInfo [function], deleteDataLakeVariable [function], getDataLakeVariableLastUpdateTimestamp [function], availableCockpitActions [object], registerNewAction [function], deleteAction [function], registerActionCallback [function], unregisterActionCallback [function], executeActionCallback [function]
2. Data Injection Architecture — CONFIRMED FACTS
Production Path (Confirmed) — cockpit_bridge WebSocket
cockpit_bridge (ROS2 node on RPi5, rov_mission package, port 9001)
WebSocket server :9001
<-- Cockpit connects as client (Settings -> Generic WebSocket Connections)
--> Sends 'variable-name=value' text messages at 2Hz
--> Data lake key: external/{variable-name}
--> DIY widget reads: getDataLakeVariableData('external/{variable-name}')
Message format: Plain text, one variable per message:
variable-name=value
Data lake key format: external/{variable-name}
CRITICAL: Cockpit normalises variable names when creating data lake IDs. Underscores become hyphens in the data lake ID. ALWAYS USE HYPHENS in WebSocket variable names.
Cockpit one-time configuration:
Cockpit -> Menu -> Settings -> Generic WebSocket Connections
Enter: ws://192.168.1.101:9001
Click: ADD CONNECTION
This configuration persists between Cockpit restarts.
Failed Injection Approaches (Do Not Retry)
| Approach | Why it failed |
|---|---|
| HTTP POST to mavlink2rest /mavlink | Stored in REST only — not broadcast to Cockpit |
| UDP to MAVLink ports from external scripts | Does not route to mavlink2rest WebSocket |
| NAMED_VALUE with sysid=1, compid=1 | ArduSub detects heartbeat conflict — do not impersonate |
Data Lake Variables (8 total, published by cockpit_bridge)
| Variable | Source topic | Notes |
|---|---|---|
external/rov-failsafe |
/rov/failsafe |
0=GREEN, 1=AMBER, 2=RED; -1=no data |
external/rov-depth |
/rov/depth |
Metres (3 dp) |
external/rov-voltage |
/mavros/battery |
Battery volts (2 dp) |
external/rov-heading |
/mavros/mavros/compass_hdg |
Compass degrees (1 dp) |
external/rov-ms |
/rov/mission/status |
0=IDLE…4=ABORTED; -1=no data |
external/rov-mp |
/rov/mission/status |
Progress 0-100% |
external/rov-recording |
/rov/recording/active |
1=recording, 0=not recording |
external/rov-altitude |
/ping2/altitude |
Ping2 metres; -1.0=NO SONAR |
3. Widget Palette — Overview
Argonaut 3 uses Cockpit as the operator hub. No more than 8 widgets are in scope. Cockpit is NOT a container for everything — only the specific operator-facing information and controls needed for field operations.
| # | Widget | Purpose | Status |
|---|---|---|---|
| W0 | Data Lake Inspector | Dev diagnostic — shows all 706 data lake variables live | Confirmed working |
| W1 | System Health Indicator | DP-style GREEN/AMBER/RED traffic light showing mission capability | Visual confirmed |
| W2 | Mission Status | Mission state, progress, current task | Visual confirmed |
| W3 | Return To Safe Button | Operator-initiated vehicle return-to-safe (DIR-5) | UI confirmed; backend LIVE; label update pending |
| W4 | Mission Setup Button | Opens mission configuration page in new tab | Visual confirmed |
| W5 | Return Budget | Battery % and dynamic return budget with headroom | Visual confirmed |
| W6 | Altitude | Ping2 downward sonar altitude with colour-banded bar | NO SONAR confirmed |
| W7 | Backup Due Notice | Operator-aware backup reminder with delay control | Not built |
| W8 | Mode Indicator | Read-only active mode profile name, colour-coded by base mode | Validated live (render + data) |
Widget testing status (corrected 9 Jul 2026). There is a hard distinction between a widget that renders and a widget that works. "Renders" means it draws in Cockpit. "Works" means it has been validated end-to-end with live data. Do not conflate them.
- Validated with live data: W0, W1, W8.
- Render-confirmed only, never validated with data: W2, W3, W4, W5, W6.
- Not built: W7.
W6 shows a correct NO SONAR state, which is its no-data state — that is not data validation. Full testing requires a live mission, FastAPI backend, and/or Ping2 hardware.
All widgets read the RPi5 autonomy stack, not the vehicle. For vehicle state (FC present, armed/disarmed, board running) the operator currently must use BlueOS/Cockpit-native surfaces. This is a defect, not a design — see W1 below and DIR-12. In AUV mode there is no operator and no second tool, so the gate must become self-sufficient.
Widget consolidation: Grant may consolidate W0–W7 into a single unified widget as development progresses and the full operational picture is clearer. Not yet designed.
4. Widget Specs
W0 — Data Lake Inspector
File: w0_data_lake_inspector.json
Status: Confirmed working — 706/706 vars live.
Purpose: Dev diagnostic tool. Renders a scrollable table of all Cockpit data lake
variables with live values. Used to confirm data is reaching the data lake from
cockpit_bridge, MAVROS, and other sources.
Data source: window.cockpit.getAllDataLakeVariablesInfo() for enumeration,
getDataLakeVariableData(id) for values.
Notes: Production use is optional — this is a dev/debug tool, not an operational widget.
W1 — System Health Indicator
File: w1_system_health_indicator.json
Status: Validated with live data (GREEN/RED observed). ⚠ But the assessment behind it is
incomplete and unsafe — see below.
Purpose: Primary mission-capability indicator. DP-style traffic light showing
whether the vehicle is ready to conduct a mission (GREEN), degraded but proceeding
(AMBER), or in a critical state (RED).
Data lake variable: external/rov-failsafe (0=GREEN, 1=AMBER, 2=RED; -1=no data)
Mode-dependent role (external/rov-health-role):
- ROV (
advisory, 0) — display only; the pilot decides. - AUV (
gate, 1) — pre-dive GO/NO-GO gate. RED blocks mission start. Last human-visible decision point before the vehicle goes dark.
Behaviour:
- GREEN: "Systems nominal" — all parameters within limits
- AMBER: Named degraded parameter — mission continues with reduced confidence
- RED: Critical failure — return-to-safe active
- Initial / no data: grey / loading state
⚠ OPEN, SAFETY-CRITICAL (9 Jul 2026). On 9 July, with the Pixhawk unreachable and BlueOS reporting "No board running", W1 displayed GREEN / "Systems nominal".
Cause:
failsafe_monitordoes not gate on flight-controller connectivity. It assesses the autonomy stack's own view of health. With no FC data arriving it has no bad data, so it reports nominal. Absence of data is being treated as good data.Consequence: in AUV mode (
health_role: gate) W1 would pass a pre-dive gate with a dead flight controller — on a vehicle that will have no operator once submerged.Required (not built):
failsafe_monitorMUST subscribe to/mavros/stateand assess FC connection + heartbeat age, driving AMBER/RED on comms loss. (This was in the node's original design intent —comms_timeout_sec,comms_lost— but is not effective in the implemented node.)- A monitor with no input MUST NOT report GREEN. "No data" and "good data" must be distinct states, distinctly displayed.
- W1's status line MUST carry cause text —
"Vehicle Disconnected","Heartbeat Lost","No Board Running","Systems nominal"— not a bare colour. The status line was previously treated as a debug affordance; it is promoted to an operational element.- Consider a pre-dive FD-headroom check on BlueOS
ardupilot_manager(handover §15a) as part of the same gate — same question, different failure mode.See DIR-7 (health MUSTs) and DIR-12 (vehicle health ≠ autonomy health).
Test required: Confirm GREEN/AMBER/RED transitions by triggering failsafe monitor state changes with live data. Additionally: confirm RED on FC disconnect once (1) above is built.
W2 — Mission Status
File: w2_mission_status.json
Status: Visual confirmed — IDLE state and progress bar display correctly. Untested with live mission.
Purpose: Show current mission state (IDLE/RUNNING/PAUSED/COMPLETE/ABORTED) and
progress as a percentage progress bar.
Data lake variables:
external/rov-ms(0=IDLE, 1=RUNNING, 2=PAUSED, 3=COMPLETE, 4=ABORTED; -1=no data)external/rov-mp(0-100 percent) Test required: Start a mission with waypoints, observe state transitions and progress bar advancing.
W3 — Return To Safe Button
File: w3_abort_button.json
Status: UI confirmed — confirm dialog, 10s auto-cancel countdown, clean network-error
handling. Label in widget code still reads "ABORT MISSION" — update to "RETURN TO SAFE" pending.
Purpose: Operator-initiated vehicle return-to-safe action (DIR-5). This is a
vehicle-layer action — it moves the vehicle. It is NOT the mission start/stop button.
Button label: "RETURN TO SAFE" (decided July 2026 per DIR-5)
- Not "ABORT MISSION" — that implies emergency hard-stop
- Not "STOP MISSION" — that is a mission-layer action (DIR-4), not vehicle layer
- "RETURN TO SAFE" correctly states what the vehicle does: follow breadcrumb path
back to the closest designated safe place
Mechanism: Confirm dialog (10s auto-dismiss) →
fetch()POST to FastAPI/abortConfig:FASTAPI_HOSTconstant in JS must be set tohttp://192.168.1.101:8081Dependency: FastAPI backend at RPi5:8081 — LIVE (commit66a18ef)./abortverified end-to-end server-side: POST → Bool/rov/mission/abort→ failsafe_monitor FSM NORMAL→HOLD_AND_RECOVER. Remaining: update widget code label ("ABORT MISSION" → "RETURN TO SAFE") and setFASTAPI_HOST, then test the full button→backend path from Cockpit.
W4 — Mission Setup Button
File: w4_mission_setup_button.json
Status: Visual confirmed — cyan button renders, "Configure before diving" status shown.
Opens 404 until setup page exists.
Purpose: Open mission setup page in a new browser tab without leaving Cockpit.
Behaviour:
- IDLE: Full brightness, "Configure before diving" label — button enabled
- RUNNING/PAUSED: Dimmed — button disabled (mission already in progress)
Config:
SETUP_URLconstant in JS must be set to the FastAPI setup page URL Dependency: FastAPI backend serving the setup page — not yet built. Test required: Open setup page successfully with live FastAPI backend.
W5 — Return Budget
File: w5_battery_return_budget.json
Status: Visual confirmed — battery % shows pending. Return budget pending
until external/rov-return-budget is published.
Purpose: Show battery percentage alongside dynamic return budget and headroom warning.
Data lake variables:
external/rov-voltage— battery voltage from cockpit_bridgeexternal/rov-return-budget— return budget % (not yet published by cockpit_bridge) Headroom thresholds:- Headroom < 15%: AMBER warning
- Headroom < 5%: RED critical
Dependency: FastAPI backend for return budget calculation; cockpit_bridge must be
updated to publish
external/rov-return-budget. Test required: Full test with live voltage and return budget data.
W6 — Altitude
File: w6_altitude.json
Status: Built and deployed (July 2026). NO SONAR state confirmed — correct
baseline with no Ping2 connected. Full test hardware-gated on Ping2 sonar purchase.
Purpose: Display downward Ping2 sonar altitude above hull or seafloor with
colour-coded status and vertical bar gauge.
Data lake variable: external/rov-altitude (metres float; -1.0 = NO SONAR sentinel)
Source topic: /ping2/altitude (sensor_msgs/Range) — published by Ping2 driver node
(hardware-gated; driver not yet built)
Colour thresholds:
- GREEN (GOOD): > 1.5m
- AMBER (CAUTION): 0.5–1.5m
- RED (CRITICAL): < 0.5m
- GREY (NO SONAR): sentinel value -1.0 (no Ping2 connected or no echo)
Bar scale: Linear, 0m (bottom) to 5m (top). Values above 5m fill bar to 100%.
No hardware default: Shows "NO SONAR" when altitude value is ≤ -1.0 (sentinel).
The sentinel is published by
cockpit_bridgewhen no/ping2/altitudemessages have been received — meaning no Ping2 driver is running. Notes: sensor_msgs/Rangefieldrange_max(100m for Ping2) is treated as "no return" and also maps to the -1.0 sentinel in cockpit_bridge.- Widget layout uses a vertical bar to the left of the numeric readout. The bar background
shows faint colour zone tints at the threshold boundaries even when reading is live.
Pending: Ping2 ROS2 driver node (wraps ping-python library). Interface defined:
topic
/ping2/altitude, typesensor_msgs/Range, fieldrangein metres. Write driver when Ping2 hardware arrives — cockpit_bridge and widget are ready.
W7 — Backup Due Notice (ops-facing)
File: w7_backup_due_notice.json — NOT YET BUILT
Status: Scoped, not built. Depends on RPi5:8081 FastAPI backend (shared with W3/W4).
Purpose: Surface to the operator that a device backup is due, and let the operator
delay it, rather than allowing an unattended backup to start during operations.
See DIR-11 for intent.
Why this exists: The automated Pi backup system (built 30 Jun 2026) runs each Pi's
self-backup via root cron — RPi4 at 00:00, RPi5 at 00:30 — unattended, which is correct
for dev. In the field this is the wrong default: an SD image is a multi-GB dd stream
that must NOT begin mid-dive. The ops model inverts the dev model — the operator is made
aware a backup is due and chooses when it runs, with the option to delay.
Behaviour:
- Hidden/dormant when no backup is due.
- When a backup is due, show a small unobtrusive notice: which device(s), how overdue.
- Offer delay options (e.g. delay 1h / 4h / until end of session). Delay is operator-chosen, never automatic.
- "Run now" option only enabled when vehicle is not in a mission (ties to
external/rov-ms).
Data sources (planned):
FastAPI /backup/status— backup-due state and overdue age per deviceexternal/rov-ms— mission state (to gate "run now")
Delay mechanism (planned): operator selection POSTs to FastAPI /backup/delay
Dependency: FastAPI backend on RPi5:8081 — not yet built. Open / TBC with Grant: exact delay options; whether "run now" is exposed in field; whether notice appears for all operators or pilot-only.
W8 — Mode Indicator
File: w8_mode_indicator.json
Status: Validated live — render + data confirmed 9 Jul 2026 (commit 87000e6).
Purpose: Read-only indicator of the active operating-mode profile. Answers one question:
"what mode am I in?" Nothing else.
Data lake variables:
external/rov-mode(string) — active profile name:ROV,AUV, or a saved hybrid nameexternal/rov-mode-base(number) — 0 = ROV, 1 = AUV; anything else treated as hybrid
Behaviour:
- Displays the profile name large and prominent, under a small
MODEheader - Colour-coded by base mode: cyan
#38bdf8= ROV, green#00e5a0= AUV, amber#f59e0b= hybrid / unrecognised base - No-data state:
--in grey#484f58with aNO DATA/NO APIstatus line - 2 Hz poll, matching
cockpit_bridgebroadcast rate
Explicitly NOT in scope:
- Read-only. W8 never writes to the data lake and never calls
rov_api. Mode switching lives in the setup wizard (POST /mode), not here. An indicator indicates. - Does not show ArduSub arm state or vehicle mode. Cockpit's native UI already surfaces ARMED/DISARMED and flight mode; duplicating it here would add clutter, not information.
Note (DIR-12): W8 reads a resolved profile that originates from
mode_profiles.yamlon the RPi5. It reflects configuration, not vehicle state — it would displayAUVwith the Pixhawk disconnected. This is correct for what W8 is, but it is another reason W1 must carry the vehicle health picture.
5. Widget File Locations
Gitea repo: rov-autonomy/widgets/
Laptop local: C:\Users\grant\Desktop\Autonomous ROV System\rov-autonomy\widgets\
Widget JSON → Gitea: W6 widget JSON (
w6_altitude.json) and any updated W0–W5 files need to be re-imported from the laptop and pushed to Gitea. Do NOT overwrite from chat history — the laptop files are the source of truth.
6. Production Data Path — Confirmed
The production data path is cockpit_bridge WebSocket (confirmed working, commit 12b5161
onwards). The NAMED_VALUE bridge node previously considered is not required — the WebSocket
path has no 10-char name limit, simpler implementation, and is already deployed.
NAMED_VALUE is not needed for production. Do not build a NAMED_VALUE bridge node.
The one case where native ArduSub NAMED_VALUE messages matter is data that ArduSub itself publishes (e.g. attitude data) — these flow automatically through mavlink2rest to Cockpit's data lake without any bridge. Custom ROS2 data goes exclusively through cockpit_bridge.
7. FastAPI Backend (rov_api)
Runs as argonaut-api.service on RPi5:8081 (manual-start in dev). Core deployed and
verified end-to-end (commit 66a18ef). Architecture: uvicorn/FastAPI in the main thread,
embedded rclpy node (RovApiNode) in a daemon background thread. CORS enabled for Cockpit.
Endpoints
| Endpoint | Method | Action | Status |
|---|---|---|---|
/health |
GET | Returns mission state, recording active, failsafe state | DONE — verified |
/abort |
POST | W3 RETURN TO SAFE — publishes Bool to /rov/mission/abort (vehicle-layer, DIR-5) |
DONE — verified end-to-end |
/mission/start |
POST | MissionCommand START (recording no-go gate enforced by mission_executor) | DONE — verified |
/mission/stop |
POST | MissionCommand ABORT | DONE — verified |
/mission/upload |
POST | Accepts YAML file, saves to RPi5 | DEFERRED — Stage 2b |
/return_budget |
GET | Returns current calculated return budget % (feeds W5) | DEFERRED — Stage 2b |
/backup/status |
GET | Per-device backup-due state and overdue age (feeds W7) | DEFERRED — Stage 2b (Option A) |
/backup/delay |
POST | Records operator-chosen backup delay window (feeds W7) | DEFERRED — Stage 2b (Option A) |
W3 abort path detail: /abort publishes Bool(true) to /rov/mission/abort. The
failsafe_monitor latches this as flag_manual_abort → FSM transitions NORMAL → HOLD_AND_RECOVER.
This is the DIR-5 vehicle-layer return-to-safe, NOT the mission ABORT service. Verified live.
W3 widget wiring (pending): update w3_abort_button.json label to "RETURN TO SAFE" and
set the FASTAPI_HOST constant to http://192.168.1.101:8081.
Stage 2b design notes:
/return_budget: return budget calculation approach under discussion ("shortest path to safety" concept). Without a DVL, position is unreliable — approach TBD with Grant./backup/*: Option A chosen — server exposes read-only JSON backup status, RPi5 FastAPI polls outbound (most secure: no credentials on the field-exposed RPi5, read-only, outbound only).
8. Development Sequence
| Order | Task | Status |
|---|---|---|
| 1 | Confirm Cockpit native app required | DONE |
| 2 | Confirm JSON import format | DONE |
| 3 | Establish CSS rules for DIY widgets | DONE |
| 4 | W0 Data Lake Inspector | DONE — confirmed working (706 vars live) |
| 5 | W1 System Health Indicator | DONE — visual confirmed; full test pending |
| 6 | W2 Mission Status | DONE — visual confirmed; full test pending |
| 7 | W3 Return To Safe Button | DONE (UI); backend LIVE; label + FASTAPI_HOST update pending |
| 8 | W4 Mission Setup Button | DONE — visual confirmed; needs setup page (Stage 2b/Phase 6) |
| 9 | W5 Return Budget | DONE — visual confirmed; needs /return_budget (Stage 2b) |
| 10 | Commit W0–W5 to Gitea | DONE — rov-autonomy/widgets/ |
| 11 | cockpit_bridge node (WebSocket production path) | DONE — 8 variables, commits 12b5161, 5d75a9d, 0640353 |
| 12 | Probe widget (API discovery tool) | DONE and DELETED — dev tool only, not part of W0–W7 |
| 13 | W6 Altitude Widget | DONE — w6_altitude.json, committed (commit 785ec56) |
| 14 | FastAPI backend core (RPi5:8081) | DONE — commit 66a18ef, verified end-to-end |
| 15 | W3 label update to "RETURN TO SAFE" + FASTAPI_HOST | PENDING — widget code update required |
| 16 | W3 backend /abort POST confirmed end-to-end |
DONE — FSM NORMAL→HOLD_AND_RECOVER verified |
| 17 | W5 /return_budget + rov-return-budget publishing |
DEFERRED — Stage 2b (approach TBD) |
| 18 | W7 Backup Due Notice + FastAPI /backup/* |
DEFERRED — Stage 2b (Option A) |
| 19 | W6 full end-to-end test | HARDWARE-GATED — requires Ping2 sonar (Phase 3 purchase) |
| 20 | W2 full test with live mission | READY — backend available; needs loaded plan + POST /mission/start |
| 21 | Mission Setup View (full page, W4 target) | Phase 6 / Stage 2b |
| 22 | Viewer Page | Phase 6 |
End of document — Argonaut 3 UI Design v1.9 — July 2026 Next revision triggered by: FastAPI backend built, W3 label updated, W7 built, Ping2 purchased.