Cuprins:

Rpibot - Despre învățarea roboticii: 9 pași
Rpibot - Despre învățarea roboticii: 9 pași

Video: Rpibot - Despre învățarea roboticii: 9 pași

Video: Rpibot - Despre învățarea roboticii: 9 pași
Video: rpibot 2024, Iulie
Anonim
Rpibot - Despre învățarea roboticii
Rpibot - Despre învățarea roboticii

Sunt inginer software încorporat într-o companie germană de automobile. Am început acest proiect ca o platformă de învățare pentru sistemele încorporate. Proiectul a fost anulat devreme, dar mi-a plăcut atât de mult încât am continuat în timpul liber. Acesta este rezultatul …

Am avut următoarele cerințe:

  • Hardware simplu (accentul este software-ul)
  • Hardware ieftin (aproximativ 100 €)
  • Extensibil (unele opțiuni fac deja parte din descriere)
  • Tensiunea de alimentare pentru toate componentele dintr-o singură sursă de 5V (powerbank)

Nu a existat cu adevărat un scop în afară de învățare. Platforma poate fi utilizată pentru învățare, supraveghere, concursuri robotice, …

Nu este un tutorial pentru începători. Aveți nevoie de cunoștințe de bază despre:

  • Programare (Python)
  • Electronică de bază (pentru a conecta modulele împreună cu tensiunea corectă)
  • Teoria controlului de bază (PID)

În cele din urmă, probabil că vă veți confrunta cu probleme așa cum am făcut-o eu. Cu o oarecare curiozitate și rezistență, veți trece prin proiect și veți rezolva provocările. Codul meu este cât se poate de simplu și liniile de cod critice sunt comentate pentru a oferi sugestii.

Codul sursă complet și fișierele sunt disponibile aici:

Provizii:

Mecanică

  • 1x placă de placaj (dimensiune A4, grosime 4 mm)
  • 3x M4 x 80 Șurub și piuliță
  • 2x motoare cu angrenaje cu arbore de ieșire secundar pentru codificator. Roți.
  • 1x roată liberă

1x montare cameră panoramică și înclinată (opțional)

Electronică

  • 1x Raspberry Pi Zero cu antet și cameră
  • 1 servocontrol PCA 9685
  • 2x roată și circuit optic pentru codificator
  • 1x fire jumper feminin
  • 1x powerbank USB
  • 1 driver DRV8833 cu motor dublu
  • 2x micro servo SG90 pentru panoramarea și înclinarea camerei (opțional)
  • 1x MPU9250 IMU (opțional)
  • 1x senzor de distanță cu ultrasunete HC-SR04 (opțional)
  • 1x placă perforată și sârmă de lipit, anteturi, …

Pasul 1: Construiți șasiul

Construiți șasiul
Construiți șasiul
Construiți șasiul
Construiți șasiul
Construiți șasiul
Construiți șasiul

Nu sunt un bun proiectant mecanic. De asemenea, scopul proiectului nu este să petreceți prea mult timp în șasiu. Oricum am definit următoarele cerințe:

  • Materiale ieftine
  • Asamblare și demontare rapidă
  • Extensibil (de exemplu, spațiu pentru senzori adăugați)
  • Materiale ușoare pentru a economisi energie pentru electronice

Un șasiu ușor și ieftin poate fi realizat din placaj. Este ușor de prelucrat cu un ferăstrău și un burghiu manual. Puteți lipi piese mici din lemn pentru a crea suporturile pentru senzori și motoare.

Gândiți-vă la înlocuirea componentelor defecte sau la depanarea electrică. Părțile principale trebuie fixate cu șuruburi pentru a fi înlocuibile. Un pistol cu lipici fierbinte poate fi simplu, dar probabil nu este cel mai bun mod de a construi un șasiu … Am avut nevoie de mult timp pentru a mă gândi la un concept ușor de dezasamblare a pieselor cu ușurință. Imprimarea 3D este o alternativă bună, dar poate fi destul de costisitoare sau consumatoare de timp.

Roata liberă este în cele din urmă foarte ușoară și ușor de montat. Alternativele erau toate grele sau pline de frecare (am încercat câteva dintre ele înainte de a găsi ultima). A trebuit să tai un distanțier din lemn pentru a nivela roata fără coadă după montarea roților principale.

Proprietățile roții (pentru calcule software)

Circumferință: 21, 5 cm Impulsuri: 20 impulsuri / tur Rezoluție: 1, 075 cm (în cele din urmă 1 impuls este de aproximativ 1 cm, ceea ce este ușor pentru calculele software)

