Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "plugindefs.h"
00027
00028 #include <boost/thread/mutex.hpp>
00029 #include <boost/thread/recursive_mutex.hpp>
00030 #include <boost/thread/condition.hpp>
00031 #include <boost/thread/thread_time.hpp>
00032 #include <boost/static_assert.hpp>
00033 #include <boost/bind.hpp>
00034 #include <boost/format.hpp>
00035
00036 #include <sensor_msgs/JointState.h>
00037
00038 class ROSPassiveController : public ControllerBase
00039 {
00040 public:
00041 ROSPassiveController(EnvironmentBasePtr penv, std::istream& ss) : ControllerBase(penv) {
00042 __description = ":Interface Author: Rosen Diankov\n\nAllows OpenRAVE to listen to ROS messages and update the robot, this does not control the robot in any way.";
00043 _bDestroyThread = true;
00044 _nControlTransformation = 0;
00045 _jointstatetopic="/joint_states";
00046 string cmd;
00047 while(!ss.eof()) {
00048 ss >> cmd;
00049 if( !ss ) {
00050 break;
00051 }
00052
00053 if( cmd == "jointstate") {
00054 ss >> _jointstatetopic;
00055 }
00056 else {
00057 break;
00058 }
00059 }
00060 }
00061 virtual ~ROSPassiveController() {
00062 _Destroy();
00063 }
00064
00065 virtual bool Init(RobotBasePtr robot, const std::vector<int>& dofindices, int nControlTransformation)
00066 {
00067 _Destroy();
00068 _probot = robot;
00069 _dofindices = dofindices;
00070 _nControlTransformation = nControlTransformation;
00071
00072 int argc=0;
00073 ros::init(argc,NULL,"openrave_rospassivecontroller", ros::init_options::NoSigintHandler|ros::init_options::AnonymousName);
00074 if( !ros::master::check() ) {
00075 return false;
00076 }
00077
00078 Reset(0);
00079 _node.reset(new ros::NodeHandle());
00080 _bDestroyThread = false;
00081 _threadros = boost::thread(boost::bind(&ROSPassiveController::_threadrosfn, this));
00082
00083 _subjointstate = _node->subscribe(_jointstatetopic, 10, &ROSPassiveController::_jointstatecb, this);
00084 FOREACHC(itjoint,_probot->GetJoints()) {
00085 _vjointnames.push_back(make_pair((*itjoint)->GetName(), (*itjoint)->GetJointIndex()));
00086 }
00087
00088 _probot->GetDOFValues(_vlastjointvalues);
00089 _vlastjointvel.resize(0);
00090 _vlastjointvel.resize(_vlastjointvalues.size(),0.0f);
00091 _vlastjointtorque = _vlastjointvel;
00092 return true;
00093 }
00094
00095 virtual const std::vector<int>& GetControlDOFIndices() const
00096 {
00097 return _dofindices;
00098 }
00099 virtual int IsControlTransformation() const
00100 {
00101 return _nControlTransformation;
00102 }
00103
00104 virtual void Reset(int options)
00105 {
00106 _controllertime = 0;
00107 _starttime = ros::Time(0);
00108 }
00109
00110 virtual bool SetDesired(const std::vector<dReal>& values, TransformConstPtr trans)
00111 {
00112 return false;
00113 }
00114
00115 virtual bool SetPath(TrajectoryBaseConstPtr ptraj)
00116 {
00117 return false;
00118 }
00119
00120 virtual void SimulationStep(dReal fTimeElapsed)
00121 {
00122 }
00123
00124 virtual bool IsDone()
00125 {
00126 return true;
00127 }
00128
00129 virtual dReal GetTime() const
00130 {
00131 return _controllertime;
00132 }
00133
00134 virtual void GetVelocity(std::vector<dReal>& vel) const {
00135 boost::mutex::scoped_lock lock(_mutex);
00136 vel = _vlastjointvel;
00137 }
00138
00139 virtual void GetTorque(std::vector<dReal>& torque) const {
00140 boost::mutex::scoped_lock lock(_mutex);
00141 torque = _vlastjointtorque;
00142 }
00143
00144 virtual RobotBasePtr GetRobot() const {
00145 return _probot;
00146 }
00147
00148 protected:
00149 virtual void _Destroy()
00150 {
00151 _bDestroyThread = true;
00152 _node.reset();
00153 _subjointstate.shutdown();
00154 _threadros.join();
00155 _probot.reset();
00156 _vjointnames.clear();
00157 }
00158
00159 virtual void _jointstatecb(const sensor_msgs::JointStateConstPtr& jstate)
00160 {
00161 boost::mutex::scoped_lock lock(_mutex);
00162 if( _bDestroyThread ) {
00163 return;
00164 }
00165 EnvironmentMutex::scoped_lock lockenv(GetEnv()->GetMutex());
00166 _probot->GetDOFValues(_vlastjointvalues);
00167
00168 _vlastjointvel.resize(_vlastjointvalues.size(),0.0f);
00169 _vlastjointtorque.resize(_vlastjointvalues.size(),0.0f);
00170 for(size_t i = 0; i < jstate->name.size(); ++i) {
00171 KinBody::JointPtr pjoint = _probot->GetJoint(jstate->name[i]);
00172 if( !pjoint ) {
00173 RAVELOG_VERBOSE(str(boost::format("could not find joint %s\n")%jstate->name[i]));
00174 continue;
00175 }
00176 else {
00177 if( i < jstate->position.size() ) {
00178 _vlastjointvalues.at(pjoint->GetJointIndex()) = jstate->position.at(i);
00179 }
00180 if( i < jstate->velocity.size() ) {
00181 _vlastjointvel.at(pjoint->GetJointIndex()) = jstate->velocity.at(i);
00182 }
00183 if( i < jstate->effort.size() ) {
00184 _vlastjointtorque.at(pjoint->GetJointIndex()) = jstate->effort.at(i);
00185 }
00186 }
00187 }
00188 if( _starttime.toSec() == 0 ) {
00189 _starttime = jstate->header.stamp;
00190 }
00191 _controllertime = (jstate->header.stamp-_starttime).toSec();
00192 _probot->SetDOFValues(_vlastjointvalues);
00193 }
00194
00195 virtual void _threadrosfn()
00196 {
00197 while(!_bDestroyThread && ros::ok()) {
00198 ros::spinOnce();
00199 usleep(1000);
00200 }
00201 }
00202
00203 bool _bDestroyThread;
00204 RobotBasePtr _probot;
00205 boost::shared_ptr<ros::NodeHandle> _node;
00206 boost::thread _threadros;
00207 ros::Subscriber _subjointstate;
00208 vector<dReal> _vlastjointvalues, _vlastjointvel, _vlastjointtorque;
00209 vector< pair<string,int> > _vjointnames;
00210 ros::Time _starttime;
00211 dReal _controllertime;
00212 std::vector<int> _dofindices;
00213 int _nControlTransformation;
00214 string _jointstatetopic;
00215 mutable boost::mutex _mutex;
00216 };
00217
00218 ControllerBasePtr CreateROSPassiveController(EnvironmentBasePtr penv, std::istream& sinput)
00219 {
00220 return ControllerBasePtr(new ROSPassiveController(penv,sinput));
00221 }