开源一个四足机器人

一、前言

玩过很长一段时间单片机,一直想接触Arduino系列板子,这次如愿以偿。用去年自己3D打印机打的机器人外壳,Arduino UNO R3+舵机控制板,做的一个四足机器人。

开源一个四足机器人_第1张图片

开源一个四足机器人_第2张图片

二、爬过的坑

不得不承认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 
#include 
// 使用默认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模块、打造成一个只能语音控制的机器人。比如直接对话查机票价格、天气等等,以及一些特殊提醒。当然实用性不重要,够酷够炫才是关键。

你可能感兴趣的:(arduino机器人)