Pasul 2: Electronică și cablare

Electronică și cablare
Electronică și cablare
Electronică și cablare
Electronică și cablare
Electronică și cablare
Electronică și cablare

Proiectul utilizează diferite module așa cum se arată pe diagramă.

Raspberry Pi Zero este controlerul principal. Citește senzorii și controlează motoarele printr-un semnal PWM. Este conectat la un computer la distanță prin wifi.

DRV8833 este o punte H cu motor dublu. Oferă curent suficient motoarelor (ceea ce Raspberry Pi nu poate face, deoarece ieșirile pot furniza doar o parte din mA).

Codificatorul optic oferă un semnal de formă pătrată de fiecare dată când lumina trece prin roțile codificatorului. Vom folosi întreruperile HW ale Raspberry Pi pentru a obține informațiile de fiecare dată când semnalul se comută.

PCA9695 este o placă servo de control. Comunică printr-o magistrală serial I2C. Această placă furnizează semnalele PWM și tensiunea de alimentare care controlează servomotoarele pentru înclinarea și înclinarea camerei.

MPU9265 este o accelerare pe 3 axe, o viteză de rotație unghiulară pe 3 axe și un senzor de flux magnetic pe 3 axe. Îl vom folosi în principal pentru a obține direcția busolei.

Diferitele module sunt toate conectate împreună prin cablu. O placă de acționare acționează ca dispecer și asigură tensiuni de alimentare (5V și 3.3V) și soluri. Conexiunile sunt descrise în tabelul de conexiuni (a se vedea atașamentul). Conectarea 5V la o intrare de 3,3V va distruge probabil cipul. Aveți grijă și verificați toate cablurile de două ori înainte de alimentare (aici mai ales trebuie luat în considerare codificatorul). Ar trebui să măsurați principalele tensiuni de alimentare pe placa de expediere cu un multimetru înainte de a conecta toate plăcile. Modulele au fost fixate cu șuruburi de nailon în șasiu. Tot aici am fost fericit că le-am reparat, dar și amovibile în caz de defecțiune.

Singura lipire a fost în cele din urmă motoarele, panoul și anteturile. Sincer să fiu, îmi plac firele jumper, dar pot duce la o conexiune slabă. În unele situații, unele monitorizări software vă pot sprijini în analiza conexiunilor.

Pasul 3: Infrastructură software

Infrastructură software
Infrastructură software
Infrastructură software
Infrastructură software

După realizarea mecanicii, vom configura o infrastructură software pentru a avea condiții de dezvoltare confortabile.

Git

Acesta este un sistem de control al versiunilor gratuit și open source. Este folosit pentru a gestiona proiecte mari ca Linux, dar poate fi utilizat cu ușurință și pentru proiecte mici (vezi Github și Bitbucket).

Modificările proiectului pot fi urmărite local și, de asemenea, trimise către un server la distanță pentru a partaja software-ul cu comunitatea.

Principalele comenzi utilizate sunt:

git clone https://github.com/makerobotics/RPIbot.git [Obțineți codul sursă și configurația git]

git pull origin master [obține cele mai recente din depozitul de la distanță]

git status [obțineți starea depozitului local. Există fișiere modificate?] Jurnal git [obțineți lista comitetelor] git add. [adăugați toate fișierele modificate la etapă pentru a fi luate în considerare pentru următorul commit] git commit -m "comentariu pentru commit" [comite modificările la depozitul local] git push origin master [împingeți toate commit-urile la depozitul la distanță]

Logare

Python oferă câteva funcții de logare încorporate. Structura software ar trebui să definească deja întregul cadru de înregistrare înainte de a începe dezvoltarea ulterioară.

Înregistratorul poate fi configurat pentru a se juca cu un format definit în terminal sau într-un fișier jurnal. În exemplul nostru, loggerul este configurat de clasa serverului web, dar am putea face acest lucru și pe cont propriu. Aici stabilim doar nivelul de înregistrare la DEBUG:

logger = logging.getLogger (_ nume_)

logger.setLevel (logging. DEBUG)

Măsurare și reprezentare grafică

Pentru a analiza semnalele în timp, cel mai bine este să le trasați într-o diagramă. Deoarece Raspberry Pi are doar un terminal de consolă, vom urmări datele într-un fișier CSV separat cu punct și virgulă și le vom trasa de pe computerul de la distanță.

Fișierul de urmărire separat cu punct și virgulă este generat de codul nostru principal python și trebuie să aibă anteturi de genul acesta:

timestamp; 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;

