Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 #include <iostream>
00009 #include <ros/ros.h>
00010 #include <nodelet/nodelet.h>
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <pluginlib/class_list_macros.h>
00023
00024 #include <geometry_msgs/Twist.h>
00025 #include <nav_msgs/Odometry.h>
00026 #include <math.h>
00027
00028 #include <message_filters/subscriber.h>
00029 #include <message_filters/synchronizer.h>
00030 #include <message_filters/sync_policies/approximate_time.h>
00031
00032 namespace micros_mars_task_alloc{
00033 using namespace std;
00034 using namespace message_filters;
00035 class RobotFollow : public nodelet::Nodelet
00036 {
00037 public:
00038 RobotFollow(): maximum_queue_size_(10), pi_(std::acos(-1)), follow_distance_(0.5), linear_velocity_(0.3), angular_velocity_(0.5){}
00039 virtual ~RobotFollow(){}
00040
00041 virtual void onInit();
00042
00043 void callback(const nav_msgs::OdometryConstPtr & msg_0, const nav_msgs::OdometryConstPtr & msg_1);
00044
00045
00046 private:
00047 ros::NodeHandle nh_;
00048
00049 typedef sync_policies::ApproximateTime<nav_msgs::Odometry, nav_msgs::Odometry> ApproximatePolicy;
00050 typedef message_filters::Synchronizer<ApproximatePolicy> ApproximateSync;
00051
00052 boost::shared_ptr<ApproximateSync> approximate_sync_;
00053
00054 message_filters::Subscriber<nav_msgs::Odometry> sub_0_, sub_1_;
00055 float pi_, follow_distance_, linear_velocity_, angular_velocity_;
00056 int maximum_queue_size_;
00057 ros::Publisher pub_;
00058 };
00059
00060 void RobotFollow::onInit()
00061 {
00062 nh_ = getMTPrivateNodeHandle();
00063 cout << "Initialising nodelet robot follow" << endl;
00064
00065 sub_0_.subscribe(nh_, "/robot_0/base_pose_ground_truth", 1);
00066 sub_1_.subscribe(nh_, "/robot_3/base_pose_ground_truth", 1);
00067
00068 approximate_sync_.reset( new ApproximateSync(ApproximatePolicy(maximum_queue_size_), sub_0_, sub_1_) );
00069 approximate_sync_->registerCallback(boost::bind(&RobotFollow::callback, this, _1, _2));
00070 pub_ = nh_.advertise<geometry_msgs::Twist>("/robot_0/cmd_vel", 10);
00071 }
00072
00073 void RobotFollow::callback(const nav_msgs::OdometryConstPtr & msg_0, const nav_msgs::OdometryConstPtr & msg_1)
00074 {
00075 cout << "callback start!" << endl;
00076 float x, y, z, w;
00077 float follower_pose_x;
00078 float follower_pose_y;
00079 float intruder_pose_x;
00080 float intruder_pose_y;
00081
00082 float leader_direction;
00083 float follower_orientation;
00084 geometry_msgs::TwistPtr cmd(new geometry_msgs::Twist);
00085
00086 x = msg_0->pose.pose.orientation.x;
00087 y = msg_0->pose.pose.orientation.y;
00088 z = msg_0->pose.pose.orientation.z;
00089 w = msg_0->pose.pose.orientation.w;
00090
00091 follower_pose_x = msg_0->pose.pose.position.x;
00092 follower_pose_y = msg_0->pose.pose.position.y;
00093
00094 intruder_pose_x = msg_1->pose.pose.position.x;
00095 intruder_pose_y = msg_1->pose.pose.position.y;
00096
00097 leader_direction = float(atan2(double(intruder_pose_y - follower_pose_y), double(intruder_pose_x - follower_pose_x)));
00098 if ((leader_direction > (-1)*pi_ || leader_direction == (-1) * pi_) && (leader_direction < 0))
00099 leader_direction = 2 * pi_ + leader_direction;
00100
00101 follower_orientation = float(atan2(double(2*(w*z+x*y)), double(1-2*(y*y+z*z))));
00102 if ((follower_orientation > -1*pi_ || follower_orientation == -1*pi_) && (follower_orientation < 0))
00103 follower_orientation = 2*pi_ + follower_orientation;
00104
00105 if (((follower_pose_x - intruder_pose_x)*(follower_pose_x - intruder_pose_x) + (follower_pose_y - intruder_pose_y)*(follower_pose_y - intruder_pose_y)) > follow_distance_*follow_distance_)
00106 {
00107 if (follower_orientation < leader_direction)
00108 {
00109 cmd->linear.x = linear_velocity_;
00110 cmd->angular.z = angular_velocity_;
00111 pub_.publish(cmd);
00112 }
00113 else
00114 {
00115 cmd->linear.x = linear_velocity_;
00116 cmd->angular.z = -1 * angular_velocity_;
00117 pub_.publish(cmd);
00118 }
00119 }
00120 else
00121 {
00122 cmd->linear.x = 0.0;
00123 cmd->angular.z = 0.0;
00124 pub_.publish(cmd);
00125 }
00126 }
00127
00128 }
00129 PLUGINLIB_EXPORT_CLASS(micros_mars_task_alloc::RobotFollow, nodelet::Nodelet)