修复电机反馈的bug,通信bug,ps2手柄支持,舵机的修复,cmdbug的修复

This commit is contained in:
chenfu
2023-03-22 16:37:12 +08:00
parent 3cf1831237
commit 58db6e5705
25 changed files with 231 additions and 145 deletions

View File

@@ -113,6 +113,8 @@ typedef struct // config parameter
float CoefB; // ITerm = Err*((A-abs(err)+B)/A) when B<|err|<A+B
float Output_LPF_RC; // RC = 1/omegac
float Derivative_LPF_RC;
} PID_Init_Config_s;
/**

View File

@@ -17,7 +17,7 @@
#include "bsp_temperature.h"
#include "spi.h"
#include "user_lib.h"
#include "general_def.h"
static INS_t INS;
static IMU_Param_t IMU_Param;
static PIDInstance TempCtrl = {0};
@@ -118,11 +118,18 @@ void INS_Task(void)
}
BodyFrameToEarthFrame(INS.MotionAccel_b, INS.MotionAccel_n, INS.q); // 转换回导航系n
// 获取最终数据
//获取最终数据
INS.Accel[X] = INS.Accel[X]*RAD_2_ANGLE;
INS.Accel[Y] = INS.Accel[Y]*RAD_2_ANGLE;
INS.Accel[Z] = INS.Accel[Z]*RAD_2_ANGLE;
INS.Gyro[X] = INS.Gyro[X]*RAD_2_ANGLE;
INS.Gyro[Y] = INS.Gyro[Y]*RAD_2_ANGLE;
INS.Gyro[Z] = INS.Gyro[Z]*RAD_2_ANGLE;
INS.Yaw = QEKF_INS.Yaw;
INS.Pitch = QEKF_INS.Pitch;
INS.Roll = QEKF_INS.Roll;
INS.YawTotalAngle = QEKF_INS.YawTotalAngle;
}
// temperature control

View File

@@ -28,6 +28,7 @@ static void DecodeVision()
{
static uint16_t flag_register;
get_protocol_info(vision_usart_instance->recv_buff, &flag_register, (uint8_t *)&recv_data.pitch);
// TODO: code to resolve flag_register;
}
@@ -58,8 +59,13 @@ void VisionSend(Vision_Send_s *send)
static uint8_t send_buff[VISION_SEND_SIZE];
static uint16_t tx_len;
// TODO: code to set flag_register
flag_register = 0x0001;
// 将数据转化为seasky协议的数据包
get_protocol_send_data(0x02, flag_register, &send->yaw, 3, send_buff, &tx_len);
USARTSend(vision_usart_instance, send_buff, tx_len);
USARTSend(vision_usart_instance, send_buff, tx_len,USART_TRANSFER_IT);
// if(vision_usart_instance->usart_handle->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
// {HAL_UARTEx_ReceiveToIdle_DMA(vision_usart_instance->usart_handle, vision_usart_instance->recv_buff, vision_usart_instance->recv_buff_size);
// __HAL_DMA_DISABLE_IT(vision_usart_instance->usart_handle->hdmarx, DMA_IT_HT);
// }
}

View File

@@ -4,7 +4,7 @@
#include "bsp_usart.h"
#include "seasky_protocol.h"
#define VISION_RECV_SIZE 36u // 当前为固定值,36字节
#define VISION_RECV_SIZE 18u // 当前为固定值,36字节
#define VISION_SEND_SIZE 36u
#pragma pack(1)

View File

@@ -15,6 +15,11 @@
#include "crc16.h"
#include "memory.h"
/*获取CRC8校验码*/
uint8_t Get_CRC8_Check(uint8_t *pchMessage,uint16_t dwLength)
{
return crc_8(pchMessage,dwLength);
}
/*检验CRC8数据段*/
static uint8_t CRC8_Check_Sum(uint8_t *pchMessage, uint16_t dwLength)
{
@@ -25,6 +30,12 @@ static uint8_t CRC8_Check_Sum(uint8_t *pchMessage, uint16_t dwLength)
return (ucExpected == pchMessage[dwLength - 1]);
}
/*获取CRC16校验码*/
uint16_t Get_CRC16_Check(uint8_t *pchMessage,uint32_t dwLength)
{
return crc_16(pchMessage,dwLength);
}
/*检验CRC16数据段*/
static uint16_t CRC16_Check_Sum(uint8_t *pchMessage, uint32_t dwLength)
{
@@ -45,7 +56,7 @@ static uint8_t protocol_heade_Check(protocol_rm_struct *pro, uint8_t *rx_buf)
pro->header.sof = rx_buf[0];
if (CRC8_Check_Sum(&rx_buf[0], 4))
{
pro->header.data_length = (rx_buf[2] << 8) | rx_buf[1];
pro->header.data_length = ((rx_buf[2] << 8) | rx_buf[1]);
pro->header.crc_check = rx_buf[3];
pro->cmd_id = (rx_buf[5] << 8) | rx_buf[4];
return 1;
@@ -114,9 +125,9 @@ uint16_t get_protocol_info(uint8_t *rx_buf, // 接收到的原始数据
if (CRC16_Check_Sum(&rx_buf[0], date_length))
{
*flags_register = (rx_buf[7] << 8) | rx_buf[6];
memcpy(rx_data, rx_buf + 8, 4 * sizeof(pro.header.data_length - 2));
memcpy(rx_data, rx_buf + 8, (pro.header.data_length - 2));
return pro.cmd_id;
}
}
}
return 0;
}