Prima coloană conține marcajul de timp. Următoarele coloane sunt gratuite. Scriptul de graficare este apelat cu o listă de coloane de trasat:

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

Scriptul de complot este disponibil în dosarul instrumentului:

Plotterul folosește mathplotlib în Python. Trebuie să îl copiați în computer.

Pentru mai mult confort, scriptul python este apelat de un script bash (plot.sh) care este utilizat pentru a copia fișierul de urmărire Raspberry Pi pe computerul de la distanță și a apela plotterul cu o selecție de semnal. Scriptul bash „plot.sh” întreabă dacă fișierul trebuie copiat. Acest lucru a fost mai convenabil pentru mine în loc să copiez manual de fiecare dată. „sshpass” este folosit pentru a copia fișierul de pe Raspberry Pi pe computerul de la distanță prin scp. Este capabil să copieze un fișier fără a cere parola (este trecut ca parametru).

În cele din urmă, se deschide o fereastră cu complotul, așa cum se arată în imagine.

Comunicare la distanță

Interfața de dezvoltare a Raspberry Pi este SSH. Fișierele pot fi editate direct pe țintă sau copiate de scp.

Pentru a controla robotul, un server web rulează pe Pi, oferind control prin Websockets. Această interfață este descrisă în pasul următor.

Configurați Raspberry Pi

Există un fișier care descrie configurarea Raspberry Pi în folderul „doc” al codului sursă (setup_rpi.txt). Nu există multe explicații, dar multe comenzi și linkuri utile.

Pasul 4: Interfața cu utilizatorul

Interfața utilizatorului
Interfața utilizatorului

Folosim serverul web ușor Tornado pentru a găzdui interfața cu utilizatorul. Este un modul Python pe care îl numim când pornim software-ul de control al robotului.

Arhitectura software

Interfața cu utilizatorul este construită prin următoarele fișiere: gui.html [Descrierea controalelor și aspectului paginii web] gui.js [Conține codul javascript pentru a gestiona comenzile și a deschide o conexiune websocket la robotul nostru] gui.css [Conține stilurile de comenzile html. Pozițiile comenzilor sunt definite aici]

Comunicarea websocket

Interfața cu utilizatorul nu este cea mai tare, dar face treaba. M-am concentrat aici pe tehnologii noi pentru mine, cum ar fi Websockets.

Site-ul web comunică cu serverul web al robotului prin Websockets. Acesta este un canal de comunicare bidirecțional care va rămâne deschis pe măsură ce conexiunea a fost inițiată. Trimitem comenzile robotului prin Websocket către Raspberry Pi și obținem informații (viteză, poziție, fluxul camerei) înapoi pentru afișare.

Aspectul interfeței

Interfața cu utilizatorul are o intrare manuală pentru comenzi. Aceasta a fost utilizată la început pentru a trimite comenzi către robot. O casetă de selectare activează și dezactivează fluxul camerei. Cele două glisoare controlează panoramarea și înclinarea camerei. Partea din dreapta sus a interfeței utilizatorului controlează mișcarea roboților. Puteți controla viteza și distanța țintă. Informațiile de bază despre telemetrie sunt afișate în desenul robotului.

Pasul 5: Programarea platformei robot

Programarea platformei robot
Programarea platformei robot
Programarea platformei robot
Programarea platformei robot
Programarea platformei robot
Programarea platformei robot

Această parte a fost scopul principal al proiectului. Am refactorizat o mulțime de programe software când am introdus noul șasiu cu motoarele de curent continuu. Am folosit Python ca limbaj de programare din diferite motive:

  • Este limba principală Raspberry Pi
  • Este un limbaj de nivel înalt, cu multe funcții și extensii încorporate
  • Este orientat obiect, dar poate fi folosit și pentru programarea secvențială
  • Nu este necesară nicio compilație și nici un lanț de instrumente. Editați codul și rulați-l.

Arhitectura software principală

Software-ul este orientat pe obiecte, împărțit în câteva obiecte. Ideea mea a fost să împart codul în 3 blocuri funcționale:

Sense Think Actuate

Sense.py

Achiziționarea și procesarea senzorului principal. Datele sunt stocate într-un dicționar pentru a fi utilizate în următoarea etapă.

Control.py

O subclasă de acționare controlează motoarele și servo-urile după o anumită abstracție. Obiectul principal de control gestionează comenzile de nivel înalt și algoritmii de control (PID) pentru motor.

rpibot.py

Acest obiect principal este gestionarea serverului web Tornado și instanțierea claselor de sens și control în fire separate.

