Late last week I found out almost by
chance about the yet undocumented ros_control [1] repository, which deferred the
writing of this email a day so I could familiarize with it. Its scope is very much
aligned with my current objectives, as it consists of a library offering functionality
similar to that of the pr2_controller_manager that can be adapted to other robot
platforms. I'm looking forward to sharing opinions and use cases with all interested
parties, and if possible map interest overlaps to common code. Some questions that come
to my mind after reviewing the code in [1]:


Hey Herman,

Just to be clear, the questions in the below list are things I am expecting from a controller manager implementation, but don't seem to be supported by [1]. Unless convinced otherwise, I'd like an implementation that allows you to do such things. The proposal attached in the original post does allow them.

- Is it possible to have a controller with multiple interfaces (eg. send position +
velocity + effort commands)?.

It is, in my opinion, not a matter of asking whether it _is_ possible:
this_should_ be possible!  But in this context I have also learned that the
mainstream software development in robotics is all about writing software
libraries with C++ code, while quite some other successful domains "out
there" don't write code, but generate it from models. Especially in the
context of this message: industrial control practice uses Simulink, 20Sim,
LabView or Modelica _models_, and _tools_ to generate the code. This helps
a lot in avoiding the problem of hand-writing APIs that support _all
possible_ relevant combinations of robot control capabilities; the latter
is just not maintainable. (I see the same problem occurring in our KDL
library, in the context of kinematics and dynamics algorithms.)


- If I understand correctly, interfaces are limited by design to position, velocity and
effort, and adding a new one (fancy example: stiffness) is not possible, correct?.

Why not? Stiffness control is (on any robot platform) a "layer" around the
real hardware actuator control.


- Is it possible to chain controllers as in the attached figure
(r_arm_follow_joint_traj + r_arm_pid_controller) from configuration files, ie. without
writing code?.

In the "Model Driven Engineering" approach it is; in the "class library
API" world it is a lot more difficult. Your "configuration file" is
basically a "model in disguise" :-) So, it makes more sense to make that
model explicit, and agree on that first.

In many orocos applications that support motion control, people have made
the error to deploy the kind of architecture that you have in your drawing
("sinks" and "sources" connected via "topic" data flows) one on one on an
Orocos "TaskContext" component design, which is _very_ inefficient.
Since ages already, industry deploys such architectures into one single
thread or process, as different functions that access the "topics" as
shared memory; this is alot more efficient, especially since the
computations in the "components" are very simple, but a lot of data has to
be streamed around all the time. In addition, the Simulink, Modelica or
20Sim tools do the code generation from your kind of "model" to such
single-thread computations for you.

I picture the controller manager as being mostly single-threaded, where clients are explicitly serialized in the manager's update cycle (using slave activities in Orocos speak). This is in fact what I have now. An example of where I'd like to have a separate thread is a joint_states publisher, a sink-only client that publishes information like joint positions and velocities at a lower frequency. I dislike bringing down the update frequency of some module with code like:

void update()
{
  if (count % 10 == 0) // Eyes start bleeding
  {
    // Do stuff
  }
  ++count;
}

So, having most clients serialized for performance, and a few exceptions spinning separate threads seems reasonable to me. I'm open to alternative solutions, though.

The solution proposed in [1] (see original post for link) uses a plugin mechanism for implementing controllers, which enforces single-threaded execution and passing data by pointers. It just does not allow the use case of clients running with different update policies (lower frequency, non-periodic triggering). How would you go about this?. As Johnny 5 would say: iiiiinput ;-)


Another way of looking at this problem is as follows: ROS/Orocos "force"
developers to thing in the "component based" design paradigm in which all
computations are in (hidden in) components and the data is flowing around in "publish/subscribe" topics; however,
control functionalities have, since ages too already, best been done in a
"functional programming" paradigm, where the data are shared, never copied, and certainly
not streamed around between computations.

When different tasks are serialized in a single thread, connection policies that don't handle concurrency can be used. In such cases data can be passed around as pointers or references. Unfortunately ROS and Orocos don't yet do this for you. You could do it in the manager, though, the information is there.


- Controllers running at lower frequency than the manager need to implement this by
doing work only one out of every n cycles, as separate controller threads are not
supported, correct?.

This is something that the _software component platform_ infrastructure has to solve;
please, let's not bring in this complexity at the _software application
platform_ level. (Although in ROS or Orocos it is not so clear where one
stops and the other starts...)


- Is there any work on decoupling the more common "workhorse" controllers out of the
pr2_controller_manager infrastructure (eg. a couple of mobile base implementations, the
FollowJointTrtajectory action)?. I've already spent some time factoring out the spline
splicing and interpolation code from the FollowJointTrtajectory action, and was
planning on writing some unit tests on it. If not, I can also make this available once
the cleanup is complete.
 
That's it for now, thanks for reading.

Thanks for your nice preparation! My summary: the ROS/Orocos worlds are not
providing the right tools, concepts and primitives for doing efficient and
advanced (realtime) motion control for robots.

One further disclaimer: I'm aiming at having a prototype controller manager in about six weeks, so I'm trying to make the best possible compromise between what's already out there and what can be done in such a time frame. I won't achieve peace on earth, but hopefully a solid step in the right direction.

Cheers,

Adolfo.


[1] https://github.com/willowgarage/ros_control

--
Adolfo Rodríguez Tsouroukdissian

Herman