Software Design

Servo Clock

To maximize the number of ways the servo thread can be instantiated (e.g., via ROS::Timer, std::chrono::high_resolution_clock, Orocos RTT, RTAI, Xenomai, etc.), we employ a ServoClock interface.  It defines the interface for all servo threads:

rapid/rapid_core/include/rapid/ServoClock.hpp

Instances of ServoClock that implement the details are located in rapid_servo_clock_library and are dynamically loaded via ROS’ pluginlib.

Robot Interface

To maximize the number of robots that RAPid can be used with, we employ a RobotInterface interface.  It defines the interface for interacting with the robot:

rapid_hydro_workspace/rapid/rapid_core/include/rapid/RobotInterface.hpp
#ifndef __RAPID_CORE_ROBOT_INTERFACE_HPP__
#define __RAPID_CORE_ROBOT_INTERFACE_HPP__

#include "ros/ros.h"
#include 

namespace rapid {

// Forward declarations
class RTControlModel;
class RobotState;
class Command;

/*!
 * The top-level definition of a RAPid robot interface.  This class specifies the
 * methods that all robot interface clases must implement.
 */
class RobotInterface
{
public:
    /*!
     * The constructor.
     */
    RobotInterface();

    /*!
     * The destructor.
     */
    virtual ~RobotInterface();

    /*!
     * Initializes this robot interface.
     *
     * \param[in] nh The ROS node handle to use during the initialization
     * process.
     * \param[in] model The robot model.
     * \return Whether the initialization was successful.
     */
    virtual bool init(ros::NodeHandle & nh, RTControlModel * model);

    /*!
     * Obtains the current state of the robot.
     *
     * \param[in] time The current time.
     * \param[out] latestRobotState The variable in which to store the latest robot state.
     * \param[in] block Whether to block waiting for message to arrive.
     * \return Whether the read was successful.
     */
    virtual bool read(const ros::Time & time, RobotState & latestRobotState, bool block = false) = 0;

    /*!
     * Sends a command to the robot.
     *
     * \param[in] time The current time.
     * \param[in] command The command to send to the robot.
     * \return Whether the write was successful.
     */
    virtual bool write(const ros::Time & time, const Command & command) = 0;

    // EIGEN_MAKE_ALIGNED_OPERATOR_NEW
protected:
    /*!
     * Whether the controller is initialized.
     */
    bool initialized;

    /*!
     * The name of the controller.  This is useful for creating a ROS node handle.
     */
    std::string controllerName;

    /*!
     * The robot control model.
     */
    RTControlModel * model;

    /*!
     * For receiving Odometry information
     */
    std::unique_ptr odometryStateReceiver;
};

} // namespace rapid

#endif // __RAPID_CORE_ROBOT_INTERFACE_HPP__

Instances of RobotInterface that implement the details are located in rapid_robot_interface_library and are dynamically loaded via ROS’ pluginlib.

Reception of Odometry Data

The odometry data is received by the RobotInterface and can be generalized to receive the data from other transport layers like shared memory.

Here is the super-class of all odometry state receivers:

rapid/rapid_core/include/rapid/OdometryStateReceiver.hpp

It currently has one child class that obtains odometry data via a ROS topic:

rapid/rapid_robot_interface_library/include/rapid/robot_interface_library/OdometryStateReceiverROSTopic.hpp

Josh will implement another child class called OdometryStateReceiverSM.hpp that obtains the data from shared memory.

RobotInterface.hpp now contains a pointer to an OdometryStateReceiver.  Child classes of RobotInterface (i.e., RobotInterfaceROSTopic, RobotInterfaceSM, and RobotInterfaceUDP) can instantiate any type of OdometryStateReceiver to obtain odometry information.

RobotInterfaceROSTopic, RobotInterfaceSM, and RobotInterfaceUDP contains the following: 

  1. At the end of init(...), they instantiate a OdometryStateReceiverROSTopic object.  This can be changed to instead instantiate a OdometryStateReceiverSM.
  2. The read(...) method calls odometryStateReceiver->getOdometry(...)