https://github.com/ros-controls/ros_control
Raw File
Tip revision: daa7f5c9d011b401111f564bd4e422b3fc42dd8f authored by Adolfo Rodriguez Tsouroukdissian on 17 August 2015, 15:47:37 UTC
Extend test suite to exercise per-controller update periods
Tip revision: daa7f5c
mainpage.dox
/**
\mainpage
\htmlinclude manifest.html

transmission_interface contains data structures for representing mechanical transmissions, and methods for
propagating position, velocity and effort variables between actuator and joint spaces.

In the same spirit as the \b hardware_interface package, this package wraps existing raw data (eg. current actuator
position, reference joint command, etc.) under a consistent interface. By not imposing a specific layout on the raw data,
it becomes easier to support arbitrary hardware drivers to software control.

The transmission_interface is \e not used by controllers themselves (it does not implement a \p HardwareInterface) but instead operates before or after the controllers update, in the \p read() and \p write() methods (or equivalents) of the robot abstraction.

\section codeapi Code API

There are three main elements involved in setting up a transmission_interface:
  - The \ref transmission_interface::Transmission "Transmission" class defines an abstract interface for mapping
  position, velocity and effort variables between actuator and joint space.
  Derived classes implement specific \ref transmission_types "transmission types" such as
  \ref transmission_interface::SimpleTransmission "simple reducers",
  \ref transmission_interface::DifferentialTransmission "differentials" or
  \ref transmission_interface::FourBarLinkageTransmission "four-bar linkages".
  Note that a single transmission may couple the variables of multiple actuators and joints (eg. a differential couples
  two actuators to two joints).

  - The \ref transmission_interface::TransmissionHandle "TransmissionHandle" class associates a name to a
  \ref transmission_interface::Transmission "Transmission" instance and a set of raw data variables
  it operates on (specified through the \ref transmission_interface::ActuatorData "ActuatorData" and
  \ref transmission_interface::JointData "JointData" structures).
  Derived classes implement specific maps, such as
  \ref transmission_interface::JointToActuatorEffortHandle "JointToActuatorEffortHandle" or
  \ref transmission_interface::ActuatorToJointStateHandle "ActuatorToJointStateHandle".

  - The \ref transmission_interface::TransmissionInterface "TransmissionInterface<HandleType>" class manages
  a set of transmission handles of the same type.
  Note that although the handles are of the same type, the underlying transmissions can be heterogeneous
  eg. a single \ref transmission_interface::ActuatorToJointPositionInterface "ActuatorToJointPositionInterface" can be
  set up to transform position variables from actuator to joint space for an arm with a four-bar-linkage in the
  shoulder, a differential in the wrist, and simple reducers elsewhere.

\section example Examples

The first example is minimal, and shows how to propagate the position of a single actuator to joint space through
a reducer.

\code

#include <transmission_interface/simple_transmission.h>
#include <transmission_interface/transmission_interface.h>

int main(int argc, char** argv)
{
  using namespace transmission_interface;

  // Raw data
  double a_pos;
  double j_pos;

  // Transmission
  SimpleTransmission trans(10.0); // 10x reducer

  // Wrap raw data
  ActuatorData a_data;
  a_data.position.push_back(&a_pos);

  JointData j_data;
  j_data.position.push_back(&j_pos);

  // Transmission interface
  ActuatorToJointPositionInterface act_to_jnt_pos;
  act_to_jnt_pos.registerHandle(ActuatorToJointPositionHandle("trans", &trans, a_data, j_data));

  // Propagate actuator position to joint space
  act_to_jnt_pos.propagate();
}
\endcode

The second example is a bit more complicated, and represents a robot with three actuators and three joints:
  - The first actuator/joint are coupled through a reducer.
  - The last two actuators/joints are coupled through a differential.

The hardware is such that one can read current actuator position, velocity and effort, and send position commands.

\code
#include <vector>

#include <transmission_interface/simple_transmission.h>
#include <transmission_interface/differential_transmission.h>
#include <transmission_interface/transmission_interface.h>

using std::vector;
using namespace transmission_interface;

class MyRobot
{
public:
  MyRobot()
   : sim_trans(-10.0,  // 10x reducer. Negative sign: actuator and joint spin in opposite directions
                 1.0), // joint position offset

     dif_trans(vector<double>(2, 5.0), // 5x reducer on each actuator
               vector<double>(2, 1.0)) // No reducer in joint output
  {
    // Wrapping the raw data is the most verbose part of the setup process... //////////////////////////////////////////

    // Wrap simple transmission raw data - current state
    a_state_data[0].position.push_back(&a_curr_pos[0]);
    a_state_data[0].velocity.push_back(&a_curr_vel[0]);
    a_state_data[0].effort.push_back(&a_curr_eff[0]);

    j_state_data[0].position.push_back(&j_curr_pos[0]);
    j_state_data[0].velocity.push_back(&j_curr_vel[0]);
    j_state_data[0].effort.push_back(&j_curr_eff[0]);

    // Wrap simple transmission raw data - position command
    a_cmd_data[0].position.push_back(&a_cmd_pos[0]); // Velocity and effort vectors are unused

    j_cmd_data[0].position.push_back(&j_cmd_pos[0]); // Velocity and effort vectors are unused

    // Wrap differential transmission raw data - current state
    a_state_data[1].position.push_back(&a_curr_pos[1]); a_state_data[1].position.push_back(&a_curr_pos[2]);
    a_state_data[1].velocity.push_back(&a_curr_vel[1]); a_state_data[1].velocity.push_back(&a_curr_vel[2]);
    a_state_data[1].effort.push_back(&a_curr_eff[1]);   a_state_data[1].effort.push_back(&a_curr_eff[2]);

    j_state_data[1].position.push_back(&j_curr_pos[1]); j_state_data[1].position.push_back(&j_curr_pos[2]);
    j_state_data[1].velocity.push_back(&j_curr_vel[1]); j_state_data[1].velocity.push_back(&j_curr_vel[2]);
    j_state_data[1].effort.push_back(&j_curr_eff[1]);   j_state_data[1].effort.push_back(&j_curr_eff[2]);

    // Wrap differential transmission raw data - position command
    a_cmd_data[1].position.push_back(&a_cmd_pos[1]); a_cmd_data[1].position.push_back(&a_cmd_pos[2]);

    j_cmd_data[1].position.push_back(&j_cmd_pos[1]); j_cmd_data[1].position.push_back(&j_cmd_pos[2]);

    // ...once the raw data has been wrapped, the rest is straightforward //////////////////////////////////////////////

    // Register transmissions to each interface
    act_to_jnt_state.registerHandle(ActuatorToJointStateHandle("sim_trans",
                                                               &sim_trans,
                                                               a_state_data[0],
                                                               j_state_data[0]));

    act_to_jnt_state.registerHandle(ActuatorToJointStateHandle("dif_trans",
                                                              &dif_trans,
                                                              a_state_data[1],
                                                              j_state_data[1]));

    jnt_to_act_pos.registerHandle(JointToActuatorPositionHandle("sim_trans",
                                                                &sim_trans,
                                                                a_cmd_data[0],
                                                                j_cmd_data[0]));

    jnt_to_act_pos.registerHandle(JointToActuatorPositionHandle("dif_trans",
                                                                &dif_trans,
                                                                a_cmd_data[1],
                                                                j_cmd_data[1]));

    // Names must be unique within a single transmission interface, but a same name can be used in
    // multiple interfaces, as shown above
  }

  void read()
  {
    // Read actuator state from hardware
    // ...

    // Propagate current actuator state to joints
    act_to_jnt_state.propagate();
  }

  void write()
  {
    // Propagate joint commands to actuators
    jnt_to_act_pos.propagate();

    // Send actuator command to hardware
    // ...
  }

private:

  // Transmission interfaces
  ActuatorToJointStateInterface    act_to_jnt_state; // For propagating current actuator state to joint space
  JointToActuatorPositionInterface jnt_to_act_pos;   // For propagating joint position commands to actuator space

  // Transmissions
  SimpleTransmission       sim_trans;
  DifferentialTransmission dif_trans;

  // Actuator and joint space variables: wrappers around raw data
  ActuatorData a_state_data[2]; // Size 2: One per transmission
  ActuatorData a_cmd_data[2];

  JointData j_state_data[2];
  JointData j_cmd_data[2];

  // Actuator and joint space variables - raw data:
  // The first actuator/joint are coupled through a reducer.
  // The last two actuators/joints are coupled through a differential.
  double a_curr_pos[3]; // Size 3: One per actuator
  double a_curr_vel[3];
  double a_curr_eff[3];
  double a_cmd_pos[3];

  double j_curr_pos[3]; // Size 3: One per joint
  double j_curr_vel[3];
  double j_curr_eff[3];
  double j_cmd_pos[3];
};
\endcode

*/
back to top