@@ -50,7 +50,9 @@ def gizmo_transform_callback(node, translation, rotation, flag):
5050 return gizmo_transform_callback
5151
5252
53- def run_gizmo_robot_control_loop (robot : "Robot" , control_part : str = "arm" ):
53+ def run_gizmo_robot_control_loop (
54+ robot : "Robot" , control_part : str = "arm" , end_link_name : str | None = None
55+ ):
5456 """Run a control loop for testing gizmo controls on a robot.
5557
5658 This function implements a control loop that allows users to manipulate a robot
@@ -59,6 +61,7 @@ def run_gizmo_robot_control_loop(robot: "Robot", control_part: str = "arm"):
5961 Args:
6062 robot (Robot): The robot to control with the gizmo.
6163 control_part (str, optional): The part of the robot to control. Defaults to "arm".
64+ end_link_name (str | None, optional): The name of the end link for FK calculations. Defaults to None.
6265
6366 Keyboard Controls:
6467 Q/ESC: Exit the control loop
@@ -78,6 +81,7 @@ def run_gizmo_robot_control_loop(robot: "Robot", control_part: str = "arm"):
7881
7982 from embodichain .lab .sim import SimulationManager
8083 from embodichain .lab .sim .objects import Robot
84+ from embodichain .lab .sim .solvers import PinkSolverCfg
8185
8286 from embodichain .utils .logger import log_info , log_warning , log_error
8387
@@ -86,14 +90,30 @@ def run_gizmo_robot_control_loop(robot: "Robot", control_part: str = "arm"):
8690 # Enter auto-update mode.
8791 sim .set_manual_update (False )
8892
93+ # Replace robot's default solver with PinkSolver for gizmo control.
94+ robot_solver = robot .get_solver (name = control_part )
95+ control_part_link_names = robot .get_control_part_link_names (name = control_part )
96+ end_link_name = (
97+ control_part_link_names [- 1 ] if end_link_name is None else end_link_name
98+ )
99+ pink_solver_cfg = PinkSolverCfg (
100+ urdf_path = robot .cfg .fpath ,
101+ end_link_name = end_link_name ,
102+ root_link_name = robot_solver .root_link_name ,
103+ pos_eps = 1e-2 ,
104+ rot_eps = 5e-2 ,
105+ max_iterations = 300 ,
106+ dt = 0.1 ,
107+ )
108+ robot .init_solver (cfg = {control_part : pink_solver_cfg })
109+
89110 # Enable gizmo for the robot
90111 gizmo = sim .enable_gizmo (uid = robot .uid , control_part = control_part )
91112
92113 # Store initial robot configuration
93114 initial_qpos = robot .get_qpos (name = control_part )
94115
95116 gizmo_visible = True
96- step_count = 0
97117
98118 log_info ("\n === Gizmo Robot Control ===" )
99119 log_info ("Gizmo Controls:" )
@@ -115,14 +135,10 @@ def get_key():
115135 return sys .stdin .read (1 )
116136 return None
117137
118- last_time = time .time ()
119- last_step = 0
120-
121138 try :
122139 while True :
123140 time .sleep (0.033 ) # ~30Hz
124141 sim .update_gizmos ()
125- step_count += 1
126142
127143 # Check for keyboard input
128144 key = get_key ()
@@ -132,6 +148,10 @@ def get_key():
132148 if key in ["q" , "Q" , "\x1b " ]: # Q or ESC
133149 log_info ("Exiting gizmo control loop..." )
134150 sim .disable_gizmo (uid = robot .uid , control_part = control_part )
151+ if robot_solver :
152+ robot .init_solver (
153+ cfg = {control_part : robot_solver .cfg }
154+ ) # Restore original solver
135155 break
136156
137157 # Print robot state
@@ -143,7 +163,14 @@ def get_key():
143163 log_info (f"Joint positions: { current_qpos .squeeze ().tolist ()} " )
144164 log_info (f"End-effector pose:\n { eef_pose .squeeze ().numpy ()} " )
145165
146- # Toggle gizmo visibility
166+ if eef_pose is None :
167+ log_info (
168+ "End-effector pose unavailable: compute_fk returned None "
169+ f"for control part '{ control_part } '."
170+ )
171+ else :
172+ eef_pose_np = eef_pose .detach ().cpu ().numpy ().squeeze ()
173+ log_info (f"End-effector pose:\n { eef_pose_np } " )
147174 elif key in ["g" , "G" ]:
148175 if gizmo_visible :
149176 sim .set_gizmo_visibility (
@@ -181,6 +208,10 @@ def get_key():
181208
182209 except KeyboardInterrupt :
183210 sim .disable_gizmo (uid = robot .uid , control_part = control_part )
211+ if robot_solver :
212+ robot .init_solver (
213+ cfg = {control_part : robot_solver .cfg }
214+ ) # Restore original solver
184215 log_info ("\n Control loop interrupted by user (Ctrl+C)" )
185216
186217 finally :
0 commit comments