Sommario:

Wallace - Robot autonomo fai da te - Parte 5 - Aggiungi IMU: 9 passaggi
Wallace - Robot autonomo fai da te - Parte 5 - Aggiungi IMU: 9 passaggi

Video: Wallace - Robot autonomo fai da te - Parte 5 - Aggiungi IMU: 9 passaggi

Video: Wallace - Robot autonomo fai da te - Parte 5 - Aggiungi IMU: 9 passaggi
Video: Chi sbaglia paga!! Lo riassumo?! #ruzzaorologi #orologio #fake #audemarspiguet 2024, Dicembre
Anonim
Image
Image

Stiamo procedendo insieme a Wallace. Il nome Wallace derivava da un mix di "Wall-E", e da un progetto precedente (riconoscimento vocale), e nell'usare l'utility "espeak", suonava un po' british. E come un cameriere o un maggiordomo. E questo è l'obiettivo finale: che questo progetto si trasformi in qualcosa di utile. Quindi "Wallace".

Wallace può muoversi, può evitare gli ostacoli usando i sensori di distanza IR (recentemente, in qualche modo hanno fritto (?) (devo esaminarlo quando ne ho la possibilità), ha anche alcuni sensori di distanza acustici (tre di questi sono andati male allo stesso tempo, insieme a un espansore MCP23017) e, infine, può rilevare i cambiamenti nella corrente del motore per sapere quando viene urtato contro qualcosa.

Oltre ai sensori, Wallace "ricorda" le 100 mosse e ha alcune analisi rudimentali utilizzando la cronologia dei movimenti.

L'obiettivo finora per Wallace è semplicemente cercare di continuare ad andare avanti e sapere quando è bloccato in uno schema ripetitivo (come in un angolo) e non si muove davvero in avanti.

Ho attraversato diverse iterazioni per il movimento e la navigazione e il costante mal di testa è stato durante la rotazione.

Dato che Wallace è un robot cingolato e volevo semplificare le cose nel software (per dopo), per girare lo faccio ruotare/ruotare in posizione. Pertanto, applicare ai motori potenza/ciclo di lavoro uguali ma opposti.

Il problema riscontrato è dovuto alla progettazione della piattaforma robot dell'Agente 390. Le cinghie dei cingoli tendono a sfregare contro le fiancate. E peggio, una parte lo fa più dell'altra.

Sul pavimento e andando dritto, non è stato un problema. Si presenta sulla moquette. Ho scelto di tenere Wallace lontano dalla moquette dopo che le sue tracce sono diventate sporche (raccolgono la sporcizia con estrema facilità).

Il vero problema è quando si fa perno sul pavimento.

Se il software applica un ciclo di lavoro di alto livello, gira più o meno costantemente. Tuttavia, durante un ciclo di lavoro basso, può o non può effettivamente girare. Oppure potrebbe girare per un po' e poi rallentare. L'azione di rotazione sembra essere incontrollabile tramite il software, o nella migliore delle ipotesi molto difficile.

Il problema si manifesta durante la navigazione e lo spostamento o l'allontanamento dagli ostacoli. Può oscillare troppo selvaggiamente, oppure può rimanere bloccato nel tentativo di fare spostamenti molto minuti, senza nemmeno muoversi.

E così la spiegazione di cui sopra ha motivato questo Instructable.

Inizialmente, volevo fare a meno o ritardare l'introduzione di un'unità di rilevamento del movimento (IMU), perché sono A) complicate, B) rumorose, C) gli errori possono essere introdotti nel tempo, ecc. Il mio pensiero aveva è stato che potremmo fare molto bene passando ai sensori laser IR a tempo di volo. E potremmo - usando i laser potremmo sapere se il robot ha ruotato o meno, monitorando i cambiamenti di distanza.

In effetti, potremmo anche (più o meno) farlo ora, con i sensori acustici.

Tuttavia, tutto questo è un modo molto indiretto e complicato per rispondere a una semplice domanda: "abbiamo ruotato o no?"

