test
Dependencies: S11059 VL6180X m3pi mbed
Fork of tc_agent by
main.cpp@4:0e6997707f43, 2017-03-29 (annotated)
- Committer:
- tennisbaca
- Date:
- Wed Mar 29 03:40:18 2017 +0000
- Revision:
- 4:0e6997707f43
- Parent:
- 3:f1ddc26da601
test
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
maruta | 2:3ebca956fd36 | 1 | #include "VL6180X.h" |
sburg | 0:2508f38e90fe | 2 | #include "mbed.h" |
tennisbaca | 1:6340d62d759f | 3 | #include "m3pi.h" |
maruta | 2:3ebca956fd36 | 4 | #include "S11059.h" |
sburg | 0:2508f38e90fe | 5 | |
tennisbaca | 4:0e6997707f43 | 6 | //必要なオブジェクトを作る |
maruta | 2:3ebca956fd36 | 7 | VL6180x rf(p28, p27); //I2C sda and scl |
sburg | 0:2508f38e90fe | 8 | Serial pc(USBTX, USBRX); //USB serial |
maruta | 2:3ebca956fd36 | 9 | S11059 col(p28,p27); |
tennisbaca | 1:6340d62d759f | 10 | m3pi m3pi; |
tennisbaca | 1:6340d62d759f | 11 | Timer t; |
tennisbaca | 4:0e6997707f43 | 12 | |
tennisbaca | 3:f1ddc26da601 | 13 | // Minimum and maximum motor speeds |
tennisbaca | 4:0e6997707f43 | 14 | #define MAX 1 //速度の最大値 |
tennisbaca | 4:0e6997707f43 | 15 | #define MIN 0 //速度の最小値(バックはしません) |
tennisbaca | 3:f1ddc26da601 | 16 | |
tennisbaca | 4:0e6997707f43 | 17 | // PID terms ライントレースに必要なPID項 |
tennisbaca | 4:0e6997707f43 | 18 | //このプログラムでは車両の下に存在する黒いテープの車両の中心からのズレを状態として、PIDで制御します。 |
tennisbaca | 3:f1ddc26da601 | 19 | #define P_TERM 1 |
tennisbaca | 3:f1ddc26da601 | 20 | #define I_TERM 0 |
tennisbaca | 3:f1ddc26da601 | 21 | #define D_TERM 20 |
tennisbaca | 3:f1ddc26da601 | 22 | |
tennisbaca | 4:0e6997707f43 | 23 | // PID terms 車両が衝突回避を行っているときのライントレースのPID項(速度がおそくなるから値を変えてます) |
tennisbaca | 3:f1ddc26da601 | 24 | #define P_TERM_COL 1 |
tennisbaca | 3:f1ddc26da601 | 25 | #define I_TERM_COL 0 |
tennisbaca | 3:f1ddc26da601 | 26 | #define D_TERM_COL 20 |
tennisbaca | 3:f1ddc26da601 | 27 | |
tennisbaca | 4:0e6997707f43 | 28 | //リニア信号機,前方車両,ライントレースから計算される速度から車両の速度(左右のタイヤにかかる電圧)を決定するための最も遅い速度のインデックスを返す関数 |
tennisbaca | 4:0e6997707f43 | 29 | int min_index(float a,float b,float c,float d,float e,float f){ |
tennisbaca | 4:0e6997707f43 | 30 | float sum1 = a + b; |
tennisbaca | 4:0e6997707f43 | 31 | float sum2 = c + d; |
tennisbaca | 4:0e6997707f43 | 32 | float sum3 = e + f; |
tennisbaca | 4:0e6997707f43 | 33 | |
tennisbaca | 4:0e6997707f43 | 34 | if(sum1<sum2 && sum1<sum3){ |
tennisbaca | 4:0e6997707f43 | 35 | return 1; |
tennisbaca | 4:0e6997707f43 | 36 | }else if(sum1>sum2 && sum3>sum2){ |
tennisbaca | 4:0e6997707f43 | 37 | return 2; |
tennisbaca | 4:0e6997707f43 | 38 | }else{ |
tennisbaca | 4:0e6997707f43 | 39 | return 3; |
tennisbaca | 4:0e6997707f43 | 40 | } |
tennisbaca | 4:0e6997707f43 | 41 | } |
sburg | 0:2508f38e90fe | 42 | |
sburg | 0:2508f38e90fe | 43 | int main() { |
tennisbaca | 1:6340d62d759f | 44 | m3pi.cls(); |
tennisbaca | 3:f1ddc26da601 | 45 | //t_for_music.start(); |
tennisbaca | 4:0e6997707f43 | 46 | //一秒間スクリーンに文字を表示する |
tennisbaca | 4:0e6997707f43 | 47 | m3pi.locate(0,0); //指定した位置(0,0)に |
tennisbaca | 4:0e6997707f43 | 48 | m3pi.printf("Battery"); //指定した文字"Battery"を表示する |
tennisbaca | 1:6340d62d759f | 49 | m3pi.locate(0,1); |
tennisbaca | 3:f1ddc26da601 | 50 | float battery = m3pi.battery(); |
tennisbaca | 3:f1ddc26da601 | 51 | m3pi.printf("%.0fmV",battery*1000); |
tennisbaca | 4:0e6997707f43 | 52 | wait(1); |
tennisbaca | 3:f1ddc26da601 | 53 | |
tennisbaca | 3:f1ddc26da601 | 54 | |
tennisbaca | 3:f1ddc26da601 | 55 | // distance sensor |
tennisbaca | 4:0e6997707f43 | 56 | int reading; //前方車両との距離を格納する変数 |
tennisbaca | 4:0e6997707f43 | 57 | float time[2]; //サンプリング時間を一定にするための配列 |
tennisbaca | 4:0e6997707f43 | 58 | //おまじない |
tennisbaca | 4:0e6997707f43 | 59 | m3pi.cls(); |
maruta | 2:3ebca956fd36 | 60 | rf.VL6180xInit(); |
maruta | 2:3ebca956fd36 | 61 | rf.VL6180xDefautSettings(); |
tennisbaca | 4:0e6997707f43 | 62 | |
tennisbaca | 4:0e6997707f43 | 63 | int check = 1; //サンプリリング時間が乱れた時にシステムを止めるための変数 |
tennisbaca | 4:0e6997707f43 | 64 | int Sensor_num = 0;//距離センサは取得に時間がかかるため3ステップに一回値を取得することにするので、そのための値 |
tennisbaca | 4:0e6997707f43 | 65 | int reading_history[3]; //ノイズがあるため前方車両との距離は最新の3つの値の平均をとるのでそのための配列 |
tennisbaca | 3:f1ddc26da601 | 66 | int i; |
tennisbaca | 4:0e6997707f43 | 67 | // |
tennisbaca | 3:f1ddc26da601 | 68 | for(i = 0;i<3;i++){ |
tennisbaca | 4:0e6997707f43 | 69 | reading_history[i] = 255;//初期値はセンサの最大値 |
tennisbaca | 3:f1ddc26da601 | 70 | } |
tennisbaca | 4:0e6997707f43 | 71 | float ave_reading = 255; |
tennisbaca | 3:f1ddc26da601 | 72 | |
tennisbaca | 4:0e6997707f43 | 73 | //おまじない |
tennisbaca | 3:f1ddc26da601 | 74 | rf.triggerDistance(); |
tennisbaca | 4:0e6997707f43 | 75 | m3pi.sensor_auto_calibrate(); |
tennisbaca | 3:f1ddc26da601 | 76 | |
tennisbaca | 3:f1ddc26da601 | 77 | |
tennisbaca | 3:f1ddc26da601 | 78 | // variables for PID |
tennisbaca | 4:0e6997707f43 | 79 | //左右のタイヤにかかる電圧を格納する変数 |
tennisbaca | 4:0e6997707f43 | 80 | float right;//右のタイヤの最終的な電圧(下記の三つの値から最終的にきめる) |
tennisbaca | 4:0e6997707f43 | 81 | float left;//左のタイヤの最終的な電圧(下記の三つの値から最終的にきめる) |
tennisbaca | 4:0e6997707f43 | 82 | |
tennisbaca | 4:0e6997707f43 | 83 | float right1;//ライントレースからの右のタイヤの電圧 |
tennisbaca | 4:0e6997707f43 | 84 | float left1;//ライントレースからの左のタイヤの電圧 |
tennisbaca | 4:0e6997707f43 | 85 | float right2;//前方車両から計算される右のタイヤの電圧 |
tennisbaca | 4:0e6997707f43 | 86 | float left2;//前方車両から計算される左のタイヤの電圧 |
tennisbaca | 4:0e6997707f43 | 87 | float right3;//リニア信号機から受け取る右のタイヤの電圧 |
tennisbaca | 4:0e6997707f43 | 88 | float left3;//リニア信号機から受け取る左のタイヤの電圧 |
tennisbaca | 4:0e6997707f43 | 89 | |
tennisbaca | 4:0e6997707f43 | 90 | int mode = 1; |
tennisbaca | 4:0e6997707f43 | 91 | |
tennisbaca | 4:0e6997707f43 | 92 | |
tennisbaca | 4:0e6997707f43 | 93 | //ライントレースに必要な変数 |
tennisbaca | 4:0e6997707f43 | 94 | float current_pos_of_line = 0.0;//現在の車両のライン上のポジション |
tennisbaca | 4:0e6997707f43 | 95 | float previous_pos_of_line = 0.0;//過去の車両のライン上のポジション |
tennisbaca | 3:f1ddc26da601 | 96 | float derivative,proportional,integral = 0; |
tennisbaca | 3:f1ddc26da601 | 97 | float power; |
tennisbaca | 3:f1ddc26da601 | 98 | float power_collision; |
tennisbaca | 3:f1ddc26da601 | 99 | float speed = MAX; |
tennisbaca | 3:f1ddc26da601 | 100 | |
tennisbaca | 3:f1ddc26da601 | 101 | |
tennisbaca | 3:f1ddc26da601 | 102 | //for color sensor |
tennisbaca | 3:f1ddc26da601 | 103 | int bl=0; |
tennisbaca | 3:f1ddc26da601 | 104 | int gr=0; |
tennisbaca | 4:0e6997707f43 | 105 | int re=0; |
tennisbaca | 3:f1ddc26da601 | 106 | |
tennisbaca | 4:0e6997707f43 | 107 | t.start();//サンプリング時間を一定に保つためタイマーを使い時間を計るので、タイマーをスタートさせる。 |
tennisbaca | 4:0e6997707f43 | 108 | time[0] = t.read();//スタート時間を格納する |
tennisbaca | 3:f1ddc26da601 | 109 | |
sburg | 0:2508f38e90fe | 110 | while(1) { |
tennisbaca | 4:0e6997707f43 | 111 | |
tennisbaca | 4:0e6997707f43 | 112 | Sensor_num = Sensor_num + 1;//距離センサは取得に時間がかかるため3ステップに一回値を取得することにするので、そのための値 |
tennisbaca | 1:6340d62d759f | 113 | m3pi.cls(); |
tennisbaca | 3:f1ddc26da601 | 114 | //t.start(); |
tennisbaca | 3:f1ddc26da601 | 115 | //time[0] = t.read(); |
tennisbaca | 3:f1ddc26da601 | 116 | col.update(); |
tennisbaca | 4:0e6997707f43 | 117 | //カラーセンサからのRGB値をそれぞれの変数に格納する。 |
tennisbaca | 3:f1ddc26da601 | 118 | bl=col.b; |
tennisbaca | 3:f1ddc26da601 | 119 | gr=col.g; |
tennisbaca | 3:f1ddc26da601 | 120 | re=col.r; |
tennisbaca | 3:f1ddc26da601 | 121 | |
tennisbaca | 4:0e6997707f43 | 122 | //左右のモータの電圧を初期化 |
tennisbaca | 4:0e6997707f43 | 123 | right1 = MAX; |
tennisbaca | 4:0e6997707f43 | 124 | right2 = MAX; |
tennisbaca | 4:0e6997707f43 | 125 | right3 = MAX; |
tennisbaca | 4:0e6997707f43 | 126 | left1 = MAX; |
tennisbaca | 4:0e6997707f43 | 127 | left2 = MAX; |
tennisbaca | 4:0e6997707f43 | 128 | left3 = MAX; |
tennisbaca | 4:0e6997707f43 | 129 | |
tennisbaca | 4:0e6997707f43 | 130 | //ライントレースするための左右のモータの電圧の計算 |
tennisbaca | 3:f1ddc26da601 | 131 | // Get the position of the line. |
tennisbaca | 3:f1ddc26da601 | 132 | current_pos_of_line = m3pi.line_position(); |
tennisbaca | 3:f1ddc26da601 | 133 | proportional = current_pos_of_line; |
tennisbaca | 3:f1ddc26da601 | 134 | |
tennisbaca | 3:f1ddc26da601 | 135 | // Compute the derivative |
tennisbaca | 3:f1ddc26da601 | 136 | derivative = current_pos_of_line - previous_pos_of_line; |
tennisbaca | 3:f1ddc26da601 | 137 | |
tennisbaca | 3:f1ddc26da601 | 138 | // Compute the integral |
tennisbaca | 3:f1ddc26da601 | 139 | integral += proportional; |
tennisbaca | 3:f1ddc26da601 | 140 | |
tennisbaca | 3:f1ddc26da601 | 141 | // Remember the last position. |
tennisbaca | 3:f1ddc26da601 | 142 | previous_pos_of_line = current_pos_of_line; |
tennisbaca | 3:f1ddc26da601 | 143 | |
tennisbaca | 3:f1ddc26da601 | 144 | // Compute the power |
tennisbaca | 3:f1ddc26da601 | 145 | power = (proportional * (P_TERM) ) + (integral*(I_TERM)) + (derivative*(D_TERM)) ; |
tennisbaca | 3:f1ddc26da601 | 146 | power_collision = (proportional * (P_TERM_COL) ) + (integral*(I_TERM_COL)) + (derivative*(D_TERM_COL)) ; |
tennisbaca | 3:f1ddc26da601 | 147 | |
tennisbaca | 3:f1ddc26da601 | 148 | // Compute new speeds if there is nothing ahead |
tennisbaca | 4:0e6997707f43 | 149 | if(ave_reading >= 190 && (gr+re) <= 10000){ |
tennisbaca | 4:0e6997707f43 | 150 | right1 = speed+power; |
tennisbaca | 4:0e6997707f43 | 151 | left1 = speed-power; |
tennisbaca | 3:f1ddc26da601 | 152 | |
tennisbaca | 3:f1ddc26da601 | 153 | // limit checks |
tennisbaca | 4:0e6997707f43 | 154 | if (right1 < MIN) |
tennisbaca | 4:0e6997707f43 | 155 | right1 = MIN; |
tennisbaca | 4:0e6997707f43 | 156 | else if (right1 > MAX) |
tennisbaca | 4:0e6997707f43 | 157 | right1 = MAX; |
tennisbaca | 4:0e6997707f43 | 158 | if (left1 < MIN) |
tennisbaca | 4:0e6997707f43 | 159 | left1 = MIN; |
tennisbaca | 4:0e6997707f43 | 160 | else if (left1 > MAX) |
tennisbaca | 4:0e6997707f43 | 161 | left1 = MAX; |
tennisbaca | 3:f1ddc26da601 | 162 | } |
tennisbaca | 3:f1ddc26da601 | 163 | |
tennisbaca | 3:f1ddc26da601 | 164 | // get distance once every three times because of the processing speed |
tennisbaca | 4:0e6997707f43 | 165 | //3ステップに一回、車両は前方車両との距離を取得する。 |
tennisbaca | 3:f1ddc26da601 | 166 | if((Sensor_num %3)== 1){ |
tennisbaca | 3:f1ddc26da601 | 167 | reading = rf.pollDistance(); |
tennisbaca | 3:f1ddc26da601 | 168 | rf.triggerDistance(); |
tennisbaca | 3:f1ddc26da601 | 169 | if(reading < 90 && reading > 0.1){ |
tennisbaca | 3:f1ddc26da601 | 170 | /*m3pi.locate(0,0); |
tennisbaca | 3:f1ddc26da601 | 171 | m3pi.printf("%dmm",reading); |
tennisbaca | 3:f1ddc26da601 | 172 | wait(10);*/ |
tennisbaca | 3:f1ddc26da601 | 173 | reading = 90; |
tennisbaca | 4:0e6997707f43 | 174 | }else if(reading < 0.1){//たまにセンサの不具合により距離0を返すときがあるのでそれを除外。 |
tennisbaca | 3:f1ddc26da601 | 175 | reading = 255; |
tennisbaca | 3:f1ddc26da601 | 176 | } |
tennisbaca | 3:f1ddc26da601 | 177 | reading_history[0] = reading_history[1]; |
tennisbaca | 3:f1ddc26da601 | 178 | reading_history[1] = reading_history[2]; |
tennisbaca | 3:f1ddc26da601 | 179 | reading_history[2] = reading; |
tennisbaca | 4:0e6997707f43 | 180 | ave_reading = float(reading_history[0]+reading_history[1]+reading_history[2])/3;//三回取得した平均値を前方車両との距離とする |
tennisbaca | 3:f1ddc26da601 | 181 | } |
tennisbaca | 3:f1ddc26da601 | 182 | |
tennisbaca | 3:f1ddc26da601 | 183 | // if distance is too close, change the speed |
tennisbaca | 4:0e6997707f43 | 184 | //前方車両との距離から左右のモータの電圧を計算 |
tennisbaca | 3:f1ddc26da601 | 185 | if(ave_reading < 190){ |
tennisbaca | 4:0e6997707f43 | 186 | right2 = ((ave_reading - 90)/100) + ((ave_reading - 90)/100) * power_collision; |
tennisbaca | 4:0e6997707f43 | 187 | left2 = ((ave_reading - 90)/100) - ((ave_reading - 90)/100) * power_collision; |
tennisbaca | 3:f1ddc26da601 | 188 | // limit checks |
tennisbaca | 4:0e6997707f43 | 189 | if (right2 < MIN) |
tennisbaca | 4:0e6997707f43 | 190 | right2 = MIN; |
tennisbaca | 4:0e6997707f43 | 191 | else if (right2 > MAX) |
tennisbaca | 4:0e6997707f43 | 192 | right2 = MAX; |
tennisbaca | 3:f1ddc26da601 | 193 | |
tennisbaca | 4:0e6997707f43 | 194 | if (left2 < MIN) |
tennisbaca | 4:0e6997707f43 | 195 | left2 = MIN; |
tennisbaca | 4:0e6997707f43 | 196 | else if (left2 > MAX) |
tennisbaca | 4:0e6997707f43 | 197 | left2 = MAX; |
tennisbaca | 3:f1ddc26da601 | 198 | } |
tennisbaca | 3:f1ddc26da601 | 199 | |
tennisbaca | 3:f1ddc26da601 | 200 | //if light is on its left side, use light to control |
tennisbaca | 4:0e6997707f43 | 201 | //カラーセンサから得られるRGB値から左右のモータの電圧を計算する。 |
tennisbaca | 4:0e6997707f43 | 202 | if((gr+re) > 10000){ |
tennisbaca | 3:f1ddc26da601 | 203 | // if(Sensor_num%3 == 2){ |
tennisbaca | 3:f1ddc26da601 | 204 | double light_position = (((double)gr)/((double) (re+gr))); |
tennisbaca | 3:f1ddc26da601 | 205 | double light_speed = light_position*(10.0/7.0)-(2.0/7.0); |
tennisbaca | 4:0e6997707f43 | 206 | right3 = light_speed + light_speed*power_collision; |
tennisbaca | 4:0e6997707f43 | 207 | left3 = light_speed - light_speed*power_collision; |
tennisbaca | 3:f1ddc26da601 | 208 | |
tennisbaca | 3:f1ddc26da601 | 209 | // limit checks |
tennisbaca | 4:0e6997707f43 | 210 | if (right3 < MIN) |
tennisbaca | 4:0e6997707f43 | 211 | right3 = MIN; |
tennisbaca | 4:0e6997707f43 | 212 | else if (right3 > MAX) |
tennisbaca | 4:0e6997707f43 | 213 | right3 = MAX; |
tennisbaca | 3:f1ddc26da601 | 214 | |
tennisbaca | 4:0e6997707f43 | 215 | if (left3 < MIN) |
tennisbaca | 4:0e6997707f43 | 216 | left3 = MIN; |
tennisbaca | 4:0e6997707f43 | 217 | else if (left3 > MAX) |
tennisbaca | 4:0e6997707f43 | 218 | left3 = MAX; |
tennisbaca | 3:f1ddc26da601 | 219 | // } |
tennisbaca | 3:f1ddc26da601 | 220 | } |
tennisbaca | 4:0e6997707f43 | 221 | |
tennisbaca | 4:0e6997707f43 | 222 | //上記で計算された左右のモータにかかる電圧(3つ)から最終的な電圧を計算する。 |
tennisbaca | 4:0e6997707f43 | 223 | mode = min_index(right1,left1,right2,left2,right3,left3); |
tennisbaca | 4:0e6997707f43 | 224 | |
tennisbaca | 4:0e6997707f43 | 225 | if(mode == 1){//(ライントレースから求められた値) |
tennisbaca | 4:0e6997707f43 | 226 | right = right1; |
tennisbaca | 4:0e6997707f43 | 227 | left = left1; |
tennisbaca | 4:0e6997707f43 | 228 | }else if(mode == 2){//(前方車両との距離から求められた値) |
tennisbaca | 4:0e6997707f43 | 229 | right = right2; |
tennisbaca | 4:0e6997707f43 | 230 | left = left2; |
tennisbaca | 4:0e6997707f43 | 231 | }else{//(カラーセンサのRGB値より求められた値) |
tennisbaca | 4:0e6997707f43 | 232 | right = right3; |
tennisbaca | 4:0e6997707f43 | 233 | left = left3; |
tennisbaca | 4:0e6997707f43 | 234 | } |
tennisbaca | 4:0e6997707f43 | 235 | |
tennisbaca | 4:0e6997707f43 | 236 | //求められた左右のモータの電圧を入力 |
tennisbaca | 3:f1ddc26da601 | 237 | m3pi.left_motor(left); |
tennisbaca | 3:f1ddc26da601 | 238 | m3pi.right_motor(right); |
tennisbaca | 3:f1ddc26da601 | 239 | //wait_ms(1); |
tennisbaca | 4:0e6997707f43 | 240 | |
tennisbaca | 4:0e6997707f43 | 241 | //サンプル時間が一定に保たれているかチェック |
tennisbaca | 3:f1ddc26da601 | 242 | while(t.read() - time[0] < 0.005){ |
tennisbaca | 3:f1ddc26da601 | 243 | check = 0; |
tennisbaca | 3:f1ddc26da601 | 244 | } |
tennisbaca | 4:0e6997707f43 | 245 | if(check == 1){//保たれていなければストップ |
tennisbaca | 3:f1ddc26da601 | 246 | m3pi.locate(0,0); |
tennisbaca | 3:f1ddc26da601 | 247 | m3pi.printf("%dmm",reading); |
tennisbaca | 3:f1ddc26da601 | 248 | wait(1); |
tennisbaca | 3:f1ddc26da601 | 249 | m3pi.stop(); |
tennisbaca | 3:f1ddc26da601 | 250 | } |
tennisbaca | 3:f1ddc26da601 | 251 | check = 1; |
tennisbaca | 4:0e6997707f43 | 252 | |
tennisbaca | 4:0e6997707f43 | 253 | //タイマーストップ |
tennisbaca | 3:f1ddc26da601 | 254 | t.stop(); |
tennisbaca | 4:0e6997707f43 | 255 | //タイマースタート(次のステップのサンプル時間をチェックするため) |
tennisbaca | 1:6340d62d759f | 256 | t.start(); |
tennisbaca | 4:0e6997707f43 | 257 | time[0] = t.read();//(スタート時間をチェック) |
sburg | 0:2508f38e90fe | 258 | } |
sburg | 0:2508f38e90fe | 259 | } |