Commit Graph

60 Commits

Author SHA1 Message Date
Grant
9aa5b5d06f feat(w3): update label to RETURN TO SAFE, point FASTAPI_HOST at deployed rov_api backend
Button label changed from "ABORT MISSION" to "RETURN TO SAFE" (DIR-5 —
this is an assessed return-to-safe, not an emergency hard-stop). Lives in
the html field, not js.

FASTAPI_HOST (W3_FASTAPI_HOST in js) was found already set to
http://192.168.1.101:8081, the deployed rov_api backend on RPi5:8081 — no
change needed there, already correct.

Endpoint path (/abort), styling, layout, colours, and confirm/countdown
polling logic all unchanged. Pre-edit backup made per CREATE-THEN-BACKUP:
widgets/w3_abort_button.json.2026-07-14.bak (untracked, not part of this
commit).
2026-07-14 09:32:51 +02:00
Grant
406bad8fbe docs: record corrected in-mission recovery intent, top-priority FSM rework, paused W1 button, build fix
v2.26, same-day continuation of v2.25:

- Records the DIR-7 in-mission-recovery intent correction just made in
  docs/design_intent_register.md v1.4 (255096f): the condition-clear-commits-
  to-recovery entry trigger built earlier today (2a3e577) is KNOWN-WRONG —
  it produced a contradictory live state (W1 GREEN while the vehicle sat in
  RETURN_TO_SAFE). Corrected model (pointer to the DIR, not duplicated):
  GREEN is unconditionally a working state; committed recovery is triggered
  by fault persistence/recurrence, never by condition-clear.

- Marks the FSM entry-trigger rework as the new top-priority NEXT item,
  ahead of everything previously listed. Confirmed Working, Open Items, and
  PARKED sections rewritten so nothing claims mode-aware recovery works
  correctly end to end — the mode-awareness mechanism (2a3e577) and the
  safe-zone-reached arrival exit (bf815cc) are both confirmed correct and
  unaffected; only entry into committed recovery was wrong.

- Records the W1 safe-zone-reached button as PAUSED, not abandoned: the
  rov_api endpoint and external/rov-failsafe-state variable are built and
  committed (2def2b1), the pre-edit W1 widget backup exists, but the widget
  edit itself was not started since the FSM state it would surface is
  currently known-wrong.

- Records a recurring rov_mission build failure, root-caused and fixed:
  stray nested build/install/log directories inside src/rov-autonomy
  (from colcon being run from the wrong directory) collided with the real
  workspace at /data/ros2_ws. Local filesystem cleanup only, no git change.
  Durable guard recorded: colcon build only ever from /data/ros2_ws.

New §15g narrative section; Recent Commits, Version History, and Changelog
all updated. Documentation only — no code, widget, or DIR file touched in
this commit. Not uploaded to Claude project knowledge; that remains a
manual step.
2026-07-13 18:13:14 +02:00
Grant
255096f20b docs(dir): correct inverted DIR-7 in-mission-recovery intent to count-based fault-persistence model
The 11 Jul DIR-7 addendum "In-mission recovery is mode-dependent" stated
that AUV gate mode commits to recovery ON CONDITION-CLEAR. That was
inverted and wrong — it produced a contradictory GREEN-while-in-
RETURN_TO_SAFE state observed live.

Corrected intent (v1.4, 13 Jul 2026, attributed to Grant):
- GREEN is unconditionally a working state. A cleared fault returns the
  vehicle to GREEN and the mission continues/resumes; a cleared condition
  must never trigger or commit a recovery. Committed recovery is triggered
  by a fault PERSISTING or RECURRING, never by it clearing.
- Three-tier fault model: (1) uncontrollable — power loss / anything that
  disables the safety logic itself, out of scope for the FSM, adjacent to
  shelved DIR-6; (2) transient/self-resetting — system attempts restore,
  returns to GREEN and resumes on success, each failure increments a raw
  count (deliberately no time window/duration), commits to RETURN_TO_SAFE
  only once the count exceeds a configured acceptable number; (3)
  hard/persistent — a RED that doesn't clear, commits immediately without
  waiting on a count.
