00001 #ifndef FEATURENAV_BASE_NJOCKEY_H 00002 #define FEATURENAV_BASE_NJOCKEY_H 00003 00004 #include <algorithm> // std::for_each 00005 #include <cmath> // std::abs, std::max, std::min, std::ceil 00006 #include <utility> // std::pair 00007 00008 #include <boost/smart_ptr.hpp> 00009 #include <boost/range/iterator_range_core.hpp> 00010 #include <boost/accumulators/accumulators.hpp> 00011 #include <boost/accumulators/statistics/density.hpp> 00012 #include <boost/accumulators/statistics/stats.hpp> 00013 00014 #include <angles/angles.h> 00015 #include <geometry_msgs/Twist.h> 00016 #include <image_transport/image_transport.h> 00017 #include <ros/ros.h> 00018 #include <sensor_msgs/Image.h> 00019 #include <tf/tf.h> 00020 #include <nav_msgs/Odometry.h> 00021 00022 #include <lama_jockeys/navigating_jockey.h> 00023 00024 #include <featurenav_base/typedef.h> 00025 #include <featurenav_base/GetSegment.h> 00026 #include <featurenav_base/Landmark.h> 00027 00028 namespace featurenav_base 00029 { 00030 00031 using boost::accumulators::tag::density; 00032 00033 // Histogram with pixel distance as x-axis and density as y-axis. 00034 typedef boost::iterator_range<vector<std::pair<double, double> >::iterator> histogram_type; 00035 typedef boost::accumulators::accumulator_set<double, boost::accumulators::stats<density> > accumulator_type; 00036 00037 class NJockey : public lama_jockeys::NavigatingJockey 00038 { 00039 public: 00040 00041 NJockey(const std::string& name, const std::string& segment_interface_name, const std::string& segment_getter_name); 00042 00043 void setExtractFeaturesFunction(feature_extractor_function_ptr f) {extract_features_ = f;} 00044 void setDescriptorMatcherFunction(descriptor_matcher_function_ptr f) {match_descriptors_ = f;} 00045 00046 can_do_function_ptr canDo; 00047 start_do_function_ptr startDo; 00048 00049 private: 00050 00051 void reset(); 00052 bool retrieveSegment(); 00053 00054 virtual void onTraverse(); 00055 virtual void onStop(); 00056 virtual void onInterrupt(); 00057 virtual void onContinue(); 00058 00059 void callback_image(const sensor_msgs::ImageConstPtr& msg); 00060 void callback_odom(const nav_msgs::OdometryConstPtr& msg); 00061 00062 geometry_msgs::Twist turnToAngle(const double direction); 00063 double saturate(double w) const; 00064 size_t processImage(const sensor_msgs::ImageConstPtr& image, double& w); 00065 vector<Landmark> select_tracked_landmarks(const double d) const; 00066 vector<double> compute_horizontal_differences(const vector<Landmark>& landmarks, 00067 const vector<cv::KeyPoint>& keypoints, const vector<Feature>& descriptors, const double d); 00068 00071 inline double distance_from_start() 00072 { 00073 if (!has_odom_) 00074 { 00075 return 0.0; 00076 } 00077 const double dx = odom_.pose.pose.position.x - start_pose_.position.x; 00078 const double dy = odom_.pose.pose.position.y - start_pose_.position.y; 00079 return std::sqrt(dx * dx + dy * dy); 00080 } 00081 00082 // Subscribers and publishers. 00083 image_transport::ImageTransport it_; 00084 image_transport::Subscriber image_handler_; 00085 ros::Subscriber odom_handler_; 00086 ros::Publisher twist_publisher_; 00087 00088 // Client proxies. 00089 ros::ServiceClient segment_getter_proxy_; 00090 00091 // ROS parameters (shown outside). 00092 double forward_velocity_; 00093 double kp_; 00094 double matcher_max_relative_distance_; 00095 00096 00097 double max_angular_velocity_; 00098 double min_angular_velocity_; 00099 00100 // Hard-coded parameters. 00101 static const ros::Duration max_odom_age_; 00102 static const int histogram_bin_size_; 00103 const static double reach_angular_distance_; 00104 00105 // Internals. 00106 std::string segment_interface_name_; 00107 std::string segment_getter_name_; 00108 feature_extractor_function_ptr extract_features_; 00109 descriptor_matcher_function_ptr match_descriptors_; 00110 nav_msgs::Odometry odom_; 00111 bool has_odom_; 00112 bool start_angle_reached_; 00113 bool image_processing_running_; 00114 geometry_msgs::Pose start_pose_; 00115 ::featurenav_base::Segment segment_; 00116 }; 00117 00118 } // namespace featurenav_base 00119 00120 #endif // FEATURENAV_BASE_NJOCKEY_H 00121