66import pinocchio
77import placo
88import meshcat .transformations as tf
9- import pyroboticsservice as xr
109
1110from placo_utils .visualization import (
1211 robot_viz ,
2019 quat_diff_as_angle_axis ,
2120)
2221
22+ from teleop_demo_mujoco .pico_client import PicoClient
23+
2324
2425class MujocoTeleopController :
2526 def __init__ (
@@ -53,6 +54,7 @@ def __init__(
5354 self .visualize_placo = visualize_placo
5455 self .scale_factor = scale_factor
5556 self .q_init = q_init
57+ self .q_current = q_init
5658
5759 # To be initialized later
5860 self .mj_model = None
@@ -76,8 +78,8 @@ def __init__(
7678 name : None for name in end_effector_config .keys ()
7779 }
7880
79- def initialize ( self ):
80- """Set up the MuJoCo simulation and the IK solver."""
81+ self . pico_client = PicoClient ()
82+
8183 self ._setup_mujoco ()
8284 self ._setup_placo ()
8385
@@ -196,10 +198,6 @@ def _setup_mocap_target(self):
196198 f"Mocap ID for '{ vis_target } ' body: { self .target_mocap_idx [name ]} "
197199 )
198200
199- def xr_init (self ):
200- """Initialize XR tracking."""
201- xr .init ()
202-
203201 def run (self ):
204202 """Run the main teleoperation loop."""
205203
@@ -215,7 +213,7 @@ def run(self):
215213 self .t += self .dt
216214
217215 for name , config in self .end_effector_config .items ():
218- xr_grip = xr .get_key_value_by_name (
216+ xr_grip = self . pico_client .get_key_value_by_name (
219217 config ["control_trigger" ]
220218 )
221219 active = xr_grip > 0.5
@@ -227,7 +225,9 @@ def run(self):
227225 self ._get_end_effector_info (config ["link_name" ])
228226 )
229227 print (f"{ name } is activated." )
230- xr_pose = xr .get_pose_by_name (config ["pose_source" ])
228+ xr_pose = self .pico_client .get_pose_by_name (
229+ config ["pose_source" ]
230+ )
231231 delta_xyz , delta_rot = self ._process_xr_pose (
232232 xr_pose , name
233233 )
@@ -302,18 +302,36 @@ def _process_xr_pose(self, xr_pose, src_name):
302302 return delta_xyz , delta_rot
303303
304304 def _update_kinematics (self ):
305- # Solve IK
306- self .solver .solve (True )
307- self .placo_robot .update_kinematics ()
305+ try :
306+ self .solver .solve (True )
307+ self .placo_robot .update_kinematics ()
308+ except RuntimeError as e : # Catch RuntimeError
309+ if "QPError" in str (e ) and "NaN in the QP solution" in str (e ):
310+ print (f"IK solver failed with QPError (NaN): { e } " )
311+ if self .floating_base :
312+ self .placo_robot .state .q = self .q_current
313+ else :
314+ self .placo_robot .state .q [7 :] = self .q_current
315+ self .placo_robot .state .q [:7 ] = np .array (
316+ [0 , 0 , 0 , 1 , 0 , 0 , 0 ]
317+ )
318+
319+ self .placo_robot .update_kinematics ()
320+ else :
321+ print (f"An unexpected RuntimeError occurred in IK solver: { e } " )
322+ return
323+ except Exception as e :
324+ print (f"An unexpected error occurred in IK solver: { e } " )
325+ return
326+
308327 if self .floating_base :
309- q = self .placo_robot .state .q
328+ self . q_current = self .placo_robot .state .q
310329 else :
311- q = self .placo_robot .state .q [7 :]
312-
313- self .mj_data .ctrl = q
330+ self .q_current = self .placo_robot .state .q [7 :]
331+ self .mj_data .ctrl = self .q_current
314332
315333 if self .visualize_placo :
316- self .placo_vis .display (self .placo_robot . state . q )
334+ self .placo_vis .display (self .q_current )
317335
318336 for name , config in self .end_effector_config .items ():
319337 robot_frame_viz (self .placo_robot , config ["link_name" ])
0 commit comments