- All thresholds (acceptable count, transient-vs-hard classification) are
  configuration-driven via the resolved mode profile, same as health_role,
  never hardcoded.
- Survives, correct: health_role mode-awareness (2a3e577); the
  safe-zone-reached arrival-exit mechanism (bf815cc) — its role (completing
  a committed recovery) is unchanged. Retired, known-wrong: 2a3e577's
  condition-clear entry logic, which bf815cc built its exit on top of —
  pending next-session rework into the count-based model. Only the ENTRY
  into committed recovery was wrong, not the exit.

New Parked Design Item: adaptive restart-timing — monitor own restore
count/duration per fault, log it, weigh future restart attempts against
observed history rather than a fixed time. Deliberately holds all
time/duration sophistication kept out of the count-based correction;
depends on the count-based retry machinery existing first. Design-captured,
not yet specified for build.

Changelog and known-implementation-drift callout updated accordingly —
failsafe_monitor's current condition-clear logic is now flagged as a known
implementation gap pending rework, not merely an unimplemented addendum.

Documentation only — no code or widget files touched. Not uploaded to
Claude project knowledge; that remains a manual step.
2026-07-13 18:02:42 +02:00
Grant
2def2b1f41 feat(nav-arrival): rov_api safe_zone_reached endpoint + cockpit_bridge failsafe_state variable
Both support the temporary gate-mode arrival-event operator button (Cockpit
side of the button is a separate later step):

- rov_api: new POST /nav/safe_zone_reached endpoint, mirroring the existing
  POST /abort pattern exactly (same publisher-creation and thread-safe
  publish mechanism). Publishes Bool(true) to /rov/nav/safe_zone_reached,
  which failsafe_monitor already subscribes to and was verified consuming
  on the bench (bf815cc). This endpoint and its future Cockpit button are
  temporary operator scaffolding standing in for navigation's real
  GPS/EKF-derived arrival event; the topic and failsafe_monitor's
  subscription to it are permanent. /abort and all other endpoints
  unchanged.

- cockpit_bridge: additive new data lake variable external/rov-failsafe-state,
  reading msg.failsafe_state off the same FailsafeStatus message already
  handled in _failsafe_cb, alongside the existing external/rov-failsafe
  (assessment_state) and external/rov-failsafe-cause. Lets a widget key a
  control on the vehicle being in RETURN_TO_SAFE (value 3, confirmed from
  rov_interfaces/msg/FailsafeStatus.msg STATE_* constants) specifically.
  Existing rov-failsafe / rov-failsafe-cause derivation unchanged.

Widget work itself (W1 button) is a separate later step, not part of this
commit. W1 widget file and its pre-edit .bak backup are untouched.
2026-07-13 17:12:58 +02:00
Grant
0eca8fef11 docs: record 13 Jul session — mode-system launch fix, gate-mode arrival event, safe-zone-reached parked item
docs/handover.md v2.25:
- mode_profile_loader found never wired into rov_full.launch.py despite being
  committed 7 Jul (4e48dc2) — /rov/mode/profile had zero publishers at
  runtime since; fixed with respawn (464e17e), verified live (0->1)
- failsafe_monitor's mode-aware recovery (2a3e577) surfaced a second gap:
  gate-mode RETURN_TO_SAFE was a terminal trap; closed by the new permanent
  /rov/nav/safe_zone_reached interface (bf815cc), verified live end-to-end
  on the bench; today's publisher is temporary bench scaffolding only
- new §15f narrative section; §0 Confirmed Working, PARKED, NEXT, Recent
  Commits, Version History, and Changelog all updated accordingly
- two pre-existing failsafe_monitor defects found this session (not caused
  by it), flagged in §0 Open Items and §15f: flag_manual_abort is a
  one-way latch never reset (shadows all lower-priority handling after any
  manual abort — field-deployment concern); failsafe_monitor produces no
  log output in journalctl (cost diagnostic time this session)

