Robotopgaver 2006

From ImageWiki

Jump to: navigation, search

Denne side indeholder de øvelser der skal læses p� kurset Robot Eksperimentarium 2006.

Contents

Øvelse 1: Hello, World

I denne opgave skal robotten køre lidt rundt. Hovedformålet med denne opgave er at blive bekendt med Hardware-laget i ERSP, men i praksis er fokus p� kørsel.

Når programmer skal afvikles p� robotten er proceduren som følger

  1. Oversæt programmet p� en maskine med ERSP installeret.
  2. Forbind robotten til maskinen via USB kablerne og tænd for robotten.
  3. Kør programmet.

For at f� adgang til diverse enheder p� robotten skal hardware-laget initialiseres, hvilket sker med følgende C++ kode:

Evolution::ResourceManager *resource_manager;
Evolution::Result result;
resource_manager = new Evolution::ResourceManager( NULL, &result ); 
Evolution::IResourceContainer *resource_container;
result = resource_manager->get_resource_container( 0, &resource_container );

Herefter kan diverse interfaces tilgås vha resource_container. Variablen result fortæller om den ønskede operation lykkedes. I praksis bør man derfor altid undersøge om denne antager værdien Evolution::RESULT_SUCCESS.

Delopgave 1: Simple bevægelser

Først skal robotten køre en kvadratisk rute. Dvs. at robotten 4 gange skal køre 1 meter ligeud og derefter dreje 90 grader. I denne forbindelse skal motorkontrollen Evolution::IDriveSystem initialiseres. Dette gøres med følgende C++ kode:

Evolution::IDriveSystem *driver;
result = resource_container->obtain_interface(Evolution::NO_TICKET, "drive", 
            Evolution::IDriveSystem::INTERFACE_ID, (void**) &driver);

Herefter kan funktionerne move_delta og turn_delta tilgås gennem objektet driver. For detaljer om hvorledes disse funktioner virker henvises der til dokumentationen til IDriveSystem og ERSP tutorialen afsnit 2.6.4 (04-drive-system).

Hint 1: I starten anbefales det at benytte de projektskabeloner, der stilles til rådighed p� siden ERSP Templates.

Hint 2: Som standard vil robotten undg� at køre ind i objekter. Dette er typisk fornuftigt, men kan ogs� drille. I denne opgave anbefales det at sl� robottens Avoidance system fra. Avoidance systemet tilgås med følgende kode:

Evolution::IAvoidance *avoid;
result = resource_container->obtain_interface(Evolution::NO_TICKET, "avoidance", 
Evolution::IAvoidance::INTERFACE_ID, (void**) &avoid);

Herefter kan Avoidance systemet slås fra med

avoid->disable_avoidance(Evolution::NO_TICKET);

Hint 3: ERSP forventer at f� hastighed og acceleration angivet når motorsystemet benyttes. Følgende værdier kan være et godt udgangspunkt for valg af disse parametre:

const double velocity = 20; // cm/sec
const double acceleration = 20; // cm/sec^2
const double angular_velocity = 0.5; // radians/sec
const double angular_acceleration = M_PI/2.0; // radians/sec^2

Hint 4: Hvis der er problemer med at anvende ERSP findes der nogle udmærkede tutorials og en Doxygen genereret API dokumentation. Begge dele kan findes p� de bærbare i kataloget /opt/evolution_robotics/doc/

Delopgave 2: Kontinuerlige bevægelser

De funktioner der blev arbejdet med i delopgave 1, er gode når omgivelserne er kendte og robotten ved præcis hvorledes den skal køre. I de fleste praktiske situationer er det nødvendigt at have mere kontrol over robottens bevægelse. I denne situation benyttes funktionen move_and_turn.

Det er op til den enkelte gruppe at finde p� en rute, som robotten skal køre. Som inspiration foreslås det at lade robotten køre i et 8-tal.

Øvelse 2: Fuzzy Logic (Avoidance)

I denne opgave skal der implementeres et Avoidance System, der benytter Fuzzy Control. Robotten skal alts� udfra målinger fra afstandssensorerne beslutte hvorledes den skal køre. Kørslen skal tilrettelægges således at robotten ikke kører ind i nogle objekter.

Der benyttes et Fuzzy Logic bibliotek skrevet i Java kaldet jFuzzyLogic til at foretage de egentlige udregninger. For at benytte dette program p� robotterne (som programmeres i C++) benyttes en klient-server arkitektur.

