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

Prepreka

Cilj

Cilj je zaobići prepreku na liniji. Naučit ćemo kako programirati složenije kretanje robota u definiranom nizu radnji.

Cilj

void RobotLine::rcjLine() {
	lineFollow();
	if (front() < 100)
		obstacleAvoid();
}

Napravimo arenu koja se sastoji od ravne crte na kojoj je prepreka, npr. neki valjak promjera oko 15-20 cm. Zadatak je pratiti crtu, obići prepreku i stati kad se nađe crta iza prepreke.

Kao i u prethodnom primjeru, počnimo program funkcijom "rcjLine()". Sastoji se od 2 dijela.
  1. "linefollow()" - pozivamo funkciju koja prati liniju.
  2. "if" - ako prednji lidar vidi prepreku na udaljenosti manjoj od 100 mm, poziva se funkcija "obstacleAvoid()" u kojoj ćemo programirati obilazak oko prepreke.
Ponovimo još jednom, "rcjLine()" se izvršava tisuće puta. Za očekivati je da će puno puta biti izvršen "lineFollow()", prije nego što se pozove "obstacleAvoid()".

Praćenje linije

void RobotLine::lineFollow() {
	if (line(8))
		go(-90, 90);
	else if (line(0))
		go(90, -90);
	else if (line(5))
		go(10, 90);
	else if (line(3))
		go(90, 10);
	else
		go(60, 60);
}

"rcjLine()" poziva "lineFollow()" funkciju, zadatak koje je praćenje linije.

Kako smo već prije napisali taj kod, prepišimo ga ovdje.

Obilazak

void RobotLine::obstacleAvoid() {
	// Stop
	stop();
	delayMs(2000);
	print("Prepreka");

	// Okret
	go(50, -50);
	uint32_t lastLineMs = millis();
	while (front() < 200 || frontLeft() < 200 ||
			millis() - lastLineMs < 200){
		noLoopWithoutThis();
		if (lineAny())
			lastLineMs = millis();
	}
	stop();
	print("Okrenut");
	delayMs(2000);

	// Okret
	while(!lineAny()){
		if (front() < 200 || frontLeft() < 200)
			go(50, 50);
		else
			go(20, 80);
		noLoopWithoutThis();
	}
	stop();
	print("Naišao");
	delayMs(2000);
	go(70, 10);
	delayMs(500);
	print("Linija");
}

Preostao je još najtežio dio, funkcija za obilazak oko prepreke, "obstacleAvoid()". Proučimo 3 bloka naredbi.
  • Prvi blok zaustavlja robota, ispisuje "Stop" i pričeka 2 sec.

    Ovaj je blok potpuno nepotreban za izvršavanje zadatka, ali nam daje primjer kako polako proučavati što robot čini. Na više mjesta u programu možemo zaustaviti motore, napraviti pauzu i ispisati na mobitel što se dogodilo. Na taj je način puno lakše naći grešku.

    Kad je program gotov, ovi se dijelovi mogu izbaciti.
  • Drugi blok okreće robota sve dok više ne vidi ni crtu ni prepreku ijednim lidarom. Želimo ga pozicionirati za početak obilaska. Ovaj je blok djelomično potreban jer ga je moguće integrirati sa sljedećim. Slijede detalji.

    Prvo pokrenemo motore u suprotnim smjerovima kako bi se robot okretao u mjestu.

    Slijedi "while", koji će se izvršavati sve dok je uvjet u zagradama istinit, a koji je "nešto je na manje od 200 mm naprijed ili je nešto na manje od 200 mm lijevo ili je robot u posljednjih 200 ms bio na crti". Znači, motori i dalje rade, robot se okreće, sve dok vidi prepreku ili crtu.

    Da je bio posljednjih 200 ms na crti gledamo tako da zapamtimo svaki put kad je vidio crtu (u varijablu "lastLineMs" i onda u uvjetu gledamo je li prošlo 200 ms od tog događaja (razlika sadašnje vremena i zapamćenog je ne više od 200 ms). Zašto tako? Zato što mogu postojati područja između 2 tranzistora senzora, na kojima se ne čita crta. Ne želimo da okret stane među tranzistorima, nego tek kad je zadnji napustio liniju.

    Zapamtimo, svaka petlja, kao što je i "while", u sebi mora imati naredbu "noLoopWithoutThis()", koja izmjenjuje poruke sa senzorima i motorima.

    Prepreke više nema ispred nas, zaustavljamo motore. Slično kao u prvom bloku, ispisujemo poruku na mobitel i pričekamo 2 sekunde.
  • Treći blok je obilazak.

    Počinjemo s "while" petljom, koja će se odvijati sve dok je uvjet ispunjen, a taj je da robot ne vidi crtu.

    "if" proučava vidi li robot prepreku. Ako vidi, ide naprijed.

    Ako ne vidi, lagano skreće, idući naprijed.

    Na kraju opet zaustavimo motore, ispišemo poruku i pričekamo.

Video

Kratki video pokazuje robota koji izvršava gornji program.

Zadatak: oko prepreke.

Programirajte robota da ne stane na crti iza prepreke, nego da se vrati na početnu i nju nastavi pratiti.

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.