| Line 5... |
Line 5... |
| 5 |
// ========================== PRIPRAVA DAT A VYSTUPU =========================== |
5 |
// ========================== PRIPRAVA DAT A VYSTUPU =========================== |
| 6 |
// pomocne konstanty |
6 |
// pomocne konstanty |
| 7 |
#define LEFT 0 |
7 |
#define LEFT 0 |
| 8 |
#define RIGHT 1 |
8 |
#define RIGHT 1 |
| 9 |
|
9 |
|
| 10 |
// konstanty a promenne pro sledovani cary |
10 |
// regulator |
| 11 |
#define SPACE 20 // urcuje, za jak dlouho robot vi, ze nic nevidi |
11 |
#define CONP 10 // konstanta pro proporcionalni regulator |
| 12 |
#define SPD1 100 // rychlost pomalejsiho motoru, kdyz je cara hodne z osy |
- |
|
| 13 |
#define SPD2 150 // rychlost pomalejsiho motoru, kdyz je cara z osy |
12 |
#define CONI 2 // konstanta pro integracni regulator |
| 14 |
#define SPD3 200 // rychlost rychlejsiho motoru pro vsechny pripady |
- |
|
| 15 |
#define SPD4 255 // pro oba motory - rovinka |
13 |
#define COND 2 // konstanta pro derivacni regulator |
| - |
|
14 |
|
| 16 |
// oblasti cary |
15 |
int8 reg_out; |
| 17 |
#define L1 25 // nejvice vlevo |
16 |
int8 err1; // odchylka prvni hodnoty |
| 18 |
#define L2 30 |
17 |
int8 err2; |
| 19 |
#define L3 45 |
18 |
int8 err3; |
| 20 |
#define R1 55 |
19 |
int8 err4; |
| 21 |
#define R2 70 |
20 |
int8 err5; // odchylka posledni hodnoty |
| 22 |
#define R3 85 // nejvice vpravo |
21 |
int8 errp; // prumer chyb |
| 23 |
|
22 |
|
| - |
|
23 |
// mezera |
| 24 |
int8 action; // akce pro nastaveni motoru |
24 |
#define SPACE 20 |
| 25 |
|
25 |
|
| 26 |
// univerzalni LED diody |
26 |
// univerzalni LED diody |
| 27 |
#define LED1 PIN_E0 |
27 |
#define LED1 PIN_E0 |
| 28 |
#define LED2 PIN_E1 |
28 |
#define LED2 PIN_E1 |
| 29 |
|
29 |
|
| Line 35... |
Line 35... |
| 35 |
#define SDIN PIN_D4 // seriovy vstup |
35 |
#define SDIN PIN_D4 // seriovy vstup |
| 36 |
#define SDOUT input(PIN_C5) // seriovy vystup |
36 |
#define SDOUT input(PIN_C5) // seriovy vystup |
| 37 |
#define SCLK PIN_D5 // takt |
37 |
#define SCLK PIN_D5 // takt |
| 38 |
|
38 |
|
| 39 |
#define LINE_PX 4 // pocet pixelu pro jiste urceni cary |
39 |
#define LINE_PX 4 // pocet pixelu pro jiste urceni cary |
| 40 |
#define OLSA_LEV 0x60 // rozhodovaci uroven (cca 10 odpovida cerne) |
40 |
#define OLSA_LEV 0x10 // rozhodovaci uroven (cca 10 odpovida cerne) |
| 41 |
|
41 |
|
| 42 |
// pro komunikaci s OLSA, prvni se posila LSB |
42 |
// pro komunikaci s OLSA, prvni se posila LSB |
| 43 |
int main_reset[8]={1,1,0,1,1,0,0,0}; // hlavni reset 0x1B |
43 |
int main_reset[8]={1,1,0,1,1,0,0,0}; // hlavni reset 0x1B |
| 44 |
int set_mode_rg[8]={1,1,1,1,1,0,1,0}; // zapis do MODE registru 0x5F |
44 |
int set_mode_rg[8]={1,1,1,1,1,0,1,0}; // zapis do MODE registru 0x5F |
| 45 |
int clear_mode_rg[8]={0,0,0,0,0,0,0,0}; // nulovani MODE registru 0x00 |
45 |
int clear_mode_rg[8]={0,0,0,0,0,0,0,0}; // nulovani MODE registru 0x00 |
| Line 63... |
Line 63... |
| 63 |
int8 *lp; // ukazatel pro levou polovinu radky |
63 |
int8 *lp; // ukazatel pro levou polovinu radky |
| 64 |
int8 *rp; // ukazatel pro levou polovinu radky |
64 |
int8 *rp; // ukazatel pro levou polovinu radky |
| 65 |
|
65 |
|
| 66 |
int8 position; // ulozeni pozice cary |
66 |
int8 position; // ulozeni pozice cary |
| 67 |
int8 old_position; // ulozeni predchozi pozice cary |
67 |
int8 old_position; // ulozeni predchozi pozice cary |
| - |
|
68 |
int8 l_position; |
| - |
|
69 |
int8 r_position; |
| 68 |
int1 line_sector; // cara je vlevo/vpravo |
70 |
int1 line_sector; // cara je vlevo/vpravo |
| 69 |
int8 gap; // pocita, jak dlouho neni videt cara |
71 |
int8 gap; // pocita, jak dlouho neni videt cara |
| 70 |
|
72 |
|
| 71 |
// ================================= NARAZNIK ================================== |
73 |
// ================================= NARAZNIK ================================== |
| 72 |
#define BUMPL input(PIN_D6) |
74 |
#define BUMPL input(PIN_D6) |
| Line 83... |
Line 85... |
| 83 |
#define LMF PIN_D0 |
85 |
#define LMF PIN_D0 |
| 84 |
#define LMB PIN_D1 |
86 |
#define LMB PIN_D1 |
| 85 |
#define RMF PIN_D2 |
87 |
#define RMF PIN_D2 |
| 86 |
#define RMB PIN_D3 |
88 |
#define RMB PIN_D3 |
| 87 |
|
89 |
|
| 88 |
int8 lm_speed; |
90 |
int8 lm_speed; // rychlost leveho motoru |
| 89 |
int8 rm_speed; |
91 |
int8 rm_speed; // rychlost praveho motoru |
| 90 |
int8 m; |
- |
|
| 91 |
|
92 |
|
| 92 |
// =============================== PODPROGRAMY ================================= |
93 |
// =============================== PODPROGRAMY ================================= |
| 93 |
|
94 |
|
| 94 |
// ================================= OLSA01A =================================== |
95 |
// ================================= OLSA01A =================================== |
| 95 |
|
96 |
|
| Line 286... |
Line 287... |
| 286 |
delay_us(period); |
287 |
delay_us(period); |
| 287 |
output_high(SOUND_LO); |
288 |
output_high(SOUND_LO); |
| 288 |
output_low(SOUND_HI); |
289 |
output_low(SOUND_HI); |
| 289 |
delay_us(period); |
290 |
delay_us(period); |
| 290 |
} |
291 |
} |
| - |
|
292 |
} |
| - |
|
293 |
|
| - |
|
294 |
// ================================= REGULATOR ================================= |
| - |
|
295 |
|
| - |
|
296 |
void calc_error() |
| - |
|
297 |
{ |
| - |
|
298 |
err1=err2; // ulozeni chyb |
| - |
|
299 |
err2=err3; |
| - |
|
300 |
err3=err4; |
| - |
|
301 |
err4=err5; |
| - |
|
302 |
if(position<50) // ulozeni a vypocet aktualni absolutni chyby |
| 291 |
} |
303 |
{ |
| - |
|
304 |
err5=(50-position); // pokud je cara vlevo |
| - |
|
305 |
} |
| - |
|
306 |
else |
| - |
|
307 |
{ |
| - |
|
308 |
err5=(position-50); // pokud je cara vpravo |
| - |
|
309 |
} |
| - |
|
310 |
errp=((err1+err2+err3+err4+err5)/5); // vypocet chyby pro integracni regulator |
| - |
|
311 |
} |
| - |
|
312 |
void calc_regulator() |
| - |
|
313 |
{ |
| - |
|
314 |
int8 p_reg; |
| - |
|
315 |
int8 i_reg; |
| - |
|
316 |
int8 d_reg; |
| - |
|
317 |
p_reg=(CONP*err5); // vypocet proporcionalni slozky |
| - |
|
318 |
i_reg=(CONI*errp); // vypocet integracni slozky |
| - |
|
319 |
if(position>old_position) // vypocet derivace |
| - |
|
320 |
{ |
| - |
|
321 |
d_reg=(COND*(position-old_position)); // pokud je aktualni pozice vetsi nez predesla |
| - |
|
322 |
} |
| - |
|
323 |
else |
| - |
|
324 |
{ |
| - |
|
325 |
d_reg=(COND*(old_position-position)); // pokud je aktualni pozice mensi nez predesla |
| - |
|
326 |
} |
| - |
|
327 |
reg_out=(p_reg+i_reg+d_reg); // vypocet celeho regulatoru |
| - |
|
328 |
} |
| 292 |
|
329 |
|
| 293 |
// ================================== MOTORY =================================== |
330 |
// ================================== MOTORY =================================== |
| 294 |
|
331 |
|
| 295 |
void l_motor_fwd(int8 speedl) // levy motor dopredu |
332 |
void l_motor_fwd(int8 speedl) // levy motor dopredu |
| 296 |
{ |
333 |
{ |
| Line 499... |
Line 536... |
| 499 |
{ |
536 |
{ |
| 500 |
old_position=position; // zaznamena predhozi polohu cary |
537 |
old_position=position; // zaznamena predhozi polohu cary |
| 501 |
read_olsa(); // precte a ulozi hodnoty z olsa |
538 |
read_olsa(); // precte a ulozi hodnoty z olsa |
| 502 |
olsa_position(); // vyhodnoti pozici cary |
539 |
olsa_position(); // vyhodnoti pozici cary |
| 503 |
read_blue_sensors(); // cte nouzove senzory |
540 |
read_blue_sensors(); // cte nouzove senzory |
| 504 |
if((line_l==0)&&(gap>SPACE)) // robot najede na levy nouzovy senzor |
- |
|
| 505 |
{ |
- |
|
| 506 |
l_motor_bwd(150); // prudce zatoc doleva |
- |
|
| 507 |
r_motor_fwd(255); |
- |
|
| 508 |
line_sector=LEFT; // pamatuj, kde je cara |
- |
|
| 509 |
delay_ms(300); |
- |
|
| 510 |
} |
- |
|
| 511 |
if((line_r==0)&&(gap>SPACE)) // robot najede na pravy nouzovy senzor |
- |
|
| 512 |
{ |
- |
|
| 513 |
l_motor_fwd(255); // prudce zatoc doprava |
- |
|
| 514 |
r_motor_bwd(150); |
- |
|
| 515 |
line_sector=RIGHT; // pamatuj, kde je cara |
- |
|
| 516 |
delay_ms(300); |
- |
|
| 517 |
} |
- |
|
| 518 |
if(position==0) // pokud neni videt cara |
541 |
if(position==0) // pokud neni videt cara |
| 519 |
{ |
542 |
{ |
| 520 |
position=old_position; // nastav predchozi pozici |
543 |
position=old_position; // nastav predchozi pozici |
| 521 |
gap++; // pocita, jak dlouho neni videt cara |
544 |
gap++; // pocita, jak dlouho neni videt cara |
| 522 |
} |
545 |
} |
| 523 |
else // pokud je videt cara |
546 |
else // pokud je videt |
| 524 |
{ |
- |
|
| 525 |
gap=0; // vynuluje citani |
- |
|
| 526 |
m=0; // pry svetsovani hulu zataceni |
- |
|
| 527 |
} |
- |
|
| 528 |
if(position>0) // urceni akci pro rizeni, pokud cara je videt |
- |
|
| 529 |
{ |
- |
|
| 530 |
if(position>L1) // cara je hodne vlevo |
- |
|
| 531 |
{ |
- |
|
| 532 |
if(position>L2) // cara je vlevo |
- |
|
| 533 |
{ |
- |
|
| 534 |
if(position>L3) // cara je mirne vlevo |
- |
|
| 535 |
{ |
- |
|
| 536 |
if(position>R1) // cara je mirne vpravo |
- |
|
| 537 |
{ |
- |
|
| 538 |
if(position>R2) // cara je vpravo |
- |
|
| 539 |
{ |
- |
|
| 540 |
if(position>R3) // cara je hodne vpravo |
- |
|
| 541 |
{ |
- |
|
| 542 |
action=6; |
- |
|
| 543 |
} |
- |
|
| 544 |
} |
- |
|
| 545 |
else |
- |
|
| 546 |
{ |
- |
|
| 547 |
action=5; |
- |
|
| 548 |
} |
- |
|
| 549 |
} |
- |
|
| 550 |
else |
- |
|
| 551 |
{ |
- |
|
| 552 |
action=4; |
- |
|
| 553 |
} |
- |
|
| 554 |
} |
- |
|
| 555 |
else |
- |
|
| 556 |
{ |
- |
|
| 557 |
action=3; |
- |
|
| 558 |
} |
- |
|
| 559 |
} |
- |
|
| 560 |
else |
- |
|
| 561 |
{ |
- |
|
| 562 |
action=2; |
- |
|
| 563 |
} |
- |
|
| 564 |
} |
- |
|
| 565 |
else |
- |
|
| 566 |
{ |
- |
|
| 567 |
action=1; |
- |
|
| 568 |
} |
- |
|
| 569 |
} |
- |
|
| 570 |
if(L3<=position>=R1) // cara je uprostred |
- |
|
| 571 |
{ |
- |
|
| 572 |
action=7; |
- |
|
| 573 |
} |
- |
|
| 574 |
switch(action) // reakce na pohyb cary |
- |
|
| 575 |
{ |
- |
|
| 576 |
case 1: // cara je hodne vlevo |
- |
|
| 577 |
rm_speed=(SPD3+position); |
- |
|
| 578 |
lm_speed=(SPD1+position); |
- |
|
| 579 |
r_motor_fwd(rm_speed); |
- |
|
| 580 |
l_motor_bwd(lm_speed); |
- |
|
| 581 |
break; |
- |
|
| 582 |
case 2: // cara je vlevo |
- |
|
| 583 |
rm_speed=(SPD3+position); |
- |
|
| 584 |
r_motor_fwd(rm_speed); |
- |
|
| 585 |
l_motor_off(); |
- |
|
| 586 |
break; |
- |
|
| 587 |
case 3: // cara je mirne vlevo |
- |
|
| 588 |
rm_speed=(SPD3+position); |
- |
|
| 589 |
lm_speed=(SPD2-position); |
- |
|
| 590 |
r_motor_fwd(rm_speed); |
- |
|
| 591 |
l_motor_fwd(lm_speed); |
- |
|
| 592 |
break; |
- |
|
| 593 |
case 4: // cara je mirne vpravo |
- |
|
| 594 |
lm_speed=(SPD3+(position/2)); |
- |
|
| 595 |
rm_speed=(SPD2-(position/2)); |
- |
|
| 596 |
l_motor_fwd(lm_speed); |
- |
|
| 597 |
r_motor_fwd(rm_speed); |
- |
|
| 598 |
break; |
- |
|
| 599 |
case 5: // cara je vpravo |
- |
|
| 600 |
lm_speed=(SPD3+(position/2)); |
- |
|
| 601 |
l_motor_fwd(lm_speed); |
- |
|
| 602 |
r_motor_off(); |
- |
|
| 603 |
break; |
- |
|
| 604 |
case 6: // cara je hodne vpravo |
- |
|
| 605 |
lm_speed=(SPD3+(position/2)); |
- |
|
| 606 |
rm_speed=(SPD2-(position/2)); |
- |
|
| 607 |
l_motor_fwd(lm_speed); |
- |
|
| 608 |
r_motor_bwd(rm_speed); |
- |
|
| 609 |
break; |
- |
|
| 610 |
case 7: // cara je uprostred |
- |
|
| 611 |
l_motor_fwd(SPD4); |
- |
|
| 612 |
r_motor_fwd(SPD4); |
- |
|
| 613 |
break; |
- |
|
| 614 |
} |
- |
|
| 615 |
if((line_sector==LEFT)&&(position==0)) |
- |
|
| 616 |
{ |
- |
|
| 617 |
r_motor_fwd(255); |
- |
|
| 618 |
l_motor_off(); |
- |
|
| 619 |
} |
- |
|
| 620 |
if((line_sector==RIGHT)&&(position==0)) |
- |
|
| 621 |
{ |
547 |
{ |
| 622 |
l_motor_fwd(255); |
548 |
gap=0; // gap je roven nule |
| 623 |
r_motor_off(); |
- |
|
| 624 |
} |
549 |
} |
| - |
|
550 |
calc_error(); |
| - |
|
551 |
calc_regulator(); |
| - |
|
552 |
printf("regulator: %u\r\n",reg_out); |
| 625 |
} |
553 |
} |
| 626 |
} |
554 |
} |
| 627 |
} |
555 |
} |
| 628 |
} |
556 |
} |
| 629 |
|
557 |
|