ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
4

Using Controller Manager and getting it to work.

asked 2014-01-19 01:20:54 -0500

updated 2014-01-28 17:19:05 -0500

ngrennan gravatar image

Hi all

I'm trying to get a controller to run in a ros_control controller manager and followed the general principles listed on the ros_control git wiki.

Now in the controller manager runs in a non-realtime loop .

The controller init routine runs and completes successfully, however, no further starting(), stopping(), or update routines get run().

At various times, I have adjusted the interface setup on the controller to open some custom interfaces, and usually they cause the init() to fail (but with out any warnings that it will or does)

EDIT Here is the loggers for the controller manager program when rosservice /controller_manager/list_controllers is called: <since removed="">

ANSWER If you aren't interested in following the comment thread attached to adolfo's answer, the problem was summed up by: 1. Not understanding how the controller manager started and stopped controllers. 2. Getting the services on the controller manager to work.

  1. The controller manager has no exposed start or stop routine or service. Instead the user has to use switch_controllers(startcontroller, stopcontroller, strictness). or the equivalent service. To use a controller, it must first be loaded by the controller_manager, using load_controller(controller), and then started. To perform a start of a newly loaded controller, the switch_controllers() routine is used with an empty field for the stopcontroller. Strictness has value of 1 (accepts errors) or 2 (switch must be perfect (STRICT)). The service call is:

    rosservice call /controller_manager/switch_controllers [starting_controller_name] [stopping_controller_name] 1

  2. If you find that the controller_manager is not processing the service calls but instead 'freezes' then your hardware implementation program is not effectively dealing with the callbacks of the controller_manager (and possibly your controller)

It was found that a specific ros::callbackqueue needed to be established for the implementation's nodehandle using nodehandle::setCallbackQueue(). It was found that an AsyncSpinner was required to work on that queue, using the ros::AsyncSpinner spinner(0, &my_callback_queue); This allowed the spinner to explicitly work on the callbacks passed to the nodehandle. As this nodehandle was passed to the controller manager, the controller manager service callbacks were also pushed onto this queue. This link details the different ways of dealing with callbacks and spinners. Section 4 covers the details of the method that worked.

Thanks to Adolfo for his perserverence and help in resolving this matter.

edit retag flag offensive close merge delete

Comments

looking through controller_manager/controller_manager.cpp, I cant see where the cm is starting the controllers. in ControllerManager::loadcontroller(). The init routine is run, but the cm does not go on to start the controllers. The update() only seems to apply to those that are running.

PeterMilani gravatar image PeterMilani  ( 2014-01-19 15:40:49 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
4

answered 2014-01-19 21:50:19 -0500

Adolfo Rodriguez T gravatar image

When the controller manager loads a controller, it is in the stopped state. You need to explicitly start it to transition to a running state. You can check a controller's state by calling /controller_manager/list_controllers

This the usual flow:

Load a controller: Use the /controller_manager/load_controller service

  • Precondition: Controller config loaded in the ROS param server.
  • Effect: Calls the controller's init(...) method.
  • Postcondition: Controller is loaded, but stopped.

Start a controller: Use the /controller_manager/switch_controller service (start_controllers field)

  • Precondition: Controller already loaded and stopped. Resources to claim are available.
  • Effect: Calls the controller's starting(...) method
  • Postcondition: Running controller.

Stop a controller: Use the /controller_manager/switch_controller service (stop_controllers field)

  • Precondition: Controller is running.
  • Effect: Calls the controller's stopping(...) method
  • Postcondition: Stopped (but still loaded) controller.

Unload a controller: Use the /controller_manager/load_controller service

  • Precondition: Controller is stopped.
  • Effect: Calls controller destructor.
  • Postcondition: Controller no longer managed by the controller_manager.
edit flag offensive delete link more

Comments

I thought it was unusual that there would be no provided way for starting the controllers. the srv /../list_controllers returns the running controller. However When I apply a switch service the cm crashes. The switch is: rosservice call /controller_maner/switch_controller [] [hmmv4_controller] 2

PeterMilani gravatar image PeterMilani  ( 2014-01-20 00:05:58 -0500 )edit

Peter, 1. When list_controllers returns a running controller, did you start it with the switch_controller service or with your loadController() modification?. 2. What is the backtrace of your crash?. 3. The switch_controller call you paste above is for stopping hmmv4_controller, is this the intent?.

Adolfo Rodriguez T gravatar image Adolfo Rodriguez T  ( 2014-01-20 21:55:04 -0500 )edit

1. yes To see the controller running i need to use the modified code. when using the standard code, a call to /list_controllers freezes with no response. 2. There is no back trace just an empty frozen cursor. The controller is loaded in code with cm.loadController("hmmv4_controller"). 3.Yes

PeterMilani gravatar image PeterMilani  ( 2014-01-20 23:13:38 -0500 )edit

When using rqt_consol to query loggers produces the same effect. The Debug Log indicates a Connection::drop(2) after a after rosservice wants a new connection to /set_logger_levels. The TCP connection Terminates. Pubs and Subs work fine though, as srv does when a controller is running

PeterMilani gravatar image PeterMilani  ( 2014-01-20 23:18:55 -0500 )edit

Could you try starting your controller using the switch_controller service and an _unmodified_ controller_manager?. Also, if you want to load+start a controller in a single call, consider using the spawner script of the controller_manager package.

Adolfo Rodriguez T gravatar image Adolfo Rodriguez T  ( 2014-01-20 23:46:08 -0500 )edit

Reverted to the original code, and displayed the log output from the controller manager (earliest last) when /list_controllers is called. The socket is recieving 0/4 bytes and is closing. Note it works when controller is already running with the modified code, so the network setup should be okay.

PeterMilani gravatar image PeterMilani  ( 2014-01-21 00:55:51 -0500 )edit

Does list_controllers work when your controller is not loaded, or when other existing controllers are loaded/running?.

Adolfo Rodriguez T gravatar image Adolfo Rodriguez T  ( 2014-01-21 03:28:45 -0500 )edit

With the controller not loaded, list_controllers freezes, with it loaded, list_controllers freezes, with it running, list_controllers returns the controller is running. By the way, roswtf returns no errors relating to comms. When frozen, roswtf reports everything ok, rossrv list still works.

PeterMilani gravatar image PeterMilani  ( 2014-01-22 00:46:56 -0500 )edit

Question Tools

2 followers

Stats

Asked: 2014-01-19 01:20:54 -0500

Seen: 6,610 times

Last updated: Jan 22 '14