En server (skrevet i Java) skal

  • modtage sensormålinger fra klienten gennem en socket,
  • behandle målingerne i et Fuzzy Logic system og
  • sende resultatet af beregningerne til klienten via samme socket.

En klient (skrevet i C++) skal

  • foretage målinger fra afstandssensorerne,
  • sende disse til serveren via en socket,
  • modtage ønskede motorhastigheder fra serveren og
  • f� motoren til at køre med de ønskede hastigheder.

Til løsning af opgaven udleveres:

  • En implementation af serveren. Denne inkluderer dog ikke Fuzzy logic systemet, der skal udvikles som en del af opgaven.
  • Et klient program der løser "afstandsmålinger" fra kommandolinien. Dette program viser hvorledes der kan kommunikeres med serveren og kan desuden anvendes til debugging af Fuzzy Logic systemet. Denne kode findes i kursets SVN under Exercise2. Det anbefales at læse README.txt i dette katalog.

Opgaven går derfor ud p� at

  • skrive et program i C/C++ der foretager målinger fra afstandssensorerne. Disse skal sendes over en socket til Java programmet. Herefter modtages ønskede motorhastigheder fra Java programmet. Disse hastigheder skal gives videre til motorkontrollen.
  • skrive Fuzzy Logic delen af serveren. Denne skal skrives i Fuzzy Control Language (FCL). Den udleverede server kan afvikle programmer skrevet i FCL, hvilket gøres med kommandoen ./FAZ FCL_FILNAVN.

Den udviklede FCL fil skal have fire inddata ("Front_sensor", "Rear_sensor", "Left_sensor" og "Right_sensor") og to uddata ("Velocity" og "Angular_velocity") for at det udviklede Java program kan benyttes. Ønskes anden ind- og uddata skal Java programmet ændres. Det betyder at følgende kan benyttes som skabelon til FCL programmet (findes under navnet Avoidance.fcl i SVN):

FUNCTION_BLOCK FuzzyAvoidance

// Define input variables
VAR_INPUT
    Front_sensor : REAL;
    Rear_sensor  : REAL;
    Left_sensor  : REAL;
    Right_sensor : REAL;
END_VAR

// Define output variables
VAR_OUTPUT
    Velocity         : REAL;
    Angular_velocity : REAL;
END_VAR

// Fuzzification of input
FUZZIFY Front_sensor
    // Fill this!
END_FUZZIFY

FUZZIFY Rear_sensor
    // Fill this!
END_FUZZIFY

FUZZIFY Left_sensor
    // Fill this!
END_FUZZIFY

FUZZIFY Right_sensor
    // Fill this!
END_FUZZIFY

// Defuzzification
// Velocity is in cm/sec and Angular_velocity is in radians/sec
DEFUZZIFY Velocity
    // Fill this!
END_DEFUZZIFY

DEFUZZIFY Angular_velocity
    // Fill this!
END_DEFUZZIFY

RULEBLOCK myrules
    // Fill this!
END_RULEBLOCK
END_FUNCTION_BLOCK

Den udleverede kode kan findes i kursets SVN under Exercise2.

Øvelse 3: Visuel objektfølgelse

I denne opgave skal der arbejdes med kameraet. Mere specifikt er skal robotten forfølge et objekt udelukkende ved brug af kameraet. Det objekt der skal forfølges er en af de orange kegler der findes i billedlab.

Overordnet set består opgaven af to dele, træning og objektfølgelse.

Træning

I denne opgave anbefales det at lave en normalfordelt farvemodel i RGB rummet der beskriver den orange kegle. Det vil sige at træningen går ud p� at beregne middelværdi og kovariansmatrix for den orange farve. I OpenCV kan funktionen cvCalcCovarMatrix med fordel benyttes til dette.

Objektfølgelse

Efter træningen er udført skal objektet forfølges af robotten. Til dette benyttes en udleveret tracker. Overordnet set skal hver iteration af robottens program se således ud:

  1. Tag et billede med kameraet.
  2. Bestem objektets position i billedet med den udleverede tracker.
  3. ændr robottens kørsel som funktion af objektets position og størrelse.

Trin 1: For at f� adgang til kameraet benyttes OpenCV -- mere specifikt highgui. I denne opgave er det nødvendigt at benytte funktionerne cvCaptureFromCAM og cvQueryFrame.

Trin 2: Den udleverede tracker arbejder p� et sandsynlighedskort. Dvs. at I skal beregne sandsynligheden for at enhver pixel tilhører en orange kegle. Herefter benyttes funktionen tracking::update for at udføre trackingen. Objektets position og størrelse kan herefter bestemmes med funktionerne tracking::object_position og tracking::object_size. Før trackeren benyttes anbefales det at skimme dens dokumentation.

