Innehållsförteckning:

Rpibot - Om lärande robotik: 9 steg
Rpibot - Om lärande robotik: 9 steg

Video: Rpibot - Om lärande robotik: 9 steg

Video: Rpibot - Om lärande robotik: 9 steg
Video: Святая Русь, Великая и Малая Русь - это церковные термины. 2024, November
Anonim
Rpibot - Om lärande robotik
Rpibot - Om lärande robotik

Jag är en inbyggd programvaruingenjör i ett tyskt bilföretag. Jag startade det här projektet som en lärande plattform för inbyggda system. Projektet avbröts tidigt men jag trivdes så bra att jag fortsatte på fritiden. Detta är resultatet …

Jag hade följande krav:

  • Enkel hårdvara (fokus är programvaran)
  • Billig hårdvara (ca 100 €)
  • Expanderbart (vissa alternativ är redan en del av beskrivningen)
  • Matningsspänning för alla komponenter från en enda 5V -källa (powerbank)

Det fanns egentligen inget mål förutom lärande. Plattformen kan användas för lärande, övervakning, robotiska tävlingar, …

Det är inte en nybörjarhandledning. Du behöver lite grundläggande kunskap om:

  • Programmering (Python)
  • Grundläggande elektronik (för att ansluta moduler tillsammans med rätt spänning)
  • Grundläggande kontrollteori (PID)

Slutligen kommer du förmodligen att få problem som jag. Med viss nyfikenhet och uthållighet kommer du att gå igenom projektet och lösa utmaningarna. Min kod är så enkel som möjligt och de kritiska kodraderna kommenteras för att ge tips.

Den fullständiga källkoden och filerna är tillgängliga här:

Tillbehör:

Mekanik

  • 1x plywoodskiva (A4 -storlek, 4 mm tjock)
  • 3x M4 x 80 Skruv och mutter
  • 2x växelmotorer med sekundär utgående axel för pulsgivare. Hjul.
  • 1x gratis hjul

1x Pan och tilt kamera montering (tillval)

Elektronik

  • 1x Raspberry Pi Zero med sidhuvud och kamera
  • 1x PCA 9685 servokontroll
  • 2x optiskt givarhjul och krets
  • 1x kvinnliga bygelkablar
  • 1x USB powerbank
  • 1x DRV8833 dubbelmotordrivrutin
  • 2x Micro servos SG90 för kamerapanel och lutning (tillval)
  • 1x MPU9250 IMU (tillval)
  • 1x ultraljudavståndssensor HC-SR04 (tillval)
  • 1x perforerad kartong och lödtråd, sidhuvuden, …

Steg 1: Bygg chassit

Bygg chassit
Bygg chassit
Bygg chassit
Bygg chassit
Bygg chassit
Bygg chassit

Jag är ingen bra mekaniker. Projektets mål är inte att spendera för mycket tid i chassit. Hur som helst definierade jag följande krav:

  • Billiga material
  • Snabb montering och demontering
  • Utbyggbart (t.ex. plats för extra sensorer)
  • Lätta material för att spara energi för elektroniken

Ett enkelt och billigt chassi kan tillverkas av plywood. Det är lätt att bearbeta med en fräsåg och en handborr. Du kan limma små trädelar för att skapa hållare för sensorer och motorer.

Tänk på byte av defektkomponenter eller elektrisk felsökning. Huvuddelarna ska fixeras med skruvar för att kunna bytas ut. En varm limpistol kan vara enkel, men förmodligen inte det bästa sättet att bygga ett chassi … Jag behövde mycket tid att tänka på ett enkelt koncept för att enkelt demontera delarna. 3D -utskrift är ett bra alternativ, men kan vara ganska dyrt eller tidskrävande.

Det fria hjulet är äntligen väldigt lätt och lätt att montera. Alternativen var alla tunga eller fulla av friktion (jag försökte ett par av dem innan jag hittade det sista). Jag var tvungen att bara klippa av en distans av trä för att jämna ut det svansfria hjulet efter att ha monterat huvudhjulen.

Hjulegenskaper (för mjukvaruberäkningar)

Omkrets: 21, 5 cm Pulser: 20 pulser/varv Upplösning: 1, 075 cm (slutligen är 1 puls cirka 1 cm, vilket är enkelt för mjukvaruberäkningar)

