tracking.cpp
Go to the documentation of this file.
00001 /*
00002  * ar_marker_processor.hpp
00003  *
00004  *  LICENSE : BSD - https://raw.github.com/yujinrobot/yujin_ocs/license/LICENSE
00005  *
00006  *  Created on: Apr 6, 2013
00007  *      Author: jorge
00008  *  Modified on: Dec, 2013 
00009  *      Jihoon Lee
00010  */
00011 
00012 #include "yocs_ar_marker_tracking/tracking.hpp"
00013 
00014 namespace yocs 
00015 {
00016 
00017 ARMarkerTracking::ARMarkerTracking() {
00018   init(); 
00019 }
00020 
00021 ARMarkerTracking::~ARMarkerTracking() {}
00022 
00023 bool ARMarkerTracking::init()
00024 {
00025   ros::NodeHandle nh, pnh("~");
00026   
00027   // Parameters
00028   pnh.param("max_valid_d_inc",    max_valid_d_inc_,        ARMarkerTrackingDefaultParams::MAX_VALID_D_INC);
00029   pnh.param("max_valid_h_inc",    max_valid_h_inc_,        ARMarkerTrackingDefaultParams::MAX_VALID_H_INC);
00030   pnh.param("max_tracking_time",  max_tracking_time_,      ARMarkerTrackingDefaultParams::MAX_TRACKING_TIME);
00031   pnh.param("min_penalized_dist", min_penalized_dist_,     ARMarkerTrackingDefaultParams::MIN_PENALIZED_DIST);
00032   pnh.param("max_reliable_dist",  max_reliable_dist_,      ARMarkerTrackingDefaultParams::MAX_RELIABLE_DIST);
00033   pnh.param("min_penalized_head", min_penalized_head_,     ARMarkerTrackingDefaultParams::MIN_PENALIZED_HEAD);
00034   pnh.param("max_reliable_head",  max_reliable_head_,      ARMarkerTrackingDefaultParams::MAX_RELIABLE_HEAD);
00035 
00036   if (nh.getParam("ar_track_alvar/max_frequency", ar_tracker_freq_) == false)
00037   {
00038     ar_tracker_freq_ = ARMarkerTrackingDefaultParams::AR_TRACKER_FREQ;
00039     ROS_WARN("Cannot get AR tracker frequency; using default value (%f)", ar_tracker_freq_);
00040     ROS_WARN("Confidence evaluation can get compromised if this is not the right value!");
00041   }
00042 
00043   sub_ar_markers_ = nh.subscribe("ar_track_alvar/ar_pose_marker", 1, &ARMarkerTracking::arPoseMarkersCB, this);
00044 
00045   // There are 18 different markers
00046   tracked_markers_.resize(ARMarkerTrackingDefaultParams::MARKERS_COUNT);
00047 
00048   return true;
00049 }
00050 
00051 void ARMarkerTracking::arPoseMarkersCB(const ar_track_alvar_msgs::AlvarMarkers::ConstPtr& msg)
00052 {
00053   // TODO: use confidence to incorporate covariance to global poses
00054   std::stringstream ss;
00055   for (unsigned int i = 0; i < msg->markers.size(); i++) {
00056     ss << " " << msg->markers[i].id;
00057   }
00058   ss << " ";
00059   if(msg->markers.size() > 0) {
00060     ROS_DEBUG_STREAM("AR Marker Tracking : received markers [" << ss.str() << "]");
00061   }
00062 
00063   // Maintain markers
00064   maintainTrackedMarkers(msg, tracked_markers_);
00065   spotted_markers_ = *msg;
00066   customCB(spotted_markers_, tracked_markers_);
00067 }
00068 
00069 void ARMarkerTracking::maintainTrackedMarkers(const ar_track_alvar_msgs::AlvarMarkers::ConstPtr& msg,std::vector<TrackedMarker>& tracked_markers)
00070 {
00071   // Make thresholds relative to the tracking frequency (as it can be dynamically changed)
00072   int obs_list_max_size  = (int)round(max_tracking_time_*ar_tracker_freq_);
00073   double max_valid_d_inc = max_valid_d_inc_ / ar_tracker_freq_;
00074   double max_valid_h_inc = max_valid_h_inc_ / ar_tracker_freq_;
00075 
00076   for (unsigned int i = 0; i < msg->markers.size(); i++)
00077   {
00078     if (msg->markers[i].id >= tracked_markers.size())
00079     {
00080       // A recognition error from Alvar markers tracker
00081       ROS_WARN("Discarding AR marker with unrecognized id (%d)", msg->markers[i].id);
00082       continue;
00083     }
00084     //ROS_INFO("Maintaining marker id = %d",msg->markers[i].id);
00085 
00086     TrackedMarker& marker = tracked_markers[msg->markers[i].id];
00087 
00088     // Confidence evaluation
00089     maintainTrackedMarker(marker, msg->markers[i], obs_list_max_size, max_valid_d_inc, max_valid_h_inc);
00090   }
00091 }
00092 
00093 
00094 void ARMarkerTracking::maintainTrackedMarker(TrackedMarker& marker,const ar_track_alvar_msgs::AlvarMarker& msgMarker, const int obs_list_max_size, const double max_valid_d_inc, const double max_valid_h_inc)
00095 {
00096   marker.distance = mtk::distance3D(msgMarker.pose.pose);
00097   marker.distance2d = mtk::distance2D(msgMarker.pose.pose.position.x, msgMarker.pose.pose.position.z, 0,0);
00098   marker.heading  = tf::getYaw(msgMarker.pose.pose.orientation) + M_PI/2.0;
00099 
00100   int position = 0;
00101   ros::Time now = ros::Time::now();
00102   geometry_msgs::PoseStamped prev = msgMarker.pose;
00103   for (ObsList::iterator it = marker.obs_list_.begin(); it != marker.obs_list_.end(); ++it)
00104   {
00105     double age = (now - it->header.stamp).toSec();
00106     if (age > ((position + 1)/ar_tracker_freq_) + 1.5)
00107     {
00108       int s0 = marker.obs_list_.size();
00109       marker.obs_list_.erase(it, marker.obs_list_.end());
00110       int s1 = marker.obs_list_.size();
00111       ROS_DEBUG("%d observations discarded (first one with position %d in the list) for being %f seconds old ( > %f)", s0 - s1, position, age, ((position + 1)/ar_tracker_freq_) + 1.5);
00112       break;
00113     }
00114 
00115     if ((mtk::distance3D(prev.pose, it->pose) > max_valid_d_inc) || (std::abs(mtk::minAngle(prev.pose, it->pose)) > max_valid_h_inc))
00116     {
00117       // Incoherent observation; stop going over the list and use current position value to fill confidence values
00118       ROS_DEBUG("%d  BREAK at %d   %f  %f     %f   %f        %f", msgMarker.id, position, mtk::distance3D(prev.pose, it->pose),  mtk::minAngle(prev.pose, it->pose), max_valid_d_inc, max_valid_h_inc, ar_tracker_freq_);
00119       break;
00120     }
00121 
00122     prev = *it;
00123     position++;
00124   }
00125 
00126   marker.conf_distance = marker.distance <= min_penalized_dist_ ? 1.0
00127                        : marker.distance >= max_reliable_dist_  ? 0.0
00128                        : 1.0 - std::pow((marker.distance - min_penalized_dist_) / (max_reliable_dist_ - min_penalized_dist_), 2);
00129   marker.conf_heading  = std::abs(marker.heading) <= min_penalized_head_ ? 1.0
00130                        : std::abs(marker.heading) >= max_reliable_head_  ? 0.0
00131                        : 1.0 - std::pow((std::abs(marker.heading) - min_penalized_head_) / (max_reliable_head_ - min_penalized_head_), 2);
00132   marker.stability     = marker.obs_list_.size() == 0 ? 0.0 : std::sqrt((double)position/(double)marker.obs_list_.size());
00133   marker.persistence   = std::sqrt((double)marker.obs_list_.size() / (double)obs_list_max_size);
00134   marker.confidence    = marker.conf_distance * marker.stability * marker.persistence; // * marker.conf_heading I don't understand how conf_heading works. it always <=-1.4 or 1.4 >= disable it until becomes necessary
00135   marker.obs_list_.insert(marker.obs_list_.begin(), msgMarker.pose);
00136   marker.obs_list_.begin()->header = msgMarker.header;  // bloody alvar tracker doesn't fill pose's header
00137   if (marker.obs_list_.size() > obs_list_max_size)
00138     marker.obs_list_.pop_back();
00139 
00140   ROS_DEBUG_STREAM(msgMarker.id << "\n" << marker);
00141 }
00142 
00143 void ARMarkerTracking::spin()
00144 {
00145   ros::spin();
00146 //  // Broadcasts the spotted ar markers tf
00147 //  if (tf_broadcast_freq_ > 0.0)
00148 //  {
00149 //    ros::Rate rate(tf_broadcast_freq_);
00150 //
00151 //    while(ros::ok())
00152 //    {
00153 //      rate.sleep();
00154 //      ros::spinOnce();
00155 //    }
00156 //  }
00157 //  else {
00158 //    while(ros::ok())
00159 //    {
00160 //      ros::Duration(0.5).sleep();
00161 //      ros::spinOnce();
00162 //    }
00163 //  }
00164 }
00165 
00166 } // yocs 


yocs_ar_marker_tracking
Author(s): Daniel Stonier, Jorge Santos
autogenerated on Thu Jun 6 2019 21:47:27