50
50
TIMEOUT_WAIT_SERVICE_INITIAL = 60
51
51
TIMEOUT_WAIT_ACTION = 10
52
52
53
- MOTION_CONTROLLERS = ["passthrough_trajectory_controller" , "scaled_joint_trajectory_controller" ]
53
+ # Only one of these can be active at any given time
54
+ MOTION_CONTROLLERS = [
55
+ "passthrough_trajectory_controller" ,
56
+ "scaled_joint_trajectory_controller" ,
57
+ "joint_trajectory_controller" ,
58
+ "freedrive_mode_controller" ,
59
+ ]
60
+
54
61
55
62
ROBOT_JOINTS = [
56
63
"shoulder_pan_joint" ,
60
67
"wrist_2_joint" ,
61
68
"wrist_3_joint" ,
62
69
]
70
+
63
71
Action_tuple = namedtuple ("Actions" , ["name" , "action_type" ])
64
72
65
73
66
74
class Actions (Enum ):
75
+ JTC = Action_tuple (
76
+ "/joint_trajectory_controller/follow_joint_trajectory" , FollowJointTrajectory
77
+ )
78
+
67
79
PASSTHROUGH_TRAJECTORY = Action_tuple (
68
80
"/passthrough_trajectory_controller/follow_joint_trajectory" , FollowJointTrajectory
69
81
)
@@ -114,9 +126,10 @@ class Robot:
114
126
def __init__ (self , node ):
115
127
self .node = node
116
128
self .init_robot ()
129
+ self .HOME = [0.0 , - 1.5708 , 0.0 , - 1.5708 , 0.0 , 0.0 ]
117
130
118
131
def init_robot (self ):
119
-
132
+ self . joints = ROBOT_JOINTS
120
133
self .service_clients = {
121
134
service .name : waitForService (self .node , service .value .name , service .value .service_type )
122
135
for (service ) in Services
@@ -151,14 +164,7 @@ def set_io(self, pin, value):
151
164
152
165
def follow_trajectory (self , waypts : list [list [float ]], time_vec : list [float ]):
153
166
# No other motion controllers can be active at the same time as the scaled joint controller
154
- self .switch_controllers (
155
- ["scaled_joint_trajectory_controller" ],
156
- [
157
- "passthrough_trajectory_controller" ,
158
- "force_mode_controller" ,
159
- "freedrive_mode_controller" ,
160
- ],
161
- )
167
+ self .switch_motion_controller ("scaled_joint_trajectory_controller" )
162
168
"""Send robot trajectory."""
163
169
if len (waypts ) != len (time_vec ):
164
170
raise Exception ("waypoints vector and time vec should be same length" )
@@ -193,9 +199,7 @@ def passthrough_trajectory(
193
199
goal_time_tolerance = Duration (sec = 1 ),
194
200
):
195
201
# The scaled joint controller can't be active at the same time as the passthrough controller
196
- self .switch_controllers (
197
- ["passthrough_trajectory_controller" ], ["scaled_joint_trajectory_controller" ]
198
- )
202
+ self .switch_motion_controller ("passthrough_trajectory_controller" )
199
203
"""Send trajectory through the passthrough controller."""
200
204
if len (waypts ) != len (time_vec ):
201
205
raise Exception ("waypoints vector and time vec should be same length." )
@@ -231,8 +235,8 @@ def call_service(self, Service: Services, request):
231
235
else :
232
236
raise Exception (f"Exception while calling service: { future .exception ()} " )
233
237
234
- def call_action (self , Action : Actions , g ):
235
- future = self .action_clients [Action .name ].send_goal_async (g )
238
+ def call_action (self , Action : Actions , goal ):
239
+ future = self .action_clients [Action .name ].send_goal_async (goal )
236
240
rclpy .spin_until_future_complete (self .node , future )
237
241
238
242
if future .result () is not None :
@@ -248,10 +252,14 @@ def get_result(self, Action: Actions, goal_response):
248
252
else :
249
253
raise Exception (f"Exception while calling action: { future_res .exception ()} " )
250
254
251
- def load_controller (self , controller_name : str ):
255
+ def list_controllers (self ):
252
256
list_response = self .call_service (Services .List_Controllers , ListControllers .Request ())
253
- names = []
257
+ return list_response
258
+
259
+ def load_controller (self , controller_name : str ):
260
+ list_response = self .list_controllers ()
254
261
# Find loaded controllers
262
+ names = []
255
263
for controller in list_response .controller :
256
264
names .append (controller .name )
257
265
# Check whether the controller is already loaded
@@ -263,7 +271,7 @@ def load_controller(self, controller_name: str):
263
271
self .call_service (Services .Load_Controller , load_request )
264
272
configure_request = ConfigureController .Request (name = controller_name )
265
273
self .call_service (Services .Configure_Controller , configure_request )
266
- list_response = self .call_service ( Services . List_Controllers , ListControllers . Request () )
274
+ list_response = self .list_controllers ( )
267
275
names .clear ()
268
276
# Update the list of controller names.
269
277
for controller in list_response .controller :
@@ -273,17 +281,33 @@ def load_controller(self, controller_name: str):
273
281
finally :
274
282
print (f"Currently loaded controllers: { names } " )
275
283
276
- def switch_controllers (self , active : list [str ] = [], inactive : list [str ] = []) -> bool :
284
+ def switch_controllers (self , activate : list [str ] = [], deactivate : list [str ] = []) -> bool :
285
+ controllers = self .list_controllers ()
286
+ activate_ = []
287
+ deactivate_ = []
288
+ for controller in controllers .controller :
289
+ if controller .name in activate and controller .state == "inactive" :
290
+ activate_ .append (controller .name )
291
+ elif controller .name in deactivate and controller .state == "active" :
292
+ deactivate_ .append (controller .name )
293
+
277
294
switch_request = SwitchController .Request ()
278
- switch_request .activate_controllers = active
279
- switch_request .deactivate_controllers = inactive
295
+ switch_request .activate_controllers = activate_
296
+ switch_request .deactivate_controllers = deactivate_
280
297
switch_request .strictness = (
281
298
SwitchController .Request .BEST_EFFORT
282
299
) # Best effort switching, will not terminate program if controller is already running
283
300
switch_request .activate_asap = False
284
301
switch_request .timeout = Duration (sec = 2 , nanosec = 0 )
285
302
return self .call_service (Services .Switch_Controller , switch_request )
286
303
304
+ def switch_motion_controller (self , motion_controller : str ):
305
+ if motion_controller not in MOTION_CONTROLLERS :
306
+ print ("Requested motion controller does not exist." )
307
+ return self .switch_controllers (
308
+ [motion_controller ], [i for i in MOTION_CONTROLLERS if motion_controller not in i ]
309
+ )
310
+
287
311
def start_force_mode (self , req : SetForceMode .Request ):
288
312
return self .call_service (Services .start_force_mode , req )
289
313
0 commit comments