objecttransformsystem.h
Go to the documentation of this file.
00001 // Software License Agreement (BSD License)
00002 // Copyright (c) 2008, Rosen Diankov
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 #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                 // if on body, have to find the global transformation
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                             // try getting the latest value by passing a 0 timestamp
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;//tnew = GetTransform(itobj->pose);
00163                         }
00164                     }
00165                 }
00166                 else
00167                     tnew = GetTransform(itobj->pose);
00168 
00169                 FOREACH(it, mapbodies) {
00170                     if( it->second->GetSid() == itobj->type ) {                            
00171                         // same type matched, need to check proximity
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         // try to add the left-over objects
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                     // append an id to the body
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                         // create a dummy manage file and try again
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                     // put somewhere at infinity until UpdateBodies thread gets to it
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
 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