123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- #include <webots/Robot.hpp>
- #include <webots/Motor.hpp>
- #include <webots/PositionSensor.hpp>
- #include <webots/GPS.hpp>
- #include <webots/Gyro.hpp>
- #include <webots/InertialUnit.hpp>
- #include <webots/Supervisor.hpp>
- #include "emqx-client/mqttmsg.h"
- #include "emqx-client/paho_client.h"
- #include <unistd.h>
- #include <chrono>
- #include <random>
- // All the webots classes are defined in the "webots" namespace
- using namespace webots;
- Paho_client* client_= nullptr;
- double g_v=0,g_vth=0;
- void SpeedChangeCallback(std::string topic,int QOS,MqttMsg& msg,void* context)
- {
- msg.toSpeed(g_v,g_vth);
- }
- double generae_random(std::default_random_engine& generator,double mean,double sigma)
- {
- std::normal_distribution<double> distribution(mean, sigma);
- return distribution(generator);
- }
- bool init_mqtt(std::string ip,int port,std::string nodeId,std::string subtopic)
- {
- if(client_!= nullptr)
- {
- client_->disconnect();
- delete client_;
- }
- client_=new Paho_client(nodeId);
- bool ret= client_->connect(ip,port);
- if(ret)
- {
- while(!client_->isconnected()) usleep(1000);
- client_->subcribe(subtopic,1,SpeedChangeCallback, nullptr);
- }
- return ret;
- }
- void Rotating(double wmg,double w,double l,
- double& R1,double& R2,double& R3,double& R4,
- double& L1,double& L2,double& L3,double& L4)
- {
- double theta=atan(l/w);
- R1=(-theta);
- R2=(theta);
- R3=(theta);
- R4=(-theta);
- double velocity=wmg*sqrt(w*w+l*l);
- L1=(-velocity);
- L2=(velocity);
- L3=(-velocity);
- L4=(velocity);
- }
- int main(int argc, char **argv) {
- //init mqtt
- if(false==init_mqtt("127.0.0.1",1883,"webots-AGV","AgvCmd/cmd1"))
- {
- printf(" Init mqtt failed...\n");
- return -1;
- }
- //随机数
- unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
- std::default_random_engine generator(seed);
- // create the Robot instance.
- webots::Supervisor* super=new webots::Supervisor();
- Node* root=super->getRoot();
- Node* worldInfo=root->getField("children")->getMFNode(0);
- Robot *robot = new Robot();
- // get the time step of the current world.
- int timeStep = (int)robot->getBasicTimeStep();
- webots::Motor* RM1=robot->getMotor("R1_motor");
- webots::Motor* RM2=robot->getMotor("R2_motor");
- webots::Motor* RM3=robot->getMotor("R3_motor");
- webots::Motor* RM4=robot->getMotor("R4_motor");
- //R1->getPositionSensor()->enable(timeStep);
- webots::Motor* R1_l=robot->getMotor("L1_motor");
- webots::Motor* R2_l=robot->getMotor("L2_motor");
- webots::Motor* R3_l=robot->getMotor("L3_motor");
- webots::Motor* R4_l=robot->getMotor("L4_motor");
- RM1->setPosition(0);
- RM2->setPosition(0);
- RM3->setPosition(0);
- RM4->setPosition(0);
- R1_l->setPosition(INFINITY);
- R2_l->setPosition(INFINITY);
- R3_l->setPosition(INFINITY);
- R4_l->setPosition(INFINITY);
- R1_l->setVelocity(0.0);
- R2_l->setVelocity(0.0);
- R3_l->setVelocity(0.0);
- R4_l->setVelocity(0.0);
- webots::GPS* gps=robot->getGPS("gps");
- webots::InertialUnit* imu=robot->getInertialUnit("imu");
- webots::Gyro* gyr=robot->getGyro("gyro");
- gyr->enable(timeStep);
- gps->enable(timeStep);
- imu->enable(timeStep);
- double w=2.5;
- double l=1.3;
- double radius=0.1915;
- double K=1.0/radius;
- auto last=std::chrono::steady_clock::now();
- while (robot->step(timeStep) != -1) {
- auto now=std::chrono::steady_clock::now();
- auto duration = std::chrono::duration_cast<std::chrono::microseconds>(now - last);
- double time = double(duration.count()) * std::chrono::microseconds::period::num /
- std::chrono::microseconds::period::den;
- ////发布:
- //增加高斯分布
- double x=gps->getValues()[2] + generae_random(generator,0,0.001);
- double y=gps->getValues()[0] + generae_random(generator,0,0.001);
- double theta=imu->getRollPitchYaw()[2]+generae_random(generator,0,0.3*M_PI/180.0);
- //获取gps速度,判断朝向
- double vm1=R3_l->getVelocity()*radius;
- double vm2=-R4_l->getVelocity()*radius;
- double v=gps->getSpeed();
- if(vm1+vm2<0.0)
- v=-v;
- //陀螺仪角速度
- double vth=gyr->getValues()[1];
- if(time>0.2)
- {
- printf(" publish delay................ time:%f -------------------------------------\n",time);
- }
- /*printf("dt:%f x y:%f %f, yaw:%f velocity:%f vth:%f %f %f\n",time,
- x,y,theta,
- v,gyr->getValues()[0],gyr->getValues()[1],gyr->getValues()[2]);*/
- last=now;
- if(client_)
- {
- MqttMsg msg;
- msg.fromStatu(x,y,theta,
- v,vth);
- client_->publish("AgvStatu/robot1",1,msg);
- }
- //变速,角速度封顶
- if(fabs(g_vth)>0.4)
- {
- g_vth=g_vth>0?0.4:-0.4;
- }
- //初始值
- double R1=0,R2=0,R3=0,R4=0;
- double L1=g_v;
- double L2=g_v;
- double L3=g_v;
- double L4=g_v;
- double theta1=0;
- double theta2=0;
- //无角速度,直线
- if(fabs(g_vth)<0.0001)
- {
- R1=R2=R3=R4=0;
- L1=L2=L3=L4=g_v;
- }
- else //有角速度
- {
- if (fabs(g_v) < 0.00001)
- {
- //原地旋转
- if (fabs(g_vth) > 0.0001)
- Rotating(g_vth, w / 2.0, l / 2.0, R1, R2, R3, R4, L1, L2, L3, L4);
- }
- else
- {
- //默认原地旋转
- Rotating(g_vth, w / 2.0, l / 2.0, R1, R2, R3, R4, L1, L2, L3, L4);
- double base = pow(g_v / g_vth,2)-(l*l/4);
- //满足运动方程
- if(base>=0.1)
- {
- double BaseR=sqrt(base)-w/2;
- if(BaseR>0)
- {
- if(g_vth*g_v>=0)
- {
- R1=atan(l/BaseR);
- R2=atan(l/(BaseR+w));
- L3=BaseR*g_vth;
- L4=(BaseR+w)*g_vth;
- R3=0;
- R4=0;
- L1=L3/cos(R1);
- L2=L4/cos(R2);
- }
- else
- {
- R1=-atan(l/(BaseR+w));
- R2=-atan(l/BaseR);
- L3=-(BaseR+w)*g_vth;
- L4=-BaseR*g_vth;
- R3=0;
- R4=0;
- L1=L3/cos(R1);
- L2=L4/cos(R2);
- }
- }
- }
- }
- }
- //printf(" R1-R4:%.5f %.5f %.5f %.5f L1-L4:%.5f %.5f %.5f %.5f V:%.5f Vth:%.5f\n",
- // R1,R2,R3,R4,L1,L2,L3,L4,v,vth);
- RM1->setPosition(R1);
- RM2->setPosition(R2);
- RM3->setPosition(R3);
- RM4->setPosition(R4);
- R1_l->setVelocity(L1*K);
- R2_l->setVelocity(-L2*K);
- R3_l->setVelocity(L3*K);
- R4_l->setVelocity(-L4*K);
- };
- // Enter here exit cleanup code.
- delete robot;
- delete super;
- return 0;
- }
|