trajectory_2_markers_alg_node.cpp
Go to the documentation of this file.
00001 #include "trajectory_2_markers_alg_node.h"
00002 
00003 Trajectory2MarkersAlgNode::Trajectory2MarkersAlgNode(void) :
00004   algorithm_base::IriBaseAlgorithm<Trajectory2MarkersAlgorithm>()
00005 {
00006   //init class attributes if necessary
00007   //this->loop_rate_ = 2;//in [Hz]
00008 
00009   // [init publishers]
00010   this->CovarianceMarkers_publisher_ = this->public_node_handle_.advertise<visualization_msgs::MarkerArray>("CovarianceMarkers", 1);
00011   this->TrajectoryMarkers_publisher_ = this->public_node_handle_.advertise<visualization_msgs::MarkerArray>("TrajectoryMarkers", 1);
00012   this->ActualPoseMarker_publisher_ = this->public_node_handle_.advertise<visualization_msgs::Marker>("ActualPoseMarker", 1);
00013   
00014   // [init subscribers]
00015   this->trajectory_subscriber_ = this->public_node_handle_.subscribe("trajectory", 100, &Trajectory2MarkersAlgNode::trajectory_callback, this);
00016   
00017   // [init services]
00018   
00019   // [init clients]
00020   
00021   // [init action servers]
00022   
00023   // [init action clients]
00024 
00025   nLoops_ = 0;
00026 }
00027 
00028 Trajectory2MarkersAlgNode::~Trajectory2MarkersAlgNode(void)
00029 {
00030   // [free dynamic memory]
00031 }
00032 
00033 void Trajectory2MarkersAlgNode::mainNodeThread(void)
00034 {
00035   // [fill msg structures]
00036   // [fill srv structure and make request to the server]
00037   // [fill action structure and make request to the action server]
00038   // [publish messages]
00039 }
00040 
00041 /*  [subscriber callbacks] */
00042 void Trajectory2MarkersAlgNode::trajectory_callback(const iri_poseslam::Trajectory::ConstPtr& msg)
00043 { 
00044   //ROS_INFO("Trajectory2MarkersAlgNode::trajectory_callback: New Message Received");
00045   //ROS_INFO_STREAM(*msg);
00046   
00047   // draw covariances and if new trajectory, 
00048   drawTrajectory(*msg);
00049   
00050   // publish trajectory, covariance and actual markers
00051   this->CovarianceMarkers_publisher_.publish(get_covariance_markers());
00052   this->TrajectoryMarkers_publisher_.publish(get_trajectory_marker());
00053   this->ActualPoseMarker_publisher_.publish(get_actual_marker());
00054 }
00055 
00056 /*  [service callbacks] */
00057 
00058 /*  [action callbacks] */
00059 
00060 /*  [action requests] */
00061 
00062 void Trajectory2MarkersAlgNode::node_config_update(Config &config, uint32_t level)
00063 {
00064   this->alg_.lock();
00065 
00066   config_ = config;
00067 
00068   this->alg_.unlock();
00069 
00070   initialize_markers();
00071 }
00072 
00073 void Trajectory2MarkersAlgNode::addNodeDiagnostics(void)
00074 {
00075 }
00076 
00077 /* main function */
00078 int main(int argc,char *argv[])
00079 {
00080   return algorithm_base::main<Trajectory2MarkersAlgNode>(argc, argv, "trajectory_2_markers_alg_node");
00081 }
00082 
00083 void Trajectory2MarkersAlgNode::initialize_markers()
00084 {
00085   // trajectory line initialization
00086   trajectory_marker_.header.stamp = ros::Time::now();
00087   trajectory_marker_.header.frame_id = "/world";
00088   trajectory_marker_.type = visualization_msgs::Marker::LINE_STRIP;
00089   trajectory_marker_.action = visualization_msgs::Marker::ADD;
00090   
00091   trajectory_marker_.color.a = config_.line_color_a;
00092   trajectory_marker_.color.r = config_.line_color_r;
00093   trajectory_marker_.color.g = config_.line_color_g;
00094   trajectory_marker_.color.b = config_.line_color_b;
00095   
00096   trajectory_marker_.ns = "/trajectory";
00097   trajectory_marker_.id = 1;
00098   
00099   trajectory_marker_.scale.x = config_.line_width;
00100   
00101   // loop line initialization
00102   loops_marker_.header.stamp = ros::Time::now();
00103   loops_marker_.header.frame_id = "/world";
00104   loops_marker_.type = visualization_msgs::Marker::LINE_LIST;
00105   loops_marker_.action = visualization_msgs::Marker::ADD;
00106   
00107   loops_marker_.color.a = config_.line_loop_color_a;
00108   loops_marker_.color.r = config_.line_loop_color_r;
00109   loops_marker_.color.g = config_.line_loop_color_g;
00110   loops_marker_.color.b = config_.line_loop_color_b;
00111   
00112   loops_marker_.ns = "/loops";
00113   loops_marker_.id = 1;
00114   
00115   loops_marker_.scale.x = config_.line_loop_width;
00116   
00117   // actual marker initialization
00118   actual_marker_.header.stamp = ros::Time::now();
00119   actual_marker_.header.frame_id = "/world";
00120   actual_marker_.type = visualization_msgs::Marker::SPHERE;
00121   actual_marker_.action = visualization_msgs::Marker::ADD;
00122   
00123   actual_marker_.color.a = config_.actual_marker_color_a;
00124   actual_marker_.color.r = config_.actual_marker_color_r;
00125   actual_marker_.color.g = config_.actual_marker_color_g;
00126   actual_marker_.color.b = config_.actual_marker_color_b;
00127   
00128   actual_marker_.ns = "/actual";
00129   actual_marker_.id = 1;
00130 
00131   ROS_WARN("TR 2 MARKERS: Config updated");
00132 }
00133 
00134 // Trajectory2MarkersAlgNode Public API
00135 void Trajectory2MarkersAlgNode::drawTrajectory(const iri_poseslam::Trajectory& msg)
00136 {
00137   //ROS_INFO("TR 2 MARKERS: draw Covariances");
00138   
00139   // Reserve space
00140   if (loop_step_.capacity() == loop_step_.size())
00141     loop_step_.reserve(loop_step_.size() + 100);
00142 
00143   if (covariance_markers_.markers.capacity() == covariance_markers_.markers.size()) 
00144     covariance_markers_.markers.reserve(covariance_markers_.markers.size() + 100);
00145 
00146   if (trajectory_marker_.points.capacity() == trajectory_marker_.points.size()) 
00147     trajectory_marker_.points.reserve(trajectory_marker_.points.size() + 100);
00148 
00149   // Boolean vector of loopclosure
00150   bool LoopClosure = (msg.loops.size() > nLoops_ * 2);
00151   loop_step_.push_back(LoopClosure);
00152 
00153   uint step = msg.poses.size() - 1;
00154   
00155   // LOOP CLOSURE --> Recompute all markers
00156   if (LoopClosure)
00157   {
00158     //ROS_INFO("TR 2 MARKERS: Loop closed: nLoops_ = %i | msg.loops.size() / 2 = %i", nLoops_, msg.loops.size() / 2);
00159     
00160     // loops_marker_ (position of old loops and adding new(s) loop(s))
00161     nLoops_ = uint(msg.loops.size()) / 2;
00162     loops_marker_.points.clear();
00163     loops_marker_.points.reserve(nLoops_);
00164 
00165     for (uint i = 0; i < nLoops_; i++)
00166     {
00167       uint from = msg.loops.at(2 * i);
00168       uint with = msg.loops.at(2 * i + 1);
00169       
00170       loops_marker_.points.push_back(msg.poses.at(from).pose.pose.position);
00171       loops_marker_.points.push_back(msg.poses.at(with).pose.pose.position);
00172       loop_step_.at(from) = true;
00173       loop_step_.at(with) = true;
00174     }
00175     
00176     // covariance_markers_ & trajectory_marker_ (covariances and poses)
00177     covariance_markers_.markers.clear();
00178     covariance_markers_.markers.reserve(msg.states_2_steps.size());
00179     trajectory_marker_.points.clear();
00180     trajectory_marker_.points.reserve(msg.poses.size());
00181 
00182     for (uint i = 0; i < msg.poses.size(); i++)
00183     {
00184       // COVARIANCE for NON-REDUNDANT POSES
00185       if (msg.steps_2_states.at(i) != -1)
00186       {
00187         Eigen::Matrix2d covs = get_ith_cov(msg, i);
00188         double theta_cov = get_ith_theta_cov(msg, i);
00189         
00190         visualization_msgs::Marker aux_marker = create_marker(i, msg.header, covs, theta_cov, msg.poses.at(i).pose.pose.position, loop_step_.at(i));
00191         covariance_markers_.markers.push_back(aux_marker);
00192       }
00193       // TRAJECTORY for ALL POSES
00194       trajectory_marker_.points.push_back(msg.poses.at(i).pose.pose.position);
00195     }
00196   }
00197   // NOT LOOP CLOSURE
00198   else
00199   {
00200     // NOT REDUNDANT POSE --> Covariance marker
00201     if (msg.steps_2_states.back() != -1)
00202     {
00203       //ROS_INFO("TR 2 MARKERS: Non-redundant pose, step = %i msg.poses.size() = %i", step, msg.poses.size());
00204 
00205       //COVARIANCE
00206       Eigen::Matrix2d covs = get_ith_cov(msg, step);
00207       double theta_cov = get_ith_theta_cov(msg, step);
00208       
00209       visualization_msgs::Marker aux_marker = create_marker(step, msg.header, covs, theta_cov, msg.poses.back().pose.pose.position, false);
00210       
00211       covariance_markers_.markers.push_back(aux_marker);
00212     }
00213     // TRAJECTORY
00214     trajectory_marker_.points.push_back(msg.poses.back().pose.pose.position);
00215   } 
00216   
00217   // CHECK IF ANY MESSANGE HAVE BEEN LOST
00218   if (trajectory_marker_.points.size() - 1 != step)
00219     ROS_ERROR("TR 2 MARKERS: Step lost!");
00220 
00221   if (covariance_markers_.markers.size() != msg.states_2_steps.size())
00222     ROS_ERROR("TR 2 MARKERS: State lost!");
00223   
00224   // UPDATE ACTUAL MARKER
00225   Eigen::Matrix2d covs = get_ith_cov(msg, step);
00226   double theta_cov = get_ith_theta_cov(msg, step);
00227   change_actual_marker(covs, theta_cov, msg.poses.back().pose.pose.position, LoopClosure);
00228 }
00229 
00230 visualization_msgs::MarkerArray Trajectory2MarkersAlgNode::get_trajectory_marker() const
00231 {
00232   visualization_msgs::MarkerArray trajectory_markers_array_;
00233   trajectory_markers_array_.markers.push_back(loops_marker_);
00234   trajectory_markers_array_.markers.push_back(trajectory_marker_);
00235   
00236   return trajectory_markers_array_;
00237 }
00238 
00239 visualization_msgs::Marker Trajectory2MarkersAlgNode::get_actual_marker() const
00240 {
00241   return actual_marker_;
00242 }
00243 
00244 visualization_msgs::MarkerArray Trajectory2MarkersAlgNode::get_covariance_markers() const
00245 {
00246   return covariance_markers_;
00247 }
00248 
00249 visualization_msgs::Marker Trajectory2MarkersAlgNode::create_marker(const uint& id, const std_msgs::Header& header, const Eigen::Matrix2d& covs, const double& theta_cov, const geometry_msgs::Point& position, const bool& loopClosure) const
00250 {
00251   visualization_msgs::Marker current_marker_;
00252   current_marker_.header = header;
00253   current_marker_.type = visualization_msgs::Marker::SPHERE;
00254   current_marker_.action = visualization_msgs::Marker::ADD;
00255   
00256   if (loopClosure)
00257   {
00258     current_marker_.color.a = config_.marker_loop_color_a;
00259     current_marker_.color.r = config_.marker_loop_color_r;
00260     current_marker_.color.g = config_.marker_loop_color_g;
00261     current_marker_.color.b = config_.marker_loop_color_b;
00262   }
00263   else
00264   {
00265     current_marker_.color.a = config_.marker_color_a;
00266     current_marker_.color.r = config_.marker_color_r;
00267     current_marker_.color.g = config_.marker_color_g;
00268     current_marker_.color.b = config_.marker_color_b;
00269   }
00270   current_marker_.ns = "/positions";
00271   current_marker_.id = id;
00272   //ROS_INFO("step %u", id);
00273   
00274   //ROS_INFO("cov:\n%f\t%f \n%f\t%f",covs(0,0),covs(0,1),covs(1,0),covs(1,1));
00275   
00276   Eigen::SelfAdjointEigenSolver<Eigen::Matrix2d> eig(covs);
00277 
00278   const Eigen::Vector2d& eigValues (eig.eigenvalues());
00279   const Eigen::Matrix2d& eigVectors (eig.eigenvectors());
00280 
00281   double angle = (atan2(eigVectors(1, 0), eigVectors(0, 0)));
00282 
00283   double lengthMajor = sqrt(eigValues[0]);
00284   double lengthMinor = sqrt(eigValues[1]);
00285 
00286   //ROS_INFO("eigValues: %f %f",eigValues[0],eigValues[1]);
00287   //ROS_INFO("lengthMajor/Minor: %f %f",lengthMajor,lengthMinor);
00288 
00289   current_marker_.scale.x = lengthMajor + 0.001;
00290   current_marker_.scale.y = lengthMinor + 0.001;
00291   current_marker_.scale.z = 2 * sqrt(theta_cov) + 0.001;
00292   
00293   current_marker_.pose.position.x = position.x;
00294   current_marker_.pose.position.y = position.y;
00295   current_marker_.pose.position.z = position.z;
00296   current_marker_.pose.orientation = tf::createQuaternionMsgFromYaw(angle);
00297   //current_marker_.pose.orientation.w = cos(angle*0.5);
00298   //current_marker_.pose.orientation.z = sin(angle*0.5);
00299   
00300   return current_marker_;
00301 }
00302 
00303 void Trajectory2MarkersAlgNode::change_actual_marker(const Eigen::Matrix2d& covs, const double& theta_cov, const geometry_msgs::Point& position, const bool& loopClosure)
00304 {  
00305   if (loopClosure)
00306   {
00307     actual_marker_.color.a = config_.marker_loop_color_a;
00308     actual_marker_.color.r = config_.marker_loop_color_r;
00309     actual_marker_.color.g = config_.marker_loop_color_g;
00310     actual_marker_.color.b = config_.marker_loop_color_b;
00311   }
00312   else
00313   {
00314     actual_marker_.color.a = config_.actual_marker_color_a;
00315     actual_marker_.color.r = config_.actual_marker_color_r;
00316     actual_marker_.color.g = config_.actual_marker_color_g;
00317     actual_marker_.color.b = config_.actual_marker_color_b;
00318   }
00319     
00320   //ROS_INFO("cov:\n%f\t%f \n%f\t%f",covs(0,0),covs(0,1),covs(1,0),covs(1,1));
00321   
00322   Eigen::SelfAdjointEigenSolver<Eigen::Matrix2d> eig(covs);
00323 
00324   const Eigen::Vector2d& eigValues (eig.eigenvalues());
00325   const Eigen::Matrix2d& eigVectors (eig.eigenvectors());
00326 
00327   double angle = (atan2(eigVectors(1, 0), eigVectors(0, 0)));
00328 
00329   double lengthMajor = sqrt(eigValues[0]);
00330   double lengthMinor = sqrt(eigValues[1]);
00331 
00332   //ROS_INFO("eigValues: %f %f",eigValues[0],eigValues[1]);
00333   //ROS_INFO("lengthMajor/Minor: %f %f",lengthMajor,lengthMinor);
00334 
00335   actual_marker_.scale.x = lengthMajor + 0.001;
00336   actual_marker_.scale.y = lengthMinor + 0.001;
00337   actual_marker_.scale.z = 2 * sqrt(theta_cov) + 0.001;
00338   
00339   actual_marker_.pose.position.x = position.x;
00340   actual_marker_.pose.position.y = position.y;
00341   actual_marker_.pose.position.z = position.z;
00342   actual_marker_.pose.orientation = tf::createQuaternionMsgFromYaw(angle);
00343   //current_marker_.pose.orientation.w = cos(angle*0.5);
00344   //current_marker_.pose.orientation.z = sin(angle*0.5);
00345 }
00346 
00347 Eigen::Matrix2d Trajectory2MarkersAlgNode::get_ith_cov(const iri_poseslam::Trajectory& msg, const uint i) const
00348 {
00349   //ROS_INFO("get cov: msg.poses.size() = %i - idx = %i", msg.poses.size(), i);
00350   Eigen::Matrix2d covs;
00351   covs(0, 0) = msg.poses.at(i).pose.covariance.at(0);
00352   covs(0, 1) = msg.poses.at(i).pose.covariance.at(1);
00353   covs(1, 0) = msg.poses.at(i).pose.covariance.at(3);
00354   covs(1, 1) = msg.poses.at(i).pose.covariance.at(4);
00355 
00356   return covs;
00357 }
00358 
00359 double Trajectory2MarkersAlgNode::get_ith_theta_cov(const iri_poseslam::Trajectory& msg, const uint i) const
00360 {
00361   //ROS_INFO("get theta cov: msg.poses.size() = %i - idx = %i", msg.poses.size(), i);
00362   
00363   return msg.poses.at(i).pose.covariance.at(8);
00364 }


iri_poseslam
Author(s): Joan Vallvé
autogenerated on Fri Dec 6 2013 21:21:14