tracker.cpp
Go to the documentation of this file.
00001 #include <stdexcept>
00002 
00003 #include <boost/filesystem/fstream.hpp>
00004 #include <boost/format.hpp>
00005 #include <boost/scope_exit.hpp>
00006 #include <boost/version.hpp>
00007 
00008 #include <dynamic_reconfigure/server.h>
00009 #include <geometry_msgs/PoseWithCovarianceStamped.h>
00010 #include <image_proc/advertisement_checker.h>
00011 #include <image_transport/image_transport.h>
00012 #include <ros/param.h>
00013 #include <ros/ros.h>
00014 #include <ros/transport_hints.h>
00015 #include <sensor_msgs/Image.h>
00016 #include <std_msgs/String.h>
00017 #include <tf/transform_broadcaster.h>
00018 
00019 #include <boost/bind.hpp>
00020 #include <visp/vpExponentialMap.h>
00021 #include <visp/vpImage.h>
00022 #include <visp/vpImageConvert.h>
00023 #include <visp/vpCameraParameters.h>
00024 
00025 #include "tracker.hh"
00026 
00027 #include "conversion.hh"
00028 #include "callbacks.hh"
00029 #include "file.hh"
00030 #include "names.hh"
00031 
00032 // TODO:
00033 // - add a topic allowing to suggest an estimation of the cMo
00034 // - handle automatic reset when tracking is lost.
00035 
00036 namespace visp_tracker
00037 {
00038   bool
00039   Tracker::initCallback(visp_tracker::Init::Request& req,
00040                         visp_tracker::Init::Response& res)
00041   {
00042     ROS_INFO("Initialization request received.");
00043 
00044     res.initialization_succeed = false;
00045 
00046     // If something goes wrong, rollback all changes.
00047     BOOST_SCOPE_EXIT((&res)(tracker_)(&state_)
00048                      (&lastTrackedImage_)(&trackerType_))
00049     {
00050       if(!res.initialization_succeed)
00051       {
00052         tracker_->resetTracker();
00053         state_ = WAITING_FOR_INITIALIZATION;
00054         lastTrackedImage_ = 0;
00055 
00056       }
00057     } BOOST_SCOPE_EXIT_END;
00058 
00059     std::string fullModelPath;
00060     boost::filesystem::ofstream modelStream;
00061 
00062     // Load model from parameter.
00063     if (!makeModelFile(modelStream, fullModelPath))
00064       return true;
00065 
00066     tracker_->resetTracker();
00067 
00068     // Common parameters
00069     convertInitRequestToVpMbTracker(req, tracker_);
00070 
00071     if(trackerType_!="klt"){ // for mbt and hybrid
00072       convertInitRequestToVpMe(req, tracker_, movingEdge_);
00073     }
00074 
00075     if(trackerType_!="mbt"){ // for klt and hybrid
00076       convertInitRequestToVpKltOpencv(req, tracker_, kltTracker_);
00077     }
00078 
00079     if(trackerType_=="mbt+klt"){ // Hybrid Tracker reconfigure
00080       visp_tracker::ModelBasedSettingsConfig config;
00081       convertVpMbTrackerToModelBasedSettingsConfig<visp_tracker::ModelBasedSettingsConfig>(tracker_, config);
00082       reconfigureSrv_->updateConfig(config);
00083       convertVpMeToModelBasedSettingsConfig<visp_tracker::ModelBasedSettingsConfig>(movingEdge_, tracker_, config);
00084       reconfigureSrv_->updateConfig(config);
00085       convertVpKltOpencvToModelBasedSettingsConfig<visp_tracker::ModelBasedSettingsConfig>(kltTracker_, tracker_, config);
00086       reconfigureSrv_->updateConfig(config);
00087     }
00088     else if(trackerType_=="mbt"){ // Edge Tracker reconfigure
00089       visp_tracker::ModelBasedSettingsEdgeConfig config;
00090       convertVpMbTrackerToModelBasedSettingsConfig<visp_tracker::ModelBasedSettingsEdgeConfig>(tracker_, config);
00091       reconfigureEdgeSrv_->updateConfig(config);
00092       convertVpMeToModelBasedSettingsConfig<visp_tracker::ModelBasedSettingsEdgeConfig>(movingEdge_, tracker_, config);
00093       reconfigureEdgeSrv_->updateConfig(config);
00094     }
00095     else{ // KLT Tracker reconfigure
00096       visp_tracker::ModelBasedSettingsKltConfig config;
00097       convertVpMbTrackerToModelBasedSettingsConfig<visp_tracker::ModelBasedSettingsKltConfig>(tracker_, config);
00098       reconfigureKltSrv_->updateConfig(config);
00099       convertVpKltOpencvToModelBasedSettingsConfig<visp_tracker::ModelBasedSettingsKltConfig>(kltTracker_, tracker_, config);
00100       reconfigureKltSrv_->updateConfig(config);
00101     }
00102 
00103     state_ = WAITING_FOR_INITIALIZATION;
00104     lastTrackedImage_ = 0;
00105 
00106     // Load the model.
00107     try
00108     {
00109       ROS_DEBUG_STREAM("Trying to load the model Tracker: " << fullModelPath);
00110       tracker_->loadModel(fullModelPath.c_str());
00111       modelStream.close();
00112     }
00113     catch(...)
00114     {
00115       ROS_ERROR_STREAM("Failed to load the model: " << fullModelPath);
00116       return true;
00117     }
00118     ROS_DEBUG("Model has been successfully loaded.");
00119 
00120     // Load the initial cMo.
00121     transformToVpHomogeneousMatrix(cMo_, req.initial_cMo);
00122 
00123     // Enable covariance matrix.
00124     tracker_->setCovarianceComputation(true);
00125 
00126     // Try to initialize the tracker.
00127     ROS_INFO_STREAM("Initializing tracker with cMo:\n" << cMo_);
00128     try
00129     {
00130       // Bug between setPose() and initFromPose() not present here due to previous call to resetTracker()
00131       tracker_->initFromPose(image_, cMo_);
00132       ROS_INFO("Tracker successfully initialized.");
00133 
00134       //movingEdge.print();
00135       ROS_INFO_STREAM(convertVpMbTrackerToRosMessage(tracker_));
00136       // - Moving edges.
00137       if(trackerType_!="klt")
00138         ROS_INFO_STREAM(convertVpMeToRosMessage(tracker_, movingEdge_));
00139 
00140       if(trackerType_!="mbt")
00141         ROS_INFO_STREAM(convertVpKltOpencvToRosMessage(tracker_,kltTracker_));
00142     }
00143     catch(const std::string& str)
00144     {
00145       ROS_ERROR_STREAM("Tracker initialization has failed: " << str);
00146     }
00147 
00148     // Initialization is valid.
00149     res.initialization_succeed = true;
00150     state_ = TRACKING;
00151     return true;
00152   }
00153 
00154   void
00155   Tracker::updateMovingEdgeSites(visp_tracker::MovingEdgeSitesPtr sites)
00156   {
00157     if (!sites)
00158       return;
00159 
00160     std::list<vpMbtDistanceLine*> linesList;
00161 
00162     if(trackerType_!="klt") { // For mbt and hybrid
00163       dynamic_cast<vpMbEdgeTracker*>(tracker_)->getLline(linesList, 0);
00164 
00165       std::list<vpMbtDistanceLine*>::iterator linesIterator = linesList.begin();
00166 
00167       bool noVisibleLine = true;
00168       for (; linesIterator != linesList.end(); ++linesIterator)
00169       {
00170         vpMbtDistanceLine* line = *linesIterator;
00171 
00172         if (line && line->isVisible() && line->meline)
00173         {
00174           std::list<vpMeSite>::const_iterator sitesIterator =
00175               line->meline->list.begin();
00176           if (line->meline->list.empty())
00177             ROS_DEBUG_THROTTLE(10, "no moving edge for a line");
00178           for (; sitesIterator != line->meline->list.end(); ++sitesIterator)
00179           {
00180             visp_tracker::MovingEdgeSite movingEdgeSite;
00181             movingEdgeSite.x = sitesIterator->ifloat;
00182             movingEdgeSite.y = sitesIterator->jfloat;
00183             movingEdgeSite.suppress = sitesIterator->suppress;
00184             sites->moving_edge_sites.push_back (movingEdgeSite);
00185           }
00186           noVisibleLine = false;
00187         }
00188       }
00189       if (noVisibleLine)
00190         ROS_DEBUG_THROTTLE(10, "no distance lines");
00191     }
00192   }
00193 
00194   void
00195   Tracker::updateKltPoints(visp_tracker::KltPointsPtr klt)
00196   {
00197     if (!klt)
00198       return;
00199 
00200 #if VISP_VERSION_INT < VP_VERSION_INT(2,10,0) // ViSP < 2.10.0
00201     vpMbHiddenFaces<vpMbtKltPolygon> *poly_lst;
00202     std::map<int, vpImagePoint> *map_klt;
00203 
00204     if(trackerType_!="mbt") { // For klt and hybrid
00205       poly_lst = &dynamic_cast<vpMbKltTracker*>(tracker_)->getFaces();
00206 
00207       for(unsigned int i = 0 ; i < poly_lst->size() ; i++)
00208       {
00209         if((*poly_lst)[i])
00210         {
00211           map_klt = &((*poly_lst)[i]->getCurrentPoints());
00212 
00213           if(map_klt->size() > 3)
00214           {
00215             for (std::map<int, vpImagePoint>::iterator it=map_klt->begin(); it!=map_klt->end(); ++it)
00216             {
00217               visp_tracker::KltPoint kltPoint;
00218               kltPoint.id = it->first;
00219               kltPoint.i = it->second.get_i();
00220               kltPoint.j = it->second.get_j();
00221               klt->klt_points_positions.push_back (kltPoint);
00222             }
00223           }
00224         }
00225       }
00226     }
00227 #else // ViSP >= 2.10.0
00228     std::list<vpMbtDistanceKltPoints*> *poly_lst;
00229     std::map<int, vpImagePoint> *map_klt;
00230 
00231     if(trackerType_!="mbt") { // For klt and hybrid
00232       poly_lst = &dynamic_cast<vpMbKltTracker*>(tracker_)->getFeaturesKlt();
00233 
00234       for(std::list<vpMbtDistanceKltPoints*>::const_iterator it=poly_lst->begin(); it!=poly_lst->end(); ++it){
00235         map_klt = &((*it)->getCurrentPoints());
00236 
00237         if((*it)->polygon->isVisible()){
00238           if(map_klt->size() > 3)
00239           {
00240             for (std::map<int, vpImagePoint>::iterator it=map_klt->begin(); it!=map_klt->end(); ++it)
00241             {
00242               visp_tracker::KltPoint kltPoint;
00243               kltPoint.id = it->first;
00244               kltPoint.i = it->second.get_i();
00245               kltPoint.j = it->second.get_j();
00246               klt->klt_points_positions.push_back (kltPoint);
00247             }
00248           }
00249         }
00250       }
00251     }
00252 #endif
00253   }
00254 
00255   void Tracker::checkInputs()
00256   {
00257     ros::V_string topics;
00258     topics.push_back(rectifiedImageTopic_);
00259     checkInputs_.start(topics, 60.0);
00260   }
00261 
00262   Tracker::Tracker(ros::NodeHandle& nh,
00263                    ros::NodeHandle& privateNh,
00264                    volatile bool& exiting,
00265                    unsigned queueSize)
00266     : exiting_ (exiting),
00267       queueSize_(queueSize),
00268       nodeHandle_(nh),
00269       nodeHandlePrivate_(privateNh),
00270       imageTransport_(nodeHandle_),
00271       state_(WAITING_FOR_INITIALIZATION),
00272       image_(),
00273       cameraPrefix_(),
00274       rectifiedImageTopic_(),
00275       cameraInfoTopic_(),
00276       modelPath_(),
00277       cameraSubscriber_(),
00278       mutex_ (),
00279       //reconfigureSrv_(mutex_, nodeHandlePrivate_),
00280       reconfigureSrv_(NULL),
00281       reconfigureKltSrv_(NULL),
00282       reconfigureEdgeSrv_(NULL),
00283       resultPublisher_(),
00284       transformationPublisher_(),
00285       movingEdgeSitesPublisher_(),
00286       kltPointsPublisher_(),
00287       initService_(),
00288       header_(),
00289       info_(),
00290       kltTracker_(),
00291       movingEdge_(),
00292       cameraParameters_(),
00293       lastTrackedImage_(),
00294       checkInputs_(nodeHandle_, ros::this_node::getName()),
00295       cMo_ (),
00296       listener_ (),
00297       worldFrameId_ (),
00298       compensateRobotMotion_ (false),
00299       transformBroadcaster_ (),
00300       childFrameId_ (),
00301       objectPositionHintSubscriber_ (),
00302       objectPositionHint_ ()
00303   {
00304     // Set cMo to identity.
00305     cMo_.eye();
00306     //tracker_ = new vpMbEdgeTracker();
00307 
00308     // Parameters.
00309     nodeHandlePrivate_.param<std::string>("camera_prefix", cameraPrefix_, "");
00310     nodeHandlePrivate_.param<std::string>("tracker_type", trackerType_, "mbt");
00311     if(trackerType_=="mbt")
00312       tracker_ = new vpMbEdgeTracker();
00313     else if(trackerType_=="klt")
00314       tracker_ = new vpMbKltTracker();
00315     else
00316       tracker_ = new vpMbEdgeKltTracker();
00317 
00318     if (cameraPrefix_.empty ())
00319       {
00320         ROS_FATAL
00321           ("The camera_prefix parameter not set.\n"
00322            "Please relaunch the tracker while setting this parameter, i.e.\n"
00323            "$ rosrun visp_tracker tracker _camera_prefix:=/my/camera");
00324         ros::shutdown ();
00325         return;
00326       }
00327     // Create global /camera_prefix param to avoid to remap in the launch files the tracker_client and tracker_viewer nodes
00328     nodeHandle_.setParam("camera_prefix", cameraPrefix_);
00329 
00330     nodeHandle_.param<std::string>("frame_id", childFrameId_, "object_position");
00331 
00332     // Robot motion compensation.
00333     nodeHandle_.param<std::string>("world_frame_id", worldFrameId_, "/odom");
00334     nodeHandle_.param<bool>
00335       ("compensate_robot_motion", compensateRobotMotion_, false);
00336 
00337     // Compute topic and services names.
00338     rectifiedImageTopic_ =
00339       ros::names::resolve(cameraPrefix_ + "/image_rect");
00340 
00341     // Check for subscribed topics.
00342     checkInputs();
00343 
00344     // Result publisher.
00345     resultPublisher_ =
00346       nodeHandle_.advertise<geometry_msgs::PoseWithCovarianceStamped>
00347       (visp_tracker::object_position_covariance_topic, queueSize_);
00348 
00349     transformationPublisher_ =
00350       nodeHandle_.advertise<geometry_msgs::TransformStamped>
00351       (visp_tracker::object_position_topic, queueSize_);
00352 
00353     // Moving edge sites_ publisher.
00354     movingEdgeSitesPublisher_ =
00355       nodeHandle_.advertise<visp_tracker::MovingEdgeSites>
00356       (visp_tracker::moving_edge_sites_topic, queueSize_);
00357 
00358     // Klt_points_ publisher.
00359     kltPointsPublisher_ =
00360       nodeHandle_.advertise<visp_tracker::KltPoints>
00361       (visp_tracker::klt_points_topic, queueSize_);
00362 
00363     // Camera subscriber.
00364     cameraSubscriber_ =
00365       imageTransport_.subscribeCamera
00366       (rectifiedImageTopic_, queueSize_,
00367        bindImageCallback(image_, header_, info_));
00368 
00369     // Object position hint subscriber.
00370     typedef boost::function<
00371     void (const geometry_msgs::TransformStampedConstPtr&)>
00372       objectPositionHintCallback_t;
00373     objectPositionHintCallback_t callback =
00374       boost::bind (&Tracker::objectPositionHintCallback, this, _1);
00375     objectPositionHintSubscriber_ =
00376       nodeHandle_.subscribe<geometry_msgs::TransformStamped>
00377       ("object_position_hint", queueSize_, callback);
00378 
00379     // Initialization.
00380     // No more necessary as it is done via the reconfigure server
00381 //    movingEdge_.initMask();
00382 //    if(trackerType_!="klt"){
00383 //      vpMbEdgeTracker* t = dynamic_cast<vpMbEdgeTracker*>(tracker_);
00384 //      t->setMovingEdge(movingEdge_);
00385 //    }
00386     
00387 //    if(trackerType_!="mbt"){
00388 //      vpMbKltTracker* t = dynamic_cast<vpMbKltTracker*>(tracker_);
00389 //      t->setKltOpencv(kltTracker_);
00390 //    }
00391     
00392     // Dynamic reconfigure.
00393     if(trackerType_=="mbt+klt"){ // Hybrid Tracker reconfigure
00394       reconfigureSrv_ = new reconfigureSrvStruct<visp_tracker::ModelBasedSettingsConfig>::reconfigureSrv_t(mutex_, nodeHandlePrivate_);
00395       reconfigureSrvStruct<visp_tracker::ModelBasedSettingsConfig>::reconfigureSrv_t::CallbackType f =
00396         boost::bind(&reconfigureCallbackAndInitViewer,
00397                     boost::ref(nodeHandle_), boost::ref(tracker_),
00398                     boost::ref(image_), boost::ref(movingEdge_), boost::ref(kltTracker_),
00399                     boost::ref(mutex_), _1, _2);
00400       reconfigureSrv_->setCallback(f);
00401     }
00402     else if(trackerType_=="mbt"){ // Edge Tracker reconfigure
00403       reconfigureEdgeSrv_ = new reconfigureSrvStruct<visp_tracker::ModelBasedSettingsEdgeConfig>::reconfigureSrv_t(mutex_, nodeHandlePrivate_);
00404       reconfigureSrvStruct<visp_tracker::ModelBasedSettingsEdgeConfig>::reconfigureSrv_t::CallbackType f =
00405         boost::bind(&reconfigureEdgeCallbackAndInitViewer,
00406                     boost::ref(nodeHandle_), boost::ref(tracker_),
00407                     boost::ref(image_), boost::ref(movingEdge_),
00408                     boost::ref(mutex_), _1, _2);
00409       reconfigureEdgeSrv_->setCallback(f);
00410     }
00411     else{ // KLT Tracker reconfigure
00412       reconfigureKltSrv_ = new reconfigureSrvStruct<visp_tracker::ModelBasedSettingsKltConfig>::reconfigureSrv_t(mutex_, nodeHandlePrivate_);
00413       reconfigureSrvStruct<visp_tracker::ModelBasedSettingsKltConfig>::reconfigureSrv_t::CallbackType f =
00414         boost::bind(&reconfigureKltCallbackAndInitViewer,
00415                     boost::ref(nodeHandle_), boost::ref(tracker_),
00416                     boost::ref(image_), boost::ref(kltTracker_),
00417                     boost::ref(mutex_), _1, _2);
00418       reconfigureKltSrv_->setCallback(f);
00419     }
00420     
00421     // Wait for the image to be initialized.
00422     waitForImage();
00423     if (this->exiting())
00424       return;
00425     if (!image_.getWidth() || !image_.getHeight())
00426       throw std::runtime_error("failed to retrieve image");
00427 
00428     // Tracker initialization.
00429     initializeVpCameraFromCameraInfo(cameraParameters_, info_);
00430 
00431     // Double check camera parameters.
00432     if (cameraParameters_.get_px () == 0.
00433         || cameraParameters_.get_px () == 1.
00434         || cameraParameters_.get_py () == 0.
00435         || cameraParameters_.get_py () == 1.
00436         || cameraParameters_.get_u0 () == 0.
00437         || cameraParameters_.get_u0 () == 1.
00438         || cameraParameters_.get_v0 () == 0.
00439         || cameraParameters_.get_v0 () == 1.)
00440       ROS_WARN ("Dubious camera parameters detected.\n"
00441                 "\n"
00442                 "It seems that the matrix P from your camera\n"
00443                 "calibration topics is wrong.\n"
00444                 "The tracker will continue anyway, but you\n"
00445                 "should double check your calibration data,\n"
00446                 "especially if the model re-projection fails.\n"
00447                 "\n"
00448                 "This warning is triggered is px, py, u0 or v0\n"
00449                 "is set to 0. or 1. (exactly).");
00450 
00451     tracker_->setCameraParameters(cameraParameters_);
00452     tracker_->setDisplayFeatures(false);
00453 
00454     ROS_INFO_STREAM(cameraParameters_);
00455 
00456     // Service declaration.
00457     initCallback_t initCallback =
00458       boost::bind(&Tracker::initCallback, this, _1, _2);
00459 
00460     initService_ = nodeHandle_.advertiseService
00461       (visp_tracker::init_service, initCallback);
00462   }
00463   
00464   Tracker::~Tracker()
00465   {
00466     delete tracker_;  
00467 
00468     if(reconfigureSrv_ != NULL)
00469       delete reconfigureSrv_;
00470 
00471     if(reconfigureKltSrv_ != NULL)
00472       delete reconfigureKltSrv_;
00473 
00474     if(reconfigureEdgeSrv_ != NULL)
00475       delete reconfigureEdgeSrv_;
00476   }
00477 
00478   void Tracker::spin()
00479   {    
00480       ros::Rate loopRateTracking(100);
00481       tf::Transform transform;
00482       std_msgs::Header lastHeader;
00483 
00484       while (!exiting())
00485       {
00486           // When a camera sequence is played several times,
00487           // the seq id will decrease, in this case we want to
00488           // continue the tracking.
00489           if (header_.seq < lastHeader.seq)
00490               lastTrackedImage_ = 0;
00491 
00492           if (lastTrackedImage_ < header_.seq)
00493           {
00494               lastTrackedImage_ = header_.seq;
00495 
00496               // If we can estimate the camera displacement using tf,
00497               // we update the cMo to compensate for robot motion.
00498               if (compensateRobotMotion_)
00499                   try
00500               {
00501                   tf::StampedTransform stampedTransform;
00502                   listener_.lookupTransform
00503                           (header_.frame_id, // camera frame name
00504                            header_.stamp,    // current image time
00505                            header_.frame_id, // camera frame name
00506                            lastHeader.stamp, // last processed image time
00507                            worldFrameId_,    // frame attached to the environment
00508                            stampedTransform
00509                            );
00510                   vpHomogeneousMatrix newMold;
00511                   transformToVpHomogeneousMatrix (newMold, stampedTransform);
00512                   cMo_ = newMold * cMo_;
00513 
00514                   mutex_.lock();
00515                   tracker_->setPose(image_, cMo_);
00516                   mutex_.unlock();
00517               }
00518               catch(tf::TransformException& e)
00519               {
00520                 mutex_.unlock();
00521               }
00522 
00523               // If we are lost but an estimation of the object position
00524               // is provided, use it to try to reinitialize the system.
00525               if (state_ == LOST)
00526               {
00527                   // If the last received message is recent enough,
00528                   // use it otherwise do nothing.
00529                   if (ros::Time::now () - objectPositionHint_.header.stamp
00530                           < ros::Duration (1.))
00531                       transformToVpHomogeneousMatrix
00532                               (cMo_, objectPositionHint_.transform);
00533 
00534                   mutex_.lock();
00535                   tracker_->setPose(image_, cMo_);
00536                   mutex_.unlock();
00537               }
00538 
00539               // We try to track the image even if we are lost,
00540               // in the case the tracker recovers...
00541               if (state_ == TRACKING || state_ == LOST)
00542                   try
00543               {
00544                   mutex_.lock();
00545                   // tracker_->setPose(image_, cMo_); // Removed as it is not necessary when the pose is not modified from outside.
00546                   tracker_->track(image_);
00547                   tracker_->getPose(cMo_);
00548                   mutex_.unlock();
00549               }
00550               catch(...)
00551               {
00552                   mutex_.unlock();
00553                   ROS_WARN_THROTTLE(10, "tracking lost");
00554                   state_ = LOST;
00555               }
00556 
00557               // Publish the tracking result.
00558               if (state_ == TRACKING)
00559               {
00560                   geometry_msgs::Transform transformMsg;
00561                   vpHomogeneousMatrixToTransform(transformMsg, cMo_);
00562 
00563                   // Publish position.
00564                   if (transformationPublisher_.getNumSubscribers        () > 0)
00565                   {
00566                       geometry_msgs::TransformStampedPtr objectPosition
00567                               (new geometry_msgs::TransformStamped);
00568                       objectPosition->header = header_;
00569                       objectPosition->child_frame_id = childFrameId_;
00570                       objectPosition->transform = transformMsg;
00571                       transformationPublisher_.publish(objectPosition);
00572                   }
00573 
00574                   // Publish result.
00575                   if (resultPublisher_.getNumSubscribers        () > 0)
00576                   {
00577                       geometry_msgs::PoseWithCovarianceStampedPtr result
00578                               (new geometry_msgs::PoseWithCovarianceStamped);
00579                       result->header = header_;
00580                       result->pose.pose.position.x =
00581                               transformMsg.translation.x;
00582                       result->pose.pose.position.y =
00583                               transformMsg.translation.y;
00584                       result->pose.pose.position.z =
00585                               transformMsg.translation.z;
00586 
00587                       result->pose.pose.orientation.x =
00588                               transformMsg.rotation.x;
00589                       result->pose.pose.orientation.y =
00590                               transformMsg.rotation.y;
00591                       result->pose.pose.orientation.z =
00592                               transformMsg.rotation.z;
00593                       result->pose.pose.orientation.w =
00594                               transformMsg.rotation.w;
00595                       const vpMatrix& covariance =
00596                               tracker_->getCovarianceMatrix();
00597                       for (unsigned i = 0; i < covariance.getRows(); ++i)
00598                           for (unsigned j = 0; j < covariance.getCols(); ++j)
00599                           {
00600                               unsigned idx = i * covariance.getCols() + j;
00601                               if (idx >= 36)
00602                                   continue;
00603                               result->pose.covariance[idx] = covariance[i][j];
00604                           }
00605                       resultPublisher_.publish(result);
00606                   }
00607 
00608                   // Publish moving edge sites.
00609                   if (movingEdgeSitesPublisher_.getNumSubscribers       () > 0)
00610                   {
00611                       visp_tracker::MovingEdgeSitesPtr sites
00612                               (new visp_tracker::MovingEdgeSites);
00613                       updateMovingEdgeSites(sites);
00614                       sites->header = header_;
00615                       movingEdgeSitesPublisher_.publish(sites);
00616                   }
00617                   // Publish KLT points.
00618                   if (kltPointsPublisher_.getNumSubscribers     () > 0)
00619                   {
00620                       visp_tracker::KltPointsPtr klt
00621                               (new visp_tracker::KltPoints);
00622                       updateKltPoints(klt);
00623                       klt->header = header_;
00624                       kltPointsPublisher_.publish(klt);
00625                   }
00626 
00627                   // Publish to tf.
00628                   transform.setOrigin
00629                           (tf::Vector3(transformMsg.translation.x,
00630                                        transformMsg.translation.y,
00631                                        transformMsg.translation.z));
00632                   transform.setRotation
00633                           (tf::Quaternion
00634                            (transformMsg.rotation.x,
00635                             transformMsg.rotation.y,
00636                             transformMsg.rotation.z,
00637                             transformMsg.rotation.w));
00638                   transformBroadcaster_.sendTransform
00639                           (tf::StampedTransform
00640                            (transform,
00641                             header_.stamp,
00642                             header_.frame_id,
00643                             childFrameId_));
00644               }
00645           }
00646 
00647           lastHeader = header_;
00648           spinOnce();
00649           loopRateTracking.sleep();
00650 
00651       }
00652   }
00653 
00654   // Make sure that we have an image *and* associated calibration
00655   // data.
00656   void
00657   Tracker::waitForImage()
00658   {
00659     ros::Rate loop_rate(10);
00660     while (!exiting()
00661            && (!image_.getWidth() || !image_.getHeight())
00662            && (!info_ || info_->K[0] == 0.))
00663     {
00664       //ROS_INFO_THROTTLE(1, "waiting for a rectified image...");
00665       spinOnce();
00666       loop_rate.sleep();
00667     }
00668   }
00669 
00670   void
00671   Tracker::objectPositionHintCallback
00672   (const geometry_msgs::TransformStampedConstPtr& transform)
00673   {
00674     objectPositionHint_ = *transform;
00675   }
00676 
00677 } // end of namespace visp_tracker.


visp_tracker
Author(s): Thomas Moulard
autogenerated on Fri Aug 28 2015 13:36:39