0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于 RT-Thread 的 RoboMaster 电控框架(一)

RTThread物联网操作系统 来源:未知 2023-09-19 19:55 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

由于 RT-Thread 稳定高效的内核,丰富的文档教程,积极活跃的社区氛围,以及设备驱动框架、Kconfig、Scons、日志系统、海量的软件包……很难不选择 RT-Thread 进行项目开发。但也正是因为这些优点的覆盖面较广,很多初学者会觉得无从下手,但只要步入 RT-Thread 的大门,你就发现她的美好。这系列文档将作为本人基于 RT-Thread 开发 RoboMaster 电控框架的记录与分享,希望能帮助到更多初识 RT-Thread 的小伙伴,也欢迎大家交流分享,指正不足,共同进步。

背景

Robomaster 机器人比赛包含多个兵种,为了提高研发效率,模块化尤为重要,使用 RT-Thread 有助于面对对象思想开发;通过配备的 Kconfig,Scons 等工具可以实现工程的灵活配置;软件定时器可用作各电机等模块监控,RingBuffer 可以实现传感器信息的高效处理 …….使用的开发板为大疆的 RoboMaster-C 型开发板,基础工程为 rt-thread>bsp>stm32f407-robomaster-c

电机模块开发

使用电机和电调均为大疆官方出品,如 2006,3508,6020 等,采用 CAN 通讯方式。

构建对象

首先我们根据使用的电机特性,构建一个通用的电机对象

 1/**
 2*@briefDJIintelligentmotortypedef
 3*/
 4typedefstructdji_motor_object
 5{
 6rt_device_tcan_dev;//电机CAN实例
 7dji_motor_measure_tmeasure;//电机测量值
 8uint32_ttx_id;//发送id(主发)
 9uint32_trx_id;//接收id(主收)
10/*分组发送设置*/
11uint8_tsend_group;//同一帧报文分组
12uint8_tmessage_num;//一帧报文中位置
13motor_type_emotor_type;//电机类型
14motor_working_type_estop_flag;//启停标志
15/*监控线程相关*/
16rt_timer_ttimer;//电机监控定时器
17/*电机控制相关*/
18void*controller;//电机控制器
19int16_t(*control)(dji_motor_measure_tmeasure);//控制电机的接口用户可以自定义,返回值为16位的电压或电流
20}dji_motor_object_t;

因为这些电机我们均使用 CAN 方式进行驱动,是 CAN 设备的延申,于是将 rt_device_t can_dev 父类结构体对象内嵌。

dji_motor_measure_t 结构体中为,电机控制时需要用到的一些反馈值,包括电调直接反馈的数据以及进一步解算的得出的:

 1/**
 2*@briefDJImotorfeedback
 3*/
 4typedefstruct
 5{
 6/*以下是处理得出的数据*/
 7floatangle_single_round;//单圈角度
 8floatspeed_aps;//角速度,单位为:度/秒
 9floattotal_angle;//总角度,注意方向
10int32_ttotal_round;//总圈数,注意方向
11floattarget;//目标值(输出轴扭矩矩/速度/角度(单位度))
12/*以下是电调直接回传的数据*/
13uint16_tecd;//0-8191
14uint16_tlast_ecd;//上一次读取的编码器
15int16_tspeed_rpm;//电机的转速值
16int16_treal_current;//实际转矩电流
17uint8_ttemperature;//Celsius
18}dji_motor_measure_t;

注册实例

通过 dji_motor_object_t *dji_motor_register(motor_config_t *config, void *controller) 注册对应的电机实例,用户通过 motor_config_t *config 对实例进行灵活配置:

 1/**
 2*@brief电机初始化,返回一个电机实例
 3*@paramconfig电机配置
 4*@returndji_motor_object_t*电机实例指针
 5*/
 6dji_motor_object_t*dji_motor_register(motor_config_t*config,void*controller)
 7{
 8dji_motor_object_t*object=(dji_motor_object_t*)rt_malloc(sizeof(dji_motor_object_t));
 9rt_memset(object,0,sizeof(dji_motor_object_t));
10//对接用户配置的motor_config
11object->motor_type=config->motor_type;//6020or2006or3508
12object->rx_id=config->rx_id;//电机接收报文的ID
13object->control=controller;//电机控制器
14/*查找CAN设备*/
15object->can_dev=rt_device_find(config->can_name);
16//电机分组,因为至多4个电机可以共用一帧CAN控制报文
17motor_send_grouping(object,config);
18//电机离线检测定时器相关
19object->timer=rt_timer_create("motor1",
20motor_lost_callback,
21object,20,
22RT_TIMER_FLAG_PERIODIC);
23rt_timer_start(object->timer);
24dji_motor_enable(object);
25dji_motor_obj[idx++]=object;
26returnobject;
27}
28/*电机配置结构体*/
29typedefstruct
30{
31motor_type_emotor_type;
32constchar*can_name;
33uint32_ttx_id;//发送id(主发)
34uint32_trx_id;//接收id(主收)
35void*controller;//电机控制器
36}motor_config_t;
motor_config_t 结构体中的 void *controller 为电机所使用到的控制器集合,是一个控制器类型为其成员的结构体变量,如下:
1staticstructchassis_controller_t{
2pid_object_t*speed_pid;
3}chassis_controller;
4staticstructgimbal_controller_t{
5pid_object_t*speed_pid;
6pid_object_t*angle_pid;
7}gimbal_controlelr;

