robotd, kinematics, robotd-params: four hardening fixes for the drive loop and startup - #199
Open
hadelan wants to merge 5 commits into
Open
robotd, kinematics, robotd-params: four hardening fixes for the drive loop and startup#199hadelan wants to merge 5 commits into
hadelan wants to merge 5 commits into
Conversation
A mode switch queued with torque off jumped straight to Homing, skipping the set_torque the enable path owns. The ramp then "finished" over dead motors: the other mode's policies loaded, the state reported Ready and homed, and the robot lay on the floor. The same request on a tick with no position sample wedged mode_change forever — its only consumer is the ramp finishing — refusing every later switch as already in flight. Keep Limp (the enable path turns the motors on and ramps; the queued switch completes when that ramp does), and refuse the switch outright on a sample-less tick. Assisted-by: Kimi:kimi-code
…and filters JSON parses 1e400 as infinity, so a client can put one on the wire. Folded into the twist/head/body EMAs it is permanent — ema += α·(inf − ema) is inf on that tick and every tick after — and the safety layer refuses non-finite joint targets rather than clamping them, so a single bad robot.move froze the robot on its hold pose until reboot. Assisted-by: Kimi:kimi-code
min_zones = 0 is a legal config value, and it makes the length check pass on an empty band — straight into the low-percentile index below, which panics on an empty Vec. Floor the check at one zone: no zones is no hand, whatever the configured floor is. Assisted-by: Kimi:kimi-code
The "none" sentinel disables the optional policy slots, but walk is the one slot resolved() cannot leave empty — every mode has a default for it, and the controller has nothing to load without it. A config that said walk = "none" got past load and panicked in resolved() at startup. Validate refuses it now, as a config error with the path attached. Assisted-by: Kimi:kimi-code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Four independent fixes, one commit each, every one with a regression test.
Homing, skipping theset_torquethe enable path owns — the ramp "finished" over dead motors, the other mode's policies loaded, and the state reportedReady/homedfor a robot lying on the floor. The same request on a tick with no position sample wedgedmode_changeforever, refusing every later switch as already in flight.Limpnow staysLimp(the enable path turns the motors on and ramps; the queued switch completes when that ramp does), and a sample-less tick refuses the switch outright.1e400as infinity, so a client can put one on the wire. Folded into the twist/head/body EMAs it is permanent (ema += α·(inf − ema)isinfon every later tick), and since the safety layer refuses non-finite joint targets rather than clamping them, a single badrobot.movefroze the robot on its hold pose until reboot. The filters now drop non-finite targets.min_zonesis 0.min_zones = 0is a legal config value, and it made the length check pass on an empty band — straight into the low-percentile index, which panics on an emptyVec. The check is now floored at one zone.policy.walk = "none"at load instead of panicking. The"none"sentinel legitimately disables the optional policy slots, butwalkis the one slotresolved()cannot leave empty, so the config got past load and panicked at startup.validate()refuses it now, as a config error with the path attached.cargo test --workspace(1035 passed, 0 failed),clippy -D warningsandfmt --checkare all green.