Fiecare modul poate fi rulat singur sau ca parte a întregului proiect. Puteți detecta și imprima doar informațiile senzorului pentru a verifica dacă senzorii sunt conectați corect și pentru a furniza informațiile corecte.

Controlul PID

Prima sarcină este să aflăm ce vrem să controlăm. Am început încercând să controlez poziția, care era foarte complexă și nu ajuta foarte mult.

În cele din urmă, dorim să controlăm viteza fiecărei roți și, de asemenea, direcția robotului. Pentru a face acest lucru, trebuie să punem în cascadă două logici de control.

Pentru a crește complexitatea pas cu pas, robotul trebuie controlat:

bucla deschisa (cu o putere constanta)

pwm = K

apoi adăugați algoritmul de buclă închisă

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

și, în cele din urmă, adăugați controlul direcției ca ultim pas.

Pentru controlul vitezei am folosit un control "PI" și "P" numai pentru gălăgie. Am setat manual parametrii experimentând. Probabil că aici ar putea fi folosiți parametri mult mai buni. Ținta mea era doar o linie dreaptă și aproape că o am. Am creat o interfață în software pentru a scrie câteva variabile de către interfața cu utilizatorul. Setarea parametrului Kp la 1.0 necesită următoarea comandă în interfața utilizatorului:

SET; Kp; 1.0

Aș putea seta parametrul P suficient de scăzut pentru a evita orice depășire. Eroarea rămasă este corectată de parametrul I (eroare integrată)

Mi-a fost greu să aflu cum să pun în cascadă ambele comenzi. Soluția este simplă, dar am încercat multe alte modalități înainte … Deci, în cele din urmă, am schimbat ținta de viteză a roților pentru a mă roti într-o direcție sau alta. Schimbarea directă a ieșirii controlului vitezei a fost o eroare, deoarece controlul vitezei încerca să elimine această perturbație.

Schema de control utilizată este atașată. Afișează doar partea stângă a comenzii robotului.

Pasul 6: Calibrările senzorului

Calibrările senzorilor
Calibrările senzorilor
Calibrările senzorilor
Calibrările senzorilor
Calibrările senzorilor
Calibrările senzorilor

Primul lucru de luat în considerare este că întreaga IMU trebuie să funcționeze corect. Am comandat 3 piese și le-am trimis înapoi până când am avut un senzor complet de lucru. Fiecare senzor anterior avea unele părți ale senzorului care nu funcționează corect sau deloc. Am folosit câteva exemple de scripturi pentru a testa elementele de bază înainte de a-l monta în robot.

Semnalele senzorului IMU trebuie calibrate înainte de al utiliza. Unele semnale ale senzorului depind de unghiul și poziția de montare.

Calibrarea vitezei de accelerație și rotație

Cea mai ușoară calibrare este pentru accelerația longitudinală (A_x). La staționare ar trebui să existe aproximativ 0 m / s². Dacă rotiți corect senzorul, puteți măsura gravitația (în jur de 9, 8 m / s²). Pentru a calibra a_x, trebuie doar să îl montați corect și apoi să definiți decalajul pentru a obține 0 m / s² la staționare. Acum A_x este calibrat. Puteți obține compensările pentru viteza de rotație într-un mod similar, în repaus.

Calibrarea magnetometrului pentru busolă

Este necesară o calibrare mai complexă pentru senzorii de câmp magnetic. Vom folosi m_x și m_y pentru a obține câmpul magnetic la nivel orizontal. Având m_x și m_y ne va oferi posibilitatea de a calcula o direcție a busolei.

În scopul nostru simplu, vom calibra abaterea fierului dur. Aceasta trebuie efectuată deoarece senzorul se află în poziția finală, deoarece depinde de perturbațiile câmpului magnetic.

Înregistrăm m_x și m_y în timp ce rotim robotul în jurul axei z. Tragem m_x vs m_y într-o diagramă XY. Rezultatul într-o elipsă așa cum se arată în imagine. Elipsa trebuie centrată la origine. Aici considerăm valorile maxime și minime ale m_x și m_y pentru a obține compensările în ambele direcții. În cele din urmă verificăm calibrarea și vedem că elipsa este acum centrată.

Calibrarea fierului moale ar însemna că schimbăm imaginea dintr-o elipsă în cerc. Acest lucru se poate face prin adăugarea unui factor pe fiecare valoare a senorului.

O rutină de testare poate fi acum codificată pentru a recalibra sau cel puțin pentru a verifica dacă senzorii sunt încă calibrați.

Direcția busolei

