Kobayashi Akihiro / ActiveCaster

Dependents:   ActiveCaster_ ActiveCaster_2

Committer:
e5119053f6
Date:
Fri Jan 28 15:43:18 2022 +0000
Revision:
2:f206311600ee
Parent:
0:5e4f1e288e2a
DDSS

Who changed what in which revision?

UserRevisionLine numberNew contents of line
e5119053f6 0:5e4f1e288e2a 1 //-----------------------------------------
e5119053f6 0:5e4f1e288e2a 2 // 軌道追従や位置のPID制御を行うためのクラス
e5119053f6 0:5e4f1e288e2a 3 // 作成:2019/05/15 by Yuki Ueno
e5119053f6 0:5e4f1e288e2a 4 // 編集:Miki Nakaone
e5119053f6 0:5e4f1e288e2a 5 //-----------------------------------------
e5119053f6 0:5e4f1e288e2a 6
e5119053f6 0:5e4f1e288e2a 7 #include "PathTracking.h"
e5119053f6 0:5e4f1e288e2a 8
e5119053f6 0:5e4f1e288e2a 9 extern coords gPosi;
e5119053f6 0:5e4f1e288e2a 10
e5119053f6 0:5e4f1e288e2a 11 PID posiPIDx(POSI_X_KP, POSI_X_KI, POSI_X_KD, INT_TIME);
e5119053f6 0:5e4f1e288e2a 12 PID posiPIDy(POSI_Y_KP, POSI_Y_KI, POSI_Y_KD, INT_TIME);
e5119053f6 0:5e4f1e288e2a 13 PID posiPIDz(POSI_Z_KP, POSI_Z_KI, POSI_Z_KD, INT_TIME);
e5119053f6 0:5e4f1e288e2a 14
e5119053f6 0:5e4f1e288e2a 15 PID yokozurePID(YOKOZURE_KP, YOKOZURE_KI, YOKOZURE_KD, INT_TIME);//(3.0, 0.0, 0.0, INT_TIME);
e5119053f6 0:5e4f1e288e2a 16 PID kakudoPID(KAKUDO_KP, KAKUDO_KI, KAKUDO_KD, INT_TIME);
e5119053f6 0:5e4f1e288e2a 17
e5119053f6 0:5e4f1e288e2a 18 // 二次遅れ使えるようになる
e5119053f6 0:5e4f1e288e2a 19 Filter sokduo_filter(INT_TIME);
e5119053f6 0:5e4f1e288e2a 20 Filter kakudo_filter(INT_TIME);
e5119053f6 0:5e4f1e288e2a 21
e5119053f6 0:5e4f1e288e2a 22 // コンストラクタ
e5119053f6 0:5e4f1e288e2a 23 PathTracking::PathTracking(int xmode){
e5119053f6 0:5e4f1e288e2a 24 path_num = 0;
e5119053f6 0:5e4f1e288e2a 25 max_pathnum = 0;
e5119053f6 0:5e4f1e288e2a 26 t_be = 0.0;
e5119053f6 0:5e4f1e288e2a 27 pre_t_be = 0.1;
e5119053f6 0:5e4f1e288e2a 28 epsilon = 1.0;
e5119053f6 0:5e4f1e288e2a 29
e5119053f6 0:5e4f1e288e2a 30 refVx = 0;
e5119053f6 0:5e4f1e288e2a 31 refVy = 0;
e5119053f6 0:5e4f1e288e2a 32 refVz = 0;
e5119053f6 0:5e4f1e288e2a 33
e5119053f6 0:5e4f1e288e2a 34 count_acc = 0;
e5119053f6 0:5e4f1e288e2a 35
e5119053f6 0:5e4f1e288e2a 36 mode = xmode;
e5119053f6 0:5e4f1e288e2a 37
e5119053f6 0:5e4f1e288e2a 38 mode_changed = true;
e5119053f6 0:5e4f1e288e2a 39 init_done = false;
e5119053f6 0:5e4f1e288e2a 40 }
e5119053f6 0:5e4f1e288e2a 41
e5119053f6 0:5e4f1e288e2a 42 // tを求めるための方程式
e5119053f6 0:5e4f1e288e2a 43 double PathTracking::func(int p, double t)
e5119053f6 0:5e4f1e288e2a 44 {
e5119053f6 0:5e4f1e288e2a 45 return a_be[p] * pow(t, 5.0) + b_be[p] * pow(t,4.0) + c_be[p] * pow(t,3.0) + d_be[p] * pow(t,2.0) + e_be[p] * t + f_be[p];
e5119053f6 0:5e4f1e288e2a 46 }
e5119053f6 0:5e4f1e288e2a 47 // tを求めるための方程式の1階微分
e5119053f6 0:5e4f1e288e2a 48 double PathTracking::dfunc(int p, double t)
e5119053f6 0:5e4f1e288e2a 49 {
e5119053f6 0:5e4f1e288e2a 50 return 5.0 * a_be[p] * pow(t, 4.0) + 4.0 * b_be[p] * pow(t,3.0) + 3.0 * c_be[p] * pow(t,2.0) + 2.0 * d_be[p] * t + e_be[p];
e5119053f6 0:5e4f1e288e2a 51 }
e5119053f6 0:5e4f1e288e2a 52
e5119053f6 0:5e4f1e288e2a 53 // tにおけるベジエ曲線の座標を求める関数
e5119053f6 0:5e4f1e288e2a 54 double PathTracking::bezier_x(int p, double t)
e5119053f6 0:5e4f1e288e2a 55 {
e5119053f6 0:5e4f1e288e2a 56 return Ax[p]*pow(t,3.0) + 3.0*Bx[p]*pow(t,2.0) + 3.0*Cx[p]*t + Dx[p];
e5119053f6 0:5e4f1e288e2a 57 }
e5119053f6 0:5e4f1e288e2a 58 double PathTracking::bezier_y(int p, double t)
e5119053f6 0:5e4f1e288e2a 59 {
e5119053f6 0:5e4f1e288e2a 60 return Ay[p]*pow(t,3.0) + 3.0*By[p]*pow(t,2.0) + 3.0*Cy[p]*t + Dy[p];
e5119053f6 0:5e4f1e288e2a 61 }
e5119053f6 0:5e4f1e288e2a 62
e5119053f6 0:5e4f1e288e2a 63 // ベジエ曲線式の1階微分
e5119053f6 0:5e4f1e288e2a 64 double PathTracking::dbezier_x(int p, double t)
e5119053f6 0:5e4f1e288e2a 65 {
e5119053f6 0:5e4f1e288e2a 66 return 3.0*Ax[p]*pow(t,2.0) + 6.0*Bx[p]*t + 3.0*Cx[p];
e5119053f6 0:5e4f1e288e2a 67 }
e5119053f6 0:5e4f1e288e2a 68 double PathTracking::dbezier_y(int p, double t)
e5119053f6 0:5e4f1e288e2a 69 {
e5119053f6 0:5e4f1e288e2a 70 return 3.0*Ay[p]*pow(t,2.0) + 6.0*By[p]*t + 3.0*Cy[p];
e5119053f6 0:5e4f1e288e2a 71 }
e5119053f6 0:5e4f1e288e2a 72
e5119053f6 0:5e4f1e288e2a 73 // ニュートン法のための係数の初期化
e5119053f6 0:5e4f1e288e2a 74 void PathTracking::initSettings(){
e5119053f6 0:5e4f1e288e2a 75 // PID関連初期化
e5119053f6 0:5e4f1e288e2a 76 posiPIDx.PIDinit(0.0, 0.0);
e5119053f6 0:5e4f1e288e2a 77 posiPIDy.PIDinit(0.0, 0.0);
e5119053f6 0:5e4f1e288e2a 78 posiPIDz.PIDinit(0.0, 0.0);
e5119053f6 0:5e4f1e288e2a 79
e5119053f6 0:5e4f1e288e2a 80 yokozurePID.PIDinit(0.0, 0.0);
e5119053f6 0:5e4f1e288e2a 81 kakudoPID.PIDinit(0.0, 0.0);
e5119053f6 0:5e4f1e288e2a 82
e5119053f6 0:5e4f1e288e2a 83 sokduo_filter.setSecondOrderPara(FILT_SOKUDO_OMEGA, FILT_SOKUDO_DZETA, 0.0);//(15.0, 1.0, 0.0);
e5119053f6 0:5e4f1e288e2a 84 kakudo_filter.setSecondOrderPara(FILT_KAKUDO_OMEGA, FILT_KAKUDO_DZETA, 0.0);//(7.0, 1.0, 0.0);
e5119053f6 0:5e4f1e288e2a 85
e5119053f6 0:5e4f1e288e2a 86 for(int i = 0; i < PATHNUM; i++) {
e5119053f6 0:5e4f1e288e2a 87 Ax[i] = Px[3*i+3] -3*Px[3*i+2] + 3*Px[3*i+1] - Px[3*i+0];
e5119053f6 0:5e4f1e288e2a 88 Ay[i] = Py[3*i+3] -3*Py[3*i+2] + 3*Py[3*i+1] - Py[3*i+0];
e5119053f6 0:5e4f1e288e2a 89 Bx[i] = Px[3*i+2] -2*Px[3*i+1] + Px[3*i+0];
e5119053f6 0:5e4f1e288e2a 90 By[i] = Py[3*i+2] -2*Py[3*i+1] + Py[3*i+0];
e5119053f6 0:5e4f1e288e2a 91 Cx[i] = Px[3*i+1] - Px[3*i+0];
e5119053f6 0:5e4f1e288e2a 92 Cy[i] = Py[3*i+1] - Py[3*i+0];
e5119053f6 0:5e4f1e288e2a 93 Dx[i] = Px[3*i+0];
e5119053f6 0:5e4f1e288e2a 94 Dy[i] = Py[3*i+0];
e5119053f6 0:5e4f1e288e2a 95 }
e5119053f6 0:5e4f1e288e2a 96
e5119053f6 0:5e4f1e288e2a 97 for(int i = 0; i < PATHNUM; i++) {
e5119053f6 0:5e4f1e288e2a 98 a_be[i] = pow(Ax[i], 2.0) + pow(Ay[i], 2.0);
e5119053f6 0:5e4f1e288e2a 99 b_be[i] = 5*(Ax[i]*Bx[i] + Ay[i]*By[i]);
e5119053f6 0:5e4f1e288e2a 100 c_be[i] = 2*((3*pow(Bx[i],2.0)+2*Ax[i]*Cx[i]) + (3*pow(By[i],2.0)+2*Ay[i]*Cy[i]));
e5119053f6 0:5e4f1e288e2a 101 d_be_[i] = 9*Bx[i]*Cx[i] + 9*By[i]*Cy[i];
e5119053f6 0:5e4f1e288e2a 102 e_be_[i] = 3*pow(Cx[i],2.0) + 3*pow(Cy[i],2.0);
e5119053f6 0:5e4f1e288e2a 103 f_be_[i] = 0;
e5119053f6 0:5e4f1e288e2a 104 }
e5119053f6 0:5e4f1e288e2a 105 init_done = true;
e5119053f6 0:5e4f1e288e2a 106 }
e5119053f6 0:5e4f1e288e2a 107
e5119053f6 0:5e4f1e288e2a 108 // ベジエ曲線までの垂線距離をニュートン法で求めて,そこまでの距離と接線角度を計算する
e5119053f6 0:5e4f1e288e2a 109 void PathTracking::calcRefpoint(){
e5119053f6 0:5e4f1e288e2a 110 if(init_done){
e5119053f6 0:5e4f1e288e2a 111 double tmpx = Px[path_num * 3] - gPosi.x;
e5119053f6 0:5e4f1e288e2a 112 double tmpy = Py[path_num * 3] - gPosi.y;
e5119053f6 0:5e4f1e288e2a 113
e5119053f6 0:5e4f1e288e2a 114 d_be[path_num] = d_be_[path_num] + Ax[path_num] * tmpx + Ay[path_num] * tmpy;
e5119053f6 0:5e4f1e288e2a 115 e_be[path_num] = e_be_[path_num] + 2*Bx[path_num] * tmpx + 2*By[path_num] * tmpy;
e5119053f6 0:5e4f1e288e2a 116 f_be[path_num] = f_be_[path_num] + Cx[path_num] * tmpx + Cy[path_num] * tmpy;
e5119053f6 0:5e4f1e288e2a 117
e5119053f6 0:5e4f1e288e2a 118 int count_newton = 0;
e5119053f6 0:5e4f1e288e2a 119 do {
e5119053f6 0:5e4f1e288e2a 120 t_be = pre_t_be - func(path_num, pre_t_be)/dfunc(path_num, pre_t_be);
e5119053f6 0:5e4f1e288e2a 121 epsilon = fabs((t_be - pre_t_be)/pre_t_be);
e5119053f6 0:5e4f1e288e2a 122
e5119053f6 0:5e4f1e288e2a 123 pre_t_be = t_be;
e5119053f6 0:5e4f1e288e2a 124 count_newton++;
e5119053f6 0:5e4f1e288e2a 125 }while(epsilon >= 1e-4 && count_newton <= 50);
e5119053f6 0:5e4f1e288e2a 126
e5119053f6 0:5e4f1e288e2a 127 //double onx, ony; //ベジエ曲線上の点
e5119053f6 0:5e4f1e288e2a 128 onx = bezier_x(path_num, t_be);
e5119053f6 0:5e4f1e288e2a 129 ony = bezier_y(path_num, t_be);
e5119053f6 0:5e4f1e288e2a 130
e5119053f6 0:5e4f1e288e2a 131 // 外積による距離導出
e5119053f6 0:5e4f1e288e2a 132 //double angle;
e5119053f6 0:5e4f1e288e2a 133 angle = atan2(dbezier_y(path_num, t_be), dbezier_x(path_num, t_be)); // ベジエ曲線の接線方向
e5119053f6 0:5e4f1e288e2a 134 if(fabs(angle - preAngle) > M_PI){
e5119053f6 0:5e4f1e288e2a 135 angle += 2 * M_PI;
e5119053f6 0:5e4f1e288e2a 136 }
e5119053f6 0:5e4f1e288e2a 137 //double dist;
e5119053f6 0:5e4f1e288e2a 138 dist = (ony - gPosi.y)*cos(angle) - (onx - gPosi.x)*sin(angle);
e5119053f6 0:5e4f1e288e2a 139
e5119053f6 0:5e4f1e288e2a 140 epsilon = 1.0;
e5119053f6 0:5e4f1e288e2a 141 }
e5119053f6 0:5e4f1e288e2a 142 }
e5119053f6 0:5e4f1e288e2a 143
e5119053f6 0:5e4f1e288e2a 144 // モードによって,それぞれ指令速度を計算する
e5119053f6 0:5e4f1e288e2a 145 int PathTracking::calcRefvel(){
e5119053f6 0:5e4f1e288e2a 146 double refVxg, refVyg, refVzg; // グローバル座標系の指定速度
e5119053f6 0:5e4f1e288e2a 147 double tmpPx, tmpPy;
e5119053f6 0:5e4f1e288e2a 148 //static int counter = 0;
e5119053f6 0:5e4f1e288e2a 149
e5119053f6 0:5e4f1e288e2a 150 if(init_done){
e5119053f6 0:5e4f1e288e2a 151 if(path_num <= max_pathnum){ // パスが存在する場合は以下の処理を行う
e5119053f6 0:5e4f1e288e2a 152 if(mode == FOLLOW_TANGENT || mode == FOLLOW_COMMAND){ // ベジエ曲線追従モード
e5119053f6 0:5e4f1e288e2a 153 calcRefpoint();
e5119053f6 0:5e4f1e288e2a 154
e5119053f6 0:5e4f1e288e2a 155 double refVtan, refVper, refVrot;
e5119053f6 0:5e4f1e288e2a 156 if((acc_mode[path_num] == MODE_START || acc_mode[path_num] == MODE_START_STOP) && count_acc <= acc_count[path_num]){
e5119053f6 0:5e4f1e288e2a 157 count_acc++;
e5119053f6 0:5e4f1e288e2a 158 refVtan = refvel[path_num] * count_acc/(double)acc_count[path_num];
e5119053f6 0:5e4f1e288e2a 159 }else if(t_be < dec_tbe[path_num]){
e5119053f6 0:5e4f1e288e2a 160 refVtan = refvel[path_num];
e5119053f6 0:5e4f1e288e2a 161 }else if((acc_mode[path_num] == MODE_STOP || acc_mode[path_num] == MODE_START_STOP) && t_be >= dec_tbe[path_num]){
e5119053f6 0:5e4f1e288e2a 162 refVtan = refvel[path_num] - refvel[path_num] * (t_be - dec_tbe[path_num]) / (1.0 - dec_tbe[path_num]);
e5119053f6 0:5e4f1e288e2a 163 }else if(t_be >= dec_tbe[path_num]){
e5119053f6 0:5e4f1e288e2a 164 refVtan = refvel[path_num] - (refvel[path_num] - refvel[path_num + 1]) * (t_be - dec_tbe[path_num]) / (1.0 - dec_tbe[path_num]);
e5119053f6 0:5e4f1e288e2a 165 }
e5119053f6 0:5e4f1e288e2a 166
e5119053f6 0:5e4f1e288e2a 167 //refVtan = sokduo_filter.SecondOrderLag(refvel[path_num]); // 接線方向速度
e5119053f6 0:5e4f1e288e2a 168 refVper = yokozurePID.getCmd(dist, 0.0, refvel[path_num] * 2.0); // 横方向速度
e5119053f6 0:5e4f1e288e2a 169
e5119053f6 0:5e4f1e288e2a 170 // 旋回は以下の2種類を mode によって変える
e5119053f6 0:5e4f1e288e2a 171 if(mode == FOLLOW_TANGENT){
e5119053f6 0:5e4f1e288e2a 172 if(mode_changed){
e5119053f6 0:5e4f1e288e2a 173 kakudoPID.PIDinit(angle, gPosi.z);
e5119053f6 0:5e4f1e288e2a 174 mode_changed = false;
e5119053f6 0:5e4f1e288e2a 175 }
e5119053f6 0:5e4f1e288e2a 176 refVrot = kakudoPID.getCmd(angle, gPosi.z, 1.57);//(refKakudo, gPosiz, 1.57);
e5119053f6 0:5e4f1e288e2a 177 }else{
e5119053f6 0:5e4f1e288e2a 178 if(mode_changed){
e5119053f6 0:5e4f1e288e2a 179 kakudoPID.PIDinit(refKakudo, gPosi.z);
e5119053f6 0:5e4f1e288e2a 180 kakudo_filter.initPrevData(refKakudo);
e5119053f6 0:5e4f1e288e2a 181 mode_changed = false;
e5119053f6 0:5e4f1e288e2a 182 }
e5119053f6 0:5e4f1e288e2a 183 refKakudo = kakudo_filter.SecondOrderLag(refangle[path_num]);
e5119053f6 0:5e4f1e288e2a 184 refVrot = kakudoPID.getCmd(refKakudo, gPosi.z, 1.57);
e5119053f6 0:5e4f1e288e2a 185 }
e5119053f6 0:5e4f1e288e2a 186
e5119053f6 0:5e4f1e288e2a 187 per = refVper;
e5119053f6 0:5e4f1e288e2a 188 rot = refVrot;
e5119053f6 0:5e4f1e288e2a 189 // ローカル座標系の指令速度(グローバル座標系のも込み込み)
e5119053f6 0:5e4f1e288e2a 190 //refVxとrefVyをコメントアウトするとkakudoPIDのパラメータ調整が出来る(手で押してみて…)
e5119053f6 0:5e4f1e288e2a 191 //refVperだけにするとyokozurePIDのパラメータ調整できる
e5119053f6 0:5e4f1e288e2a 192 refVx = refVtan * cos( gPosi.z - angle ) + refVper * sin( gPosi.z - angle );
e5119053f6 0:5e4f1e288e2a 193 refVy = -refVtan * sin( gPosi.z - angle ) + refVper * cos( gPosi.z - angle );
e5119053f6 0:5e4f1e288e2a 194 refVz = refVrot;
e5119053f6 0:5e4f1e288e2a 195 }else{ // PID位置制御モード
e5119053f6 0:5e4f1e288e2a 196 if( mode_changed ){
e5119053f6 0:5e4f1e288e2a 197 Px[3 * path_num] = gPosi.x;
e5119053f6 0:5e4f1e288e2a 198 Py[3 * path_num] = gPosi.y;
e5119053f6 0:5e4f1e288e2a 199 posiPIDx.PIDinit(Px[3 * path_num], gPosi.x); // ref, act
e5119053f6 0:5e4f1e288e2a 200 posiPIDy.PIDinit(Py[3 * path_num], gPosi.y);
e5119053f6 0:5e4f1e288e2a 201 posiPIDz.PIDinit(refKakudo, gPosi.z);
e5119053f6 0:5e4f1e288e2a 202 kakudo_filter.initPrevData(refKakudo);
e5119053f6 0:5e4f1e288e2a 203 setRefKakudo();
e5119053f6 0:5e4f1e288e2a 204 mode_changed = false;
e5119053f6 0:5e4f1e288e2a 205 }
e5119053f6 0:5e4f1e288e2a 206
e5119053f6 0:5e4f1e288e2a 207 if(count_acc <= acc_count[path_num]){
e5119053f6 0:5e4f1e288e2a 208 count_acc++;
e5119053f6 0:5e4f1e288e2a 209 tmpPx = Px[3 * path_num] + (Px[3 * path_num + 3] - Px[3 * path_num]) * count_acc / (double)acc_count[path_num];
e5119053f6 0:5e4f1e288e2a 210 tmpPy = Py[3 * path_num] + (Py[3 * path_num + 3] - Py[3 * path_num]) * count_acc / (double)acc_count[path_num];
e5119053f6 0:5e4f1e288e2a 211 }else{
e5119053f6 0:5e4f1e288e2a 212 tmpPx = (Px[3 * path_num + 3]);
e5119053f6 0:5e4f1e288e2a 213 tmpPy = (Py[3 * path_num + 3]);
e5119053f6 0:5e4f1e288e2a 214 }
e5119053f6 0:5e4f1e288e2a 215
e5119053f6 0:5e4f1e288e2a 216 // PIDクラスを使って位置制御を行う(速度の指令値を得る)
e5119053f6 0:5e4f1e288e2a 217 refVxg = posiPIDx.getCmd(tmpPx, gPosi.x, refvel[path_num]);//(Px[30], gPosix, refvel[phase]);
e5119053f6 0:5e4f1e288e2a 218 refVyg = posiPIDy.getCmd(tmpPy, gPosi.y, refvel[path_num]);//(Py[30], gPosiy, refvel[phase]);
e5119053f6 0:5e4f1e288e2a 219 refKakudo = kakudo_filter.SecondOrderLag(refangle[path_num]);
e5119053f6 0:5e4f1e288e2a 220 refVzg = posiPIDz.getCmd(refKakudo, gPosi.z, 1.57);//角速度に対してrefvelは遅すぎるから refvel[path_num]);//(0.0, gPosiz, refvel[phase]);
e5119053f6 0:5e4f1e288e2a 221
e5119053f6 0:5e4f1e288e2a 222 // 上記はグローバル座標系における速度のため,ローカルに変換
e5119053f6 0:5e4f1e288e2a 223 refVx = refVxg * cos(gPosi.z) + refVyg * sin(gPosi.z);
e5119053f6 0:5e4f1e288e2a 224 refVy = -refVxg * sin(gPosi.z) + refVyg * cos(gPosi.z);
e5119053f6 0:5e4f1e288e2a 225 refVz = refVzg;
e5119053f6 0:5e4f1e288e2a 226 }
e5119053f6 0:5e4f1e288e2a 227
e5119053f6 0:5e4f1e288e2a 228 // 収束判定して,収束していたら 1 を返す
e5119053f6 0:5e4f1e288e2a 229 dist2goal = sqrt(pow(gPosi.x - Px[3 * path_num + 3], 2.0) + pow(gPosi.y - Py[3 * path_num + 3], 2.0));
e5119053f6 0:5e4f1e288e2a 230 if(mode == FOLLOW_TANGENT || mode == FOLLOW_COMMAND){
e5119053f6 0:5e4f1e288e2a 231 // 軌道追従制御なら,到達位置からの距離とベジエ曲線の t のどちらかの条件
e5119053f6 0:5e4f1e288e2a 232 if(dist2goal <= conv_length || t_be >= conv_tnum){
e5119053f6 0:5e4f1e288e2a 233 //counter = 0;
e5119053f6 0:5e4f1e288e2a 234 return 1;
e5119053f6 0:5e4f1e288e2a 235 }
e5119053f6 0:5e4f1e288e2a 236 }if(mode == POSITION_PID){
e5119053f6 0:5e4f1e288e2a 237 // 位置制御なら,目標位置と角度両方を見る
e5119053f6 0:5e4f1e288e2a 238 if(dist2goal <= conv_length && fabs(refangle[path_num] - gPosi.z)){
e5119053f6 0:5e4f1e288e2a 239 //counter = 0;
e5119053f6 0:5e4f1e288e2a 240 return 1;
e5119053f6 0:5e4f1e288e2a 241 }
e5119053f6 0:5e4f1e288e2a 242 }
e5119053f6 0:5e4f1e288e2a 243
e5119053f6 0:5e4f1e288e2a 244 // 収束していなかったら 0 を返す
e5119053f6 0:5e4f1e288e2a 245 return 0;
e5119053f6 0:5e4f1e288e2a 246 }else{
e5119053f6 0:5e4f1e288e2a 247 // path_num が設定された max_pathnum を超えたら -2 を返す
e5119053f6 0:5e4f1e288e2a 248 return -2;
e5119053f6 0:5e4f1e288e2a 249 }
e5119053f6 0:5e4f1e288e2a 250
e5119053f6 0:5e4f1e288e2a 251 }else{
e5119053f6 0:5e4f1e288e2a 252 // 初期化されていなかったら -1 を返す
e5119053f6 0:5e4f1e288e2a 253 return -1;
e5119053f6 0:5e4f1e288e2a 254 }
e5119053f6 0:5e4f1e288e2a 255 }
e5119053f6 0:5e4f1e288e2a 256
e5119053f6 0:5e4f1e288e2a 257 // ベジエ曲線のパス番号をインクリメントする
e5119053f6 0:5e4f1e288e2a 258 void PathTracking::incrPathnum(double xconv_length, double xconv_tnum = 0.997){
e5119053f6 0:5e4f1e288e2a 259 path_num++;
e5119053f6 0:5e4f1e288e2a 260 pre_t_be = 0.1;
e5119053f6 0:5e4f1e288e2a 261 count_acc = 0;
e5119053f6 0:5e4f1e288e2a 262 setConvPara(xconv_length, xconv_tnum);
e5119053f6 0:5e4f1e288e2a 263 }
e5119053f6 0:5e4f1e288e2a 264
e5119053f6 0:5e4f1e288e2a 265 int PathTracking::getPathNum(){
e5119053f6 0:5e4f1e288e2a 266 return path_num;
e5119053f6 0:5e4f1e288e2a 267 }
e5119053f6 0:5e4f1e288e2a 268
e5119053f6 0:5e4f1e288e2a 269 void PathTracking::setPathNum(int num){
e5119053f6 0:5e4f1e288e2a 270 path_num = num;
e5119053f6 0:5e4f1e288e2a 271 }
e5119053f6 0:5e4f1e288e2a 272
e5119053f6 0:5e4f1e288e2a 273 // 収束判定に用いる距離などをセットする
e5119053f6 0:5e4f1e288e2a 274 void PathTracking::setConvPara(double xconv_length, double xconv_tnum = 0.997){
e5119053f6 0:5e4f1e288e2a 275 conv_length = xconv_length;
e5119053f6 0:5e4f1e288e2a 276 conv_tnum = xconv_tnum;
e5119053f6 0:5e4f1e288e2a 277 }
e5119053f6 0:5e4f1e288e2a 278
e5119053f6 0:5e4f1e288e2a 279 void PathTracking::setMode(int xmode){
e5119053f6 0:5e4f1e288e2a 280 mode = xmode;
e5119053f6 0:5e4f1e288e2a 281 mode_changed = true;
e5119053f6 0:5e4f1e288e2a 282 }
e5119053f6 0:5e4f1e288e2a 283
e5119053f6 0:5e4f1e288e2a 284 int PathTracking::getMode(){
e5119053f6 0:5e4f1e288e2a 285 return mode;
e5119053f6 0:5e4f1e288e2a 286 }
e5119053f6 0:5e4f1e288e2a 287
e5119053f6 0:5e4f1e288e2a 288 void PathTracking::setMaxPathnum(int num){
e5119053f6 0:5e4f1e288e2a 289 max_pathnum = num;
e5119053f6 0:5e4f1e288e2a 290 }
e5119053f6 0:5e4f1e288e2a 291
e5119053f6 0:5e4f1e288e2a 292 void PathTracking::setPosiPIDxPara(float xKp, float xKi, float xKd){
e5119053f6 0:5e4f1e288e2a 293 posiPIDx.setPara(xKp, xKi, xKd);
e5119053f6 0:5e4f1e288e2a 294 }
e5119053f6 0:5e4f1e288e2a 295
e5119053f6 0:5e4f1e288e2a 296 void PathTracking::setPosiPIDyPara(float xKp, float xKi, float xKd){
e5119053f6 0:5e4f1e288e2a 297 posiPIDy.setPara(xKp, xKi, xKd);
e5119053f6 0:5e4f1e288e2a 298 }
e5119053f6 0:5e4f1e288e2a 299
e5119053f6 0:5e4f1e288e2a 300 void PathTracking::setPosiPIDzPara(float xKp, float xKi, float xKd){
e5119053f6 0:5e4f1e288e2a 301 posiPIDz.setPara(xKp, xKi, xKd);
e5119053f6 0:5e4f1e288e2a 302 }
e5119053f6 0:5e4f1e288e2a 303
e5119053f6 0:5e4f1e288e2a 304 void PathTracking::setYokozurePIDPara(float xKp, float xKi, float xKd){
e5119053f6 0:5e4f1e288e2a 305 yokozurePID.setPara(xKp, xKi, xKd);
e5119053f6 0:5e4f1e288e2a 306 }
e5119053f6 0:5e4f1e288e2a 307
e5119053f6 0:5e4f1e288e2a 308 void PathTracking::setKakudoPIDPara(float xKp, float xKi, float xKd){
e5119053f6 0:5e4f1e288e2a 309 kakudoPID.setPara(xKp, xKi, xKd);
e5119053f6 0:5e4f1e288e2a 310 }
e5119053f6 0:5e4f1e288e2a 311
e5119053f6 0:5e4f1e288e2a 312
e5119053f6 0:5e4f1e288e2a 313 void PathTracking::kakudoPIDinit(){
e5119053f6 0:5e4f1e288e2a 314 kakudoPID.PIDinit(refKakudo, gPosi.z);
e5119053f6 0:5e4f1e288e2a 315 }
e5119053f6 0:5e4f1e288e2a 316
e5119053f6 0:5e4f1e288e2a 317 void PathTracking::setRefKakudo(){
e5119053f6 0:5e4f1e288e2a 318 refKakudo = refangle[path_num];
e5119053f6 0:5e4f1e288e2a 319 }
e5119053f6 0:5e4f1e288e2a 320
e5119053f6 0:5e4f1e288e2a 321 double PathTracking::getRefVper(){
e5119053f6 0:5e4f1e288e2a 322 return per;
e5119053f6 0:5e4f1e288e2a 323 }
e5119053f6 0:5e4f1e288e2a 324
e5119053f6 0:5e4f1e288e2a 325 double PathTracking::getRefVrot(){
e5119053f6 0:5e4f1e288e2a 326 return rot;
e5119053f6 0:5e4f1e288e2a 327 }