模型文件来自于大神Spider robot开源,代码文件为原创测试用,比较无脑的重复代码,入门阶段。单片机采用arduino uno开发板,HC05蓝牙模块,SG90舵机12个,目前还没有PID算法,后期应该会加上吧。
#转载引用请标明出处,另外禁止商用
Arduino UNO开发板
Adruino UNO是一款常见的Adruino板子,如图5.1所示,从复位按钮开始顺时针依次是TWI接口、数字输入输出接口、电源指示灯、ICSP编程接口、主控单片机ATmega328,模拟输入接口、电源接口、DC电源输入接口、稳压芯片、USB接口。
Adruino UNO的工作电压为5V,供电范围一般是6-20V。考虑电压较低可能导致供电不足,驱动不了模块电压过高可能会使板子上面的稳压芯片过热影响板子使用寿命,所以实际的供电范围在7-12V之间。Adruino UNO的供电方式有3种,可以根据开发者的需要自己选择供电方式。第一种是外部的直流电源连接到DC电源输入接口来给UNO板子供电;第二种是通过UNO板子的USB接口,电脑通过USB线连接到UNO板子的USB接口可以用来下载程序给板子以及供电。当前两种供电方式没有采用时,可以使用第三种供电方式,即使用UNO板子上电源接口处的GND 和VIN引脚供电。但如果前两种供电方式已经采用的话,可以通过VIN给外部模块或者面包板供电。电源接口引脚中的5V引脚是通过稳压芯片或USB的5V电压,为板子上的5V芯片供电;其中的3.3V引脚是通过稳压芯片产生的3.3V电压,驱动电流最大为50mA。
板子上的14路数字输入输出接口工作电压为5V,其中还有一些具有特定功能的引脚。本次毕业设计过程中使用到0、1、2、6以及7号数字输入输出引脚。0号引脚和1号引脚可用于串口通信,0号引脚为RX,1号引脚为TX,提供串口接收信号。这两个引脚用于连接HC-05蓝牙模块。2号引脚作为触发中断引脚,有3种触发模式,分别是上升沿、下降沿触发以及同时触发。本次毕设中2号引脚用于控制4个LED指示灯。6号和7号引脚属于正常功能的引脚。
板子上的AO-A5接口是模拟输入接口,默认输入信号范围是0-5V。和数字输入接口类似,模拟输入接口也有几个引脚具有特定功能。
步态规划:
四足步态采用了x型步态,操作部分代码见AutodataCmd部分,使用HC05蓝牙模块,由于舵机数量较多采用数组直接定义。启动时会进入准备状态,进行行进前需要启动Start进入预备状态。
‘x’型步态规划方式如下:
前进步态:
如图所示,在“X”型步态时,四足榛蛛机器人前进步态是A腿抬起→A腿前移(1号舵机带着A腿逆时针转动)→A腿落下→C腿抬起→C腿前移(7号舵机带着C腿顺时针转动)→C腿落下→AC两条腿复位→B腿抬起→B腿前移(4号舵机带着B腿顺时针转动)→B腿落下→D腿抬起→D腿前移(10号舵机带着D腿逆时针转动)一D腿落下一BD两条腿复位。
后退步态:
在“X”字型步态时,如图所示,四足蜘蛛机器人后退步态是:A腿抬起→A腿向右移(1号舵机带着A腿顺时针转动)→A腿落下→C腿抬起→C腿向右移(7号舵机带着C腿逆时针转动)→C腿落下→AC两条腿复位→B腿抬起一B腿向左移(4号舵机带着B腿逆时针转动)一B腿落下一D腿抬起→D腿向左移(10号舵机带着D腿顺时针转动)→D腿落下→ED两条腿复位。
左转/右转步态规划:
在“X”型步态时,如图所示,四足蜘蛛机器人左转步态是A腿抬起→A腿向左移(1号舵机带着A腿逆时针转动)→A腿落下→C腿抬起→C腿向右移(7号舵机带着C腿逆时针转动)→C腿落下→B腿抬起→B腿向左移(4号舵机带着B腿逆时针转动)→B腿落下→D腿抬起→D腿向右移(10号舵机带着D腿逆时针转动)→一D腿落下→ABCD 四条腿复位。
图略,四足蜘蛛机器人右转步态是:A腿抬起→A腿向右移(1号舵机带着A腿顺时针转动)→A腿落下→C腿抬起→C腿向左移(7号舵机带着C腿顺时针转动)→C腿落下→B腿抬起→B腿向右移(4号舵机带着B腿顺时针转动)→B腿落下一→D腿抬起→D腿向左移(10号舵机带着D腿顺时针转动)→D腿落下一ABCD 四条腿复位。
#转载引用请标明出处,另外禁止商用
UNO代码控制代码:
#include
//#include
#define sMaxAngle 175
#define sMinAngle 5
Servo servo[12];//定义舵机数组名称
int servo_pin[12];//定义引脚
bool mode;//模式调整
void setup() {
Serial.begin(9600);
Serial.println("Robot begin work");
Initialize();
}
void loop() {
if(Serial.available()){
char serialCmd = Serial.read();
if(mode == 1){
//ArmdataCmd(serialCmd);//指令模式
}else{
AutodataCmd(serialCmd);//自动模式
}
}
}
void PreMode(char serialCmd = 's'){//进入预备模式
for(int pre = 90;pre >= 45;pre--){
servo[4].write(pre);
delay(15);
servo[6].write(pre);
delay(15);
}
for(int pre = 90;pre <= 135;pre++){
servo[5].write(pre);
delay(15);
servo[7].write(pre);
delay(15);
}
for(int pre_2 = 90;pre_2 <= 135;pre_2++){
servo[9].write(pre_2);
delay(15);
servo[10].write(pre_2);
delay(15);
}
for(int pre_2 = 90;pre_2 >= 45;pre_2--){
servo[8].write(pre_2);
delay(15);
servo[11].write(pre_2);
delay(15);
}
for(int pos = 90;pos <= 135;pos++){//进入准备模式
Serial.println(pos);
servo[0].write(pos);
delay(15);
servo[2].write(pos);
delay(15);
}
for(int pos = 90;pos >= 45;pos--){
Serial.println(pos);
servo[1].write(pos);
delay(15);
servo[3].write(pos);
delay(15);
}
}
void AutodataCmd(char serialCmd){//自动模式给出相应操作
if(serialCmd == 'B'||serialCmd == 'H'||serialCmd == 'R'||serialCmd == 'L'){
Serial.println("+Warning:Robot in Auto Mode...");
delay(100);
while(Serial.available()>0) char wrongCommand =Serial.read();//清除串口错误信息
return;
}
switch(serialCmd){
case 's':
Serial.println("Enter preparing Model!!!");
PreMode();
Serial.println("Preparation Over!!!");
break;
case 'w'://前进步态命令
Serial.println("Robot starts to go ahead!!!");
for(int i = 0;i <= 5;i++){
Goahead_leg1();
Goahead_leg3();
aheadIni_leg13();
Goahead_leg2();
Goahead_leg4();
aheadIni_leg24();
}
Serial.println("Ahead Command had overed!!!");
break;
case 'x'://后退步态命令
Serial.println("Robot starts to come back!!!");
for(int i = 0;i <= 3;i++){
Bcak_leg1();
Back_leg3();
Back_Ini13();
Back_leg2();
Back_leg4();
Back_Ini24();
}
Serial.println("Back Command had overed!!!");
break;
case 'a'://左转步态命令
Serial.println("Robot starts to turn left!!!");
Goahead_leg1();
Back_leg3();
Back_leg2();
Goahead_leg4();
Left_Ini();
//turnLeft();
break;
case 'd':
Serial.println("Robot starts to turn right!!!");
Bcak_leg1();
Goahead_leg3();
Goahead_leg2();
Back_leg4();
Right_Ini();
//turnRight();
break;
case 'q':
Serial.println("Robot starts to stand up!!!");
turnUp();
break;
case 'o':
Serial.println("Robot initialized");
Initialize();
break;
}
}
void Initialize(){//机器人初始化
for(int i = 0;i <= 11;i++){
servo_pin[i] = i+2;
servo[i].attach(servo_pin[i],500,2500);
servo[i].write(90);
}
}
void Goahead_leg1(char serialCmd = 'w'){//前进腿1
for(int pos = 45;pos <= 75;pos++){
servo[8].write(pos);
delay(15);
}
for(int pos = 135;pos <= 165;pos++){
servo[0].write(pos);
delay(15);
}
for(int pos = 75;pos >= 45;pos--){
servo[8].write(pos);
delay(15);
}
}
void Goahead_leg3(char serialCmd = 'w'){//前进腿3
for(int pos = 45;pos <= 75;pos++){
servo[11].write(pos);
delay(15);
}
for(int pos = 135;pos >= 105;pos--){
servo[2].write(pos);
delay(15);
}
for(int pos = 75;pos >= 45;pos--){
servo[11].write(pos);
delay(15);
}
}
void aheadIni_leg13(char serialCmd = 'w'){//腿13复原
for(int pos = 165;pos >= 135;pos--){
servo[0].write(pos);
delay(15);
}
for(int pos = 105;pos <= 135;pos++){
servo[2].write(pos);
delay(15);
}
}
void Goahead_leg2(char serialCmd = 'w'){//前进腿2
for(int pos = 135;pos >= 105;pos--){
servo[9].write(pos);
delay(15);
}
for(int pos = 45;pos >= 15;pos--){
servo[1].write(pos);
delay(15);
}
for(int pos = 105;pos <= 135;pos++){
servo[9].write(pos);
delay(15);
}
}
void Goahead_leg4(char serialCmd = 'w'){//前进腿4
for(int pos = 135;pos >= 105;pos--){
servo[10].write(pos);
delay(15);
}
for(int pos = 45;pos <= 75;pos++){
servo[3].write(pos);
delay(15);
}
for(int pos = 105;pos <= 135;pos++){
servo[10].write(pos);
delay(15);
}
}
void aheadIni_leg24(char serialCmd = 'w'){//腿24复原
for(int pos = 15;pos <= 45;pos++){
servo[1].write(pos);
delay(15);
}
for(int pos = 75;pos >= 45;pos--){
servo[3].write(pos);
delay(15);
}
}
void turnUp(char serialCmd ='q'){//皮皮虾代码,谨慎使用
for(int pos = 90;pos <=135;pos++){
servo[4].write(pos);
delay(15);
servo[6].write(pos);
delay(15);
}
for(int pos = 45;pos <= 90;pos++){
servo[5].write(pos);
delay(15);
servo[7].write(pos);
delay(15);
}
for(int pos = 135;pos >= 90;pos--){
servo[4].write(pos);
delay(15);
servo[6].write(pos);
delay(15);
}
for(int pos = 90;pos >= 45;pos--){
servo[5].write(pos);
delay(15);
servo[7].write(pos);
delay(15);
}
}
void Bcak_leg1(char serialCmd = 'x'){//腿1撤回
for(int pos = 45;pos <= 90;pos++){
servo[8].write(pos);
delay(15);
}
for(int pos = 135;pos >= 105;pos--){
servo[0].write(pos);
delay(15);
}
for(int pos = 90;pos >= 45;pos--){
servo[8].write(pos);
delay(15);
}
}
void Back_leg3(char serialCmd = 'x'){//腿3撤回
for(int pos = 45;pos <= 75;pos++){
servo[11].write(pos);
delay(15);
}
for(int pos = 135;pos <= 165;pos++){
servo[2].write(pos);
delay(15);
}
for(int pos = 75;pos >= 45;pos--){
servo[11].write(pos);
delay(15);
}
}
void Back_Ini13(char serialCmd = 'x'){//撤回13复原
for(int pos = 105;pos <= 135;pos++){
servo[0].write(pos);
delay(15);
}
for(int pos = 165;pos >= 135;pos--){
servo[2].write(pos);
delay(15);
}
}
void Back_leg2(char serialCmd = 'x'){//腿2撤回
for(int pos = 135;pos >= 105;pos--){
servo[9].write(pos);
delay(15);
}
for(int pos = 45;pos <= 75;pos++){
servo[1].write(pos);
delay(15);
}
for(int pos = 105;pos <= 135;pos++){
servo[9].write(pos);
delay(15);
}
}
void Back_leg4(char serialCmd = 'x'){//腿4撤回
for(int pos = 135;pos >= 105;pos--){
servo[10].write(pos);
delay(15);
}
for(int pos = 45;pos >= 15;pos--){
servo[3].write(pos);
delay(15);
}
for(int pos = 105;pos <= 135;pos++){
servo[10].write(pos);
delay(15);
}
}
void Back_Ini24(char serialCmd = 'x'){//撤回24复原
for(int pos = 75;pos >= 45;pos--){
servo[1].write(pos);
delay(15);
}
for(int pos = 15;pos <= 45;pos++){
servo[3].write(pos);
delay(15);
}
}
void Left_Ini(){//x步态左转复原
for(int pos = 165;pos >= 135;pos--){
servo[0].write(pos);
delay(15);
servo[2].write(pos);
delay(15);
}
for(int pos = 75;pos >= 45;pos--){
servo[1].write(pos);
delay(15);
servo[3].write(pos);
delay(15);
}
}
void Right_Ini(){//x步态右转复原
for(int pos = 105;pos <= 135;pos++){
servo[0].write(pos);
delay(15);
servo[2].write(pos);
delay(15);
}
for(int pos = 15;pos <= 45;pos++){
servo[1].write(pos);
delay(15);
servo[3].write(pos);
delay(15);
}
}