132 lines
4.4 KiB
C
132 lines
4.4 KiB
C
/**
|
|
* @file dji_motor.h
|
|
* @author neozng
|
|
* @brief DJI智能电机头文件
|
|
* @version 0.2
|
|
* @date 2022-11-01
|
|
*
|
|
* @todo 1. 给不同的电机设置不同的低通滤波器惯性系数而不是统一使用宏
|
|
2. 为M2006和M3508增加开环的零位校准函数,并在初始化时调用(根据用户配置决定是否调用)
|
|
|
|
* @copyright Copyright (c) 2022 HNU YueLu EC all rights reserved
|
|
*
|
|
*/
|
|
|
|
#ifndef DJI_MOTOR_H
|
|
#define DJI_MOTOR_H
|
|
|
|
#include "bsp_can.h"
|
|
#include "controller.h"
|
|
#include "motor_def.h"
|
|
#include "stdint.h"
|
|
#include "daemon.h"
|
|
|
|
#define DJI_MOTOR_CNT 12
|
|
|
|
/* 滤波系数设置为1的时候即关闭滤波 */
|
|
#define SPEED_SMOOTH_COEF 0.85f // 最好大于0.85
|
|
#define CURRENT_SMOOTH_COEF 0.9f // 必须大于0.9
|
|
#define ECD_ANGLE_COEF_DJI 0.043945f // (360/8192),将编码器值转化为角度制
|
|
|
|
/* DJI电机CAN反馈信息*/
|
|
typedef struct
|
|
{
|
|
uint16_t last_ecd; // 上一次读取的编码器值
|
|
uint16_t ecd; // 0-8191,刻度总共有8192格
|
|
float angle_single_round; // 单圈角度
|
|
float speed_aps; // 角速度,单位为:度/秒
|
|
int16_t real_current; // 实际电流
|
|
uint8_t temperature; // 温度 Celsius
|
|
|
|
float total_angle; // 总角度,注意方向
|
|
int32_t total_round; // 总圈数,注意方向
|
|
} DJI_Motor_Measure_s;
|
|
|
|
/**
|
|
* @brief DJI intelligent motor typedef
|
|
*
|
|
*/
|
|
typedef struct
|
|
{
|
|
DJI_Motor_Measure_s measure; // 电机测量值
|
|
Motor_Control_Setting_s motor_settings; // 电机设置
|
|
Motor_Controller_s motor_controller; // 电机控制器
|
|
|
|
CANInstance *motor_can_instance; // 电机CAN实例
|
|
// 分组发送设置
|
|
uint8_t sender_group;
|
|
uint8_t message_num;
|
|
|
|
Motor_Type_e motor_type; // 电机类型
|
|
Motor_Control_Type_e motor_control_type; //电机控制方式
|
|
Motor_Working_Type_e stop_flag; // 启停标志
|
|
|
|
DaemonInstance* daemon;
|
|
uint32_t feed_cnt;
|
|
float dt;
|
|
} DJIMotorInstance;
|
|
|
|
/**
|
|
* @brief 调用此函数注册一个DJI智能电机,需要传递较多的初始化参数,请在application初始化的时候调用此函数
|
|
* 推荐传参时像标准库一样构造initStructure然后传入此函数.
|
|
* recommend: type xxxinitStructure = {.member1=xx,
|
|
* .member2=xx,
|
|
* ....};
|
|
* 请注意不要在一条总线上挂载过多的电机(超过6个),若一定要这么做,请降低每个电机的反馈频率(设为500Hz),
|
|
* 并减小DJIMotorControl()任务的运行频率.
|
|
*
|
|
* @attention M3508和M2006的反馈报文都是0x200+id,而GM6020的反馈是0x204+id,请注意前两者和后者的id不要冲突.
|
|
* 如果产生冲突,在初始化电机的时候会进入IDcrash_Handler(),可以通过debug来判断是否出现冲突.
|
|
*
|
|
* @param config 电机初始化结构体,包含了电机控制设置,电机PID参数设置,电机类型以及电机挂载的CAN设置
|
|
*
|
|
* @return DJIMotorInstance*
|
|
*/
|
|
DJIMotorInstance *DJIMotorInit(Motor_Init_Config_s *config);
|
|
|
|
/**
|
|
* @brief 被application层的应用调用,给电机设定参考值.
|
|
* 对于应用,可以将电机视为传递函数为1的设备,不需要关心底层的闭环
|
|
*
|
|
* @param motor 要设置的电机
|
|
* @param ref 设定参考值
|
|
*/
|
|
void DJIMotorSetRef(DJIMotorInstance *motor, float ref);
|
|
|
|
/**
|
|
* @brief 切换反馈的目标来源,如将角速度和角度的来源换为IMU(小陀螺模式常用)
|
|
*
|
|
* @param motor 要切换反馈数据来源的电机
|
|
* @param loop 要切换反馈数据来源的控制闭环
|
|
* @param type 目标反馈模式
|
|
*/
|
|
void DJIMotorChangeFeed(DJIMotorInstance *motor, Closeloop_Type_e loop, Feedback_Source_e type);
|
|
|
|
/**
|
|
* @brief 该函数被motor_task调用运行在rtos上,motor_stask内通过osDelay()确定控制频率
|
|
*/
|
|
void DJIMotorControl();
|
|
|
|
/**
|
|
* @brief 停止电机,注意不是将设定值设为零,而是直接给电机发送的电流值置零
|
|
*
|
|
*/
|
|
void DJIMotorStop(DJIMotorInstance *motor);
|
|
|
|
/**
|
|
* @brief 启动电机,此时电机会响应设定值
|
|
* 初始化时不需要此函数,因为stop_flag的默认值为0
|
|
*
|
|
*/
|
|
void DJIMotorEnable(DJIMotorInstance *motor);
|
|
|
|
/**
|
|
* @brief 修改电机闭环目标(外层闭环)
|
|
*
|
|
* @param motor 要修改的电机实例指针
|
|
* @param outer_loop 外层闭环类型
|
|
*/
|
|
void DJIMotorOuterLoop(DJIMotorInstance *motor, Closeloop_Type_e outer_loop);
|
|
|
|
#endif // !DJI_MOTOR_H
|