ROBOT_STATIC_META names the viewer pointers before an episode starts, and every rig with an arm writes it as static data at episode start (positronic/eval/__init__.py:11, positronic/data_collection.py:303, positronic/cfg/embodiment.py:33, :61). Its pose_signals value is [robot_state.ee_pose, robot_command.pose].
Serializers.robot_command writes .pose for a CartesianPosition and .joints for a JointPosition (positronic/dataset/serializers.py:125-132). An episode whose commands are joints never carries robot_command.pose, so its static data points at a signal it does not have. Every joints-policy eval has this today (positronic/policy/action.py:75, positronic/vendors/dreamzero/codecs.py:175), and a leader rig will have it.
The viewer skips a pointer the episode lacks (positronic/server/dataset_utils.py:622), so nothing visible breaks. The static data is still wrong: it names a signal that does not exist, and a reader that trusts it fails.
Proposed fix: write the two pointers when the episode closes, from the signals it holds.
- Beside
ROBOT_STATIC_META, a function robot_signal_pointers(signals) -> dict that keeps JOINTS when present, and keeps each of EE_POSE and TARGET_EE_POSE that is present.
- The writer agent applies static data at stop (
positronic/dataset/ds_writer_agent.py:124-132), and DiskEpisodeWriter knows every signal it wrote (positronic/dataset/local_dataset.py:111). Apply the function there, so the pointers name what the episode has.
ROBOT_STATIC_META at start then goes away. The DROID override in positronic/cfg/ds/internal.py:41-45 stays for the legacy plural rename only.
One design choice: the writer agent prunes the pointer lists it was given at start (the agent learns the two pointer keys), or the caller passes a closing hook. The prune is the smaller change.
Line numbers are on main at cab986af.
ROBOT_STATIC_METAnames the viewer pointers before an episode starts, and every rig with an arm writes it as static data at episode start (positronic/eval/__init__.py:11,positronic/data_collection.py:303,positronic/cfg/embodiment.py:33,:61). Itspose_signalsvalue is[robot_state.ee_pose, robot_command.pose].Serializers.robot_commandwrites.posefor aCartesianPositionand.jointsfor aJointPosition(positronic/dataset/serializers.py:125-132). An episode whose commands are joints never carriesrobot_command.pose, so its static data points at a signal it does not have. Every joints-policy eval has this today (positronic/policy/action.py:75,positronic/vendors/dreamzero/codecs.py:175), and a leader rig will have it.The viewer skips a pointer the episode lacks (
positronic/server/dataset_utils.py:622), so nothing visible breaks. The static data is still wrong: it names a signal that does not exist, and a reader that trusts it fails.Proposed fix: write the two pointers when the episode closes, from the signals it holds.
ROBOT_STATIC_META, a functionrobot_signal_pointers(signals) -> dictthat keepsJOINTSwhen present, and keeps each ofEE_POSEandTARGET_EE_POSEthat is present.positronic/dataset/ds_writer_agent.py:124-132), andDiskEpisodeWriterknows every signal it wrote (positronic/dataset/local_dataset.py:111). Apply the function there, so the pointers name what the episode has.ROBOT_STATIC_METAat start then goes away. The DROID override inpositronic/cfg/ds/internal.py:41-45stays for the legacy plural rename only.One design choice: the writer agent prunes the pointer lists it was given at start (the agent learns the two pointer keys), or the caller passes a closing hook. The prune is the smaller change.
Line numbers are on
mainatcab986af.