00001
00023 #include "gazebo_flocking/gazebo_flocking.h"
00024 #include "hector_uav_msgs/EnableMotors.h"
00025 #include <tf/tf.h>
00026 #include <cmath>
00027
00028 double my_theta = 0;
00029 double PI =acos(-1);
00030 #define EPSILON 0.1
00031 #define A 5
00032 #define B 5
00033 const double C = abs(A-B) / sqrt(4*A*B);
00034 #define H 0.2
00035 #define D 7
00036 #define R 9
00037 #define C1 0.3
00038 #define C2 0.6
00039 #define speedlimit 2
00040
00041 double pm1=0.3,pm2=1,pm3=0.3;
00042
00043 using namespace std;
00044
00045 class NeighborHandle
00046 {
00047 public:
00048 double _px,_py,_vx,_vy;
00049 pair<double,double> _position,_velocity;
00050 int _r_id;
00051 double mypm_g;
00052 NeighborHandle(int r_id, float x, float y, float vx, float vy)
00053 {
00054
00055 _px=x;
00056 _py=y;
00057 _vx=vx;
00058 _vy=vy;
00059 _position=pair<double,double>(x,y);
00060 _velocity=pair<double,double>(vx,vy);
00061 _r_id = r_id;
00062 mypm_g=1;
00063 }
00064 };
00065
00066 static list<NeighborHandle*> neighbor_list;
00067 pair<double,double> my_position=pair<double,double>(0,0);
00068 pair<double,double> my_velocity=pair<double,double>(0,0);
00069
00070 pair<double,double> get_vector(pair<double,double> start,pair<double,double> end)
00071 {
00072 pair<double,double> re=pair<double,double>(0,0);
00073 re.first=end.first-start.first;
00074 re.second=end.second-start.second;
00075 return re;
00076 }
00077
00078 double segma_norm(pair<double,double> v)
00079 {
00080 double re = EPSILON*(v.first*v.first+v.second*v.second);
00081 re = sqrt(1+re)-1;
00082 re /= EPSILON;
00083 return re;
00084 }
00085
00086 double R_alpha = segma_norm(pair<double,double>(R,0));
00087 double D_alpha = segma_norm(pair<double,double>(D,0));
00088
00089 pair<double,double> segma_epsilon(pair<double,double> v)
00090 {
00091 pair<double,double> re = pair<double,double>(0,0);
00092 double scale = 1+EPSILON*(v.first*v.first+v.second*v.second);
00093 scale = sqrt(scale);
00094 re.first = v.first / scale;
00095 re.second = v.second / scale;
00096 return re;
00097 }
00098
00099 double segma_1(double z)
00100 {
00101 return z / sqrt(1+z*z);
00102 }
00103
00104 double phi(double z)
00105 {
00106 return 0.5*((A+B)*segma_1(z+C)+A-B);
00107 }
00108
00109 double rho(double z)
00110 {
00111 if(z<H)
00112 return 1;
00113 if(z>1)
00114 return 0;
00115 return 0.5*(1+cos(PI*(z-H)/(1-H)));
00116 }
00117
00118 double phi_alpha(double z)
00119 {
00120 return rho(z/R_alpha)*phi(z-D_alpha);
00121 }
00122
00123 pair<double,double> f_g()
00124 {
00125 pair<double,double> re = pair<double,double>(0,0);
00126 for(list<NeighborHandle*>::iterator i=neighbor_list.begin();i!=neighbor_list.end();i++)
00127 {
00128 pair<double,double> q_ij = get_vector(my_position,(*i)->_position);
00129 pair<double,double> n_ij = segma_epsilon(q_ij);
00130 re.first += phi_alpha(segma_norm(q_ij))*n_ij.first*(*i)->mypm_g;
00131 re.second += phi_alpha(segma_norm(q_ij))*n_ij.second*(*i)->mypm_g;
00132 }
00133 return re;
00134 }
00135
00136 double a_ij(pair<double,double> j_p)
00137 {
00138 return rho(segma_norm(get_vector(my_position,j_p)) / R_alpha);
00139 }
00140
00141 pair<double,double> f_d()
00142 {
00143 pair<double,double> re = pair<double,double>(0,0);
00144 for(list<NeighborHandle*>::iterator i=neighbor_list.begin();i!=neighbor_list.end();i++)
00145 {
00146 pair<double,double> p_ij = get_vector(my_velocity,(*i)->_velocity);
00147 re.first += a_ij((*i)->_position) * p_ij.first;
00148 re.second += a_ij((*i)->_position) * p_ij.second;
00149 }
00150 return re;
00151 }
00152
00153 double interval = 0.1;
00154 pair<double,double> p_r = pair<double,double>(3,0);
00155 pair<double,double> q_r = pair<double,double>(-40,-40);
00156 pair<double,double> f_r()
00157 {
00158 pair<double,double> re = pair<double,double>(0,0);
00159
00160
00161
00162 re.first = -C1*get_vector(q_r,my_position).first - C2*get_vector(p_r,my_velocity).first;
00163 re.second = -C1*get_vector(q_r,my_position).second - C2*get_vector(p_r,my_velocity).second;
00164 return re;
00165 }
00166
00167
00168 PLUGINLIB_EXPORT_CLASS(gazebo_flocking::GazeboFlocking, micros_swarm::Application)
00169
00170 namespace gazebo_flocking{
00171
00172 GazeboFlocking::GazeboFlocking() {}
00173
00174 GazeboFlocking::~GazeboFlocking() {}
00175
00176 void GazeboFlocking::stop() {}
00177
00178 void GazeboFlocking::init()
00179 {
00180
00181 hz = 10;
00182 interval = 1.0/hz;
00183 }
00184
00185 int vel_loop_count =0;
00186
00187 bool test_location(float a, float b, float x, float y)
00188 {
00189 float s = sqrt((a-x)*(a-x)+(b-y)*(b-y));
00190 if(s <= 2) {
00191 return true;
00192 }
00193 return false;
00194 }
00195
00196 void GazeboFlocking::publish_cmd(const ros::TimerEvent&)
00197 {
00198 static double base_angle = 0;
00199 vel_loop_count++;
00200 int time_count = vel_loop_count;
00201 int hz = 10;
00202 double baseomega = 0;
00203 double basespeed = 3;
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 if(time_count>=23*hz && time_count<=23*hz+10*hz)
00236 baseomega = PI/2.0/10;
00237 else if(time_count >= 49.5*hz && time_count <= 49.5*hz+10*hz)
00238 baseomega = PI/2.0/10;
00239 else if (time_count >= 76*hz && time_count<=76*hz+21*hz)
00240 baseomega = (PI-0.15)/2.0/10;
00241 else if (time_count >=103*hz)
00242 {
00243 basespeed=0;
00244
00245 baseomega =0;
00246 }
00247
00248 base_angle += baseomega /hz;
00249 p_r.first = basespeed * cos(base_angle);
00250 p_r.second = basespeed * sin(base_angle);
00251 q_r.first += p_r.first * interval;
00252 q_r.second += p_r.second * interval;
00253
00254 geometry_msgs:: Twist msg;
00255 micros_swarm::Neighbors<micros_swarm::NeighborBase> n(true);
00256
00257 typename std::map<int, micros_swarm::NeighborBase>::iterator it;
00258 for(it=n.data().begin();it!=n.data().end();it++)
00259 {
00260 NeighborHandle* nh=new NeighborHandle(it->first, it->second.x, it->second.y, it->second.vx, it->second.vy);
00261 neighbor_list.push_back(nh);
00262 }
00263
00264 micros_swarm::Base nl = get_base();
00265
00266 my_position=pair<double,double>(nl.x, nl.y);
00267 my_velocity=pair<double,double>(nl.vx, nl.vy);
00268
00269 msg.linear.x += (f_g().first*pm1+f_d().first*pm2+f_r().first*pm3)/hz;
00270 msg.linear.y += (f_g().second*pm1+f_d().second*pm2+f_r().second*pm3)/hz;
00271
00272
00273 if (msg.linear.x >speedlimit)
00274 msg.linear.x=speedlimit;
00275 if (msg.linear.x <-speedlimit)
00276 msg.linear.x=-speedlimit;
00277 if (msg.linear.y >speedlimit)
00278 msg.linear.y=speedlimit;
00279 if (msg.linear.y <-speedlimit)
00280 msg.linear.y=-speedlimit;
00281
00282 msg.linear.x +=p_r.first;
00283 msg.linear.y +=p_r.second;
00284
00285
00286
00287 geometry_msgs::Twist sendmsg;
00288 sendmsg.linear.x =msg.linear.x;
00289 sendmsg.linear.y = msg.linear.y;
00290 if(sendmsg.linear.x==0 && sendmsg.linear.y==0)
00291 pub.publish(sendmsg);
00292 else{
00293 double fi = PI/2;
00294 if(sendmsg.linear.x!=0)
00295 {
00296 fi=atan(sendmsg.linear.y/sendmsg.linear.x);
00297 if(sendmsg.linear.x<0&&sendmsg.linear.y>=0)
00298 fi+=PI;
00299 else if (sendmsg.linear.x<0 && sendmsg.linear.y<0)
00300 fi-=PI;
00301 }
00302 else if (sendmsg.linear.y<0)
00303 fi= -PI/2;
00304 double v_scale = sqrt(sendmsg.linear.x*sendmsg.linear.x+sendmsg.linear.y*sendmsg.linear.y);
00305 sendmsg.linear.x = v_scale*cos(fi-my_theta);
00306 sendmsg.linear.y = v_scale *sin(fi-my_theta);
00307 pub.publish(sendmsg);}
00308
00309
00310 neighbor_list.clear();
00311 }
00312
00313 void GazeboFlocking::baseCallback(const nav_msgs::Odometry& lmsg)
00314 {
00315 float x = lmsg.pose.pose.position.x;
00316 float y = lmsg.pose.pose.position.y;
00317
00318 float vx = lmsg.twist.twist.linear.x;
00319 float vy = lmsg.twist.twist.linear.y;
00320 my_theta = tf::getYaw(lmsg.pose.pose.orientation);
00321 micros_swarm::Base l(x, y, 0, vx, vy, 0, 1);
00322 set_base(l);
00323 }
00324
00325 void GazeboFlocking::start()
00326 {
00327 init();
00328
00329 ros::NodeHandle nh;
00330 ros::ServiceClient client = nh.serviceClient<hector_uav_msgs::EnableMotors>("enable_motors");
00331 hector_uav_msgs::EnableMotors srv;
00332 srv.request.enable = true;
00333 if (client.call(srv))
00334 {
00335 ;
00336 }
00337 else
00338 {
00339 ROS_ERROR("Failed to call service enable_motors");
00340 }
00341
00342 set_dis(12);
00343 pub = nh.advertise<geometry_msgs::Twist>("cmd_vel", 1000);
00344 ros::Rate loop_rate(10);
00345 for(int i = 0; i < 7*10; i++) {
00346 geometry_msgs:: Twist upmsg;
00347 upmsg.linear.z = 1;
00348 pub.publish(upmsg);
00349 loop_rate.sleep();
00350 }
00351
00352
00353 sub = nh.subscribe("ground_truth/state", 1000, &GazeboFlocking::baseCallback, this, ros::TransportHints().udp());
00354
00355
00356 timer = nh.createTimer(ros::Duration(interval), &GazeboFlocking::publish_cmd, this);
00357 }
00358 };
00359