Table of Contents

Implementing a Joint Space Controller

In this exercise you will use standard ROS libraries and interfaces to write a position-resolved joint-space controller for the PR2. This will be genuine low-level controller running in hard realtime on the robot.

For the next couple of tasks, make sure to have understood this tutorial.

Creating the ROS Package

Exporting the Controller as a Controller Plugin

In order to tell the pr2 controller manager that our controller can be loaded and run as a realtime controller we need to register it as a controller plugin. Adapt the example from here to do so, and test if the plugin is visible with

rospack plugins --attrib=plugin pr2_controller_interface

iai_seminar_manipulation_controllers should now be in the list of controllers. Tipp: In case you wonder what the real name of your library is: Look for it after in your /lib dirrectory…

Loading, starting and stopping our Controller Plugin

Just to make sure we have set up everything correctly, let's use the pr2_controller_manager to load, start and stop our (still empty) controller.

$ rosrun pr2_controller_manager pr2_controller_manager list-types
  ...some other controllers...
  iai_seminar_manipulation_controllers/<YourControllerClassName>
  ...some other controllers...
$ rosparam set rosparam set iai_joint_position_controller/type iai_seminar_manipulation_controllers/<YourControllerClassName>
$ rosrun pr2_controller_manager pr2_controller_manager load iai_joint_position_controller
$ rosrun pr2_controller_manager pr2_controller_manager list
$ rosrun pr2_controller_manager pr2_controller_manager start iai_joint_position_controller
$ rosrun pr2_controller_manager pr2_controller_manager list

NOTE: Our controller code is now running on the simulated PR2. Right now, it does not do anything because you haven't filed any code in init(), start(), update(), stop(), yet.

$ rosrun pr2_controller_manager pr2_controller_manager stop iai_joint_position_controller

More examples of how to use the pr2_controller_manager can be found here.

Adding a launch-file

We will now add a launch-file to start our controllers automatically:

For hints, look again here and here.

Implementing the basic init-function

Now, we start implementing the actual controller functionalities. By setting up our controller in the init-phase:

Reporting information from the controller

We want our controller to publish its current state information during every 10th update-call. For that we will use a realtime-publisher from the realtime_tools package because the regular publisher is not thread-safe.

Hint: The documentation of the realtime publisher is here, and we want to use this message type. Also have a look at API of the realtime publisher.

For testing, launch our controller launch-file and start the controllers via the console. Afterwards you can listen to the messages on the topic from the console:

$ rostopic echo r_arm_iai_joint_position_controller/state

Getting a command inside

Our controller should be able to react to external commands. Therefore it shall listen to a topic 'command' in its own namespace. Since we are implementing a realtime process, we need to protect our internal command data structure 'position_command_' from read-write conflicts. A good way to do this is to use a double buffer, guarded by a boost::mutex. A very thorough introduction on double buffers can be found here. Perform your own websearch to find out how to use boost::scoped_locks with a boost::mutex.

$ rostopic pub /l_arm_iai_joint_position_controller/command std_msgs/Float64MultiArray '{data: [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6]}'

Using PIDs

For doing the actual control we will use the PID-controller implementation provided by Willow Garage. The h-file already declares a vector of such controllers.

Filling in start

Now, we will fill the start-hook:

Closing the loop

Finally, we will calculate the actual feedback control:

Using our controller from

TBD.