Hrvatsko društvo za robotiku - Uvod u robotiku - vježbe

Akcije

Cilj

Kako naučiti program da se kreće kroz razna "stanja" - koja opisuju logičke cjeline okoline.

Dijagram toka

Uzmimo kao primjer Robocup Rescue Line i opišimo ga dijagramom toka - grafičkim prikazom stanja robota i puteva prelaska iz jedno stanja u drugo.

Pravokutnici sa zaobljenim kutovima su stanja.

Deltoidi predstavljaju grananja u programu, mjesta gdje izvršavanje koda može krenuti u 2 razna smjera, ovisno o tome je li uvjet ispunjen ili nije.

Sva su stanja povezana strelicama koje predstavljaju promjene iz jednog stanja u drugo, uz prolazak kroz grananje ili ne.

Pravokutnike uobičajeno opisujemo funkcijama. Funkcije smo već koristili, uobičajeno jednu: loop().

Kao što smo vidjeli u prethodnoj vježbi, dolazi do problema kad više funkcija trebamo povezati u program. Može se napraviti jednostavno i dugoročno loše ili na dobar i kompliciran način. Ovo potonje će biti predmet trenutne vježbe.

Funkcija uobičajeno ima u sebi niz naredbi. Njenim se sadržajem u ovoj vježbi nećemo baviti.

Nažalost nam C++ neće biti prijatelj jer traži nepotrebno složeno programiranje.

Pogledajmo dalje jedan primjer akcije, u našem dijagramu "Prati liniju".

1. Deklaracija funkcije

	/** Follow a RCJ line.
	*/
	void lineFollow();
Svaka akcija ima svoju funkciju, niz naredbi koji stvarno izvšava potrebnu radnju. U C++ se funkcija definira u 2 datoteke, .h (zaglavlja) i .cpp (izvršni kod). U našem slučaju su to "mrm-robot-line.h" i "mrm-robot-line.cpp".

U zaglavlju se samo prijavi kako funkcija izgleda: vraća li kao rezultat neki podatak i kakav, koje joj je ima i koje parametre koristi.

Funkcije za akcije ne smiju vraćati nikakav podatak, niti imati parametre, pa im je oblik uvijek kao u kodu lijevo, samo će ime biti drugačije. U našem je slučaju "lineFollow".

2. Definicija funkcije

/** Follow a RCJ line.
*/
void RobotLine::lineFollow() {
	...
}
Otvorimo sad "mrm-robot-line.cpp" datoteku i nađimo kod lijevo. Umjesto "..." će biti neki kod, koji nas u ovom času ne zanima. To je program koji vodi robota po liniji.

Bitno je da je potpis funkcije isti kao i u "mrm-robot-line.h", jedino će sad umjesto ";" biti vitičaste zagrade i unutra proizvoljni kod. Dodatno, ispred imena funkcije ("lineFollow") piše "RobotLine::".

Na taj način se ukazuje C++-u da je ova funkcija dio klase "RobotLine". Nemojte previše razmišljati o ovome, nego samo prihvatite da se to mora napisati.

Završili smo s funkcijom, koja može poslužiti za akciju, ali i za bilo što drugo. To je standardni način pisanja nove C++ funkcije.

3. Akcija

/** Follow a line.
*/
actions->insert({"lnf", new ActionRobotLine(this, "Line follow", 1, Board::BoardId::ID_ANY, NULL, &RobotLine::lineFollow)});
Otprilike na početku "mrm-robot-line.cpp" datoteke je definicija naše akcije.

Nećemo ni pokušati objasniti zašto piše sve što piše. Zasad to prihvatimo kao činjenicu jer bi nas objašnjavanje odvelo predaleko. Objasnimo samo dijelove koje možete mijenjati.
  • lineFollow je ime naše funkcije.
  • lnf je proizvoljna, troslovna kratica, kojom pokrećemo akciju iz menija (Arduino monitor ili terminal na mobitelu).
  • Line follow je proizvoljno ime, koje se ispisuje u meniju, odmah do kratice, koje opisuje značenje kratica.
  • 1 je meni u kojem će se ispisivati korisniku. Meni br. 1 je osnovni meni.
  • NULL je znak koji će se ispisivati na 8x8 LED displeju prilikom izvršavanja. NULL znači da nema promjene, ali mogu se staviti razni drugi znakovi ili tekstovi. Probajte npr. "signTest".
