00001 #include <string> 00002 #include <vector> 00003 00004 #include <boost/thread/mutex.hpp> 00005 00006 #include <ros/ros.h> 00007 #include <ros/callback_queue.h> 00008 #include <ros/advertise_options.h> 00009 #include <ros/subscribe_options.h> 00010 00011 #include <geometry_msgs/Twist.h> 00012 #include <geometry_msgs/Pose.h> 00013 #include <geometry_msgs/Vector3.h> 00014 #include <geometry_msgs/WrenchStamped.h> 00015 #include <std_msgs/String.h> 00016 #include <std_srvs/Empty.h> 00017 00018 #include <boost/thread.hpp> 00019 #include <boost/thread/condition.hpp> 00020 00021 #include <gazebo/math/gzmath.hh> 00022 #include <gazebo/physics/physics.hh> 00023 #include <gazebo/physics/PhysicsTypes.hh> 00024 #include <gazebo/transport/TransportTypes.hh> 00025 #include <gazebo/common/Time.hh> 00026 #include <gazebo/common/Plugin.hh> 00027 #include <gazebo/common/Events.hh> 00028 #include <gazebo/common/PID.hh> 00029 #include <gazebo/sensors/SensorManager.hh> 00030 #include <gazebo/sensors/SensorTypes.hh> 00031 #include <gazebo/sensors/ContactSensor.hh> 00032 #include <gazebo/sensors/ImuSensor.hh> 00033 #include <gazebo/sensors/Sensor.hh> 00034 00035 #include <sensor_msgs/Imu.h> 00036 #include <sensor_msgs/JointState.h> 00037 00038 #include "hrpsys_gazebo_msgs/JointCommand.h" 00039 #include "hrpsys_gazebo_msgs/RobotState.h" 00040 00041 #include "hrpsys_gazebo_msgs/SyncCommand.h" 00042 00043 #include "PubQueue.h" 00044 00045 namespace gazebo 00046 { 00047 typedef boost::shared_ptr< sensors::ImuSensor > ImuSensorPtr; 00048 typedef hrpsys_gazebo_msgs::JointCommand JointCommand; 00049 typedef hrpsys_gazebo_msgs::RobotState RobotState; 00050 typedef boost::shared_ptr< math::Pose > PosePtr; 00051 00052 class IOBPlugin : public ModelPlugin 00053 { 00054 public: 00055 IOBPlugin(); 00056 virtual ~IOBPlugin(); 00057 void Load(physics::ModelPtr _parent, sdf::ElementPtr _sdf); 00058 00059 private: 00060 void UpdateStates(); 00061 void RosQueueThread(); 00062 void SrvQueueThread(); 00063 void DeferredLoad(); 00064 void GetRobotStates(const common::Time &_curTime); 00065 void SetJointCommand(const JointCommand::ConstPtr &_msg); 00066 void SetJointCommand_impl(const JointCommand &_msg); 00067 void LoadPIDGainsFromParameter(); 00068 void ZeroJointCommand(); 00069 void UpdatePIDControl(double _dt); 00070 void UpdatePID_Velocity_Control(double _dt); 00071 void PublishJointState(); 00072 00073 void GetIMUState(const common::Time &_curTime); 00074 void GetForceTorqueSensorState(const common::Time &_curTime); 00075 00076 bool serviceCallback(hrpsys_gazebo_msgs::SyncCommandRequest &req, 00077 hrpsys_gazebo_msgs::SyncCommandResponse &res); 00078 bool serviceRefCallback(std_srvs::EmptyRequest &req, 00079 std_srvs::EmptyResponse &res); 00080 00081 struct force_sensor_info { 00082 physics::JointPtr joint; 00083 std::string frame_id; 00084 PosePtr pose; 00085 }; 00086 00087 struct imu_sensor_info { 00088 physics::LinkPtr link; 00089 ImuSensorPtr sensor; 00090 std::string sensor_name; 00091 std::string frame_id; 00092 }; 00093 00094 ros::NodeHandle* rosNode; 00095 ros::CallbackQueue rosQueue; 00096 ros::CallbackQueue srvQueue; 00097 00098 physics::WorldPtr world; 00099 physics::ModelPtr model; 00100 sdf::ElementPtr sdf; 00101 00102 event::ConnectionPtr updateConnection; 00103 00104 boost::thread callbackQueeuThread_msg; 00105 boost::thread callbackQueeuThread_srv; 00106 boost::thread deferredLoadThread; 00107 00108 common::Time lastControllerUpdateTime; 00109 00110 RobotState robotState; 00111 ros::Publisher pubRobotState; 00112 PubQueue<RobotState>::Ptr pubRobotStateQueue; 00113 00114 bool publish_joint_state; 00115 int publish_joint_state_step; 00116 int publish_joint_state_counter; 00117 ros::Publisher pubJointState; 00118 PubQueue<sensor_msgs::JointState>::Ptr pubJointStateQueue; 00119 00120 ros::ServiceServer jointrefServ; 00121 ros::ServiceServer controlServ; 00122 00123 JointCommand jointCommand; 00124 ros::Subscriber subIOBCommand; 00125 00126 std::vector<std::string> jointNames; 00127 physics::Joint_V joints; 00128 00129 std::vector<double> lastJointCFMDamping; 00130 std::vector<double> jointDampingModel; 00131 std::vector<double> jointDampingMax; 00132 std::vector<double> jointDampingMin; 00133 00134 typedef std::map< std::string, struct force_sensor_info > forceSensorMap; 00135 typedef std::map< std::string, struct imu_sensor_info > imuSensorMap; 00136 std::vector<std::string> forceSensorNames; 00137 std::vector<std::string> imuSensorNames; 00138 forceSensorMap forceSensors; 00139 imuSensorMap imuSensors; 00140 00141 std::vector<double> effortLimit; 00142 00143 class ErrorTerms { 00145 double q_p; 00146 double d_q_p_dt; 00147 double k_i_q_i; // integral term weighted by k_i 00148 double qd_p; 00149 friend class IOBPlugin; 00150 }; 00151 std::vector<ErrorTerms> errorTerms; 00152 00153 // 00154 PubMultiQueue pmq; 00155 boost::mutex mutex; 00156 // 00157 boost::mutex uniq_mutex; 00158 boost::condition_variable wait_service_cond_; 00159 boost::condition_variable return_service_cond_; 00160 // 00161 std::string robot_name; 00162 std::string controller_name; 00163 bool use_synchronized_command; 00164 bool use_loose_synchronized; 00165 bool use_velocity_feedback; 00166 bool use_joint_effort; 00167 double iob_period; 00168 00169 static inline int xmlrpc_value_as_int(XmlRpc::XmlRpcValue &v) { 00170 if((v.getType() == XmlRpc::XmlRpcValue::TypeDouble) || 00171 (v.getType() == XmlRpc::XmlRpcValue::TypeInt)) { 00172 if(v.getType() == XmlRpc::XmlRpcValue::TypeDouble) { 00173 double d = v; 00174 return (int)d; 00175 } else { 00176 int i = v; 00177 return i; 00178 } 00179 } 00180 // not number 00181 return 0; 00182 } 00183 static inline double xmlrpc_value_as_double(XmlRpc::XmlRpcValue &v) { 00184 if((v.getType() == XmlRpc::XmlRpcValue::TypeDouble) || 00185 (v.getType() == XmlRpc::XmlRpcValue::TypeInt)) { 00186 if(v.getType() == XmlRpc::XmlRpcValue::TypeDouble) { 00187 double d = v; 00188 return d; 00189 } else { 00190 int i = v; 00191 return (double)i; 00192 } 00193 } 00194 // not number 00195 return 0.0; 00196 } 00197 // force sensor averaging 00198 int force_sensor_average_window_size; 00199 int force_sensor_average_cnt; 00200 std::map<std::string, boost::shared_ptr<std::vector<boost::shared_ptr<geometry_msgs::WrenchStamped> > > > forceValQueueMap; 00201 // effort averaging 00202 int effort_average_cnt; 00203 int effort_average_window_size; 00204 std::vector< boost::shared_ptr<std::vector<double> > > effortValQueue; 00205 // stepping data publish cycle 00206 int publish_count; 00207 int publish_step; 00208 }; 00209 }