/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2016, CNRS // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // * Neither the name of hiDOF, Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. ////////////////////////////////////////////////////////////////////////////// /* * Author: Olivier STASSE */ #ifndef RC_SOT_CONTROLLER_H #define RC_SOT_CONTROLLER_H #include <string> #include <map> #include <talos_controller_interface/controller.h> #include <talos_hardware_interface/joint_command_interface.h> #include <talos_hardware_interface/imu_sensor_interface.h> #include <talos_hardware_interface/force_torque_sensor_interface.h> #include <talos_pal_hardware_interfaces/actuator_temperature_interface.h> #include <dynamic_graph_bridge/sot_loader_basic.hh> #include "log.hh" #include <ros/ros.h> #include <control_toolbox/pid.h> namespace talos_sot_controller { enum SotControlMode { POSITION, EFFORT}; class XmlrpcHelperException : public ros::Exception { public: XmlrpcHelperException(const std::string& what) : ros::Exception(what) {} }; struct EffortControlPDMotorControlData { control_toolbox::Pid pid_controller; //double p_gain,d_gain,i_gain; double prev; double vel_prev; double des_pos; double integ_err; EffortControlPDMotorControlData(); // void read_from_xmlrpc_value(XmlRpc::XmlRpcValue &aXRV); void read_from_xmlrpc_value(const std::string &prefix); }; /** This class encapsulates the Stack of Tasks inside the ros-control infra-structure. */ class RCSotController : public talos_controller_interface::ControllerBase, SotLoaderBasic { protected: /// Robot nb dofs. size_t nbDofs_; /// Data log. rc_sot_system::DataToLog DataOneIter_; private: /// @{ \name Ros-control related fields /// \brief Vector of joint handles. std::vector<talos_hardware_interface::JointHandle> joints_; std::vector<std::string> joints_name_; /// \brief Vector towards the IMU. std::vector<talos_hardware_interface::ImuSensorHandle> imu_sensor_; /// \brief Vector of 6D force sensor. std::vector<talos_hardware_interface::ForceTorqueSensorHandle> ft_sensors_; /// \brief Vector of temperature sensors for the actuators. std::vector<talos_hardware_interface::ActuatorTemperatureSensorHandle> act_temp_sensors_; /// \brief Interface to the joints controlled in position. talos_hardware_interface::PositionJointInterface * pos_iface_; /// \brief Interface to the joints controlled in force. talos_hardware_interface::EffortJointInterface * effort_iface_; /// \brief Interface to the sensors (IMU). talos_hardware_interface::ImuSensorInterface* imu_iface_; /// \brief Interface to the sensors (Force). talos_hardware_interface::ForceTorqueSensorInterface* ft_iface_; /// \brief Interface to the actuator temperature sensor. talos_hardware_interface::ActuatorTemperatureSensorInterface * act_temp_iface_; /// @} /// \brief Log rc_sot_system::Log RcSotLog; /// @} const std::string type_name_; /// \brief Adapt the interface to Gazebo simulation bool simulation_mode_; /// \brief The robot can controlled in effort or position mode (default). SotControlMode control_mode_; /// \brief Implement a PD controller for the robot when the dynamic graph /// is not on. std::map<std::string,EffortControlPDMotorControlData> effort_mode_pd_motors_; /// \brief Map from ros-control quantities to robot device /// ros-control quantities are for the sensors: /// * motor-angles /// * joint-angles /// * velocities /// * torques /// ros-control quantities for control are: /// * joints /// * torques std::map<std::string,std::string> mapFromRCToSotDevice_; public : RCSotController (); /// \brief Read the configuration files, /// claims the request to the robot and initialize the Stack-Of-Tasks. bool initRequest (talos_hardware_interface::RobotHW * robot_hw, ros::NodeHandle &robot_nh, ros::NodeHandle &controller_nh, std::set<std::string> & claimed_resources); /// \brief Display claimed resources void displayClaimedResources(std::set<std::string> & claimed_resources); /// \brief Claims bool init(); /// \brief Read the sensor values, calls the control graph, and apply the control. /// void update(const ros::Time&, const ros::Duration& ); /// \brief Starting by filling the sensors. void starting(const ros::Time&); /// \brief Stopping the control void stopping(const ros::Time&); /// \brief Display the kind of hardware interface that this controller is using. virtual std::string getHardwareInterfaceType() const; protected: /// Initialize the roscontrol interfaces bool initInterfaces(talos_hardware_interface::RobotHW * robot_hw, ros::NodeHandle &, ros::NodeHandle &, std::set<std::string> & claimed_resources); /// Initialize the hardware interface using the joints. bool initJoints(); /// Initialize the hardware interface accessing the IMU. bool initIMU(); /// Initialize the hardware interface accessing the force sensors. bool initForceSensors(); /// Initialize the hardware interface accessing the temperature sensors. bool initTemperatureSensors(); ///@{ \name Read the parameter server /// \brief Entry point bool readParams(ros::NodeHandle &robot_nh); /// \brief Creates the list of joint names. bool readParamsJointNames(ros::NodeHandle &robot_nh); /// \brief Set the SoT library name. bool readParamsSotLibName(ros::NodeHandle &robot_nh); /// \Brief Set the mapping between ros-control and the robot device /// For instance the yaml file should have a line with map_rc_to_sot_device: /// map_rc_to_sot_device: [ ] bool readParamsFromRCToSotDevice(ros::NodeHandle &robot_nh); /// \brief Read the control mode. bool readParamsControlMode(ros::NodeHandle & robot_nh); /// \brief Read the PID information of the robot in effort mode. bool readParamsEffortControlPDMotorControlData(ros::NodeHandle &robot_nh); ///@} /// \brief Fill the SoT map structures void fillSensorsIn(std::string &title, std::vector<double> & data); /// \brief Get the information from the low level and calls fillSensorsIn. void fillJoints(); /// In the map sensorsIn_ creates the key "name_IMUNb" /// and associate to this key the vector data. void setSensorsImu(std::string &name, int IMUNb, std::vector<double> &data); /// @{ \name Fill the sensors /// Read the imus and set the interface to the SoT. void fillImu(); /// Read the force sensors void fillForceSensors(); /// Read the temperature sensors void fillTempSensors(); /// Entry point for reading all the sensors . void fillSensors(); ///@} /// Extract control values to send to the simulator. void readControl(std::map<std::string,dgs::ControlValues> &controlValues); /// Map of sensor readings std::map <std::string,dgs::SensorValues> sensorsIn_; /// Map of control values std::map<std::string,dgs::ControlValues> controlValues_; /// \brief Command send to motors /// Depending on control_mode it can be either /// position control or torque control. std::vector<double> command_; /// One iteration: read sensor, compute the control law, apply control. void one_iteration(); }; } #endif /* RC_SOT_CONTROLLER_H */