navigator.cpp
Go to the documentation of this file.
00001 
00024 #include "ccny_rgbd/apps/navigator.h"
00025 #include "aruco/aruco.h"
00026 namespace ccny_rgbd {
00027 
00028 Navigator::Navigator(
00029         const ros::NodeHandle& nh,
00030         const ros::NodeHandle& nh_private):
00031     nh_(nh),
00032     nh_private_(nh_private),
00033     rgbd_frame_index_(0)
00034 {
00035     ROS_INFO("Starting Navigator node");
00036 
00037     // **** params
00038 
00039     initParams();
00040 
00041     // **** publishers
00042 
00043     keyframes_pub_ = nh_.advertise<PointCloudT>(
00044                 "keyframes", queue_size_);
00045     poses_pub_ = nh_.advertise<visualization_msgs::Marker>(
00046                 "keyframe_poses", queue_size_);
00047     kf_assoc_pub_ = nh_.advertise<visualization_msgs::Marker>(
00048                 "keyframe_associations", queue_size_);
00049     path_pub_ = nh_.advertise<PathMsg>(
00050                 "mapper_path", queue_size_);
00051     aruco_pub_ = nh_.advertise<PathMsg>(
00052                 "aRuco_path", queue_size_);
00053 
00054     // **** services
00055 
00056     pub_keyframe_service_ = nh_.advertiseService(
00057                 "publish_keyframe", &Navigator::publishKeyframeSrvCallback, this);
00058     pub_keyframes_service_ = nh_.advertiseService(
00059                 "publish_keyframes", &Navigator::publishKeyframesSrvCallback, this);
00060     save_kf_service_ = nh_.advertiseService(
00061                 "save_keyframes", &Navigator::saveKeyframesSrvCallback, this);
00062     load_kf_service_ = nh_.advertiseService(
00063                 "load_keyframes", &Navigator::loadKeyframesSrvCallback, this);
00064     save_pcd_map_service_ = nh_.advertiseService(
00065                 "save_pcd_map", &Navigator::savePcdMapSrvCallback, this);
00066     save_octomap_service_ = nh_.advertiseService(
00067                 "save_octomap", &Navigator::saveOctomapSrvCallback, this);
00068     add_manual_keyframe_service_ = nh_.advertiseService(
00069                 "add_manual_keyframe", &Navigator::addManualKeyframeSrvCallback, this);
00070     generate_graph_service_ = nh_.advertiseService(
00071                 "generate_graph", &Navigator::generateGraphSrvCallback, this);
00072     solve_graph_service_ = nh_.advertiseService(
00073                 "solve_graph", &Navigator::solveGraphSrvCallback, this);
00074 
00075     // **** subscribers
00076 
00077     ImageTransport rgb_it(nh_);
00078     ImageTransport depth_it(nh_);
00079 
00080     sub_rgb_.subscribe(rgb_it,     "/camera/rgb/image_rect_color",   queue_size_);
00081     sub_depth_.subscribe(depth_it, "/camera/depth_registered/image_rect_raw", queue_size_);
00082     sub_info_.subscribe(nh_,       "/camera/rgb/camera_info",  queue_size_);
00083 
00084     // Synchronize inputs.
00085     sync_.reset(new RGBDSynchronizer3(
00086                     RGBDSyncPolicy3(queue_size_), sub_rgb_, sub_depth_, sub_info_));
00087 
00088     sync_->registerCallback(boost::bind(&Navigator::RGBDCallback, this, _1, _2, _3));
00089 }
00090 
00091 Navigator::~Navigator()
00092 {
00093 
00094 }
00095 aruco::MarkerDetector MDetector;
00096 rgbdtools::KeyframeGraphSolverISAM solver_;
00097 void Navigator::initParams()
00098 {
00099     bool verbose;
00100 
00101     if (!nh_private_.getParam ("verbose", verbose))
00102         verbose = true;
00103     if (!nh_private_.getParam ("queue_size", queue_size_))
00104         queue_size_ = 5;
00105     if (!nh_private_.getParam ("fixed_frame", fixed_frame_))
00106         fixed_frame_ = "/odom";
00107     if (!nh_private_.getParam ("pcd_map_res", pcd_map_res_))
00108         pcd_map_res_ = 0.01;
00109     if (!nh_private_.getParam ("octomap_res", octomap_res_))
00110         octomap_res_ = 0.05;
00111     if (!nh_private_.getParam ("octomap_with_color", octomap_with_color_))
00112         octomap_with_color_ = true;
00113     if (!nh_private_.getParam ("kf_dist_eps", kf_dist_eps_))
00114         kf_dist_eps_  = 0.10;
00115     if (!nh_private_.getParam ("kf_angle_eps", kf_angle_eps_))
00116         kf_angle_eps_  = 10.0 * M_PI / 180.0;
00117     if (!nh_private_.getParam ("max_range", max_range_))
00118         max_range_  = 05.0;
00119     if (!nh_private_.getParam ("max_stdev", max_stdev_))
00120         max_stdev_  = 555;
00121     if (!nh_private_.getParam ("max_map_z", max_map_z_))
00122         max_map_z_ = std::numeric_limits<double>::infinity();
00123 
00124     // configure graph detection
00125     MDetector.setThresholdParams( 10.0,7.0);
00126     MDetector.setCornerRefinementMethod(aruco::MarkerDetector::LINES);
00127 
00128     int graph_n_keypoints;
00129     int graph_n_candidates;
00130     int graph_k_nearest_neighbors;
00131     bool graph_matcher_use_desc_ratio_test = true;
00132 
00133     if (!nh_private_.getParam ("graph/n_keypoints", graph_n_keypoints))
00134         graph_n_keypoints = 500;
00135     if (!nh_private_.getParam ("graph/n_candidates", graph_n_candidates))
00136         graph_n_candidates = 10;
00137     if (!nh_private_.getParam ("graph/k_nearest_neighbors", graph_k_nearest_neighbors))
00138         graph_k_nearest_neighbors = 4;
00139     int min_inliers = 25;
00140 
00141     graph_detector_.setMapping(false);
00142     graph_detector_.setNKeypoints(graph_n_keypoints);
00143     graph_detector_.setNCandidates(graph_n_candidates);
00144     graph_detector_.setKNearestNeighbors(graph_k_nearest_neighbors);
00145     graph_detector_.setMatcherUseDescRatioTest(graph_matcher_use_desc_ratio_test);
00146     graph_detector_.setSacMinInliers(min_inliers);
00147     graph_detector_.setSACReestimateTf(false);
00148     graph_detector_.setSACSaveResults(true);
00149     graph_detector_.setVerbose(verbose);
00150     graph_detector_.setMaxIterations(300);
00151 }
00152 
00153 void Navigator::filter_aruco()
00154 {
00155     double max_dist_ = 0.2*0.2;
00156     std::vector<std::vector<double> > positions;
00157     std::vector<std::vector<int> > inds;
00158     for(u_int i = 0; i < aruco_pos.size(); i++)
00159     {
00160         std::vector<double> val;
00161         val.push_back(0);
00162         val.push_back(0);
00163         val.push_back(0);
00164         std::vector<int> sub_inds;
00165         for(u_int j = 0; j < aruco_pos.size() ; j++)
00166         {
00167             double man_dist = std::pow(aruco_pos[i][0]-aruco_pos[j][0],2)+ std::pow(aruco_pos[i][1]-aruco_pos[j][1],2)+ std::pow(aruco_pos[i][2]-aruco_pos[j][2],2);
00168             if (man_dist < max_dist_)
00169             {
00170                 sub_inds.push_back(j);
00171                 val[0] += aruco_pos[j][0];
00172                 val[1] += aruco_pos[j][1];
00173                 val[2] += aruco_pos[j][2];
00174             }
00175 
00176         }
00177         val[0] /= sub_inds.size();
00178         val[1] /= sub_inds.size();
00179         val[2] /= sub_inds.size();
00180         positions.push_back(val);
00181         inds.push_back(sub_inds);
00182     }
00183     PathMsg ar;
00184     ar.header.frame_id = fixed_frame_;
00185     ar.header.seq = 0;
00186     ar.header.stamp = ros::Time::now();
00187     double min_readings = 2;
00188     std::vector<std::vector<double> > aruc;
00189     //    aruco_pos.clear();
00190     for(u_int i = 0; i < positions.size(); i++)
00191     {
00192         std::vector<double> val;
00193         val.push_back(0);
00194         val.push_back(0);
00195         val.push_back(0);
00196         std::vector<int> sub_inds;
00197         for(u_int j = 0; j < positions.size() ; j++)
00198         {
00199             if(inds[j].size() <= min_readings) //we need min 2 readings to consider a position safe.
00200             {
00201                 continue;
00202             }
00203             double dist = std::pow(positions[i][0]-positions[j][0],2)+ std::pow(positions[i][1]-positions[j][1],2)+ std::pow(positions[i][2]-positions[j][2],2);
00204             if (dist < max_dist_)
00205             {
00206                 sub_inds.push_back(j);
00207                 val[0] += positions[j][0];
00208                 val[1] += positions[j][1];
00209                 val[2] += positions[j][2];
00210             }
00211 
00212         }
00213         if(sub_inds.size() <= min_readings)
00214         {
00215             val[0] = -99999;
00216             aruc.push_back(val);
00217             continue;
00218         }
00219         if(!(val[0]==-99999))
00220         {
00221             val[0] /= sub_inds.size();
00222             val[1] /= sub_inds.size();
00223             val[2] /= sub_inds.size();
00224         }
00225         aruc.push_back(val);
00226     }
00227     aruco_pos.clear();
00228     for(u_int i = 0; i< aruc.size(); i++)
00229     {
00230         geometry_msgs::PoseStamped pose;
00231         if(aruc[i][0] == -99999)
00232             continue;
00233         rgbdtools::RGBDKeyframe keyframe=keyframes_[aruco_kfs[i]];
00234         pose.header.frame_id = fixed_frame_;
00235         pose.header.seq = keyframe.header.seq;
00236         pose.header.stamp.sec = keyframe.header.stamp.sec;
00237         pose.header.stamp.nsec = keyframe.header.stamp.nsec;
00238         pose.pose.position.x = aruc[i][0];
00239         pose.pose.position.y = aruc[i][1];
00240         pose.pose.position.z = aruc[i][2];
00241         pose.pose.orientation.x = 1;
00242         pose.pose.orientation.y = 0;
00243         pose.pose.orientation.z = 0;
00244         pose.pose.orientation.w = 1;
00245         ar.poses.push_back(pose);
00246         std::vector<double> pos;
00247         pos.push_back(aruc[i][0]);
00248         pos.push_back(aruc[i][1]);
00249         pos.push_back(aruc[i][2]);
00250         aruco_pos.push_back(pos);
00251     }
00252     aruco_pub_.publish(ar);
00253     //    positions.clear();
00254     //    for(u_int i = 0; i< aruco_pos.size(); i++)
00255     //    {
00256     //        double x,y,z;
00257     //        x = aruco_pos[i][0];
00258     //        y = aruco_pos[i][1];
00259     //        z = aruco_pos[i][2];
00260     //        bool hit = false;
00261     //        for(u_int j = 0; j < positions.size(); j++)
00262     //        {
00263     //            if (x == positions[j][0] && y == positions[j][1] && z == positions[j][2])
00264     //            {
00265     //                hit = true;
00266     //                break;
00267     //            }
00268     //        }
00269     //        if(!hit)
00270     //        {
00271     //            positions.push_back(aruco_pos[i]);
00272     //        }
00273     //    }
00274     //    aruco_pos.clear();
00275     //    for(u_int i = 0; i < positions.size(); i++)
00276     //        aruco_pos.push_back(positions[i]);
00277     //    std::cout << "oh hai!" << std::endl;
00278 }
00279 
00280 bool first = true;
00281 aruco::CameraParameters param;
00282 cv::Mat intr, dist;
00283 cv::Size CamSize;
00284 
00285 void Navigator::RGBDCallback(
00286         const ImageMsg::ConstPtr& rgb_msg,
00287         const ImageMsg::ConstPtr& depth_msg,
00288         const CameraInfoMsg::ConstPtr& info_msg)
00289 {
00290     tf::StampedTransform transform;
00291 
00292     const ros::Time& time = rgb_msg->header.stamp;
00293     if (first)
00294     {
00295         convertCameraInfoToMats(info_msg, intr, dist);
00296         CamSize.width = info_msg->width;
00297         CamSize.height = info_msg->height;
00298         param.CameraMatrix = intr;
00299         param.CamSize = CamSize;
00300         param.Distorsion = dist;
00301 
00302         first = false;
00303     }
00304     try{
00305         tf_listener_.waitForTransform(
00306                     fixed_frame_, rgb_msg->header.frame_id, time, ros::Duration(0.1));
00307         tf_listener_.lookupTransform(
00308                     fixed_frame_, rgb_msg->header.frame_id, time, transform);
00309     }
00310     catch(...)
00311     {
00312         return;
00313     }
00314 
00315     // create a new frame and increment the counter
00316     rgbdtools::RGBDFrame frame;
00317     createRGBDFrameFromROSMessages(rgb_msg, depth_msg, info_msg, frame);
00318     frame.index = rgbd_frame_index_;
00319     rgbd_frame_index_++;
00320     std::vector<aruco::Marker> markers;
00321 
00322     ros::WallTime start_detect = ros::WallTime::now();
00323 
00324     MDetector.detect(frame.rgb_img,markers,param,0.20); // magic number 0.20 = marker size
00325     if (markers.size()>0)
00326     {
00327         manual_add_ = true;
00328         solver_.giveMarkers(markers);
00329     }
00330     ros::WallTime end_detect = ros::WallTime::now();
00331 
00332     //    bool result = processFrame(frame, eigenAffineFromTf(transform));
00333     addKeyframe(frame,eigenAffineFromTf( transform));
00334 
00335     ros::WallTime prepare_start = ros::WallTime::now();
00336     graph_detector_.prepareFeaturesForRANSAC_Iterative(keyframes_.size()-1,keyframes_);
00337     ros::WallTime prepare_end = ros::WallTime::now();
00338 
00339     ros::WallTime matrix_start = ros::WallTime::now();
00340     graph_detector_.buildMatchMatrixSurfTree_Iterative(keyframes_.size()-1,keyframes_);
00341     ros::WallTime matrix_end = ros::WallTime::now();
00342 
00343     ros::WallTime candidate_start = ros::WallTime::now();
00344     graph_detector_.buildCandidateMatrixSurfTree_Iterative(keyframes_.size()-1);
00345     ros::WallTime candidate_end = ros::WallTime::now();
00346 
00347     ros::WallTime correspondence_start = ros::WallTime::now();
00348     graph_detector_.buildCorrespondenceMatrix_mine_Iterative(keyframes_.size()-1,keyframes_,associations_);
00349     ros::WallTime correspondence_end = ros::WallTime::now();
00350 
00351     ros::WallTime solver_start = ros::WallTime::now();
00352     solver_.add_edges(keyframes_.size()-1,keyframes_,associations_);
00353     solver_.solve_Iterative(keyframes_);
00354     solver_.getArucoPos(&aruco_pos,&aruco_kfs,keyframes_);
00355     ros::WallTime solver_end = ros::WallTime::now();
00356 
00357     ros::WallTime filter_start = ros::WallTime::now();
00358     filter_aruco();
00359     ros::WallTime filter_end = ros::WallTime::now();
00360 
00361 //            ros::ServiceClient client = nh_.serviceClient<ccny_rgbd::Save>("reset_pos_");
00362 //            ccny_rgbd::Save save;
00363 
00364 //            if(keyframes_[keyframes_.size()-1].used == true)
00365 //            {
00366 //                Pose pose = keyframes_[keyframes_.size()-1].pose;
00367 //                std::stringstream text;
00368 //                text << pose(0,0) << " " << pose(0,1) << " " << pose(0,2) << " " << pose(0,3) << '\n' <<
00369 //                        pose(1,0) << " " << pose(1,1) << " " << pose(1,2) << " " << pose(1,3) << '\n' <<
00370 //                        pose(2,0) << " " << pose(2,1) << " " << pose(2,2) << " " << pose(2,3) << '\n' <<
00371 //                        pose(3,0) << " " << pose(3,1) << " " << pose(3,2) << " " << pose(3,3) << '\n';
00372 //                save.request.filename = text.str();
00373 //                //            std::cout << text.str() << std::endl;
00374 //                client.call(save);
00375 //            }
00376 
00377 
00378 
00379     ros::WallTime publish_start = ros::WallTime::now();
00380     publishKeyframePoses();
00381     publishPath();
00382     publishArucoPos();
00383     publishKeyframeAssociations();
00384     ros::WallTime publish_end = ros::WallTime::now();
00385     std::cout << "Statistics:" << std::endl;
00386     std::cout << "Prepare Features:        "    << 1000.0 * (prepare_end    - prepare_start   ).toSec() << std::endl;
00387     std::cout << "Building Matrix:         "    << 1000.0 * (matrix_end    - matrix_start   ).toSec() << std::endl;
00388     std::cout << "Finding Candidates:      "    << 1000.0 * (candidate_end    - candidate_start   ).toSec() << std::endl;
00389     std::cout << "Creating Correspondeces: "    << 1000.0 * (correspondence_end    - correspondence_start   ).toSec() << std::endl;
00390     std::cout << "Solving graph:           "    << 1000.0 * (solver_end    - solver_start   ).toSec() << std::endl;
00391     std::cout << "Filtering Aruco:         "    << 1000.0 * (filter_end    - filter_start   ).toSec() << std::endl;
00392     std::cout << "Publishing Results:      "    << 1000.0 * (publish_end    - publish_start   ).toSec() << std::endl;
00393 
00394 }
00395 
00396 int triple_add=0;
00397 
00398 
00399 bool Navigator::processFrame(
00400         const rgbdtools::RGBDFrame& frame,
00401         const AffineTransform& pose)
00402 {
00403     // add the frame pose to the path vector
00404     geometry_msgs::PoseStamped frame_pose;
00405     tf::Transform frame_tf = tfFromEigenAffine(pose);
00406     tf::poseTFToMsg(frame_tf, frame_pose.pose);
00407 
00408     // update the header of the pose for the path
00409     frame_pose.header.frame_id = fixed_frame_;
00410     frame_pose.header.seq = frame.header.seq;
00411     frame_pose.header.stamp.sec = frame.header.stamp.sec;
00412     frame_pose.header.stamp.nsec = frame.header.stamp.nsec;
00413 
00414     path_msg_.poses.push_back(frame_pose);
00415 
00416     // determine if a new keyframe is needed
00417     bool result;
00418 
00419     if(keyframes_.empty() || manual_add_)
00420     {
00421         result = true;
00422     }
00423     else
00424     {
00425         double dist, angle;
00426         getTfDifference(tfFromEigenAffine(pose),
00427                         tfFromEigenAffine(keyframes_.back().pose),
00428                         dist, angle);
00429 
00430         if (triple_add >0 || dist > kf_dist_eps_ || angle > kf_angle_eps_)
00431         {
00432             result = true;
00433             //        if (triple_add == 0)
00434             //        {
00435             //            triple_add = 2;
00436             //        }
00437             //        else
00438             //        {
00439             //            triple_add--;
00440             //        }
00441         }
00442         else
00443             result = false;
00444     }
00445 
00446     if (result)
00447     {
00448         addKeyframe(frame, pose);
00449     }
00450     return result;
00451 }
00452 
00453 void Navigator::addKeyframe(
00454         const rgbdtools::RGBDFrame& frame,
00455         const AffineTransform& pose)
00456 {
00457     rgbdtools::RGBDKeyframe keyframe(frame);
00458     keyframe.pose = pose;
00459 
00460     if (manual_add_)
00461     {
00462         ROS_INFO("Adding frame manually");
00463         manual_add_ = false;
00464         keyframe.manually_added = true;
00465     }
00466     keyframes_.push_back(keyframe);
00467 }
00468 
00469 bool Navigator::publishKeyframeSrvCallback(
00470         PublishKeyframe::Request& request,
00471         PublishKeyframe::Response& response)
00472 {
00473     int kf_idx = request.id;
00474 
00475     if (kf_idx >= 0 && kf_idx < (int)keyframes_.size())
00476     {
00477         ROS_INFO("Publishing keyframe %d", kf_idx);
00478         publishKeyframeData(kf_idx);
00479         Pose(kf_idx);
00480         return true;
00481     }
00482     else
00483     {
00484         ROS_ERROR("Index out of range");
00485         return false;
00486     }
00487 }
00488 
00489 bool Navigator::publishKeyframesSrvCallback(
00490         PublishKeyframes::Request& request,
00491         PublishKeyframes::Response& response)
00492 {
00493     bool found_match = false;
00494 
00495     // regex matching - try match the request string against each
00496     // keyframe index
00497     boost::regex expression(request.re);
00498 
00499     for (unsigned int kf_idx = 0; kf_idx < keyframes_.size(); ++kf_idx)
00500     {
00501         std::stringstream ss;
00502         ss << kf_idx;
00503         std::string kf_idx_string = ss.str();
00504 
00505         boost::smatch match;
00506 
00507         if(boost::regex_match(kf_idx_string, match, expression))
00508         {
00509             found_match = true;
00510             ROS_INFO("Publishing keyframe %d", kf_idx);
00511             publishKeyframeData(kf_idx);
00512             publishKeyframePose(kf_idx);
00513             usleep(25000);
00514         }
00515     }
00516 
00517     publishPath();
00518 
00519     return found_match;
00520 }
00521 
00522 void Navigator::publishKeyframeData(int i)
00523 {
00524     //    //for testing iterative stuff
00525     //    graph_detector_.prepareFeaturesForRANSAC_Iterative(i,keyframes_);
00526     //    graph_detector_.buildMatchMatrixSurfTree_Iterative(i,keyframes_);
00527     //    graph_detector_.buildCandidateMatrixSurfTree_Iterative(i);
00528     rgbdtools::RGBDKeyframe& keyframe = keyframes_[i];
00529 
00530     // construct a cloud from the images
00531     PointCloudT cloud;
00532     keyframe.constructDensePointCloud(cloud, max_range_, max_stdev_);
00533 
00534     // cloud transformed to the fixed frame
00535     PointCloudT cloud_ff;
00536     pcl::transformPointCloud(cloud, cloud_ff, keyframe.pose);
00537 
00538     cloud_ff.header.frame_id = fixed_frame_;
00539 
00540     keyframes_pub_.publish(cloud_ff);
00541 }
00542 
00543 void Navigator::publishKeyframeAssociations()
00544 {
00545     visualization_msgs::Marker marker;
00546     marker.header.stamp = ros::Time::now();
00547     marker.header.frame_id = fixed_frame_;
00548     marker.id = 0;
00549     marker.type = visualization_msgs::Marker::LINE_LIST;
00550     marker.action = visualization_msgs::Marker::ADD;
00551 
00552     marker.points.resize(associations_.size() * 2);
00553 
00554     marker.color.a = 1.0;
00555 
00556     for (unsigned int as_idx = 0; as_idx < associations_.size(); ++as_idx)
00557     {
00558         // set up shortcut references
00559         const rgbdtools::KeyframeAssociation& association = associations_[as_idx];
00560         int kf_idx_a = association.kf_idx_a;
00561         int kf_idx_b = association.kf_idx_b;
00562         rgbdtools::RGBDKeyframe& keyframe_a = keyframes_[kf_idx_a];
00563         rgbdtools::RGBDKeyframe& keyframe_b = keyframes_[kf_idx_b];
00564 
00565         int idx_start = as_idx*2;
00566         int idx_end   = as_idx*2 + 1;
00567 
00568         tf::Transform keyframe_a_pose = tfFromEigenAffine(keyframe_a.pose);
00569         tf::Transform keyframe_b_pose = tfFromEigenAffine(keyframe_b.pose);
00570 
00571         // start point for the edge
00572         marker.points[idx_start].x = keyframe_a_pose.getOrigin().getX();
00573         marker.points[idx_start].y = keyframe_a_pose.getOrigin().getY();
00574         marker.points[idx_start].z = keyframe_a_pose.getOrigin().getZ();
00575 
00576         // end point for the edge
00577         marker.points[idx_end].x = keyframe_b_pose.getOrigin().getX();
00578         marker.points[idx_end].y = keyframe_b_pose.getOrigin().getY();
00579         marker.points[idx_end].z = keyframe_b_pose.getOrigin().getZ();
00580 
00581         if (association.type == rgbdtools::KeyframeAssociation::VO)
00582         {
00583             marker.ns = "VO";
00584             marker.scale.x = 0.002;
00585 
00586             marker.color.r = 0.0;
00587             marker.color.g = 1.0;
00588             marker.color.b = 0.0;
00589         }
00590         else if (association.type == rgbdtools::KeyframeAssociation::RANSAC)
00591         {
00592             marker.ns = "RANSAC";
00593             marker.scale.x = 0.002;
00594 
00595             marker.color.r = 1.0;
00596             marker.color.g = 1.0;
00597             marker.color.b = 0.0;
00598         }
00599 
00600         kf_assoc_pub_.publish(marker);
00601     }
00602 }
00603 
00604 void Navigator::publishKeyframePoses()
00605 {
00606     for(unsigned int kf_idx = 0; kf_idx < keyframes_.size(); ++kf_idx)
00607     {
00608         publishKeyframePose(kf_idx);
00609     }
00610 }
00611 
00612 void Navigator::publishArucoPos()
00613 {
00614     for(u_int i = 0; i < aruco_pos.size(); i++)
00615     {
00616         visualization_msgs::Marker marker;
00617         marker.header.stamp = ros::Time::now();
00618         marker.header.frame_id = fixed_frame_;
00619         marker.ns = "Aruco_pos";
00620         marker.id = i;
00621         marker.type = visualization_msgs::Marker::SPHERE;
00622         marker.action = visualization_msgs::Marker::ADD;
00623         marker.pose.position.x = aruco_pos[i][0];
00624         marker.pose.position.y = aruco_pos[i][1];
00625         marker.pose.position.z = aruco_pos[i][2];
00626         marker.pose.orientation.x = 0.0;
00627         marker.pose.orientation.y = 0.0;
00628         marker.pose.orientation.z = 0.0;
00629         marker.pose.orientation.w = 1.0;
00630         marker.scale.x = 0.1;
00631         marker.scale.y = 0.1;
00632         marker.scale.z = 0.1;
00633         marker.color.a = 1.0;
00634         marker.color.r = 1.0;
00635         marker.color.g = 0.0;
00636         marker.color.b = 0.0;
00637         poses_pub_.publish(marker);
00638     }
00639 }
00640 void Navigator::publishPath()
00641 {
00642     PathMsg kfs;
00643     kfs.header.frame_id = fixed_frame_;
00644     kfs.header.seq = 0;
00645     kfs.header.stamp = ros::Time::now();
00646     for(u_int i = solver_.n_original_poses; i < keyframes_.size(); i++)
00647     {
00648         const rgbdtools::RGBDKeyframe& keyframe=keyframes_[i];
00649 
00650         if(!keyframe.used)
00651         {
00652             continue;
00653         }
00654 
00655         geometry_msgs::PoseStamped pose;
00656         pose.header.frame_id = fixed_frame_;
00657         pose.header.seq = keyframe.header.seq;
00658         pose.header.stamp.sec = keyframe.header.stamp.sec;
00659         pose.header.stamp.nsec = keyframe.header.stamp.nsec;
00660         pose.pose.position.x = keyframe.pose(0,3);
00661         pose.pose.position.y = keyframe.pose(1,3);
00662         pose.pose.position.z = keyframe.pose(2,3);
00663         pose.pose.orientation.x = 1;
00664         pose.pose.orientation.y = 0;
00665         pose.pose.orientation.z = 0;
00666         pose.pose.orientation.w = 1;
00667         kfs.poses.push_back(pose);
00668     }
00669     if(kfs.poses.size()!=0)
00670         path_pub_.publish(kfs);
00671 }
00672 
00673 void Navigator::publishKeyframePose(int i)
00674 {
00675     rgbdtools::RGBDKeyframe& keyframe = keyframes_[i];
00676 
00677     // **** publish camera pose
00678 
00679     visualization_msgs::Marker marker;
00680     marker.header.stamp = ros::Time::now();
00681     marker.header.frame_id = fixed_frame_;
00682     marker.ns = "keyframe_poses";
00683     marker.id = i;
00684     marker.type = visualization_msgs::Marker::ARROW;
00685     marker.action = visualization_msgs::Marker::ADD;
00686     marker.points.resize(2);
00687 
00688     // start point for the arrow
00689     tf::Transform keyframe_pose = tfFromEigenAffine(keyframe.pose);
00690     marker.points[0].x = keyframe_pose.getOrigin().getX();
00691     marker.points[0].y = keyframe_pose.getOrigin().getY();
00692     marker.points[0].z = keyframe_pose.getOrigin().getZ();
00693 
00694     // end point for the arrow
00695     tf::Transform ep;
00696     ep.setIdentity();
00697     ep.setOrigin(tf::Vector3(0.00, 0.00, 0.12)); // z = arrow length
00698     ep = keyframe_pose * ep;
00699 
00700     marker.points[1].x = ep.getOrigin().getX();
00701     marker.points[1].y = ep.getOrigin().getY();
00702     marker.points[1].z = ep.getOrigin().getZ();
00703 
00704     marker.scale.x = 0.02; // shaft radius
00705     marker.scale.y = 0.05; // head radius
00706     if((u_int)i < solver_.n_original_poses)
00707     {
00708         marker.color.a = 1.0;
00709         marker.color.r = 0.0;
00710         marker.color.g = 1.0;
00711         marker.color.b = 0.0;
00712     }
00713     else
00714     {
00715         if(!keyframe.used)
00716         {
00717             marker.color.a = 0.5;
00718             marker.color.r = 1.0;
00719             marker.color.g = 0.0;
00720             marker.color.b = 0.0;
00721         }
00722         else
00723         {
00724             marker.color.a = 1.0;
00725             marker.color.r = 1.0;
00726             marker.color.g = 1.0;
00727             marker.color.b = 0.0;
00728         }
00729 
00730     }
00731     poses_pub_.publish(marker);
00732 
00733     // **** publish frame index text
00734 
00735     visualization_msgs::Marker marker_text;
00736     marker_text.header.stamp = ros::Time::now();
00737     marker_text.header.frame_id = fixed_frame_;
00738     marker_text.ns = "keyframe_indexes";
00739     marker_text.id = i;
00740     marker_text.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
00741     marker_text.action = visualization_msgs::Marker::ADD;
00742 
00743     tf::poseTFToMsg(keyframe_pose, marker_text.pose);
00744 
00745     marker_text.pose.position.z -= 0.05;
00746 
00747     char label[6];
00748     sprintf(label, "%d", i);
00749     marker_text.text = label;
00750 
00751     marker_text.color.a = 1.0;
00752     marker_text.color.r = 1.0;
00753     marker_text.color.g = 1.0;
00754     marker_text.color.b = 0.0;
00755 
00756     marker_text.scale.z = 0.05; // shaft radius
00757 
00758     poses_pub_.publish(marker_text);
00759 }
00760 
00761 bool Navigator::saveKeyframesSrvCallback(
00762         Save::Request& request,
00763         Save::Response& response)
00764 {
00765     std::string filepath = request.filename;
00766 
00767     ROS_INFO("Saving keyframes...");
00768     std::string filepath_keyframes = filepath + "/keyframes/";
00769     bool result_kf = saveKeyframes(keyframes_, filepath_keyframes);
00770     if (result_kf) ROS_INFO("Keyframes saved to %s", filepath.c_str());
00771     else ROS_ERROR("Keyframe saving failed!");
00772 
00773     ROS_INFO("Saving path...");
00774     bool result_path = savePath(filepath);
00775     savePathTUMFormat(filepath);
00776     if (result_path ) ROS_INFO("Path saved to %s", filepath.c_str());
00777     else ROS_ERROR("Path saving failed!");
00778     solver_.save_graph(filepath);
00779 
00780     return result_kf && result_path;
00781 }
00782 
00783 bool Navigator::loadKeyframesSrvCallback(
00784         Load::Request& request,
00785         Load::Response& response)
00786 {
00787     bool skip = false;
00788     ros::WallTime start_all = ros::WallTime::now();
00789     std::string filepath1 = request.filename;
00790     char buffer[200];
00791     std::string filepath;
00792     if(filepath1.at(filepath1.size()-1)=='!')
00793     {
00794         skip = true;
00795         int copied = filepath1.copy(buffer,filepath1.size()-1,0);
00796         buffer[copied] = '\0';
00797         filepath = buffer;
00798     }
00799     else
00800     {
00801         filepath = filepath1;
00802     }
00803     ROS_INFO("Loading keyframes...");
00804     std::string filepath_keyframes = filepath + "/keyframes/";
00805     bool result_kf = loadKeyframes(keyframes_, filepath_keyframes);
00806     if (result_kf) ROS_INFO("Keyframes loaded successfully");
00807     else ROS_ERROR("Keyframe loading failed!");
00808 
00809     ROS_INFO("Loading path...");
00810     bool result_path = loadPath(filepath);
00811     if (result_path) ROS_INFO("Path loaded successfully");
00812     else ROS_ERROR("Path loading failed!");
00813     publishKeyframePoses();
00814     solver_.parse((filepath).c_str(),keyframes_);
00815     publishKeyframePoses();
00816     if(!(result_kf && result_path))
00817         return false;
00818     if(skip)
00819         return result_kf && result_path;
00820     graph_detector_.generateKeyframeAssociations_Iterative(keyframes_,associations_);
00821     double dur = getMsDuration(start_all);
00822 
00823     ROS_INFO("Everything took %.1f ms", dur);
00824     return result_kf && result_path;
00825 }
00826 
00827 bool Navigator::savePcdMapSrvCallback(
00828         Save::Request& request,
00829         Save::Response& response)
00830 {
00831     ROS_INFO("Saving map as pcd...");
00832     const std::string& path = request.filename;
00833     bool result = savePcdMap(path);
00834 
00835     if (result) ROS_INFO("Pcd map saved to %s", path.c_str());
00836     else ROS_ERROR("Pcd map saving failed");
00837 
00838     return result;
00839 }
00840 
00841 bool Navigator::saveOctomapSrvCallback(
00842         Save::Request& request,
00843         Save::Response& response)
00844 {
00845     ROS_INFO("Saving map as Octomap...");
00846     const std::string& path = request.filename;
00847     bool result = saveOctomap(path);
00848 
00849     if (result) ROS_INFO("Octomap saved to %s", path.c_str());
00850     else ROS_ERROR("Octomap saving failed");
00851 
00852     return result;
00853 }
00854 
00855 //void Navigator::createmap(octomap::ColorOcTree* m_octree)
00856 //{
00857 //    nav_msgs::OccupancyGrid m_gridmap;
00858 //    m_gridmap.data.clear();
00859 //    m_gridmap.info.height = 0.0;
00860 //    m_gridmap.info.width = 0.0;
00861 //    m_gridmap.info.resolution = 0.0;
00862 //    m_gridmap.info.origin.position.x = 0.0;
00863 //    m_gridmap.info.origin.position.y = 0.0;
00864 //    m_gridmap.header.frame_id = fixed_frame_;
00865 //    m_gridmap.header.stamp = ros::Time::now();
00866 //    // now, traverse all leafs in the tree:
00867 //    for (octomap::ColorOcTree::iterator it = m_octree->begin(999),
00868 //         end = m_octree->end(); it != end; ++it)
00869 //    {
00870 //        if (m_octree->isNodeOccupied(*it)){
00871 //            double z = it.getZ();
00872 //            if (z > min_map_z_ && z < max_map_z_)
00873 //            {
00874 //                double size = it.getSize();
00875 //                double x = it.getX();
00876 //                double y = it.getY();
00877 
00878 
00879 //                if (publishCollisionMap){
00880 //                    collObjBox.extents.x = collObjBox.extents.y = collObjBox.extents.z = size;
00881 
00882 //                    collObjBox.center.x = x;
00883 //                    collObjBox.center.y = y;
00884 //                    collObjBox.center.z = z;
00885 //                    collisionMap.boxes.push_back(collObjBox);
00886 
00887 //                }
00888 
00889 //                //create marker:
00890 //                if (publishMarkerArray){
00891 //                    unsigned idx = it.getDepth();
00892 //                    assert(idx < occupiedNodesVis.markers.size());
00893 
00894 //                    geometry_msgs::Point cubeCenter;
00895 //                    cubeCenter.x = x;
00896 //                    cubeCenter.y = y;
00897 //                    cubeCenter.z = z;
00898 
00899 //                    occupiedNodesVis.markers[idx].points.push_back(cubeCenter);
00900 //                    if (m_useHeightMap){
00901 //                        double minX, minY, minZ, maxX, maxY, maxZ;
00902 //                        m_octree->getMetricMin(minX, minY, minZ);
00903 //                        m_octree->getMetricMax(maxX, maxY, maxZ);
00904 
00905 //                        double h = (1.0 - std::min(std::max((cubeCenter.z-minZ)/ (maxZ - minZ), 0.0), 1.0)) *m_colorFactor;
00906 //                        occupiedNodesVis.markers[idx].colors.push_back(heightMapColor(h));
00907 //                    }
00908 //                }
00909 
00910 //                // insert into pointcloud:
00911 //                if (publishPointCloud)
00912 //                    pclCloud.push_back(pcl::PointXYZ(x, y, z));
00913 
00914 //            }
00915 //        } else{ // node not occupied => mark as free in 2D map if unknown so far
00916 //            double z = it.getZ();
00917 //            if (z > m_occupancyMinZ && z < m_occupancyMaxZ)
00918 //            {
00919 //                handleFreeNode(it);
00920 //                if (inUpdateBBX)
00921 //                    handleFreeNodeInBBX(it);
00922 
00923 //                if (m_publishFreeSpace){
00924 //                    double x = it.getX();
00925 //                    double y = it.getY();
00926 
00927 //                    if (publishFreeMap){
00928 //                        freeObjBox.extents.x = freeObjBox.extents.y = freeObjBox.extents.z = it.getSize();
00929 //                        freeObjBox.center.x = x;
00930 //                        freeObjBox.center.y = y;
00931 //                        freeObjBox.center.z = z;
00932 //                        freeMap.boxes.push_back(freeObjBox);
00933 //                    }
00934 
00935 //                    //create marker for free space:
00936 //                    if (publishFreeMarkerArray){
00937 //                        unsigned idx = it.getDepth();
00938 //                        assert(idx < freeNodesVis.markers.size());
00939 
00940 //                        geometry_msgs::Point cubeCenter;
00941 //                        cubeCenter.x = x;
00942 //                        cubeCenter.y = y;
00943 //                        cubeCenter.z = z;
00944 
00945 //                        freeNodesVis.markers[idx].points.push_back(cubeCenter);
00946 //                    }
00947 //                }
00948 
00949 //            }
00950 //        }
00951 //    }
00952 //}
00953 
00954 bool Navigator::addManualKeyframeSrvCallback(
00955         AddManualKeyframe::Request& request,
00956         AddManualKeyframe::Response& response)
00957 {
00958 
00959     manual_add_ = true;
00960 
00961     return true;
00962 }
00963 
00964 bool Navigator::generateGraphSrvCallback(
00965         GenerateGraph::Request& request,
00966         GenerateGraph::Response& response)
00967 {
00968     associations_.clear();
00969     graph_detector_.generateKeyframeAssociations(keyframes_, associations_);
00970 
00971     ROS_INFO("%d associations detected", (int)associations_.size());
00972     publishKeyframePoses();
00973     publishKeyframeAssociations();
00974 
00975     return true;
00976 }
00977 
00978 bool Navigator::solveGraphSrvCallback(
00979         SolveGraph::Request& request,
00980         SolveGraph::Response& response)
00981 {
00982     ros::WallTime start = ros::WallTime::now();
00983 
00984     // Graph solving: keyframe positions only, path is interpolated
00985     //  graph_solver_.solve(keyframes_, associations_);
00986     solver_.solve(keyframes_, associations_);
00987     //  updatePathFromKeyframePoses();
00988     max_map_z_ = getmaxheight(path_msg_)+0.2; //cut the ceiling
00989     min_map_z_= getminheight(path_msg_)-0.5; //cut the ground
00990     // Graph solving: keyframe positions and VO path
00991     /*
00992   AffineTransformVector path;
00993   pathROSToEigenAffine(path_msg_, path);
00994   graph_solver_.solve(keyframes_, associations_, path);
00995   pathEigenAffineToROS(path, path_msg_);
00996   */
00997 
00998     double dur = getMsDuration(start);
00999 
01000     ROS_INFO("Solving took %.1f ms", dur);
01001 
01002     //  publishPath();
01003     publishKeyframePoses();
01004     publishKeyframeAssociations();
01005 
01006     return true;
01007 }
01008 
01009 
01013 void Navigator::updatePathFromKeyframePoses()
01014 {
01015     int kf_size = keyframes_.size();
01016     int f_size = path_msg_.poses.size();
01017 
01018     // temporary store the new path
01019     AffineTransformVector path_new;
01020     path_new.resize(f_size);
01021 
01022     if (kf_size < 2) return;
01023 
01024     for (int kf_idx = 0; kf_idx < kf_size - 1; ++kf_idx)
01025     {
01026         // the indices of the current and next keyframes (a and b)
01027         const rgbdtools::RGBDKeyframe& keyframe_a = keyframes_[kf_idx];
01028         const rgbdtools::RGBDKeyframe& keyframe_b = keyframes_[kf_idx + 1];
01029 
01030         // the corresponding frame indices
01031         int f_idx_a = keyframe_a.index;
01032         int f_idx_b = keyframe_b.index;
01033 
01034         // the new poses of keyframes a and b (after graph solving)
01035         tf::Transform kf_pose_a = tfFromEigenAffine(keyframe_a.pose);
01036         tf::Transform kf_pose_b = tfFromEigenAffine(keyframe_b.pose);
01037 
01038         // the previous pose of keyframe a and b (before graph solving)
01039         tf::Transform kf_pose_a_prev, kf_pose_b_prev;
01040         tf::poseMsgToTF(path_msg_.poses[f_idx_a].pose, kf_pose_a_prev);
01041         tf::poseMsgToTF(path_msg_.poses[f_idx_b].pose, kf_pose_b_prev);
01042 
01043         // the motion, in the camera frame (after and before graph solving)
01044         tf::Transform kf_motion      = kf_pose_a.inverse() * kf_pose_b;
01045         tf::Transform kf_motion_prev = kf_pose_a_prev.inverse() * kf_pose_b_prev;
01046 
01047         // the correction from the graph solving
01048         tf::Transform correction = kf_motion_prev.inverse() * kf_motion;
01049 
01050         // update the poses in-between keyframes
01051         for (int f_idx = f_idx_a; f_idx < f_idx_b; ++f_idx)
01052         {
01053             // calculate interpolation scale
01054             double interp_scale = (double)(f_idx - f_idx_a) / (double)(f_idx_b - f_idx_a);
01055 
01056             // create interpolated correction translation and rotation
01057             tf::Vector3 v_interp = correction.getOrigin() * interp_scale;
01058             tf::Quaternion q_interp = tf::Quaternion::getIdentity();
01059             q_interp.slerp(correction.getRotation(), interp_scale);
01060 
01061             // create interpolated correction
01062             tf::Transform interpolated_correction;
01063             interpolated_correction.setOrigin(v_interp);
01064             interpolated_correction.setRotation(q_interp);
01065 
01066             // the previous frame pose
01067             tf::Transform frame_pose_prev;
01068             tf::poseMsgToTF(path_msg_.poses[f_idx].pose, frame_pose_prev);
01069 
01070             // the pevious frame motion
01071             tf::Transform frame_motion_prev = kf_pose_a_prev.inverse() * frame_pose_prev;
01072 
01073             // the interpolated motion
01074             tf::Transform interpolated_motion = frame_motion_prev * interpolated_correction;
01075 
01076             // calculate the interpolated pose
01077             path_new[f_idx] = keyframe_a.pose * eigenAffineFromTf(interpolated_motion);
01078         }
01079     }
01080 
01081     // update the last pose
01082     const rgbdtools::RGBDKeyframe& last_kf = keyframes_[kf_size - 1];
01083 
01084     tf::Transform last_kf_pose_prev;
01085     tf::poseMsgToTF(path_msg_.poses[last_kf.index].pose, last_kf_pose_prev);
01086 
01087     // update the poses in-between last keyframe and end of vo path
01088     for (int f_idx = last_kf.index; f_idx < f_size; ++f_idx)
01089     {
01090         // the previous frame pose
01091         tf::Transform frame_pose_prev;
01092         tf::poseMsgToTF(path_msg_.poses[f_idx].pose, frame_pose_prev);
01093 
01094         // the pevious frame motion
01095         tf::Transform frame_motion_prev = last_kf_pose_prev.inverse() * frame_pose_prev;
01096 
01097         // calculate the new pose
01098         path_new[f_idx] = last_kf.pose * eigenAffineFromTf(frame_motion_prev);
01099     }
01100 
01101     // copy over the interpolated path
01102     pathEigenAffineToROS(path_new, path_msg_);
01103 }
01104 
01105 
01106 bool Navigator::savePcdMap(const std::string& path)
01107 {
01108     PointCloudT pcd_map;
01109     buildPcdMap(pcd_map);
01110 
01111     // write out
01112     pcl::PCDWriter writer;
01113     int result_pcd = writer.writeBinary<PointT>(path, pcd_map);
01114 
01115     if (result_pcd < 0) return false;
01116     else return true;
01117 }
01118 
01119 void Navigator::buildPcdMap(PointCloudT& map_cloud)
01120 {
01121     PointCloudT::Ptr aggregate_cloud(new PointCloudT());
01122     aggregate_cloud->header.frame_id = fixed_frame_;
01123 
01124     // aggregate all frames into single cloud
01125     for (unsigned int kf_idx = 0; kf_idx < keyframes_.size(); ++kf_idx)
01126     {
01127         const rgbdtools::RGBDKeyframe& keyframe = keyframes_[kf_idx];
01128 
01129         PointCloudT cloud;
01130         keyframe.constructDensePointCloud(cloud, max_range_, max_stdev_);
01131 
01132         PointCloudT cloud_tf;
01133         pcl::transformPointCloud(cloud, cloud_tf, keyframe.pose);
01134         cloud_tf.header.frame_id = fixed_frame_;
01135 
01136         *aggregate_cloud += cloud_tf;
01137     }
01138 
01139     // filter cloud using voxel grid, and for max z
01140     pcl::VoxelGrid<PointT> vgf;
01141     vgf.setInputCloud(aggregate_cloud);
01142     vgf.setLeafSize(pcd_map_res_, pcd_map_res_, pcd_map_res_);
01143     vgf.setFilterFieldName("z");
01144     vgf.setFilterLimits (-std::numeric_limits<double>::infinity(), max_map_z_);
01145 
01146     vgf.filter(map_cloud);
01147 }
01148 void Navigator::buildFullCloud(PointCloudT& map_cloud)
01149 {
01150     PointCloudT::Ptr aggregate_cloud(new PointCloudT());
01151     aggregate_cloud->header.frame_id = fixed_frame_;
01152 
01153     // aggregate all frames into single cloud
01154     for (unsigned int kf_idx = 0; kf_idx < keyframes_.size(); ++kf_idx)
01155     {
01156         const rgbdtools::RGBDKeyframe& keyframe = keyframes_[kf_idx];
01157 
01158         PointCloudT cloud;
01159         keyframe.constructDensePointCloud(cloud, max_range_, max_stdev_);
01160 
01161         PointCloudT cloud_tf;
01162         pcl::transformPointCloud(cloud, cloud_tf, keyframe.pose);
01163         cloud_tf.header.frame_id = fixed_frame_;
01164 
01165         *aggregate_cloud += cloud_tf;
01166     }
01167     map_cloud = *aggregate_cloud;
01168 }
01169 
01170 bool Navigator::saveOctomap(const std::string& path)
01171 {
01172     bool result;
01173 
01174     if (octomap_with_color_)
01175     {
01176         octomap::ColorOcTree tree(octomap_res_);
01177         buildColorOctomap(tree);
01178         result = tree.write(path);
01179         //        std::cout << "Publishing octomap as pointcloud" << std::endl;
01180         //        octomap::point3d_list points_;
01181         //        tree.getOccupied(points_);
01182         //        PointCloudT cloud;
01183         //        for (octomap::point3d_list::iterator it=points_.begin(); it != points_.end(); ++it)
01184         //        {
01185         //            PointT point;
01186         //            point.x = it->x();
01187         //            point.y = it->y();
01188         //            point.z = it->z();
01189         //            point.rgb = 0;
01190         //            cloud.push_back(point);
01191         //        }
01192         //        cloud.header.frame_id = fixed_frame_;
01193         //        keyframes_pub_.publish(cloud);
01194     }
01195     else
01196         result = false;
01197     return result;
01198 }
01199 
01200 
01201 void Navigator::buildColorOctomap(octomap::ColorOcTree& tree)
01202 {
01203     ROS_INFO("Building Octomap with color...");
01204 
01205     octomap::point3d sensor_origin(0.0, 0.0, 0.0);
01206     for (unsigned int kf_idx = 0; kf_idx < keyframes_.size(); ++kf_idx)
01207     {
01208         ROS_INFO("Processing keyframe %u", kf_idx);
01209         const rgbdtools::RGBDKeyframe& keyframe = keyframes_[kf_idx];
01210 
01211         // construct the cloud
01212         PointCloudT::Ptr cloud_unf(new PointCloudT());
01213         keyframe.constructDensePointCloud(*cloud_unf, max_range_, max_stdev_);
01214 
01215         // perform filtering for max z
01216         pcl::transformPointCloud(*cloud_unf, *cloud_unf, keyframe.pose);
01217         PointCloudT cloud;
01218         pcl::PassThrough<PointT> pass;
01219         pass.setInputCloud (cloud_unf);
01220         pass.setFilterFieldName ("z");
01221         pass.setFilterLimits (-std::numeric_limits<double>::infinity(), max_map_z_);
01222         pass.filter(cloud);
01223         pcl::transformPointCloud(cloud, cloud, keyframe.pose.inverse());
01224 
01225         octomap::pose6d frame_origin = poseTfToOctomap(tfFromEigenAffine(keyframe.pose));
01226 
01227         // build octomap cloud from pcl cloud
01228         octomap::Pointcloud octomap_cloud;
01229         for (unsigned int pt_idx = 0; pt_idx < cloud.points.size(); ++pt_idx)
01230         {
01231             const PointT& p = cloud.points[pt_idx];
01232             if (!std::isnan(p.z))
01233                 octomap_cloud.push_back(p.x, p.y, p.z);
01234         }
01235 
01236         // insert scan (only xyz considered, no colors)
01237         tree.insertScan(octomap_cloud, sensor_origin, frame_origin);
01238 
01239         // insert colors
01240         PointCloudT cloud_tf;
01241         pcl::transformPointCloud(cloud, cloud_tf, keyframe.pose);
01242         for (unsigned int pt_idx = 0; pt_idx < cloud_tf.points.size(); ++pt_idx)
01243         {
01244             const PointT& p = cloud_tf.points[pt_idx];
01245             if (!std::isnan(p.z))
01246             {
01247                 octomap::point3d endpoint(p.x, p.y, p.z);
01248                 octomap::ColorOcTreeNode* n = tree.search(endpoint);
01249                 if (n) n->setColor(p.r, p.g, p.b);
01250             }
01251         }
01252 
01253         tree.updateInnerOccupancy();
01254     }
01255 }
01256 
01257 //void Navigator::publishPath()
01258 //{
01259 //    path_msg_.header.frame_id = fixed_frame_;
01260 //    path_pub_.publish(path_msg_);
01261 //}
01262 
01263 bool Navigator::savePath(const std::string& filepath)
01264 {
01265     // open file
01266     std::string filename = filepath + "/path.txt";
01267     std::ofstream file(filename.c_str());
01268     if (!file.is_open()) return false;
01269 
01270     file << "# index seq stamp.sec stamp.nsec x y z qx qy qz qw" << std::endl;
01271 
01272     for (unsigned int idx = 0; idx < path_msg_.poses.size(); ++idx)
01273     {
01274         const geometry_msgs::PoseStamped& pose = path_msg_.poses[idx];
01275 
01276         file << idx << " "
01277              << pose.header.seq << " "
01278              << pose.header.stamp.sec << " "
01279              << pose.header.stamp.nsec << " "
01280              << pose.pose.position.x << " "
01281              << pose.pose.position.y << " "
01282              << pose.pose.position.z << " "
01283              << pose.pose.orientation.x << " "
01284              << pose.pose.orientation.y << " "
01285              << pose.pose.orientation.z << " "
01286              << pose.pose.orientation.w << std::endl;
01287     }
01288 
01289     file.close();
01290 
01291     return true;
01292 }
01293 
01294 bool Navigator::savePathTUMFormat(const std::string& filepath)
01295 {
01296     // open file
01297     std::string filename = filepath + "/path.tum.txt";
01298     std::ofstream file(filename.c_str());
01299     if (!file.is_open()) return false;
01300 
01301     file << "# stamp x y z qx qy qz qw" << std::endl;
01302 
01303     for (unsigned int idx = 0; idx < path_msg_.poses.size(); ++idx)
01304     {
01305         const geometry_msgs::PoseStamped& pose = path_msg_.poses[idx];
01306 
01307         file << pose.header.stamp.sec << "."
01308              << pose.header.stamp.nsec << " "
01309              << pose.pose.position.x << " "
01310              << pose.pose.position.y << " "
01311              << pose.pose.position.z << " "
01312              << pose.pose.orientation.x << " "
01313              << pose.pose.orientation.y << " "
01314              << pose.pose.orientation.z << " "
01315              << pose.pose.orientation.w << std::endl;
01316     }
01317 
01318     file.close();
01319 
01320     return true;
01321 }
01322 
01323 bool Navigator::loadPath(const std::string& filepath)
01324 {
01325     path_msg_.poses.clear();
01326 
01327     // open file
01328     std::string filename = filepath + "/path.txt";
01329     std::ifstream file(filename.c_str());
01330     if (!file.is_open()) return false;
01331 
01332     std::string line;
01333 
01334     // get header
01335     getline(file, line);
01336 
01337     // read each line
01338     while(std::getline(file, line))
01339     {
01340         std::istringstream is(line);
01341 
01342         // fill out pose information
01343         geometry_msgs::PoseStamped pose;
01344         pose.header.frame_id = fixed_frame_;
01345         int idx;
01346 
01347         is >> idx
01348            >> pose.header.seq
01349            >> pose.header.stamp.sec
01350            >> pose.header.stamp.nsec
01351            >> pose.pose.position.x
01352            >> pose.pose.position.y
01353            >> pose.pose.position.z
01354            >> pose.pose.orientation.x
01355            >> pose.pose.orientation.y
01356            >> pose.pose.orientation.z
01357            >> pose.pose.orientation.w;
01358 
01359         // add to poses vector
01360         path_msg_.poses.push_back(pose);
01361     }
01362 
01363     file.close();
01364     return true;
01365 }
01366 
01367 } // namespace ccny_rgbd
01368 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends


ccny_rgbd
Author(s): Ivan Dryanovski
autogenerated on Tue Aug 27 2013 10:34:02