@@ -75,6 +75,27 @@ def get_observations(self) -> dict[str, np.ndarray]:
7575 if self ._client is None :
7676 raise RuntimeError ("Client not connected" )
7777 return self ._client .get_observations ().result ()
78+
79+ def get_gripper_from_encoder (self ) -> float :
80+ """
81+ Try to get gripper state from teaching handle encoder button.
82+ Returns a value between 0 (closed) and 1 (open).
83+ Falls back to 1.0 (open) if not available.
84+ """
85+ if self ._client is None :
86+ raise RuntimeError ("Client not connected" )
87+ try :
88+ # Try to get encoder state if the server exposes it
89+ # This requires custom method in the i2rt server
90+ obs = self ._client .get_observations ().result ()
91+ # Check if encoder button data is available in observations
92+ # The encoder button state might be in io_inputs or similar field
93+ if "io_inputs" in obs :
94+ # Button pressed = closed gripper (0), not pressed = open (1)
95+ return 0.0 if obs ["io_inputs" ][0 ] > 0.5 else 1.0
96+ return 1.0 # Default to open if no encoder data
97+ except Exception :
98+ return 1.0 # Default to open on any error
7899
79100
80101class BiYamLeader (Teleoperator ):
@@ -184,8 +205,8 @@ def get_action(self) -> dict[str, float]:
184205 """
185206 Get action from both leader arms by reading their current joint positions.
186207
187- For teaching handles (no physical gripper), we add a default gripper position
188- to match the follower arm's expected 7 DOFs (6 joints + 1 gripper) .
208+ For teaching handles (no physical gripper), we try to read encoder button state
209+ to control the gripper, falling back to fully open if not available .
189210
190211 Returns:
191212 Dictionary with joint positions for both arms (including gripper)
@@ -196,12 +217,13 @@ def get_action(self) -> dict[str, float]:
196217 left_obs = self .left_arm .get_observations ()
197218 left_joint_pos = left_obs ["joint_pos" ]
198219
199- # If no gripper (teaching handle), add default gripper position (fully open = 1.0)
220+ # Handle gripper: either from physical gripper or teaching handle encoder
200221 if "gripper_pos" in left_obs :
201222 left_joint_pos = np .concatenate ([left_joint_pos , left_obs ["gripper_pos" ]])
202223 else :
203- # Teaching handle: add default gripper value (1.0 = fully open)
204- left_joint_pos = np .concatenate ([left_joint_pos , [1.0 ]])
224+ # Teaching handle: try to get gripper from encoder button
225+ left_gripper = self .left_arm .get_gripper_from_encoder ()
226+ left_joint_pos = np .concatenate ([left_joint_pos , [left_gripper ]])
205227
206228 # Add with "left_" prefix
207229 for i , pos in enumerate (left_joint_pos ):
@@ -211,12 +233,13 @@ def get_action(self) -> dict[str, float]:
211233 right_obs = self .right_arm .get_observations ()
212234 right_joint_pos = right_obs ["joint_pos" ]
213235
214- # If no gripper (teaching handle), add default gripper position (fully open = 1.0)
236+ # Handle gripper: either from physical gripper or teaching handle encoder
215237 if "gripper_pos" in right_obs :
216238 right_joint_pos = np .concatenate ([right_joint_pos , right_obs ["gripper_pos" ]])
217239 else :
218- # Teaching handle: add default gripper value (1.0 = fully open)
219- right_joint_pos = np .concatenate ([right_joint_pos , [1.0 ]])
240+ # Teaching handle: try to get gripper from encoder button
241+ right_gripper = self .right_arm .get_gripper_from_encoder ()
242+ right_joint_pos = np .concatenate ([right_joint_pos , [right_gripper ]])
220243
221244 # Add with "right_" prefix
222245 for i , pos in enumerate (right_joint_pos ):
0 commit comments