00001
00002
00003
00004
00005
00006
00007
00008
00009
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
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
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
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
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
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
00081 ROS_WARN("Discarding AR marker with unrecognized id (%d)", msg->markers[i].id);
00082 continue;
00083 }
00084
00085
00086 TrackedMarker& marker = tracked_markers[msg->markers[i].id];
00087
00088
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
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;
00135 marker.obs_list_.insert(marker.obs_list_.begin(), msgMarker.pose);
00136 marker.obs_list_.begin()->header = msgMarker.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
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 }
00165
00166 }