Go to the documentation of this file.00001 #include "trajectory_scans_2_pointcloud_alg_node.h"
00002
00003 TrajectoryScans2PointcloudAlgNode::TrajectoryScans2PointcloudAlgNode(void) :
00004 algorithm_base::IriBaseAlgorithm<TrajectoryScans2PointcloudAlgorithm>()
00005 {
00006
00007 emptyPointCloud_ = true;
00008
00009
00010
00011
00012 this->laser_pointcloud_publisher_ = this->public_node_handle_.advertise<sensor_msgs::PointCloud2>("laser_pointcloud", 100);
00013
00014
00015 this->scan_subscriber_ = this->public_node_handle_.subscribe("scan", 1000, &TrajectoryScans2PointcloudAlgNode::scan_callback, this);
00016 this->trajectory_subscriber_ = this->public_node_handle_.subscribe("trajectory", 100, &TrajectoryScans2PointcloudAlgNode::trajectory_callback, this);
00017
00018
00019
00020
00021
00022
00023
00024
00025 }
00026
00027 TrajectoryScans2PointcloudAlgNode::~TrajectoryScans2PointcloudAlgNode(void)
00028 {
00029
00030 }
00031
00032 void TrajectoryScans2PointcloudAlgNode::mainNodeThread(void)
00033 {
00034
00035
00036
00037
00038
00039
00040
00041 }
00042
00043
00044 void TrajectoryScans2PointcloudAlgNode::scan_callback(const sensor_msgs::LaserScan::ConstPtr& msg)
00045 {
00046
00047
00048
00049
00050 if (laser_scan_buffer_.size() == laser_scan_buffer_.capacity())
00051 laser_scan_buffer_.reserve(laser_scan_buffer_.size() + 1000);
00052
00053 laser_scan_buffer_.push_back(*msg);
00054 }
00055
00056 void TrajectoryScans2PointcloudAlgNode::trajectory_callback(const iri_poseslam::Trajectory::ConstPtr& msg)
00057 {
00058
00059
00060
00061 iri_poseslam::Trajectory new_trajectory = *msg;
00062
00063
00064 if (new_trajectory.steps_2_states.back() != -1 || publish_redundant_)
00065 {
00066
00067
00068 bool added = false;
00069 while (!added)
00070 {
00071 if (laser_scan_buffer_.front().header.seq == new_trajectory.poses.back().header.seq)
00072 {
00073 trajectory_laser_scan_buffer_.push_back(laser_scan_buffer_.front());
00074 laser_scan_buffer_.erase(laser_scan_buffer_.begin());
00075 added = true;
00076
00077 }
00078 else if (laser_scan_buffer_.front().header.seq < new_trajectory.poses.back().header.seq)
00079 laser_scan_buffer_.erase(laser_scan_buffer_.begin());
00080 else
00081 {
00082 ROS_ERROR("TR 2 PC: Last trajectory pose laser scan not found!");
00083 sensor_msgs::LaserScan empty_LaserScan;
00084 empty_LaserScan.header = new_trajectory.poses.back().header;
00085 trajectory_laser_scan_buffer_.push_back(empty_LaserScan);
00086 added = true;
00087 }
00088
00089 }
00090 }
00091
00092
00093 if (recompute_PointCloud_msg(new_trajectory))
00094 {
00095
00096 this->laser_pointcloud_publisher_.publish(this->PointCloud_msg_);
00097 ROS_DEBUG("TR 2 PC: PointCloud_msg_ published! size = %u", PointCloud_msg_.height * PointCloud_msg_.width);
00098 }
00099 }
00100
00101
00102
00103
00104
00105
00106
00107 void TrajectoryScans2PointcloudAlgNode::node_config_update(Config &config, uint32_t level)
00108 {
00109 this->alg_.lock();
00110
00111 T_laser_frame = transformation_matrix(config.dx_base_2_laser, config.dy_base_2_laser, config.dz_base_2_laser, config.dth_base_2_laser);
00112 publish_redundant_ = config.publish_redundant;
00113
00114 ROS_WARN("TR 2 PC: Config updated");
00115
00116 this->alg_.unlock();
00117 }
00118
00119 void TrajectoryScans2PointcloudAlgNode::addNodeDiagnostics(void)
00120 {
00121 }
00122
00123
00124 int main(int argc,char *argv[])
00125 {
00126 return algorithm_base::main<TrajectoryScans2PointcloudAlgNode>(argc, argv, "trajectory_scans_2_pointcloud_alg_node");
00127 }
00128
00129 bool TrajectoryScans2PointcloudAlgNode::recompute_PointCloud_msg(const iri_poseslam::Trajectory& trajectory)
00130 {
00131 bool cloud_changed;
00132 bool LoopClosed = false;
00133 if (trajectory.loops.size() > 0)
00134 LoopClosed = (trajectory.loops.back() == trajectory.states_2_steps.back() && trajectory.steps_2_states.back() != -1);
00135
00136
00137 if (LoopClosed)
00138 {
00139 clear_PointCloud_msg();
00140
00141 ROS_DEBUG("TR 2 PC: Loop Closed! Recompute all %u poses of the trajectory with %u laser scans", uint(trajectory.poses.size()), uint(trajectory_laser_scan_buffer_.size()));
00142
00143 for (uint i = 0; i < trajectory.poses.size(); i++)
00144 {
00145 sensor_msgs::LaserScan laser_scan;
00146
00147 if (publish_redundant_)
00148 laser_scan = trajectory_laser_scan_buffer_.at(i);
00149
00150 else if (trajectory.steps_2_states.at(i) != -1)
00151 laser_scan = trajectory_laser_scan_buffer_.at(trajectory.steps_2_states.at(i));
00152
00153 if (publish_redundant_ || trajectory.steps_2_states.at(i) != -1)
00154 {
00155 if (laser_scan.header.seq != trajectory.poses.at(i).header.seq)
00156 ROS_ERROR("TR 2 PC: headers don't match! step %i", i);
00157
00158 add_to_PointCloud_msg(laser_scan_to_point_cloud(laser_scan, trajectory.poses.at(i).pose.pose));
00159 cloud_changed = true;
00160 }
00161 }
00162
00163 }
00164
00165
00166 else if (trajectory.steps_2_states.back() != -1 || publish_redundant_)
00167 {
00168
00169 add_to_PointCloud_msg(laser_scan_to_point_cloud(trajectory_laser_scan_buffer_.back(), trajectory.poses.back().pose.pose));
00170 cloud_changed = true;
00171 }
00172
00173 return cloud_changed;
00174 }
00175
00176 sensor_msgs::PointCloud2 TrajectoryScans2PointcloudAlgNode::laser_scan_to_point_cloud(const sensor_msgs::LaserScan& LScan, const geometry_msgs::Pose& pose)
00177 {
00178 sensor_msgs::PointCloud2 pcloud;
00179 sensor_msgs::PointCloud2 transformed_pcloud;
00180
00181 laser_projector_.projectLaser(LScan, pcloud, LScan.range_max - 0.0001);
00182
00183 Matrix4f T_pose = transformation_matrix(pose.position.x, pose.position.y, pose.position.z, tf::getYaw(pose.orientation));
00184
00185 pcl_ros::transformPointCloud(T_pose * T_laser_frame, pcloud, transformed_pcloud);
00186
00187 return transformed_pcloud;
00188 }
00189
00190 void TrajectoryScans2PointcloudAlgNode::add_to_PointCloud_msg(const sensor_msgs::PointCloud2& newPointCloud)
00191 {
00192
00193 pcl::PointCloud<pcl::PointXYZ> newcloud;
00194
00195 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud2 (new pcl::PointCloud<pcl::PointXYZ>);
00196 pcl::fromROSMsg(newPointCloud, *cloud2);
00197
00198 if (emptyPointCloud_)
00199 {
00200 newcloud = *cloud2;
00201 emptyPointCloud_ = false;
00202
00203 }
00204 else
00205 {
00206 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud1 (new pcl::PointCloud<pcl::PointXYZ>);
00207 pcl::fromROSMsg(PointCloud_msg_, *cloud1);
00208
00209 newcloud = *cloud1 + *cloud2;
00210 }
00211
00212 pcl::toROSMsg(newcloud, PointCloud_msg_);
00213 PointCloud_msg_.header.frame_id = "/map";
00214 }
00215
00216 void TrajectoryScans2PointcloudAlgNode::clear_PointCloud_msg()
00217 {
00218 pcl::PointCloud<pcl::PointXYZ> cloud;
00219 pcl::fromROSMsg(PointCloud_msg_, cloud);
00220
00221 cloud.clear();
00222
00223 pcl::toROSMsg(cloud, PointCloud_msg_);
00224 }
00225
00226 Matrix4f TrajectoryScans2PointcloudAlgNode::transformation_matrix(const float x, const float y, const float z, const float alpha) const
00227 {
00228 Matrix4f T = MatrixXf::Identity(4,4);
00229
00230
00231 T(0,0) = cos(alpha);
00232 T(0,1) = -sin(alpha);
00233 T(1,0) = sin(alpha);
00234 T(1,1) = cos(alpha);
00235
00236
00237 T(0,3) = x;
00238 T(1,3) = y;
00239 T(2,3) = z;
00240
00241 return T;
00242 }