Steg 2: Elektronik och ledningar

Elektronik och ledningar
Elektronik och ledningar
Elektronik och ledningar
Elektronik och ledningar
Elektronik och ledningar
Elektronik och ledningar

Projektet använder olika moduler enligt diagrammet.

Raspberry Pi Zero är huvudkontrollen. Den läser sensorerna och styr motorerna med en PWM -signal. Den är ansluten till en fjärrdator via wifi.

DRV8833 är en dubbelmotor H-bro. Det ger tillräckligt med ström till motorerna (vilket Raspberry Pi inte kan göra eftersom utgångarna bara kan leverera lite mA).

Den optiska kodaren ger en fyrkantig signal varje gång ljuset går genom kodarhjulen. Vi kommer att använda HW -avbrotten i Raspberry Pi för att få informationen varje gång signalen växlar.

Pca9695 är ett servokontrollkort. Den kommunicerar med en I2C -seriell buss. Detta kort levererar PWM -signaler och matningsspänning som styr servon för panorering och lutning av kammen.

MPU9265 är en 3-axlig acceleration, 3-axlig vinkelrotationshastighet och 3-axlig magnetisk flödessensor. Vi kommer att använda den främst för att få kompassen på väg.

De olika modulerna är alla sammankopplade med bygelkabel. En brödbräda fungerar som en avsändare och ger matningsspänningar (5V och 3.3V) och jord. Anslutningarna beskrivs alla i anslutningstabellen (se bilaga). Om du ansluter 5V till en 3.3V -ingång kommer du förmodligen att förstöra ditt chip. Var försiktig och kontrollera alla dina ledningar två gånger innan du levererar (speciellt här måste kodaren övervägas). Du bör mäta huvudmatningsspänningarna på avsändarkortet med en multimeter innan du ansluter alla kort. Modulerna fixerades med nylonskruvar i chassit. Även här var jag glad att få dem fixade men också borttagbara vid fel.

Den enda lödningen var slutligen motorerna och brödbrädan och sidhuvud. För att vara ärlig gillar jag hopparkablarna men de kan leda till lös anslutning. I vissa situationer kan vissa programövervakningar hjälpa dig att analysera anslutningarna.

Steg 3: Programvaruinfrastruktur

Programvaruinfrastruktur
Programvaruinfrastruktur
Programvaruinfrastruktur
Programvaruinfrastruktur

Efter att ha uppnått mekaniken kommer vi att skapa en mjukvaruinfrastruktur för att ha bekväma utvecklingsförhållanden.

Git

Detta är ett gratis och öppen källkod versionskontrollsystem. Den används för att hantera stora projekt som Linux, men kan också enkelt användas för små projekt (se Github och Bitbucket).

Projektändringarna kan spåras lokalt och även skickas till en fjärrserver för att dela programvara med gemenskapen.

De viktigaste kommandona är:

git -klon https://github.com/makerobotics/RPIbot.git [Hämta källkoden och git -konfigurationen]

git pull origin master [få det senaste från fjärrförvaret]

git status [få status för det lokala förvaret. Är det några filer ändrade?] Git log [få listan över åtaganden] git add. [lägg till alla ändrade filer till scenen som ska övervägas för nästa åtagande] git commit -m "comment for commit" [begå ändringarna i det lokala förvaret] git push origin master [push all commits to the remote repository]

Skogsavverkning

Python tillhandahåller några inbyggda loggningsfunktioner. Mjukvarustrukturen bör redan definiera alla loggningsramar innan vidareutveckling påbörjas.

Loggaren kan konfigureras för att logga med ett definierat format i terminalen eller i en loggfil. I vårt exempel konfigureras loggaren av webbserverklassen men vi kan också göra det på egen hand. Här ställer vi bara in loggningsnivån till DEBUG:

logger = logging.getLogger (_ namn_)

logger.setLevel (logging. DEBUG)

Mätning och plottning

För att analysera signaler över tid är det bästa att plotta dem i ett diagram. Eftersom Raspberry Pi bara har en konsolterminal kommer vi att spåra data i en semikolonseparerad csv -fil och plotta den från fjärrdatorn.

Den semikolonseparerade spårfilen genereras av vår huvudsakliga pythonkod och måste ha rubriker så här:

tidsstämpel; 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; cycleTime

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;