调用 dji_motor_object_t *dji_motor_register 时传入的 void *controller 为电机对应的控制器具体实现,如进行 pid 计算,滤波等,会赋值给电机对象对应的函数指针,在进行电机控制计算时被执行,如下:

1rt_int16_tchassis_control(dji_motor_measure_tmeasure){
2staticrt_int16_tset=0;
3set=pid_calculate(chassis_controller.speed_pid,measure.speed_rpm,1000);
4returnset;
5}

数据处理

电机对象离不开对数据稳定快速的收发和解析计算,接下来展开讨论使用 RT-Thread 的 CAN 设备驱动收发数据的思路。

首先是数据的接收,stm32f4 拥有 2 个 CAN 外设,所有电机和使用 CAN 总线的设备都挂载在这两条总线上,但 RT-Thread 的每个 CAN 总线只能通过 rt_device_set_rx_indicate(can_dev, can_rx_call); 注册一个对应的接收回调函数。但不同类型电机,不同 CAN 设备的数据解析处理都是不一样的,我这里的解决思路是:首先创建了一个 usr_callback 文件,用于统一管理 CAN、串口等设备可能用到的用户接收对调函数;将一个大的设备类型回调函数注册到对应 CAN 设备,其中再细分各挂载设备的数据解析,实现如下:

 1#ifdefBSP_USING_CAN
 2rt_err_tcan_rx_call(rt_device_tdev,rt_size_tsize)
 3{
 4structrt_can_msgrxmsg={0};
 5uint8_t*rxbuff=rxmsg.data;
 6/*从CAN读取一帧数据*/
 7rt_device_read(dev,0,&rxmsg,sizeof(rxmsg));
 8/*CAN接收到数据后产生中断,调用此回调函数,然后发送接收信号量*/
 9#ifdefBSP_USING_DJI_MOTOR
10dji_motot_rx_callback(rxmsg.id,rxbuff);
11#endif/*BSP_USING_DJI_MOTOR*/
12returnRT_EOK;
13}
14#endif/*BSP_USING_CAN*/
但是这其中也有一点问题,rt_err_t can_rx_call(rt_device_t dev, rt_size_t size) 传入的参数无法判断具体的 CAN 设备来源,因此所有使用到的 CAN 外设数据处理函数都会被调用,但目前问题不大,因为同一条总线上不会挂载相同 ID 的设备,这也是一开始就应该避免的错误。接下来是 CAN 报文的发送,调用 rt_device_write 发送填充好的 CAN 报文帧即可。离线检测这里使用 RT-Thread 的软件定时器对电机进行离线检测,当超过定时间没有接收到对应电机反馈报文,则进入超时回调,并输出警告日志:
 1/**
 2*@brief电机定时器超时回调函数
 3*@parammotor_ptr
 4*/
 5staticvoidmotor_lost_callback(void*motor_ptr)
 6{
 7dji_motor_object_t*motor=(dji_motor_object_t*)motor_ptr;
 8//dji_motor_stop(motor);
 9LOG_W("[dji_motor]Motorlost,canbus[%s],id0x[%x]",motor->can_dev->parent.name,motor->rx_id);
10}

使用实例

封装完成的电机模块使用示例如下:

 1staticstructchassis_controller_t{
 2pid_object_t*speed_pid;
 3}chassis_controller;
 4staticstructgimbal_controller_t{
 5pid_object_t*speed_pid;
 6pid_object_t*angle_pid;
 7}gimbal_controlelr;
 8staticdji_motor_object_t*chassis_motor;
 9staticdji_motor_object_t*gimbal_motor;