Trin 3: Afslutningsvist skal motoren styres. Generelt ønskes følgende opførsel:

  • Hvis objektet er til højre for robotten skal den dreje til højre og tilsvarende hvis objektet er til venstre for robotten.
  • Hvis objektet er lille (langt fra robotten) skal den køre fremad. Hvis objektet er stort skal robotten køre bagud.

Hint 1: De orange kegler har nogle aflange huller i siden. Disse kan "fjernes" ved at stille to kegler oven p� hinanden. Derved bliver objekt detektionen noget nemmere.

Hint 2: Når der arbejdes med farver er det vigtigt at kameraet ikke dynamisk ændrer sit farveoptag. Ellers er det nødvendigt at opdatere sin farvemodel løbende. Det nemmeste er derfor at sætte gain til 0, hvilket kan gøres med pwc-driveren.

Hint 3: Det anbefales at benytte en normalfordeling i (R,G,B) rummet som farvemodel. Den udleverede tracker arbejder p� 8-bit billeder, hvilket betyder at sandsynlighederne i de enkelte pixels skal skaleres til intervallet [0, 255]. Dette kan gøres ved

 probability = round( 255*exp(-0.5*d*d) );

hvor d angiver Mahalanobis' afstand fra den aktuelle pixels farve til middelværdien af farvemodellen. (Mahalanobis' afstand kan beregnes med funktionen cvMahalanobis)

Øvelse 4: Lokalisering

I denne opgave skal robotten bestemme sin egen position ud fra visuelle målinger. Mere præcist ved robotten hvor to orange kegler (disse kaldes Landmarks i forbindelse med lokalisering) befinder sig. Når robotten ser et landmark kan den derfor forbedre sin egen position.

Opgaven går ud p� at implementere et partikelfilter til estimering af robottens position. Der udleveres kode til at adskille de enkelte landmarks fra hinanden og måle afstand til disse. Denne kode findes i kursets SVN under Exercise4 (læs README.txt).

Robotten skal vide hvor de to landmarks befinder sig, hvilket betyder at denne viden skal optræde i det udviklede program. I den udleverede kode er det ene landmark opstillet i (0,0) og det andet i (300,0). Det vil sige at de benyttede landmarks skal opstilles med 300 cm's afstand.

Robotten skal være i stand til at adskille de enkelte landmarks fra hinanden, hvilket gøres ved at placere en gul bold p� toppen af det ene landmark og en bl� bold p� toppen af det andet. I billedlab findes nogle sm� bolde med huller i bunden, der er lavet s� de kan sidde oven p� en orange kegle. For at robotten kan se de orange kegler tæt p� er det nødvendigt at hæve disse fra jorden. Det anbefales at stille disse oven p� de specialdesignede flamingoforhøjninger der findes i billedlab (forhøjningerne består af tre stykker flamingo der er limet sammen).

Hint 1: Afstanden mellem de to landmarks behøver ikke være præcis 300 cm for at programmet virker. Bare sørg for at afstanden passer nogenlunde (en fejl p� under 10 cm bør ikke gøre den store forskel).

Hint 2: For at afstandsberegninger kan foretages korrekt er det ndøvendigt at kompensere for kameraets tøndeforvrængning. Den udleverede programskal foretager denne opretning. For detaljer henvises der til Kalibrering af Scorpion robotternes kamera. Hint 3: Samlet skal robottens position og orientering bestemmes, hvilket giver tre parametre (x, y, theta) der skal estimeres. I begyndelsen anbefales det kun at estimere positionen (x, y) og først når dette fungerer ogs� estimere orienteringen (theta).

Hint 4: (fra Gert) Bemærk at koordinatsystemet i visualiseringen ses nedefra, som om gulvet var af glas og kameraet kiggede op under det. I skal derfor forvente at drejninger foregår modsat af, hvad i ser i virkeligheden - dvs. hvis robotten drejer med uret, drejer robottens indikator p� skærmen modsat uret.

Øvelse 5: Kommunikation

I denne opgave skal robotten ikke bare bestemme sin egen position, men ogs� en anden robots. Som i øvelse 4 opstilles to landmarks som robotterne kender positionerne p�. Disse benyttes til at estimere en robots egenposition.

