更新dji_motor初始化的配置,优化参数传递
This commit is contained in:
parent
55e12955b7
commit
0fb67070b8
|
@ -116,31 +116,31 @@ int main(void)
|
||||||
MX_USART6_UART_Init();
|
MX_USART6_UART_Init();
|
||||||
/* USER CODE BEGIN 2 */
|
/* USER CODE BEGIN 2 */
|
||||||
RC_init(&huart3);
|
RC_init(&huart3);
|
||||||
can_instance_config can_config = {.can_handle = &hcan1,
|
DWT_Init(168);
|
||||||
.tx_id = 1};
|
Motor_Init_Config_s config = {
|
||||||
Motor_Control_Setting_s motor_config = {.angle_feedback_source = MOTOR_FEED,
|
.motor_type = M3508,
|
||||||
|
.can_init_config = {
|
||||||
|
.can_handle = &hcan1,
|
||||||
|
.tx_id = 1},
|
||||||
|
.controller_setting_init_config = {.angle_feedback_source = MOTOR_FEED,
|
||||||
.close_loop_type = SPEED_LOOP | CURRENT_LOOP,
|
.close_loop_type = SPEED_LOOP | CURRENT_LOOP,
|
||||||
.speed_feedback_source = MOTOR_FEED,
|
.speed_feedback_source = MOTOR_FEED,
|
||||||
.reverse_flag = MOTOR_DIRECTION_NORMAL};
|
.reverse_flag = MOTOR_DIRECTION_NORMAL},
|
||||||
Motor_Controller_Init_s controller_init = {.current_PID = {
|
.controller_param_init_config = {.current_PID = {
|
||||||
.Improve = 0,
|
.Improve = 0,
|
||||||
.Kp = 1,
|
.Kp = 1,
|
||||||
.Ki = 0,
|
.Ki = 0,
|
||||||
.Kd = 0,
|
.Kd = 0,
|
||||||
.DeadBand = 0,
|
.DeadBand = 0,
|
||||||
.MaxOut = 4000,
|
.MaxOut = 4000},
|
||||||
},
|
|
||||||
.speed_PID = {
|
.speed_PID = {
|
||||||
.Improve = 0,
|
.Improve = 0,
|
||||||
.Kp = 1,
|
.Kp = 1,
|
||||||
.Ki = 0,
|
.Ki = 0,
|
||||||
.Kd = 0,
|
.Kd = 0,
|
||||||
.DeadBand = 0,
|
.DeadBand = 0,
|
||||||
.MaxOut = 4000,
|
.MaxOut = 4000}}};
|
||||||
}};
|
dji_motor_instance *djimotor = DJIMotorInit(config);
|
||||||
Motor_Type_e type = M3508;
|
|
||||||
DWT_Init(168);
|
|
||||||
dji_motor_instance *djimotor = DJIMotorInit(can_config, motor_config, controller_init, type);
|
|
||||||
/* USER CODE END 2 */
|
/* USER CODE END 2 */
|
||||||
|
|
||||||
/* Call init function for freertos objects (in freertos.c) */
|
/* Call init function for freertos objects (in freertos.c) */
|
||||||
|
|
|
@ -57,7 +57,7 @@ static void CANServiceInit()
|
||||||
|
|
||||||
/* -----------------------two extern callable function -----------------------*/
|
/* -----------------------two extern callable function -----------------------*/
|
||||||
|
|
||||||
void CANRegister(can_instance *ins, can_instance_config config)
|
void CANRegister(can_instance *ins, can_instance_config_s config)
|
||||||
{
|
{
|
||||||
static uint8_t idx;
|
static uint8_t idx;
|
||||||
if (!idx)
|
if (!idx)
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
#define MX_CAN_FILTER_CNT (2 * 14) // temporarily useless
|
#define MX_CAN_FILTER_CNT (2 * 14) // temporarily useless
|
||||||
#define DEVICE_CAN_CNT 2 // CAN1,CAN2
|
#define DEVICE_CAN_CNT 2 // CAN1,CAN2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* can instance typedef, every module registered to CAN should have this variable */
|
/* can instance typedef, every module registered to CAN should have this variable */
|
||||||
typedef struct _
|
typedef struct _
|
||||||
{
|
{
|
||||||
|
@ -24,7 +22,6 @@ typedef struct _
|
||||||
void (*can_module_callback)(struct _ *); // callback needs an instance to tell among registered ones
|
void (*can_module_callback)(struct _ *); // callback needs an instance to tell among registered ones
|
||||||
} can_instance;
|
} can_instance;
|
||||||
|
|
||||||
|
|
||||||
/* this structure is used as initialization*/
|
/* this structure is used as initialization*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -32,12 +29,11 @@ typedef struct
|
||||||
uint32_t tx_id;
|
uint32_t tx_id;
|
||||||
uint32_t rx_id;
|
uint32_t rx_id;
|
||||||
void (*can_module_callback)(can_instance *);
|
void (*can_module_callback)(can_instance *);
|
||||||
} can_instance_config;
|
} can_instance_config_s;
|
||||||
|
|
||||||
/* module callback,which resolve protocol when new mesg arrives*/
|
/* module callback,which resolve protocol when new mesg arrives*/
|
||||||
typedef void (*can_callback)(can_instance *);
|
typedef void (*can_callback)(can_instance *);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief transmit mesg through CAN device
|
* @brief transmit mesg through CAN device
|
||||||
*
|
*
|
||||||
|
@ -45,14 +41,12 @@ typedef void (*can_callback)(can_instance*);
|
||||||
*/
|
*/
|
||||||
void CANTransmit(can_instance *_instance);
|
void CANTransmit(can_instance *_instance);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Register a module to CAN service,remember to call this before using a CAN device
|
* @brief Register a module to CAN service,remember to call this before using a CAN device
|
||||||
*
|
*
|
||||||
* @param config init config
|
* @param config init config
|
||||||
* @return can_instance* can instance owned by module
|
* @return can_instance* can instance owned by module
|
||||||
*/
|
*/
|
||||||
void CANRegister(can_instance* instance, can_instance_config config);
|
void CANRegister(can_instance *instance, can_instance_config_s config);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,7 +1,16 @@
|
||||||
# 湖南大学RoboMaster电控组通信协议
|
# 湖南大学RoboMaster电控组通信协议
|
||||||
|
|
||||||
|
<p align='right'>Seasky LIUWei</p>
|
||||||
|
|
||||||
|
<p align='right'>modified by neozng1@hnu.edu.cn</p>
|
||||||
|
|
||||||
可用于视觉,以及其他自研模块(仅限串口通信)
|
可用于视觉,以及其他自研模块(仅限串口通信)
|
||||||
|
|
||||||
|
> TODO:
|
||||||
|
>
|
||||||
|
> 1. 利用F4自带的硬件CRC模块计算校验码,提高速度
|
||||||
|
> 2. 增加更多的数据类型支持,使得数据类型也为可配置的
|
||||||
|
|
||||||
## 一、串口配置
|
## 一、串口配置
|
||||||
|
|
||||||
通信方式是串口,配置为波特率 115200,8 位数据位,1 位停止位,无硬件流控,无校验位。
|
通信方式是串口,配置为波特率 115200,8 位数据位,1 位停止位,无硬件流控,无校验位。
|
||||||
|
|
|
@ -36,7 +36,7 @@ static void DecodeJoint(can_instance* motor_instance)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
joint_instance* HTMotorInit(can_instance_config config)
|
joint_instance *HTMotorInit(can_instance_config_s config)
|
||||||
{
|
{
|
||||||
static uint8_t idx;
|
static uint8_t idx;
|
||||||
joint_motor_info[idx] = (joint_instance *)malloc(sizeof(joint_instance));
|
joint_motor_info[idx] = (joint_instance *)malloc(sizeof(joint_instance));
|
||||||
|
|
|
@ -32,7 +32,7 @@ typedef enum
|
||||||
CMD_ZERO_POSITION = 0xfe
|
CMD_ZERO_POSITION = 0xfe
|
||||||
} joint_mode;
|
} joint_mode;
|
||||||
|
|
||||||
joint_instance* HTMotorInit(can_instance_config config);
|
joint_instance *HTMotorInit(can_instance_config_s config);
|
||||||
|
|
||||||
void JointControl(joint_instance *_instance, float current);
|
void JointControl(joint_instance *_instance, float current);
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ static void DecodeDriven(can_instance *_instance)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
driven_instance *LKMotroInit(can_instance_config config)
|
driven_instance *LKMotroInit(can_instance_config_s config)
|
||||||
{
|
{
|
||||||
static uint8_t idx;
|
static uint8_t idx;
|
||||||
driven_motor_info[idx] = (driven_instance *)malloc(sizeof(driven_instance));
|
driven_motor_info[idx] = (driven_instance *)malloc(sizeof(driven_instance));
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
|
|
||||||
#define LIMIT_MIN_MAX(x, min, max) (x) = (((x) <= (min)) ? (min) : (((x) >= (max)) ? (max) : (x)))
|
#define LIMIT_MIN_MAX(x, min, max) (x) = (((x) <= (min)) ? (min) : (((x) >= (max)) ? (max) : (x)))
|
||||||
|
|
||||||
|
|
||||||
typedef struct // 9025
|
typedef struct // 9025
|
||||||
{
|
{
|
||||||
uint16_t last_ecd;
|
uint16_t last_ecd;
|
||||||
|
@ -30,7 +29,7 @@ typedef enum
|
||||||
unused = 0,
|
unused = 0,
|
||||||
} driven_mode;
|
} driven_mode;
|
||||||
|
|
||||||
driven_instance* LKMotroInit(can_instance_config config);
|
driven_instance *LKMotroInit(can_instance_config_s config);
|
||||||
|
|
||||||
void DrivenControl(int16_t motor1_current, int16_t motor2_current);
|
void DrivenControl(int16_t motor1_current, int16_t motor2_current);
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ static void IDcrash_Handler(uint8_t conflict_motor_idx, uint8_t temp_motor_idx)
|
||||||
*
|
*
|
||||||
* @param config
|
* @param config
|
||||||
*/
|
*/
|
||||||
static void MotorSenderGrouping(can_instance_config *config)
|
static void MotorSenderGrouping(can_instance_config_s *config)
|
||||||
{
|
{
|
||||||
uint8_t motor_id = config->tx_id - 1; // 下标从零开始,先减一方便赋值
|
uint8_t motor_id = config->tx_id - 1; // 下标从零开始,先减一方便赋值
|
||||||
uint8_t motor_send_num;
|
uint8_t motor_send_num;
|
||||||
|
@ -146,29 +146,26 @@ static void DecodeDJIMotor(can_instance *_instance)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 电机初始化,返回一个电机实例
|
// 电机初始化,返回一个电机实例
|
||||||
dji_motor_instance *DJIMotorInit(can_instance_config can_config,
|
dji_motor_instance *DJIMotorInit(Motor_Init_Config_s config)
|
||||||
Motor_Control_Setting_s motor_setting,
|
|
||||||
Motor_Controller_Init_s controller_init,
|
|
||||||
Motor_Type_e type)
|
|
||||||
{
|
{
|
||||||
dji_motor_info[idx] = (dji_motor_instance *)malloc(sizeof(dji_motor_instance));
|
dji_motor_info[idx] = (dji_motor_instance *)malloc(sizeof(dji_motor_instance));
|
||||||
memset(dji_motor_info[idx], 0, sizeof(dji_motor_instance));
|
memset(dji_motor_info[idx], 0, sizeof(dji_motor_instance));
|
||||||
|
|
||||||
// motor basic setting
|
// motor basic setting
|
||||||
dji_motor_info[idx]->motor_type = type;
|
dji_motor_info[idx]->motor_type = config.motor_type;
|
||||||
dji_motor_info[idx]->motor_settings = motor_setting;
|
dji_motor_info[idx]->motor_settings = config.controller_setting_init_config;
|
||||||
|
|
||||||
// motor controller init
|
// motor controller init
|
||||||
PID_Init(&dji_motor_info[idx]->motor_controller.current_PID, &controller_init.current_PID);
|
PID_Init(&dji_motor_info[idx]->motor_controller.current_PID, &config.controller_param_init_config.current_PID);
|
||||||
PID_Init(&dji_motor_info[idx]->motor_controller.speed_PID, &controller_init.speed_PID);
|
PID_Init(&dji_motor_info[idx]->motor_controller.speed_PID, &config.controller_param_init_config.speed_PID);
|
||||||
PID_Init(&dji_motor_info[idx]->motor_controller.angle_PID, &controller_init.angle_PID);
|
PID_Init(&dji_motor_info[idx]->motor_controller.angle_PID, &config.controller_param_init_config.angle_PID);
|
||||||
dji_motor_info[idx]->motor_controller.other_angle_feedback_ptr = controller_init.other_angle_feedback_ptr;
|
dji_motor_info[idx]->motor_controller.other_angle_feedback_ptr = config.controller_param_init_config.other_angle_feedback_ptr;
|
||||||
dji_motor_info[idx]->motor_controller.other_speed_feedback_ptr = controller_init.other_speed_feedback_ptr;
|
dji_motor_info[idx]->motor_controller.other_speed_feedback_ptr = config.controller_param_init_config.other_speed_feedback_ptr;
|
||||||
// group motors, because 4 motors share the same CAN control message
|
// group motors, because 4 motors share the same CAN control message
|
||||||
MotorSenderGrouping(&can_config);
|
MotorSenderGrouping(&config.can_init_config);
|
||||||
// register motor to CAN bus
|
// register motor to CAN bus
|
||||||
can_config.can_module_callback = DecodeDJIMotor; // set callback
|
config.can_init_config.can_module_callback = DecodeDJIMotor; // set callback
|
||||||
CANRegister(&dji_motor_info[idx]->motor_can_instance, can_config);
|
CANRegister(&dji_motor_info[idx]->motor_can_instance, config.can_init_config);
|
||||||
|
|
||||||
return dji_motor_info[idx++];
|
return dji_motor_info[idx++];
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,22 +76,11 @@ typedef struct
|
||||||
* @attention M3508和M2006的反馈报文都是0x200+id,而GM6020的反馈是0x204+id,请注意前两者和后者的id不要冲突.
|
* @attention M3508和M2006的反馈报文都是0x200+id,而GM6020的反馈是0x204+id,请注意前两者和后者的id不要冲突.
|
||||||
* 如果产生冲突,在初始化电机的时候会进入IDcrash_Handler(),可以通过debug来判断是否出现冲突.
|
* 如果产生冲突,在初始化电机的时候会进入IDcrash_Handler(),可以通过debug来判断是否出现冲突.
|
||||||
*
|
*
|
||||||
* @param config 电机can设置,对于DJI电机仅需要将tx_id设置为电调闪动次数(c620,615,610)或拨码开关的值(GM6020)
|
* @param config 电机初始化结构体,包含了电机控制设置,电机PID参数设置,电机类型以及电机挂载的CAN设置
|
||||||
* 你不需要自己查表计算发送和接收id,我们会帮你处理好!
|
|
||||||
*
|
*
|
||||||
* @param motor_setting 电机的控制设置,包括是否反转,闭环类型和是否使用编码器之外的反馈值
|
* @return dji_motor_instance*
|
||||||
*
|
|
||||||
* @param controller_init 电机控制器的参数设置,包括其他的反馈来源数据指针和三环PID的参数.
|
|
||||||
* 如果不需要其他数据来源或不需要三个环,将不需要指针置为NULL即可
|
|
||||||
*
|
|
||||||
* @param type 电机的类型枚举,包括m2006,m3508和gm6020
|
|
||||||
*
|
|
||||||
* @return dji_motor_instance* 返回一个电机实例指针给应用,方便其对电机的参考值进行设置,即调用DJIMotorSetRef()
|
|
||||||
*/
|
*/
|
||||||
dji_motor_instance *DJIMotorInit(can_instance_config config,
|
dji_motor_instance *DJIMotorInit(Motor_Init_Config_s config);
|
||||||
Motor_Control_Setting_s motor_setting,
|
|
||||||
Motor_Controller_Init_s controller_init,
|
|
||||||
Motor_Type_e type);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 被application层的应用调用,给电机设定参考值.
|
* @brief 被application层的应用调用,给电机设定参考值.
|
||||||
|
|
|
@ -20,9 +20,14 @@ dji_motor模块对DJI智能电机,包括M2006,M3508以及GM6020进行了详
|
||||||
|
|
||||||
初始化电机时,你需要传入的参数包括:
|
初始化电机时,你需要传入的参数包括:
|
||||||
|
|
||||||
- 电机挂载的总线设置:CAN1 or CAN2,以及电机的id
|
- **电机挂载的CAN总线设置**,CAN1 or CAN2,以及电机的id,使用`can_instance_config_s`封装,只需要设置这两个参数:
|
||||||
|
|
||||||
- 电机类型:
|
```c
|
||||||
|
CAN_HandleTypeDef *can_handle;
|
||||||
|
uint32_t tx_id; // tx_id设置为电机id,不需要查说明书计算,直接为电调的闪动次数或拨码开关值,为1-8
|
||||||
|
```
|
||||||
|
|
||||||
|
- **电机类型**,使用`Motor_Type_e`:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
GM6020 = 0
|
GM6020 = 0
|
||||||
|
@ -30,6 +35,8 @@ dji_motor模块对DJI智能电机,包括M2006,M3508以及GM6020进行了详
|
||||||
M2006 = 2
|
M2006 = 2
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- **电机控制设置**
|
||||||
|
|
||||||
- 闭环类型
|
- 闭环类型
|
||||||
|
|
||||||
```c
|
```c
|
||||||
|
@ -55,12 +62,11 @@ dji_motor模块对DJI智能电机,包括M2006,M3508以及GM6020进行了详
|
||||||
MOTOR_FEED = 0
|
MOTOR_FEED = 0
|
||||||
OTHER_FEED = 1
|
OTHER_FEED = 1
|
||||||
---
|
---
|
||||||
float *other_angle_feedback_ptr
|
|
||||||
float *other_speed_feedback_ptr
|
|
||||||
// 电流只能从电机传感器获得所以无法设置其他来源
|
// 电流只能从电机传感器获得所以无法设置其他来源
|
||||||
```
|
```
|
||||||
|
|
||||||
- 每个环的PID参数以及是否使用改进功能
|
- 每个环的PID参数以及是否使用改进功能,以及其他反馈来源指针(如果在上一步启用了其他数据来源)
|
||||||
|
|
||||||
```c
|
```c
|
||||||
typedef struct // config parameter
|
typedef struct // config parameter
|
||||||
|
@ -99,6 +105,53 @@ dji_motor模块对DJI智能电机,包括M2006,M3508以及GM6020进行了详
|
||||||
// 若希望使用多个环节的优化,这样就行:Integral_Limit |Trapezoid_Intergral|...|...
|
// 若希望使用多个环节的优化,这样就行:Integral_Limit |Trapezoid_Intergral|...|...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```c
|
||||||
|
float *other_angle_feedback_ptr
|
||||||
|
float *other_speed_feedback_ptr
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
推荐的初始化参数编写格式如下:
|
||||||
|
|
||||||
|
```c
|
||||||
|
Motor_Init_Config_s config = {
|
||||||
|
.motor_type = M3508, // 要注册的电机为3508电机
|
||||||
|
.can_init_config = {.can_handle = &hcan1, // 挂载在CAN1
|
||||||
|
.tx_id = 1}, // C620每隔一段时间闪动1次,设置为1
|
||||||
|
// 采用电机编码器角度与速度反馈,启用速度环和电流环,不反转
|
||||||
|
.controller_setting_init_config = {.angle_feedback_source = MOTOR_FEED,
|
||||||
|
.close_loop_type = SPEED_LOOP | CURRENT_LOOP,
|
||||||
|
.speed_feedback_source = MOTOR_FEED,
|
||||||
|
.reverse_flag = MOTOR_DIRECTION_NORMAL},
|
||||||
|
// 电流环和速度环PID参数的设置,不采用计算优化则不需要传入Improve参数
|
||||||
|
// 不使用其他数据来源(如IMU),不需要传入反馈数据变量指针
|
||||||
|
.controller_param_init_config = {.current_PID = {.Improve = 0,
|
||||||
|
.Kp = 1,
|
||||||
|
.Ki = 0,
|
||||||
|
.Kd = 0,
|
||||||
|
.DeadBand = 0,
|
||||||
|
.MaxOut = 4000},
|
||||||
|
.speed_PID = {.Improve = 0,
|
||||||
|
.Kp = 1,
|
||||||
|
.Ki = 0,
|
||||||
|
.Kd = 0,
|
||||||
|
.DeadBand = 0,
|
||||||
|
.MaxOut = 4000}}};
|
||||||
|
|
||||||
|
dji_motor_instance *djimotor = DJIMotorInit(config); // 设置好参数后进行初始化并保留返回的指针
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
要控制一个DJI电机,我们提供了2个接口:
|
要控制一个DJI电机,我们提供了2个接口:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
|
@ -113,6 +166,16 @@ void DJIMotorChangeFeed(dji_motor_instance *motor,
|
||||||
|
|
||||||
调用第二个并设定要修改的反馈环节和反馈类型,它会将反馈数据指针切换到你设定好的变量(需要在初始化的时候设置反馈指针)。
|
调用第二个并设定要修改的反馈环节和反馈类型,它会将反馈数据指针切换到你设定好的变量(需要在初始化的时候设置反馈指针)。
|
||||||
|
|
||||||
|
**如果需要获取电机的反馈数据**(如小陀螺模式需要根据麦克纳姆轮逆运动学解算底盘速度),直接通过你拥有的`dji_motor_instance`访问成员变量:
|
||||||
|
|
||||||
|
```c
|
||||||
|
// LeftForwardMotor是一个dji_motor_instance实例
|
||||||
|
float speed=LeftForwardMotor->motor_measure->speed_rpm;
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
***现在,忘记PID的计算和发送、接收以及协议解析,专注于模块之间的逻辑交互吧。***
|
***现在,忘记PID的计算和发送、接收以及协议解析,专注于模块之间的逻辑交互吧。***
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -94,4 +94,13 @@ typedef struct
|
||||||
|
|
||||||
} Motor_Controller_Init_s;
|
} Motor_Controller_Init_s;
|
||||||
|
|
||||||
|
/* 用于初始化CAN电机的结构体,各类电机通用 */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
Motor_Controller_Init_s controller_param_init_config;
|
||||||
|
Motor_Control_Setting_s controller_setting_init_config;
|
||||||
|
Motor_Type_e motor_type;
|
||||||
|
can_instance_config_s can_init_config;
|
||||||
|
} Motor_Init_Config_s;
|
||||||
|
|
||||||
#endif // !MOTOR_DEF_H
|
#endif // !MOTOR_DEF_H
|
||||||
|
|
Loading…
Reference in New Issue