10rt_int16_tchassis_control(dji_motor_measure_tmeasure){
11staticrt_int16_tset=0;
12set=pid_calculate(chassis_controller.speed_pid,measure.speed_rpm,1000);
13returnset;
14}
15rt_int16_tgimbal_control(dji_motor_measure_tmeasure){
16staticrt_int16_tset=0;
17set=pid_calculate(gimbal_controlelr.speed_pid,measure.speed_rpm,0);
18returnset;
19}
20staticvoidexample_init()
21{
22pid_config_tchassis_speed_config={
23.Kp=10,//4.5
24.Ki=0,//0
25.Kd=0,//0
26.IntegralLimit=3000,
27.Improve=PID_Trapezoid_Intergral|PID_Integral_Limit|PID_Derivative_On_Measurement,
28.MaxOut=12000,
29};
30pid_config_tgimbal_speed_config={
31.Kp=50,//50
32.Ki=200,//200
33.Kd=0,
34.Improve=PID_Trapezoid_Intergral|PID_Integral_Limit|PID_Derivative_On_Measurement,
35.IntegralLimit=3000,
36.MaxOut=20000,
37};
38chassis_controller.speed_pid=pid_register(&chassis_speed_config);
39gimbal_controlelr.speed_pid=pid_register(&gimbal_speed_config);
40motor_config_tchassis_motor_config={
41.motor_type=M3508,
42.can_name=CAN_CHASSIS,
43.rx_id=0x201,
44.controller=&chassis_controller,
45};
46motor_config_tgimbal_motor_config={
47.motor_type=GM6020,
48.can_name=CAN_GIMBAL,
49.rx_id=0x206,
50.controller=&gimbal_controlelr,
51};
52chassis_motor=dji_motor_register(&chassis_motor_config,chassis_control);
53gimbal_motor=dji_motor_register(&gimbal_motor_config,gimbal_control);
54}

到此就可以方便且灵活的配置和使用电机模块啦

仓库地址放这里了 HNU_RM_SHARK_C ,觉得不错可以点个 Star !

存在问题及优化方向

  1. 目前 rt-thread 下 stm32 can驱动似乎仅支持 FIFO0 ,但 stm32f4 系列 can 具备两个 FIFO,如能同时使能所有 FIFO,应该能有效提高性能和稳定性。

  2. 电机的离线回调可以增加相应的声光报警。

  3. 后续考虑能不能也优化为,read,write,control 等形式。

————————————————

版权声明:本文为RT-Thread论坛用户「螺丝松掉的人」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://club.rt-thread.org/ask/article/0a655bcf83494c87.html

———————End——————

点击阅读原文进入官网


原文标题:基于 RT-Thread 的 RoboMaster 电控框架(一)

文章出处:【微信公众号:RTThread物联网操作系统】欢迎添加关注!文章转载请注明出处。


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • RT-Thread
    +关注

    关注

    32

    文章

    1636

    浏览量

    45200

原文标题:基于 RT-Thread 的 RoboMaster 电控框架(一)

