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 #ifndef OBJECTTRANSFORM_SENSOR_SYSTEM
00027 #define OBJECTTRANSFORM_SENSOR_SYSTEM
00028
00029 #include <tf/transform_listener.h>
00030 #include <posedetection_msgs/ObjectDetection.h>
00031 #include "rossensorsystem.h"
00032
00034 class ObjectTransformSystem : public ROSSensorSystem<posedetection_msgs::ObjectDetection>
00035 {
00036 public:
00037 static boost::shared_ptr<void> RegisterXMLReader(EnvironmentBasePtr penv)
00038 {
00039 return RegisterXMLReaderId(penv,"objecttransform");
00040 }
00041
00042 ObjectTransformSystem(EnvironmentBasePtr penv)
00043 : ROSSensorSystem<posedetection_msgs::ObjectDetection>("objecttransform",penv), _nNextId(1)
00044 {
00045 __description = ":Interface Author: Rosen Diankov\n\nAdd objects from the ROS network using the posedetection_msgs/ObjectDetection message. The type field in the message is interpreted as an OpenRAVE-loadable object file.";
00046 }
00047 virtual ~ObjectTransformSystem() {
00048 _tflistener.reset();
00049 }
00050
00051 virtual bool Init(istream& sinput)
00052 {
00053 _fThreshSqr = 0.05*0.05f;
00054 _listtopics.clear();
00055 string cmd;
00056 while(!sinput.eof()) {
00057 sinput >> cmd;
00058 if( !sinput )
00059 break;
00060 std::transform(cmd.begin(), cmd.end(), cmd.begin(), ::tolower);
00061
00062 if( cmd == "topic") {
00063 string topic;
00064 sinput >> topic;
00065 _listtopics.push_back(topic);
00066 }
00067 else if( cmd == "thresh" ) {
00068 sinput >> _fThreshSqr;
00069 _fThreshSqr *= _fThreshSqr;
00070 }
00071 else if( cmd == "robot" || cmd == "bodyoffset") {
00072 string name;
00073 sinput >> name;
00074 _pbodyoffset = GetEnv()->GetKinBody(name);
00075 }
00076 else if( cmd == "matrixoffset") {
00077 TransformMatrix tmat;
00078 sinput >> tmat;
00079 _toffset = tmat;
00080 }
00081 else if( cmd == "expirationtime") {
00082 double expirationtime;
00083 sinput >> expirationtime;
00084 if( !!sinput )
00085 _expirationtime = (uint64_t)(expirationtime*1000000);
00086 }
00087 else break;
00088
00089 if( !sinput ) {
00090 RAVELOG_ERRORA("failed\n");
00091 return false;
00092 }
00093 }
00094 if( _listtopics.size() == 0 )
00095 _listtopics.push_back("ObjectDetection");
00096 return startsubscriptions();
00097 }
00098
00099 virtual bool startsubscriptions()
00100 {
00101 if( !ROSSensorSystem<posedetection_msgs::ObjectDetection>::startsubscriptions() )
00102 return false;
00103
00104 _tflistener.reset(new tf::TransformListener(*_ros));
00105 return true;
00106 }
00107
00108 virtual void Destroy()
00109 {
00110 ROSSensorSystem<posedetection_msgs::ObjectDetection>::Destroy();
00111 _tflistener.reset();
00112 }
00113
00114 private:
00115
00116 virtual void newdatacb(const boost::shared_ptr<posedetection_msgs::ObjectDetection const>& topicmsg)
00117 {
00118 list< SNAPSHOT > listbodies;
00119 list< pair<string,Transform> > listnewobjs;
00120
00121 if( topicmsg->header.stamp == ros::Time(0) )
00122 RAVELOG_WARN(str(boost::format("incoming topic has 0 timestamp, bodies might not appear!\n")));
00123
00124 {
00125 EnvironmentMutex::scoped_lock lockenv(GetEnv()->GetMutex());
00126 boost::mutex::scoped_lock lock(_mutex);
00127 BODIES mapbodies = _mapbodies;
00128 geometry_msgs::PoseStamped posestamped, poseout;
00129 Transform tbodyoffset;
00130 string strbodybaselink;
00131 bool bHasBodyTransform = false;
00132
00133 if( !!_pbodyoffset && topicmsg->objects.size() > 0 ) {
00134 bHasBodyTransform = true;
00135 tbodyoffset = _pbodyoffset->GetTransform();
00136 strbodybaselink = _pbodyoffset->GetLinks().at(0)->GetName();
00137 }
00138
00139 FOREACHC(itobj, topicmsg->objects) {
00140 boost::shared_ptr<BodyData> b;
00141
00142 Transform tnew;
00143
00144
00145 if( bHasBodyTransform && !!_tflistener ) {
00146 posestamped.pose = GetPose(_toffset * GetTransform(itobj->pose));
00147 posestamped.header = topicmsg->header;
00148
00149 try {
00150 _tflistener->transformPose(strbodybaselink, posestamped, poseout);
00151 tnew = tbodyoffset * GetTransform(poseout.pose);
00152 }
00153 catch(std::runtime_error& ex) {
00154 try {
00155
00156 posestamped.header.stamp = ros::Time();
00157 _tflistener->transformPose(strbodybaselink, posestamped, poseout);
00158 tnew = tbodyoffset * GetTransform(poseout.pose);
00159 }
00160 catch(std::runtime_error& ex) {
00161 RAVELOG_WARNA("failed to get tf frames %s (body link:%s) for object %s\n",posestamped.header.frame_id.c_str(), strbodybaselink.c_str(), itobj->type.c_str());
00162 continue;
00163 }
00164 }
00165 }
00166 else
00167 tnew = GetTransform(itobj->pose);
00168
00169 FOREACH(it, mapbodies) {
00170 if( it->second->GetSid() == itobj->type ) {
00171
00172 if( (it->second->GetRecentTransform().trans-tnew.trans).lengthsqr3() > _fThreshSqr )
00173 continue;
00174
00175 b = it->second;
00176 mapbodies.erase(it);
00177 break;
00178 }
00179 }
00180
00181 if( !b ) {
00182 listnewobjs.push_back(pair<string,Transform>(itobj->type,tnew));
00183 }
00184 else {
00185 if( !b->IsEnabled() )
00186 continue;
00187
00188 listbodies.push_back(SNAPSHOT(b, tnew));
00189 }
00190 }
00191 }
00192 _UpdateBodies(listbodies);
00193 listbodies.clear();
00194
00195
00196 if( listnewobjs.size() > 0 ) {
00197 string data;
00198 EnvironmentMutex::scoped_lock lock(GetEnv()->GetMutex());
00199 FOREACH(itobj, listnewobjs) {
00200 try {
00201 KinBodyPtr pbody = GetEnv()->ReadKinBodyXMLFile(resolveName(itobj->first));
00202 if( !pbody ) {
00203 RAVELOG_ERRORA(str(boost::format("failed to create object %s\n")%itobj->first.c_str()));
00204 continue;
00205 }
00206
00207
00208 pbody->SetName(str(boost::format("%s%d")%pbody->GetName()%(_nNextId++)));
00209 GetEnv()->AddKinBody(pbody,true);
00210
00211 boost::shared_ptr<BodyData> b = boost::static_pointer_cast<BodyData>(AddKinBody(pbody, XMLReadableConstPtr()));
00212 if( !b ) {
00213
00214 boost::shared_ptr<XMLData> pdummydata(new XMLData(_xmlid));
00215 pdummydata->sid = itobj->first;
00216 b = boost::static_pointer_cast<BodyData>(AddKinBody(pbody, pdummydata));
00217 if( !b ) {
00218 GetEnv()->Remove(pbody);
00219 continue;
00220 }
00221 }
00222
00223 SetRecentTransform(b,itobj->second);
00224
00225
00226 pbody->SetTransform(Transform(Vector(1,0,0,0), Vector(10000,10000,10000)));
00227 listbodies.push_back(SNAPSHOT(b,itobj->second));
00228 }
00229 catch (openrave_exception& e) {
00230 RAVELOG_ERROR("failed to create object: %s (%s)\n",e.what());
00231 continue;
00232 }
00233 }
00234
00235 if( listbodies.size() > 0 ) {
00236 _UpdateBodies(listbodies);
00237 }
00238 }
00239 }
00240
00241 boost::shared_ptr<tf::TransformListener> _tflistener;
00242 KinBodyPtr _pbodyoffset;
00243 Transform _toffset;
00244 dReal _fThreshSqr;
00245 int _nNextId;
00246 };
00247
00248 #endif