For at estimere den anden robots position stilles en orange kegle oven p� robotterne således at disse kan genkendes og behandles som landmarks (benyt sorte bolde til robotterne). Igen skal der benyttes et partikelfilter til at bestemme den anden robots position. For at opdatere partiklernes bevægelser når robotterne ikke ser hinanden skal de to robotter udveksle bevægelsesinformation via det trådløse netværk. Dvs. at når en robot bevæger sig med (delta_x, delta_y, delta_theta) skal denne information transmiteres til den anden robot. For at gøre dette skal der udvikles ennetværksprotokol. Dette er den ene del af opgaven.

Den anden del af opgaven er at implementere to partikelfiltre

  • Det første partikelfilter benyttes til at estimere robottens egenposition. Her kan partikelfilteret fra øvelse 4 benyttes uændret.
  • Det andet partikelfilter skal estimere den anden robots position. Partiklerne flyttes når robotten modtager en besked fra den anden robot om at den har bevæget sig med (delta_x, delta_y). Når robotten ser den anden robot skal partiklerne vægtes, hvilket kan gøres p� forskellige måder. Tre forskellige metoder beskrives kort i de følgende afsnit. Der er op til den enkelte gruppe at vælge hvilken metode der benyttes. Bedst er det selvfølgelig at implementere alle metoderne og sammenligne disse.

Metode 1

Robotten starter med at estimere sin egen position ved at beregne middelværdi og kovarians af partiklerne i det første partikelfilter. Herefter kan en partikel vægtes ved at se p� en funktion af Mahalanobis' afstand mellem partiklen og robottens estimat af sin egen position. Evt. kan man undlade at estimere kovariansen og blot benytte euklidisk afstand.

Metode 2

For at vægte partiklen p tages et vægtet gennemsnit af afstandene til partiklerne i det første partikel filter:

 weight = 0
 for hver partikel p1 i det første partikel filter:
     dist = afstand mellem p og p1
     weight += p1.weight * F(dist)
 p.weight = weight

her er F en vilkårlig funktion (eksempelvis en normalfordeling). Problemet ved denne metode er at køretiden er O(n^2), hvilket giver problemer.

Metode 3

For at overkomme køretidsproblemet med forrige metode udvikles et estimat af metoden der kører i O(n*log(n)). Ideen er kun at benytte en delmængde af partiklerne i det første partikelfilter:

 weight = 0
 weight_sum = 0
 Gentag N gange:
     p1 =  en tilfældigt trukket partikel fra det første partikel filter
       (p1 skal trækkes således at partikler med høj vægt trækkes med høj sandsynlighed)
     dist = afstanden mellem p og p1
     weight += p1.weight * F(dist)
     weight_sum += p1.weight
 p.weight = weight/weight_sum

Her er N en konstant, der eksempelvist kan vælges lig 20. Denne metode kører i O(n*log(n)) da en partikel kan trækkes i O(log(n)).

Udleveret kode

Grundlæggende skal koden fra øvelse 4 benyttes, hvorfor der ikke udleveres en skabelon til løsning af denne opgave. Dog udleveres en ændret variant landmark_detection.[cc|h] således at genkendelse af sorte landmarks ogs� indgår.

En simpel mdåe at transmitere data over en socket er ved at benytte følgende to funktioner

inline void send_float(TCPSocket *socket, float f)
{
    socket->send((char*)(&(f)), sizeof(float));
}
inline float get_float(TCPSocket *socket)
{
    char buffer[sizeof(float)];
    socket->recv(buffer, sizeof(float));
    return *((float*)buffer);
}

Praktiske kommentarer

For at etablere en netværksforbindelse mellem to robotter kan der med fordel anvendes sockets. P� en maskine skal der startes en server, mens den anden maskine skal forbinde til denne server. Et eksempel p� en simpel klient og server kan ses p� Practical Sockets hjemmeside -- find det eksempel der hedder TCPEchoServer og TCPEchoClient. I min implementation foregår modtagelsen af information fra den anden robot i en separat tråd, men det behøver I ikke gøre i jeres implementation. Hvis I skal benytte tråde anbefales det at benytte PThreads.

Den trådløse netværkskommunikation kan være noget ustabil p� DIKU. Hvis dette giver jer problemer foreslås to løsningsmuligheder:

  1. Kobl maskinerne p� den trådede adgang til det trådløse netværk. Dette begrænser dog robotternes mobilitet væsentligt.
  2. Undlad helt at kommunikere via netværk! Dette kan gøres hvis den enkelte robot ved hvorledes den anden kører. Eksempelvis kan begge robotter køre lige ud hele tiden.
Personal tools