Is "Twist" (still) a good velocity command interface

I believe that Alison’s breakdown identifies the key points in this discussion.

From this I’m seeing three different things that need to be expressed. First there’s an abstract description of a motion, second is a concrete description of the motion and the third is the constraints for the motion. I believe that all three of them need independent representation.

And I agree with @Ingo_Lutkebohle that we’re talking about the interface between the high level controller with a generalized sensor of a vehicle and the low level controller which is going to be executing the actions.

The Twist message on the cmd_vel topics has been our abstract representation of the desired movement of the vehicle. The twist message has the ability to represent arbitrary fixed body motions but no vehicle is capable of expressing arbitrary fixed body motions they are all subject to certain constraints.

Most current implementations of lower level controllers take in the abstract command and then project it down onto the envelope that they can achieve. For example something like a diff drive controller typically just ignores any y or z velocities and non-z rotations.

The abstract representation of the commands are very powerful as we can have many different tools that can interact. All the different planners can have the same output, there are many safety functionalities that do things like limit velocities and accelerations, as well as things like the joystick controllers and tools to mux different inputs with different policies for teleoperation from a joystick or other remote controller.

At the other end once we’re inside the differential drive controller or ackermann etc clearly things need to operate with representations that map onto the actual actuators. Historically this has been internal to the controller but as ROS gets pushed to lower level computation providing an abstraction at this level becomes more valuable.

I think that the drone community has a good model for this that we can leverage to improve our abstraction. They have a architectural component called a mixer that is where they do the mapping from the abstract commands to the concrete commands. All representations before the mixer are abstracted away from the hardware. And the mixer then supports converting to hardware specific commands. This approach allows you to switch airframes and you just have to match your mixer settings to the hardware and the same autopilot can fly.

This works across multiple airframe types with different numbers of rotors etc. This same architecture works for planes and copters. Clearly the vehicles have different envelopes. And the mappings go to completely different actuators, servos for ailerons vs motor controllers for propellers. Planes vs drones have similarly different envelopes as ackermann vs holonomic bases.

The reason this works for both is that the planners output the same type of message but with completely different constraints. So now we need to make sure that our constraints are met. It would be possible for us to push the more concrete types further up the stack to make sure that every planner will output only valid commands for the hardware implementation. However this will mean that every planner needs to be customized for every potential hardware type. This is both expensive in terms of parallel implementations but also still does not actually communicate the appropriate constraints to the planner. Our basic drives types are straight forward, but once you start trying to list all possible ones it gets infeasible. Diff drive, holonomic, powered caster (pseudo holonomic like pr2, with 12 independent actuators), front powered caster, Ackermann, double Ackermann, skid steer/tank drive, center articulated.

Capturing all of the potential variations gets even more challenging when you think about the subtleties such as powered casters that may or may not be able to do continuous rotation, steering limits, individual actuator speed limits, suspension parameters such as toe in for Ackermann or compensation for the slip angle. For arbitrary hardware configurations there’s an arbitrary number of constraints that might need to be applied in addition to just picking the high level geometric type of the drive unit. And some vehicles may use hybrids of the above options etc. And we’re not even getting into the possibility of legged locomotion.

To that end what the planners really care about is constraints that they can feed back into their optimizations. And I think that creating a standard way for this to be parameterized by the hardware implementation and then feed into the planner would make the most sense. This is clearly a whole new area that there has not been a lot of discussion on but I think that this would be valuable to develop a good abstraction of this that could keep our planners generalized and support arbitrary vehicle architectures in a more standardized way.

The constraints could even be setup to be dynamically updated as a vehicle experiences system degradation or is reconfigured (like a tilt rotor). For this initial scope I would suggest limiting this to the local planners that are focused on immediate execution and not high level planners that are producing full trajectories through time etc. These are the same controllers that already produce Twists on cmd_vel topics. There are likely separate constraints representations at that higher level that could be expressed too.

As a first pass simply putting in limits on velocity, acceleration, (optional jerk and snap) in each dimension would seem to be a reasonable first step towards a potential message along these lines. If this makes sense we can iterate on making a new message to represent this.

So in summary my suggestion is to consider planning to work towards the following structure.

out
source

This will keep the twist as the abstract interface. And when it’s applicable we can split the mixer functionality away from the actuator functionality and provide common messages for classes of vehicles such as diff drive, ackermann or otherwise. And we look at adding a new message to support communicating the constraints back to the controller. These constraints are likely currently either implicity in the controllers or captured in parameters or other settings. If this makes sense we could consider moving this over to a REP proposal.

The abstraction proposed in REP 147 actually does this at the slightly higher level of acceleration and might be a good reference model for specifying the abstraction.

6 Likes