fix(safety): keep the velocity clamp live after another joint's violation - #303
Open
eastagiletracker wants to merge 1 commit into
Open
Conversation
…tion The velocity gate in check_single() read the whole cross-joint violations list, so once any joint recorded a position or effort violation the gate was false for every remaining joint and their velocity deltas were never checked or clamped. Scope the gate to the joint being checked. Position/effort precedence on the same joint is unchanged; a joint that was itself clamped still skips its own velocity check.
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.
This PR proposes scoping the velocity gate in
ActionGuard.check_single()to the joint being checked, so a position or effort violation on one joint no longer switches velocity clamping off for every joint after it — fixes #277. We include this PR work along with a full history of your repo at https://eastagiletracker.com/projects/323. You can sign in with your GitHub ID to claim ownership of the project.What's wrong
In
src/tether/safety/guard.py, the per-joint loop incheck_single()gates the velocity check onnot any("velocity limit" not in v for v in violations), which isall("velocity limit" in v for v in violations).violationsaccumulates across the whole loop, so the moment any joint records a position or effort violation the gate reads false for that joint and for every higher-indexed joint after it — their velocity deltas are then neither reported nor clamped. The clamp fails open in exactly the situation it exists for: an action that is already out of range.Reproducing it on current
main(97d2a87)Public API, no hardware, no model:
On
mainthis prints3.0— joint 3's delta of 3.0 goes straight through the 2.0 cap, and the returned violations mention joint 0 only. Change the single unrelated value5.0back to0.0and the identical joint 3 delta clamps to2.0. With this PR, both print2.0.The change
check_single()now recordsjoint_violation_start = len(violations)at the top of each joint's iteration and gates the velocity check onlen(violations) == joint_violation_start— "this joint has recorded nothing of its own yet" — instead of scanning the shared cross-joint list. That is four lines insrc/tether/safety/guard.py. Same-joint precedence is deliberately unchanged: a joint that was itself position- or effort-clamped still skips its own velocity check, which is what your existingtest_partial_clamp_preserves_other_actionsasserts and what a new control test here pins down. The chunk-levelprevious_safereset that #277 mentions as compounding is left alone — separate concern, separate PR, per your one-concern-per-PR rule.How it was verified
pytest tests/on97d2a87before the change: 3217 passed, 75 skipped, none failing. After the change: 3222 passed, 75 skipped, none failing. The five extra are new tests intests/test_guard.py. Three of them fail on the unpatched tree and pass with it —test_velocity_clamp_survives_position_violation_on_earlier_jointandtest_velocity_clamp_survives_effort_violation_on_earlier_jointcovercheck_single()directly, andtest_chunk_velocity_clamp_survives_position_violation_on_earlier_jointcovers the chunk pathcheck()thatservecalls. The other two are controls that stay green either way: same-joint precedence, and joints with no configured velocity limit.ruff checkandmypy --config-file=pyproject.tomlonsrc/tether/safety/guard.pyreport exactly the same pre-existing findings before and after.How this was managed
We imported this repo's issues and pull requests into a live board — 287 stories and 38 labels — and worked this change as the story for #277 on it. The story is at https://eastagiletracker.com/projects/323/stories/209656 and the board is at https://eastagiletracker.com/projects/323.
If you'd rather not receive contributions like this, reply
no-more-prson this pull request and we won't open any further ones on your repositories.Lawrence W. Sinclair
CEO / East Agile
linkedin.com/in/lwsinclair/
eastagile.com