Go to the documentation of this file.00001 #include <ros/ros.h>
00002 #include <actionlib/server/simple_action_server.h>
00003 #include <laser_geometry/laser_geometry.h>
00004 #include <tf/transform_listener.h>
00005 #include <scan_mapper/canonical_scan.h>
00006
00007 class OmnixAlignment{
00008 private:
00009 std::map<std::string,sensor_msgs::LaserScan> location_scans;
00010
00011 sensor_msgs::LaserScan prev_scan_;
00012
00013 bool align_active_;
00014 std::string goal_name_;
00015
00016 scan_tools::CanonicalScan canonicalScan;
00017
00018 public:
00019 ros::NodeHandle n_;
00020 tf::TransformListener tf_listener_;
00021
00022 ros::ServiceServer align_save_srv_;
00023 ros::Subscriber laser_sub_;
00024
00025 OmnixAlignment() :
00026 n_("~"),
00027 tf_listener_(ros::Duration(60.0))
00028 {
00029 align_active_ = false;
00030
00031 laser_sub_ = n_.subscribe<sensor_msgs::LaserScan>("scan",1,boost::bind(&OmnixAlignment::laserScanCallback,this,_1));
00032
00033 align_save_srv_ = n_.advertiseService("save_location",&OmnixAlignment::alignSaveCallback,this);
00034 }
00035
00036 bool OmnixAlignment::alignSaveCallback(omnix::AlignSave::Request &req, omnix::AlignSave::Response &res)
00037 {
00038
00039 location_scans[req.location_name] = prev_scan_;
00040 return true;
00041 }
00042
00043 bool OmnixAlignment::alignCallback(omnix::Align::Request &req, omnix::Align::Response &res)
00044 {
00045
00046 if(location_scans.find(res.location_name) == location_scans.end()){
00047 ROS_ERROR("OmnixAlignment: Requested key not known!");
00048 return false;
00049 }
00050
00051
00052 goal_name_ = req.location_name;
00053
00054
00055 align_active_ = true;
00056
00057 return true;
00058 }
00059
00060 void OmnixAlignment::laserScanCallback(const sensor_msgs::LaserScan::ConstPtr& scan_msg)
00061 {
00062 LDP prev_ldp;
00063 LDP curr_ldp;
00064
00065 if(align_active){
00066
00067 canonicalScan.laserScanToLDP(prev_scan_,prev_ldp);
00068 canonicalScan.laserScanToLDP(scan_msg,curr_ldp);
00069
00070 tf::Transform init_pose = btTransform(tf::createQuaternionFromYaw(0.0),btVector3(0.0,0.0,0.0));
00071 gtsam::Pose2 output_pose;
00072 gtsam::noiseModel::Gaussian::shared_ptr noise_model;
00073
00074 bool worked = canonicalScan.processScan(curr_ldp,prev_ldp,
00075 init_pose,
00076 output_pose,
00077 noise_model);
00078
00079
00080 if(!worked){
00081 ROS_INFO("ICP fail!");
00082 } else {
00083 ROS_INFO("Pose: %lf %lf %lf",output_pose.x(),output_pose.y(),output_pose.z());
00084
00085
00086
00087 tf::StampedTransform laser_to_base;
00088 try{
00089 tf_listener_->waitForTransform(scan_msg.header.frame_id, "/base_link",scan_msg.header.stamp,ros::Duration(0.6));
00090 tf_listener_->lookupTransform(scan_msg.header.frame_id, "/base_link",scan_msg.header.stamp,laser_to_base);
00091 } catch(tf::TransformException ex){
00092 ROS_ERROR("Omnix Alignment: TF Fail!");
00093 }
00094
00095
00096
00097
00098
00099
00100 }
00101
00102 }
00103
00104 prev_scan_ = scan_msg;
00105 }
00106
00107 };