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

Greške

Cilj

Mjeriti točno.

Deklaracija funkcije

     
/** Front distance in mm. Warning - 
	the function will take 
	considerable amount of time to 
	execute if sampleCount > 0!
@param sampleCount - Number or readings. 
	40% of the readings, with 
	extreme values, will be discarded 
	and the rest will be averaged. 
	Keeps returning 0 till all the 
	sample is read. If sampleCount 
	is 0, it will not wait but will 
	just return the last value.
@param sigmaCount - Values outiside sigmaCount 
	sigmas will be filtered 
	out. 1 sigma will leave 68% of 
	the values, 2 sigma 95%, 
	3 sigma 99.7%. Therefore, lower 
	sigma number will remove more 
	errornous readings.
@return - distance in mm
*/
     uint16_t 
     front(uint8_t sampleCount = 0, uint8_t sigmaCount = 1);
Dosad se nismo previše bavili datotekom zaglavljima, datotekom "mrm-robot-line.h". Između ostalog, tu se nalaze deklaracije funkcija, njihovi potpisi.

Bez zalaženja u detalje, opišimo ukratko o čemu se radi.

Zadnji red je sama deklaracija funkcije:
  • uint16_t je tip podatka koji funkcija vraća van, rezultat mjerenje. U našem slučaju je to jedan tip cijelog broja, srednje veličine, broj milimetara.
  • front je ime funkcije.
  • uint8_t je tip prvog ulaznog parametra, vrlo mali cijeli broj.
  • sampleCount je ime prvog parametra.
  • = 0 je vrijednost koju će parametar poprimiti, ako korisnik ne upiše neki drugi.
Prije potpisa je komentar, dio koda koji se ne izvršava: /** Front distance in mm.... U njemu je opisano što funkcija radi, koji su ulazni parametri i koji je rezultat.

Mjeri jednom

void RobotLine::loop() {
	print("%i\n\r", front());
}
Pogledajmo rezultate poznatog koda s lijeve strane.

Senzor će mjeriti udaljenost.

Budući da u zagradi nema broja, parametar će poprimiti svoju implicitnu vrijednost: 0.

Rezultat će biti posljednja vrijednost udaljenosti, koja je stigla iz senzora, i bit će vraćena trenutno.

Na ovaj smo način uvijek dosad koristili funkcije za mjerenje udaljenosti.

Rezultati jednostrukog mjerenja

Rezultati su relativno ujednačeni, osim predzanjeg. Očito se dogodila neka greška i senzor je krivo očitao udaljenost.

Je li to vanjsko svjetlo, neravnina na podu ili nešto drugo, nije bitno - senzori nisu 100% točni.

Ako u Rescue Maze labirintu odlučujemo ima li zida ispred nas, i uzmemo baš to mjerenje, rezultati će biti katastrofalni. Robot će lupiti u zid i izgubiti se u labirintu.

S druge strane, ako pratimo zid, jedna će greška u nizu dobrih rezultata biti nebitna, neprimjetni trzaj robota, koji će odmah biti ispravljen sljedećim mjerenjem.

Kako riješiti situaciju kad trebamo jedno točno mjerenje? Pogledajmo dalje.

Mjeri više puta

void RobotLine::loop() {
	print("%i\n\r", front(10));
}
Promijenimo kod, dodavši argument 10.

Pogledajmo, u prvom odjeljku, koje je značenje prvog parametra, sampleCount.

To je broj mjerenja. Funkcija će izvršiti 10 mjerenja i vratiti prosjek.

Sam prosjek bi bio bolji od 2000, ali 2000 bi ga kvario. Zato funkcija ima ugrađenu dodatnu funkcionalnost, izbacivanje svih mjerenja koja jako odstupaju.

Nećemo dalje zalaziti u statistiku, možemo samo navesti da će biti izbačeni svi udaljeniji od jedne standardne devijacije od prosjeka. Na ovaj će način nestati problematični 2000, kao što bi bila izbačena zalutala nula.

Rezultati višestrukog mjerenja

Ekstremi su nestali i rezultati su jednolikiji.

Ima li ova metoda neku manu? Ima. Znatno je sporija. 10 mjerenja će u ovom senzoru trajati oko 0.3 sekunde, što je znatno presporo za npr. praćenje zida.

Recimo da želimo detektirati kuglu pored robota. Način kako pomiriti 2 tipa mjerenja je:
  1. Ići robotom naprijed i stalno mjeriti s, npr., frontLeft() (jednostruka mjerenja). frontLeft() mjeri udaljenost prednjim lijevim lidarom.
  2. Ako dobijemo malu vrijednost, to znači da je ili greška ili je stvarno kugla.
  3. Stanemo nakratko, npr. 0.1 sec. Ovo je bitan korak. Ne zastanemo li, robot će se nekontrolirano gibati 0.3 sekunde, dok traju mjerenja.
  4. Izmjerimo pomoću frontLeft(10).
  5. Ako je i dalje mala vrijednost, to je kugla.
  6. Ako nije, bila je greška i idemo dalje.

Zadatak: test.

Testirajte ovaj način mjerenja u nekom od programa koji ste prije koristili.

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.