123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324 |
- #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 "emqx-client/mqttmsg.h"
- #include "emqx-client/paho_client.h"
- #include <unistd.h>
- #include <chrono>
- #include <random>
- #include "timedlockdata.hpp"
- // All the webots classes are defined in the "webots" namespace
- using namespace webots;
- Paho_client* client_= nullptr;
- TimedLockData<NavMessage::ToAgvCmd> g_speed;
- void SpeedChangeCallback(std::string topic,int QOS,MqttMsg& msg,void* context)
- {
- NavMessage::ToAgvCmd speed;
- msg.toProtoMessage(speed);
- g_speed.reset(speed,0.3);
- }
- 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);
- }
- void Vrtical(double velocity,double wmg,double w,double l,double& R1,double& R2,double& R3,double& R4,
- double& L1,double& L2,double& L3,double& L4) {
- if (fabs(wmg) < 0.0001) {
- R1 = R2 = R3 = R4 = 0;
- L1 = L2 = L3 = L4 = velocity;
- printf("virtical111 R1-R4:%.5f %.5f %.5f %.5f L1-L4:%.5f %.5f %.5f %.5f \n",
- R1,R2,R3,R4,L1,L2,L3,L4);
- } else {//有角速度
- double base = pow(velocity / wmg, 2) - (l * l / 4);
- //满足运动方程
- if (base >= 0.0001) {
- double BaseR = sqrt(base) - w / 2;
- if (BaseR < 0.05)
- BaseR = 0.05;
- //printf("BaseR : %f \n",BaseR);
- if (BaseR > 0) {
- if (wmg * velocity >= 0) {
- R1 = atan(l / BaseR);
- R2 = atan(l / (BaseR + w));
- L3 = BaseR * wmg;
- L4 = (BaseR + w) * wmg;
- 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) * wmg;
- L4 = -BaseR * wmg;
- R3 = 0;
- R4 = 0;
- L1 = L3 / cos(R1);
- L2 = L4 / cos(R2);
- }
- printf("virtical222 R1-R4:%.5f %.5f %.5f %.5f L1-L4:%.5f %.5f %.5f %.5f \n",
- R1,R2,R3,R4,L1,L2,L3,L4);
- }
- }
- }
- }
- void Horizontal(double velocity,double wmg,double w,double l,double& R1,double& R2,double& R3,double& R4,
- double& L1,double& L2,double& L3,double& L4)
- {
- Vrtical(velocity,wmg,w,l,R3,R1,R4,R2,L3,L1,L4,L2);
- if (fabs(wmg) < 0.0001) {
- R1 = -M_PI / 2.0;
- R2 = M_PI / 2.0;
- R3 = M_PI / 2.0;
- R4 = -M_PI / 2.0;
- L1 = -velocity;
- L2 = velocity;
- L3 = velocity;
- L4 = -velocity;
- }else{
- R1-=M_PI/2.0;
- R2+=M_PI/2.0;
- R3+=M_PI/2.0;
- R4-=M_PI/2.0;
- L1=-L1;
- L4=-L4;
- }
- }
- int main(int argc, char **argv) {
- //init mqtt
- if(false==init_mqtt("127.0.0.1",1883,"webots_main","MainPLC/speedcmd"))
- {
- 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.
- 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);
- /*RM1->setTorque(100);
- RM2->setTorque(100);
- RM3->setTorque(100);
- RM4->setTorque(100);*/
- 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.005);
- double y=gps->getValues()[0] + generae_random(generator,0,0.005);
- double theta=imu->getRollPitchYaw()[2]+generae_random(generator,0,0.1*M_PI/180.0);
- //获取gps速度,判断朝向
- double vm1=R3_l->getVelocity()*radius;
- double vm2=-R2_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;
- NavMessage::LidarOdomStatu odom;
- odom.set_x(x);
- odom.set_y(y);
- odom.set_theta(theta);
- odom.set_v(v);
- odom.set_vth(vth);
- msg.fromProtoMessage(odom);
- client_->publish("lidar_odom/main",1,msg);
- NavMessage::AgvStatu speed;
- speed.set_v(v);
- speed.set_w(vth);
- speed.set_clamp(0);
- speed.set_clamp_other(0);
- msg.fromProtoMessage(speed);
- client_->publish("MainPLC/speed",1,msg);
- }
- if(g_speed.timeout())
- {
- RM1->setPosition(0);
- RM2->setPosition(0);
- RM3->setPosition(0);
- RM4->setPosition(0);
- R1_l->setVelocity(0);
- R2_l->setVelocity(0);
- R3_l->setVelocity(0);
- R4_l->setVelocity(0);
- continue;
- }
- //变速----------------------------------
- double cmd_v=g_speed.Get().v();
- double cmd_vth=g_speed.Get().w();
- //初始值
- double R1=0,R2=0,R3=0,R4=0;
- double L1=cmd_v;
- double L2=cmd_v;
- double L3=cmd_v;
- double L4=cmd_v;
- if(g_speed.Get().t()==1) //原地旋转
- {
- printf("旋转:");
- if (fabs(cmd_vth) > 0.0001)
- Rotating(cmd_vth, w / 2.0, l / 2.0, R1, R2, R3, R4, L1, L2, L3, L4);
- }
- else if(g_speed.Get().t()==2) //横移
- {
- printf("横移:");
- if (fabs(cmd_vth) > 0.4) {
- cmd_vth = cmd_vth > 0 ? 0.4 : -0.4;
- }
- Horizontal(cmd_v,cmd_vth,l,w,R1, R2, R3, R4, L1, L2, L3, L4);
- }
- else if(g_speed.Get().t()==3){ //巡线/前进
- printf("前进:");
- if (fabs(cmd_vth) > 0.4) {
- cmd_vth = cmd_vth > 0 ? 0.4 : -0.4;
- }
- Vrtical(cmd_v,cmd_vth,w,l,R1,R2,R3,R4,L1,L2,L3,L4);
- }
- printf("Child 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,cmd_v,cmd_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;
- return 0;
- }
|