00001
00002
00003
00004
00005
00006
00007
00008 #include <ros/ros.h>
00009 #include <nodelet/nodelet.h>
00010 #include <limits>
00011 #include <iostream>
00012 #include <pluginlib/class_list_macros.h>
00013
00014 #include <vector>
00015 #include <algorithm>
00016 #include <functional>
00017 #include <math.h>
00018
00019 #include <message_filters/subscriber.h>
00020 #include <message_filters/synchronizer.h>
00021 #include <message_filters/sync_policies/approximate_time.h>
00022
00023 #include <sensor_msgs/Range.h>
00024 #include <micros_mars_task_alloc/Force.h>
00025
00026 namespace micros_mars_task_alloc {
00027 using namespace sensor_msgs;
00028 using namespace message_filters;
00029 using namespace std;
00030
00031 class Feelforce : public nodelet::Nodelet
00032 {
00033 public:
00034 Feelforce(): maximum_queue_size_(10), min_range_(0.3), max_range_(3.0), pi_(std::acos(-1)){}
00035 ~Feelforce(){}
00036
00037 virtual void onInit();
00038
00039
00040
00041 void callback_0(const RangeConstPtr& msg_0, const RangeConstPtr& msg_1, const RangeConstPtr& msg_2,
00042 const RangeConstPtr& msg_3, const RangeConstPtr& msg_4, const RangeConstPtr& msg_5);
00043 void callback_1(const RangeConstPtr& msg_0, const RangeConstPtr& msg_1, const RangeConstPtr& msg_2,
00044 const RangeConstPtr& msg_3, const RangeConstPtr& msg_4, const RangeConstPtr& msg_5);
00045
00046 void timerCallback(const ros::TimerEvent&);
00047
00048 typedef struct force
00049 {
00050 float range;
00051 float angle;
00052 }Force;
00053
00054 private:
00055
00056
00057 typedef sync_policies::ApproximateTime<Range, Range, Range, Range, Range, Range> ApproximatePolicy;
00058 typedef message_filters::Synchronizer<ApproximatePolicy> ApproximateSync;
00059
00060
00061 boost::shared_ptr<ApproximateSync> approximate_sync_1_;
00062 boost::shared_ptr<ApproximateSync> approximate_sync_2_;
00063
00064 float pi_;
00065 int maximum_queue_size_;
00066 float min_range_;
00067 float max_range_;
00068
00069 float r_[12];
00070
00071 message_filters::Subscriber<Range> sub_0_, sub_1_, sub_2_, sub_3_, sub_4_, sub_5_, sub_6_, sub_7_, sub_8_, sub_9_, sub_10_, sub_11_;
00072 ros::Timer timer_;
00073 ros::NodeHandle nh_;
00074 ros::Publisher pub_;
00075
00076 };
00077
00078 void Feelforce::onInit()
00079 {
00080 nh_ = getPrivateNodeHandle();
00081 cout << "Initialising nodelet ..." << endl;
00082
00083
00084 sub_0_.subscribe(nh_, "/robot0/sonar_0", 1);
00085 sub_1_.subscribe(nh_, "/robot0/sonar_1", 1);
00086 sub_2_.subscribe(nh_, "/robot0/sonar_2", 1);
00087 sub_3_.subscribe(nh_, "/robot0/sonar_3", 1);
00088 sub_4_.subscribe(nh_, "/robot0/sonar_4", 1);
00089 sub_5_.subscribe(nh_, "/robot0/sonar_5", 1);
00090 sub_6_.subscribe(nh_, "/robot0/sonar_6", 1);
00091 sub_7_.subscribe(nh_, "/robot0/sonar_7", 1);
00092 sub_8_.subscribe(nh_, "/robot0/sonar_8", 1);
00093 sub_9_.subscribe(nh_, "/robot0/sonar_9", 1);
00094 sub_10_.subscribe(nh_, "/robot0/sonar_10", 1);
00095 sub_11_.subscribe(nh_, "/robot0/sonar_11", 1);
00096
00097 approximate_sync_1_.reset( new ApproximateSync(ApproximatePolicy(maximum_queue_size_), sub_0_, sub_1_, sub_2_, sub_3_, sub_4_, sub_5_ ) );
00098 approximate_sync_1_->registerCallback(boost::bind(&Feelforce::callback_0, this, _1, _2, _3, _4, _5, _6));
00099
00100 approximate_sync_2_.reset( new ApproximateSync(ApproximatePolicy(maximum_queue_size_), sub_6_, sub_7_, sub_8_, sub_9_, sub_10_, sub_11_ ) );
00101 approximate_sync_2_->registerCallback(boost::bind(&Feelforce::callback_1, this, _1, _2, _3, _4, _5, _6));
00102
00103 timer_ = nh_.createTimer(ros::Duration(0.1), &Feelforce::timerCallback, this);
00104
00105 }
00106
00107 void Feelforce::callback_0(const RangeConstPtr& msg_0, const RangeConstPtr& msg_1, const RangeConstPtr& msg_2,
00108 const RangeConstPtr& msg_3, const RangeConstPtr& msg_4, const RangeConstPtr& msg_5)
00109 {
00110
00111 r_[0] = msg_0 -> range;
00112 r_[1] = msg_1 -> range;
00113 r_[2] = msg_2 -> range;
00114 r_[3] = msg_3 -> range;
00115 r_[4] = msg_4 -> range;
00116 r_[5] = msg_5 -> range;
00117 }
00118
00119 void Feelforce::callback_1(const RangeConstPtr& msg_0, const RangeConstPtr& msg_1, const RangeConstPtr& msg_2,
00120 const RangeConstPtr& msg_3, const RangeConstPtr& msg_4, const RangeConstPtr& msg_5)
00121 {
00122
00123 r_[6] = msg_0 -> range;
00124 r_[7] = msg_1 -> range;
00125 r_[8] = msg_2 -> range;
00126 r_[9] = msg_3 -> range;
00127 r_[10] = msg_4 -> range;
00128 r_[11] = msg_5 -> range;
00129 }
00130
00131 void Feelforce::timerCallback(const ros::TimerEvent&)
00132 {
00133 vector<Force> vec;
00134
00135 float rectangular_coordinates_sum_x = 0;
00136 float rectangular_coordinates_sum_y = 0;
00137 for (int i = 0; i < 12; i++)
00138 {
00139 Force a;
00140
00141
00142
00143
00144
00145
00146
00147 if (r_[i] == std::numeric_limits<float>::infinity())
00148 a.range = max_range_;
00149 else if (r_[i] == -std::numeric_limits<float>::infinity())
00150 a.range = min_range_;
00151 else
00152 a.range = r_[i];
00153
00154 a.angle = i * 30.0;
00155 vec.push_back(a);
00156 }
00157
00158 for_each(vec.begin(), vec.end(), [&, this](const Force& val)->void
00159 {
00160
00161
00162
00163 rectangular_coordinates_sum_x += (1/(val.range*val.range)) * std::cos(pi_ * val.angle / 180.0);
00164 rectangular_coordinates_sum_y += (1/(val.range*val.range)) * std::sin(pi_ * val.angle / 180.0);
00165 });
00166 rectangular_coordinates_sum_x = (-1) * rectangular_coordinates_sum_x;
00167 rectangular_coordinates_sum_y = (-1) * rectangular_coordinates_sum_y;
00168
00169
00170
00171 micros_mars_task_alloc::ForcePtr force_ptr(new micros_mars_task_alloc::Force);
00172
00173 force_ptr -> magnitude = float( sqrt(double(rectangular_coordinates_sum_x * rectangular_coordinates_sum_x) + double(rectangular_coordinates_sum_y * rectangular_coordinates_sum_y))/12.0);
00174 force_ptr -> direction = float( fmod((atan2(double(rectangular_coordinates_sum_y), double(rectangular_coordinates_sum_x)) + 2 * double(pi_)) , (2 * double(pi_))) );
00175
00176
00177
00178
00179 pub_ = nh_.advertise<micros_mars_task_alloc::Force>("force", 10);
00180 pub_.publish(force_ptr);
00181 }
00182 }
00183 PLUGINLIB_EXPORT_CLASS(micros_mars_task_alloc::Feelforce, nodelet::Nodelet)