Skip to content

Add libivpico_helm: pHelmIvP's helm loop without MOOS - #4

Merged
tsaubergine merged 1 commit into
claude/admiring-clarke-s2ay8b-goby-prereqsfrom
claude/admiring-clarke-s2ay8b-helm-library
Nov 4, 2026
Merged

tsaubergine merged 1 commit into
claude/admiring-clarke-s2ay8b-goby-prereqsfrom
claude/admiring-clarke-s2ay8b-helm-library

Conversation

@tsaubergine

Copy link
Copy Markdown
Member

This PR is stacked on #3, which is stacked on #2, and targets #3's branch. Merge those first.

This is the first half of Phase 1 of the Goby helm plan: the helm library, which has no middleware. The second half (replaying recorded MOOS-IvP missions against it) comes in the next PR.

ivpico::helm::Helm (src/lib/helm)

The class ports HelmIvP's startup (OnStartUp), mail handling (OnNewMail) and Iterate() onto the ivp.interface messages. HelmEngine, BehaviorSet, modes and behaviors are MOOS-IvP's own, from the helm libraries, used unchanged.

  • Inputs (Navigation, Variable, Command) are queued by handle() and applied at the start of the next iterate(t), as pHelmIvP applies its mail before each iteration.
    • A Variable with a key pHelmIvP treats specially (MOOS_MANUAL_OVERRIDE, BHV_ABLE_FILTER, NODE_REPORT, HELM_MAP_CLEAR, …) is handled the same way. So the helm can take MOOS variables as they are.
  • The MOOSDB echo (D6). Whatever pHelmIvP would have posted on one iteration is fed back on the next, but only for variables the helm registered (the behaviors' info variables, update variables, and pHelmIvP's fixed list), as the MOOSDB delivers it. Behaviors that update or spawn each other depend on this.
  • initialize_ (deferred) variables are posted after defer_window (default 1 s) if nothing else has set them. This stands in for the MOOSDB sending current values on registration.
  • Each iteration returns an Output:
    • the Solution (decisions, or zeros on an allstop), only on iterations where pHelmIvP posts DESIRED_*;
    • Status: state, allstop, modes, behaviors with run states, contacts, CPU and piece counts;
    • Postings from behaviors, modes, initialize and helm start;
    • BehaviorEvents (BHV_WARNING, BHV_ERROR, …);
    • LifeEvents;
    • ObjectiveFunctions, if report_objective_functions is set.
  • Contacts: Navigation with self: false, or a NODE_REPORT variable, goes into a ContactLedger and the LedgerSnap that contact behaviors read. The alerts that spawn contact behaviors come in Phase 3.
  • Conversions (conversions.h): radians clockwise from north to degrees, Navigation.speed selection, Navigation to NodeRecord, the able-filter string, and decisions to ControlSetpoint fields (custom for domain variables with no field).

interface/config.proto adds ivp.interface.HelmConfig, pHelmIvP's configuration block. Its unset optional fields take pHelmIvP's defaults.

Tests (src/test/helm/test_helm.cpp)

Scenarios with a fake clock, and a simple vehicle model where needed:

  • s1_alpha pattern: initialize postings, PARK until DEPLOY and the override arrive, DRIVE in ACTIVE:SURVEYING, and the survey's endflag RETURN=true.
    • With the default park_on_allstop, the helm parks when the survey completes, because no behavior produces a function on that iteration. That's what real pHelmIvP does: I ran MOOS-IvP's own s1_alpha mission headless, and its log shows RETURN=true, IVPHELM_ALLSTOP=NothingToDo, then IVPHELM_STATE=PARK.
    • Without it, the mode switches to ACTIVE:RETURNING and the vehicle turns around.
  • An update between behaviors through the echo: a timer's endflag updates a constant-heading behavior. The course changes exactly one iteration after the post.
  • Spawning from an updates variable: a SPAWN life event, and the spawned behavior's decision.
  • Allstop: MISSING_DECISION_VARIABLES then PARK; CLEAR when speed is optional; manual override.
  • MALCONFIG on a bad .bhv file.
  • Deferred initialize, with and without a value from elsewhere.

Test plan

  • ./build.sh and ctest: helm_libs and helm pass.
  • CI on all four jobs.

Generated by Claude Code

ivpico::helm::Helm ports HelmIvP's startup, mail handling and Iterate()
onto the interface messages. HelmEngine, BehaviorSet, the modes and the
behaviors are MOOS-IvP's own, unchanged.

- Inputs (Navigation, Variable, Command) are queued and applied at the
  start of the next iterate(t), as pHelmIvP applies its mail.
- What pHelmIvP would have posted to the MOOSDB on one iteration is fed
  back on the next, for the variables the helm registered, as the MOOSDB
  echoes it. Behaviors that update or spawn each other depend on this.
- "initialize_" (deferred) variables are posted after defer_window if
  nothing else has set them.
- Each iteration returns an Output: the Solution, Status, Postings,
  BehaviorEvents and LifeEvents, and ObjectiveFunctions if asked for.
- interface/config.proto adds HelmConfig, pHelmIvP's configuration.
- Contacts from Navigation (self: false) or NODE_REPORT variables go into
  a ContactLedger and LedgerSnap; alerts come later.

src/test/helm/test_helm.cpp runs scenarios with a fake clock: the
s1_alpha pattern (with and without park_on_allstop), an update between
behaviors through the echo, spawning, allstop reasons, MALCONFIG, and
deferred initialize.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VLcYK4e29B5FiPbDDJy5fp
@tsaubergine
tsaubergine added this pull request to stack #8 November 3, 2026 23:30
@tsaubergine
tsaubergine merged commit be97f06 into main Nov 4, 2026
4 checks passed
@tsaubergine
tsaubergine deleted the claude/admiring-clarke-s2ay8b-helm-library branch November 4, 2026 04:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants