gazebo_flocking.cpp
Go to the documentation of this file.
1 
24 #include "hector_uav_msgs/EnableMotors.h"
25 #include <tf/tf.h>
26 #include <cmath>
27 
28 double my_theta = 0;
29 double PI =acos(-1);
30 #define EPSILON 0.1
31 #define A 5
32 #define B 5
33 const double C = abs(A-B) / sqrt(4*A*B);
34 #define H 0.2
35 #define D 7
36 #define R 9
37 #define C1 0.3
38 #define C2 0.6
39 #define speedlimit 2
40 
41 double pm1=0.3,pm2=1,pm3=0.3;
42 
43 using namespace std;
44 
46 {
47 public:
48  double _px,_py,_vx,_vy;
49  pair<double,double> _position,_velocity;
50  int _r_id;
51  double mypm_g;
52  NeighborHandle(int r_id, float x, float y, float vx, float vy)
53  {
54 
55  _px=x;
56  _py=y;
57  _vx=vx;
58  _vy=vy;
59  _position=pair<double,double>(x,y);
60  _velocity=pair<double,double>(vx,vy);
61  _r_id = r_id;
62  mypm_g=1;
63  }
64 };
65 
66 static list<NeighborHandle*> neighbor_list;
67 pair<double,double> my_position=pair<double,double>(0,0);
68 pair<double,double> my_velocity=pair<double,double>(0,0);
69 
70 pair<double,double> get_vector(pair<double,double> start,pair<double,double> end)
71 {
72  pair<double,double> re=pair<double,double>(0,0);
73  re.first=end.first-start.first;
74  re.second=end.second-start.second;
75  return re;
76 }
77 
78 double segma_norm(pair<double,double> v)
79 {
80  double re = EPSILON*(v.first*v.first+v.second*v.second);
81  re = sqrt(1+re)-1;
82  re /= EPSILON;
83  return re;
84 }
85 
86 double R_alpha = segma_norm(pair<double,double>(R,0));
87 double D_alpha = segma_norm(pair<double,double>(D,0));
88 
89 pair<double,double> segma_epsilon(pair<double,double> v)
90 {
91  pair<double,double> re = pair<double,double>(0,0);
92  double scale = 1+EPSILON*(v.first*v.first+v.second*v.second);
93  scale = sqrt(scale);
94  re.first = v.first / scale;
95  re.second = v.second / scale;
96  return re;
97 }
98 
99 double segma_1(double z)
100 {
101  return z / sqrt(1+z*z);
102 }
103 
104 double phi(double z)
105 {
106  return 0.5*((A+B)*segma_1(z+C)+A-B);
107 }
108 
109 double rho(double z)
110 {
111  if(z<H)
112  return 1;
113  if(z>1)
114  return 0;
115  return 0.5*(1+cos(PI*(z-H)/(1-H)));
116 }
117 
118 double phi_alpha(double z)
119 {
120  return rho(z/R_alpha)*phi(z-D_alpha);
121 }
122 
123 pair<double,double> f_g()
124 {
125  pair<double,double> re = pair<double,double>(0,0);
126  for(list<NeighborHandle*>::iterator i=neighbor_list.begin();i!=neighbor_list.end();i++)
127  {
128  pair<double,double> q_ij = get_vector(my_position,(*i)->_position);
129  pair<double,double> n_ij = segma_epsilon(q_ij);
130  re.first += phi_alpha(segma_norm(q_ij))*n_ij.first*(*i)->mypm_g;
131  re.second += phi_alpha(segma_norm(q_ij))*n_ij.second*(*i)->mypm_g;
132  }
133  return re;
134 }
135 
136 double a_ij(pair<double,double> j_p)
137 {
138  return rho(segma_norm(get_vector(my_position,j_p)) / R_alpha);
139 }
140 
141 pair<double,double> f_d()
142 {
143  pair<double,double> re = pair<double,double>(0,0);
144  for(list<NeighborHandle*>::iterator i=neighbor_list.begin();i!=neighbor_list.end();i++)
145  {
146  pair<double,double> p_ij = get_vector(my_velocity,(*i)->_velocity);
147  re.first += a_ij((*i)->_position) * p_ij.first;
148  re.second += a_ij((*i)->_position) * p_ij.second;
149  }
150  return re;
151 }
152 
153 double interval = 0.1;
154 pair<double,double> p_r = pair<double,double>(3,0);
155 pair<double,double> q_r = pair<double,double>(-40,-40);
156 pair<double,double> f_r()
157 {
158  pair<double,double> re = pair<double,double>(0,0);
159 
160 
161 
162  re.first = -C1*get_vector(q_r,my_position).first - C2*get_vector(p_r,my_velocity).first;
163  re.second = -C1*get_vector(q_r,my_position).second - C2*get_vector(p_r,my_velocity).second;
164  return re;
165 }
166 
167 // Register the application
169 
170 namespace gazebo_flocking{
171 
172  GazeboFlocking::GazeboFlocking() {}
173 
174  GazeboFlocking::~GazeboFlocking() {}
175 
176  void GazeboFlocking::stop() {}
177 
178  void GazeboFlocking::init()
179  {
180  //set parameters
181  hz = 10;
182  interval = 1.0/hz;
183  }
184 
186 
187  bool test_location(float a, float b, float x, float y)
188  {
189  float s = sqrt((a-x)*(a-x)+(b-y)*(b-y));
190  if(s <= 2) {
191  return true;
192  }
193  return false;
194  }
195 
196  void GazeboFlocking::publish_cmd(const ros::TimerEvent&)
197  {
198  static double base_angle = 0;
199  vel_loop_count++;
200  int time_count = vel_loop_count;
201  int hz = 10;
202  double baseomega = 0;
203  double basespeed = 3;
204  /*
205  //if(q_r.first == 40 && q_r.second == -40)
206  if(vel_loop_count==230)
207  //if(test_location(q_r.first, q_r.second, 40, -40))
208  {
209  p_r.first = 0;
210  p_r.second = 3;
211  }
212 
213  //if(q_r.first == 40 && q_r.second == 40)
214  if(vel_loop_count==440)
215  //if(test_location(q_r.first, q_r.second, 40, 40))
216  {
217  p_r.first = -3;
218  p_r.second = 0;
219  }
220 
221  //if(q_r.first == -40 && q_r.second == 40)
222  if(vel_loop_count==500)
223  if(test_location(q_r.first, q_r.second, -40, 40))
224  {
225  p_r.first = 0;
226  p_r.second = -3;
227  }
228  if(vel_loop_count==620)
229  if(test_location(q_r.first, q_r.second, -40, 40))
230  {
231  p_r.first = 3;
232  p_r.second = 0;
233  } */
234 
235  if(time_count>=23*hz && time_count<=23*hz+10*hz)
236  baseomega = PI/2.0/10;//PI/30;
237  else if(time_count >= 49.5*hz && time_count <= 49.5*hz+10*hz)
238  baseomega = PI/2.0/10;
239  else if (time_count >= 76*hz && time_count<=76*hz+21*hz)
240  baseomega = (PI-0.15)/2.0/10;
241  else if (time_count >=103*hz)
242  {
243  basespeed=0;
244  //else
245  baseomega =0;
246  }
247 
248  base_angle += baseomega /hz;
249  p_r.first = basespeed * cos(base_angle);
250  p_r.second = basespeed * sin(base_angle);
251  q_r.first += p_r.first * interval;
252  q_r.second += p_r.second * interval;
253 
254  geometry_msgs:: Twist msg;
256 
257  typename std::map<int, micros_swarm::NeighborBase>::iterator it;
258  for(it=n.data().begin();it!=n.data().end();it++)
259  {
260  NeighborHandle* nh=new NeighborHandle(it->first, it->second.x, it->second.y, it->second.vx, it->second.vy);
261  neighbor_list.push_back(nh);
262  }
263 
264  micros_swarm::Base nl = get_base();
265 
266  my_position=pair<double,double>(nl.x, nl.y);
267  my_velocity=pair<double,double>(nl.vx, nl.vy);
268 
269  msg.linear.x += (f_g().first*pm1+f_d().first*pm2+f_r().first*pm3)/hz;
270  msg.linear.y += (f_g().second*pm1+f_d().second*pm2+f_r().second*pm3)/hz;
271  //cout<<f_g().second<<' '<<f_d().second<<' '<<msg.linear.y<<endl;
272 
273  if (msg.linear.x >speedlimit)
274  msg.linear.x=speedlimit;
275  if (msg.linear.x <-speedlimit)
276  msg.linear.x=-speedlimit;
277  if (msg.linear.y >speedlimit)
278  msg.linear.y=speedlimit;
279  if (msg.linear.y <-speedlimit)
280  msg.linear.y=-speedlimit;
281 
282  msg.linear.x +=p_r.first;
283  msg.linear.y +=p_r.second;
284 
285 
286  //theta handle
287  geometry_msgs::Twist sendmsg;
288  sendmsg.linear.x =msg.linear.x;
289  sendmsg.linear.y = msg.linear.y;
290  if(sendmsg.linear.x==0 && sendmsg.linear.y==0)
291  pub.publish(sendmsg);
292  else{
293  double fi = PI/2;
294  if(sendmsg.linear.x!=0)
295  {
296  fi=atan(sendmsg.linear.y/sendmsg.linear.x);
297  if(sendmsg.linear.x<0&&sendmsg.linear.y>=0)
298  fi+=PI;
299  else if (sendmsg.linear.x<0 && sendmsg.linear.y<0)
300  fi-=PI;
301  }
302  else if (sendmsg.linear.y<0)
303  fi= -PI/2;
304  double v_scale = sqrt(sendmsg.linear.x*sendmsg.linear.x+sendmsg.linear.y*sendmsg.linear.y);
305  sendmsg.linear.x = v_scale*cos(fi-my_theta);
306  sendmsg.linear.y = v_scale *sin(fi-my_theta);
307  pub.publish(sendmsg);}
308  //pub.publish(msg);
309 
310  neighbor_list.clear();
311  }
312 
313  void GazeboFlocking::baseCallback(const nav_msgs::Odometry& lmsg)
314  {
315  float x = lmsg.pose.pose.position.x;
316  float y = lmsg.pose.pose.position.y;
317 
318  float vx = lmsg.twist.twist.linear.x;
319  float vy = lmsg.twist.twist.linear.y;
320  my_theta = tf::getYaw(lmsg.pose.pose.orientation);
321  micros_swarm::Base l(x, y, 0, vx, vy, 0, 1);
322  set_base(l);
323  }
324 
325  void GazeboFlocking::start()
326  {
327  init();
328 
329  ros::NodeHandle nh;
330  ros::ServiceClient client = nh.serviceClient<hector_uav_msgs::EnableMotors>("enable_motors");
331  hector_uav_msgs::EnableMotors srv;
332  srv.request.enable = true;
333  if (client.call(srv))
334  {
335  ;
336  }
337  else
338  {
339  ROS_ERROR("Failed to call service enable_motors");
340  }
341 
342  set_dis(12);
343  pub = nh.advertise<geometry_msgs::Twist>("cmd_vel", 1000);
344  ros::Rate loop_rate(10);
345  for(int i = 0; i < 7*10; i++) {
346  geometry_msgs:: Twist upmsg;
347  upmsg.linear.z = 1;
348  pub.publish(upmsg);
349  loop_rate.sleep();
350  }
351  //sub = nh.subscribe("base_pose_ground_truth", 1000, &App3::baseCallback, this, ros::TransportHints().udp());
352 
353  sub = nh.subscribe("ground_truth/state", 1000, &GazeboFlocking::baseCallback, this, ros::TransportHints().udp());
354  //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.
355 
356  timer = nh.createTimer(ros::Duration(interval), &GazeboFlocking::publish_cmd, this);
357  }
358 };
359 
#define R
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
double phi_alpha(double z)
double PI
double pm3
double a_ij(pair< double, double > j_p)
pair< double, double > get_vector(pair< double, double > start, pair< double, double > end)
const double C
double interval
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
static double getYaw(const Quaternion &bt_q)
XmlRpcServer s
#define D
bool call(MReq &req, MRes &res)
pair< double, double > my_velocity
TFSIMD_FORCE_INLINE const tfScalar & y() const
pair< double, double > q_r
#define EPSILON
pair< double, double > p_r
double segma_1(double z)
double pm1
double D_alpha
pair< double, double > segma_epsilon(pair< double, double > v)
pair< double, double > f_r()
double rho(double z)
pair< double, double > my_position
#define A
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
std::map< int, Type > & data()
TFSIMD_FORCE_INLINE const tfScalar & x() const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
pair< double, double > f_d()
pair< double, double > _velocity
double phi(double z)
#define H
NeighborHandle(int r_id, float x, float y, float vx, float vy)
pair< double, double > f_g()
static list< NeighborHandle * > neighbor_list
#define C1
double segma_norm(pair< double, double > v)
#define B
double R_alpha
double pm2
bool test_location(float a, float b, float x, float y)
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
double my_theta
#define speedlimit
#define ROS_ERROR(...)
#define C2


gazebo_flocking
Author(s):
autogenerated on Mon Jun 10 2019 14:02:17