Name the triggered safe input when the arm refuses a move - #678
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a92ecfae29
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 56094131cd
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cfc8958409
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 21b97767e5
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8219ab8850
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a43ade5f4d
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
44000c2 to
6bc5c8e
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6bc5c8e966
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: da76451a05
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: abff34450e
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9ec5d833b0
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4b88f18aa9
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
4b88f18 to
1c5b0d1
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1c5b0d137a
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
1c5b0d1 to
de3b447
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: de3b447e28
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
de3b447 to
cd50d7b
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cd50d7bf50
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
cd50d7b to
8cd4a53
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8cd4a53e47
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
8cd4a53 to
9c3c3bf
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9c3c3bf738
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
The rig's control box trips safe input x31 on its own. While an input is
triggered, libfranka refuses every move and says only "Move command rejected:
command not possible in the current mode ("Other")". It prints that from the
control thread, unstamped and outside Python. The control box raises no error
flag for a safe input, so the driver reads none and the run log names no cause.
On 2026-08-25 one run printed hundreds of those lines and stopped at 25 of 45
episodes.
A watch thread now reads the safe inputs from Desk every 0.5 s, over a Desk
client it owns: the read needs no control token, and the session that drives the
arm stays on one thread. It logs one stamped line for an input that changes
state. The run loop logs the first move the arm refuses, with libfranka's reason
and the inputs the control box reports as triggered, then the count once the arm
accepts moves again.
A refused move fails and ends the run. Nothing retries it: the control box logs
a trip to one second and the driver polls at 0.5 s, so a fast press by a person
and a bouncing contact read the same.
The refusal log and the brakes both need the goal, so the loop reads it once and
hands it to each.
Ticket: Positronic-Robotics/internal#729 #refs
9c3c3bf to
373bc2f
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 373bc2fcb4
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
`move_to` reads the goal once more after the poll loop exits, then replaces it with a hold target. A goal that turned ABORTED in the last gap before the deadline was never passed to `note_refusals`, so that refusal reached no log. The run loop's own per-tick call catches such a goal on its next iteration; the teardown park has no next iteration. Ticket: Positronic-Robotics/internal#729 #refs
884efb1 to
c1cc820
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c1cc820e8a
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
The fault
The rig's control box trips safe input x31 on its own. While an input is triggered, libfranka refuses
every move and says only:
It prints that from the control thread, unstamped and outside Python. The control box raises no error
flag for a safe input, so
st.errorstays 0 and the driver reads nothing. On 2026-08-25 one runprinted hundreds of those lines and stopped at 25 of 45 episodes, with no line in the run log naming a
cause (Positronic-Robotics/internal#729).
What this ships
A watch thread reads the safe inputs.
_SafeInputsreads Desk'ssafety_statusevery 0.5 s, overa Desk client it owns: the read needs no control token, and the session that drives the arm stays on
one thread. It logs one stamped line for an input that changes state, in either direction.
A refused move says why. The run loop logs the first move the arm refuses, with
Goal.reason—libfranka's own words, where the logger stamps them — and the safe inputs the control box reports as
triggered:
One line covers the whole wall, and a count follows once the arm accepts moves again. Where nothing
reads the safe inputs —
manage_desk=False, or a Desk that stopped answering — the line carries thereason alone and names no input.
Nothing retries
A safe-input stop fails the move and ends the run, which is what the driver does on
maintoday.The driver cannot tell a person's hand from a bouncing contact. The control box's safety log resolves
to one second and the driver polls at 0.5 s. Of 11 trips over 25-26 August, all on x31, nine cleared
inside one second and two lasted 4 s and 6 s.
So the recovery this pull request opened with is gone:
_StoppedShort,_SAFE_STOP_WAIT_S, the retrycap, the wait for a triggered input to clear, and the dispatch mark that told one trip from another.
await_goalraisesRuntimeErroragain, andmove_toismain's. Codex raised the same objection onthree threads, and it was right.
The control box has tripped no safe input since 2026-08-26.
Where a refusal is recorded
await_goalnotes the refusal where it reads the aborted goal, which covers a sync move, the openingpark and the teardown park. The run loop notes every tick as well, which is what ends a streak and
reports its count.
move_tonotes one more reading at the deadline, where the poll loop has already stopped: on theteardown park nothing else reads a goal that turned ABORTED in that last gap.
The refusal log and
_Brakes.close_if_idleboth need the goal, so the run loop reads it once and handsit to each.
Tests
Sixteen tests over
FakeDesk: a reading the driver does not recognise, the state-change log, awatch that has a reading the moment it is entered, the refusal line naming the triggered input, the
two cases where it names none (no Desk session, and a Desk that stopped answering), one line for a
wall of refusals, the count across two moves, a goal the arm reached ending the streak, a refusal
that never lets up, a stopped move that fails, a refused sync move and a refused teardown park each
logging itself, a refusal landing as the deadline expires and a plain timeout that is no refusal,
and the whole of it end to end.
uv run --locked pytestis green: 1832 passed, 8 skipped.pre-commit run --from-ref origin/main --to-ref HEADpasses, basedpyright included.