PlankTrick: verschil tussen versies

Uit RobotMC.be
Ga naar: navigatie, zoeken
(Nieuwe pagina aangemaakt met 'thumb ''In augustus 2014 was ik begonnen met een robot 'PlanckTrick' genaamd die bestond uit een paars platform van Aloys, twe...')
 
Geen bewerkingssamenvatting
Regel 1: Regel 1:
[[Afbeelding:PlankTrick_schema.jpg|thumb]]  
[[Afbeelding:PlankTrick_schema.jpg|thumb]]  
''In augustus 2014 was ik begonnen met een robot 'PlanckTrick' genaamd die bestond uit een paars platform van Aloys, twee tweedehandsmotoren van Joep (Portescap 22n28 210e D16 5). Ik had nog een STM32VLDiscovery bordje liggen en wat Sharp sensoren en wat spullen uit mijn voorraaddoos en wat knutselen had ik een werkende robot klaar. Het was echter eerder gepruts dan geknutsel en PlanckTrick heeft nooit echt stabiel gewerkt. Ook de STM32VLDiscovery was wat krap voor RobotLib en dan vooral het RAM gedeelte. Toen hij op 1 november 2015 finaal de geest gaf, leek dit experiment voorbij. Dankzij Joep is echter '''PlankTrick''' (zonder de 'c' deze keer) uit de as verrezen in een verbeterde en vooral stabiele versie : STM32F4Discovery bord met 1Mb Flash en 192K RAM, een kleinere motorcontroller, een kleinere step-down converter, de nodige condensators en vooral deftig gebouwd. Dit alles resulteerde in een robot conform het 'referentieplatform' van RobotLib. In de foto zie je het schema van de belangrijkste zaken van PlankTrick, maar in essentie is het [http://wiki.robotmc.org/index.php?title=RobotLib_Hardware deze hardware].''
''In augustus 2014 was ik begonnen met een robot 'PlanckTrick' genaamd die bestond uit een paars platform van Aloys, twee tweedehandsmotoren van Joep (Portescap 22n28 210e D16 5). Ik had nog een STM32VLDiscovery bordje liggen en wat Sharp sensoren en wat spullen uit mijn voorraaddoos en wat knutselen had ik een werkende robot klaar. Het was echter eerder gepruts dan geknutsel en PlanckTrick heeft nooit echt stabiel gewerkt. Ook de STM32VLDiscovery was wat krap voor RobotLib en dan vooral het RAM gedeelte. Toen hij op 1 november 2015 finaal de geest gaf, leek dit experiment voorbij. Dankzij Joep is echter '''PlankTrick''' (zonder de 'c' deze keer) uit de as verrezen in een verbeterde en vooral stabiele versie : STM32F4Discovery bord met 1Mb Flash en 192K RAM, een kleinere motorcontroller, een kleinere step-down converter, de nodige condensators en vooral deftig gebouwd. Dit alles resulteerde in een robot conform het 'referentieplatform' van RobotLib. In de foto zie je het schema van de belangrijkste zaken van PlankTrick, maar in essentie is het [http://wiki.robotmc.be/index.php?title=RobotLib_Hardware deze hardware].''


''Op deze pagina wil ik je mee begeleiden doorheen het software traject van PlankTrick met de bedoeling stap voor stap een robot op te bouwen  die aan Roborama kan meedoen. Gedurende het traject wil ik je ook enkele principes van RobotLib uitleggen zodat je zelf snel aanpassingen en uitbreidingen kan maken. Het is geen echte tutorial, maar eerder mijn weg doorheen Robotlib van vallen en opstaan, maar dan zonder het vallen.''
''Op deze pagina wil ik je mee begeleiden doorheen het software traject van PlankTrick met de bedoeling stap voor stap een robot op te bouwen  die aan Roborama kan meedoen. Gedurende het traject wil ik je ook enkele principes van RobotLib uitleggen zodat je zelf snel aanpassingen en uitbreidingen kan maken. Het is geen echte tutorial, maar eerder mijn weg doorheen Robotlib van vallen en opstaan, maar dan zonder het vallen.''
Regel 49: Regel 49:
** umpwm 1000 0 : nu moet de linker motor traag vooruit draaien
** umpwm 1000 0 : nu moet de linker motor traag vooruit draaien
** umpwm -1000 0 : nu moet de linker motor traag achteruit draaien
** umpwm -1000 0 : nu moet de linker motor traag achteruit draaien
** umpwm (+/-)4000 0 : nu moet de linker motor snel vooruit(4000)/achteruit(-4000) draaien
** umpwm (+/-)4000 0 : nu moet de linker motor snel vooruit(4000)/
** umpwm 0 +/-1000 : nu moet de rechter motor traag vooruit(+)/achteruit(-) draaien
** umpwm 0 +/-4000 : nu moet de rechter motor snel vooruit(+)/achteruit(-) draaien
* '''Motorsnelheid regeling : 'motorcal' ''' : Zorg dat je robot van de grond staat of dat je genoeg plek hebt. Als je deze functie uitvoert gaan de wielen wat draaien en op basis daarvan zal je op de console wat defines zien die je Prj_RobotLib_conf.h moet aanpassen
// Voorbeeldwaardes voor Portescap 22n28 210e D16 5 motoren:
#define MOTORL_SPEED_GAIN 130
#define MOTORL_OFFSET    -360
#define MOTORR_SPEED_GAIN 110
#define MOTORR_OFFSET    -110
* '''Afstandsbepaling''' : Gebruik hiervoor MotorCalibrate2 (PF 9) en daarna PF6 (reset counters), PF3 (rij vooruit) en PF0 (stop robot). De waardes op het display van de robot (ODO_mm) moet je vergelijken met de werkelijk gemeten afstand. Bij mijn eerste tests was de gemeten waarde lager dan de waarde op het display. Na enige testen zoals beschreven op [[RobotLib_MotorCalibratie|deze pagina]] moest ik de waarde van ODO_TICK_TO_MM veranderen van 325 in 341 en daarna was de afstand redelijk correct (+- 5mm op 2 meter)
* '''Wielomtrek & Hoekafstelling''' : Nadat ik de waardes berekend had zoals op [[RobotLib_MotorCalibratie|deze pagina]] beschreven startte ik "umbmark 1 2000 150" en daarna "umbmark -1 2000 150" en kwam ik afwijkingen van respectivelijk 192mm en -415mm tegen. Invullen in  deze [[http://www.robotmc.org/documents/odo_calibratie.xlsx Excel sheet]] en dan kon ik ODO_TICK_L_R aanpassen naar 4127 en  ODO_HEADING 1559. Een nieuwe test leverde een afwijking op van minder dan 1 cm op een vierkant met zijde 2 meter. Niet slecht. je kan dit nog gaan verfijnen met meerdere tests te doen, maar voor mij was het al lang prima zo.
 
==Stap 4 : Calibratie sharp sensoren==
De odometrie van RobotLib werkt in mm. Het zou dus handig zijn als je sharp sensoren ook afstanden gaven in mm ipv een ADC waarde tussen 0 en 4095. Sharp sensoren hebben echter een vervelende eigenschap. Er is geen lineair verband tussen de ADC waarde en de afstand in mm. Een grote wijziging in analoge meetwaarde betekent niet  dat er een groot afstandsverschil is. Mijn beste vriend (Google) wist me te vertellen dat het verband van de vorm tussen spanning en afstand van de vorm 1/x is. Dit wordt zeer netjes uitgelegd op [http://www.acroname.com/articles/linearizing-sharp-ranger.html deze pagina].
 
In RobotLib zijn alle tools voorhande om dit allemaal zeer eenvoudig op te lossen in volgende eenvoudige stappen.
* Maak in je hoofprogramma het aantal sensoren aan die je nodig hebt. Ik gebruik er 3 (links, midden en rechts) en heb dus 3 maal dit stukje code nodig (telkens met een ander object van de class TSharpSensor)
 
  TSharpSensor glob_SharpL ;
 
  glob_SharpL.Name = "Links" ;
  glob_SharpL.AdcChannel = ADC_Channel_7;
  glob_SharpL.CalibrationA = 343000; //default, een goede benadering
  glob_SharpL.CalibrationB=  0 ;  // default waarde
  glob_SharpL.SetTimeConstant(3); // 3 = 2^3, 24x = 95%
 
* Zorg voor een goed reflecterend oppervlak (bv. drie plankjes) en zet dit op een welbepaalde afstand voor elke sensor(bv. 100mm). Met het commando "sharpcal 100" (beschikbaar nadat je "addtests" doet) doe je de eerste stap van de calibratie.
* Zet het plankje nu op een andere afstand (bv. 400mm) en voer nu "sharpcal 400" uit.
* Met deze twee metingen kan RobotLib de formule vastleggen voor de linearizatie van alle sensoren tegelijk. Er wordt een A en een B waarde geprint. Verander in bovenstaande code de calibrationA en calibrationB waardes hiermee.
 
Met de default waardes kan je starten en krijg je een behoorlijke benadering, maar de juiste waardes hangen af van jouw sensoren, hoe stabiel je voeding is, of je de sensoren voorzien hebt van een condensator etc etc....
 
'''Tip''' : Maak het jezelf gemakkelijk en voeg de sensoren toe aan KDU met commando's zoals
    Kdu.Add("SharpL", glob_SharpL.Distance, true);
dan kan je gelijk de afstand in mm op je LCD display uitlezen voor elke sensor.
 
=Roborama Opdrachten programmeren=
RobotLib voert altijd "Missions" uit. Elke roborama opdracht kan je als een missie zien. Wat je gaat doen is een "MissionHandler" maken en deze dan aan je afstandsbediening, de commando-lijn of beide koppelen. Klinkt ingewikkeld ? Geen paniek. Valt best mee. Joep legt op [[RobotLib_HowTo|deze pagina]] uit welke de bouwstenen zijn om dit te realizeren.
 
== Heen & Weer, geen opties, adhv Odometrie ==
Dit is waarschijnlijk de simpelste variant : rij een bepaalde afstand vooruit, draai 180° en rij dezelfde afstand terug. Die afstand is voor Roborama om van het midden van vak A naar het midden van vak B te geraken 3m of 3000mm. We zullen deze gebruiken om de verschillende stappen toe te lichten. Voor de andere Roborama opdrachten gaan we dan alleen nog de kern van de zaak en/of de verschillen beschrijven.
 
===De Mission Handler===
De "Mission Handler" zelf. Deze wordt door de "Takt" routine opgeroepen totdat er "true" wordt teruggeven. Zolang de functie "false" terug geeft zal de methode Mission.Takt regelmatig (bv. elke 50 msec) opgeroepen worden. In onze implementatie gebruiken we een andere mission (Mover) die ook aangeroepen wordt in de hoofdlus met Mover.Takt. We vullen eerst een lijst met commando's en laten die dan door Mover afhandelen. Als mover klaar is eindigen we ook de Heen & Weer-missie
 
bool MSM_Roborama_HW_Odometrie(int &State, int NewState)
{       
  switch (State) {  // case of MSM_Roborama_Odometrie
      case 0 :    // Rij naar X, 0   
        if (NewState) {
            Mover.ListMode();    // Set list mode (UmSet commando's worden in een lijst gezet) 
            Mover.Reset();      // Reset voordat we de lijst (opnieuw) gaan vullen.
           
            // STAP: Rij tot in vak B
            UmXYSet(MhParam.Get(1), 0, glob_Speed, 0); // X, Y, Speed, EndSpeed - alles in mm(/sec)
            // STAP: Draai naar 180°
            UmRotateSet(180); // Heading (in graden)
           
            // STAP: Rij terug naar vak A
            UmXYSet( 0, 0, glob_Speed, 0); // X, Y, Speed, EndSpeed - alles in mm(/sec)
                   
            // STAP: Draai naar 0° graden (= oorspronkelijke positie)
            UmRotateSet(0); // Heading (in graden)
           
            //-----------------------------------             
            // Alle stappen staan nu in de lijst.
            // Tijd om de robot te laten bewegen
            //-----------------------------------
            Mover.Dump();
            Mover.Run();
            Mover.Dump();
                     
        } // einde van First-sectie, we hebben nu verteld wat er moet gebeuren.     
        //-----------------------------------------------------------------           
        // Controleer of de beweging klaar is.
        //-----------------------------------------------------------------                   
        if (Mover.IsDone()) { // Als de lijst met bewegingen klaar is
            return true;  // Geef aan dat de missie klaar is.
                          // De Msm zal nu niet meer aangeroepen worden.
        }
      break;     
         
      default :  // error
            return true;  // mission end
        break;
  }         
  return false;  // mission nog niet gereed
}
 
===Koppelen aan de afstandsbediening===
De PFKeys handler zorgt voor de afhandeling van de knoppen op je afstandsbediening. Je kan knoppen 0 tot 9 gebruiken of ze simuleren door op de commando lijn 'pf <nr>' in te typen.
 
void PFKeyRoborama (int Nr)
{
  switch(Nr) {  // case of PFKeyUmTest1 (Um-SpeedHeading)
      case 1 :    // UmbMark Linksom
        MhParam.Set(0,  0);    // geen optie
        MhParam.Set(1, DISTANCE_TO_B);    // afstand
        MhParam.Set(2, 200) ; // snelheid
        Mission.Start(MSM_Roborama_HW_Odometrie, "H&W met odometrie, geen opties");
        break;       
      case 0 :    // Stop     
        RobotStop();       
        break;
  } 
}
 
Om deze te activeren moet je in het hoofdprogramma
PFKeyHandlerSet(PFKeyRoborama, "Roborama 1.4"); 
oproepen
 
===Command Line Interface===
De command-line interface moet je eerst programmeren. Je krijgt het aantal meegegeven parameters in een array mee. In dit voorbeeld programmeren we een functie 'hw <optie> <distance> <speed>'
 
void CliCmd_HeenWeer (int ParamCounter, int *Params)
{     
  // Controleer parameter bereik
  if ((Params[0] < 0 || Params[0] > 0)) {
      printf("CliCmd_HeenWeer fout: 1e parameter moet 0 zijn (%d)\n", Params[0]);
      return;
  }
  if ((Params[1] < 100) ) {
      printf("CliCmd_HeenWeer fout: 2e parameter (afstand) moeten groter dan 100 zijn (%d)\n", Params[1]);
      return;
  }
  if ((Params[2] < 50) ) {
      printf("CliCmd_HeenWeer fout: 2e parameter (snelheid) moeten groter dan 50 zijn (%d)\n", Params[2]);
      return;
  }
  // Sla parameters voor Mission State Machine op
  MhParam.Set(0, Params[0]);  // optie
  MhParam.Set(1, Params[1]) ; // distance
  MhParam.Set(2, Params[2]);  // snelheid       
 
  // Start Mission
  Mission.Start(MSM_Roborama_HW_Odometrie, "MSM_Roborama_HW_Odometrie");
}     
 
Om deze toe te voegen moeten we alle commando's in een lijst stoppen en eindigen met een sentinel (alles 0 of lege string)
 
  t_cli_record CliRecords_Roborama[] = {     
  // Functie              keyword    #param  help_tekst
  { CliCmd_HeenWeer,      "hw",  3,  " <optie> <afstand> <snelheid> - Start MSM_HeenWeer_Odometrie met gegeven parameters." },
  // laatste regel niet wijzgigen
  { 0, "", 0, ""  } // last one has function pointer value 0
};
 
Het activeren van de command line interface doe je door in het hoofdprogramma
CliAddCommands(CliRecords_Roborama, "Roborama 1.4"); 
op te roepen
 
==Heen en Weer, 1 Sharp Sensor in het midden en optie 1 en 2==
In de vorige optie gebruikten we als enige sensor de encorders van de motoren om een bepaalde afstand vooruit te rijden, te draaien en terug te keren naar de start positie. Voor heel deze bewerking was maar 1 'state' nodig van de robot omdat we de Mover eerst een lijst van commando's gaven (rij naar X,Y - draai - Rij naar 0,0 - draai) en dan de Mover opdracht gaven die lijst af te werken.
 
In deze Mission gaan we anders te werk. In 'State 1' laten we de robot rechtdoor rijden tot de sharp sensor de muur ziet. Dan gaan we naar 'State 2' waar we de opdracht geven om terug naar 0,0 te rijden. We draaien niet. We rijden achteruit door de snelheid als negatief getal te geven. Verder nog effe koppelen aan de afstandsbediening en een command line interface mee geven zoals in de vorige stap en Klaar is Joep ... of was het Kees ? Hier de Mission met de Sharp. De rest zal wel lukken zeker ?
 
Optie 1 (180°) en Optie 2 (540°) zijn ook geimplementeerd. Om een mooie bocht te rijden varieer ik de snelheid van linker- en rechterwiel. Daarna test ik of ik reeds 180° gedraaid ben om terug rechtdoor te rijden. Bij Optie 2 ga ik 3x180° draaien omdat het teken van de hoek telkens verandert (-180° ... +180°). Ik laat het aan jou om na te gaan of je de logica van onderstaand programma kan uitpluizen.
 
bool MSM_Roborama_HW_Sharp (int &State, int NewState)
{       
    static float left_speed, right_speed ;
    switch (State) {  // case of MSM_Roborama_Odometrie
      case 0 :   
        if (NewState) {
// voor het eerst in deze state
Mover.DirectMode();  // Set direct mode (UmSet commando's werken direct)
UmSpeedHeadingSet(MhParam.Get(2), 0);
          }   
        //-----------------------------------------------------------------           
        // Controleer of de beweging klaar is.
        //-----------------------------------------------------------------                   
        if (glob_SharpM.Distance < MhParam.Get(1)) { // Als we te dicht bij de muur komen
              if (MhParam.Get(0) == 0) State = 2;  // return home     
                  else  State = 1 ; // draai 180° rond blik              
}
        break;                         
      case 1 : // Draai 180° rond blik
if (NewState) {
Mover.DirectMode();  // Set direct mode (UmSet commando's werken direct)
left_speed  = 0.5+((float)MhParam.Get(2))*(300.0-WIEL_BASIS/2.0)/300.0 ;
right_speed = 0.5+((float)MhParam.Get(2))*(300.0+WIEL_BASIS/2.0)/300.0 ;
UmSpeedLRSet((int)left_speed, (int) right_speed) ;// Draai 180° rond blik met straal +-300mm
}
        //-----------------------------------------------------------------           
        // Controleer of de beweging klaar is.
        //-----------------------------------------------------------------                   
        if (RobotHoek() < 0 ) { // 180° gedraaid
            if (MhParam.Get(0) == 1) State = 4;  // return home     
                  else  State = 2 ; // draai 540° rond blik
}
        break;
 
      case 2 : // draai door tot 0°
        if (RobotHoek() > 0 ) { // 360° gedraaid
              State++; // Rij terug naar beginpositie     
}
        break;
      case 3 : // Draai 180° rond blik
        if (RobotHoek() < 0 ) { // 540°° gedraaid
            State++; // Rij terug naar beginpositie             
}
        break;
 
      case 4 : // Keer terug naar begin positie
        if (NewState) {
// voor het eerst in deze state
Mover.DirectMode();  // Set direct mode (UmSet commando's werken direct)
if (MhParam.Get(0) == 0)
UmXYSet (0, 0, -MhParam.Get(2), 0) ; // terug naar beginpositie
else
UmXYSet (0, 600, MhParam.Get(2), 0) ; // terug naar beginpositie
          }   
        //-----------------------------------------------------------------           
        // Controleer of de beweging klaar is.
        //-----------------------------------------------------------------                   
        if (Mover.IsDone()) { // Als we te dicht bij de muur komen
              State = 99 ;  // almost finished, return home 
}
        break;
      case 5 :
      case 99 : // Rij terug naar 0,0 met heading 0° (= startpositie)
        if (NewState) {
    // voor het eerst in deze state
    Mover.ListMode();    // Set list mode (UmSet commando's worden in een lijst gezet) 
            Mover.Reset();      // Reset voordat we de lijst (opnieuw) gaan vullen.
            UmRotateSet(-90); // Heading (in graden)
            UmXYSet( 0, 0, glob_Speed, 0); // X, Y, Speed, EndSpeed - alles in mm(/sec)
            UmRotateSet(0); // Heading (in graden)  = startpositie         
            //-----------------------------------             
            // Alle stappen staan nu in de lijst.
            // Tijd om de robot te laten bewegen
            //-----------------------------------
            Mover.Dump();
            Mover.Run();
            Mover.Dump();         
        }   
        //-----------------------------------------------------------------           
        // Controleer of de beweging klaar is.
        //-----------------------------------------------------------------                   
        if (Mover.IsDone()) { // Als de lijst met bewegingen klaar is
            return true;  // Geef aan dat de missie klaar is.
                          // De Msm zal nu niet meer aangeroepen worden.
        }
      break;     
           
      default :  // error
printf ("ERROR-Undefined State (%d)\n", State) ;
return true;  // mission end
        break;
  } 
 
  printf ("HW : SharpM=%d - Hoek=%d - Speed %d (L=%d, R=%d)\n", glob_SharpM.Distance, RobotHoek(), glob_Speed, (int)left_speed, (int) right_speed) ;
  return false;  // mission nog niet gereed
}

Versie van 17 dec 2017 21:01

PlankTrick schema.jpg

In augustus 2014 was ik begonnen met een robot 'PlanckTrick' genaamd die bestond uit een paars platform van Aloys, twee tweedehandsmotoren van Joep (Portescap 22n28 210e D16 5). Ik had nog een STM32VLDiscovery bordje liggen en wat Sharp sensoren en wat spullen uit mijn voorraaddoos en wat knutselen had ik een werkende robot klaar. Het was echter eerder gepruts dan geknutsel en PlanckTrick heeft nooit echt stabiel gewerkt. Ook de STM32VLDiscovery was wat krap voor RobotLib en dan vooral het RAM gedeelte. Toen hij op 1 november 2015 finaal de geest gaf, leek dit experiment voorbij. Dankzij Joep is echter PlankTrick (zonder de 'c' deze keer) uit de as verrezen in een verbeterde en vooral stabiele versie : STM32F4Discovery bord met 1Mb Flash en 192K RAM, een kleinere motorcontroller, een kleinere step-down converter, de nodige condensators en vooral deftig gebouwd. Dit alles resulteerde in een robot conform het 'referentieplatform' van RobotLib. In de foto zie je het schema van de belangrijkste zaken van PlankTrick, maar in essentie is het deze hardware.

Op deze pagina wil ik je mee begeleiden doorheen het software traject van PlankTrick met de bedoeling stap voor stap een robot op te bouwen die aan Roborama kan meedoen. Gedurende het traject wil ik je ook enkele principes van RobotLib uitleggen zodat je zelf snel aanpassingen en uitbreidingen kan maken. Het is geen echte tutorial, maar eerder mijn weg doorheen Robotlib van vallen en opstaan, maar dan zonder het vallen.

Hardware configuratie

Onderdelenlijst

  • Processor : STM32F4Discovery [1] : 32 bits, 1Mb flash, 192K RAM, 168Mhz (denk ik)
  • Voeding : LiPo 4 cells, 2200 mAh [2] : 4 cellen geven tussen de 14.2 en 16.8 volt. Perfect voor mijn motoren, maar veel te hoog voor de processor. Om de spanning te reduceren gebruikte Joep een step-down converter ????? naar 8V en dan een 7805 voor het logische gedeelte zoals de voeding van het processorbord en de motorcontroller.
  • Motoren : 2xPortescap 22n28 210e D16 5 [3]
  • Motorsturing : ???? De spanningsval is 3V, wat de batterijspanning verlaagt naar 11.2...13.8V wat perfect is voor deze 12V motoren.
  • HC-05 Bluetooth module [4]. Deze werkt op 3.3V, ideaal voor de STM32, maar voor andere processoren opletten dat je op de RX poort een spanningsdeler zet.
  • RC5 ontvanger : TSOP36 [5] en een oude Philips afstandsbediening
  • LCD display : ik koos voor een 16x2 LCD tekst-display zonder backlight (HD44780 compatibel) maar wel met een I²C interface module om pinnen te besparen [6]
  • I²C level converter : omdat de STM32 op 3.3V werkt en het LCD display op 5V besloot ik er een level shifter tussen te zetten. Deze is niet strikt nodig, maar wel 'veiliger') [7]
  • 3x Sharp GP2D12 afstandssensor (10-80cm) met een 10uF elco over de + en - recht op de pinnen van de afstandssensor zelf
  • Polulu QTR-8A 8xIR sensor [8] voor de lijnvolger met een MAX127 als I²C interface om datalijnen te sparen

PIN-aansluitingen

Onder het motto 'blijf op bewandelde paden', besloot Joep dezelfde pin-layout te gebruiken als in het referentieplatform.

Rlib hw 03.jpg

Software Library : RobotLib

Joep heeft een mooie software library online gezet : RobotLib waar hij met een vergelijkbare configuratie een robot heeft gebouwd. De library is in lagen opgebouwd die het mogelijk maakt om andere processoren, andere motoren, ander platformen te gebruiken en door ze juist te configureren te integreren zodat de rest van je code niet moet aangepast worden. Verder is al heel wat voor jou bedacht : RC5 decoder, command-line interface, calibratieroutines, het programmeren van een "mission" door verschillende toestanden na elkaar te zetten enz.... Kortom, het wiel bestond al, waarom dan zelf iets bouwen? Ik ga hier niet herhalen wat je kan lezen in de documentatie van RobotLib maar toch is het nuttig te beschrijven wat ik moest aanpassen om alles werkend te krijgen denk ik voor anderen (en mezelf binnen 3 maand).

Stap 1 : "Hello World"

Bespaar jezelf een hoop ellende en doe gewoon wat Joep op deze pagina beschrijft. Als je alles tot en met de stap "Test" succesvol aan de praat krijgt, ben je al een heel eind gevorderd.
>> Herlees vorige 2 zinnen 3x
Toen dit werkte kreeg ik een hoop informatie op het scherm van m'n PC (via bluetooth) en kon ik commando's van de commando lijn ingeven (bv : '?' geeft je een lijst van beschikbare commandos) en als ik op mijn afstandsbediening een knop indrukte kreeg ik netjes de waarde van die knop op het scherm te zien. Alles gratis en voor niks -toegegeven - mits wat geknutsel, maar in elk geval heel wat minder werk dan zelf een wiel proberen uit te vinden. Belangrijk voordat je verder gaat is dat je console (UART) werkt omdat je die echt wel zal nodig hebben om alles te calibreren.

Stap 2 : Afstandsbediening

RobotLib bevat de nodige routines om een RC5 afstandsbediening uit te lezen. Meer nog, er zit zelfs de nodige code in om functies aan knoppen te linken en reeds een heleboel test programma's voorgeprogrammeerd. Je moet wel de juiste mapping doen tussen de toets op je afstandsbediening en de gewenste functie-code. Niet zo moeilijk als het klinkt.

  • Toetscodes bepalen : Simpel. Gewoon de console openen, het commando 'dset 2' ingeven (debug RC5) en dan de toetsen drukken die je wenst. Je zal dan dingen zien zoals verschijnen zoals 'D02: Rc5RxWord : 4430 / 0x114e (29006/0x714e) Unhandled RC5 code 4430'. Je schrijft de toets en de bijhorende code even op, in dit voorbeeld 4430.
  • Mapping tussen toets en functie : Dit alles kan je regelen door in het bestand Prj_RobotLib_conf.h de constanten RC_xxxxx naar de juiste code te mappen die je in de vorige stap opschreef. Constantes die je niet gebruikt of wil mappen, geef je een waarde die je afstandsbediening niet kan genereren, maar zorg wel dat elk getal maar 1 keer voorkomt. Deze constanten worden in een grote case gebruikt en als een waarde 2x voorkomt krijg je een compilatiefout.
  • Test missies :
    • Bij het opstarten is de groep "DemoUmbMark1" aan de afstandsbediening gekoppeld. Deze bevat 3 'missies' die gekoppeld zijn aan je afstandsbediening. RC_F01 is "UmbMark1 Linksom". RC_F02 is "UmbMark1 Rechtsom". RC_F10 is "Stop". Met de toets 9 activeer je de volgende groep missies (als die bestaat). In RobotLib taal heet dit de volgende 'PfKeyHandler'
    • Om de robot te calibreren verander je in "main.cpp" de oproep 'PFKeyHandlerSet(FP_FNAME(PFKeyUmbMark1))' in 'PFKeyHandlerSet(PFKeyMotorCalibrate1, "MotorCalibrate1")'
    • Je kan met de UP / DOWN toets die je definieerde op de LCD display verschillende waardes uitlezen : afstand, hoek, x en y positie, linkse en rechtse sharp sensor (= adc 1 en 2 ?).

Tip1 : Je kan natuurlijk ook lui zijn zoals ik : zet het bestand in de editor en de console naast elkaar op het scherm en je kan direct de code intypen. Dit heeft als voordeel dat je ziet welke codes je nodig hebt en je kan in de commentaar direct zeggen welk label de toets op de afstandsbediening heeft. Gegarandeerd dat je dit later handig gaat vinden.

Tip 2 : Je kan de functie-toetsen 0..9 van je afstandsbediening emuleren door in de console het commando 'pf 0' tot 'pf 9' in te typen.

Stap 3 : Motorcalibratie

Alles wordt perfect uitgelegd op deze pagina. De gebruikte pinnen van je processor kan je definieren in het bestand 'Prj_Hal_conf.h', maar doordat ik dezelfde layout gebruikte als Joep was dat niet nodig. Nadat de hardware fouten opgelost waren (slechte verbinding, links en rechts verwisseld) was het tijd om de motoren te configureren en calibreren. Doordat ik dezelfde pin-layout gebruikt had deden mijn motoren het een beetje, maar niet volledig. De code was voor pittmann motoren, ik had de portescap motoren. We gaan nu de commando lijn op de seriele terminal gebruiken om commando's aan onze robot te geven. Voer eerst het commando "addtests" uit zodat je extra functies ter beschikking krijgt

  • Vooruit/Achteruit & PWM : 'umpwm x y'  : dit is een belangrijk commando om te zien dat je motoren in de juiste richting draaien en om te zien of PWM werkt. Als dat niet zo is, moet je in het bestand prj_Hal_motors.cpp de functie PrjMotorPwm aanpassen. Ik moest het teken omwisselen op de lijn 82 'int Pwm = -PwmL; // flip direction here if required.' om de juiste draairichting te hebben en negatieve PWM waardes inverteren om bij kleine getallen de motor traag te laten draaien, bij grote getallen snel op lijn 88 'Pwm = (4095+Pwm);' Eventueel hetzelfde doen voor de rechter motor. Hier te commando's om alles te testen.
    • umpwm 1000 0 : nu moet de linker motor traag vooruit draaien
    • umpwm -1000 0 : nu moet de linker motor traag achteruit draaien
    • umpwm (+/-)4000 0 : nu moet de linker motor snel vooruit(4000)/