Den första kolumnen innehåller tidsstämpeln. Följande kolumner är gratis. Plottningsskriptet kallas med en lista över kolumner som ska plottas:

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

Plottskriptet är tillgängligt i verktygsmappen:

Plottern använder mathplotlib i Python. Du måste kopiera den till din dator.

För mer komfort kallas python -skriptet av ett bash -skript (plot.sh) som används för att kopiera Raspberry Pi -spårningsfilen till fjärrdatorn och ringa upp plotteren med ett signalval. Bash -skriptet "plot.sh" frågar om filen måste kopieras. Detta var mer bekvämt för mig istället för att manuellt kopiera varje gång. "sshpass" används för att kopiera filen från Raspberry Pi till fjärrdatorn via scp. Den kan kopiera en fil utan att be om lösenordet (den skickas som en parameter).

Slutligen öppnas ett fönster med tomten som visas på bilden.

Fjärrkommunikation

Utvecklingsgränssnittet till Raspberry Pi är SSH. Filer kan redigeras direkt på målet eller kopieras av scp.

För att styra roboten körs en webbserver på Pi som ger kontroll via Websockets. Detta gränssnitt beskrivs i nästa steg.

Konfigurera Raspberry Pi

Det finns en fil som beskriver installationen av Raspberry Pi i mappen "doc" i källkoden (setup_rpi.txt). Det finns inte många förklaringar men många användbara kommandon och länkar.

Steg 4: Användargränssnittet

Användargränssnittet
Användargränssnittet

Vi använder den lätta Tornado -webbservern för att vara värd för användargränssnittet. Det är en Python -modul som vi kallar när vi startar robotstyrningsprogrammet.

Programvaruarkitektur

Användargränssnittet är byggt av följande filer: gui.html [Beskrivning av webbsidans kontroller och layout] gui.js [Innehåller javascript -koden för att hantera kontrollerna och öppna en websocket -anslutning till vår robot] gui.css [Innehåller stilarna för html -kontrollerna. Kontrollernas positioner definieras här]

Webbsocket kommunikation

Användargränssnittet är inte det coolaste, men det gör jobbet. Jag fokuserade här på teknik som var ny för mig som Websockets.

Webbplatsen kommunicerar med robotens webbserver av Websockets. Detta är en dubbelriktad kommunikationskanal som kommer att förbli öppen när anslutningen initierades. Vi skickar robotens kommandon via Websocket till Raspberry Pi och får information (hastighet, position, kameraström) tillbaka för visning.

Gränssnittets layout

Användargränssnittet har en manuell ingång för kommandona. Detta användes i början för att skicka kommandon till roboten. En kryssruta slår på och av kameraströmmen. De två reglagen styr kamerapanelen och lutningen. Den övre högra delen av användargränssnittet styr robotarnas rörelse. Du kan styra hastigheten och måldistansen. Den grundläggande telemetriinformationen visas på robotritningen.

Steg 5: Programmering av robotplattformen

Programmering av robotplattformen
Programmering av robotplattformen
Programmering av robotplattformen
Programmering av robotplattformen
Programmering av robotplattformen
Programmering av robotplattformen

Denna del var projektets huvudmål. Jag återskapade mycket programvara när jag introducerade det nya chassit med likströmsmotorerna. Jag använde Python som programmeringsspråk av olika anledningar:

  • Det är Raspberry Pi huvudspråk
  • Det är ett språk på hög nivå med många inbyggda funktioner och tillägg
  • Det är objektorienterat men kan också användas för sekventiell programmering
  • Ingen sammanställning eller verktygskedja behövs. Redigera koden och kör den.

Huvudprogramvaruarkitektur

Programvaran är objektorienterad, uppdelad i några få objekt. Min idé var att dela upp koden i tre funktionsblock:

Sense Think Actuate

Sense.py

Huvudsensorn förvärv och bearbetning. Data lagras i en ordlista för att användas i följande steg.

Control.py

En aktiveringsunderklass styr motorer och servon efter en viss abstraktion. Huvudkontrollobjektet hanterar kommandon på hög nivå och även styralgoritmerna (PID) för motorn.

rpibot.py

Detta huvudsyfte är att hantera Tornado -webbservern och instansera känsla- och kontrollklasserna i separata trådar.

