Crtanje zidova
Cilj
Ispisati zidove na 8x8 displeju.
Brisanje
void RobotMaze::wallsDisplay() {
/* Contrary to the method used mostly here, this bitmap is not stored beforehand. There are too many combinations and that will not be feasible.
So, it will be built on-line.*/
// Clear red and green dots.
uint8_t red[8];
uint8_t green[8];
for (uint8_t i = 0; i < 8; i++)
red[i] = 0, green[i] = 0;
...
}
U programu "mrm-robot-maze.cpp" postoji funkcija "wallsDisplay()".
Proučimo ju.
Na početku deklariramo 2 polja s po 8 elemenata: "red" i "green";
U njih ćemo upisivati točke koje želimo upaliti na 8x8 displeju.
Gornji red
void RobotMaze::wallsDisplay() {
/* Contrary to the method used mostly here, this bitmap is not stored beforehand. There are too many combinations and that will not be feasible.
So, it will be built on-line.*/
// Clear red and green dots.
uint8_t red[8];
uint8_t green[8];
for (uint8_t i = 0; i < 8; i++)
red[i] = 0, green[i] = 0;
//2 top sensors form top pixels' row.
if (distance(rToM(Direction::UP), false) < NO_WALL_DISTANCE)
red[0] |= 0b00001111;
if (distance(rToM(Direction::UP), true) < NO_WALL_DISTANCE)
red[0] |= 0b11110000;
...
}
Funkcija "rToM()" prebacuje koordinatni sustav robota u koordinatni sustav labirinta.
Nećemo ju sad proučavati. Ona omogućava da uvijek gornji red displeja ispisuje gornji zid.
Uočite da robot može biti okrenut na 4 načina i da za svaki treba uzeti drugu stranu robota koja mjeri "gornji" zid.
Funkcija "distance()", u varijanti za robota za labirint, ima dva argumenta.
Prvi je smjer.
Drugi je "true", ako je to prvi senzor u smjeru suprotnom od kazaljke na satu za tu stranicu.
"false" ako je drugi.
Kad "if" ustanovi da je izraz "true" (zid je ispred tog senzora), doda jedinice u 4 bita bajta koji je u prvom redu (gornji red displeja).
Operacija je na bitovima: "|=", što znači da će izraz s lijeve strane ostati isti, osim što će se jedinice s desne strane prekopirati na odgovarajuća mjesta lijeve strane.
Na taj način će upaliti 4 LED diode ispred danog senzora.
Lijeva kolona
void RobotMaze::wallsDisplay() {
/* Contrary to the method used mostly here, this bitmap is not stored beforehand. There are too many combinations and that will not be feasible.
So, it will be built on-line.*/
// Clear red and green dots.
uint8_t red[8];
uint8_t green[8];
for (uint8_t i = 0; i < 8; i++)
red[i] = 0, green[i] = 0;
//2 top sensors form top pixels' row.
if (distance(rToM(Direction::UP), false) < NO_WALL_DISTANCE)
red[0] |= 0b00001111;
if (distance(rToM(Direction::UP), true) < NO_WALL_DISTANCE)
red[0] |= 0b11110000;
//2 left sensors form left row.
if (distance(rToM(Direction::LEFT), false) < NO_WALL_DISTANCE)
for (uint8_t i = 0; i < 4; i++)
red[i] |= 0b10000000;
if (distance(rToM(Direction::LEFT), true) < NO_WALL_DISTANCE)
for (uint8_t i = 4; i < 8; i++)
red[i] |= 0b10000000;
...
}
Na sličan način mjerimo lijevu stranu.
Ovaj put ne možemo mijenjati samo jedan element polja, nego ih moramo svih 8, jer se lijeva kolona proteže kroz najljevije bitove svih 8 bajtova (cijelo polje).
Ovo činimo u "for" petlji, opet koristeći istu bit-operaciju i na taj način palimo po 4 LEDa u gornja 4 ili donja 4 reda.
Preostale stranice
void RobotMaze::wallsDisplay() {
/* Contrary to the method used mostly here, this bitmap is not stored beforehand. There are too many combinations and that will not be feasible.
So, it will be built on-line.*/
// Clear red and green dots.
uint8_t red[8];
uint8_t green[8];
for (uint8_t i = 0; i < 8; i++)
red[i] = 0, green[i] = 0;
//2 top sensors form top pixels' row.
if (distance(rToM(Direction::UP), false) < NO_WALL_DISTANCE)
red[0] |= 0b00001111;
if (distance(rToM(Direction::UP), true) < NO_WALL_DISTANCE)
red[0] |= 0b11110000;
//2 left sensors form left row.
if (distance(rToM(Direction::LEFT), false) < NO_WALL_DISTANCE)
for (uint8_t i = 0; i < 4; i++)
red[i] |= 0b10000000;
if (distance(rToM(Direction::LEFT), true) < NO_WALL_DISTANCE)
for (uint8_t i = 4; i < 8; i++)
red[i] |= 0b10000000;
// 2 bottom sensors.
if (distance(rToM(Direction::DOWN), false) < NO_WALL_DISTANCE)
red[7] |= 0b11110000;
if (distance(rToM(Direction::DOWN), true) < NO_WALL_DISTANCE)
red[7] |= 0b00001111;
// Finally, 2 right sensors.
if (distance(rToM(Direction::RIGHT), false) < NO_WALL_DISTANCE)
for (uint8_t i = 4; i < 8; i++)
red[i] |= 0b00000001;
if (distance(rToM(Direction::RIGHT), true) < NO_WALL_DISTANCE)
for (uint8_t i = 0; i < 4; i++)
red[i] |= 0b00000001;
...
}
Na isti način ispišemo donju i desnu stranicu.
Ispis
void RobotMaze::wallsDisplay() {
/* Contrary to the method used mostly here, this bitmap is not stored beforehand. There are too many combinations and that will not be feasible.
So, it will be built on-line.*/
// Clear red and green dots.
uint8_t red[8];
uint8_t green[8];
for (uint8_t i = 0; i < 8; i++)
red[i] = 0, green[i] = 0;
//2 top sensors form top pixels' row.
if (distance(rToM(Direction::UP), false) < NO_WALL_DISTANCE)
red[0] |= 0b00001111;
if (distance(rToM(Direction::UP), true) < NO_WALL_DISTANCE)
red[0] |= 0b11110000;
//2 left sensors form left row.
if (distance(rToM(Direction::LEFT), false) < NO_WALL_DISTANCE)
for (uint8_t i = 0; i < 4; i++)
red[i] |= 0b10000000;
if (distance(rToM(Direction::LEFT), true) < NO_WALL_DISTANCE)
for (uint8_t i = 4; i < 8; i++)
red[i] |= 0b10000000;
// 2 bottom sensors.
if (distance(rToM(Direction::DOWN), false) < NO_WALL_DISTANCE)
red[7] |= 0b11110000;
if (distance(rToM(Direction::DOWN), true) < NO_WALL_DISTANCE)
red[7] |= 0b00001111;
// Finally, 2 right sensors.
if (distance(rToM(Direction::RIGHT), false) < NO_WALL_DISTANCE)
for (uint8_t i = 4; i < 8; i++)
red[i] |= 0b00000001;
if (distance(rToM(Direction::RIGHT), true) < NO_WALL_DISTANCE)
for (uint8_t i = 0; i < 4; i++)
red[i] |= 0b00000001;
// Send the result to mrm-8x8a.
mrm_8x8a->bitmapCustomDisplay(red, green);
}
Zadnja naredba šalje polja u 8x8 displej, ispisujući ih.
Pokretanje programa
void RobotMaze::loop() {
wallsDisplay();
}
Program pokrenite iz funkcije "loop()".
Zadatak: crtanje
Iscrtajte na isti način crvenom bojom bliske zidove, a zelenom daleke.
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.