一、前言
玩過很長一段時間單片機,一直想接觸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模塊、打造成一個只能語音控制的機器人。比如直接對話查機票價格、天氣等等,以及一些特殊提醒。當然實用性不重要,夠酷夠炫纔是關鍵。