Varje modul kan köras ensam eller som en del av hela projektet. Du kan bara känna av och skriva ut sensorinformationen för att kontrollera att sensorerna är korrekt anslutna och ger rätt information.

PID -kontrollen

Första uppgiften är att ta reda på vad vi vill kontrollera. Jag började med att försöka kontrollera positionen, vilket var väldigt komplext och inte hjälpte så mycket.

Slutligen vill vi styra varje hjulhastighet och även robotriktningen. För att göra det måste vi kaskad två kontrolllogiker.

För att öka komplexiteten steg för steg bör roboten styras:

öppen slinga (med konstant effekt)

pwm = K

lägg sedan till slutslingealgoritmen

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

och till sist lägg till riktningskontrollen som ett sista steg.

För hastighetskontrollen använde jag en "PI" -kontroll och "P" endast för gaffeln. Jag ställer in parametrarna manuellt genom att experimentera. Förmodligen kan mycket bättre parametrar användas här. Mitt mål var bara en rak linje och jag fick det nästan. Jag skapade ett gränssnitt i programvaran för att skriva några variabler av användargränssnittet. Inställning av parametern Kp till 1.0 kräver följande kommando i användargränssnittet:

SET; Kp; 1,0

Jag kunde ställa in P -parametern tillräckligt låg för att undvika överskott. Det återstående felet korrigeras med I -parametern (integrerat fel)

Det var svårt för mig att ta reda på hur man skulle kaskadera båda kontrollerna. Lösningen är enkel, men jag försökte många andra sätt innan … Så slutligen ändrade jag hjulens hastighetsmål för att svänga åt det ena eller andra hållet. Att ändra hastighetsregleringens utgång direkt var ett fel eftersom hastighetskontrollen försökte ta bort denna störning.

Det använda kontrollschemat bifogas. Det visar bara den vänstra sidan av robotstyrningen.

Steg 6: Sensorkalibreringar

Sensorkalibreringar
Sensorkalibreringar
Sensorkalibreringar
Sensorkalibreringar
Sensorkalibreringar
Sensorkalibreringar

Det första du bör tänka på är att hela IMU måste fungera korrekt. Jag beställde 3 delar och skickade tillbaka dem tills jag hade en full fungerande sensor. Varje tidigare sensor hade vissa delar av sensorn som inte fungerade korrekt eller inte alls. Jag använde några exempelskript för att testa grunderna innan den monterades i roboten.

IMU -sensorsignalerna måste kalibreras innan de används. Vissa givarsignaler beror på monteringsvinkel och position.

Kalibrering av acceleration och rotationshastighet

Den enklaste kalibreringen är för longitudinell acceleration (A_x). Vid stillastående bör det vara cirka 0 m/s². Om du vrider sensorn korrekt kan du mäta gravitationen (cirka 9, 8 m/s²). För att kalibrera a_x behöver du bara montera den ordentligt och sedan definiera förskjutningen för att få 0 m/s² vid stillastående. Nu är A_x kalibrerad. Du kan få förskjutningarna för rotationshastigheterna på ett liknande sätt vid stillastående.

Magnetometerkalibreringen för kompassen

En mer komplex kalibrering är nödvändig för magnetfältssensorerna. Vi kommer att använda m_x och m_y för att få magnetfältet i horisontell nivå. Att ha m_x och m_y ger oss möjlighet att beräkna en kompassriktning.

För vårt enkla ändamål kommer vi bara att kalibrera den hårda järnavvikelsen. Detta måste utföras eftersom sensorn är i slutläget eftersom det beror på magnetfältstörningar.

Vi registrerar m_x och m_y medan vi vrider roboten runt z-axeln. Vi plottar m_x vs m_y i ett XY -diagram. Resultatet i en ellips som visas på bilden. Ellipsen måste centreras till ursprunget. Här överväger vi max- och minimivärdena för m_x och m_y för att få förskjutningarna i båda riktningarna. Slutligen kontrollerar vi kalibreringen och ser att ellipsen nu är centrerad.

Mjukkalibrering skulle innebära att vi ändrar bilden från en ellips till en cirkel. Detta kan göras genom att lägga till en faktor på varje senorvärde.

En testrutin kan nu kodas för omkalibrering eller åtminstone för att kontrollera att sensorerna fortfarande är kalibrerade.

Kompassens kurs

