123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- #include <adc_controller/pid_controller.h>
- #include <common/constants.h>
- #include <common/car_status.h>
- #include <math.h>
- #include <iostream>
- #include <fstream>
- using namespace std;
- iv::decition::PIDController::PIDController(){
- controller_id = 0;
- controller_name="pid";
- }
- iv::decition::PIDController::~PIDController(){
- }
- /**
- * @brief getControlDecition
- * pid方式计算横向方向盘和纵向加速度
- *
- * @param now_gps_ins 实时gps信息
- * @param path 目标路径
- * @param dSpeed 决策速度
- * @param ObsDistacne 障碍物距离
- * @param ObsSpeed 障碍物速度
- * @param computeAngle 是否要计算方向盘角度
- * @param computeAcc 是否要计算纵向加速度
- * @param decition 决策信息结构体的指针
- * @return iv::decition::Decition
- */
- iv::decition::Decition iv::decition::PIDController::getControlDecition(GPS_INS now_gps_ins, std::vector<Point2D> path, float dSpeed, float obsDistacne, float obsSpeed,
- bool computeAngle, bool computeAcc, Decition *decition){
- float realSpeed= now_gps_ins.speed;
- int roadMode = now_gps_ins.roadMode;
- if(computeAngle){
- (*decition)->wheel_angle=getPidAngle( realSpeed, path,roadMode);
- }
- if(computeAcc){
- (*decition)->accelerator=getPidAcc( now_gps_ins, dSpeed, obsDistacne, obsSpeed);
- }
- return *decition;
- }
- float iv::decition::PIDController::getPidAngle(float realSpeed, std::vector<Point2D> trace, int roadMode){
- double ang = 0;
- double EPos = 0, EAng = 0;
- double KEang = 14, KEPos = 10, DEang = 0, DEPos = 0,IEpos=0,IEang=0;
- bool turning=false;
- if(roadMode==14||roadMode==15||roadMode==16||roadMode==17){
- turning=true;
- }
- double PreviewDistance;//预瞄距离
- if(ServiceCarStatus.msysparam.mvehtype=="ge3" || ServiceCarStatus.msysparam.mvehtype=="vv7"){
- realSpeed > 40 ? PreviewDistance = max(6.0, realSpeed *0.6) : PreviewDistance = max(4.0, realSpeed *0.3);
- }else if(ServiceCarStatus.msysparam.mvehtype=="hapo"){
- if(turning){
- realSpeed > 40 ? PreviewDistance = max(6.0, realSpeed *0.6) : PreviewDistance = max(4.0, realSpeed *0.3);
- }else{
- realSpeed > 40 ? PreviewDistance = max(6.0, realSpeed *0.6) : PreviewDistance = max(6.0, realSpeed *0.5);
- }
- } else{
- realSpeed > 40 ? PreviewDistance = max(6.0, realSpeed *0.6) : PreviewDistance = max(6.0, realSpeed *0.5);
- }
- // if(ServiceCarStatus.msysparam.mvehtype=="bus"){
- // KEang = 14, KEPos = 7, DEang = 0, DEPos = 0,IEpos=0,IEang=0;
- // realSpeed > 40 ? PreviewDistance = max(6.0, realSpeed *0.6) : PreviewDistance = max(6.0, realSpeed *0.5);
- // }
- // if(realSpeed <15){
- // PreviewDistance = max(4.0, realSpeed *0.4) ;
- // }
- // if(realSpeed <10){
- // PreviewDistance = max(3.0, realSpeed *0.3) ;
- // }
- double sumdis = 0;
- int gpsIndex = 0;
- std::vector<Point2D> farTrace;
- int nsize = trace.size();
- for (int i = 1; i < nsize-1; i++)
- {
- sumdis += GetDistance(trace[i - 1], trace[i]);
- if (sumdis > PreviewDistance)
- {
- gpsIndex = i;
- break;
- }
- }
- EPos = trace[gpsIndex].x;
- for (unsigned int i = max(0, gpsIndex - 3); i < min((size_t)(gpsIndex + 3), trace.size()); i++) {
- farTrace.push_back(trace[gpsIndex]);
- }
- if (farTrace.size() == 0) {
- EAng = 0;
- }
- else {
- EAng = getAveDef(farTrace);
- }
- if(abs(realSpeed)<3){
- eAngSum=0;
- ePosSum=0;
- }else{
- eAngSum=eAngSum*0.8+EAng;
- ePosSum=ePosSum*0.8+EPos;
- }
- ang = KEang * EAng + KEPos * EPos + DEang * (EAng - lastEA) + DEPos * (EPos - lastEP)
- +IEang*eAngSum + IEpos*ePosSum;
- lastEA = EAng;
- lastEP = EPos;
- // if (ang > angleLimit) {
- // ang = angleLimit;
- // }
- // else if (ang < -angleLimit) {
- // ang = -angleLimit;
- // }
- if (lastAng >-3000&&lastAng<3000) {
- ang = 0.2 * lastAng + 0.8 * ang;
- }
- if(ang >-3000&&ang<3000){
- lastAng = ang;
- }else{
- ang=lastAng;
- }
- return ang;
- }
- float iv::decition::PIDController::getAveDef(std::vector<Point2D> farTrace){
- double sum_x = 0;
- double sum_y = 0;
- for (int i = 0; i < min(5, (int)farTrace.size()); i++)
- {
- sum_x += farTrace[i].x;
- sum_y += abs(farTrace[i].y);
- }
- double average_y = sum_y / min(5, (int)farTrace.size());
- double average_x = sum_x / min(5, (int)farTrace.size());
- return atan(average_x / average_y) / M_PI * 180;
- }
- float iv::decition::PIDController::getPidAcc (GPS_INS gpsIns,float dSpeed, float obsDistance, float obsSpeed){
- std::cout << "\n计算用obs速度:%f\n" << obsSpeed << std::endl;
- std::cout << "\n计算用obs距离:%f\n" << obsDistance << std::endl;
- if(ServiceCarStatus.msysparam.mvehtype=="hapo")
- {
- static int obs_line=0;
- if(obsDistance<6 && obsDistance>0){
- dSpeed=0;
- obs_line=1;
- }
- if(obs_line==1)
- {
- if(obsDistance<8 && obsDistance>0){
- dSpeed=0;
- }else{
- obs_line=0;
- }
- }
- }else if(obsDistance<10 && obsDistance>0){
- dSpeed=0;
- }
- float dSecSpeed = dSpeed / 3.6;
- float realSpeed=gpsIns.speed;
- float secSpeed =realSpeed/3.6;
- double vt = dSecSpeed;
- double vs = secSpeed;
- if (abs(vs) < 0.05) vs = 0;
- if (abs(obsSpeed) < 0.05) obsSpeed = 0;
- double vl = vs + obsSpeed;
- double vh = vs;
- double dmax = 150;
- //车距滤波
- if (obsDistance < 0||obsDistance>100) {
- obsDistance = 500;
- obsSpeed=0;
- }
- if (obsDistance > 150) vl = 25; //25m/s
- //TTC计算
- double ds = 0.2566 * vl * vl + 5;
- double ttcr = (vh - vl) / obsDistance;
- double ttc = 15;
- if (15 * (vh - vl) > obsDistance)
- ttc = obsDistance / (vh - vl);
- ServiceCarStatus.mfttc = ttc;
- if (obsDistance <= dmax)
- {
- if (ttc > 10)
- {
- if (obsDistance > ds + 5)
- {
- double dds = min(30.0, obsDistance - (ds + 5));
- vt = vt * dds / 30 + vl * (1 - dds / 30);
- }
- else
- {
- vt = min(vt, vl);
- }
- }
- else
- {
- vt = min(vt, vl);
- }
- }else{
- vt=dSecSpeed;
- }
- vt=min((float)vt,dSecSpeed);
- std::cout << "\nvt:%f\n" << vt << std::endl;
- //计算加速度
- float u =computeU(obsDistance,ds,vs,vt,vh,vl,ttc,ttcr);
- //u 限值
- u=limiteU(u,ttc);
- lastVt = vt;
- lastU = u;
- float acc=0-u;
- return acc;
- }
- float iv::decition::PIDController::computeU(float obsDistance, float ds,float vs,float vt,float vh,float vl,float ttc,float ttcr){
- double Id = 0;
- double ed = ds - obsDistance;
- if (obsDistance > 150) ed = 0;
- double ev = vs - vt;
- double u = 0;
- if (ttc>10)
- {
- double kp = 0.5; //double kp = 0.5;
- double kd = 0.5; //kd = 0.5
- // double k11 = 0.025;
- // double k12 = 0.000125;
- double dev = (ev - lastEv) / 0.1;
- Iv = 0.925 * Iv + ev;
- Id = 0.85 * Id + ed;
- if (abs(vh) < 2.0&& abs(vl) < 2.0)
- {
- Iv = 0.0; Id = 0.0;
- }
- //u = kp * ev + kd * dev + k11 * Iv + k12 * Id;
- u = kp * ev + kd * dev;
- }
- else if (ttc < 1.6 || (ttc <= 10 && obsDistance <= 0.75 * ds))
- {
- //AEB控制
- Id = 0; Iv = 0;
- u = 0;
- if (ttc < 0.8) u = 7;
- else if (ttc < 1.6) u = 3 + 5 * (1.6 - ttc);
- else
- {
- u = (10 - ttc) * (10 - ttc) / 23.52;
- }
- }
- else
- {
- //制动控制
- Id = 0; Iv = 0;
- if (obsDistance > 1.25 * ds)
- {
- double rev_ed = 1 / ed;
- u = -0.5 * obsDistance * obsDistance * rev_ed * ttcr * ttcr;
- }
- else
- {
- if (abs(vl) > 2.0)
- u = 0;
- else
- u = max(lastU, 1.0f);
- }
- }
- if (abs(vl) < 1.0 && abs(vh) < 1.0
- && obsDistance < 2 * ds)
- {
- u = 0.5;
- }
- lastEv = ev;
- return u;
- }
- float iv::decition::PIDController::limiteU(float u,float ttc){
- if(ttc<3 && u<-0.2){
- u=-0.2;
- }
- else
- {
- if (u < -1.5) u = -1.5;
- }
- if (u >= 0 && lastU <= 0)
- {
- if (u > 0.5) u = 0.5;
- }
- else if (u >= 0 && lastU >= 0)
- {
- if (u > lastU + 0.5) u = lastU + 0.5;
- }
- else if (u <= 0 && lastU >= 0)
- {
- if (u < -0.04) u = -0.04;
- }
- else if (u <= 0 && lastU <= 0)
- {
- if (u < lastU - 0.04) u = lastU - 0.04;
- }
- return u;
- }
|