YARP  2.3.70.1
Yet Another Robot Platform
The YARP motor control interfaces

When controlling a robot you typically use one of the interfaces from the ControlBoardInterfaces.h header file.

These are meant to abstract a great deal of details but not all of it since we want to retain the possibility of efficient and specialized motor control code.

Motor control.

We take an example of a motor control device since this is simpler to explain than a general controller. The approach itself is completely general though as for other device abstactions in yarp. In particular, the following is an extract of the EsdMotionControl (see EsdMotionControl.h) declaration which wraps the iCub controller:

class yarp::dev::EsdMotionControl :
    public DeviceDriver,
    public IPidControlRaw,
    public IPositionControlRaw,
    public IVelocityControlRaw,
    public IEncodersRaw,
    public IAmplifierControlRaw,
    public IControlDebug,
    public IControlLimitsRaw,
    public ImplementPositionControl<EsdMotionControl, IPositionControl>,
    public ImplementVelocityControl<EsdMotionControl, IVelocityControl>,
    public ImplementPidControl<EsdMotionControl, IPidControl>,
    public ImplementEncoders<EsdMotionControl, IEncoders>,
    public ImplementAmplifierControl<EsdMotionControl, IAmplifierControl>,
    public ImplementControlLimits<EsdMotionControl, IControlLimits>

Beside the confusion here due to the multiplicity of interfaces the important thing to notice is the standard inheritance from DeviceDriver. The controller abstraction assumes:

  • a low-level PID controller, if implemented at all (IPidControl)
  • a position controller (something that takes angular positions and generates appropriate reference trajectories IPositionControl)
  • a velocity controller (to istantaneously specify the angular speed, IVelocityControl)
  • encoders or other positional sensors (IEncoders)
  • an amplifier to power the actuators (IAmplifierControl)

These features are mapped directly onto interfaces. There are "raw" interfaces that speak directly to the control cards and wrapped interfaces that convert and rescale the values before sending them to the control cards. The wrapped interfaces accept angle in degrees, speed in degrees per seconds, etc. The numbering of the axes is also made coherent with respect to the robot kinematics.

The wrapped interfaces are implemented through an "implement" template since the code is likely to be reused in other device drivers: i.e. any control card would perform the same type of mapping. These interfaces use the corresponding "raw" version internally (ControlBoardInterfacesImpl.h).

Robot control is typically effected by:

  • loading the controller/cards default parameters
  • turning the amplifiers on
  • sending control values

when done:

  • turning the amplifiers off
  • closing the device driver (note that the close() unlike the open() method is generic DeviceDriver).

The loading of the controller parameters can be also done from a file by using the Property class and the fromConfigFile() method. This is the preferred method since the list of parameters is fairly large.

For the EsdMotionControl , for example, you find:

[CAN]
CanAddresses 14 13 12 128 128 128 128 128 128 128 128 128 128 128 128 128
CanDeviceNum    0
CanMyAddress    0
CanPollingInterval  2
CanTimeout  20

[GENERAL]
Joints 6
MaxDAC 100.0 100.0 100.0 100.0 100.0 100.0

AxisMap 0 1 2 3 4 5
Encoder 375.46 375.46 1399.46 1399.46 1399.46 1399.46
Zeros 0.0 0.0 0.0 0.0 0.0 0.0

Verbose 0

[LIMITS]
Max 31.9 31.9 30.0 50.0 80.0 45.0
Min -29.29 -29.9 -30.0 -50.0 -80.0 -10.0
Currents 1220.0 1220.0 1220.0 1220.0 1220.0 1220.0

[PIDS]
Pid0 32 128 2 1333 1333 4 0
Pid1 32 128 2 1333 1333 4 0
Pid2 32 128 2 1333 1333 4 0
Pid3 32 128 2 1333 1333 4 0
Pid4 32 128 4 1333 1333 4 0
Pid5 32 128 1 1333 1333 4 0

Some of them are specific to the control card, other are a bit more general. After loading the parameters and opening the device, perhaps through the PolyDriver, you need to:

  • configure the reference values: speed when doing position control or acceleration for velocity control. This is accomplished through the IPositionControl or IVelocityControl respectively. The IEncoders is used to read the positional information back for your own use: e.g. closing another control loop.
  • turn the amplifiers on: this is obtained through the use of the IAmplifierControl.
  • the IPidControl interface allows you to change the gains that have been loaded during open.

All these operations are performed through the wrapped interfaces. The "raw" interfaces are not normally used (they are used internally though). Once you are all set with this part, you can then start moving your axes by issuing commands through the:

  • positionMove()
  • velocityMove()

methods. They come in two flavors, one for single joints and another to move all joints simultaneously. The accuracy of the movement is clearly control card and robot dependent. They assume also that you set the reference speeds and accelerations appropriately.

To finish working with a motion control device, be gentle and reverse the settings you changed (some of them might stay resident in the controller memory). As a last operation before close(), disable the amplifiers so that it becomes safe again to move the robot.