Magnetometerdata kommer nu att användas för att beräkna kompassriktningen. För detta måste vi konvertera m_x- och m_y -signalerna till en vinkel. Python tillhandahåller direkt math.atan2 -funktionen som har detta mål. Den fullständiga beräkningen definieras i filen mpu9250_i2c.py ("calcHeading (mx, my, mz)").

Steg 7: Alternativa mönster

Alternativa mönster
Alternativa mönster
Alternativa mönster
Alternativa mönster
Alternativa mönster
Alternativa mönster

Projektet tog mycket tid eftersom designen var helt öppen. För varje komponent gjorde jag lite prototypimplementering och upplevde systemets gränser.

Det mest komplexa ämnet var hjulkodaren. Jag testade 3 olika alternativ innan jag hittade den för närvarande använda optiska kodaren. Jag tycker att de avbrutna lösningarna också är väldigt intressanta i ett sådant projekt. Det gäller de delar där jag lärde mig mest.

Kontinuerlig rotationsservo ansluten till PCA 9695

För att undvika en extra H-bro för en likströmsmotor började jag först med kontinuerliga rotationsservos. Dessa drivs av den redan närvarande pca 9695 servodrivrutinen. All framdrivningsmekanik och korrespondentelektroniken var mycket enklare. Denna design hade två nackdelar:

  • Servosens dåliga kontrollområde.
  • Den saknade platsen för kodaren

Servon börjar röra sig med 50% pwm och har full hastighet på cirka 55%. Detta är ett mycket dåligt kontrollområde.

Utan en givare som innehöll var det mycket svårt att hitta en redo att köra. Jag testade 3 olika reflektansgivare som var monterade på chassit. Jag tejpade ett självtillverkat kodarhjul på hjulets utsida med svartvita sektioner. Jag använde QTR-1RC-sensorerna som behöver mycket signalbehandling för att få rätt signal. Raspberry Pi kunde inte utföra den typen av realtidsbehandling. Så jag bestämde mig för att lägga till en NodeMCU D1 mini som en realtidsstyrenhet till roboten. Den var ansluten till hallon Pi med den seriella UART för att leverera de bearbetade sensordata. NodeMCU hanterade också HC-SR04-sensorn. Mekaniken var svår och inte särskilt robust, serielinjen fick ljud från I2C-linjen och motorerna, så slutligen byggde jag den andra versionen av chassit med enkla växelströmsmotorer som drivs av en H-bro. Dessa motorer har en sekundär utgående axel för att placera en optisk kodare.

Steg 8: Bildbehandling

Bildbehandling
Bildbehandling
Bildbehandling
Bildbehandling
Bildbehandling
Bildbehandling
Bildbehandling
Bildbehandling

För att förbättra den autonoma körningen kan vi göra lite bildbehandling.

Opencv -biblioteket är en referens för det. Den kan användas av Python för att snabbt implementera hinderdetektering.

Vi tar en bild och tillämpar några bildbehandlingsuppgifter:

Första tester gjordes med Canny och Sobel transformationer. Canny kan vara en bra kandidat men är inte tillräckligt vettig. Sobel är för vettig (för mycket objekt detekteras).

Slutligen gjorde jag mitt eget filter för att blanda alla horisontella och vertikala lutningar (upptäcka möbler):

  • Förvandla färgbilden till en gråbild
  • Oskärpa bilden för att ta bort små brus
  • Tröskla bilden till en svartvit bild
  • Nu upptäcker vi horisontella och vertikala lutningar för att upptäcka föremål som väggar och möbler
  • Vi filtrerar bara de stora återstående konturerna (se färgade konturer på bilden)

Nu kan vi använda denna nya information för att upptäcka hinder …

Steg 9: Nästa steg …

Nästa steg…
Nästa steg…
Nästa steg…
Nästa steg…

Nu har vi en enkel robotplattform med sensorer, ställdon och en kamera. Mitt mål är att flytta autonomt och gå tillbaka till stationen utan att lägga till ytterligare sensorer. För detta behöver jag följande steg:

  • Sensorsmältning av yaw och magnetiska riktningssignaler
  • Kamerabildbehandling (endast låg CPU tillgänglig för det)
  • Kollisionsdetektering (ultraljudsavstånd och kamera)
  • Kartbyggnad eller orientering

Gå nu och skapa dina egna utmaningar eller mål …

Rekommenderad: