Realtidssystem med OSEK och Lego Mindstorms NXT

Bakgrund

Ännu en gång har vi fått leka med Lego på skoltid, första gången var i en tidigare kurs i Distribuerade System för cirka ett och ett halvt år sedan. Senast så utförde vi projektet med hjälp av Lejos NXT och Java, den här gången använde vi nxtOSEK och programmeringsspråket C.

Vår uppgift var att genomföra lite småuppgifter med en robot som vi konstruerade och avsluta med att göra en robot som följer ett streck på marken. I och med att det är en kurs i realtidssystem så måste det finnas något moment av realtid i det hela, så samtidigt som den ska följa ett streck ska den hela tiden avläsa avståndet till en robot som kommer köra framför och hålla 20cm avstånd.

OSEK är en implementation av ett RTOS (real time operating system) som är skapat av ett samarbete av tyska biltillverkare. NXT-implementationen hjälper sedan till med kopplingen mot hårdvaran, dvs sensorer och motorer.

Programmen skrivs i C och har en tillhörande .OIL-fil som innehåller en beskrivning av systemet med alla events, timers osv. Du använder sedan en rad verktyg för att kompilera ihop dessa och få in den på din Lego Mindstorms NXT.

Vår uppgift

Den ska som sagt följa ett streck och samtidigt hålla ett konstant avstånd till roboten framför. Uppgiften var hyfsat enkel att genomföra när vi fått klart för oss hur nxtOSEK fungerade, kommit ihåg hur API:erna till roboten fungerade och vilka saker man ska tänka på.

För att nämna några av utmaningarna vi har haft:

  • Hur definieras mörker?
  • Hur hanterar man en bana som har kurvor? (Skarpa och/eller långa?)

Algoritm

Vår algoritm för att hålla oss på banan är mycket enkel och bygger på att vi har en fast arm som vår sensor sitter fast på.

  1. Vi har ett task (LightTask) som läser av ljuset mot backen
  2. Har ljuset ändrats sedan sist? Isf, läs av och kolla om den är högre eller lägre
  3. Är det ljust så ändra så ena hjulet (hjul 1) går exempelvis 50 och det andra hjulet (hjul 2) går 20
  4. Är det mörkt så ändra så hjul 1 går i 20 och hjul 2 går i 50.
  5. Börja om

Vi har gjort lite justeringar på detta så att den kör med en faktor när den räknar ut hur fort den ska köra. Detta för att den ska ha möjlighet att “smyga” framåt om det är ganska nära.

Demonstration

Källkod

Finns på GitHub

Runestone 2011: WALL-E

Uppdaterad 2011-03-31 med källkod och lite mer information

Vi har under de senaste 7 veckorna arbetat med ett projekt i en kurs som heter “Distribuerade system med projekt”. Vår projektbeskrivning var i korta drag detta:

“You are to design and implement a complete software system that provides Internet access to semi-autonomous soft-realtime robot.”

Då hälsar vi WALL-E välkommen!


WALL-E med orginalet

Introduktion

WALL-E är konstruerad i Lego, den är ifrån Lego Mindstorms NXJ och omflashad med LeJOS för att vi ska kunna köra Java på den.

Vårt projekt krävde att vi skulle kunna styra roboten från vilken klient som helst, därför valde vi att köra Java RMI mellan våra olika system.


System diagram

Klienten


Windowsklienten

Klienten är skriven som en Java-applet och kan därför köras ifrån alla möjliga operativsystem, de vi har testat är Linux, Mac OS X samt Windows 7. Den ansluter till ett externt ip som “robotservern” körs på.

 


Dataflöde – Manuellt läge

Ovan ser ni även hur flödet ser ut när vi skickar enskilda kommandon ifrån det manuella läget i klienten.

Autopiloten

I projektet ingick även att vi ska samarbeta med en annan robot i Sverige och söka av ett rum. Vi satte därför upp ytterligare en service som sköter kartan, den körs via RMI och använder sig av en MySQL-databas som robotarna sedan kommunicerar med via interfaces. Kartan genereras sedan med hjälp av GD och PHP och skickas sedan till klienten.

Denna del är den som tagit överlägset längst tid, vår autopilot gör väldigt komplicerade beslut på egen hand. Bra jobbat Julius, Erik och Henrik!

 


Dataflöde – Autopilot

När roboten körs i autopilot-läget så gör den inga beslut själv, alla beslut sker genom robotservern och den i sin tur kontrollerar hela tiden med kartservern vilka ytor som är lediga/upptagna.

Kartläggningsalgoritm

  • Allting baseras på en “tile map” för att förenkla algoritmen.
  • Den använder en egenkomponerad Dijkstra-algoritm med viktbaserad beslutshantering för all kartläggning.
  • Den använder även ett poängsystem för att bestämma vilken del av kartan den ska besöka härnäst.
  • Varje gång den kollar något så kollar den detta tre gånger, med små vinkelskiftningar, för att förbättra avläsningen.

Demonstration

Detta är en 40 sekunder lång demonstration, där WALL-E har kört igenom en hinderbana och håller på att slutföra kartan. Håll koll på den övre högra delen på kartan på laptopen där den monterar ut väggarna allt eftersom den flyttar på sig (jag ber om ursäkt att ljudet hackar i videon).

Källkod

Finns i Runestone2011 på Github.

Tyvärr verkar den ha tappat all commit-historik när jag flyttade över det, det var lite trist. För en fullständig historik av commitsen så har jag en lokal kopia lagrad med all information.

Så här i efterhand så är vi väl inte särskilt nöjda med kodresultatet, vi hade nog gjort om det mesta på ett “bättre” sätt.

Min guide till Whilenium

I en projektkurs den här perioden “Operativsystem” har vi skapat ett ganska grundläggande operativsystem vid namn “Whilenium”, vi har kört det genom Simics med emulering av MIPS. Simics beskrivs så här av Wikipedia:

Simics is a full-system simulator used to run unchanged production binaries of the target hardware at high-performance speeds. Simics was originally developed by the Swedish Institute of Computer Science (SICS), and then spun off to Virtutech for commercial development in 1998.

Vårt operativsystem har i korta drag följande funktioner:

  • Skapa flera processer
  • Köra processerna samtidigt
  • Skicka och ta emot I/O

Däremellan är det väldigt mycket saker varje process ska kunna göra (och inte göra), exempelvis ska processerna kunna avsluta varandra, inte dela minne med varandra etc.

Det har varit en väldigt intressant kurs som byggde på en tidigare väldigt teoretisk kurs med mycket praktiskt arbete. Det som var svårast var nog att förstå kopplingen mellan C och Assembler. Därefter stötte vi på en del problem vad gäller schemaläggningen av processer samt få till systemanropen för att hoppa mellan “User-space” och “Kernel-space”

För de som är intresserade kan ni ladda ner källkoden och se (den väldigt korta) dokumentationen här. Ni kan även besöka vårt projekt på Google Code vårt projekt på Github.

Källkoden har en del struktureringsbrister och är inte helt komplett dokumenterad, det hann vi inte med i slutspurten av projektet.


Tack till Jesper Friberg, Oskar Wirén och Daniel Lervik för ett bra arbete!