@@ -135,7 +135,7 @@ def is_controller_loaded(node, controller_manager, controller_name):
135
135
def main (args = None ):
136
136
rclpy .init (args = args , signal_handler_options = SignalHandlerOptions .NO )
137
137
parser = argparse .ArgumentParser ()
138
- parser .add_argument ("controller_name " , help = "Name of the controller " )
138
+ parser .add_argument ("controller_names " , help = "List of controllers" , nargs = "+ " )
139
139
parser .add_argument (
140
140
"-c" ,
141
141
"--controller-manager" ,
@@ -184,10 +184,17 @@ def main(args=None):
184
184
default = 10 ,
185
185
type = int ,
186
186
)
187
+ parser .add_argument (
188
+ "--activate-as-group" ,
189
+ help = "Activates all the parsed controllers list together instead of one by one."
190
+ " Useful for activating all chainable controllers altogether" ,
191
+ action = "store_true" ,
192
+ required = False ,
193
+ )
187
194
188
195
command_line_args = rclpy .utilities .remove_ros_args (args = sys .argv )[1 :]
189
196
args = parser .parse_args (command_line_args )
190
- controller_name = args .controller_name
197
+ controller_names = args .controller_names
191
198
controller_manager_name = args .controller_manager
192
199
controller_namespace = args .namespace
193
200
param_file = args .param_file
@@ -197,11 +204,7 @@ def main(args=None):
197
204
if param_file and not os .path .isfile (param_file ):
198
205
raise FileNotFoundError (errno .ENOENT , os .strerror (errno .ENOENT ), param_file )
199
206
200
- prefixed_controller_name = controller_name
201
- if controller_namespace :
202
- prefixed_controller_name = controller_namespace + "/" + controller_name
203
-
204
- node = Node ("spawner_" + controller_name )
207
+ node = Node ("spawner_" + controller_names [0 ])
205
208
206
209
if not controller_manager_name .startswith ("/" ):
207
210
spawner_namespace = node .get_namespace ()
@@ -219,115 +222,142 @@ def main(args=None):
219
222
)
220
223
return 1
221
224
222
- if is_controller_loaded (node , controller_manager_name , prefixed_controller_name ):
223
- node .get_logger ().warn (
224
- bcolors .WARNING
225
- + "Controller already loaded, skipping load_controller"
226
- + bcolors .ENDC
227
- )
228
- else :
229
- if controller_type :
230
- parameter = Parameter ()
231
- parameter .name = prefixed_controller_name + ".type"
232
- parameter .value = get_parameter_value (string_value = controller_type )
225
+ for controller_name in controller_names :
226
+ prefixed_controller_name = controller_name
227
+ if controller_namespace :
228
+ prefixed_controller_name = controller_namespace + "/" + controller_name
233
229
234
- response = call_set_parameters (
235
- node = node , node_name = controller_manager_name , parameters = [parameter ]
230
+ if is_controller_loaded (node , controller_manager_name , prefixed_controller_name ):
231
+ node .get_logger ().warn (
232
+ bcolors .WARNING
233
+ + "Controller already loaded, skipping load_controller"
234
+ + bcolors .ENDC
236
235
)
237
- assert len (response .results ) == 1
238
- result = response .results [0 ]
239
- if result .successful :
240
- node .get_logger ().info (
241
- bcolors .OKCYAN
242
- + 'Set controller type to "'
243
- + controller_type
244
- + '" for '
245
- + bcolors .BOLD
246
- + prefixed_controller_name
247
- + bcolors .ENDC
236
+ else :
237
+ if controller_type :
238
+ parameter = Parameter ()
239
+ parameter .name = prefixed_controller_name + ".type"
240
+ parameter .value = get_parameter_value (string_value = controller_type )
241
+
242
+ response = call_set_parameters (
243
+ node = node , node_name = controller_manager_name , parameters = [parameter ]
248
244
)
249
- else :
245
+ assert len (response .results ) == 1
246
+ result = response .results [0 ]
247
+ if result .successful :
248
+ node .get_logger ().info (
249
+ bcolors .OKCYAN
250
+ + 'Set controller type to "'
251
+ + controller_type
252
+ + '" for '
253
+ + bcolors .BOLD
254
+ + prefixed_controller_name
255
+ + bcolors .ENDC
256
+ )
257
+ else :
258
+ node .get_logger ().fatal (
259
+ bcolors .FAIL
260
+ + 'Could not set controller type to "'
261
+ + controller_type
262
+ + '" for '
263
+ + bcolors .BOLD
264
+ + prefixed_controller_name
265
+ + bcolors .ENDC
266
+ )
267
+ return 1
268
+
269
+ ret = load_controller (node , controller_manager_name , controller_name )
270
+ if not ret .ok :
250
271
node .get_logger ().fatal (
251
272
bcolors .FAIL
252
- + 'Could not set controller type to "'
253
- + controller_type
254
- + '" for '
273
+ + "Failed loading controller "
255
274
+ bcolors .BOLD
256
275
+ prefixed_controller_name
257
276
+ bcolors .ENDC
258
277
)
259
278
return 1
260
-
261
- ret = load_controller (node , controller_manager_name , controller_name )
262
- if not ret .ok :
263
- node .get_logger ().fatal (
264
- bcolors .FAIL
265
- + "Failed loading controller "
279
+ node .get_logger ().info (
280
+ bcolors .OKBLUE
281
+ + "Loaded "
266
282
+ bcolors .BOLD
267
283
+ prefixed_controller_name
268
284
+ bcolors .ENDC
269
285
)
270
- return 1
271
- node .get_logger ().info (
272
- bcolors .OKBLUE + "Loaded " + bcolors .BOLD + prefixed_controller_name + bcolors .ENDC
273
- )
274
286
275
- if param_file :
276
- # load_parameter_file writes to stdout/stderr. Here we capture that and use node logging instead
277
- with redirect_stdout (io .StringIO ()) as f_stdout , redirect_stderr (
278
- io .StringIO ()
279
- ) as f_stderr :
280
- load_parameter_file (
281
- node = node ,
282
- node_name = prefixed_controller_name ,
283
- parameter_file = param_file ,
284
- use_wildcard = True ,
287
+ if param_file :
288
+ # load_parameter_file writes to stdout/stderr. Here we capture that and use node logging instead
289
+ with redirect_stdout (io .StringIO ()) as f_stdout , redirect_stderr (
290
+ io .StringIO ()
291
+ ) as f_stderr :
292
+ load_parameter_file (
293
+ node = node ,
294
+ node_name = prefixed_controller_name ,
295
+ parameter_file = param_file ,
296
+ use_wildcard = True ,
297
+ )
298
+ if f_stdout .getvalue ():
299
+ node .get_logger ().info (bcolors .OKCYAN + f_stdout .getvalue () + bcolors .ENDC )
300
+ if f_stderr .getvalue ():
301
+ node .get_logger ().error (bcolors .FAIL + f_stderr .getvalue () + bcolors .ENDC )
302
+ node .get_logger ().info (
303
+ bcolors .OKCYAN
304
+ + 'Loaded parameters file "'
305
+ + param_file
306
+ + '" for '
307
+ + bcolors .BOLD
308
+ + prefixed_controller_name
309
+ + bcolors .ENDC
285
310
)
286
- if f_stdout .getvalue ():
287
- node .get_logger ().info (bcolors .OKCYAN + f_stdout .getvalue () + bcolors .ENDC )
288
- if f_stderr .getvalue ():
289
- node .get_logger ().error (bcolors .FAIL + f_stderr .getvalue () + bcolors .ENDC )
290
- node .get_logger ().info (
291
- bcolors .OKCYAN
292
- + 'Loaded parameters file "'
293
- + param_file
294
- + '" for '
295
- + bcolors .BOLD
296
- + prefixed_controller_name
297
- + bcolors .ENDC
298
- )
299
- # TODO(destogl): use return value when upstream return value is merged
300
- # ret =
301
- # if ret.returncode != 0:
302
- # Error message printed by ros2 param
303
- # return ret.returncode
304
- node .get_logger ().info ("Loaded " + param_file + " into " + prefixed_controller_name )
305
-
306
- if not args .load_only :
307
- ret = configure_controller (node , controller_manager_name , controller_name )
308
- if not ret .ok :
309
- node .get_logger ().error (
310
- bcolors .FAIL + "Failed to configure controller" + bcolors .ENDC
311
+ # TODO(destogl): use return value when upstream return value is merged
312
+ # ret =
313
+ # if ret.returncode != 0:
314
+ # Error message printed by ros2 param
315
+ # return ret.returncode
316
+ node .get_logger ().info (
317
+ "Loaded " + param_file + " into " + prefixed_controller_name
311
318
)
312
- return 1
313
319
314
- if not args .inactive :
315
- ret = switch_controllers (
316
- node , controller_manager_name , [], [controller_name ], True , True , 5.0
317
- )
320
+ if not args .load_only :
321
+ ret = configure_controller (node , controller_manager_name , controller_name )
318
322
if not ret .ok :
319
323
node .get_logger ().error (
320
- bcolors .FAIL + "Failed to activate controller" + bcolors .ENDC
324
+ bcolors .FAIL + "Failed to configure controller" + bcolors .ENDC
321
325
)
322
326
return 1
323
327
324
- node .get_logger ().info (
325
- bcolors .OKGREEN
326
- + "Configured and activated "
327
- + bcolors .BOLD
328
- + prefixed_controller_name
329
- + bcolors .ENDC
328
+ if not args .inactive and not args .activate_as_group :
329
+ ret = switch_controllers (
330
+ node , controller_manager_name , [], [controller_name ], True , True , 5.0
331
+ )
332
+ if not ret .ok :
333
+ node .get_logger ().error (
334
+ bcolors .FAIL + "Failed to activate controller" + bcolors .ENDC
335
+ )
336
+ return 1
337
+
338
+ node .get_logger ().info (
339
+ bcolors .OKGREEN
340
+ + "Configured and activated "
341
+ + bcolors .BOLD
342
+ + prefixed_controller_name
343
+ + bcolors .ENDC
344
+ )
345
+
346
+ if not args .inactive and args .activate_as_group :
347
+ ret = switch_controllers (
348
+ node , controller_manager_name , [], controller_names , True , True , 5.0
349
+ )
350
+ if not ret .ok :
351
+ node .get_logger ().error (
352
+ bcolors .FAIL + "Failed to activate the parsed controllers list" + bcolors .ENDC
330
353
)
354
+ return 1
355
+
356
+ node .get_logger ().info (
357
+ bcolors .OKGREEN
358
+ + "Configured and activated all the parsed controllers list!"
359
+ + bcolors .ENDC
360
+ )
331
361
332
362
if not args .unload_on_kill :
333
363
return 0
@@ -339,8 +369,9 @@ def main(args=None):
339
369
except KeyboardInterrupt :
340
370
if not args .inactive :
341
371
node .get_logger ().info ("Interrupt captured, deactivating and unloading controller" )
372
+ # TODO(saikishor) we might have an issue in future, if any of these controllers is in chained mode
342
373
ret = switch_controllers (
343
- node , controller_manager_name , [ controller_name ] , [], True , True , 5.0
374
+ node , controller_manager_name , controller_names , [], True , True , 5.0
344
375
)
345
376
if not ret .ok :
346
377
node .get_logger ().error (
0 commit comments