Braccio meccanico: vi presento il mio progetto (è già fatto, tranquilli)

Qui http://www.lynxmotion.com/driver.aspx?Topic=oldvideos#arms trovi una serie di video dimostrativi dei bracci robot di Lynxmotion, usano tutti la SSC32 come servo controller, così ti rendi conto cosa intendo con movimenti fluidi e precisi, e si può fare di meglio :slight_smile:
In diversi video viene utilizzata la cinematica inversa per realizzare movimenti composti coordinati, però questa è solo una questione di analisi matematica.

Si, l'articolo principalmente era per mostrare le traiettorie punto-punto, teoricamente e con un esempio di codice. Non avendo motori DC con encoder adatti.. ho fatto prove con quello che avevo in casa, dei servo low-cost.

Avevo puntato sul fatto che i servo hanno una loro inerzia e dando nuove posizioni da raggiungere prima del raggiungimento della posizione precedente li mantenevo in movimento "forzando" il profilo di movimento originale. Come si vede anche dai grafici, per forza di cose il movimento è comunque scattoso ma ci sono comunque dei miglioramenti come descritto nell'articolo.
Non conoscevo la servo.writeMicroseconds() provvederò ad utilizzarla visto che non comporta grandi cambiamenti di codice, unica cosa ho visto che ha una risoluzione di 1000 step su 180° e non su 90°, quindi una risoluzione di 0.18°, un bel miglioramento comunque rispetto ai 0.7° del servo.write() :smiley:

Ho visto il video, sicuramente non sono come il mio servo low-cost, ho dato un'occhiata anche al sorgente di SSC32 ma è completamente senza documentazione.. :astonished: alcune parti sono scritte in Assembly e non è immediato studiarlo purtroppo.

Ciao

flz47655:
SNon conoscevo la servo.writeMicroseconds() provvederò ad utilizzarla visto che non comporta grandi cambiamenti di codice, unica cosa ho visto che ha una risoluzione di 1000 step su 180° e non su 90°, quindi una risoluzione di 0.18°, un bel miglioramento comunque rispetto ai 0.7° del servo.write() :smiley:

La risoluzione è di 1000 step su 90° perché il comando standard dei servo prevede una variazione compresa tra 1000us e 2000us per 90°, per ottenere 180° l'impulso cambia tra 500us e 2500us.
Non tutti i servo rispettano questo standard, a seconda del produttore e del modello è possibile sia che il punto neutro non si trovi a 1500us e che gli estremi (+/-45°) si trovano a valori minori di 1000 e 2000 us.

Ok, dalla documentazione di Arduino non era chiaro

Writes a value in microseconds (uS) to the servo, controlling the shaft accordingly. On a standard servo, this will set the angle of the shaft. On standard servos a parameter value of 1000 is fully counter-clockwise, 2000 is fully clockwise, and 1500 is in the middle.

Uwe in un intervento diceva Arduino Forum

Con myservo.writeMicrosecond() dai come valore il tempo in µsecondi del impulso dove 1000 corrisponde a 0 di myservo.write() e 2000 a 180

Con queste informazioni avevo dedotto che la risoluzione era 180/(2000-1000) = 0.18°

flz47655:
Ok, dalla documentazione di Arduino non era chiaro

Abbiamo già accertato in più di una occasione che la documentazione di Arduino è errata :slight_smile:

Uwe in un intervento diceva Arduino Forum

Con myservo.writeMicrosecond() dai come valore il tempo in µsecondi del impulso dove 1000 corrisponde a 0 di myservo.write() e 2000 a 180

Non è corretto, del resto basta guardare il datasheet di un qualunque servo per rendersi conto che l'impulso compreso tra 1000us e 2000us è quello per una variazione compresa tra +/- 45° rispetto alla posizione centrale, sono possibili leggeri scostamenti da questi valori a seconda del produttore e del modello.

Ok, grazie

Che tipo di pinza monta il braccio, è di plastica verniciata o alluminio?
Ne sto progettando una simile a 3 dita per tagliarmela poi con la cnc ma se non costa parecchio credo rimando molto volentieri l'autocostruzione :slight_smile:

Dimenticavo: bel progetto, complimenti!

