Inhoudsopgave:

Rpibot - Over het leren van robotica: 9 stappen
Rpibot - Over het leren van robotica: 9 stappen

Video: Rpibot - Over het leren van robotica: 9 stappen

Video: Rpibot - Over het leren van robotica: 9 stappen
Video: Raspberry Pi Pico for Robotics 2024, Juli-
Anonim
Rpibot - Over het leren van robotica
Rpibot - Over het leren van robotica

Ik ben embedded software engineer bij een Duits autobedrijf. Ik ben dit project begonnen als een leerplatform voor embedded systemen. Het project werd vroegtijdig geannuleerd, maar ik vond het zo leuk dat ik in mijn vrije tijd doorging. Dit is het resultaat…

Ik had de volgende eisen:

  • Eenvoudige hardware (focus is de software)
  • Goedkope hardware (ongeveer € 100)
  • Uitbreidbaar (sommige opties zijn al onderdeel van de beschrijving)
  • Voedingsspanning voor alle componenten uit een enkele 5V-bron (powerbank)

Er was niet echt een doel behalve leren. Het platform kan gebruikt worden voor leren, surveillance, robotwedstrijden, …

Het is geen beginnerscursus. Je hebt enige basiskennis nodig over:

  • Programmeren (Python)
  • Basis elektronica (om modules aan elkaar te koppelen door de juiste spanning)
  • Basisregeltheorie (PID)

Eindelijk zul je waarschijnlijk met problemen worden geconfronteerd zoals ik deed. Met enige nieuwsgierigheid en uithoudingsvermogen ga je door het project en los je de uitdagingen op. Mijn code is zo eenvoudig mogelijk en de kritische coderegels zijn becommentarieerd om hints te geven.

De volledige broncode en bestanden zijn hier beschikbaar:

Benodigdheden:

Mechanica

  • 1x Multiplexplaat (A4-formaat, 4 mm dik)
  • 3x M4 x 80 Schroef en moer
  • 2x Tandwielmotoren met secundaire uitgaande as voor encoder. Wielen.
  • 1x vrijloop

1x Pan en tilt camera montage (optioneel)

Elektronica

  • 1x Raspberry Pi Zero met header en camera
  • 1x PCA 9685 servobesturing
  • 2x Optisch encoderwiel en circuit
  • 1x Vrouwelijke jumperdraden
  • 1x USB-powerbank
  • 1x DRV8833 dubbele motordriver
  • 2x Micro servo's SG90 voor camera pan en tilt (optioneel)
  • 1x MPU9250 IMU (optioneel)
  • 1x HC-SR04 ultrasone afstandssensor (optioneel)
  • 1x geperforeerde plaat en soldeerdraad, headers, …

Stap 1: Bouw het chassis

Bouw het chassis
Bouw het chassis
Bouw het chassis
Bouw het chassis
Bouw het chassis
Bouw het chassis

Ik ben geen goede mechanische ontwerper. Ook is het doel van het project om niet te veel tijd in het chassis door te brengen. Hoe dan ook, ik heb de volgende vereisten gedefinieerd:

  • Goedkope materialen
  • Snelle montage en demontage
  • Uitbreidbaar (bijv. ruimte voor toegevoegde sensoren)
  • Lichte materialen om energie te besparen voor de elektronica

Een eenvoudig en goedkoop chassis kan gemaakt worden van multiplex. Het is gemakkelijk te bewerken met een figuurzaag en een handboor. U kunt kleine houten onderdelen lijmen om de houder voor sensoren en motoren te maken.

Denk hierbij aan het vervangen van defecte onderdelen of het elektrisch debuggen. De belangrijkste onderdelen moeten worden vastgezet met schroeven om vervangbaar te zijn. Een heetlijmpistool is misschien eenvoudig, maar waarschijnlijk niet de beste manier om een chassis te bouwen… Ik had veel tijd nodig om na te denken over een eenvoudig concept om de onderdelen gemakkelijk te demonteren. 3D-printen is een goed alternatief, maar kan behoorlijk duur of tijdrovend zijn.

Het vrijloopwiel is tenslotte zeer licht en eenvoudig te monteren. De alternatieven waren allemaal zwaar of vol wrijving (ik heb er een paar geprobeerd voordat ik de laatste vond).

