分享一个四足蜘蛛机器人
- 开题
- 进入大学以来,学习单片机已经很长时间了。之前都是在开发板上学习各种外设,做各种实验,一直也都没正经的做过什么项目。刚好临近毕业,需要做毕业设计,我感觉这是一个很好的机会,结合之前所学的全部知识,完成一个完整的项目流程。于是我便提前两个月开始准备,在开始项目选题时犹豫了许久,本来是考虑做四轴,但是介于现在这方面网络上的开源项目很多,有许多成熟的方案,还是决定做一点不一样的,所以最终就选定了这个题材。
第一次写博客,有些地方有错误或者描述不清的地方欢迎指出。 - 话不多说,先看图片
- 项目概述
- 整个项目都采用了模块化设计,然后把模块固定到pcb板子上(板子是在学校自己做的,只有单层),全部都是在某宝可以直接买到的模块,目的是方便调试和更换,因此外部走线会有点多。
- 本次设计由机器人主机与遥控器从机两部分组成,机器人采用3D打印骨架,共4条腿,每条腿三个关节,用三个SG92R舵机驱动,一共12个SG92R舵机,12个舵机使用PCA9685 16路PWM控制器集中管理控制,通过IIC总线与单片机通讯;机器人电路设计将分为两层,分为底板和顶板:
- 底板的下方固定住一块1500mAh2S锂电池,连接到LM2596S 降压模块,降压后供电给舵机,电池再连接到一个多路电源模块,分别降压成5V/3.3V后负责给整机电路供电。底板上除了固定住PWM控制器外,还分别搭载了一个MPU6050三维角度传感器与一个HY-SRF05超声波测距模块,三维角度传感器负责采集机器人的姿态信息与温度信息,姿态信息用于实现机器人的稳定功能及遥控器联动功能;超声波测距模块负责采集障碍距离信息,用于实现障碍报警和避障功能。
- 顶板上搭载了单片机STM32f103rct6核心板、HC-05串口蓝牙无线透传模块、双轴舵机云台。STM32f103rct6核心板引出相应引脚对整机进行控制和运算,核心板上拥有两个LED灯与两个按键,两个LED用于显示程序运行状态信息,一个按键用于复位,另一个暂未用到。HC-05蓝牙模块连接上单片机串口二负责传输与遥控器的通讯信息。舵机云台使用两个SG90舵机驱动,连接PCA9685统一控制,云台可搭载小型航拍摄像头或其他设备。
- 底板与顶板之间通过杜邦线连接,整机供电正常模式下估计可以持续运行30-40分钟。
- 遥控器由主控芯片STM32f103c8t6核心板、HC-05串口蓝牙无线透传模块、MPU6050三维角度传感器、0.96寸OLED12864、双轴ADC摇杆与四个按键组成:STM32f103c8t6核心板除了负责控制整个遥控器电路外还将对整个遥控器其他模块供电,考虑到遥控器大小,遥控器不搭载电池,需要外部5v供电;HC-05蓝牙模块负责与主机机器人通讯;OLED用于显示机器人各种状态信息并与按键配合实现一个简单的操作界面,用于选择各种模式;三维角度传感器用于采集遥控器的三维角度信息实现对机器人的体感控制;双轴摇杆使用单片机采集ADC信息用于控制机器人搭载的云台,摇杆还自带一个点触按键实现云台的锁定/控制。
- 主机基于UCOSIII实时操作系统开发,将四条腿分别由四个进程控制,使用时间片轮转运行实现同步,其他每一个模块的采集程序各占用一条进程,通过一条优先级最高的主进程控制各个进程的开关以及信息的采集发送。遥控器采用裸机运行自动采集信息通过判断按键进行各个模式之间的切换。
- 主要内容
- 步态
步态可以说是整个设计中最复杂的部分之一了,刚开始构思项目是打算做成单步行走的(一次只动一条腿),然后把效果做出来之后觉得实在是太捞了,程序顺序执行且舵机一次只能做一组点对点的僵硬动作,而且做不到奔跑的动作(虽然最终也没有实现),所以就放弃了这个方案。最终想到了现在的解决方案:使用操作系统,把每一条腿分离成单独的任务,每个任务只执行自己动作的部分,利用任务并发实现整个移动姿势的动作周期。把四个任务设置成一样的优先级,使用时间片轮转调度,以达到同步的效果。
在做这个项目之前,从来都没有接触过步态这方面的知识,之前也有查阅过各种资料,也有各种公式去计算,但是最大的问题还是如何去实现,我在这个地方卡了很久,最终是通过自己反复看一张小猫走路的gif,把姿态分解成步骤,然后花了很长时间调试出来的。就是下面这个:
从图片来看,貌似可以把每条腿给分成四个阶段,分别是抬起前移->前移放下->放下后移->后移抬起(我将其称为四分割)就像下面这样:
图中对应关系:起->“抬起前移”、落->“前移放下”、前->“放下后移”、后->“后移抬起”
但实际上我这个机器人做不到猫的平衡性和协调性,在实际测试过发现并不能保持平衡,因此必须要同一时刻至少有三条腿接触地面才能不导致重心便宜。解决方法是把腿在地面接触的“放下后移”这个动作姿势给分成两个部分,延长这条腿呆在地面的时间,这样总体的总做时间就变成了5个动作单位(我将其称为五分割,好想也有叫4+1步态的说法,但我不确定是不是一样的),这里可能说的不太清除,具体看下图:
最终实现效果:
为了让舵机在规定时间内均匀的运动(为了同步),我写了一个函数可以实现对一个动作执行的总共时间及分辨率控制:
`//腿部运动控制角度函数
//Leg_num:选择腿号1-4分别对应 右前 左前 左后 右后
//Mov_time:完成一次动作所需要的总共时间
//Mov_rate:分辨率,分割时间的精度(速率不可以超过三个角度中的任何一个角度)
//Joint_A,Joint_B,Joint_C:分别对应三个关节需要移动的角度,可以是负数
void Leg_movements(char Leg_num,int Mov_time,int Mov_rate,int Joint_A,int Joint_B,int Joint_C)
{
CPU_SR_ALLOC();
OS_ERR err;
int i;
float Mov_time_ave,Joint_A_ave,Joint_B_ave,Joint_C_ave;
Mov_time_ave=Mov_time/Mov_rate;
Joint_A_ave=Joint_A/Mov_rate;
Joint_B_ave=Joint_B/Mov_rate;
Joint_C_ave=Joint_C/Mov_rate;
if(Leg_num==1)
{
for(i=0;i<Mov_rate;i++)
{
OS_CRITICAL_ENTER(); //进入临界区
RH_A_Current_angle=RH_A_Current_angle+Joint_A_ave;
RH_B_Current_angle=RH_B_Current_angle+Joint_B_ave;
RH_C_Current_angle=RH_C_Current_angle+Joint_C_ave;
PCA_Ctrl(0,RH_A_Current_angle);
PCA_Ctrl(1,RH_B_Current_angle);
PCA_Ctrl(2,RH_C_Current_angle);
OS_CRITICAL_EXIT(); //退出临界区
OSTimeDlyHMSM(0,0,0,Mov_time_ave,OS_OPT_TIME_HMSM_STRICT,&err); //延时Mov_time_ave
}
}`
…
但是事实上最快速度也只能设置成150ms,再快就会导致无法四条腿同步。
当然这也就决定了在同步执行移动动作之前会有一段姿势初始化的程序,把四条腿都运动到准备开始走的姿势。这个过程我是直接顺序执行的,会消耗一段比较长的时间去完成这个姿势初始化。具体实现见源码。
不过也因为需要同步执行的原因,暂时还没有实现运动时转向的功能,只能停下来转向再前进。
- 稳定模式
主机上搭载了一个mpu6050陀螺仪,可以采集到三轴的角度信息,我用它实现了一个稳定模式的功能,通过采集俯仰角和横滚角,利用四条腿计算偏移进行调整,使其在一个不稳定的平面上保持水平。如图:
while(mpu_dmp_get_data(&pitch,&roll,&yaw)==1); //获取角度数据
LED = ~LED;
if(pitch>3)
{
pitch_move=pitch_move+1;
}
if(pitch<-3)
{
pitch_move=pitch_move-1;
}
if(roll>3)
{
roll_move=roll_move+1;
}
if(roll<-3)
{
roll_move=roll_move-1;
}
PCA_Ctrl(1,RH_B_Initial_angle+(pitch_move*1.2*1.75)+(roll_move*1.2*1.75));
PCA_Ctrl(2,RH_C_Initial_angle+pitch_move*1.2+roll_move*1.2);
PCA_Ctrl(4,LH_B_Initial_angle-(pitch_move*1.2*1.75)+(roll_move*1.2*1.75));
PCA_Ctrl(5,LH_C_Initial_angle-pitch_move*1.2+roll_move*1.2);
PCA_Ctrl(7,LT_B_Initial_angle-(pitch_move*1.2*1.75)-(roll_move*1.2*1.75));
PCA_Ctrl(8,LT_C_Initial_angle-pitch_move*1.2-roll_move*1.2);
PCA_Ctrl(10,RT_B_Initial_angle+(pitch_move*1.2*1.75)-(roll_move*1.2*1.75));
PCA_Ctrl(11,RT_C_Initial_angle+pitch_move*1.2-roll_move*1.2);
由于摸具等各种原因,这里调整精度最小只设置到3,如果在小就会导致无法归位到完全水平状态,导致来回摇摆。
- 通讯
我使用的是串口蓝牙HC-05模块铜通讯,没什么好说的配置好AT指令后用串口就可以通讯了,值得一说的是,我把每一帧数据给做成了结构体,加入帧头帧尾,发送时转换成字符串发送。因为数据量小,我给所以数据都做成了统一的格式,一个帧可以包括所有类型的数据,当然这也是可以优化的地方。
struct XS_Control_Msg
{
char head_flag[4]; //帧头
char ctrl_cmd[4]; //命令类型
short ctrl_movetime; //动作时间
short ctrl_moverate; //动作分辨率
short tripod_x; //云台x轴角度
short tripod_y; //云台y轴角度
short ctrl_pitch; //遥控pitch角度
short ctrl_roll; //遥控roll角度
short ctrl_yaw; //遥控器yaw角度
char tail_flag[4]; //帧尾
};
- 其他
出了上面说到的这些,我还实现了联动、采集温度、舵机云台等功能,但是都比较简易,所以在这里不细讲,感兴趣的可以看看源码。
模型是油管老哥分享的,建议拿来后修改下中间平台的宽度,我这个元器件实在是放的有点挤。
下载地址:https://www.thingiverse.com/thing:1009659
- 总结
总的来说做这个毕业设计让我收获了许多,当然我在上面也花费了许多时间,有很多还可以优化的地方(比如通讯上,通讯控制时能明显感到延时),不过也算是完整的完成这个项目。后续应该也不会继续优化了(把它放到柜子里吃灰把)。当然这段时间去了解这个东西也让我喜欢上了它,考虑做第二代,目前正在考虑是做六足蜘蛛还是四足舵狗,不过肯定的是下次会采用更强舵机,更大的电池,以及更快主频的芯片,f103跑多任务还是有点难受(当然主要还是我没怎么优化的锅)。之后如果做了的话也还会分享上来。
源码提供下载,是基于正点原子的工程模板。做的不是很好,代码也仅供参考,我也是小白一个,总的来说是分享一下吧。之后可能会发一个演示视频到B站,到时候会把视频链接贴上来。
源码下载链接:https://download.csdn.net/download/weixin_45332920/12719852