collapse

* Posts Recentes

Amplificador - Rockboard HA 1 In-Ear por almamater
[Ontem às 19:13]


O que é isto ? por KammutierSpule
[26 de Março de 2024, 19:35]


Bateria - Portátil por almamater
[25 de Março de 2024, 22:14]


Emulador NES em ESP32 por dropes
[13 de Março de 2024, 21:19]


Escolher Osciloscópio por jm_araujo
[06 de Fevereiro de 2024, 23:07]


TP4056 - Dúvida por dropes
[31 de Janeiro de 2024, 14:13]


Leitura de dados por Porta Serie por jm_araujo
[22 de Janeiro de 2024, 14:00]


Distancia Cabo por jm_araujo
[08 de Janeiro de 2024, 16:30]


Meu novo robô por josecarlos
[06 de Janeiro de 2024, 16:46]


Laser Engraver - Alguém tem? por almamater
[16 de Dezembro de 2023, 14:23]

Autor Tópico: Suavizar movimentos dos servos  (Lida 12226 vezes)

0 Membros e 1 Visitante estão a ver este tópico.

Offline guibot

  • Mini Robot
  • *
  • Mensagens: 651
    • Guibot
Suavizar movimentos dos servos
« 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.

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



Código para usar os servos directamente ligados ao arduino:
Código: [Seleccione]
// 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:
Código: [Seleccione]
// 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);
  }
}





« Última modificação: 22 de Agosto de 2009, 08:24 por guibot »

jspgresende

  • Visitante
Re:Suavizar movimentos dos servos
« Responder #1 em: 21 de Agosto de 2009, 22:55 »
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" ...

Offline guibot

  • Mini Robot
  • *
  • Mensagens: 651
    • Guibot
Re:Suavizar movimentos dos servos
« Responder #2 em: 21 de Agosto de 2009, 23:27 »
Fantástico! e não nos queres mostrar o teu braço robótico?  :p

jspgresende

  • Visitante
Re:Suavizar movimentos dos servos
« Responder #3 em: 22 de Agosto de 2009, 00:27 »
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

Offline guibot

  • Mini Robot
  • *
  • Mensagens: 651
    • Guibot
Re:Suavizar movimentos dos servos
« Responder #4 em: 22 de Agosto de 2009, 00:50 »
pois, é o mesmo problema que eu tenho.

Offline guibot

  • Mini Robot
  • *
  • Mensagens: 651
    • Guibot
Re:Suavizar movimentos dos servos
« Responder #5 em: 22 de Agosto de 2009, 08:25 »
comentários em português adiccionados ao código ;)

Offline TigPT

  • Administrator
  • Mini Robot
  • *****
  • Mensagens: 5.372
    • Tiago Rodrigues
Re:Suavizar movimentos dos servos
« Responder #6 em: 22 de Agosto de 2009, 11:39 »
Sim senhor... agora já não dá só para karaté, também dá para bailado :D

Offline andnobre

  • Mini Robot
  • *
  • Mensagens: 402
Re:Suavizar movimentos dos servos
« Responder #7 em: 22 de Agosto de 2009, 13:18 »
bruce lee em accao.
muito fixe

Offline guibot

  • Mini Robot
  • *
  • Mensagens: 651
    • Guibot
Re:Suavizar movimentos dos servos
« Responder #8 em: 22 de Agosto de 2009, 14:18 »
 :D

a investigação continua, pois isto ainda vai vais longe ;)

Offline zordlyon

  • Mini Robot
  • *
  • Mensagens: 1.768
Re:Suavizar movimentos dos servos
« Responder #9 em: 10 de Março de 2010, 12:58 »
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

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...
Cumprimentos,
André Carvalho.