# M3508_Project **Repository Path**: carbon-xu/m3508_project ## Basic Information - **Project Name**: M3508_Project - **Description**: 基于大疆A板的M3508电机闭环驱动以及串口绘图 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2025-11-30 - **Last Updated**: 2026-03-23 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 对M3508电机的闭环驱动以及串口绘图项目的总结 ## 一、控制流程 ### 角度环、速度环控制 : __输入目标角度__ → __角度环PID输出目标速度__ → __速度环PID输出目标电流__ → __通过CAN通信驱动M3508电机__ → __反馈报文给相应的PID __ ## 二、代码理解 ### 1、尝试使用C++进行类的封装 ```c++ class Class_Motor_M3508 { public: Class_Motor_M3508(uint16_t ID, CAN_HandleTypeDef *hcan); //构造函数 Class_PID Speed_PID{15.0f, 0.0f, 0.1f, 0.01f, 16384.0f, 16384.0f}; // 速度环PID参数 Class_PID Angle_PID{5.0f, 0.0f, 0.5f, 0.01f, 500.0f, 300.0f}; // 角度环PID参数 void Set_Current(int16_t current); // 设置电机电流 void Set_Speed(float target_speed); // 设置目标速度,使用速度环PID计算电流 void Set_Angle(float target_angle); // 设置目标角度,使用角度环PID计算速度 void Update_From_Feedback(Struct_CAN_Rx_Buffer *rx_buffer); // 从反馈数据更新电机状态 int16_t Get_Actual_Current() const { return actual_current; } // 获取实际电机电流 uint16_t Get_Speed() const { return speed; } // 获取电机速度 uint16_t Get_Angle() const { return angle; } // 获取电机角度 uint8_t Get_Temperature() const { return temperature; } // 获取电机温度 uint16_t Get_ID() const { return motor_ID; } // 获取电机ID private: uint16_t motor_ID; //电机序号(1~8) CAN_HandleTypeDef *can_handler; // CAN句柄 uint8_t *tx_buffer = nullptr; //发送缓冲区指针 uint8_t data_index; //数组元素序号 int16_t actual_current = 0; // 实际电机电流 uint16_t speed = 0; // 电机速度 uint16_t angle = 0; // 电机角度 uint8_t temperature = 0; // 电机温度 }; ``` ### 2、对CAN通信的一些理解 #### 2.1 CAN通信架构 - 使用经典CAN (Classic CAN) - **波特率**: 1Mbps (典型值) - **采样点**: 87.5% - **同步跳转宽度**: 1个时间量子 - **位时间**: 16个时间量子 ##### 2.1.1 M3508电机CAN通信协议 **发送数据包 (控制指令)**: - **CAN ID**: 0x200 (主控发送给电机) - **数据长度**: 8字节 - **数据结构**: ``` Byte 0: 电机1电流值 (低8位) Byte 1: 电机1电流值 (高8位) Byte 2: 电机2电流值 (低8位) Byte 3: 电机2电流值 (高8位) Byte 4: 电机3电流值 (低8位) Byte 5: 电机3电流值 (高8位) Byte 6: 电机4电流值 (低8位) Byte 7: 电机4电流值 (高8位) ``` - **电流值范围**: -16384 ~ 16384 (对应-20A ~ 20A) **接收数据包 (反馈信息)**: - **CAN ID**: 0x201 ~ 0x208 (对应电机1~8) - **数据长度**: 8字节 - **数据结构**: ``` Byte 0-1: 角度值 (0~8191, 对应0~360°) Byte 2-3: 速度值 (rpm, 有符号16位) Byte 4-5: 转矩电流值 (有符号16位) Byte 6: 电机温度 (℃) Byte 7: 预留字节 ``` ##### 2.1.2 通信时序 **典型控制周期**: ``` 1ms周期执行: ┌─────────────────────────────────────────────────────────┐ │ 控制计算周期 (1ms) │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ PID计算 │ │ 数据打包 │ │ CAN发送 │ │ │ │ (角度环) │ │ (电流指令) │ │ (0x200) │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ PID计算 │ │ 数据解析 │ │ 状态更新 │ │ │ │ (速度环) │ │ (反馈数据) │ │ (电机状态) │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ └─────────────────────────────────────────────────────────┘ ``` **数据传输时序**: ``` 时间轴: ──────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────> 0ms 1ms 2ms 3ms 4ms 5ms 6ms 7ms 8ms 发送: [0x200] [0x200] [0x200] [0x200] [0x200] (控制指令) (控制指令) (控制指令) (控制指令) (控制指令) 接收: [0x201] [0x202] [0x203] [0x204] [0x201] [0x202] (电机1) (电机2) (电机3) (电机4) (电机1) (电机2) ``` ##### 2.1.3 错误处理机制 **CAN总线错误检测**: - 位错误 (Bit Error) - 填充错误 (Stuff Error) - CRC错误 (CRC Error) - 格式错误 (Form Error) - 应答错误 (Ack Error) **错误恢复策略**: ``` 错误检测 → 错误计数器增加 → 总线离线 → 自动重连 → 恢复通信 ``` **理论最大吞吐量**: ``` 帧长度 = 67位 (标准帧) 帧间隔 = 3位 总周期 = 70位 最大帧率 = 1Mbps / 70位 = 14,285帧/秒 ``` ##### 2.1.4 扩展帧协议 (29位ID) **扩展帧ID结构**: ``` 31 24 23 16 15 8 7 0 ┌─────────┬─────────┬─────────┬─────────┐ │ 设备ID │ 数据2 │ 数据1 │ 命令ID │ │ (8位) │ (8位) │ (8位) │ (8位) │ └─────────┴─────────┴─────────┴─────────┘ ``` - **设备ID**: 0x00 ~ 0xFF (设备类型识别) - **命令ID**: 0x00 ~ 0xFF (具体命令) - **数据1/2**: 命令参数或附加信息 #### 2.2 核心数据结构 **CAN接收缓冲区结构体**: ```c struct Struct_CAN_Rx_Buffer { CAN_RxHeaderTypeDef Header; // CAN帧头信息 uint8_t Data[8]; // 8字节数据缓冲区 }; ``` **CAN管理对象结构体**: ```c struct Struct_CAN_Manage_Object { CAN_HandleTypeDef *CAN_Handler; // CAN句柄指针 Struct_CAN_Rx_Buffer Rx_Buffer; // 接收缓冲区 CAN_Call_Back Callback_Function; // 回调函数指针 }; ``` #### 2.3 过滤器配置机制 过滤器采用掩码模式,支持标准帧(11位ID)和扩展帧(29位ID): ```c void can_filter_mask_config(CAN_HandleTypeDef *hcan, uint8_t Object_Para, uint32_t ID, uint32_t Mask_ID) ``` **Object_Para参数位定义**: - 位[7:3]: 滤波器编号(0-27) - 位[2]: FIFO选择(0=FIFO0, 1=FIFO1) - 位[1]: ID类型(0=标准帧, 1=扩展帧) - 位[0]: 帧类型(0=数据帧, 1=遥控帧) #### 2.4 通信流程 1. **初始化阶段**: - 配置CAN硬件参数 - 设置过滤器掩码 - 启动CAN外设 - 激活接收中断 2. **数据发送**: ```c uint8_t CAN_Send_Data(CAN_HandleTypeDef *hcan, uint16_t ID, uint8_t *Data, uint16_t Length) ``` 3. **数据接收**: - 通过中断回调函数接收数据 - FIFO0/FIFO1分别对应不同的中断处理 - 调用用户定义的回调函数处理接收数据 #### 2.5 扩展帧支持 支持29位扩展帧的构造和发送: ```c // 构造扩展帧ID uint32_t EXT_ID_Set(uint8_t equipment_id, uint16_t data2, uint8_t cmd_id); // 发送扩展帧数据 uint8_t CAN_Send_EXT_Data(CAN_HandleTypeDef *hcan, uint32_t ID, uint8_t *Data, uint16_t Length) ``` #### 2.6 多总线支持 项目支持多路CAN总线: - CAN1: 主要用于M3508电机控制 - CAN2: 备用总线或其他设备通信 每路总线都有独立的发送缓冲区和接收处理机制。 #### 2.7 定时发送机制 提供1ms定时器回调函数,用于周期性发送控制指令: ```c void TIM_1ms_CAN_PeriodElapsedCallback() ``` 可在此函数中实现多路电机的同步控制发送。 ## 三、代码不足之处与改进建议 ### 3.1 CAN通信问题 #### 3.1.1 缺乏错误处理机制 - **问题**: `tsk_config_and_callback.cpp:12-30` 中的CAN回调函数缺乏错误处理 - **改进建议**: - 添加CAN错误状态检测和处理 - 实现通信超时检测和重发机制 - 添加通信质量监控,如丢包率统计 #### 3.1.2 硬编码的通信周期 - **问题**: `tsk_config_and_callback.cpp:44-48` 中通信周期硬编码为10ms,缺乏灵活性 - **改进建议**: - 将通信周期参数化,支持动态调整 - 考虑实现自适应通信频率,根据控制需求调整 - 添加通信负载监控,避免总线过载 #### 3.1.3 数据解析不完整 - **问题**: `tsk_config_and_callback.cpp:16-29` 中只处理了0x201报文,其他报文处理为空 - **改进建议**: - 完善所有电机ID的报文处理 - 添加报文有效性检查 - 实现数据校验机制,确保数据完整性 ### 3.2 电机控制问题 #### 3.2.1 单电机控制限制 - **问题**: 当前代码仅支持单个电机的控制,未实现多电机同步控制 - **改进建议**: - 实现电机数组管理,支持多电机控制 - 添加电机同步机制,确保多电机协调运动 - 考虑实现电机分组控制,支持不同控制策略 #### 3.2.2 控制模式切换不完善 - **问题**: 电流环、速度环、角度环之间的切换逻辑不清晰 - **改进建议**: - 实现清晰的状态机,管理控制模式切换 - 添加模式切换平滑过渡,避免突变 - 考虑实现混合控制模式,同时使用多个控制环 #### 3.2.3 缺乏安全保护机制 - **问题**: `tsk_config_and_callback.cpp:41` 中直接设置电流值,缺乏安全检查 - **改进建议**: - 添加一个Constrain函数 ### 3.3 系统架构问题 #### 3.3.1 实时性不足 - **问题**: 主循环中混合了控制、通信和数据处理,可能影响实时性 - **改进建议**: - 优化任务优先级,确保控制任务的及时执行 - 考虑使用TIM定时器触发关键控制任务 #### 3.3.2 缺乏系统状态管理 - **问题**: 系统缺乏统一的状态管理,难以进行系统级控制 - **改进建议**: - 实现系统状态机,管理初始化、运行、故障等状态 - 添加状态转换条件和处理逻辑 - 考虑实现系统健康监控和自诊断 #### 3.3.3 调试和监控功能不足 - **问题**: 系统缺乏完善的调试和监控接口 - **改进建议**: - 实现参数在线调整接口 - 添加数据记录和分析功能 - 考虑实现远程监控和控制接口 ### 3.4 代码质量问题 #### 3.4.1 注释不足 - **问题**: 部分关键代码缺乏注释,如PID计算逻辑 - **改进建议**: - 添加算法原理和实现思路的注释 - 补充参数取值范围和物理意义的说明 - 添加使用示例和注意事项 #### 3.4.2 错误处理不统一 - **问题**: 错误处理方式不统一,有些地方直接忽略错误 - **改进建议**: - 建立统一的错误处理机制 - 实现错误码定义和处理流程 - 添加错误日志记录功能 ### 3.8 系统安全和保护问题 #### 3.8.1 缺乏过温保护 - **问题**: 系统未实现电机过温保护机制 - **改进建议**: - 添加温度监控和过温保护 - 实现温度阈值报警和自动降功率 - 考虑实现温度预测和预防性保护 #### 3.8.2 缺乏过流保护 - **问题**: `dvc_M3508.cpp:19-23` 中只对电流值进行简单限幅 - **改进建议**: - 实现过流检测和保护机制 - 添加电流变化率监控 - 考虑实现短路保护和快速关断 #### 3.8.3 缺乏系统故障诊断 - **问题**: 系统缺乏故障诊断和恢复机制 - **改进建议**: - 实现系统自检和故障诊断 - 添加故障代码记录和查询 - 考虑实现自动故障恢复和系统重启