Riguardo la discussione sei servomotori, confesso la mia ignoranza dei dettagli in materia, provvederò a documentarmi meglio. Prossimamente mi piacerebbe tentare di lavorare con l'ATmega "nudo", per tentare un controllo più sofisticato.

La pinza è di alluminio, è questa:

Io ne ho inizialmente costruita una simile, ma il risultato poco soddisfacente mi ha fatto propendere per questo acquisto! Anche perchè è a buon mercato, con meno di 15€ te la porti a casa (senza servo, ovvio).
Unico problema: lì sopra ci puoi montare agevolmente solo uno dei servomotori che ti propongono loro secondo me, io ad esempio ho utilizzato un micro-servo hitec e non si incastrava bene, anche se un po' di colla ha risolto la questione!

Ciao,
A.

ndrplz:
La pinza è di alluminio, è questa:

" Peso: 70 grammi."

Mi sembrano veramente tanti per un oggetto che dovrebbe essere realizzato in lega di alluminio leggera, mi sa tanto che è fatto con un qualche metallo tenero ma pesante.
Tieni presente che quei 70 grammi gravano tutti su i servo moltiplicati per la distanza dal fulcro, già i bracci robot realizzati con servo low cost riescono a sollevare poco se poi vengono gravati da pesi eccessivi delle parti allora non sollevano più nulla :slight_smile:
Un consiglio per chi vuole realizzare un ottimo braccio spendendo il giusto, usate i servo AX12A di Dynamixel, oltre ad essere di tipo digitale ed avere un'elevata coppia (15kg*cm) si controllano tramite una connessione serial onewire multidrop a 1 Mbps (si ottiene facilmente tramite la UART di un 328), non serve il PPM, permettono di impostare tutti i parametri operativi quali velocità e coppia massima, profilo di movimento, comportamento elastico etc, sopratutto permettono di impostare sia lo spazio da percorrere che la velocità di movimento, il che li rende perfetti per la robotica.
Gli AX12A costano circa 50 Euro l'uno, ovvero meno di un buon servo digitale RC e offrono caratteristiche superiori visto che sono progettati specificatamente per la robotica, anche il sistema di fissaggio multiplo e la possibilità di vincolare la squadretta alla carcassa posteriore (carico ripartito in modo omogeneo) sono caratteristiche uniche presenti solo in questi servo.

Complimenti per il progetto come hai interfacciato il nunchuck?

spero che non hai maltrattato altre paperelle di gomma

Iz2rpn:
Complimenti per il progetto come hai interfacciato il nunchuck?

Il Nunchuck si interfaccia ad Arduino tramite il bus I2C, è abbastanza semplice gestirlo, ti allego uno sketch sicuramente funzionante con i Nunchuk originali, legge tutti i dati forniti mettendoli in apposite variabili dedicate e le stampa a video sul monitor seriale.
In testa allo sketch trovi anche come collegare i pin del connettore, oppure lo tagli e fai riferimento ai colori del cavo, non servono pull up per la I2C perché sono presenti internamente al Nunchuck, attenzione che lo sketch è stato scritto con l'IDE 0022, se lo usi con la 1.x tocca aggiornare i nomi delle funzioni per l'I2C.

/*
_________
| 1 2 3 |
|       |
| 6 5 4 |
|_-----_|

•pin 1: verde - data (Arduino analog pin 4) 
•pin 2: (not connected) 
•pin 3: rosso - 3.3V 
•pin 4: giallo - clock (Arduino analog pin 5) 
•pin 5: (not connected) 
•pin 6: bianco - GND 
*/

#include <Wire.h>

void setup()
{
Serial.begin(115200);
nunchuck_init(); // inizializza il nunchuck
}

void loop()
{
nunchuck_get_data();
nunchuck_print_data();
delay(100);
}

//
// Nunchuck functions
//

static uint8_t nunchuck_buf[6];   //array utilizzato per immagazzinare i dati in arrivo dal nunchuck,


void nunchuck_init()
{ 
Wire.begin();                    
Wire.beginTransmission(0x52);    // trasmettiamo l'indirizzo della periferica 0x52
Wire.send(0x40);        // trasmettiamo l'indirizzo della memoria
Wire.send(0x00);        // trasmettiamo uno 0 perchè vogliamo leggere dati
Wire.endTransmission();    // smettiamo di trasmettere
}

