首先说一下结果,由于场地原因(很多组在上面调试,黑线撕来撕去在上面留下了很深的痕迹,导致我们机器的传感器误识别最终导致比赛时一箱都没搬,很遗憾,之前感觉是比较稳的还想着冲下国一,成功视频都拍了十几个)虽然说有我们自己的原因,我们没有提前到场地调试,也没有做好应对突发情况的补救措施。因为我们说是五个人的队伍,实际就两个人主要参与了这次比赛,当然也要感谢学长给我提供的电控的经验和指导,帮我走了不少弯路.
虽有遗憾,我在这次经历也不是什么都没有学到,学了很多东西,独立完成一个项目,有了自己的经验,也认识了很多优秀学长。明年大三我也准备继续参赛,争取拿个国一,弥补今年的遗憾。
我在此次比赛中主要负责电控,所以此篇文章也是主要分享电控部分的内容,我写此篇博客的目的也很明确,一方面是将技术及经验分享给更多需要的人,另一方面是我也想继续学习更多想学的,但是大家都懂,硬件是很烧钱的,我没有老师带,就更没有经费,所以我需要用这些来挣一些经费。
考虑到我们明年还会参加 目前分享的一些可能只是一个方向,具体的该怎么实现我会在第八届比赛结束后补充更加详细一些。
比赛视频:第七届物流起重机大赛-哔哩哔哩】 https://b23.tv/k2rHV50
第七届物流起重机大赛源码及资料,经验
包含三个主体部分: 底盘运动部分(最基础的pwm控制轮子转动,pid循迹,陀螺仪矫正姿态),取物机构(机械爪,步进电机),路径规划部分
底盘运动部分
1.pwm控制驱动轮子旋转
电机选型:考虑到起重机比赛的机器一般都比较重(一二十斤),所以我们必须选择合适型号(扭矩)的电机才能带的动,嫌麻烦的可以直接买我们这种。
要想让轮子转起来,你就得分几步去完成,分几个部分,配置电机正反转引脚GPIO,然后就是配置定时器能输出pwm波从而控制电机的速度,pwm是怎么调速的呢,简单来说,你的电机是电压驱动的,电压越高转速越快,如果你不加pwm,直接接电池,此时轮子是满速的,pwm就是以固定周期(定时器周期)输出一定时间的高电平,即占空比,(ccr/T)*电压即你给电机的速度。实现电机pwm调速了,你就完成了第一步了,第二部就是应用部分,你要编写运动函数控制小车运动比如向前向后,左平移右平移(我们用的麦克纳姆轮)
下面展示一些 内联代码片
。
//*************************小车运动状态配置********************************
//前进
void car_GO(int ccr1,int ccr2,int ccr3,int ccr4)
{
LED_RED;
SysTick_Delay_Ms(1000);
MOTOR1_state(GO);
MOTOR2_state(GO);
MOTOR3_state(GO);
MOTOR4_state(GO);
Speed_1(ccr1);Speed_2(ccr2);Speed_3(ccr3);Speed_4(ccr4);
LED_GREEN;
}
//后退
void car_BACK(int ccr1,int ccr2,int ccr3,int ccr4)
{
MOTOR1_state(BACK);
MOTOR2_state(BACK);
MOTOR3_state(BACK);
MOTOR4_state(BACK);
Speed_1(ccr1);Speed_2(ccr2);Speed_3(ccr3);Speed_4(ccr4);
}
//右平移
void car_RIGHT(int ccr1,int ccr2,int ccr3,int ccr4)
{
MOTOR1_state(GO);
MOTOR2_state(BACK);
MOTOR3_state(BACK);
MOTOR4_state(GO);
Speed_1(ccr1);Speed_2(ccr2);Speed_3(ccr3);Speed_4(ccr4);
}
void car_LEFT(int ccr1,int ccr2,int ccr3,int ccr4)
//左平移
{
MOTOR1_state(BACK);
MOTOR2_state(GO);
MOTOR3_state(GO);
MOTOR4_state(BACK);
Speed_1(ccr1);Speed_2(ccr2);Speed_3(ccr3);Speed_4(ccr4);
}
//逆时针旋转
void car_ANTICLOCK(int ccr1,int ccr2,int ccr3,int ccr4)
{
MOTOR1_state(BACK);
MOTOR2_state(GO);
MOTOR3_state(BACK);
MOTOR4_state(GO);
Speed_1(ccr1);Speed_2(ccr2);Speed_3(ccr3);Speed_4(ccr4);
}
//顺时针旋转
void car_CLOCK(int ccr1,int ccr2,int ccr3,int ccr4)
{
MOTOR1_state(GO);
MOTOR2_state(BACK);
MOTOR3_state(GO);
MOTOR4_state(BACK);
Speed_1(ccr1);Speed_2(ccr2);Speed_3(ccr3);Speed_4(ccr4);
}
//刹车 注意这里为了方便 也为了减少各电机关闭的时间差 PORT没有采用定义的 如果改变电机逻辑引脚IO这里也要修改
void car_STOP(void)
{
GPIO_ResetBits(GPIOE,A1IN_PIN|B1IN_PIN|A2IN_PIN|B2IN_PIN);
GPIO_ResetBits(GPIOA,A3IN_PIN|B3IN_PIN|A4IN_PIN|B4IN_PIN);
Speed_1(0);Speed_2(0);Speed_3(0);Speed_4(0);
}
2.pid循迹
VID_20220822_201802
循迹部分我们是在小车前后用了两个循迹模块,先说结论:两路模拟量完全够用
主要是用adc采样,以左右两路adc的差值作为判断依据编写pid函数。
3.陀螺仪矫正姿态
VID_20220822_201802
由于我们使用的是麦克纳姆轮,且四个电机转动实际速度肯定有不同,再考虑到摩擦力,机械结构导致的每个轮子与地面接触程度不同,它是肯定跑不直的,所以我们需要借助陀螺仪获取航向角,将航向角加入pid算法中即可。
陀螺仪是最后几天才加进去的,由于时间紧迫且我们没有用过陀螺仪,我们直接在淘宝花三百多买了个陀螺仪,它内置了官方的算法,只要给它供电,再配置下串口,就能直接发送航向角给主控,而航向角刚好是我们想要的,这就帮我们解决了很多时间。
取物机构
1.机械爪
机械爪我们是直接买的成品 发现其实就是控制两个舵机旋转一定的角度 把舵机pwm控制学会就好了很容易的
2.步进电机
在一般情况下EN端可不接,EN有效时电机转子处于自由状态(脱机状态),这时 可以手
动转动电机转轴,做适合您的调节。手动调节完成后,再将 EN 设为 无效状态,以继续自动控制 。
我当时采用的是共阴极接法,
即驱动器的DIR- ,PUL-还有GND都与单片机的GND相连即共地
细分数设定(需要注意的是并不是设置电流越大越好,根据电机的功率取合适值即可)
步距角=电机固有步距角/细分数
如:一台固有步距角 为1.8°的步进电机在4细分下步距角为1.8°/4=0.45°
驱动板上 拨码开关1、2、3、分别对应S1、S2、S3 . (这里需要注意的是并不是设置细分数越大越好,400细分的意思就是:400个脉冲电机转动1圈)
电流大小设定
这是当时写的一个上升函数
步进电机速度只与pwm频率有关 只用改动period的值 占空比一般设置为50% 对应改ccr为period的一半
void generalInit(uint16_t ccr,uint16_t period,uint16_t psc)//generalInit函数是初始化定时器的函数
{
GENERAL_GPIO_CONFIG();
GENERAL_TIM_MODE_CONFIG(ccr,period,psc);
DIR_GPIO_CONFIG();
}
void UP_t(uint16_t t_up)//t_up为需要上升的时间
{
DIR_ANTICLK(DIR_PORT_BUJIN,DIR_PIN_BUJIN);//顺时针旋转
generalInit(500,999,71);
Systick_Delay_ms(t_up);
generalInit(500,0,71);
}
路径规划部分
我将整个工程分成了三步(取物,送物,放物)在主函数中循环三次 根据相应标志位触发跳到下一步
这个是当时的路线图
比赛视频:第七届物流起重机大赛-哔哩哔哩】 https://b23.tv/k2rHV50
第七届物流起重机大赛源码及资料,经验
https://mianbaoduo.com/o/author-bmyalmln