Mi sembrava che saltare a usare i sensori laser ToF mi avrebbe portato al livello successivo del software; vale a dire, SLAM (localizzazione e mappatura simultanee). Non ero ancora pronto per andarci.

È una buona cosa fare un progetto di robot a strati, con i primi strati (inferiori) più semplici e gli ultimi strati (superiori) più astratti e che affrontano problemi più difficili.

I livelli possono essere pensati in questo modo:

  1. struttura fisica del robot / base strutturale meccanica
  2. sistema di azionamento rudimentale (Raspberry, Roboclaw, motori, cablaggio, ecc., software di base, comandato da tastiera)
  3. circuiti essenziali per supportare i sensori (modificatore di tensione bidirezionale, port expander, E-Stop, distribuzione dell'alimentazione, ecc.)
  4. sensori di evitamento ostacoli (acustici, IR)
  5. essenziale, posizionamento di base e rilevamento del movimento (accelerometro, giroscopio, magnetometro, encoder motore, encoder ruota)

Puoi creare la tua lista. I punti su questo elenco sono che probabilmente dovresti farlo più o meno in quell'ordine, e anche che se trascorri un po 'di tempo in ogni livello per ottenere ciascuno un buon stato di funzionamento, ciò dovrebbe aiutarti in seguito man mano che le cose si complicano.

L'elenco di cui sopra potrebbe essere più o meno mappato a questi livelli concettuali nel software.

  • SLAM (localizzazione e mappatura simultanee)
  • Controllo e Consapevolezza del Movimento, Rotazione
  • Evitare gli ostacoli di base
  • Controllo e rilevamento dei dati del sensore
  • Movimento essenziale Avanti, Indietro, Sinistra e Destra, Accelera, Rallenta, Stop

Come puoi vedere, per questo elenco, i primi elementi sarebbero i livelli superiori e più complicati che affrontano questioni e domande più astratte, come "dove sono" e "dove sto andando", mentre gli ultimi elementi sarebbero i livelli software inferiori che gestiscono "come parlare/ascoltare il sensore A" o "come spostare questa ruota".

Ora, non sto dicendo che quando inizi da un livello, lo avrai completato e poi sarà sul livello successivo, per non tornare mai a quello precedente. Un progetto di robot può essere molto simile ai metodi di sviluppo software moderni e iterativi (agile, SCRUM, ecc.).

Sto solo dicendo di prenderti del tempo a ciascuno. Dovrai bilanciare quanto fare in ciascuno e decidere se ciò che stai tentando a un certo livello vale il tempo e i problemi.

C'è un certo "conflitto" o "tensione" tra due idee o direzioni in competizione.

Uno è quello che chiamerei "plug-n-play" per risolvere il problema A.

L'altro è fai da te (fai da te). E questa potrebbe non essere nemmeno l'etichetta migliore per quest'altra idea.

Ecco un esempio di ciascuno, si spera che vedrai la tensione o il conflitto tra le due scelte.

Per questo esempio, consideriamo SLAM, evitamento degli ostacoli e movimento di base essenziale come un problema da risolvere allo stesso tempo.

  1. Se decidiamo di seguire il percorso plug-n-play, saltiamo immediatamente (a seconda del budget) a cose come quei laser rotanti montati in alto, o la fotocamera per la profondità di campo, o i laser ToF e l'IMU (argomento di questo Insegnabile).
  2. Se, d'altra parte, vogliamo seguire la seconda strada, possiamo provare a estrarre ogni possibile informazione da alcuni sensori acustici o sensori IR, o da nessun sensore - usiamo solo il monitoraggio della corrente del motore (bump)

Cosa si può dire di #1 vs #2? Una cosa sarebbe che avremo imparato molto di più facendo #2. I limiti di avere solo sensori acustici con cui lavorare, ci costringe a pensare a molti più problemi.

D'altra parte, se siamo troppo concentrati sul fare le cose tramite #2, potremmo perdere tempo, perché chiediamo più di quanto dovremmo dai sensori acustici.

Un altro concetto o idea su cui riflettere: quale combinazione di hardware e software risponde meglio alle domande su "come fare", e quale combinazione di software (e hardware?) risponde alla domanda su "cosa", "quando", "dove". Perché "come" è in genere una domanda di livello inferiore da cui dipendono "cosa", "quando" e "dove" per ottenere una risposta.

Comunque, tutto quanto sopra era solo qualcosa su cui riflettere.

Nel mio caso, dopo un grande sforzo e dopo aver riscontrato il fastidioso problema dell'attrito della pista e l'impossibilità di ottenere un controllo e un movimento coerenti, è ora di fare qualcos'altro.

Così questo Instructable - un IMU.

L'obiettivo è che se l'IMU dice che il robot NON sta ruotando, aumentiamo il ciclo di lavoro. Se giriamo troppo velocemente, riduciamo il ciclo di lavoro.

Passaggio 1: il sensore IMU

Il sensore IMU
Il sensore IMU
Il sensore IMU
Il sensore IMU

E così il nostro prossimo sensore da aggiungere a Wallace è l'IMU. Dopo alcune ricerche, mi sono deciso su un MPU6050. Ma poi in questo momento, l'MPU9050 (e anche più recentemente, l'MPU9250) sembrava un'idea ancora migliore.

La mia fonte di riferimento è stata Amazon (negli Stati Uniti). Così ne ho ordinati due.

Quello che ho ottenuto in effetti (sembra che non ci sia alcun controllo su questo, questo è quello che non mi piace di Amazon) sono stati due MPU92/65. Mi chiedo un po' sulla designazione. Dai un'occhiata alle immagini; che sembra essere una designazione "famiglia". In ogni caso, è quello che mi blocca.

Aggiungerlo è molto semplice: prendi una scheda proto con tracce di collegamento, salda il sensore alla scheda, aggiungi una morsettiera a vite a 10 pin (la mia l'ho presa da Pololu).

Per ridurre al minimo qualsiasi interferenza, ho cercato di posizionare questi sensori lontano da ogni altra cosa.

Ciò significava anche utilizzare alcuni bulloni/dadi in nylon.

Userò il protocollo I2C. Speriamo che la lunghezza totale del cavo non sia troppo male.

Ci sono molte informazioni altrove sulle connessioni di base e sui livelli di tensione, ecc., Quindi non lo ripeterò qui.

Passaggio 2: le cose non sono sempre pulite, facili

Al momento della stesura, non sembra esserci molto online per questo particolare MPU-92/65. Ciò che è disponibile, proprio come con la maggior parte dei sensori, sembrano essere esempi che utilizzano Arduino.

Cerco di rendere questi Instructables un po' diversi presentando un processo non così pulito, perché le cose non sempre funzionano subito.

Suppongo che questi Instructables siano più simili a un blog che a un semplice A-B-C, 1-2-3 "questo è come lo fai".

Passaggio 3: test iniziale

Test iniziale
Test iniziale
Test iniziale
Test iniziale

Dalle immagini del passaggio precedente, i fili rosso e nero che vanno ai sensori sono ovviamente VCC (5V) e GND. I fili verde e giallo sono le connessioni I2C.

Se hai realizzato altri progetti I2C o hai seguito queste serie, allora conosci già "i2cdetect" e questo è il primo passo per sapere se il Raspberry può vedere il nuovo sensore.

Come puoi vedere dalle immagini in questo passaggio, il nostro primo tentativo non è andato a buon fine. L'IMU non viene visualizzato (dovrebbe essere l'ID dispositivo 0x68).

Tuttavia, la buona notizia è che il bus I2C è operativo. Vediamo un dispositivo 0x20 ed è il port expander MCP23017 (attualmente responsabile dei sensori acustici HCSR04).

Non è facile da vedere nell'immagine, ma ho collegato gli stessi fili colorati verde e giallo dall'IMU all'MCP23017 (vedi in basso a sinistra nell'immagine)

Dovremo fare un po 'di risoluzione dei problemi.

Passaggio 4: risoluzione dei problemi

Image
Image
Risoluzione dei problemi
Risoluzione dei problemi
Risoluzione dei problemi
Risoluzione dei problemi

Usando l'impostazione di continuità su un voltmetro (quello con il tono acuto), ho testato le connessioni VCC (5 V), GND, SDA e SCL. Quelli erano buoni.

Il tentativo successivo è stato scollegare l'MCP23017 dal bus I2C, lasciando solo l'MPU-92/65 sul bus. Ciò si è rivelato infruttuoso: "i2cdetect" non ha mostrato alcun dispositivo.

Quindi, successivamente, ho smontato il sensore dal totem e l'ho ricablato direttamente al bus bidirezionale da 5 V a 3 V; cioè, direttamente al lampone. (cavi più corti?).

E voilà. Questa volta c'è successo. Vediamo 0x68 apparire usando "i2cdetect".

Ma non sappiamo ancora perché questa volta abbia funzionato. Potrebbe essere la lunghezza dei fili? La posizione precedente?

Nota: non faceva alcuna differenza se ADO fosse messo a terra o meno. Potrebbe essere che ci siano resistenze pullup e pulldown integrate. Lo stesso potrebbe essere vero per FSYNC.

Successivamente, ho ricollegato l'MCP23017. Quindi ora abbiamo due dispositivi sul bus I2C. (vedi immagine). Successo, ora vediamo sia 0x20 che 0x68 con i2cdetect.

I video approfondiscono un po 'più di ciò che è successo durante la risoluzione dei problemi.

Passaggio 5: lettura dei dati del sensore

Image
Image
Lettura dei dati del sensore
Lettura dei dati del sensore
Lettura dei dati del sensore
Lettura dei dati del sensore

Vari approcci

Ho deciso di adottare diversi approcci per ottenere informazioni utili dal sensore. Eccoli, non in nessun ordine:

  1. prova un po' di programmazione di base
  2. guarda un po' di documentazione online sui registri
  3. dai un'occhiata agli esempi e/o al codice di altri

Perché questi approcci? Perché non cercare semplicemente qualche libreria o codice esistente?

Sperimentando e provando alcune idee, possiamo assorbire meglio alcune conoscenze non solo su questo particolare sensore, ma anche acquisire una certa tecnica, abilità e modi di pensare per affrontare qualcosa di nuovo e qualcosa che potrebbe non avere molta documentazione; qualcosa che può avere molte incognite.

Inoltre, una volta che abbiamo giocato e provato alcune delle nostre idee e acquisito qualche intuizione, siamo in una posizione migliore per valutare il codice o la libreria di qualcun altro.

Ad esempio, dopo aver esaminato del codice C++ per l'MPU9250 in github, mi sono reso conto che mi stava costringendo a utilizzare gli interrupt, cosa che non desidero ancora fare.

Inoltre, include cose extra come la calibrazione; di nuovo, qualcosa che non mi interessa ancora.

Può essere che ciò che devo fare per rispondere alla semplice domanda "il robot sta ruotando sì o no" potrebbe essere risposto molto semplicemente leggendo alcuni registri.

Registri

Al momento della stesura, non sembra esserci molto disponibile su questo sensore. In effetti, se dai un'occhiata alle immagini fornite con questo Instructable e dai un'occhiata da vicino alle iscrizioni sui chip reali, mi chiedo se questo non sia un knock-off. Non sto collegando ciò che vedo a nulla di Invense. Indipendentemente da ciò, ho scelto di guardare le informazioni di registro per i modelli che ho trovato: l'MPU-6050 e l'MPU-9250.

In entrambi i casi, quanto segue è lo stesso per entrambi. E per cominciare, supponiamo che sarà lo stesso anche per questo MPU-92/65.

da 59 a 64 - misurazioni dell'accelerometro

65, 66 - misurazioni della temperatura da 67 a 72 - misurazioni del giroscopio da 73 a 96 - dati del sensore esterno

Un elemento da notare: l'MPU-6050 sembra NON avere un magnetometro, mentre l'MPU-9250 (e supponiamo anche questo) ne ha uno.

Alcune informazioni più interessanti, si spera utili, raccolte dal documento del registro:

Informazioni sul magnetometro:

id magnetometro: 0x48 registri da 00 a 09: 00H WIA 0 1 0 0 1 0 0 0 01H INFO INFO7 INFO6 INFO5 INFO4 INFO3 INFO2 INFO1 INFO0 02H ST1 0 0 0 0 0 0 DOR DRDY 03H HXL HX7 HX6 HX5 HX4 HX3 HX2 HX1 H HXH HX15 HX14 HX13 HX12 HX11 HX10 HX9 HX8 05H HYL HY7 HZ HY6 HY5 HY4 HY3 HY2 HY1 HY0 06H HYH HY15 HY14 HY13 HY12 HY11 HY10 HY9 HYZZ3 HZH HZH9 HYZZ2 HZH HZHZ7 HZZ6 HZH HZH9 HZ3 HZH HZH9 HZZ HZH ST2 0 0 0 BITM HOFL 0 0 0 una suddivisione del significato di ciascun registro: HXL[7:0]: dati di misurazione dell'asse X inferiori a 8 bit HXH[15:8]: dati di misurazione dell'asse X superiori a 8 bit HYL[7:0]: dati di misurazione dell'asse Y inferiori a 8 bit HYH[15:8]: dati di misurazione dell'asse Y superiori a 8 bit HZL[7:0]: dati di misurazione dell'asse Z inferiori a 8 bit HZH[15:8]: dati di misurazione dell'asse Z superiori 8bit

Programmazione

Un'altra informazione dai documenti del registro è che sembravano esserci solo circa 100 registri. Quindi una tattica potrebbe essere quella di scrivere un semplice programma che acceda al dispositivo (0x68) e tenti di leggere una serie di registri in sequenza, senza riguardo al loro significato, solo per vedere quali dati si possono vedere.

E poi, esegui passaggi successivi, utilizzando lo stesso codice e confronta i dati di un passaggio con il successivo.

L'idea è che potremmo probabilmente eliminare tutti i registri che sembrano non avere dati (zeri o FF ?) o che non cambiano assolutamente mai, e potremmo anche concentrarci su quelli che cambiano.

Quindi, uno stiamo guardando solo quelli che cambiano, aggiungi una funzione di media che fa la media delle ultime N letture di quel registro, per vedere se c'è in effetti un certo valore costante per quel registro. Ciò presupporrebbe che stiamo mantenendo il sensore molto fermo e nella stessa posizione.

Infine, potremmo quindi provare delicatamente le cose con il sensore, come spingerlo (accelerometro, giroscopio) o soffiarci sopra (temperatura) o ruotarlo (i due precedenti più il magnetometro) e vedere che effetto ha sui valori.

Mi piace usare il più possibile la libreria di cablaggioPi. Ha il supporto per I2C.

Prima corsa:

/********************************************************************************

* per compilare: gcc first.test.mpu9265.c -o first.test.mpu9265 -lwiringPi * * per eseguire: sudo./first.test.mpu9265 * * questo programma emette solo una gamma di (possibili) registri dall'MCP23017, * e poi dall'MPU9265 (o qualsiasi altra MPU a quell'indirizzo 0x68) * * L'ho usato per verificare se potevo leggere anche dal sensore, dato che già * avevo fiducia nell'MCP23017. * ************************************************** ****************************/ #include #include #include #include #include int main(int argc, char** argv) { puts("Vediamo cosa ha da dire MCP23017 @ 0x20:"); errore = 0; int deviceId1 = 0x20; int fd1 = cablaggioPiI2CSetup(deviceId1); if (-1 == fd1) { fprintf (stderr, "Impossibile aprire il dispositivo I2C di cablaggioPi: %s\n", strerror (errno)); ritorno 1; } for (int reg=0;reg<300;reg++) { fprintf(stderr, "%d", cablaggioPiI2CReadReg8(fd1, reg));fflush(stderr); ritardo(10); } mette(""); puts("Vediamo cosa ha da dire MPU9265 @ 0x20:"); errore = 0; int deviceId2 = 0x68; int fd2 = cablaggioPiI2CSetup(deviceId2); if (-1 == fd2) { fprintf (stderr, "Impossibile aprire il dispositivo I2C di cablaggioPi: %s\n", strerror (errno)); ritorno 1; } for (int reg=0;reg<300;reg++) { fprintf(stderr, "%d", cablaggioPiI2CReadReg8(fd2, reg));fflush(stderr); ritardo(10); } mette(""); restituisce 0; }

La seconda corsa:

/********************************************************************************

* per costruire: gcc second.test.mpu9265.c -o second.test.mpu9265 -lwiringPi * * per eseguire: sudo./second.test.mpu9265 * * Questo programma emette il numero di registro accanto al valore letto. * * Ciò rende utile reindirizzare (reindirizzare) l'output su un file, e quindi * possono essere eseguite diverse esecuzioni da confrontare. Potrebbe fornire alcune informazioni su * quali registri sono importanti e come potrebbero comportarsi i dati. * ************************************************** ****************************/ #include #include #include #include #include #include int main(int argc, char** argv) { int deviceId = -1; if (0) { } else if (!strncmp(argv[1], "0x20", strlen("0x20"))) { deviceId = 0x20; } else if (!strncmp(argv[1], "0x68", strlen("0x68"))) { deviceId = 0x68; } else if (!strncmp(argv[1], "0x69", strlen("0x69"))) { deviceId = 0x69; } puts("Vediamo cosa ha da dire MPU9265 @ 0x20:"); errore = 0; int fd = cablaggioPiI2CSetup(deviceId); if (-1 == fd) { fprintf (stderr, "Impossibile aprire il dispositivo I2C di cablaggioPi: %s\n", strerror (errno)); ritorno 1; } for (int reg=0;reg<300;reg++) { fprintf(stderr, "%d:%d\n", reg, cablaggioPiI2CReadReg8(fd, reg));fflush(stderr); ritardo(10); } restituisce 0; }

La terza corsa:

/********************************************************************************

* per compilare: gcc third.test.mpu9265.c -o third.test.mpu9265 -lwiringPi * * per eseguire: sudo./terzo.test.mpu9265 * * Questo programma è il risultato del secondo. Legge solo dai registri * che hanno indicato una differenza tra una corsa e la successiva.* ************************************************** ****************************/ #include #include #include #include #include #include int main(int argc, char** argv) { int deviceId = -1; if (0) { } else if (!strncmp(argv[1], "0x68", strlen("0x68"))) { deviceId = 0x68; } else if (!strncmp(argv[1], "0x69", strlen("0x69"))) { deviceId = 0x69; } puts("Vediamo cosa ha da dire MPU9265 @ 0x20:"); errore = 0; int fd = cablaggioPiI2CSetup(deviceId); if (-1 == fd) { fprintf (stderr, "Impossibile aprire il dispositivo I2C di cablaggioPi: %s\n", strerror (errno)); ritorno 1; } for (int reg=61;reg<=73;reg++) { fprintf(stderr, "%d:%d\n", reg, cablaggioPiI2CReadReg8(fd, reg));fflush(stderr); ritardo(10); } for (int reg=111;reg<=112;reg++) { fprintf(stderr, "%d:%d\n", reg, cablaggioPiI2CReadReg8(fd, reg));fflush(stderr); ritardo(10); } for (int reg=189;reg<=201;reg++) { fprintf(stderr, "%d:%d\n", reg, cablaggioPiI2CReadReg8(fd, reg));fflush(stderr); ritardo(10); } for (int reg=239;reg<=240;reg++) { fprintf(stderr, "%d:%d\n", reg, cablaggioPiI2CReadReg8(fd, reg));fflush(stderr); ritardo(10); } restituisce 0; }

Quindi cosa abbiamo imparato finora? L'immagine della tabella con le aree evidenziate colorate indica che l'output sembra corrispondere ai primi set di registri.

I risultati finora possono generare nuove domande.

Domanda: perché c'è un solo risultato di registro per il gruppo "esterno"?

Domanda: cosa sono tutti quei registri sconosciuti "??????"

Domanda: poiché il programma non è guidato da interrupt, ha richiesto dati troppo lentamente? troppo veloce?

Domanda: possiamo influenzare i risultati provando con il sensore stesso mentre funziona?

Passaggio 6: approfondiamo le letture/i dati

Penso che il passo successivo prima di ogni altra cosa sia migliorare il programma per:

  • essere flessibile in quanto loop delay (ms)
  • essere flessibile su quante letture dare una media corrente per registro

(Ho dovuto allegare il programma come file. Sembrava essere un problema inserirlo qui. "fourth.test.mpu9265.c")

Ecco una corsa che utilizza le ultime 10 letture per una media, con un ciclo di 10 ms:

sudo./quarto.test.mpu9265 0x68 10 10

61:255 0 255 0 255 0 255 0 0 0: 102 62:204 112 140 164 148 156 188 248 88 228: 167 63:189 188 189 187 189 188 188 188 188 189: 188 64: 60 40 16 96 208 132 116 252 172 36: 112 65: 7 7 7 7 7 7 7 7 7 7: 7 66:224 224 224 240 160 208 224 208 144 96: 195 67: 0 0 0 0 0 0 0 0 0 0: 0 68:215 228 226 228 203 221 239 208 214 187: 216 69: 0 255 0 255 255 0 255 0 0 0: 102 70:242 43 253 239 239 45 206 28 247 207: 174 71: 0 255 255 0 255 255 255 255 255 255: 204 72: 51 199 19 214 11 223 21 236 193 8: 117 73: 0 0 0 0 0 0 0 0 0 0: 0 111: 46 149 91 199 215 46 142 2 233 199: 132 112: 0 0 0 0 0 0 0 0 0 0: 0 189:255 0 255 0 255 0 0 255 0 255: 127 190: 76 36 240 36 100 0 164 164 152 244: 121 191:188 188 188 188 187 188 187 189 187 189: 187 192: 8 48 48 196 96 220 144 0 76 40: 87 193: 7 7 7 7 7 8 7 7 7 7: 7 194:208 224 144 240 176 240 224 208 240 224: 212 195: 0 0 0 0 0 0 0 0 0 0: 0 196:243 184 233 200 225 192 189 242 188 203: 209 197:255 0 0 0 255 0 255 0 0 255: 102 198:223 39 247 43 245 22 255 221 0 6: 130 199: 0 255 255 255 0 255 255 255 255 0: 178 200:231 225 251 1 252 20 211 216 218 16: 164 201: 0 0 0 0 0 0 0 0 0 0: 0 239: 21 138 196 87 26 89 16 245 187 144: 114 240: 0 0 0 0 0 0 0 0 0 0: 0

La prima colonna più a sinistra è il numero di registro. Poi vengono le ultime 10 letture per quel registro. Infine, l'ultima colonna è la media per ogni riga.

Sembra che i registri 61, 69, 71, 189, 197 e 199 siano solo binari, o pronti/non pronti, oppure siano il byte alto di un valore a 16 bit (negativo?).

Altre osservazioni interessanti:

  • registri 65, 193 - molto stabile e stesso valore
  • registro 63, 191 - molto stabile e stesso valore
  • registri 73, 112, 195, 201, 240 - tutti a zero

Mettiamo in relazione queste osservazioni con l'immagine della tabella evidenziata a più colori di prima.

Registro 65 - temperatura

Registrati 193 - ??????

Registro 63 - accelerometro

Registro 191 - ??????

Registro 73 - esterno

Registrati 112 e oltre - ??????

Ebbene, abbiamo ancora delle incognite, però abbiamo imparato qualcosa di utile.

Il registro 65 (temperatura) e il registro 63 (accelerometro) erano entrambi molto stabili. Questo è qualcosa che ci aspetteremmo. Non ho toccato il sensore; non si muove, a parte eventuali vibrazioni accidentali, poiché il robot è appoggiato sullo stesso tavolo del mio computer.

C'è un test interessante che possiamo fare per ciascuno di questi registri di temperatura/accelerometro. Per quel test, abbiamo bisogno di un'altra versione del programma.

Passaggio 7: siamo in grado di influenzare la temperatura e l'accelerazione

Nei passaggi precedenti abbiamo ristretto almeno un registro per la temperatura e uno per l'accelerazione.

Con questa prossima versione del programma ("fifth.test.mpu9265.c"), possiamo effettivamente vedere un cambiamento per entrambi i registri. Si prega di guardare i video.

Più scavo

Se torniamo indietro e diamo un'occhiata alle informazioni del registro, vediamo che ci sono:

  • tre uscite a 16 bit per giroscopio
  • tre uscite a 16 bit per accelerometro
  • tre uscite a 16 bit per magnetometro
  • un'uscita a 16 bit per la temperatura

Tuttavia, i risultati ottenuti dai nostri semplici programmi di test erano tutti singoli output a 8 bit. (registri unici).

Quindi proviamo più dello stesso approccio, ma questa volta leggendo 16 bit invece di 8.

Probabilmente dovremo fare qualcosa come di seguito. Usiamo la temperatura come esempio, poiché è solo un'uscita a 16 bit.

//ottengo il descrittore di file fd…

int tempRegHi = 65; int tempRegLo = 66; int hiByte = cablaggioPiI2CReadReg8(fd, tempRegHi); int loByte = cablaggioPiI2CReadReg8(fd, tempRegLo); int risultato = hiByte << 8; // inserisce gli 8 bit di ordine alto nella parte superiore di un risultato di valore a 16 bit |= loByte; // ora aggiungi nell'ordine lo 8 bit, ottenendo un numero completo a 16 bit // stampa quel numero o usa la funzione di visualizzazione grafica orizzontale di prima

Dai nostri passaggi precedenti abbiamo visto che il registro 65 è abbastanza stabile, mentre il registro 66 è molto rumoroso. Poiché 65 è il byte di alto ordine e 66 il byte di ordine inferiore, ciò ha senso.

Per la lettura, possiamo prendere i dati del registro 65 così come sono, ma potremmo fare la media dei valori del registro 66.

Oppure possiamo semplicemente fare la media dell'intero risultato.

Dai un'occhiata all'ultimo video di questa parte; dimostra la lettura dell'intero valore di temperatura a 16 bit. Il codice è "sesto.test.mpu9265.c"

Passaggio 8: l'accelerometro e il giroscopio

Image
Image

I video di questa sezione mostrano l'output dell'accelerometro e del giroscopio, utilizzando un programma di test "seventh.test.mpu9265.c". Quel codice può leggere 1, 2 o 3 coppie di byte consecutive (hi e lo byte) e converte i valori in un singolo valore a 16 bit. Quindi, possiamo leggere qualsiasi singolo asse, o possiamo leggerne due insieme (e somma le modifiche), oppure possiamo leggere tutti e tre (e somma le modifiche).

Per ribadire, per questa fase, per questo Instructable, sto solo cercando di rispondere a una semplice domanda: "il robot ha ruotato/ruotato?". Non sto cercando alcun valore preciso, ad esempio, ha ruotato di 90 gradi. Ciò verrà in seguito quando arriveremo a fare SLAM, ma non è necessario per evitare semplici ostacoli e movimenti casuali.

Fase 9: (lavori in corso) il Magnetometro

quando si utilizza lo strumento i2cdetect, l'MPU9265 viene visualizzato come 0x68 nella tabella:

0 1 2 3 4 5 6 7 8 9 a b c d e f

00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --

Sono necessari ulteriori passaggi per leggere dalla parte del magnetometro dell'IMU.

Dal documento PDF dei registri Invesense:

REGISTRI DA 37 A 39 – CONTROLLO I2C SLAVE 0

  • REGISTRO 37 - I2C_SLV0_ADDR
  • REGISTRO 38 - I2C_SLV0_REG
  • REGISTRO 39 - I2C_SLV0_CTRL

Consigliato: