開源一個四足機器人

一、前言

玩過很長一段時間單片機,一直想接觸Arduino系列板子,這次如願以償。用去年自己3D打印機打的機器人外殼,Arduino UNO R3+舵機控制板,做的一個四足機器人。

這裏寫圖片描述

這裏寫圖片描述

二、爬過的坑

不得不承認Arduino確是個好東西,開發速度極快,極易上手。從開始動手到完成,只持續了3天不到,測試。調代碼。封裝。
整個過程裏一開始就感覺會頭疼的就是機器人的步態,因爲之前也沒接觸過。實際操作起來比想象中容易的多。現在的機器人支持前進、後退、左轉、右轉、起立、坐下。五種步態。通過搖桿控制。
廢話不多說,貼一下代碼。
代碼經過粗略的封裝,舵機控制板有個庫文件需要下載調用,別的都是手打的代碼
主要封裝了單足控制函數action.參數說明:foot:第N只足,Up:足舉起的高度,Dis:足向前轉動的角度幅度,walk:取0或1,0代表原地運動,1代表走動。主要是爲了區別出起立坐下這兩個原地運動。
再把action函數封裝進前進、後退、左轉、右轉四個函數中,參數僅有t,用於設定動作間的延時,以控制整體的運動速度。

void action(int foot,int Up,int Dis,int walk=0){
switch (foot){
case 0 : hor = 0 ; ver = 4 ; verBegin=340;
break ;
case 1 : hor = 1 ; ver = 5 ; Up=-Up;verBegin=400;
Dis=-Dis;
break ;
case 2 : hor = 2 ; ver = 6 ; verBegin=340;
Dis=-Dis;
break ;
case 3 : hor = 3 ; ver = 7 ; Up=-Up;verBegin=400;
break ;
}
pwm.setPWM(ver, 0, verBegin + Up);
pwm.setPWM(hor, 0, SERVOBEGIN_0 + Dis);
delay(150);
if(walk){
pwm.setPWM(ver, 0, verBegin);
}
}

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
// 使用默認I2C地址 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);
#define SERVOMIN  150 // this is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX  600 // this is the 'maximum' 脈衝寬度 count (out of 4096)
//定義begin狀態,即機器人準備爬行狀態的舵機初始值,修改初始定義值調節四足平衡,消除機械誤差
//註釋後爲無機械誤差的理想值

#define SERVOBEGIN_0   375   //左前橫臂 375
#define SERVOBEGIN_1   375   //右前橫臂 375
#define SERVOBEGIN_2   375   //右後橫臂 375
#define SERVOBEGIN_3   375   //左後橫臂 375
#define SERVOBEGIN_4   340   //左前縱臂 340
#define SERVOBEGIN_5   400   //右前縱臂 400
#define SERVOBEGIN_6   340   //右後縱臂 340
#define SERVOBEGIN_7   400   //左後縱臂 400
#define SERVOBEGIN_8   375   //尾巴起點 375
#define UP 60 //縱向幅度
#define Distance 80 //前進幅度
int i =0;
boolean q;

void setup() {
  Serial.begin(9600);
  //Serial.println("16 channel Servo test!");
  pwm.begin();
  pwm.setPWMFreq(60);  // Analog servos run at ~60 Hz updates
}

/*參數說明
 * A0爲Y軸,A1爲X軸
 * 從 0 ~ 1023 分別代表 左~右,上~下。中間值爲512。
 * 舵機信號範圍150-600
 * 縱向腳的擺動幅度設置:機械上最大值爲90度,實際操作設置爲70度
 * 170爲上止點,170+175=345,345下止點(實際用340)
 * 旁邊臂爲對稱2號和4號,起始點570,下止點570-175=395(實際用400)
 * 150-600代表180度行程,(450/180)*70=175
 * 橫向腳擺動設置:以375爲中間點,機械上擺動幅度爲180度,
 * 前後擺動幅度爲各40度,375+-100爲前後,(275,475)
 * 0-3爲橫向舵機,4-7爲縱向舵機
 *動作部分:
 *0,1,2,3 代表前後左右,4代表起立或坐下
 */
/*
 * 轉動方向前,Dis爲正
 */
int ver;//縱向舵機
int verBegin;
int hor;//橫向舵機

void action(int foot,int Up,int Dis,int walk=0){
  switch (foot){
    case 0 : hor = 0 ; ver = 4 ; verBegin=340;
    break ;
    case 1 : hor = 1 ; ver = 5 ; Up=-Up;verBegin=400;
          Dis=-Dis;
    break ;
    case 2 : hor = 2 ; ver = 6 ; verBegin=340;
          Dis=-Dis;
    break ;
    case 3 : hor = 3 ; ver = 7 ; Up=-Up;verBegin=400;
    break ;
    }
    pwm.setPWM(ver, 0, verBegin + Up);
    pwm.setPWM(hor, 0, SERVOBEGIN_0 + Dis);
    delay(150);
    if(walk){
    pwm.setPWM(ver, 0, verBegin);
    }
}
void sit(){
  //下蹲
  //橫臂鎖定調中
    pwm.setPWM(0, 0, SERVOBEGIN_0);
    pwm.setPWM(1, 0, SERVOBEGIN_1);   
    pwm.setPWM(2, 0, SERVOBEGIN_2);
    pwm.setPWM(3, 0, SERVOBEGIN_3); 
  //下蹲
    pwm.setPWM(4, 0, SERVOBEGIN_4 - 170);//1,2號縱臂
    pwm.setPWM(5, 0, SERVOBEGIN_5 + 170);
    pwm.setPWM(6, 0, SERVOBEGIN_6 - 170);//3,4號縱臂
    pwm.setPWM(7, 0, SERVOBEGIN_7 + 170);
}
void stand(){ //站立
   //橫向調中
    pwm.setPWM(0, 0, SERVOBEGIN_0);
    pwm.setPWM(1, 0, SERVOBEGIN_1);   
    pwm.setPWM(2, 0, SERVOBEGIN_2);
    pwm.setPWM(3, 0, SERVOBEGIN_3); 
  //站立
    pwm.setPWM(4, 0, SERVOBEGIN_4);
    pwm.setPWM(5, 0, SERVOBEGIN_5);
    pwm.setPWM(6, 0, SERVOBEGIN_6);
    pwm.setPWM(7, 0, SERVOBEGIN_7);
}
void prewalk0(){
  pwm.setPWM(1, 0, SERVOBEGIN_0+80);
  pwm.setPWM(0, 0, SERVOBEGIN_0-80);
}
void move0(int t){
  action(1,-70,0,1);
  delay(t/4);
  action(3,-70,80,1);
  delay(t/2);
  pwm.setPWM(1, 0, SERVOBEGIN_0+80);
  delay(t/8);
  pwm.setPWM(3, 0, SERVOBEGIN_0);
  delay(t/8);
  action(0,-70,0,1);
  delay(t/4);
  action(2,-70,80,1);
  delay(t/2);
  pwm.setPWM(0, 0, SERVOBEGIN_0-80);
  delay(t/8);
  pwm.setPWM(2, 0, SERVOBEGIN_0);
  delay(t/8);
}
void prewalk1(){
  pwm.setPWM(2, 0, SERVOBEGIN_0-80);
  pwm.setPWM(3, 0, SERVOBEGIN_0+80);
}
void move1(int t){
  action(3,-70,0,1);
  delay(t/4);
  action(1,-70,-80,1);
  delay(t/2);
  pwm.setPWM(3, 0, SERVOBEGIN_0+80);
  delay(t/8);
  pwm.setPWM(1, 0, SERVOBEGIN_0);
  delay(t/8);
  action(2,-70,0,1);
  delay(t/4);
  action(0,-70,-80,1);
  delay(t/2);
  pwm.setPWM(2, 0, SERVOBEGIN_0-80);
  delay(t/8);
  pwm.setPWM(0, 0, SERVOBEGIN_0);
  delay(t/8);
}
void turnLeft(int t){
  action(1,-70,-80,1);
  delay(t/2);
  action(3,-70,80,1);
  delay(t/2);
  action(0,-70,80,1);
  delay(t/2);
  action(2,-70,-80,1);
  delay(t/2);
  pwm.setPWM(1, 0, SERVOBEGIN_0);
  pwm.setPWM(3, 0, SERVOBEGIN_0);
  pwm.setPWM(0, 0, SERVOBEGIN_0);
  pwm.setPWM(2, 0, SERVOBEGIN_0);
  delay(t*1.5);
}
void turnRight(int t){
  action(0,-70,-80,1);
  delay(t/2);
  action(2,-70,80,1);
  delay(t/2);
  action(1,-70,80,1);
  delay(t/2);
  action(3,-70,-80,1);
  delay(t/2);
  pwm.setPWM(0, 0, SERVOBEGIN_0);
  pwm.setPWM(2, 0, SERVOBEGIN_0);
  pwm.setPWM(1, 0, SERVOBEGIN_0);
  pwm.setPWM(3, 0, SERVOBEGIN_0);
  delay(t*1.5);
}
void loop() {
  // Drive each servo one at a time
  //Serial.println(servonum);

//縱臂擺動,橫臂鎖定
q=true;
int p=0;
int act=5;
while(1){
  if(analogRead(A1)<100){act=0;}
  if(analogRead(A1)>900){act=1;}
  if(analogRead(A0)>900){act=2;}
  if(analogRead(A0)<100){act=3;}
  if (!digitalRead(7)){    //站坐切換
    delay(20);
    if(!digitalRead(7)){
    act=4;
    }
    }
  switch (act){
    case 0 :
    if(p){ stand() ; prewalk0() ; delay( 150 ) ; p=0;}
    else move0( 150 ) ;
    act=5;
    break;
    case 1 :
    if(p){ stand() ; prewalk1() ; delay( 150 ) ; p=0;}
    else move1( 150 ) ;
    act=5;
    break;
    case 2 :
    if(p){ stand() ; delay( 150 ) ; p=0;}
    else turnLeft( 350 ) ;delay(150);
    act=5;
    break;
    case 3 :
    if(p){ stand() ; delay( 150 ) ; p=0;}
    else turnRight( 350 ) ;delay(150);
    act=5;
    break;
    case 4 :q=!q;act=5;
    break;
    default:
    delay(100);
    if(q){ stand() ; p = 1 ; }
    else{ sit();  p = 1 ; }
    break;
  }
}
}

三、步態說明

**如代碼所見,四足的前進步態,(左前爲1,右前爲2,右後爲3,左後爲4)1,延時,3,小延時,1、3回正且邁出2,延時,4,小延時,2、4回正且邁出1…如此循環。後退步態無異。
左轉步態也相似,主要都是一組交叉足先移動,再移動另一組交叉足。
期間試過四五種起始步態,有四足平行,“共”字的起始步態,晃動得很嚴重,猜測是因爲機身較輕,且足底不平(貼了橡皮擦的切片增加摩擦力),還有就是“X”型起始步態,也不理想,最後還是確認了前兩足“一”字,後兩足八字。其實就是前兩足用“工”,後兩足用“X”。穩定性表現得最好。
當然還可以有更好的步態,機械結構上也有待改進。本人在此就暫時不深究了。**

四、配件list

1、3D打印的機器人外殼一套
2、Arduino UNO一塊,Arduino搖桿模塊一枚
3、16路PMW控制板一塊
4、12V2A電源一枚
5、7805穩壓芯片2枚,2枚散熱片(用來並聯,因爲8個舵機同時工作+主板大約1.5A+的電流),或者別的2A輸出的5V穩壓芯片
6、小散熱風扇,用來冷卻7805的散熱片
7、9g舵機8個
8、螺絲螺母:

M3*16螺絲4枚,M3防滑螺母4枚
M4*16螺絲4,
M4*25螺絲4,
M4*20螺絲4,M4防滑螺母4,M4螺母8
M3、M4尼龍墊片若干

五、視頻動圖

轉身

這裏寫圖片描述

前進

這裏寫圖片描述

這裏寫圖片描述

六、後續

這個機器人現階段是爲了調試運動性能,算合格了,後面會加入語音識別模塊、語言播放模塊、傳感機械手、wifi模塊、打造成一個只能語音控制的機器人。比如直接對話查機票價格、天氣等等,以及一些特殊提醒。當然實用性不重要,夠酷夠炫纔是關鍵。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章