Wieleigenschappen (voor softwareberekeningen)

Omtrek: 21,5 cmPulsen: 20 pulsen/omw. Resolutie: 1.075 cm (eindelijk is 1 puls ongeveer 1 cm, wat gemakkelijk is voor softwareberekeningen)

Stap 2: Elektronica en bedrading

Elektronica en bedrading
Elektronica en bedrading
Elektronica en bedrading
Elektronica en bedrading
Elektronica en bedrading
Elektronica en bedrading

Het project maakt gebruik van verschillende modules zoals weergegeven in het diagram.

De Raspberry Pi Zero is de hoofdcontroller. Het leest de sensoren en stuurt de motoren aan via een PWM-signaal. Het is via wifi verbonden met een externe pc.

De DRV8833 is een dubbele motor H-brug. Het levert voldoende stroom aan de motoren (wat de Raspberry Pi niet kan omdat de uitgangen maar wat mA kunnen leveren).

De optische encoder geeft elke keer dat het licht door de encoderwielen gaat een vierkant signaal. We zullen de HW-interrupts van de Raspberry Pi gebruiken om de informatie te krijgen telkens wanneer het signaal wordt omgeschakeld.

De pca9695 is een servobesturingskaart. Het communiceert via een I2C seriële bus. Dit bord levert de PWM-signalen en voedingsspanning die de servo's besturen voor het pannen en kantelen van de nok.

De MPU9265 is een 3-assige versnelling, 3-assige hoekrotatiesnelheid en 3-assige magnetische fluxsensor. We zullen het voornamelijk gebruiken om de kompasrichting te bepalen.

De verschillende modules zijn allemaal met elkaar verbonden door middel van een jumperdraad. Een breadboard fungeert als dispatcher en levert voedingsspanningen (5V en 3,3V) en massa. De aansluitingen staan allemaal beschreven in de aansluittabel (zie bijlage). Het aansluiten van 5V op een ingang van 3,3V zal waarschijnlijk je chip vernietigen. Wees voorzichtig en controleer al uw bedrading twee keer voordat u ze levert (hier moet vooral rekening worden gehouden met de encoder). U dient de netvoedingsspanningen op de verdelerkaart te meten met een multimeter voordat u alle kaarten aansluit. De modules werden met nylon schroeven in het chassis bevestigd. Ook hier was ik blij om ze vast te hebben maar ook verwijderbaar in geval van storing.

Het enige soldeerwerk waren uiteindelijk de motoren en het breadboard en de headers. Om eerlijk te zijn, ik hou van de jumperdraden, maar ze kunnen leiden tot een losse verbinding. In sommige situaties kunnen sommige softwarecontroles u ondersteunen bij het analyseren van de verbindingen.

Stap 3: Software-infrastructuur

Software-infrastructuur
Software-infrastructuur
Software-infrastructuur
Software-infrastructuur

Nadat we de mechanica hebben bereikt, zullen we een software-infrastructuur opzetten om comfortabele ontwikkelingsomstandigheden te hebben.

Git

Dit is een gratis en open source versiebeheersysteem. Het wordt gebruikt om grote projecten als Linux te beheren, maar kan ook gemakkelijk worden gebruikt voor kleine projecten (zie Github en Bitbucket).

De projectwijzigingen kunnen lokaal worden gevolgd en ook naar een externe server worden gepusht om software met de gemeenschap te delen.

De belangrijkste gebruikte commando's zijn:

git clone https://github.com/makerobotics/RPIbot.git [Verkrijg de broncode en git-configuratie]

git pull origin master [haal het laatste nieuws uit de externe repository]

git status [haal de status van de lokale repository. Zijn er bestanden gewijzigd?] git log [haal de lijst met commits] git add. [voeg alle gewijzigde bestanden toe aan de stage om in aanmerking te komen voor de volgende commit] git commit -m "comment for commit" [leg de wijzigingen vast in de lokale repository]git push origin master [push alle commits naar de remote repository]

Loggen

Python biedt een aantal ingebouwde logboekfuncties. De softwarestructuur moet al het logging-framework definiëren voordat met verdere ontwikkeling wordt begonnen.

