00001
00002
00003
00004 #include <config.h>
00005 #if defined(CONF_DMOTOR) && defined(CONF_DSENSOR) && defined(CONF_DSENSOR_ROTATION)
00006
00007 #include <conio.h>
00008 #include <stdlib.h>
00009 #include <unistd.h>
00010 #include <dmotor.h>
00011 #include <dsensor.h>
00012 #include <tm.h>
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #define ANGLES 6
00025 #define MOVEMENTS 6
00026
00027
00028
00029
00030
00031 #define FAR_RIGHT 0
00032 #define FAR_LEFT 4
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #define HEAVEN 5
00043 #define HEAVEN_REWARD 20
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 #define TURN_MULTIPLIER 2
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 #define EPSILON_MAX .60
00072 #define EPSILON_MIN .10
00073 #define EPSILON_DECAY .02
00074 double EPSILON_CURRENT = EPSILON_MAX;
00075
00076
00077
00078
00079
00080
00081
00082 #define ALPHA .20
00083
00084
00085
00086 #define GAMMA .90
00087
00088
00089 #define KAPPA 10
00090
00091
00092
00093
00094
00095
00096 enum movement
00097 {
00098 HARD_LEFT, SOFT_LEFT, FORWARD, SOFT_RIGHT, HARD_RIGHT, REVERSE
00099 };
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 double steering_results[ANGLES][MOVEMENTS][ANGLES];
00116 double q_score[ANGLES][MOVEMENTS];
00117
00118
00119
00120
00121 double norm_random()
00122 {
00123 double temp;
00124 temp = random();
00125 temp /= 2147483647;
00126 return temp;
00127 }
00128
00129
00130
00131
00132
00133
00134 int norm_rotation(int real_value)
00135 {
00136 switch(real_value)
00137 {
00138
00139 case -1:
00140 case 0:
00141 case 1:
00142 case 2:
00143 return 0;
00144
00145 case 3:
00146 case 4:
00147 case 5:
00148 case 6:
00149 return 1;
00150
00151 case 7:
00152 case 8:
00153 case 9:
00154 case 10:
00155 case 11:
00156 case 12:
00157 return 2;
00158
00159 case 13:
00160 case 14:
00161 case 15:
00162 case 16:
00163 return 3;
00164
00165 case 17:
00166 case 18:
00167 case 19:
00168 case 20:
00169 return 4;
00170
00171 default:
00172
00173 cputs("ERROR");
00174 sleep(1);
00175 return -1;
00176 }
00177
00178 return 0;
00179 }
00180
00181
00182
00183
00184
00185 void array_initialization()
00186 {
00187 int i, j, k;
00188
00189
00190
00191
00192
00193
00194
00195 for(i=0; i<ANGLES; i++)
00196 {
00197 for(j=0; j<MOVEMENTS; j++)
00198 {
00199 for(k=0; k<ANGLES; k++)
00200 {
00201 steering_results[i][j][k] = (1/ANGLES);
00202 }
00203 }
00204 }
00205
00206
00207 for(i=0; i<ANGLES; i++)
00208 {
00209 for(j=0; j<MOVEMENTS; j++)
00210 {
00211 q_score[i][j] = 0;
00212 }
00213 }
00214 }
00215
00216
00217
00218
00219
00220
00221 void run_motors()
00222 {
00223 motor_a_speed(MAX_SPEED);
00224 motor_c_speed(MAX_SPEED);
00225 }
00226
00227 void go_forward()
00228 {
00229 motor_a_dir(fwd);
00230 motor_c_dir(fwd);
00231 run_motors();
00232 msleep(100*TURN_MULTIPLIER);
00233 }
00234
00235 void go_back()
00236 {
00237 motor_a_dir(rev);
00238 motor_c_dir(rev);
00239 run_motors();
00240 msleep(150*TURN_MULTIPLIER);
00241 }
00242
00243 void soft_left()
00244 {
00245 motor_a_dir(fwd);
00246 motor_c_dir(fwd);
00247 motor_a_speed(MAX_SPEED);
00248 motor_c_speed(MAX_SPEED/2);
00249 msleep(75*TURN_MULTIPLIER);
00250 }
00251
00252 void soft_right()
00253 {
00254 motor_a_dir(fwd);
00255 motor_c_dir(fwd);
00256 motor_a_speed(MAX_SPEED/2);
00257 motor_c_speed(MAX_SPEED);
00258 msleep(75*TURN_MULTIPLIER);
00259 }
00260
00261 void hard_right()
00262 {
00263 motor_a_dir(rev);
00264 motor_c_dir(fwd);
00265 motor_a_speed(MAX_SPEED);
00266 motor_c_speed(MAX_SPEED);
00267 msleep(100*TURN_MULTIPLIER);
00268 }
00269
00270 void hard_left()
00271 {
00272 motor_a_dir(fwd);
00273 motor_c_dir(rev);
00274 motor_a_speed(MAX_SPEED);
00275 motor_c_speed(MAX_SPEED);
00276 msleep(100*TURN_MULTIPLIER);
00277 }
00278
00279 void stop_motors()
00280 {
00281 motor_a_speed(0);
00282 motor_c_speed(0);
00283 motor_a_dir(brake);
00284 motor_c_dir(brake);
00285
00286
00287 msleep(500);
00288 motor_a_dir(off);
00289 motor_c_dir(off);
00290 }
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 void move()
00301 {
00302 int i;
00303
00304
00305 int max_q_score = 0;
00306
00307
00308
00309 int next_movement = -1;
00310
00311
00312
00313 int initial_angle = norm_rotation(ROTATION_2);
00314
00315
00316 int new_angle;
00317
00318
00319 cputs("ANGLE");
00320 msleep(200);
00321 lcd_int(initial_angle);
00322 msleep(500);
00323
00324
00325
00326
00327
00328
00329
00330
00331 if(norm_random() > EPSILON_CURRENT)
00332 {
00333
00334 cputs("real ");
00335 msleep(500);
00336
00337 for(i=0; i<MOVEMENTS; i++)
00338 {
00339 if(q_score[initial_angle][i] > max_q_score)
00340 {
00341 max_q_score = q_score[initial_angle][i];
00342 next_movement = i;
00343 }
00344 }
00345 }
00346 else
00347 {
00348 double temp;
00349
00350 cputs("rand ");
00351 msleep(500);
00352
00353
00354
00355 temp = norm_random();
00356 next_movement = temp*MOVEMENTS;
00357
00358
00359 lcd_int(next_movement);
00360 sleep(1);
00361 }
00362
00363
00364
00365
00366
00367 if(-1==next_movement)
00368 {
00369 double temp;
00370 temp = norm_random();
00371 next_movement = temp*MOVEMENTS;
00372 }
00373
00374
00375 switch(next_movement)
00376 {
00377 case HARD_LEFT:
00378 cputs("HL ");
00379 hard_left();
00380 break;
00381 case SOFT_LEFT:
00382 cputs("SL ");
00383 soft_left();
00384 break;
00385 case FORWARD:
00386 cputs("FWD ");
00387 go_forward();
00388 break;
00389 case SOFT_RIGHT:
00390 cputs("SR ");
00391 soft_right();
00392 break;
00393 case HARD_RIGHT:
00394 cputs("HR ");
00395 hard_right();
00396 break;
00397 case REVERSE:
00398 cputs("REV ");
00399 go_back();
00400 break;
00401 default:
00402
00403 cputs("ERROR");
00404 sleep(1);
00405 stop_motors();
00406 break;
00407 }
00408
00409
00410 stop_motors();
00411
00412
00413 msleep(500);
00414
00415
00416 new_angle = norm_rotation(ROTATION_2);
00417
00418
00419 cputs("NEW ");
00420 msleep(200);
00421 lcd_int(new_angle);
00422 msleep(500);
00423
00424
00425
00426
00427
00428
00429 steering_results[initial_angle][next_movement][new_angle] += ALPHA;
00430
00431
00432 for(i=0; i<ANGLES; i++)
00433 {
00434 steering_results[initial_angle][next_movement][i] /= (1+ALPHA);
00435 }
00436
00437
00438 if(EPSILON_CURRENT > EPSILON_MIN)
00439 {
00440 EPSILON_CURRENT-=EPSILON_DECAY;
00441 }
00442
00443 }
00444
00445
00446
00447
00448
00449
00450
00451
00452 void q_score_update()
00453 {
00454
00455 int i, j, k, l;
00456
00457
00458 float reward;
00459 float q_sum;
00460 float max_q_score;
00461
00462 for(i=0; i<ANGLES; i++)
00463 {
00464 for(j=0; j<MOVEMENTS; j++)
00465 {
00466
00467 if((i>=FAR_LEFT)||(i<=FAR_RIGHT)||(REVERSE==j))
00468 {
00469 reward = 0;
00470 }
00471
00472 else if(HEAVEN==i)
00473 {
00474 reward = HEAVEN_REWARD;
00475 }
00476
00477 else
00478 {
00479 reward = 1;
00480 }
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492 q_sum = 0;
00493
00494 for(k=0; k<ANGLES; k++)
00495 {
00496 max_q_score = 0;
00497 for(l=0; l<MOVEMENTS; l++)
00498 {
00499 if(q_score[k][l] > max_q_score)
00500 {
00501 max_q_score = q_score[k][l];
00502 }
00503 }
00504 q_sum += (steering_results[i][j][k]*max_q_score);
00505 }
00506
00507
00508 q_score[i][j] = reward+(GAMMA*q_sum);
00509 }
00510 }
00511 }
00512
00513
00514
00515
00516
00517 int main(int argc, char **argv)
00518 {
00519 int k;
00520
00521
00522
00523 ds_active(&SENSOR_1);
00524 msleep(100);
00525 srandom(LIGHT_1);
00526 ds_passive(&SENSOR_1);
00527
00528
00529
00530 ds_active(&SENSOR_2);
00531 ds_rotation_on(&SENSOR_2);
00532
00533
00534
00535 cputs("start");
00536 msleep(500);
00537 cputs("at ");
00538 msleep(500);
00539 cputs("right");
00540 sleep(2);
00541
00542
00543 ds_rotation_set(&SENSOR_2, FAR_RIGHT);
00544 msleep(50);
00545
00546 cputs("now ");
00547 msleep(500);
00548 cputs("centr");
00549 sleep(1);
00550
00551
00552 array_initialization();
00553
00554 while (!shutdown_requested())
00555 {
00556
00557
00558 cputs("move");
00559 msleep(500);
00560 move();
00561
00562
00563 cputs("score");
00564
00565 for(k=0; k<KAPPA; k++)
00566 {
00567 q_score_update();
00568 }
00569 }
00570
00571 cls();
00572 return 0;
00573 }
00574
00575 #else
00576 #warning trailerbot.c requires CONF_DMOTOR, CONF_DSENSOR, and CONF_DSENSOR_ROTATION
00577 #warning trailerbot demo will do nothing
00578 int main(int argc, char *argv[]) {
00579 return 0;
00580 }
00581 #endif // defined(CONF_DMOTOR) && defined(CONF_DSENSOR) && defined(CONF_DSENSOR_ROTATION)