void nunchuck_send_request()
{
Wire.beginTransmission(0x52);    //trasmettiamo l'indirizzo del nunchuck 
Wire.send(0x00);        // trasmettiamo un byte
Wire.endTransmission();    // smettiamo di trasmettere
}

// Ricevere dati e immagazzinarli in un buffer
int nunchuck_get_data()
{
int cnt=0;
Wire.requestFrom (0x52, 6);   
while (Wire.available ()) {
// decodifichiamo i byte che ci arrivano e li traformiamo in un intero
nunchuck_buf[cnt] = nunchuk_decode_byte(Wire.receive());
cnt++;
}
nunchuck_send_request();  

if (cnt >= 5) {
return 1;  //restituisce 1 se fallisce
}
return 0; //restituisce 0 se i dati sono stati ricevuti in maniera corretta
}

// Stampare i dati arrivati
// i dati di accelerazione sono lunghi 10 bit
// quindi ne leggiamo 8 poi aggiungiamo
// gli ultimi 2 bit.
void nunchuck_print_data()
{ 
static int i=0;
int joy_x_axis = nunchuck_buf[0];
int joy_y_axis = nunchuck_buf[1];
int accel_x_axis = nunchuck_buf[2] << 2; 
int accel_y_axis = nunchuck_buf[3] << 2;
int accel_z_axis = nunchuck_buf[4] << 2;

int z_button = 0;
int c_button = 0;

// byte nunchuck_buf[5] contains bits for z and c buttons
// it also contains the least significant bits for the accelerometer data
// so we have to check each bit of byte outbuf[5]
if ((nunchuck_buf[5] >> 0) & 1) z_button = 1;
if ((nunchuck_buf[5] >> 1) & 1) c_button = 1;

if ((nunchuck_buf[5] >> 2) & 1) accel_x_axis += 1;
if ((nunchuck_buf[5] >> 3) & 1) accel_x_axis += 2;

if ((nunchuck_buf[5] >> 4) & 1) accel_y_axis += 1;
if ((nunchuck_buf[5] >> 5) & 1) accel_y_axis += 2;

if ((nunchuck_buf[5] >> 6) & 1) accel_z_axis += 1;
if ((nunchuck_buf[5] >> 7) & 1) accel_z_axis += 2;

Serial.print(i,DEC);
Serial.print(",");

Serial.print(accel_x_axis, DEC);
Serial.print(",");
Serial.print(accel_y_axis, DEC);
Serial.print(",");
Serial.print(accel_z_axis, DEC);
Serial.print(",");
Serial.print(joy_x_axis,DEC);
Serial.print(",");
Serial.print(joy_y_axis, DEC);
Serial.print(",");
Serial.print(z_button, DEC);
Serial.print(",");
Serial.print(c_button, DEC);
Serial.print(",");
Serial.print(nunchuck_buf[5], BIN);

Serial.print("\r\n");  // newline
i++;
}

// metodi di codifica dei nunchuck originali
char nunchuk_decode_byte (char x)
{
 x = (x ^ 0x17) + 0x17;
 return x;
}

@astrobeed: grazie sei gentilissimo, ma in che senso devo cambiare i nomi per farlo funzionare con la ide 1.x?

Ciao,
aggiungo solo una cosa: in rete vedo molti che tagliano il cavo e utilizzano i fili singoli, non ne vale proprio la pena, perchè i jumper si incastrano perfettamente nel connettore nintendo (seguendo lo schema riportato da astrobeed)!

Esempio:

Per l'interfacciamento software, io ho utilizzato la libreria che puoi trovare qui:
http://www.gabrielbianconi.com/projects/arduinonunchuk/

Funziona perfettamente con la versione 1.0

Ciao,
A.

Iz2rpn:
@astrobeed: grazie sei gentilissimo, ma in che senso devo cambiare i nomi per farlo funzionare con la ide 1.x?

