Robomaster C610+M2007+stm32组成伺服系统
写这篇文章之前,首先要感谢前人的基础(https://blog.csdn.net/Introver_t/article/details/80103041)。没有了解过基础之前,建议初学者先了解大疆C610+M2007的相关软硬件资料,再看看伺服系统的基本三环结构,当然stm32是需要熟练掌握的。
参考上述文章,再结合大疆官网给出的demo改动,才得以调试出 C610+M2007组成伺服系统用以参加四川省机器人大赛,并获得19年度一等奖。
好了,进入正题。
首先是通信,c610使用can 总线通信,因此需要对STM32的CAN初始化:
Can2Init();
由于我的系统中有4套电机,所以我过滤的时候保留这些电机的地址:
Can_filter_Structure.CAN_FilterIdHigh = ((uint16_t)CAN_2006Moto1_ID << 5);
Can_filter_Structure.CAN_FilterIdLow = ((uint16_t)CAN_2006Moto2_ID << 5);
Can_filter_Structure.CAN_FilterMaskIdHigh = ((uint16_t)CAN_2006Moto3_ID << 5);
Can_filter_Structure.CAN_FilterMaskIdLow = ((uint16_t)CAN_2006Moto4_ID << 5);
这是第一点要注意的,第二:初始化的顺序相当重要,STM32F407单片机CAN总线初始化需要注意一定的顺序,不然老是有can总线初始化失败或者串口工作不正常。如果使用STM32CUBE也许可以避免上述问题。我这里
初始化的顺序:uart6_init(115200);uart4_init(9600);uart3_init(9600);CAN1_Configuration(); //CAN13?¨º??¡¥Can2Init(); InitBar(); //舵机
先串口,再CAN1、CAN2,最后TIM
初始化过后,CAN2接收函数内部需要改动:
1、增加操作系统接口OSIntEnter(),OSIntExit();(无操作系统的无视此行)
2、针对地址做过滤,免得收到无效信息(CAN_2006Moto1_ID……)
moto_measure_t moto_chassis[4] = {0};//4 chassis moto
void CAN2_RX0_IRQHandler(void)
{CanRxMsg rx_message;u8 i;OSIntEnter(); // extern moto_measure_t moto_chassis[4];if (CAN_GetITStatus(CAN2,CAN_IT_FMP0)!= RESET){CAN_ClearITPendingBit(CAN2, CAN_IT_FMP0);CAN_Receive(CAN2, CAN_FIFO0, &rx_message);if((rx_message.IDE == CAN_Id_Standard)&&(rx_message.IDE == CAN_RTR_Data)&&(rx_message.DLC == 8)) //标准帧、数据帧、数据长度为8{if((rx_message.StdId == CAN_2006Moto1_ID)||(rx_message.StdId == CAN_2006Moto2_ID)\||(rx_message.StdId == CAN_2006Moto3_ID)||(rx_message.StdId == CAN_2006Moto4_ID)){i = rx_message.StdId - CAN_2006Moto1_ID;get_moto_measure(&moto_chassis[i], &rx_message);}}}OSIntExit();
}
然后就是重点了:
void TurnMoterSpeedPosCircleTask(void)
{int i;OS_ERR err;extern int Display1;
// Can2Init();for(i=0; i<TurnMotorNum; i++){ /*pid, maxout, intergral_limit, deadband, kp, ki, kd*/pid_param_init(&SpeedTurnMotorPid[i], 10000, 0, 100, 2.5, 0, 2.0); pid_param_init(&LocationTurnMotorPid[i], 10000, 0, 20, 0.3, 0.01, 0.35);}while(1) {for(i=0; i<TurnMotorNum; i++){ pid_calculate(&LocationTurnMotorPid[i], moto_chassis[i].total_angle, TurnMotorPos[i]);pid_calculate(&SpeedTurnMotorPid[i], moto_chassis[i].speed_rpm, LocationTurnMotorPid[i].output); }
#ifndef MotorDebugset_moto_current(SpeedTurnMotorPid[0].output, SpeedTurnMotorPid[1].output,\SpeedTurnMotorPid[2].output, SpeedTurnMotorPid[3].output);
#endifOSTimeDlyHMSM(0,0,0,10,OS_OPT_TIME_HMSM_NON_STRICT,&err); }
}
上述代码使用pid控制器构建了速度环和位置环。
pid_param_init(&SpeedTurnMotorPid[i], 10000, 0, 100, 2.5, 0, 2.0); 这是对速度环的初始化,pid_param_init(&LocationTurnMotorPid[i], 10000, 0, 20, 0.3, 0.01, 0.35);是对位置环路的初始化。
void pid_param_init(PID_TypeDef * pid, uint16_t maxout,uint16_t intergral_limit,float deadband,float kp, float ki, float kd)
设置的参数有:pid, maxout, intergral_limit, deadband, kp, ki, kd。pid指你需要设定的PID控制器,本质是一个结构体。maxout指最大输出量,也就是限制幅度。intergral_limit是抗饱和积分,该参数可以限制积分器的最大输出值,我没有用,直接设置0。deadband是死区,意思是误差绝对值如果小于该参数,PID输出0,防止系统产生抖动。然后就是kp, ki, kd三个参数。这是初始化。
接下来就是PID环路的运算,我有四个电机,每个电机都要分别运算速度、位置环路,因此有个4循环:
for(i=0; i<TurnMotorNum; i++){ pid_calculate(&LocationTurnMotorPid[i], moto_chassis[i].total_angle, TurnMotorPos[i]);pid_calculate(&SpeedTurnMotorPid[i], moto_chassis[i].speed_rpm, LocationTurnMotorPid[i].output); }
循环内部的PID运算环路:
float pid_calculate(PID_TypeDef* pid, float measure, float set)
参数意义分别是:PID控制器,分别对应速度环、位置环。measure是测量值,也就是通过编码器获取得到的速度值或者位置值。set是设定值,也就是期望达到的值。该函数运算后,将控制量(输出量)存放在结构体PID_TypeDef* pid当中,以供后续调用使用。
需要指出的是:位置环的设定值是指定值(例如:需要转到xx度),而速度环的设定值是位置环的输出值:LocationTurnMotorPid[i].output,而速度环路的输出值,直接给电流环作为输入使用:
set_moto_current(SpeedTurnMotorPid[0].output, SpeedTurnMotorPid[1].output,\SpeedTurnMotorPid[2].output, SpeedTurnMotorPid[3].output);
上述伺服系统作为机器人舵轮的转向系统使用,欢迎交流Q:348913335
代码分享:https://download.csdn.net/download/lianqingde/87817797
运行视频:https://www.bilibili.com/video/av76449463/
Robomaster C610+M2007+stm32组成伺服系统相关推荐
- 如何用Robomaster C610/820R电调组成伺服电机控制系统(附STM32F407源码实现及分析)
写在前面,因为代码在一个工程里很混乱,难以单独剥离出来,所以求源码的我就不一一回复发送了,请大家见谅.但可以参考Robomaster官方提供的DEMO,官方的代码条理性更强,更适合拿来参考,传送门:h ...
- 大疆M2006电机测试文档
一.项目 MilkTeaBrother是使用麦克纳姆移动方式的室内服务小车,动力系统为RoboMaster M2006,文中提到的相关文件可以在下方获取. 点击此处了解MilkTeaBrother相关 ...
- 从零开始,用CubeMX让M2006电机转起来,大疆C板控制M2006电机
发现网上很少有关于这个的文章,到处找,搜索引擎试了个遍,还在Robomaster的论坛里找了找,最终也是没有找到类似的文章.还好在B站上找到了一个视频教程,帮助很多,致敬前辈!,视频链接在文末.但是这 ...
- RoboMaster机甲大师比赛入门?我们从STM32开始!
同步博客地址:从STM32开始的RoboMaster生活:入门篇 项目&教程仓库:-STM32-RoboMaster- 1.0 STM32是什么 1.1 定义 ST + M + 32 = ST ...
- STM32 电机教程 28 - ST MCLIB实战之 位置闭环控制
前言 ST MotorControl Workbench 生成的工程默认实现了电机的电流闭环和速度闭环控制,有些应用场合需要对电机的位置也实现闭环控制,如舵机,伺服系统等,本节就给大家介绍一下基于ST ...
- 【STM32】CubeMX+HAL库之 硬件IIC+DMA控制OLED(兼容SSD1306SH1106驱动)
[STM32]CubeMX+HAL库之 硬件IIC+DMA控制1.3寸OLED 前言 目前网上大多数驱动OLED屏都采用软件IIC,因为HAL库的升级使得硬件IIC的稳定性得到了保障,所以想采用硬件I ...
- RoboMaster视觉教程(8)串口通讯
RoboMaster视觉教程(8)串口通讯 概览 DJI开源代码串口部分 东南大学开源代码串口部分 Qt编写串口助手 概览 这几天一直在做一个小车打算做好了再往下写的,但是由于我两年没写stm32的程 ...
- 【Robomaster】电控入门手册
文章目录 0 电控介绍 0.1 电控学习内容 0.2 物资准备 1 C语言学习 1.1 学习资料 1.2 学习规划 1.2.1 基础 1.2.2 函数 1.2.3 数组 1.2.4 进阶 2 Ardu ...
- 了解CV和RoboMaster视觉组(二)视觉在各兵种中的作用
--NeoZng[neozng1@hnu.edu.cn] 2.视觉在各兵种中的作用 2.1.装甲板识别(步兵.英雄.无人机) 由于机器人上安装的图传模块到操作手看到的第一视角的延迟加上操作手反应速度的 ...
最新文章
- 高文、张钹、杨强隔空论道:AI精度与隐私的博弈
- 架构师应具备的概要技能
- pytorch 三角函数
- python input与返回值-Python 详解基本语法_函数_返回值
- Python自定义函数的创建、调用和函数的参数详解
- 【Android 应用开发】View 与 SurfaceView 区别
- nginx 开启gzip 配置js_前端性能优化之缓存与GZIP
- 【工业控制】PolyWorks培训教程-PCB字符机平行度和垂直度
- 浅谈C++类(5)--友元
- 多亏了这篇文章,我的开发效率远远领先于我的同事
- 编码 data text html c,谁说前端不需要懂二进制
- 计算机以弧计算和以度计算公式,角度换算公式(角度计算公式图解)
- 学习如何读论文的一些磨刀不误砍柴工
- 得到app文稿导出_得到app的文稿怎么下载复制导出
- 锐捷BFD+VSU配置
- AD18中元器件的中心点标注和叉叉怎么取消掉
- pete shinners_Hanselminutes播客155-带有Silverlight 3的C64模拟器,作者:Pete Brown
- 随机合并多个视频,同时更换背景音频
- .net 流——使用流进行文件复制
- 关于吉他5种指型Mi-La-Re-Sol-Ti
热门文章
- iOS程序员如何面试?
- python浪漫代码表白npy_Python 存取npy格式数据实例
- Docker下载太慢或者卡死的解决办法
- 如何使用 SigNoz 快速搭建一个可观测系统
- 未能找到任何适合于指定的区域性或非特定区域性的资源。请确保在编译时已将“xxx.Resources.resources”正确嵌入或链接到程序集...
- 玩转「Wi-Fi」系列之应用程序(五)
- hctf 2016 write up
- Redis集群数据同步与选举
- 2022河南萌新联赛第(三)场:河南大学
- JavaScript类型转换: Boolean