Datele magnetometrului vor fi folosite acum pentru a calcula direcția busolei. Pentru aceasta, trebuie să convertim semnalele m_x și m_y într-un unghi. Python furnizează direct funcția math.atan2 care are acest obiectiv. Calculul complet este definit în fișierul mpu9250_i2c.py ("calcHeading (mx, my, mz)").

Pasul 7: modele alternative

Modele alternative
Modele alternative
Modele alternative
Modele alternative
Modele alternative
Modele alternative

Proiectul a durat mult timp, deoarece designul a fost complet deschis. Pentru fiecare componentă am realizat unele implementări prototip și am experimentat limitele sistemului.

Cel mai complex subiect a fost codificatorul de roți. Am testat 3 opțiuni diferite înainte de a găsi codificatorul optic utilizat în prezent. Cred că soluțiile avortate sunt, de asemenea, foarte interesante într-un astfel de proiect. Se referă la părțile în care am învățat cel mai mult.

Servo de rotație continuă conectat la pca 9695

Pentru a evita o punte H suplimentară pentru un motor DC, am început mai întâi cu servouri de rotație continuă. Acestea au fost conduse de servo-driverul pca 9695 deja prezent. Toate mecanica de propulsie și electronica corespondentă erau mult mai simple. Acest design avea două dezavantaje:

  • Gama de control slabă a servo-urilor.
  • Codificatorul lipsă care deține locația

Servo-urile încep să se miște cu 50% pwm și au viteză maximă la aproximativ 55%. Acesta este un domeniu de control foarte slab.

Fără un codificator, a fost foarte dificil să găsim un codificator gata de utilizare. Am testat 3 codificatoare de reflectanță diferite care au fost montate pe șasiu. Am înregistrat o roată de codificare auto-fabricată pe exteriorul roții cu secțiuni alb-negru. Am folosit senzorii QTR-1RC care necesită multă procesare a semnalului pentru a obține semnalul potrivit. Raspberry Pi nu a reușit să efectueze acest tip de procesare în timp real. Așa că am decis să adaug un robot NodeMCU D1 mini ca controler în timp real la robot. A fost conectat la raspberry Pi prin serialul UART pentru a livra datele procesate ale senzorului. NodeMCU gestiona, de asemenea, senzorul HC-SR04. Mecanica era dificilă și nu foarte robustă, linia de serie obținea zgomot de la linia I2C și de la motoare, așa că, în cele din urmă, am construit a doua versiune a șasiului cu motoare de curent continuu simple cu transmisie. un pod H. Aceste motoare au un arbore de ieșire secundar pentru a plasa un codificator optic.

Pasul 8: Prelucrarea imaginilor

Procesarea imaginii
Procesarea imaginii
Procesarea imaginii
Procesarea imaginii
Procesarea imaginii
Procesarea imaginii
Procesarea imaginii
Procesarea imaginii

Pentru a îmbunătăți conducerea autonomă, putem face unele prelucrări de imagine.

Biblioteca opencv este o referință pentru asta. Poate fi folosit de Python pentru a implementa rapid detectarea obstacolelor.

Capturăm o imagine și aplicăm câteva sarcini de procesare a imaginii:

Primele teste au fost făcute cu transformările Canny și Sobel. Canny poate fi un candidat bun, dar nu este suficient de sensibil. Sobel este prea sensibil (se detectează prea multe obiecte).

În cele din urmă mi-am făcut propriul filtru pentru a amesteca toate gradientele orizontale și verticale (detectarea mobilierului):

  • Transformați imaginea color într-o imagine de nivel de gri
  • Estompați imaginea pentru a elimina zgomotul mic
  • Pragul imaginii la o imagine alb-negru
  • Acum detectăm gradiente orizontale și verticale pentru a detecta obiecte ca pereți și mobilier
  • Filtrăm doar marile contururi rămase (vezi contururile colorate din imagine)

Acum putem folosi aceste noi informații pentru a detecta obstacolele …

Pasul 9: Pașii următori …

Pasii urmatori…
Pasii urmatori…
Pasii urmatori…
Pasii urmatori…

Acum, avem o platformă robotică simplă cu senzori, actuatoare și o cameră. Scopul meu este să mă mișc autonom și să mă întorc la stație fără a mai adăuga senzori. Pentru aceasta, voi avea nevoie de următorii pași:

  • Fuziunea senzorilor de semnale de direcție și magnetice
  • Prelucrarea imaginii camerei foto (este disponibil doar CPU cu acest nivel scăzut)
  • Detectarea coliziunilor (distanță cu ultrasunete și cameră)
  • Construirea sau orientarea hărții

Acum du-te și creează-ți propriile provocări sau ținte …

Recomandat: