Summary
ReBotB601DM.get_observation() reports raw motor degrees, but send_action() multiplies each target by REBOT_B601_DM_JOINT_DIRECTIONS before clipping. The observation and action therefore use different joint frames.
Anything that holds the arm by echoing its observation back as an action sends the wrong targets:
physicalai_rebot_b601_plugin.motion.HoldPoseSource
- Physical AI Studio's follower hold:
application/backend/src/runtime/action_source.py sets _hold_target from robot_state.joint_positions
With the current DM constants:
| Joint |
Direction |
Target sent when echoing observation p |
shoulder_pan, shoulder_lift, wrist_roll |
-1 |
-p (mirrored; e.g. a 20° jump from +10°) |
elbow_flex, wrist_flex, wrist_yaw |
+1 |
p (correct) |
gripper |
-6 |
-6p, then clipped to the joint limit |
Expected: passing get_observation().joint_positions to send_action() holds every joint in place.
Reproduction details
Source inspection plus a mocked run (no DM arm was available for a hardware run). Mocking motorbridge as in packages/physicalai-rebot-b601-plugin/tests/test_dm.py, with control_mode="mit" and gripper_control_mode="mit", then calling robot.send_action(robot.get_observation().joint_positions):
shoulder_pan current +10.00 deg -> echoed hold target -10.00 deg
shoulder_lift current -20.00 deg -> echoed hold target +0.00 deg (mirrored +20, clipped to limit)
elbow_flex current -30.00 deg -> echoed hold target -30.00 deg
wrist_flex current +15.00 deg -> echoed hold target +15.00 deg
wrist_yaw current -5.00 deg -> echoed hold target -5.00 deg
wrist_roll current +12.00 deg -> echoed hold target -12.00 deg
gripper current -30.00 deg -> echoed hold target +0.00 deg (-6 x -30 = +180, clipped to limit)
Additional context
The RobStride driver had the same mismatch. On a B601-RS arm, read-joints-rs.yaml (HoldPoseSource) produced audible hold chatter, and the gripper would creep open whenever it rested above zero because its hold target was six times its position. That driver is fixed in a separate PR by reporting observations in the action frame (motor value / direction).
The analogous DM fix changes recorded observation values (sign flip on shoulder_pan, shoulder_lift, wrist_roll; gripper divided by -6). Existing DM datasets and trained policies would no longer match, so this needs a maintainer decision:
- Report DM observations in the action frame, matching the RS fix, and document the data change; or
- Keep raw observations and give hold sources an explicit observation-to-action mapping from the driver.
Environment
- Runtime commit:
3b95a45 (upstream main)
- Package:
physicalai-rebot-b601-plugin (workspace)
- Robot: B601-RS used to observe the RS symptom; DM behavior established by source inspection
Summary
ReBotB601DM.get_observation()reports raw motor degrees, butsend_action()multiplies each target byREBOT_B601_DM_JOINT_DIRECTIONSbefore clipping. The observation and action therefore use different joint frames.Anything that holds the arm by echoing its observation back as an action sends the wrong targets:
physicalai_rebot_b601_plugin.motion.HoldPoseSourceapplication/backend/src/runtime/action_source.pysets_hold_targetfromrobot_state.joint_positionsWith the current DM constants:
pshoulder_pan,shoulder_lift,wrist_roll-p(mirrored; e.g. a 20° jump from +10°)elbow_flex,wrist_flex,wrist_yawp(correct)gripper-6p, then clipped to the joint limitExpected: passing
get_observation().joint_positionstosend_action()holds every joint in place.Reproduction details
Source inspection plus a mocked run (no DM arm was available for a hardware run). Mocking
motorbridgeas inpackages/physicalai-rebot-b601-plugin/tests/test_dm.py, withcontrol_mode="mit"andgripper_control_mode="mit", then callingrobot.send_action(robot.get_observation().joint_positions):Additional context
The RobStride driver had the same mismatch. On a B601-RS arm,
read-joints-rs.yaml(HoldPoseSource) produced audible hold chatter, and the gripper would creep open whenever it rested above zero because its hold target was six times its position. That driver is fixed in a separate PR by reporting observations in the action frame (motor value / direction).The analogous DM fix changes recorded observation values (sign flip on
shoulder_pan,shoulder_lift,wrist_roll; gripper divided by -6). Existing DM datasets and trained policies would no longer match, so this needs a maintainer decision:Environment
3b95a45(upstreammain)physicalai-rebot-b601-plugin(workspace)