00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <ucl_drone/map/map_keyframe_based.h>
00011
00012 Map::Map()
00013 : visualizer(new pcl::visualization::PCLVisualizer("3D visualizer"))
00014 , cloud(new pcl::PointCloud< pcl::PointXYZRGBSIFT >())
00015 {
00016 cv::initModule_nonfree();
00017
00018
00019 this->processedImgReceived = false;
00020 this->tracking_lost = false;
00021 this->pending_reset = false;
00022
00023
00024 ros::param::get("~do_search", this->do_search);
00025 ros::param::get("~stop_if_lost", this->stop_if_lost);
00026
00027
00028
00029 threshold_lost = 10;
00030 threshold_new_keyframe = 50;
00031 threshold_new_keyframe_percentage = 0.25;
00032
00033
00034 reference_keyframe = new KeyFrame();
00035
00036
00037
00038 processed_image_channel_in = nh.resolveName("processed_image");
00039 processed_image_sub = nh.subscribe(processed_image_channel_in, 1, &Map::processedImageCb,
00040 this);
00041
00042 reset_pose_channel = nh.resolveName("reset_pose");
00043 reset_pose_sub = nh.subscribe(reset_pose_channel, 1, &Map::resetPoseCb, this);
00044
00045 end_reset_pose_channel = nh.resolveName("end_reset_pose");
00046 end_reset_pose_sub = nh.subscribe(end_reset_pose_channel, 1, &Map::endResetPoseCb, this);
00047
00048
00049
00050 pose_PnP_channel = nh.resolveName("pose_visual");
00051 pose_PnP_pub = nh.advertise< ucl_drone::Pose3D >(pose_PnP_channel, 1);
00052
00053 pose_correction_channel = nh.resolveName("pose_visual_correction");
00054 pose_correction_pub = nh.advertise< ucl_drone::Pose3D >(pose_correction_channel, 1);
00055
00056 target_channel_out = nh.resolveName("ucl_drone/target_detected");
00057 target_pub = nh.advertise< ucl_drone::TargetDetected >(target_channel_out, 1);
00058
00059
00060 pcl::visualization::PointCloudColorHandlerCustom< pcl::PointXYZRGBSIFT > single_color(cloud, 0,
00061 255, 0);
00062 visualizer->setBackgroundColor(0, 0.1, 0.3);
00063 visualizer->addPointCloud< pcl::PointXYZRGBSIFT >(cloud, single_color, "SIFT_cloud");
00064 visualizer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3,
00065 "SIFT_cloud");
00066 visualizer->addCoordinateSystem(1.0);
00067
00068
00069 if (!Read::CamMatrixParams("cam_matrix"))
00070 {
00071 ROS_ERROR("cam_matrix not properly transmitted");
00072 }
00073 if (!Read::ImgSizeParams("img_size"))
00074 {
00075 ROS_ERROR("img_size not properly transmitted");
00076 }
00077
00078 this->camera_matrix_K =
00079 (cv::Mat_< double >(3, 3) << Read::focal_length_x(), 0, Read::img_center_x(), 0,
00080 Read::focal_length_y(), Read::img_center_y(), 0, 0, 1);
00081
00082
00083 this->tvec = cv::Mat::zeros(3, 1, CV_64FC1);
00084 this->rvec = cv::Mat::zeros(3, 1, CV_64FC1);
00085
00086 this->init_planes();
00087
00088 ROS_DEBUG("simple_map initialized");
00089 }
00090
00091 Map::~Map()
00092 {
00093 }
00094
00095 void Map::resetPoseCb(const std_msgs::Empty& msg)
00096 {
00097 pending_reset = true;
00098 KeyFrame::resetList();
00099 this->cloud = boost::shared_ptr< pcl::PointCloud< pcl::PointXYZRGBSIFT > >(
00100 new pcl::PointCloud< pcl::PointXYZRGBSIFT >);
00101 processed_image_sub.shutdown();
00102
00103 this->visualizer->updatePointCloud< pcl::PointXYZRGBSIFT >(this->cloud, "SIFT_cloud");
00104
00105 this->previous_frame = Frame();
00106 this->tvec = cv::Mat::zeros(3, 1, CV_64FC1);
00107 this->rvec = cv::Mat::zeros(3, 1, CV_64FC1);
00108 processed_image_sub = nh.subscribe(processed_image_channel_in, 3, &Map::processedImageCb, this);
00109 }
00110
00111 void Map::endResetPoseCb(const std_msgs::Empty& msg)
00112 {
00113 pending_reset = false;
00114 }
00115
00116 void Map::processedImageCb(const ucl_drone::ProcessedImageMsg::ConstPtr processed_image_in)
00117 {
00118 TIC(callback);
00119 if (pending_reset)
00120 return;
00121 this->processedImgReceived = true;
00122 this->lastProcessedImgReceived = processed_image_in;
00123 Frame current_frame(processed_image_in);
00124
00125 #ifdef DEBUG_PROJECTION // the cloud is re-initialized at each new message and alawys centered at
00126
00127 this->cloud = boost::shared_ptr< pcl::PointCloud< pcl::PointXYZRGBSIFT > >(
00128 new pcl::PointCloud< pcl::PointXYZRGBSIFT >);
00129 current_frame.msg.pose.x = 0;
00130 current_frame.msg.pose.y = 0;
00131 #endif
00132
00133 if (this->cloud->size() != 0)
00134 {
00135 TIC(doPnP);
00136 std::vector< int > inliers;
00137 bool PnP_success = this->doPnP(current_frame, PnP_pose, inliers, reference_keyframe);
00138 TOC(doPnP, "doPnP");
00139
00140
00141
00142
00143
00144 if (abs(PnP_pose.z - current_frame.msg.pose.z) > 0.8)
00145 {
00146 ROS_INFO("TRACKING LOST ! (PnP found bad symmetric clone? jump of: %f)",
00147 fabs(PnP_pose.z - current_frame.msg.pose.z));
00148 PnP_success = false;
00149 }
00150
00151 if (PnP_success)
00152 {
00153 TIC(publish);
00154 this->publishPoseVisual(current_frame.msg.pose, PnP_pose);
00155 TOC(publish, "publish");
00156 current_frame.pose_visual_msg = PnP_pose;
00157
00158
00159
00160
00161
00162
00163
00164
00165 }
00166
00167
00168
00169 if (this->newKeyFrameNeeded(inliers.size()))
00170 {
00171 ROS_DEBUG("new keyframe needed");
00172 int keyframe_ID = -1;
00173
00174 ucl_drone::Pose3D pose;
00175 if (!PnP_success)
00176 {
00177 pose = current_frame.msg.pose;
00178 }
00179 else
00180 {
00181 pose = PnP_pose;
00182 pose.z = current_frame.msg.pose.z;
00183
00184
00185
00186 pose.rotX = current_frame.msg.pose.rotX;
00187 pose.rotY = current_frame.msg.pose.rotY;
00188 }
00189
00190 bool search_success = false;
00191 if (do_search)
00192 {
00193 TIC(search);
00194 search_success = closestKeyFrame(pose, keyframe_ID, current_frame);
00195 TOC(search, "search");
00196 }
00197
00198 if (search_success)
00199 {
00200 reference_keyframe = KeyFrame::getKeyFrame(keyframe_ID);
00201 }
00202 else
00203 {
00204 reference_keyframe = new KeyFrame(pose);
00205
00206
00207 std::vector< cv::Point3f > points_out;
00208 TIC(projection);
00209 projection_2D(current_frame.imgPoints, pose, points_out);
00210 TOC(projection, "projection");
00211 pcl::PointCloud< pcl::PointXYZRGBSIFT >::Ptr pointcloud(
00212 new pcl::PointCloud< pcl::PointXYZRGBSIFT >);
00213 current_frame.convertToPcl(points_out, reference_keyframe->getID(), pointcloud);
00214 reference_keyframe->addPoints(pointcloud);
00215
00216 *(this->cloud) += *pointcloud;
00217
00218 this->visualizer->updatePointCloud< pcl::PointXYZRGBSIFT >(this->cloud, "SIFT_cloud");
00219 }
00220 TOC(callback, "callback");
00221 return;
00222 }
00223 }
00224 else
00225 {
00226 ROS_DEBUG("MAP INITIALIZATION");
00227 reference_keyframe = new KeyFrame(current_frame.msg.pose);
00228
00229 std::vector< cv::Point3f > points_out;
00230 projection_2D(current_frame.imgPoints, current_frame.msg.pose, points_out,
00231 false);
00232 pcl::PointCloud< pcl::PointXYZRGBSIFT >::Ptr pointcloud(
00233 new pcl::PointCloud< pcl::PointXYZRGBSIFT >);
00234 current_frame.convertToPcl(points_out, reference_keyframe->getID(), pointcloud);
00235 reference_keyframe->addPoints(pointcloud);
00236 *(this->cloud) = *pointcloud;
00237
00238 PnP_pose.header.stamp =
00239 processed_image_in->pose.header.stamp;
00240 this->publishPoseVisual(current_frame.msg.pose, PnP_pose);
00241 ROS_DEBUG("MAP INITIALIZATION : rotZ = %f", current_frame.msg.pose.rotZ);
00242 this->visualizer->updatePointCloud< pcl::PointXYZRGBSIFT >(this->cloud, "SIFT_cloud");
00243 }
00244
00245 ROS_DEBUG("Present keyframe id = %d", reference_keyframe->getID());
00246 previous_frame = current_frame;
00247
00248 TOC(callback, "callback");
00249 }
00250
00251 void Map::publishPoseVisual(ucl_drone::Pose3D poseFrame, ucl_drone::Pose3D posePnP)
00252 {
00253 ucl_drone::Pose3D pose_correction;
00254 pose_correction.header.stamp = ros::Time::now();
00255 pose_correction.x = poseFrame.x - posePnP.x;
00256 pose_correction.y = poseFrame.y - posePnP.y;
00257 pose_correction.z = poseFrame.z - posePnP.z;
00258 pose_correction.rotX = poseFrame.rotX - posePnP.rotX;
00259 pose_correction.rotY = poseFrame.rotY - posePnP.rotY;
00260 pose_correction.rotZ = poseFrame.rotZ - posePnP.rotZ;
00261 pose_PnP_pub.publish(PnP_pose);
00262 pose_correction_pub.publish(pose_correction);
00263 }
00264
00265 bool Map::doPnP(Frame current_frame, ucl_drone::Pose3D& PnP_pose, std::vector< int >& inliers,
00266 KeyFrame* ref_keyframe)
00267 {
00268 std::vector< std::vector< int > > idx_matching_points;
00269 std::vector< cv::Point3f > ref_keyframe_matching_points;
00270 std::vector< cv::Point2f > frame_matching_points;
00271
00272 TIC(matchWithFrame);
00273 ref_keyframe->matchWithFrame(current_frame, idx_matching_points, ref_keyframe_matching_points,
00274 frame_matching_points);
00275 if (ref_keyframe == reference_keyframe)
00276 TOC(matchWithFrame, "matchWithFrame");
00277
00278 if (ref_keyframe_matching_points.size() < threshold_lost)
00279 {
00280 if (ref_keyframe == reference_keyframe)
00281 ROS_INFO("TRACKING LOST ! (Not enough matching points: %d)",
00282 ref_keyframe_matching_points.size());
00283 return false;
00284 }
00285
00286 cv::Mat_< double > tcam, cam2world, world2drone, distCoeffs;
00287
00288 distCoeffs = (cv::Mat_< double >(1, 5) << 0, 0, 0, 0, 0);
00289
00290 TIC(solvePnPRansac);
00291
00292 cv::solvePnPRansac(ref_keyframe_matching_points, frame_matching_points, this->camera_matrix_K,
00293 distCoeffs, rvec, tvec, true, 2500, 2, 2 * threshold_new_keyframe, inliers,
00294 CV_P3P);
00295 TOC(solvePnPRansac, "solvePnPRansac");
00296
00297
00298
00299
00300 if (inliers.size() < threshold_lost)
00301 {
00302 if (ref_keyframe == reference_keyframe)
00303 ROS_INFO("TRACKING LOST ! (Not enough inliers)");
00304 return false;
00305 }
00306
00307 if (ref_keyframe == reference_keyframe)
00308 {
00309
00310 std::vector< cv::Point3f > inliers_ref_keyframe_matching_points;
00311 std::vector< cv::Point2f > inliers_frame_matching_points;
00312
00313 for (int j = 0; j < inliers.size(); j++)
00314 {
00315 int i = inliers[j];
00316
00317 inliers_ref_keyframe_matching_points.push_back(ref_keyframe_matching_points[i]);
00318 inliers_frame_matching_points.push_back(frame_matching_points[i]);
00319 }
00320
00321
00322 cv::solvePnP(inliers_ref_keyframe_matching_points, inliers_frame_matching_points,
00323 this->camera_matrix_K, distCoeffs, rvec, tvec, true, CV_EPNP);
00324 }
00325
00326 cv::Rodrigues(rvec, cam2world);
00327
00328 if (fabs(determinant(cam2world)) - 1 > 1e-07)
00329 {
00330 ROS_DEBUG("TRACKING LOST ! (Determinant of rotation matrix)");
00331 return false;
00332 }
00333
00334
00335 cv::Mat_< double > drone2cam =
00336 (cv::Mat_< double >(3, 3) << 0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0);
00337
00338 tcam = -cam2world.t() * tvec;
00339 PnP_pose.x = tcam(0);
00340 PnP_pose.y = tcam(1);
00341 PnP_pose.z = tcam(2);
00342
00343 cv::Mat_< double > world2cam = cam2world.t();
00344 cv::Mat_< double > cam2drone = drone2cam.t();
00345 world2drone = world2cam * cam2drone;
00346
00347 tf::Matrix3x3(world2drone(0, 0), world2drone(0, 1), world2drone(0, 2), world2drone(1, 0),
00348 world2drone(1, 1), world2drone(1, 2), world2drone(2, 0), world2drone(2, 1),
00349 world2drone(2, 2))
00350 .getRPY(PnP_pose.rotX, PnP_pose.rotY, PnP_pose.rotZ);
00351
00352 PnP_pose.xvel = 0.0;
00353 PnP_pose.yvel = 0.0;
00354 PnP_pose.zvel = 0.0;
00355 PnP_pose.rotXvel = 0.0;
00356 PnP_pose.rotYvel = 0.0;
00357 PnP_pose.rotZvel = 0.0;
00358
00359 PnP_pose.header.stamp = current_frame.msg.pose.header.stamp;
00360
00361 ROS_DEBUG("# img:%4d, keyframe%d:%4d, match:%4d, inliers:%4d", current_frame.imgPoints.size(),
00362 ref_keyframe->getID(), ref_keyframe->cloud->points.size(),
00363 ref_keyframe_matching_points.size(), inliers.size());
00364
00365 return true;
00366 }
00367
00369 void Map::targetDetectedPublisher()
00370 {
00371 if (processedImgReceived && target_pub.getNumSubscribers() > 0)
00372 {
00373 if (lastProcessedImgReceived->target_detected)
00374 {
00375 ROS_DEBUG("TARGET IS DETECTED");
00376
00377 ucl_drone::TargetDetected msg;
00378 msg.pose = lastProcessedImgReceived->pose;
00379 msg.img_point.x = lastProcessedImgReceived->target_points[4].x;
00380 msg.img_point.y = lastProcessedImgReceived->target_points[4].y;
00381 msg.img_point.z = 0;
00382 std::vector< cv::Point2f > target_center(1);
00383 target_center[0].x = lastProcessedImgReceived->target_points[4].x;
00384 target_center[0].y = lastProcessedImgReceived->target_points[4].y;
00385 std::vector< cv::Point3f > world_coord;
00386 projection_2D(target_center, msg.pose, world_coord);
00387 msg.world_point.x = world_coord[0].x;
00388 msg.world_point.y = world_coord[0].y;
00389 msg.world_point.z = world_coord[0].z;
00390 target_pub.publish(msg);
00391 }
00392 }
00393 }
00394
00395 void Map::init_planes()
00396 {
00397 float thres = 0.95;
00398 cv::Mat top_left = (cv::Mat_< double >(3, 1) << -Read::img_center_x() / Read::focal_length_x(),
00399 -Read::img_center_y() / Read::focal_length_y(), thres);
00400 cv::Mat top_right = (cv::Mat_< double >(3, 1)
00401 << (Read::img_width() - Read::img_center_x()) / Read::focal_length_x(),
00402 -Read::img_center_y() / Read::focal_length_y(), thres);
00403 cv::Mat bottom_right =
00404 (cv::Mat_< double >(3, 1) << (Read::img_width() - Read::img_center_x()) /
00405 Read::focal_length_x(),
00406 (Read::img_height() - Read::img_center_y()) / Read::focal_length_y(), thres);
00407 cv::Mat bottom_left =
00408 (cv::Mat_< double >(3, 1) << -Read::img_center_x() / Read::focal_length_x(),
00409 (Read::img_height() - Read::img_center_y()) / Read::focal_length_y(), thres);
00410 cam_plane_top = top_left.cross(top_right);
00411 cam_plane_right = top_right.cross(bottom_right);
00412 cam_plane_bottom = bottom_right.cross(bottom_left);
00413 cam_plane_left = bottom_left.cross(top_left);
00414 ROS_DEBUG("MAP: planes initilized");
00415 }
00416
00417 bool customLess(std::vector< int > a, std::vector< int > b)
00418 {
00419 return a[1] > b[1];
00420 }
00421
00422 bool Map::closestKeyFrame(const ucl_drone::Pose3D& pose, int& keyframe_ID, Frame current_frame)
00423 {
00424 std::vector< std::vector< int > > keyframes_ID;
00425 TIC(getVisibleKeyFrames)
00426 this->getVisibleKeyFrames(pose, keyframes_ID);
00427 TOC(getVisibleKeyFrames, "getVisibleKeyFrames")
00428
00429 int best_keyframe = -1;
00430 int best_keyframe_inlier_size = 0;
00431 std::vector< int > inliers;
00432 ucl_drone::Pose3D PnP_pose;
00433 KeyFrame* reference_keyframe_candidate;
00434
00435 for (int i = 0; i < keyframes_ID.size(); i++)
00436 {
00437
00438 if (keyframes_ID[i][1] > threshold_lost)
00439 {
00440
00441
00442 reference_keyframe_candidate = KeyFrame::getKeyFrame(keyframes_ID[i][0]);
00443 bool PnP_success =
00444 this->doPnP(current_frame, PnP_pose, inliers, reference_keyframe_candidate);
00445
00446
00447
00448
00449
00450
00451 if (abs(PnP_pose.z - current_frame.msg.pose.z) > 0.5)
00452 {
00453 PnP_success = false;
00454 }
00455
00456 if (PnP_success)
00457 {
00458
00459 if (inliers.size() > best_keyframe_inlier_size &&
00460 !this->newKeyFrameNeeded(inliers.size(), reference_keyframe_candidate))
00461 {
00462 best_keyframe = keyframes_ID[i][0];
00463 best_keyframe_inlier_size = inliers.size();
00464 }
00465 if (inliers.size() > 1.1 * threshold_new_keyframe)
00466 {
00467 break;
00468 }
00469 }
00470 }
00471 else
00472 {
00473 break;
00474
00475 }
00476 }
00477
00478
00479 if (best_keyframe == -1)
00480 {
00481 return false;
00482 }
00483 keyframe_ID = best_keyframe;
00484 return true;
00485 }
00486
00487 void Map::getVisibleKeyFrames(const ucl_drone::Pose3D& pose,
00488 std::vector< std::vector< int > >& keyframes_ID)
00489 {
00490 std::vector< int > idx;
00491 this->getVisiblePoints(pose, idx);
00492 int j;
00493 for (unsigned i = 0; i < idx.size(); ++i)
00494 {
00495 int id = cloud->points[idx[i]].keyframe_ID;
00496 for (j = 0; j < keyframes_ID.size(); j++)
00497 {
00498 if (id == keyframes_ID[j][0])
00499 {
00500 keyframes_ID[j][1]++;
00501 break;
00502 }
00503 }
00504 if (j == keyframes_ID.size())
00505 {
00506 std::vector< int > vec(2);
00507 vec[0] = id;
00508 vec[1] = 1;
00509 keyframes_ID.push_back(vec);
00510 }
00511 }
00512
00513 std::sort(keyframes_ID.begin(), keyframes_ID.end(), customLess);
00514
00515
00516
00517
00518
00519
00520 }
00521
00522 void Map::getVisiblePoints(const ucl_drone::Pose3D& pose, std::vector< int >& idx)
00523 {
00524 double yaw = -pose.rotZ;
00525 double pitch = -pose.rotY;
00526 double roll = -pose.rotX;
00527
00528 cv::Mat world2drone = rollPitchYawToRotationMatrix(roll, pitch, yaw);
00529
00530 cv::Mat_< double > drone2cam =
00531 (cv::Mat_< double >(3, 3) << 0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0);
00532 cv::Mat world2cam = drone2cam * world2drone;
00533
00534
00535
00536 cv::Mat world_plane_top = world2cam.t() * cam_plane_top;
00537 cv::Mat world_plane_right = world2cam.t() * cam_plane_right;
00538 cv::Mat world_plane_bottom = world2cam.t() * cam_plane_bottom;
00539 cv::Mat world_plane_left = world2cam.t() * cam_plane_left;
00540 cv::Mat translation = (cv::Mat_< double >(3, 1) << pose.x, pose.y, pose.z);
00541 double d_top = -translation.dot(world_plane_top);
00542 double d_right = -translation.dot(world_plane_right);
00543 double d_bottom = -translation.dot(world_plane_bottom);
00544 double d_left = -translation.dot(world_plane_left);
00545
00546
00547
00548 for (unsigned i = 0; i < cloud->points.size(); ++i)
00549 {
00550 cv::Mat point =
00551 (cv::Mat_< double >(3, 1) << cloud->points[i].x, cloud->points[i].y, cloud->points[i].z);
00552
00553 double t_top = point.dot(world_plane_top) + d_top;
00554 double t_right = point.dot(world_plane_right) + d_right;
00555 double t_bottom = point.dot(world_plane_bottom) + d_bottom;
00556 double t_left = point.dot(world_plane_left) + d_left;
00557
00558 if (t_top >= 0 && t_right >= 0 && t_bottom >= 0 && t_left >= 0)
00559 {
00560 idx.push_back(i);
00561 }
00562 }
00563 }
00564
00565 void Map::getDescriptors(const ucl_drone::Pose3D& pose, cv::Mat& descriptors,
00566 std::vector< int >& idx, bool only_visible)
00567 {
00568
00569 if (!only_visible)
00570 {
00571 descriptors = cv::Mat_< float >(cloud->points.size(), DESCRIPTOR_SIZE);
00572 for (unsigned i = 0; i < cloud->points.size(); ++i)
00573 {
00574 for (unsigned j = 0; j < DESCRIPTOR_SIZE; ++j)
00575 {
00576 descriptors.at< float >(i, j) = cloud->points[i].descriptor[j];
00577 }
00578 idx.push_back(i);
00579 }
00580 }
00581 if (only_visible)
00582
00583 {
00584 ROS_DEBUG("GET_DESCRIPTORS, pose:pos(%f, %f, %f) rot(%f, %f, %f)", pose.x, pose.y, pose.z,
00585 pose.rotX, pose.rotY, pose.rotZ);
00586
00587 this->getVisiblePoints(pose, idx);
00588 this->getDescriptors(idx, descriptors);
00589
00590 ROS_DEBUG(" %d POINTS VISIBLE", idx.size());
00591 }
00592 }
00593
00594 void Map::getDescriptors(const std::vector< int >& idx, cv::Mat& descriptors)
00595 {
00596 descriptors = cv::Mat_< float >(idx.size(), DESCRIPTOR_SIZE);
00597 for (unsigned i = 0; i < idx.size(); ++i)
00598 {
00599 for (unsigned j = 0; j < DESCRIPTOR_SIZE; ++j)
00600 {
00601 descriptors.at< float >(i, j) = cloud->points[idx[i]].descriptor[j];
00602 }
00603 }
00604 }
00605
00606 bool Map::newKeyFrameNeeded(int number_of_common_keypoints)
00607 {
00608 return newKeyFrameNeeded(number_of_common_keypoints, this->reference_keyframe);
00609 }
00610
00611 bool Map::newKeyFrameNeeded(int number_of_common_keypoints, KeyFrame* reference_keyframe_candidate)
00612 {
00613 return (number_of_common_keypoints < threshold_new_keyframe ||
00614 number_of_common_keypoints <
00615 threshold_new_keyframe_percentage * reference_keyframe_candidate->size());
00616 }
00617
00618 void cloud_debug(pcl::PointCloud< pcl::PointXYZRGBSIFT >::ConstPtr cloud)
00619 {
00620 for (size_t i = 0; i < cloud->points.size(); ++i)
00621 {
00622 ROS_DEBUG("points[%d] = (%f, %f, %f)", i, cloud->points[i].x, cloud->points[i].y,
00623 cloud->points[i].z);
00624 }
00625 }
00626
00627 int main(int argc, char** argv)
00628 {
00629 ros::init(argc, argv, "simple_map");
00630 ROS_INFO_STREAM("simple map started!");
00631
00632
00633
00634
00635
00636
00637 Map map;
00638 ros::Time t = ros::Time::now() + ros::Duration(13);
00639 while (ros::Time::now() < t)
00640 {
00641 map.visualizer->spinOnce(100);
00642 }
00643
00644 ros::Rate r(3);
00645
00646 int visualizer_count = 0;
00647
00648 while (ros::ok())
00649 {
00650 TIC(cloud);
00651 map.visualizer->spinOnce(10);
00652 TOC(cloud, "cloud");
00653
00654 TIC(target);
00655 map.targetDetectedPublisher();
00656 TOC(target, "target");
00657
00658 ros::spinOnce();
00659 r.sleep();
00660 }
00661 return 0;
00662 }