De logger kan worden geconfigureerd om te loggen met een gedefinieerd formaat in de terminal of in een logbestand. In ons voorbeeld is de logger geconfigureerd door de webserverklasse, maar we kunnen het ook alleen doen. Hier stellen we alleen het logniveau in op DEBUG:

logger = logging.getLogger(_name_)

logger.setLevel(logging. DEBUG)

Meten en plotten

Om signalen in de loop van de tijd te analyseren, kunt u ze het beste in een grafiek plotten. Omdat de Raspberry Pi alleen een consoleterminal heeft, zullen we de gegevens traceren in een door puntkomma's gescheiden csv-bestand en deze plotten vanaf de externe pc.

Het door puntkomma's gescheiden traceerbestand wordt gegenereerd door onze hoofdpython-code en moet headers hebben zoals deze:

tijdstempel;yawCorr;encoderR;I_L;odoDistance;ax;encoderL;I_R;yaw;eSpeedR;eSpeedL;pwmL;speedL;CycleTimeControl;wz;pwmR;speedR;Iyaw;hdg;m_y;m_x;eYaw;cycleTimeSense;

1603466959.65;0;0;25;0.0;-0.02685546875;0;25;0;25;25;52;0.0;23;0.221252441406;16;0.0;0;252.069366413;-5.19555664062;-16.0563964844;0;6; 1603466959.71;0;0;50;0.0;0.29150390625;0;50;0;25;25;55;0.0;57;-8.53729248047;53;0.0;0;253.562118111;-5.04602050781;-17.1031494141;0;6; 1603466959.76;0;-1;75;0.0;-0.188232421875;1;75;2;25;25;57;0;52;-24.1851806641;55;0;0;251.433794171;-5.64416503906;-16.8040771484;2;7;

De eerste kolom bevat de tijdstempel. De volgende kolommen zijn gratis. Het plotscript wordt aangeroepen met een lijst van te plotten kolommen:

remote@pc:~/python rpibot_plotter -f trace.csv -p speedL, speedR, pwmL, pwmR

Het plotscript is beschikbaar in de toolmap:

De plotter gebruikt mathplotlib in Python. U moet het naar uw pc kopiëren.

Voor meer comfort wordt het python-script aangeroepen door een bash-script (plot.sh) dat wordt gebruikt om het Raspberry Pi-traceerbestand naar de externe pc te kopiëren en de plotter aan te roepen met een signaalselectie. Het bash-script "plot.sh" vraagt als het bestand moet worden gekopieerd. Dit was handiger voor mij in plaats van elke keer handmatig te kopiëren. "sshpass" wordt gebruikt om het bestand via scp van de Raspberry Pi naar de externe pc te kopiëren. Het kan een bestand kopiëren zonder om het wachtwoord te vragen (het wordt doorgegeven als parameter).

Ten slotte wordt een venster geopend met de plot zoals weergegeven in de afbeelding.

Communicatie op afstand

De ontwikkelinterface voor de Raspberry Pi is SSH. Bestanden kunnen direct op het doel worden bewerkt of door scp worden gekopieerd.

Om de robot te besturen, draait er een webserver op de Pi, die controle biedt via Websockets. Deze interface wordt beschreven in de volgende stap.

Stel de Raspberry Pi in

Er is een bestand dat de installatie van de Raspberry Pi beschrijft in de map "doc" van de broncode (setup_rpi.txt). Er zijn niet veel uitleg maar veel handige commando's en links.

Stap 4: De gebruikersinterface

De gebruikersinterface
De gebruikersinterface

We gebruiken de lichtgewicht Tornado-webserver om de gebruikersinterface te hosten. Het is een Python-module die we noemen als we de robotbesturingssoftware starten.

Software architectuur

De gebruikersinterface is opgebouwd door de volgende bestanden:gui.html [Beschrijving van de bedieningselementen en lay-out van de webpagina] gui.js [Bevat de javascript-code om de bedieningselementen af te handelen en een websocket-verbinding met onze robot te openen] gui.css [Bevat de stijlen van de html-besturingselementen. De posities van de bedieningselementen worden hier gedefinieerd]

