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.
*/
class ActionLineFollow : public ActionBase {
	void perform(){ ((RobotLine*)_robot)->lineFollow(); }
public:
	ActionLineFollow(RobotLine* robot) : 
		ActionBase(robot, "lnf", "Line follow", 1) {}
};
Vratimo se u datoteku "mrm-robot-line.h". Lijevo je deklaracija klase "ActionLineFollow".

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.
  • ActionLineFollow je ime koje proizvoljno biramo. "Rotkvica" bi bilo jednako dobro, ali mi smo izabrali nešto što nas podsjeća na našu funkciju. Budući da je ime funkcije "lineFollow", dodali smo "Action" na početak i dobili ActionLineFollow.
  • 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.
Ako pogledamo što imamo u meniju, vidjet ćemo kamo idu "lnf" i "Line follow".

Meni se automatski formira prema upisanim akcijama.

4. Preddefinicija akcije

class ActionLineFollow;
U istoj datoteci, "mrm-robot-line.h" se na početku nalazi linija s lijeve strane. Zašto, to nećemo detaljno objašnjavati.

Ukratko, moramo najaviti našu akciju jer će se pozivati u kodu prije nego što se dođe do njene deklaracije pri kraju datoteke.

5. Prijava akcije robotu

	ActionLineFollow* actionLineFollow;
U istoj datoteci, "mrm-robot-line.cpp", nedaleko iza prethodne linije, se nalazi kod lijevo. Opet u grubim crtama: uključuje našu novostvorenu akciju u robota.

actionLineFollow je također proizvoljno ime. Mi smo se odlučili za isto kao ActionLineFollow, samo smo prvo slovo promijenili u malo.

Za one koji se više razumiju u programiranje: ActionLineFollow je klasa, actionLineFollow je pointer na objekt.

4. Uključivanje akcije

actionLineFollow = new ActionLineFollow(this);
Otvorimo "mrm-robot-line.cpp". Blizu početka datoteke se nalazi programska linija lijevo. Držat ćemo se i dalje taktike da ne objašnjavamo puno zašto je takva.

Ne pitate puno, upišite i radit će.

Ovo je bilo 6. i zadnje mjesto u kojem treba mijenjati kod za upis nove akcije.

Postojeće akcije

	// All the actions will be defined here; the objects will...
	actionEvacuationZone = new ActionEvacuationZone(this);
	actionLineFollow = new ActionLineFollow(this);
	actionObstacleAvoid = new ActionObstacleAvoid(this);
	actionRCJLine = new ActionRCJLine(this);
	actionWallFollow = new ActionWallFollow(this);
	actionStop = new ActionStop(this);
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, 5. za praćenje zida.

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 ActionLineFollow. Dodajte točno takav kod za vašu proizvoljnu akciju.

Program

void RobotLine::lineFollow() {
	// Ovdje ide kod za praćenje linije 
	...

	if (front() < 100)
		actionSet(actionObstacleAvoid);
	
	...
}

void RobotLine::obstacleAvoid(){
	// Kod za obilazak prepreke
	...

	actionSet(actionLineFollow);
}
Ž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(actionRCJLine, 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 actionRCJLine u actionLineFollow, 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.