文章出处:【微信号:RTThread,微信公众号:RTThread物联网操作系统】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    RT-Thread任务+消息订阅管理框架软件包:thread_manager+event_loop

    读者留言,是否可以支持RT-Thread,索性放假也无聊,所以就整了两个软件包:eventloop+thread_manager二.eventloop软件包个是
    的头像 发表于 04-19 15:39 3403次阅读
    <b class='flag-5'>RT-Thread</b>任务+消息订阅管理<b class='flag-5'>框架</b>软件包:<b class='flag-5'>thread</b>_manager+event_loop

    恩智浦亮相RT-Thread 20周年开发者大会

    日前,“开源向实·生产力进化启示录”全球峰会暨RT-Thread 20周年开发者大会在上海成功举办,恩智浦作为RT-Thread的紧密合作伙伴,在活动中重磅亮相,展示双方在共建RT-Thread OS开发生态方面的新成果、新方案
    的头像 发表于 01-26 09:07 740次阅读

    基于RT-Thread和兆易创新GD32F527系列MCU的健康监测站 | 技术集结

    本项目为RT-Thread嵌入式大赛获奖作品,基于RT-Thread和兆易创新GD32F527I-EVAL的健康监测站。目录项目概述系统硬件框架结构基础驱动程序实现整体驱动实现工程效果演示视频及代码演示
    的头像 发表于 01-20 17:37 7392次阅读
    基于<b class='flag-5'>RT-Thread</b>和兆易创新GD32F527系列MCU的健康监测站 | 技术集结

    手搓RT-Thread工地巡检机器人要几步? | 技术集结

    本项目为RT-Thread嵌入式大赛获奖作品,基于CanMVK230的工地巡检机器人。K230芯片集成了两颗RISC-V处理器核心,双核玄铁C908。RT-Thread已全面支持XUANTIE系
    的头像 发表于 12-29 21:46 4268次阅读
    手搓<b class='flag-5'>一</b>个<b class='flag-5'>RT-Thread</b>工地巡检机器人要几步? | 技术集结

    基于RT-Thread的简单物联网温控箱 | 技术集结

    目录项目概述RT-Thread使用情况概述硬件框架软件框架说明演示效果改进方向代码地址1项目概述本项目是个简易的、较高精度的、易于扩展的桌面级温控系统。实现对箱内温度的精确控制,并通
    的头像 发表于 12-26 18:18 7428次阅读
    基于<b class='flag-5'>RT-Thread</b>的简单物联网温控箱 | 技术集结

    首搭RT-Thread程翧车控平台| RT-Thread程翧 S32K344 快速原型开发平台正式上市!| 产品动态

    在智能汽车迈向高集成与高安全的时代,VCU/ECU开发正面临效率与可靠性的双重考验。依赖单硬件或拼凑软件方案的传统模式,已成为制约创新的瓶颈。为此,RT-Thread带来里程碑式的解决方案
    的头像 发表于 10-31 11:53 1257次阅读
    首搭<b class='flag-5'>RT-Thread</b>程翧车控平台| <b class='flag-5'>RT-Thread</b>程翧 S32K344 快速原型开发平台正式上市!| 产品动态

    2025年RT-Thread开发者巡回培训报名正式启动!

    亲爱的RT-Thread社区成员们:新程再启,共赴热爱!2025年RT-Thread开发者巡回培训正式启动报名!今年,我们选择了西安、武汉、北京、杭州、深圳、上海、成都这7座城市,为大家带来
    的头像 发表于 09-27 10:39 2355次阅读
    2025年<b class='flag-5'>RT-Thread</b>开发者巡回培训报名正式启动!

    rt-thread studio 2.2.9如何使用最新的RT-Thread v5.2.0 released?

    rt-thread studio2.2.9如何使用最新的RT-Thread v5.2.0 released? 原先以为修改index_all.json,发现联网的时候,会自动覆盖 另lastet版本
    发表于 09-16 06:06

    【好书推荐】RT-Thread第20本相关书籍!《嵌入式实时操作系统RT-Thread原理与应用》| 技术集结

    01内容简介ContentSummary本书为读者提供了个全面、系统的RT-Thread学习指南,旨在帮助初学者及有经验的开发者掌握RT-Thread实时操作系统和STM32嵌入式微控制器的核心
    的头像 发表于 08-24 10:05 1260次阅读
    【好书推荐】<b class='flag-5'>RT-Thread</b>第20本相关书籍!《嵌入式实时操作系统<b class='flag-5'>RT-Thread</b>原理与应用》| 技术集结

    RT-Thread 遇上 Rust:安全内核 RusT-Thread 的诞生

    大家好,我们是中国科学技术大学操作系统原理与设计(H)课oooooS小组。这个项目是我们的课程大作业:参考RT-Thread架构,使用Rust搭建个原生的嵌入式操作系统内核。初识Rust是因为xk
    的头像 发表于 08-02 11:03 3711次阅读
    <b class='flag-5'>RT-Thread</b> 遇上 Rust:安全内核 RusT-<b class='flag-5'>Thread</b> 的诞生

    RT-Thread荣获2025优秀开源项目 | 新闻速递

    6月底,RT-Thread睿赛德受邀参与由上海开源信息技术协会主办的2025上海开源创新精英荟。上海市商委副主任张杰出席会议并致辞。RT-Thread嵌入式操作系统项目凭借其卓越的技术创新与开源生态
    的头像 发表于 07-04 09:04 2812次阅读
    <b class='flag-5'>RT-Thread</b>荣获2025优秀开源项目 | 新闻速递

    深度剖析 RT-Thread 线程调度流程

    RT-Thread调度第个线程的主要流程分如下:rtthread_startup:RTT的启动函数,主要负责板级驱动,调度器,系统线程初始化,启动调度的工作
    的头像 发表于 06-25 18:24 1950次阅读
    深度剖析 <b class='flag-5'>RT-Thread</b> 线程调度流程

    揭秘RT-Thread上的AUTOSAR CP系统

    本文探讨了RT-Thread与AUTOSARCP的融合,解决车载ECU开发中实时性、安全性与灵活性的平衡问题。通过分层安全内核(rt-safetyos/autoos)和工具链整合,兼容AUTOSAR
    的头像 发表于 06-23 20:22 3421次阅读
    揭秘<b class='flag-5'>RT-Thread</b>上的AUTOSAR CP系统

    2025 RT-Thread全球技术大会议程正式发布!

    RT-ThreadGlobalTechConference(RT-ThreadGTC,RT-Thread全球技术大会)是聚焦基础软件技术创新与实践的嵌入式技术盛会,持续推动技术价值转化
    的头像 发表于 05-27 19:28 1541次阅读
    2025 <b class='flag-5'>RT-Thread</b>全球技术大会议程正式发布!

    RT-Thread审核团招募: 深度参与开源RTOS社区治理与演进

    全球开发者招募:RT-Thread审核团(ReviewTeam)正式开放申请!在开源的世界里,代码审查(CodeReview)是保证软件质量、促进技术交流的关键环节。RT-Thread作为全球领先
    的头像 发表于 05-21 18:02 1426次阅读
    <b class='flag-5'>RT-Thread</b>审核团招募: 深度参与开源RTOS社区治理与演进