De websocket-communicatie

De gebruikersinterface is niet de coolste, maar hij doet zijn werk. Ik concentreerde me hier op technologieën die nieuw voor me waren, zoals Websockets.

De website communiceert via Websockets met de robotwebserver. Dit is een bidirectioneel communicatiekanaal dat open blijft wanneer de verbinding tot stand is gebracht. We sturen de commando's van de robot via Websocket naar de Raspberry Pi en krijgen informatie (snelheid, positie, camerastream) terug voor weergave.

De interface-indeling

De gebruikersinterface heeft een handmatige invoer voor de commando's. Dit werd in het begin gebruikt om opdrachten naar de robot te sturen. Een selectievakje zet de camerastream aan en uit. De twee schuifregelaars regelen het pannen en kantelen van de camera. Het deel rechtsboven in de gebruikersinterface regelt de beweging van de robot. U kunt de snelheid en de doelafstand regelen. De basistelemetrie-informatie wordt weergegeven in de robottekening.

Stap 5: Het robotplatform programmeren

Het robotplatform programmeren
Het robotplatform programmeren
Het robotplatform programmeren
Het robotplatform programmeren
Het robotplatform programmeren
Het robotplatform programmeren

Dit onderdeel was het hoofddoel van het project. Ik heb veel van de software aangepast toen ik het nieuwe chassis met de DC-motoren introduceerde. Ik gebruikte Python om verschillende redenen als programmeertaal:

  • Het is de hoofdtaal van Raspberry Pi
  • Het is een taal op hoog niveau met veel ingebouwde functies en extensies
  • Het is objectgeoriënteerd, maar kan ook worden gebruikt voor sequentiële programmering
  • Geen compilatie of gereedschapsketting nodig. Bewerk de code en voer deze uit.

Belangrijkste software-architectuur

De software is object georiënteerd, opgedeeld in enkele objecten. Mijn idee was om de code in 3 functionele blokken te splitsen:

Zin Denken Activeren

Sense.py

Belangrijkste sensor acquisitie en verwerking. De gegevens worden opgeslagen in een woordenboek dat in de volgende fase moet worden gebruikt.

Control.py

Een subklasse voor activering bestuurt de motoren en servo's na enige abstractie. Het belangrijkste besturingsobject is het afhandelen van de commando's op hoog niveau en ook de besturingsalgoritmen (PID) voor de motor.

rpibot.py

Dit hoofddoel is het beheren van de Tornado-webserver en het instantiëren van de sense- en control-klassen in afzonderlijke threads.

Elke module kan afzonderlijk of als onderdeel van het hele project worden uitgevoerd. U kunt de sensorinformatie alleen detecteren en afdrukken om te controleren of de sensoren correct zijn aangesloten en de juiste informatie leveren.

De PID-regeling

De eerste taak is om erachter te komen wat we willen controleren. Ik begon door te proberen de positie onder controle te krijgen, wat erg complex was en niet veel hielp.

Ten slotte willen we elke wielsnelheid en ook de richting van de robot regelen. Om dat te doen, moeten we twee besturingslogica's cascaderen.

Om de complexiteit stap voor stap te vergroten, moet de robot worden bestuurd:

open lus (met een constant vermogen)

pwm = K

voeg vervolgens het close-loop-algoritme toe

pwm = Kp.speedError+Ki. Integration(speedError)

en voeg als laatste stap de richtingsbesturing toe.

Voor de snelheidsregeling gebruikte ik een "PI" -regeling en "P" alleen voor de gier. Ik stel de parameters handmatig in door te experimenteren. Waarschijnlijk zouden hier veel betere parameters kunnen worden gebruikt. Mijn doel was gewoon een rechte lijn en ik had het bijna. Ik heb een interface in de software gemaakt om enkele variabelen door de gebruikersinterface te schrijven. Het instellen van de parameter Kp op 1.0 vereist het volgende commando in de gebruikersinterface:

SET;Kp;1.0

Ik zou de P-parameter net laag genoeg kunnen instellen om overschrijding te voorkomen. De resterende fout wordt gecorrigeerd door de I-parameter (geïntegreerde fout)