Dalla versione 1.x dell'IDE sono stati modificati i nomi di alcune funzioni/classi, tra queste c'è la I2C, se provi a compilare il programma ti vengono segnalati una serie di errori proprio su queste funzioni perché i nomi sono deprecati e ti viene suggerito il nuovo nome da utilizzare.

ndrplz:
aggiungo solo una cosa: in rete vedo molti che tagliano il cavo e utilizzano i fili singoli, non ne vale proprio la pena, perchè i jumper si incastrano perfettamente nel connettore nintendo (seguendo lo schema riportato da astrobeed)!

Esiste anche un apposito adattatore che si introduce nel connettore e rende disponibili i vari contatti, volendo si realizza facilmente in casa con uno scarto di pcb.
Personalmente ho tagliato il cavo e gli ho saldato sopra una stripline a passo 2.54, non ho la Wii pertanto non mi interessa mantenere il loro connettore.

astrobeed:

Iz2rpn:
@astrobeed: grazie sei gentilissimo, ma in che senso devo cambiare i nomi per farlo funzionare con la ide 1.x?

Dalla versione 1.x dell'IDE sono stati modificati i nomi di alcune funzioni/classi, tra queste c'è la I2C, se provi a compilare il programma ti vengono segnalati una serie di errori proprio su queste funzioni perché i nomi sono deprecati e ti viene suggerito il nuovo nome da utilizzare.

appena libero arduino dal progetto che sto ultimando ci provo a giocare grazie :slight_smile:

Una domanda: parlando del servo 4, intendo non quelli sulla base ma quello sul 'gomito', questo è collegato ai servi della base con due staffe. Una staffa è collegata alla squadretta del servo ed è quella che si vede nel video, dalla parte opposta come è collegato il servo alla staffa? come lo hai fissato? puoi fare una foto così si vede?

Parlando dei servi dynamixel Ax-12A, c'è una alternativa, se qualcuno ha voglia di sbattersi. Ci sono dei servi venduti da www.robossavy.co.uk ma anche da nodna.de che si chiamano Dongbu HerkuleX Servo DRS-0101 che costano una 40 ina di euro che sono, secondo le intenzioni del produttore, dei dynamixel migliorati. Roba cinese, ma apparentemente di ottima qualità.

Si possono controllare un sacco di parametri, tra cui quelli del PID del servo, che dovrebbero lasciare molta più libertà di configurazione. Bisogna però trovare qualcuno di buona volontà che si metta a scrivere una libreria, sul modello di quella di savageelectronics per i dynamixel.

Parlando dei servi dynamixel Ax-12A, c'è una alternativa, se qualcuno ha voglia di sbattersi. Ci sono dei servi venduti da www.robossavy.co.uk ma anche da nodna.de che si chiamano Dongbu HerkuleX Servo DRS-0101 che costano una 40 ina di euro che sono, secondo le intenzioni del produttore, dei dynamixel migliorati. Roba cinese, ma apparentemente di ottima qualità.

Ok, ma se poi li compro e sono delle cinesate? Ti conviene andare avanti tu e farci sapere..

dubito siano una cinesata, vengono usati nei robot hovis, fai una ricerca. Io ho già 6-7 dynamixel, non penso proprio prenderò gli herculex. Il fatto che li venda robosavvy penso sia una garanzia di qualità, se ti fai un giro nel loro sito vedrai che vendono solo prodotti di alto livello. comunque era solo una segnalazione di alternativa ai dynamixel.

alegiaco:
Una domanda: parlando del servo 4, intendo non quelli sulla base ma quello sul 'gomito', questo è collegato ai servi della base con due staffe. Una staffa è collegata alla squadretta del servo ed è quella che si vede nel video, dalla parte opposta come è collegato il servo alla staffa? come lo hai fissato? puoi fare una foto così si vede?

Ciao,
come hai visto una staffa è incollata alla squadretta del servo. L'altra staffa è tenuta attaccata al servo da una specie di "bottone" metallico, che è passante rispetto alla staffa ed ha un estremo incollato al servo, l'altro estremo "abbottonato".
Allego tre foto, nelle prime due si vede da vicino l'incastro, nella terza si vede la specie di "bottone" metallico che ho usato (so che c'è un termine specifico, ma non mi viene in mente!)

Ciao,
A.