Okret robota
Cilj
Okrenuti robota za točan kut.
Pokretanje motora
void RobotMaze::moveTurn() {
// Note that this function will execute many times during a single turn.
static uint32_t startedAtMs;
if (setup())
startedAtMs = millis();
int8_t speed = actionMoveTurn->turnByCCW > 180 ? TOP_SPEED : -TOP_SPEED;
motorGroup->go(speed, -speed); // Turn on the motors. In fact, only first
run will do anything as the speeds will not change later.
...
}
Zabilježimo vrijeme prvog pokretanja funkcije. Kasnije će nam poslužiti da prekinemo kretanje, ako predugo traje.
U akciji za okretanje je već zapisano u kojem se smjeru robot okreće.
U skladu s tim odredimo predznak brzine.
Pokrenemo okretanje.
Kraj
void RobotMaze::moveTurn() {
...
if (fabs(mrm_imu->heading() - actionMoveTurn->endAngle) < 5) {
motorGroup->stop();
directionCurrent = actionMove->direction;
// Remember the new heading that IMU following algorithm uses. If no
wall to alignment after turn, this value will be used immediately.
imuLastValid = actionMoveTurn->endAngle;
if (testMode)
end();
else
actionSet(actionDecide); // After rotation, the tile stays
the same, and no mapping will be needed. The new
action is decision what to do next.
}
}
Proučavamo grešku, razliku između ciljnog kuta i trenutnog.
Trenutni daje "heading()", ciljni kut je upisan u akciju, "endAngle".
Ako je ta greška postala manja od 5 (stupnjeva), okret je završen.
U tom slučaju zaustavljamo motore.
Upisujemo u kojem je smjeru sad okrenut robot ("directionCurrent").
Zapamtimo i krajnji kut ("imuLastValid").
Ako je robot u testnom radu, završimo akciju.
Ako nije, postavimo akciju tako da nastavi kretanje u labirintu.
Osigurač
void RobotMaze::moveTurn() {
...
/* A safety measure as timeout elapsed. Most probably, the robot is stuck.
In this example program we will just quit. In a production program
evasive actions should be performed, like turning CW-CCW vigorously, or going
a little forward. We will have to do whatever possible to rotate
the robot in the desired heading. Without success, the exit bonus will
probably be lost in this point.*/
if (millis() - startedAtMs > 5000) {
motorGroup->stop();
print("Turn timeout %i->%i\n\r", startedAtMs, millis());
end(); // End of program.
}
}
Na kraju je osigurač, dio koda koji će se izvršiti ako je nastupio timeout. Robot se predugo okretao.
U tom slučaju se zaustavljaju motori i završava program.
Pokretanje testa
void RobotMaze::moveTurnTest(){
testMode = true;
directionCurrent = Direction::UP;
actionMoveTurn->turnByCCW = 90;
actionSet(actionMoveTurn);
}
Želimo li testirati gornji kod, pokrenimo funkciju "moveTurnTest()".
Upišemo da je način rada testni, da robot ne nastavi ići po labirintu.
Smjer je prema gore, ali mogli bismo napisati i neki drugi.
Upišemo da se okreće za 90 stupnjeva u smjeru suprotnom od kazaljke sata (counter clockwise).
Pokreće se akcija koja izvršava prethodnu funkciju.
Zadatak: usporavanje
Usporite okretanje pred kraj okreta.
Primjedbe
Projekt "Uvod u robotiku" sufinanciran je iz Europskog socijalnog fonda, poziv "Jačanje kapaciteta organizacija civilnoga društva za popularizaciju STEM-a".
Relevantne stranice:
Sadržaj vježbe za virtualne radionice isključiva je odgovornost Hrvatskog društva za robotiku.