Het was moeilijk voor mij om erachter te komen hoe ik beide bedieningselementen in cascade kon zetten. De oplossing is eenvoudig, maar ik heb al veel andere manieren geprobeerd … Dus uiteindelijk heb ik de snelheidsdoelstelling van de wielen gewijzigd om in de ene of de andere richting te draaien. Het rechtstreeks wijzigen van de uitgang van de snelheidsregeling was een fout omdat de snelheidsregeling deze storing probeerde op te heffen.

Het gebruikte regelschema is bijgevoegd. Het toont alleen de linkerkant van de robotbesturing.

Stap 6: De sensorkalibraties

De sensorkalibraties
De sensorkalibraties
De sensorkalibraties
De sensorkalibraties
De sensorkalibraties
De sensorkalibraties

Allereerst moet u bedenken dat de hele IMU goed moet werken. Ik bestelde 3 onderdelen en stuurde ze terug totdat ik een volledig werkende sensor had. Bij elke vorige sensor werkten sommige delen van de sensor niet goed of helemaal niet. Ik heb enkele voorbeeldscripts gebruikt om de basis te testen voordat ik deze in de robot monteerde.

De signalen van de IMU-sensor moeten worden gekalibreerd voordat ze worden gebruikt. Sommige sensorsignalen zijn afhankelijk van de montagehoek en -positie.

De kalibraties voor acceleratie en rotatiesnelheid

De eenvoudigste kalibratie is voor de longitudinale versnelling (A_x). Bij stilstand moet er ongeveer 0 m/s² zijn. Als je de sensor goed draait, kun je de zwaartekracht meten (ongeveer 9, 8 m/s²). Om a_x te kalibreren, moet je het gewoon goed monteren en vervolgens de offset definiëren om 0 m/s² bij stilstand te krijgen. Nu is A_x gekalibreerd. U kunt de offsets voor de rotatiesnelheden op een vergelijkbare manier bij stilstand krijgen.

De magnetometerkalibratie voor het kompas

Voor de magneetveldsensoren is een complexere kalibratie nodig. We zullen m_x en m_y gebruiken om het magnetische veld in het horizontale niveau te krijgen. Het hebben van m_x en m_y geeft ons de mogelijkheid om een kompaskoers te berekenen.

Voor ons eenvoudige doel zullen we alleen de hardijzerafwijking kalibreren. Dit moet worden uitgevoerd terwijl de sensor zich in de definitieve positie bevindt, aangezien deze afhankelijk is van verstoringen van het magnetische veld.

We nemen m_x en m_y op terwijl we de robot rond de z-as draaien. We plotten de m_x vs m_y in een XY-diagram. Het resultaat in een weglatingsteken zoals weergegeven in de afbeelding. De ellips moet worden gecentreerd op de oorsprong. Hier beschouwen we de maximale en minimale waarden van m_x en m_y om de offsets in beide richtingen te krijgen. Ten slotte controleren we de kalibratie en zien dat de ellips nu gecentreerd is.

Zachtijzerkalibratie zou betekenen dat we de afbeelding van een ellips in een cirkel veranderen. Dit kan door bij elke senorwaarde een factor toe te voegen.

Een testroutine kan nu worden gecodeerd om opnieuw te kalibreren of in ieder geval om te controleren of de sensoren nog steeds gekalibreerd zijn.

De kompasrichting

De magnetometergegevens worden nu gebruikt om de kompasrichting te berekenen. Hiervoor moeten we de m_x en m_y signalen omzetten in een hoek. Python levert rechtstreeks de math.atan2-functie die dit doel heeft. De volledige berekening is gedefinieerd in het bestand mpu9250_i2c.py ("calcHeading(mx, my, mz)").

Stap 7: alternatieve ontwerpen

Alternatieve ontwerpen
Alternatieve ontwerpen
Alternatieve ontwerpen
Alternatieve ontwerpen
Alternatieve ontwerpen
Alternatieve ontwerpen

Het project nam veel tijd in beslag omdat het ontwerp volledig open was. Voor elk onderdeel heb ik een prototype implementatie gemaakt en de limieten van het systeem ervaren.

