6.3 KiB
Rover control behaviour prototype
Status: offline behavioural reference; no production actuation adapter. Requested by the owner while unavailable for physical testing, 2026-09-24. Neither Core composition nor Node/VESC runtime imports these modules. No new driver, service, firmware, motor settings or authority capability is installed.
src/profile.ts contains the versioned desired-profile parser, Tank and Arcade
mixers, continuous deadband, linear/squared response, relative output scaling,
and fan-out to any number of UUID-bound motors on both sides. UUIDs must be
unique; a missing side is rejected. forwardSign is the verified sign at the
future actuator adapter, not a copy of m_invert_direction and not a second
automatic inversion of the current VESC configuration.
The normalized result has no electrical units. It cannot be sent as amperes, watts, duty, ERPM or speed without a separately qualified adapter and individual motor, battery/BMS and braking limits. A profile output scale of 80% is not the owner's proposed 20% safety margin against verified equipment ratings. The current real RC path is PPM Duty Cycle; this prototype does not change it.
Arcade uses continuous diamond desaturation, with forward positive and right
yaw positive. For shaped inputs v and r, the pair is (v+r, v-r) multiplied
by max(abs(v),abs(r))/(abs(v)+abs(r)), or zero at the origin. This follows the
WPILib ArcadeDriveIK geometry with the steering sign adapted to the UI.
Reverse plus right still requests right yaw; it is not a car steering-wheel
convention, curvature drive, a turn-radius controller or omnidirectional motion.
No VESC Tool calibration algorithm is reproduced.
References inspected 2026-09-24:
Authority model
src/authority.ts is a pure deterministic model. Its output contains intent
to stop all drives, revoke the Core epoch, flush queued motion and cancel
autonomous motion tasks; it does not actually stop a motor or cancel a process.
The future actuator must enforce the gate synchronously before asynchronous
task cancellation. RC reception, drive supervision and telemetry must survive.
Boot, input loss, controller loss, stale/invalid data, a timing gap or Core command loss enter hold. First RC deflection while Core owns motion consumes the gesture and revokes the old token. Every assigned input must then be neutral and every motor must have trusted physical-stop evidence for the full configured interval. A held first gesture or repeated packet does not qualify. The next gesture starts RC manual operation. Neutral never resumes the previous Core task. Reacquisition requires a new explicit, nonreplayed request in neutral. Old Core commands cannot cross an epoch or process boot identity.
Policy values are mandatory constructor arguments. The demo uses 100 ms freshness / 200 ms neutral solely as synthetic fixtures, not accepted rover reaction limits. Use one monotonic clock domain from an authenticated local producer and a fresh unpredictable boot identity per instance. A token is a stale-command fence, not authentication or a replacement for access control. Calls and input types belong to a trusted model harness; this is not a public network request parser. Run a supervisory tick even when no new input arrives.
link.live, sample acquisition timestamps/sequences and drive.stopped must
come from qualified evidence. A fresh USB response with old decoded PPM does
not meet this contract. Zero motor current/duty alone is not physical stop.
The current FW 5.02 input API does not supply all required evidence. In
particular, stop-first independent of Mini needs an enforcement point outside
Mini and coordination of all motor controllers. No such qualified mechanism
is claimed by these tests. Receiver failsafe is also still awaiting acceptance.
Input axes are semantic controls, not invented receiver channels. The mixer for
Tank requires two Y axes; Arcade requires both axes of the selected stick. The
authority policy separately declares all monitoredAxes: the demo watches all
four axes, so the other stick also stops Core in Arcade. Missing monitored axes
are rejected, not synthesized as zero; all must return to neutral. The current two
separate receiver-to-VESC PWM outputs do not establish access to those Arcade
axes. The channel map, radio-link semantics and independent mixed RC path remain
hardware integration work. Profile revision or binding changes require a fresh
model initialized in hold, not an in-place live change.
Preview and validation
Use the already installed Control Station toolchain; no new dependencies:
cd apps/control-station
node --test test/roverControl.test.mjs
./node_modules/.bin/tsc --project tools/rover-control-preview/tsconfig.json
node tools/rover-control-preview/build.mjs /absolute/artifact/directory
The self-contained HTML uses canonical Design Guideline components. Its CSP disables all network connections, and no transport/serial code exists in the bundle. It is an owner-review artifact, outside production navigation. Browser storage and JSON export contain a draft, never confirmed applied state. It does not add USB controls, device-specific phantom entities or a runtime source-selection switch to the product. The synthetic takeover trace is engineering review content, not a proposed operator control panel.
Intended product placement remains the existing shared «Настройки борта» section
on Core and Node, between computer details and devices. Alternatives (a new
workspace or separate per-VESC control-mode selectors) would fragment a single
vehicle-wide profile and are not used. Existing Inspector, SettingsCard,
InspectorSelectField, RangeControl, Button, StatusBadge cover the review;
no Design Guideline extensions or new visual primitives were needed.
Before production integration: verified input mapping and radio failsafe, independent stop-first actuator mechanism, desired/applied profile storage on Node with optimistic revision checking, all-member application receipts and failure recovery, then shared UI and supervised unloaded tests. Do not expose an enabled Apply button based only on successful model tests.