docs/design_intent_register.md v1.3:
- new Parked Design Item: mode-aware safe-zone-reached arrival event —
  permanent /rov/nav/safe_zone_reached interface, mode-aware/sensor-derived
  arrival judgement (GPS at surface + EKF/dead-reckoning underwater), GPS
  recorded as first-class across mission types (not hull/jacket-specific),
  gate-only scope, temporary W1-button bench-scaffolding publisher pending
  navigation — cross-referenced to the DIR-7 "in-mission recovery is
  mode-dependent" addendum, whose Implementation note is updated to record
  the mechanism is no longer mode-blind (2a3e577)

Not uploaded to Claude project knowledge — that remains a manual step.
2026-07-13 11:55:52 +02:00
Grant
bf815cc600 feat(failsafe): gate-mode safe-zone-reached completion event closes RETURN_TO_SAFE trap
Adds the missing exit from RETURN_TO_SAFE for gate-mode (AUV) committed
recovery. Confirmed live on RPi5 12 Jul 2026: with the mode system now
publishing a real gate profile, failsafe_monitor commits HOLD_AND_RECOVER
-> RETURN_TO_SAFE on condition-clear as designed (2a3e577) but then never
leaves, because the gate branch deliberately ignores further
condition-clear so committed recovery runs to completion (DIR-7 addendum,
"In-mission recovery is mode-dependent") — nothing signalled completion.

New subscription: /rov/nav/safe_zone_reached (std_msgs/Bool), same plain
QoS and latch-on-True callback style as the existing flag_manual_abort
subscription. This topic and this subscription are the PERMANENT nav
interface — the navigation subsystem will publish the real arrival event
here (GPS at surface, EKF dead-reckoning underwater); only today's
publisher is temporary bench-test/button scaffolding. failsafe_monitor
only ever consumes this event, never computes position itself.

health_role == HEALTH_GATE, fsm_state == RETURN_TO_SAFE, flag True ->
transition to NORMAL, cause text "Safe zone reached — recovery complete"
(DIR-7's cause-text MUST, via the existing message-prefix mechanism — no
FailsafeStatus.msg change, no cockpit_bridge/W1 change needed). Any other
combination (not in RETURN_TO_SAFE, or advisory mode) is ignored — advisory
keeps its existing, untouched operator-resume mechanism.

Gate's HOLD_AND_RECOVER->RETURN_TO_SAFE commit behaviour and the advisory
branch are both unchanged — this only adds the missing exit.
2026-07-13 09:33:52 +02:00
Grant
464e17ed43 fix(bringup): wire mode_profile_loader into rov_full.launch.py
mode_profile_loader was built and committed 7 Jul 2026 (4e48dc2) but never
added to any launch file, so /rov/mode/profile has had zero publishers at
runtime on every startup since — confirmed 12 Jul 2026 on RPi5 via
`ros2 node list` (no mode node) and `ros2 topic info /rov/mode/profile`
(Publisher count: 0, 2 subscribers waiting). The entire operating-mode
profile system has been dark since it was built; failsafe_monitor's
health_role has been silently running on its gate default the whole time
rather than the actual configured mode.

Adds the Node action (package rov_mission, executable mode_profile_loader)
alongside the other core nodes, before Perception, so failsafe_monitor and
cockpit_bridge — both latched subscribers to its output — wait as little as
possible on a publisher. respawn=True/respawn_delay=5.0 to match the other
core nodes (c099c00, a5e1c99); not on the respawn exclusion list.

mode_profile_loader.py and mode_profiles.yaml are untouched — this closes
the wiring gap only.
2026-07-12 17:27:59 +02:00
Grant
2a3e5777af feat(failsafe): mode-dependent recovery per DIR-7 addendum (gate commits, advisory holds)
Implements the DIR-7 addendum "In-mission recovery is mode-dependent" (11 Jul
2026, docs/design_intent_register.md). failsafe_monitor now subscribes to
/rov/mode/profile (latched) for health_role and branches condition-clear
recovery behaviour on it, replacing the mode-blind unconditional-NORMAL
recovery added in 1b0050d:

- gate (AUV): HOLD_AND_RECOVER commits to RETURN_TO_SAFE on condition-clear
  instead of returning to NORMAL; an in-progress RETURN_TO_SAFE is left
  alone (recovery runs to completion). Mission resumption stays a separate
  deliberate action (DIR-10) — not touched here.
- advisory (ROV): stays in its current recovery state on condition-clear;
  only an explicit operator resume (new placeholder topic
  /rov/failsafe/operator_resume, pending the real rov_api endpoint) returns
  it to NORMAL.

health_role defaults to gate (not advisory) until the first ModeProfile
message arrives, per DIR-7's absence-of-data-is-not-health guidance applied
to mode assumption. Cause text ("Recovering to safe zone" /
"Holding — awaiting operator decision") flows through the existing
message-prefix mechanism, so cockpit_bridge and W1 need no changes.

FailsafeStatus.msg, mission_executor, and mission-resume logic are
out of scope and untouched.
2026-07-12 13:33:18 +02:00
Grant
5551173b7a docs: restructure into docs/, CLAUDE.md rules-only, DIR v1.2, handover v2.24 2026-07-11 18:46:58 +02:00
Grant
aae70776a0 docs(claude): add 2026-07-11 SESSION LOG — failsafe FC-comms-loss resolved, parked items 2026-07-11 17:55:30 +02:00
Grant
7ce9d282db docs(claude): add measurement/step-back/restart/widget rules, correct Gitea-tracking note (v3.6) 2026-07-11 17:52:30 +02:00
Grant
3409ae5739 fix(w1): move cause text to footer, keep message line state-driven to stop flicker 2026-07-11 17:31:31 +02:00
Grant
3e923609b8 feat(w1): display failsafe cause text in status line for AMBER/RED 2026-07-11 16:29:01 +02:00
Grant
dbe95150e3 feat(cockpit_bridge): publish rov-failsafe-cause text for W1 status line 2026-07-11 16:12:23 +02:00
Grant
1b0050dd6f fix(failsafe): allow recovery to NORMAL from RETURN_TO_SAFE, not just HOLD_AND_RECOVER 2026-07-11 14:14:30 +02:00
Grant
d8546413d1 fix(cockpit_bridge): publish assessment_state not failsafe_state to rov-failsafe 2026-07-11 13:23:53 +02:00
Grant
86b272802f fix(failsafe): FC comms loss now forces unconditional RED per DIR-7/DIR-12 2026-07-11 11:56:38 +02:00
Grant
2add8c9e68 docs: correct ardupilot-manager FD leak root cause (i2c handles, not TCP sockets); flag failsafe FC-comms gap 2026-07-09 10:36:09 +02:00
Grant
917342a27b docs: log respawn rollout across stack nodes 2026-07-08 18:24:38 +02:00
Grant
a5e1c9930b fix(launch): respawn safety and state-critical nodes (failsafe_monitor, motion_controller, ekf, depth, mission_executor) 2026-07-08 18:24:15 +02:00
Grant
9a337d1eb1 docs: flag recording_manager DIR-9/DIR-9a drift as open item 2026-07-08 18:16:23 +02:00
Grant
d5c6baa598 docs: log cockpit_bridge respawn fix and W8 validation 2026-07-08 18:08:25 +02:00
Grant
c099c00917 fix(launch): respawn cockpit_bridge so a failed start cannot leave the data lake feed dead 2026-07-08 18:07:31 +02:00
Grant
87000e6d62 feat(widget): add W8 mode indicator (read-only active profile display) 2026-07-08 17:18:12 +02:00
Grant
47bd376fc7 docs: log /mode endpoints in session log 2026-07-08 12:19:52 +02:00
Grant
9109439707 feat(api): add GET /mode and POST /mode endpoints to rov_api 2026-07-08 12:14:10 +02:00
Grant
882768af01 Merge branch 'master' of ssh://symbytech:222/administrator/rov-autonomy 2026-07-08 11:14:40 +02:00
Grant
6498c14dc2 docs: CLAUDE.md v3.5 - add VSC terminal label, session log bridge 2026-07-08 11:14:14 +02:00
Grant du Toit
4e48dc2c53 feat(mode): operating-mode profile system
Add ModeProfile.msg (atomic resolved flag set) to rov_interfaces.
Add mode_profile_loader node + config/mode_profiles.yaml to rov_mission:
ROV/AUV profiles plus custom/hybrid Save As, published latched on
/rov/mode/profile, reloadable via /rov/mode/reload service.
cockpit_bridge subscribes and surfaces flags to the Cockpit data lake
as external/rov-*. Single source of truth; widgets read flags, not modes.
Verified end-to-end: ROV and AUV resolve correctly and live reload works.