Ako pogledamo što imamo u meniju, vidjet ćemo kamo idu "lnf" i "Line follow".

Meni se automatski formira prema upisanim akcijama.

4. Uključivanje akcije

actionSet("lnf");
Otvorimo "mrm-robot-line.cpp". Nađite u kodu funkciju void RobotLine::rcjLine() i vidjet ćete kako je ova naredba upotrijebljena da robot počne pratiti liniju.

Postojeće akcije

	actions->insert({"eva", new ActionRobotLine(this, "Evacuation zone", 1, Board::BoardId::ID_ANY, NULL, &RobotLine::evacuationZone)});
	actions->insert({"lnf", new ActionRobotLine(this, "Line follow", 1, Board::BoardId::ID_ANY, NULL, &RobotLine::lineFollow)});
	actions->insert({"obs", new ActionRobotLine(this, "Obstacle avoid", 0, Board::BoardId::ID_ANY, NULL, &RobotLine::obstacleAvoid)});
	actions->insert({"rcj", new ActionRobotLine(this, "RCJ line", 1, Board::BoardId::ID_ANY, NULL, &RobotLine::rcjLine)});
	actions->insert({"str", new ActionRobotLine(this, "Stop motors", 1, Board::BoardId::ID_ANY, NULL, &RobotLine::stop)});
	actions->insert({"msh", new ActionRobotLine(this, "Motor short test", 1, Board::BoardId::ID_ANY, NULL, &RobotLine::motorShortTest)});
	actions->insert({"lo5", new ActionRobotLine(this, "loop5", 8, Board::BoardId::ID_ANY, signTest, &RobotLine::loop5)});
	actions->insert({"lo6", new ActionRobotLine(this, "loop6", 8, Board::BoardId::ID_ANY, signTest, &RobotLine::loop6)});
	actions->insert({"lo7", new ActionRobotLine(this, "loop7", 8, Board::BoardId::ID_ANY, signTest, &RobotLine::loop7)});
	actions->insert({"lo8", new ActionRobotLine(this, "loop8", 8, Board::BoardId::ID_ANY, signTest, &RobotLine::loop8)});
	actions->insert({"lo9", new ActionRobotLine(this, "loop9", 8, Board::BoardId::ID_ANY, signTest, &RobotLine::loop9)});
Pogledajte kod oko posljednjeg mjesta na kojem smo bili u kodu i vidjet ćete ostale akcije vezane za Rescue Line.

1. je za kretanje u sobi evakuacije, 3. za obilazak prepreke na crti, 4. za samo pokretanje programa, itd.

Možete koristiti ove akcije ili napraviti nove. Ako koristite postojeće, slobodno obrišite sav kod u njihovim funkcijama.

Nove napravite na isti način kako je gore definirana akcija u našem primjeru. Dodajte točno takav kod za vašu proizvoljnu akciju.

Program

void RobotLine::lineFollow() {
	// Here goes the line tracking code
	...

	if (front() < 100)
		actionSet("obs");
	
	...
}

void RobotLine::obstacleAvoid(){
	// Obstacle bypass code
	...

	actionSet("lnf");
}
Želimo li pokrenuti akciju programski, koristimo naredbu "actionSet", koja mijenja akciju u novu.

Kako završiti sve akcije? Već znamo, to je naredba "end()".

Tipkalo

	// Set buttons' actions.
	mrm_8x8a->actionSet(actionFind("rcj"), 0); // Button 1 starts...
Na početku "mrm-robot-line.cpp" su 4 linije, od kojih neke mogu biti komentirane ("//") na početku. Izgledaju kao linija lijevo.

Svaka definira akciju koja može biti zadana jednom od 4 tipkala.

Promijenite li actionFind("rcj") u actionFind("lnf"), tipka 1 će pokretati praćenje linije.

Svakom tipkalu možete pridružiti svoju akciju.

Zadatak: program za robota.

Proučite program za robota za labirint i pogledajte kako se u praksi koriste akcije.

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.