View File

@@ -238,7 +238,8 @@ void DJIMotorControl()
motor_controller = &motor->motor_controller;
motor_measure = &motor->motor_measure;
pid_ref = motor_controller->pid_ref; // 保存设定值,防止motor_controller->pid_ref在计算过程中被修改
if (motor_setting->motor_reverse_flag == MOTOR_DIRECTION_REVERSE)
pid_ref*= -1; // 设置反转
// pid_ref会顺次通过被启用的闭环充当数据的载体
// 计算位置环,只有启用位置环且外层闭环为位置时会计算速度环输出
if ((motor_setting->close_loop_type & ANGLE_LOOP) && motor_setting->outer_loop_type == ANGLE_LOOP)
@@ -270,8 +271,7 @@ void DJIMotorControl()
// 获取最终输出
set = (int16_t)pid_ref;
if (motor_setting->reverse_flag == MOTOR_DIRECTION_REVERSE)
set *= -1; // 设置反转
// 分组填入发送数据
group = motor->sender_group;

View File

@@ -138,7 +138,7 @@ Motor_Init_Config_s config = {
.outer_loop_type = SPEED_LOOP,
.close_loop_type = SPEED_LOOP | CURRENT_LOOP,
.speed_feedback_source = MOTOR_FEED,
.reverse_flag = MOTOR_DIRECTION_NORMAL},
.motor_reverse_flag = MOTOR_DIRECTION_NORMAL},
// 电流环和速度环PID参数的设置,不采用计算优化则不需要传入Improve参数
// 不使用其他数据来源(如IMU),不需要传入反馈数据变量指针
.controller_param_init_config = {.current_PID = {.Improve = 0,
@@ -241,7 +241,7 @@ typedef struct
{
Closeloop_Type_e outer_loop_type;
Closeloop_Type_e close_loop_type;
Reverse_Flag_e reverse_flag;
Motor_Reverse_Flag_e motor_reverse_flag;
Feedback_Source_e angle_feedback_source;
Feedback_Source_e speed_feedback_source;
} Motor_Control_Setting_s;
@@ -268,14 +268,14 @@ typedef struct
> 注意务必分清串级控制多环和外层闭环的区别。前者是为了提高内环的性能使得其能更好地跟随外环参考值而后者描述的是系统真实的控制目标闭环目标。如3508没有电流环仍然可以对速度完成闭环对于高层的应用来说它们本质上不关心电机内部是否还有电流环它们只把外层闭环为速度的电机当作一个**速度伺服执行器****外层闭环**描述的就是真正的闭环目标。
- 为了避开恼人的正负号,提高代码的可维护性,在初始化电机时设定`reverse_flag`使得所有电机都按照你想要的方向旋转,其定义如下:
- 为了避开恼人的正负号,提高代码的可维护性,在初始化电机时设定`motor_reverse_flag`使得所有电机都按照你想要的方向旋转,其定义如下:
```c
typedef enum
{
MOTOR_DIRECTION_NORMAL = 0,
MOTOR_DIRECTION_REVERSE = 1
} Reverse_Flag_e;
} Motor_Reverse_Flag_e;
```
- `speed_feedback_source`以及`angle_feedback_source`是指示电机反馈来源的标志位。一般情况下电机使用自身的编码器作为控制反馈量。但在某些时候如小陀螺模式云台电机会使用IMU的姿态数据作为反馈数据来源。其定义如下
@@ -433,7 +433,7 @@ Motor_Init_Config_s config = {
.outer_loop_type = SPEED_LOOP,
.close_loop_type = SPEED_LOOP | ANGLE_LOOP,
.speed_feedback_source = MOTOR_FEED,
.reverse_flag = MOTOR_DIRECTION_NORMAL
.motor_reverse_flag = MOTOR_DIRECTION_NORMAL
},
.controller_param_init_config = {
.angle_PID = {

View File

@@ -137,7 +137,7 @@ void HTMotorControl()
}
set = pid_ref;
if (setting->reverse_flag == MOTOR_DIRECTION_REVERSE)
if (setting->motor_reverse_flag == MOTOR_DIRECTION_REVERSE)
set *= -1;
LIMIT_MIN_MAX(set, T_MIN, T_MAX); // 限幅,实际上这似乎和pid输出限幅重复了

View File

@@ -110,7 +110,7 @@ void LKMotorControl()
}
set = pid_ref;
if (setting->reverse_flag == MOTOR_DIRECTION_REVERSE)
if (setting->motor_reverse_flag == MOTOR_DIRECTION_REVERSE)
set *= -1;
// 这里随便写的,为了兼容多电机命令.后续应该将tx_id以更好的方式表达电机id,单独使用一个CANInstance,而不是用第一个电机的CANInstance
memcpy(sender_instance->tx_buff + (motor->motor_can_ins->tx_id - 0x280) * 2, &set, sizeof(uint16_t));

View File

@@ -54,8 +54,13 @@ typedef enum
{
MOTOR_DIRECTION_NORMAL = 0,
MOTOR_DIRECTION_REVERSE = 1
} Reverse_Flag_e;
} Motor_Reverse_Flag_e;
/* 反馈量正反标志 */
typedef enum
{
FEEDBACK_DIRECTION_NORMAL = 0,
FEEDBACK_DIRECTION_REVERSE = 1
} Feedback_Reverse_Flag_e;
typedef enum
{
MOTOR_STOP = 0,
@@ -67,7 +72,8 @@ typedef struct
{
Closeloop_Type_e outer_loop_type; // 最外层的闭环,未设置时默认为最高级的闭环
Closeloop_Type_e close_loop_type; // 使用几个闭环(串级)
Reverse_Flag_e reverse_flag; // 是否反转
Motor_Reverse_Flag_e motor_reverse_flag; // 是否反转
Feedback_Reverse_Flag_e feedback_reverse_flag; // 反馈是否反向
Feedback_Source_e angle_feedback_source; // 角度反馈类型
Feedback_Source_e speed_feedback_source; // 速度反馈类型
Feedfoward_Type_e feedforward_flag; // 前馈标志