Refs DIR-1/2 (ROV/AUV duality), DIR-9 (amended: ARM-bounded recording), DIR-10.
2026-07-07 11:15:35 +00:00
Grant
785ec56432 Widgets housekeeping: add W6, remove probe widget
- Add widgets/w6_altitude.json (Ping2 downward sonar altitude, W6)
- Remove widgets/diagnostics/w_probe_api.json (dev API probe tool, no longer needed)
2026-07-05 18:11:59 +02:00
Grant du Toit
97decac205 Add deploy/ folder — systemd units and launch wrappers
- argonaut.service + argonaut-stack.sh (autonomy stack)
- argonaut-api.service + argonaut-api.sh (FastAPI backend)
- README documents deploy locations, pip dependencies, install procedure
- Resolves: systemd/wrapper files were previously not version-controlled
- Documents fastapi/uvicorn system-wide install (--ignore-installed typing_extensions)
2026-07-05 15:50:42 +00:00
Grant du Toit
66a18ef707 Phase 3 Stage 2: rov_api FastAPI backend (core)
- New rov_api package: HTTP-to-ROS2 bridge on port 8081
- GET /health: mission state, recording active, failsafe state
- POST /abort: W3 RETURN TO SAFE, publishes Bool to /rov/mission/abort
- POST /mission/start: MissionCommand START (recording no-go gate enforced)
- POST /mission/stop: MissionCommand ABORT
- Embedded rclpy node in background thread, uvicorn in main thread
- Verified end-to-end: /abort -> failsafe_monitor FSM NORMAL -> HOLD_AND_RECOVER
- Runs as argonaut-api.service (manual-start in dev, same policy as argonaut.service)
- Deferred to Stage 2b: /return_budget, /backup/*, /mission/upload
2026-07-05 15:40:34 +00:00
Grant du Toit
06403533f2 W6: Add rov-altitude to cockpit_bridge for Ping2 downward sonar
- Add Range subscription on /ping2/altitude (sensor_msgs/Range)
- Publish rov-altitude to data lake (-1.0 sentinel = NO SONAR)
- Treats range_max (100m) as no-return, same as no-data sentinel
2026-07-04 11:27:39 +00:00
Grant du Toit
5d75a9d30d Phase 3 Stage 1: Recording Manager (DIR-9)
- Add recording_manager node: continuous rosbag2 MCAP recorder,
  zstd compression, 500MB bag splitting, 10GB retention policy,
  1Hz health monitoring and restart on subprocess exit
- Add /rov/recording/active no-go gate to mission_executor START handler
- Add rov-recording variable to cockpit_bridge (data lake visibility)
- Replace foxglove_mcap ExecuteProcess with recording_manager Node
- Register recording_manager entry point in setup.py
- Confirmed: data: true on /rov/recording/active in full stack
2026-07-04 07:42:09 +00:00
Grant
2cb7b74777 W0: fixed column layout (3 columns, horizontal scroll when narrow) 2026-06-23 15:00:32 +02:00
Grant
66f9bd7440 Widgets W1-W5 confirmed working in Cockpit v1.18.2; update README, add probe diagnostic and gitignore, remove obsolete html 2026-06-23 14:22:20 +02:00
Grant du Toit
12b5161436 Add cockpit_bridge node for Cockpit data-lake injection
- New node bridges ROV topics to Cockpit via Generic WebSocket on :9001
- Sends variableName=value format (Cockpit v1.18+ protocol)
- Variables land in data lake as external/rov-{failsafe,depth,voltage,heading,ms,mp}
- Subscribes: /rov/failsafe, /rov/depth, /mavros/battery,
  /mavros/mavros/compass_hdg, /rov/mission/status
- Added to mission.launch.py and rov_mission entry points
- Verified: Cockpit connects, all 6 external/rov-* vars appear in data lake
2026-06-22 09:37:41 +00:00
Grant du Toit
d7f6d3f93e Remove accidental .bak file 2026-06-20 13:55:58 +00:00
Grant du Toit
8a12e3bf50 Retire stub state_estimator; consumers use EKF /odometry/filtered
- state_estimator was an unimplemented stub (empty callbacks, never
  published /rov/state) - removed node, entry point, launch block
- motion_controller + mission_executor: /rov/state -> /odometry/filtered
  (the working robot_localization EKF output)
- Eliminates redundant/competing state estimators; single source of truth
- Verified: EKF publishes ~11Hz, both consumers subscribed
2026-06-20 13:55:12 +00:00
Grant du Toit
7d4e6dfc23 Fix EKF IMU input: point imu0 at real MAVROS topic
- ekf.yaml imu0: /imu/data -> /mavros/mavros/data (the empty /imu/data
  topic had no publisher; EKF produced no output)
- Verified: /odometry/filtered now publishes valid fused orientation
  with real Pixhawk IMU via MAVROS
- Note: high covariance expected (single budget IMU, untuned, no position
  input) - tune after Xsens/DVL added
2026-06-20 13:39:02 +00:00
Grant du Toit
e36644e97e Fix rel_alt type collision; retire VM-era mock_publisher
- depth_node + failsafe_monitor: subscribe to real MAVROS topic
  /mavros/mavros/rel_alt (was /mavros/global_position/rel_alt)
- failsafe_monitor: Float32 -> Float64 (resolves duplicate-type error
  that dropped the topic from recordings)
- Remove mock_publisher (VM-era fake data, now collides with real MAVROS)
- Verified: /rov/depth now publishes real data; zero duplicate-type errors
2026-06-20 13:15:15 +00:00
Grant du Toit
c94412ddae Fix full-stack launch: MAVROS fcu_url + plugin_allowlist, timestamped bag dir, BEST_EFFORT QoS on MAVROS subs, battery<0 unknown guard
- rov_full.launch.py: fcu_url to udp://@<ip>:14550 (was bad local bind); add plugin_allowlist (sys_status,sys_time,command,imu,global_position,setpoint_velocity) to stop duplicate-subscription crash on companion_process_status/debug_value
- foxglove_mcap.launch.py: timestamp bag output dir (was fixed /data/bags/dive, failed on second launch)
- failsafe_monitor/depth_node/state_estimator: qos_profile_sensor_data on MAVROS-sourced subs (MAVROS publishes BEST_EFFORT; default RELIABLE blocked all messages)
- failsafe_monitor: treat battery_percent<0 as UNKNOWN not critical (SITL has no battery; was forcing permanent EMERGENCY_SURFACE)
2026-06-17 18:28:06 +00:00
Grant du Toit
45b3301952 Fix ekf.yaml process_noise_covariance: all floats (was mixed int/float, failed YAML parse) 2026-06-17 12:14:28 +00:00
Grant du Toit
7590fafa04 Add missing setup.cfg to all Python packages - fixes executable install path for ros2 launch 2026-06-17 12:05:46 +00:00
Grant du Toit
f1c6710b1a Add missing rov_bringup/config directory to fix colcon build 2026-06-17 10:09:31 +00:00
Grant
6aa64f02c2 Task 11: update W2 variable names for WebSocket data path 2026-05-14 06:45:26 +02:00
Grant
d16e451765 Task 11: rewrite publisher as WebSocket server for Cockpit v1.18.0 2026-05-13 05:24:55 +02:00
Grant
eb19cee7af Task 11: fix sysid to 1 for mavlink2rest routing; fix W1 variable name 2026-05-12 08:25:43 +02:00
Grant
46e34f6605 Task 11: mock NAMED_VALUE publisher; update W0 widget 2026-05-12 07:08:40 +02:00
Grant
5396949cf6 chore: remove duplicate and zip files from widgets folder 2026-05-12 00:42:13 +02:00