LusoRobótica - Robótica em Português
Robótica => Tutoriais => Tópico iniciado por: guibot em 21 de Agosto de 2009, 19:14
-
Já ando de volta disto à bastante tempo, e finalmente decidi-me a publicar os resultados obtidos :)
No video que segue vão ver duas experiências distintas. Primeiro com os servos ligados directamente ao arduino e de segundo com o controlador de servos - pololu micro serial servo controller. (http://<a href="http://www.pololu.com/catalog/product/207">)
O controlador da pololu dá-nos uma boa possibilidade de definir velocidade, e em conjunto com o filtro de suavização conseguem-se movimentos verdadeiramente suaves, podem ver mesmo no final do video.
O robot treme bastante mas isso deve-se à sua estrutura de suporte frágil, é apenas um ferro que o suporta e facilmente ele desata a tremer. Tenho que arranjar outra solução para ficar bem fixo.
Código fonte depois do video ;)
http://www.youtube.com/watch?v=g6uo2K8M6BM&feature=player_embedded
Código para usar os servos directamente ligados ao arduino:
// suavizar movimentos de um servo
// para correres este código o sinal do servo deverá
// estar directamente ligado ao pin 2 do arduino
// Intervalo de tempo, correr uma porção de código de tempo a tempo
// Download da biblioteca Metro e Instruções:
// http://www.arduino.cc/playground/Code/Metro
#include <Metro.h>
int duration = 3500; // duração do intervalo em milisegundos
Metro intervaller = Metro (duration);
// Biblioteca MegaServo
// Download da biblioteca e Instruções:
// http://www.arduino.cc/playground/Code/MegaServo
#include <MegaServo.h>
MegaServo servos;
// posições máxima e mínima do servo, equivalente a 0 e 180º
#define MIN_POS 800
#define MAX_POS 2200
// servo pin
#define s0_pin 2
// variáveis para armazenar novas posições de destino do servo
int d0; // destino0
int d0_sh; // destino0 com suavização, "_sh" = smooth
// variável que contem o valor do filtro que vai ser aplicado
// este valor vai ser multiplicado pelo d0 e pelo d0_sh
float filtro = 0.05; // 0.01 to 1.0
// função de inicialização, correr uma vez quando o programa é inciado
void setup() {
// inicializa comunicação serial
Serial.begin(9600);
// define pin onde vai estar o servo
servos.attach(s0_pin);
}
// programa loop(), função que corre eternamente
void loop() {
// analiza o intervalo de tempo, sempre que chega ao limite da duração volta a 1
// e correr o código que estiver entre {}
if (intervaller.check() == 1) {
// calcula nova posição aleatória entre os valores min e max
d0 = random(MIN_POS, MAX_POS);
// reinicia intervalo de tempo com valor aleatório
intervaller.interval(random(500,2000));
}
// suavizar o valor de destino
d0_sh = d0_sh * (1.0-filtro) + d0 * filtro;
// atribui o valor de destino à posição do servo
servos.write(d0_sh);
// delay para dar tempo ao servo de se mover
delay(25);
}
Código para o controlador da pololu:
// suavizar movimentos de um servo
// para correres este código precisas de Pololu Micro Serial Servo Controller
// http://www.pololu.com/catalog/product/207
// Intervalo de tempo, correr uma porção de código de tempo a tempo
// Download da biblioteca Metro e Instruções:
// http://www.arduino.cc/playground/Code/Metro
#include <Metro.h>
int duration = 3500; // duration of the interval in miliseconds
Metro intervaller = Metro (duration);
// posições máxima e mínima do servo, equivalente a 0 e 180º
#define MIN_POS 500
#define MAX_POS 5500
// variáveis para armazenar novas posições de destino do servo
int d0; // destino0
int d0_sh; // destino0 com suavização, "_sh" = smooth
// variável que contem o valor do filtro que vai ser aplicado
// este valor vai ser multiplicado pelo d0 e pelo d0_sh
float filtro = 0.05; // 0.01 to 1.0
// define velocidade do servo, pode ser um valor entre 0 e 127
int servoSpeed = 120;
// função de inicialização, correr uma vez quando o programa é inciado
void setup() {
// inicializa comunicação serial
Serial.begin(9600);
// define pin onde vai estar o servo
servoSetSpeed(0, servoSpeed);
}
// programa loop(), função que corre eternamente
void loop() {
// analiza o intervalo de tempo, sempre que chega ao limite da duração volta a 1
// e correr o código que estiver entre {}
if (intervaller.check() == 1) {
// calcula nova posição aleatória entre os valores min e max
d0 = random(MIN_POS, MAX_POS);
// reinicia intervalo de tempo com valor aleatório
intervaller.interval(random(500,3000));
}
// suavizar o valor de destino
d0_sh = d0_sh * (1.0-filtro) + d0 * filtro;
// atribui o valor de destino à posição do servo
put(0,d0_sh);
// delay para dar tempo ao servo de se mover
delay(25);
}
// as funções seguintes foram retiradas deste tópico:
// http://forum.pololu.com/viewtopic.php?f=16&t=745&start=60&st=0&sk=t&sd=a
void put(int servo, int angle)
{
//servo is the servo number (typically 0-7)
//angle is the absolute position from 500 to 5500
unsigned char buff[6];
unsigned int temp;
unsigned char pos_hi,pos_low;
//Convert the angle data into two 7-bit bytes
temp=angle&0x1f80;
pos_hi=temp>>7;
pos_low=angle & 0x7f;
//Construct a Pololu Protocol command sentence
buff[0]=0x80; //start byte
buff[1]=0x01; //device id
buff[2]=0x04; //command number
buff[3]=servo; //servo number
buff[4]=pos_hi; //data1
buff[5]=pos_low; //data2
//Send the command to the servo controller
for(int i=0;i<6;i++){
Serial.print(buff[i],BYTE);
}
}
void servoSetSpeed(int servo, int speed){
//servo is the servo number (typically 0-7)
//speed is servo speed (1=fastest, 127=slowest)
//set speed to zero to turn off speed limiting
unsigned char buff[5];
unsigned char speedcmd;
speedcmd=speed&0x7f;//take only lower 7 bits of speed
buff[0]=0x80;//start byte
buff[1]=0x01;//device id
buff[2]=0x01;//command number
buff[3]=servo;//servo number
buff[4]=speed;//data1
for(int i=0;i<5;i++){
Serial.print(buff[i],BYTE);
}
}
-
Para o meu braço robótico tive de fazer a mesma coisa...
Interpolar o movimento de modo a criar X pontos para uma curva de aceleração em forma de "S" ...
-
Fantástico! e não nos queres mostrar o teu braço robótico? :p
-
tens aqui o "canal" da coisa
os servos é que não são os melhores... como são muito fracos por vezes ele oscila um bocado
http://www.youtube.com/user/era1x
-
pois, é o mesmo problema que eu tenho.
-
comentários em português adiccionados ao código ;)
-
Sim senhor... agora já não dá só para karaté, também dá para bailado :D
-
bruce lee em accao.
muito fixe
-
:D
a investigação continua, pois isto ainda vai vais longe ;)
-
tens aqui o "canal" da coisa
os servos é que não são os melhores... como são muito fracos por vezes ele oscila um bocado
http://www.youtube.com/user/era1x (http://www.youtube.com/user/era1x)
Muito bom, o braço robotico esta fenomenal, e o trabalho do sr. Guilherme e sem duvida uma boa utilidade para coisas que necessitem de precisão.
Cumprimentos...