Go to the documentation of this file.00001
00002
00003 #include <vector>
00004 #include <opencv2/opencv.hpp>
00005 #include <boost/random.hpp>
00006 #include <boost/random/mersenne_twister.hpp>
00007 #include <boost/nondet_random.hpp>
00008 #include <boost/random/normal_distribution.hpp>
00009
00010 #include <Eigen/Core>
00011 #include <Eigen/Eigen>
00012
00013 #include <ros/ros.h>
00014 #include <geometry_msgs/Twist.h>
00015 #include <nav_msgs/Odometry.h>
00016 #include <nav_msgs/OccupancyGrid.h>
00017 #include <nav_msgs/GetMap.h>
00018
00019 #include <sensor_msgs/LaserScan.h>
00020 #include <tf/tf.h>
00021 #include <tf/transform_broadcaster.h>
00022
00023 #include <visualization_msgs/Marker.h>
00024 #include "featuresextractor.h"
00025
00026
00027 #include <pcl/point_cloud.h>
00028 #include <pcl/point_types.h>
00029 #include <pcl_ros/publisher.h>
00030 #include <pcl_ros/point_cloud.h>
00031 #include <pcl/common/transforms.h>
00032 #include <tf/transform_listener.h>
00033 #include <pcl_ros/transforms.h>
00034 #include <pcl_conversions/pcl_conversions.h>
00035 #include <pcl/registration/icp.h>
00036 #include <pcl/registration/icp_nl.h>
00037 #include <pcl/filters/voxel_grid.h>
00038 #include <pcl/filters/statistical_outlier_removal.h>
00039 #include <pcl_conversions/pcl_conversions.h>
00040
00041
00042 #include <filter/extendedkalmanfilter.h>
00043 #include <pdf/analyticconditionalgaussian.h>
00044 #include <pdf/linearanalyticconditionalgaussian.h>
00045 #include <model/linearanalyticsystemmodel_gaussianuncertainty.h>
00046 #include <model/linearanalyticmeasurementmodel_gaussianuncertainty.h>
00047
00048 #include "bayesian_filtering/nonlinearanalyticconditionalgaussianmobile.h"
00049 #include <laser_geometry/laser_geometry.h>
00050
00051
00052 class EKFnode
00053 {
00054 typedef pcl::PointXYZ point_type;
00055 typedef pcl::PointCloud<point_type> map_t;
00056 typedef map_t::Ptr map_t_ptr;
00057
00058
00059 ros::NodeHandle nh_priv;
00060 ros::NodeHandle nh_;
00061
00062 tf::Transformer transformer_;
00063 ros::Time odom_last_stamp_, laser_last_stamp_, odom_init_stamp_,laser_init_stamp_, filter_stamp_;
00064
00065 boost::shared_ptr<tf::TransformListener> listener;
00066 std::string base_link;
00067 std::string odom_link;
00068 std::string map_link;
00069 std::string laser_link;
00070 bool use_map_topic_, first_map_only_,first_map_received_;
00071 ros::Subscriber laser_sub;
00072 ros::Subscriber map_sub_;
00073 ros::Publisher location_undertainty;
00074 ros::Publisher map_pub_;
00075 ros::Publisher local_features_pub;
00076 ros::Timer timer_;
00077 int laser_max_beams_;
00078
00079 tf::TransformBroadcaster tf_broadcaster;
00080 pcl::PointCloud<point_type>::Ptr laser;
00081 laser_geometry::LaserProjection projector_;
00082 boost::shared_ptr<BFL::ExtendedKalmanFilter> filter;
00083 boost::shared_ptr<BFL::NonLinearAnalyticConditionalGaussianMobile> sys_pdf;
00084 boost::shared_ptr<BFL::AnalyticSystemModelGaussianUncertainty> sys_model;
00085 boost::shared_ptr<BFL::LinearAnalyticConditionalGaussian> meas_pdf;
00086 boost::shared_ptr<BFL::LinearAnalyticMeasurementModelGaussianUncertainty> meas_model;
00087
00088 pcl::PointCloud<point_type>::Ptr map_;
00089
00090 double alpha_1, alpha_2, alpha_3, alpha_4;
00091 double d_thresh_, a_thresh_;
00092 double voxel_grid_size;
00093
00094
00095 tf::Stamped<tf::Pose> latest_odom_pose_;
00096 tf::Stamped<tf::Pose> filter_odom_pose_;
00097
00098 FeaturesExtractor features_extractor;
00099 double max_correspondence_distance;
00100 int max_iterations;
00101 int ransac_iterations;
00102 double ransac_outlier_threshold;
00103 double icp_optimization_epsilon;
00104 double icp_score_scale;
00105 double covariance_marker_scale_;
00106
00107 bool odom_active_, laser_active_, odom_initialized_,laser_initialized_;
00108
00109 BFL::ColumnVector last_laser_pose_;
00110 void laser_callback(const sensor_msgs::LaserScan::ConstPtr& msg);
00111 void drawCovariance(const Eigen::Matrix2f& covMatrix);
00112 void drawFeatures();
00113 void requestMap();
00114 void mapReceived(const nav_msgs::OccupancyGridConstPtr& msg);
00115 void handleMapMessage(const nav_msgs::OccupancyGrid& msg);
00116 void convertMap( const nav_msgs::OccupancyGrid& map_msg );
00117
00118 void broadcast(const ros::Time & broad_cast_time);
00119 bool predict();
00120
00121 void angleOverflowCorrect(double& a)
00122 {
00123 while ((a) > M_PI) a -= 2*M_PI;
00124 while ((a) < -M_PI) a += 2*M_PI;
00125 }
00126
00127 void publishFeatures()
00128 {
00129 map_pub_.publish(map_);
00130 }
00131 enum {OCCUPIED = 0, FREE = 255};
00132 const static int CV_TYPE = CV_64F;
00133
00134 public:
00135
00136 EKFnode(const ros::NodeHandle& nh, const double & spin_rate, const double & voxel_grid_size_=0.005);
00137
00138 void spin(const ros::TimerEvent& e);
00139 };
00140