Agv_surper_controller.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. #include <webots/Robot.hpp>
  2. #include <webots/Motor.hpp>
  3. #include <webots/PositionSensor.hpp>
  4. #include <webots/GPS.hpp>
  5. #include <webots/Gyro.hpp>
  6. #include <webots/InertialUnit.hpp>
  7. #include <webots/Supervisor.hpp>
  8. #include "emqx-client/mqttmsg.h"
  9. #include "emqx-client/paho_client.h"
  10. #include <unistd.h>
  11. #include <chrono>
  12. #include <random>
  13. // All the webots classes are defined in the "webots" namespace
  14. using namespace webots;
  15. Paho_client* client_= nullptr;
  16. double g_v=0,g_vth=0;
  17. void SpeedChangeCallback(std::string topic,int QOS,MqttMsg& msg,void* context)
  18. {
  19. msg.toSpeed(g_v,g_vth);
  20. }
  21. double generae_random(std::default_random_engine& generator,double mean,double sigma)
  22. {
  23. std::normal_distribution<double> distribution(mean, sigma);
  24. return distribution(generator);
  25. }
  26. bool init_mqtt(std::string ip,int port,std::string nodeId,std::string subtopic)
  27. {
  28. if(client_!= nullptr)
  29. {
  30. client_->disconnect();
  31. delete client_;
  32. }
  33. client_=new Paho_client(nodeId);
  34. bool ret= client_->connect(ip,port);
  35. if(ret)
  36. {
  37. while(!client_->isconnected()) usleep(1000);
  38. client_->subcribe(subtopic,1,SpeedChangeCallback, nullptr);
  39. }
  40. return ret;
  41. }
  42. void Rotating(double wmg,double w,double l,
  43. double& R1,double& R2,double& R3,double& R4,
  44. double& L1,double& L2,double& L3,double& L4)
  45. {
  46. double theta=atan(l/w);
  47. R1=(-theta);
  48. R2=(theta);
  49. R3=(theta);
  50. R4=(-theta);
  51. double velocity=wmg*sqrt(w*w+l*l);
  52. L1=(-velocity);
  53. L2=(velocity);
  54. L3=(-velocity);
  55. L4=(velocity);
  56. }
  57. int main(int argc, char **argv) {
  58. //init mqtt
  59. if(false==init_mqtt("127.0.0.1",1883,"webots-AGV","AgvCmd/cmd1"))
  60. {
  61. printf(" Init mqtt failed...\n");
  62. return -1;
  63. }
  64. //随机数
  65. unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
  66. std::default_random_engine generator(seed);
  67. // create the Robot instance.
  68. webots::Supervisor* super=new webots::Supervisor();
  69. Node* root=super->getRoot();
  70. Node* worldInfo=root->getField("children")->getMFNode(0);
  71. Robot *robot = new Robot();
  72. // get the time step of the current world.
  73. int timeStep = (int)robot->getBasicTimeStep();
  74. webots::Motor* RM1=robot->getMotor("R1_motor");
  75. webots::Motor* RM2=robot->getMotor("R2_motor");
  76. webots::Motor* RM3=robot->getMotor("R3_motor");
  77. webots::Motor* RM4=robot->getMotor("R4_motor");
  78. //R1->getPositionSensor()->enable(timeStep);
  79. webots::Motor* R1_l=robot->getMotor("L1_motor");
  80. webots::Motor* R2_l=robot->getMotor("L2_motor");
  81. webots::Motor* R3_l=robot->getMotor("L3_motor");
  82. webots::Motor* R4_l=robot->getMotor("L4_motor");
  83. RM1->setPosition(0);
  84. RM2->setPosition(0);
  85. RM3->setPosition(0);
  86. RM4->setPosition(0);
  87. R1_l->setPosition(INFINITY);
  88. R2_l->setPosition(INFINITY);
  89. R3_l->setPosition(INFINITY);
  90. R4_l->setPosition(INFINITY);
  91. R1_l->setVelocity(0.0);
  92. R2_l->setVelocity(0.0);
  93. R3_l->setVelocity(0.0);
  94. R4_l->setVelocity(0.0);
  95. webots::GPS* gps=robot->getGPS("gps");
  96. webots::InertialUnit* imu=robot->getInertialUnit("imu");
  97. webots::Gyro* gyr=robot->getGyro("gyro");
  98. gyr->enable(timeStep);
  99. gps->enable(timeStep);
  100. imu->enable(timeStep);
  101. double w=2.5;
  102. double l=1.3;
  103. double radius=0.1915;
  104. double K=1.0/radius;
  105. auto last=std::chrono::steady_clock::now();
  106. while (robot->step(timeStep) != -1) {
  107. auto now=std::chrono::steady_clock::now();
  108. auto duration = std::chrono::duration_cast<std::chrono::microseconds>(now - last);
  109. double time = double(duration.count()) * std::chrono::microseconds::period::num /
  110. std::chrono::microseconds::period::den;
  111. ////发布:
  112. //增加高斯分布
  113. double x=gps->getValues()[2] + generae_random(generator,0,0.001);
  114. double y=gps->getValues()[0] + generae_random(generator,0,0.001);
  115. double theta=imu->getRollPitchYaw()[2]+generae_random(generator,0,0.3*M_PI/180.0);
  116. //获取gps速度,判断朝向
  117. double vm1=R3_l->getVelocity()*radius;
  118. double vm2=-R4_l->getVelocity()*radius;
  119. double v=gps->getSpeed();
  120. if(vm1+vm2<0.0)
  121. v=-v;
  122. //陀螺仪角速度
  123. double vth=gyr->getValues()[1];
  124. if(time>0.2)
  125. {
  126. printf(" publish delay................ time:%f -------------------------------------\n",time);
  127. }
  128. /*printf("dt:%f x y:%f %f, yaw:%f velocity:%f vth:%f %f %f\n",time,
  129. x,y,theta,
  130. v,gyr->getValues()[0],gyr->getValues()[1],gyr->getValues()[2]);*/
  131. last=now;
  132. if(client_)
  133. {
  134. MqttMsg msg;
  135. msg.fromStatu(x,y,theta,
  136. v,vth);
  137. client_->publish("AgvStatu/robot1",1,msg);
  138. }
  139. //变速,角速度封顶
  140. if(fabs(g_vth)>0.4)
  141. {
  142. g_vth=g_vth>0?0.4:-0.4;
  143. }
  144. //初始值
  145. double R1=0,R2=0,R3=0,R4=0;
  146. double L1=g_v;
  147. double L2=g_v;
  148. double L3=g_v;
  149. double L4=g_v;
  150. double theta1=0;
  151. double theta2=0;
  152. //无角速度,直线
  153. if(fabs(g_vth)<0.0001)
  154. {
  155. R1=R2=R3=R4=0;
  156. L1=L2=L3=L4=g_v;
  157. }
  158. else //有角速度
  159. {
  160. if (fabs(g_v) < 0.00001)
  161. {
  162. //原地旋转
  163. if (fabs(g_vth) > 0.0001)
  164. Rotating(g_vth, w / 2.0, l / 2.0, R1, R2, R3, R4, L1, L2, L3, L4);
  165. }
  166. else
  167. {
  168. //默认原地旋转
  169. Rotating(g_vth, w / 2.0, l / 2.0, R1, R2, R3, R4, L1, L2, L3, L4);
  170. double base = pow(g_v / g_vth,2)-(l*l/4);
  171. //满足运动方程
  172. if(base>=0.1)
  173. {
  174. double BaseR=sqrt(base)-w/2;
  175. if(BaseR>0)
  176. {
  177. if(g_vth*g_v>=0)
  178. {
  179. R1=atan(l/BaseR);
  180. R2=atan(l/(BaseR+w));
  181. L3=BaseR*g_vth;
  182. L4=(BaseR+w)*g_vth;
  183. R3=0;
  184. R4=0;
  185. L1=L3/cos(R1);
  186. L2=L4/cos(R2);
  187. }
  188. else
  189. {
  190. R1=-atan(l/(BaseR+w));
  191. R2=-atan(l/BaseR);
  192. L3=-(BaseR+w)*g_vth;
  193. L4=-BaseR*g_vth;
  194. R3=0;
  195. R4=0;
  196. L1=L3/cos(R1);
  197. L2=L4/cos(R2);
  198. }
  199. }
  200. }
  201. }
  202. }
  203. //printf(" R1-R4:%.5f %.5f %.5f %.5f L1-L4:%.5f %.5f %.5f %.5f V:%.5f Vth:%.5f\n",
  204. // R1,R2,R3,R4,L1,L2,L3,L4,v,vth);
  205. RM1->setPosition(R1);
  206. RM2->setPosition(R2);
  207. RM3->setPosition(R3);
  208. RM4->setPosition(R4);
  209. R1_l->setVelocity(L1*K);
  210. R2_l->setVelocity(-L2*K);
  211. R3_l->setVelocity(L3*K);
  212. R4_l->setVelocity(-L4*K);
  213. };
  214. // Enter here exit cleanup code.
  215. delete robot;
  216. delete super;
  217. return 0;
  218. }