Het meest complexe onderwerp was de wiel-encoder. Ik heb 3 verschillende opties getest voordat ik de momenteel gebruikte optische encoder vond. Ik denk dat de afgebroken oplossingen ook erg interessant zijn in zo'n project. Het betreft de onderdelen waar ik het meest heb geleerd.

Continu draaiende servo aangesloten op pca 9695

Om een extra H-brug voor een gelijkstroommotor te vermijden, ben ik eerst begonnen met continu draaiende servo's. Deze werden aangestuurd door de reeds aanwezige pca 9695 servodriver. Alle voortstuwingsmechanica en de bijbehorende elektronica waren veel eenvoudiger. Dit ontwerp had twee nadelen:

  • Het slechte regelbereik van de servo's.
  • De ontbrekende locatie voor het vasthouden van de encoder

De servo's beginnen te bewegen met 50% pwm en hebben volle snelheid op ongeveer 55%. Dit is een zeer slecht regelbereik.

Zonder een encoder die vastzit, was het erg moeilijk om een kant-en-klare encoder te vinden. Ik heb 3 verschillende reflectie-encoders getest die op het chassis waren gemonteerd. Ik heb een zelfgemaakt encoderwiel aan de buitenkant van het wiel geplakt met zwarte en witte secties. Ik heb de QTR-1RC-sensoren gebruikt die veel signaalverwerking nodig hebben om het juiste signaal te krijgen. De Raspberry Pi was niet in staat om dat soort realtime verwerking uit te voeren. Dus besloot ik een NodeMCU D1 mini als realtime controller aan de robot toe te voegen. Het was verbonden met de Raspberry Pi door de seriële UART om de verwerkte sensorgegevens te leveren. De NodeMCU beheerde ook de HC-SR04-sensor. De mechanica was moeilijk en niet erg robuust, de seriële lijn kreeg ruis van de I2C-lijn en de motoren, dus uiteindelijk bouwde ik de tweede versie van het chassis met eenvoudige DC-versnellingsmotoren aangedreven door een H-brug. Deze motoren hebben een secundaire uitgaande as om een optische encoder te plaatsen.

Stap 8: Beeldverwerking

Afbeelding verwerken
Afbeelding verwerken
Afbeelding verwerken
Afbeelding verwerken
Afbeelding verwerken
Afbeelding verwerken
Afbeelding verwerken
Afbeelding verwerken

Om het autonoom rijden te verbeteren, kunnen we wat beeldverwerking doen.

De opencv-bibliotheek is daarvoor een referentie. Het kan door Python worden gebruikt om obstakeldetectie snel te implementeren.

We leggen een afbeelding vast en passen enkele beeldverwerkingstaken toe:

De eerste tests zijn gedaan met Canny- en Sobel-transformaties. Canny kan een goede kandidaat zijn, maar is niet verstandig genoeg. Sobel is te gevoelig (te veel objecten gedetecteerd).

Eindelijk heb ik mijn eigen filter gemaakt om alle horizontale en verticale gradiënten te mengen (meubels detecteren):

  • Transformeer de kleurenafbeelding naar een grijswaardenafbeelding
  • Vervaag de afbeelding om kleine ruis te verwijderen
  • Drempel de afbeelding tot een zwart-witafbeelding
  • Nu detecteren we horizontale en verticale gradiënten om objecten als muren en meubels te detecteren
  • We filteren alleen de grote resterende contouren (zie gekleurde contouren in de afbeelding)

Nu kunnen we deze nieuwe informatie gebruiken om obstakels te detecteren…

Stap 9: Volgende stappen…

Volgende stappen…
Volgende stappen…
Volgende stappen…
Volgende stappen…

Nu hebben we een eenvoudig robotplatform met sensoren, actuatoren en een camera. Mijn doel is om autonoom te bewegen en terug te gaan naar het station zonder verdere sensoren toe te voegen. Hiervoor heb ik de volgende stappen nodig:

  • Sensorfusie van gier- en magnetische koerssignalen
  • Camerabeeldverwerking (alleen lage CPU beschikbaar daarvoor)
  • Botsingsdetectie (ultrasone afstand en camera)
  • Kaartopbouw of oriëntatie

Ga nu en creëer je eigen uitdagingen of doelen…

Aanbevolen: