gazebo_flocking.cpp
Go to the documentation of this file.
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 // Register the application
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         //set parameters
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             //if(q_r.first == 40 && q_r.second == -40)
00206             if(vel_loop_count==230)
00207             //if(test_location(q_r.first, q_r.second, 40, -40))
00208             {
00209                 p_r.first = 0;
00210                 p_r.second = 3;
00211             }
00212 
00213             //if(q_r.first == 40 && q_r.second == 40)
00214             if(vel_loop_count==440)
00215             //if(test_location(q_r.first, q_r.second, 40, 40))
00216             {
00217                 p_r.first = -3;
00218                 p_r.second = 0;
00219             }
00220 
00221             //if(q_r.first == -40 && q_r.second == 40)
00222             if(vel_loop_count==500)
00223             if(test_location(q_r.first, q_r.second, -40, 40))
00224             {
00225                 p_r.first = 0;
00226                 p_r.second = -3;
00227             }
00228             if(vel_loop_count==620)
00229             if(test_location(q_r.first, q_r.second, -40, 40))
00230             {
00231                 p_r.first = 3;
00232                 p_r.second = 0;
00233             }     */
00234 
00235         if(time_count>=23*hz && time_count<=23*hz+10*hz)
00236             baseomega = PI/2.0/10;//PI/30;
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             //else
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         //cout<<f_g().second<<' '<<f_d().second<<' '<<msg.linear.y<<endl;
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         //theta handle
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         //pub.publish(msg);
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         //sub = nh.subscribe("base_pose_ground_truth", 1000, &App3::baseCallback, this, ros::TransportHints().udp());
00352 
00353         sub = nh.subscribe("ground_truth/state", 1000, &GazeboFlocking::baseCallback, this, ros::TransportHints().udp());
00354         //ros::Duration(5).sleep();  //this is necessary, in order that the runtime platform kernel of the robot has enough time to publish it's base information.
00355 
00356         timer = nh.createTimer(ros::Duration(interval), &GazeboFlocking::publish_cmd, this);
00357     }
00358 };
00359 


gazebo_flocking
Author(s):
autogenerated on Thu Jun 6 2019 18:52:26