rospassivecontroller.cpp
Go to the documentation of this file.
00001 // Software License Agreement (BSD License)
00002 // Copyright (c) 2008, Willow Garage, Inc.
00003 // Redistribution and use in source and binary forms, with or without
00004 // modification, are permitted provided that the following conditions are met:
00005 //   * Redistributions of source code must retain the above copyright notice,
00006 //     this list of conditions and the following disclaimer.
00007 //   * Redistributions in binary form must reproduce the above copyright
00008 //     notice, this list of conditions and the following disclaimer in the
00009 //     documentation and/or other materials provided with the distribution.
00010 //   * The name of the author may not be used to endorse or promote products
00011 //     derived from this software without specific prior written permission.
00012 //
00013 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00014 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00015 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00016 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00017 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00018 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00019 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00020 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00021 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00022 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00023 // POSSIBILITY OF SUCH DAMAGE.
00024 //
00025 // \author Rosen Diankov
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(); // deadlock condition with environment
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         //resize the vel and torque vectors if necessary:
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); // query every 1ms?
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines


orrosplanning
Author(s): Rosen Diankov (rosen.diankov@gmail.com)
autogenerated on Sat Mar 23 2013 22:32:59