00001 #include "trajectory_2_markers_alg_node.h"
00002
00003 Trajectory2MarkersAlgNode::Trajectory2MarkersAlgNode(void) :
00004 algorithm_base::IriBaseAlgorithm<Trajectory2MarkersAlgorithm>()
00005 {
00006
00007
00008
00009
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
00015 this->trajectory_subscriber_ = this->public_node_handle_.subscribe("trajectory", 100, &Trajectory2MarkersAlgNode::trajectory_callback, this);
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 nLoops_ = 0;
00026 }
00027
00028 Trajectory2MarkersAlgNode::~Trajectory2MarkersAlgNode(void)
00029 {
00030
00031 }
00032
00033 void Trajectory2MarkersAlgNode::mainNodeThread(void)
00034 {
00035
00036
00037
00038
00039 }
00040
00041
00042 void Trajectory2MarkersAlgNode::trajectory_callback(const iri_poseslam::Trajectory::ConstPtr& msg)
00043 {
00044
00045
00046
00047
00048 drawTrajectory(*msg);
00049
00050
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
00057
00058
00059
00060
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
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
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
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
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
00135 void Trajectory2MarkersAlgNode::drawTrajectory(const iri_poseslam::Trajectory& msg)
00136 {
00137
00138
00139
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
00150 bool LoopClosure = (msg.loops.size() > nLoops_ * 2);
00151 loop_step_.push_back(LoopClosure);
00152
00153 uint step = msg.poses.size() - 1;
00154
00155
00156 if (LoopClosure)
00157 {
00158
00159
00160
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
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
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
00194 trajectory_marker_.points.push_back(msg.poses.at(i).pose.pose.position);
00195 }
00196 }
00197
00198 else
00199 {
00200
00201 if (msg.steps_2_states.back() != -1)
00202 {
00203
00204
00205
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
00214 trajectory_marker_.points.push_back(msg.poses.back().pose.pose.position);
00215 }
00216
00217
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
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
00273
00274
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
00287
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
00298
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
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
00333
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
00344
00345 }
00346
00347 Eigen::Matrix2d Trajectory2MarkersAlgNode::get_ith_cov(const iri_poseslam::Trajectory& msg, const uint i) const
00348 {
00349
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
00362
00363 return msg.poses.at(i).pose.covariance.at(8);
00364 }