发布beta版本,目前基本功能都可用

This commit is contained in:
NeoZng
2022-12-11 14:59:45 +08:00
parent 37c23ddb79
commit 78cc27ee1a
19 changed files with 320 additions and 115 deletions

View File

@@ -85,6 +85,12 @@ float PID_Calculate(PIDInstance *pid, float measure, float ref)
// 输出限幅
f_Output_Limit(pid);
}
else // 进入死区,清空积分和输出
{
pid->Output=0;
pid->ITerm=0;
}
pid->Last_Measure = pid->Measure;
pid->Last_Output = pid->Output;
pid->Last_Dout = pid->Dout;

View File

@@ -30,7 +30,7 @@ static void DecodeJoint(CANInstance *motor_instance)
tmp = (motor_instance->rx_buff[3] << 4) | (motor_instance->rx_buff[4] >> 4);
joint_motor_info[i]->speed_rpm = uint_to_float(tmp, V_MAX, V_MIN, 12);
tmp = ((motor_instance->rx_buff[4] & 0xf) << 8) | motor_instance->rx_buff[5];
joint_motor_info[i]->given_current = uint_to_float(tmp, T_MAX, T_MIN, 12);
joint_motor_info[i]->real_current = uint_to_float(tmp, T_MAX, T_MIN, 12);
break;
}
}

View File

@@ -20,7 +20,7 @@ typedef struct // HT04
float last_ecd;
float ecd;
float speed_rpm;
float given_current;
float real_current;
PIDInstance pid;
CANInstance *motor_can_instace;

View File

@@ -11,7 +11,7 @@ static void DecodeDriven(CANInstance *_instance)
driven_motor_info[i]->last_ecd = driven_motor_info[i]->ecd;
driven_motor_info[i]->ecd = (uint16_t)((_instance->rx_buff[7] << 8) | _instance->rx_buff[6]);
driven_motor_info[i]->speed_rpm = (uint16_t)(_instance->rx_buff[5] << 8 | _instance->rx_buff[4]);
driven_motor_info[i]->given_current = (uint16_t)(_instance->rx_buff[3] << 8 | _instance->rx_buff[2]);
driven_motor_info[i]->real_current = (uint16_t)(_instance->rx_buff[3] << 8 | _instance->rx_buff[2]);
driven_motor_info[i]->temperate = _instance->rx_buff[1];
break;
}

View File

@@ -15,7 +15,7 @@ typedef struct // 9025
uint16_t last_ecd;
uint16_t ecd;
int16_t speed_rpm;
int16_t given_current;
int16_t real_current;
uint8_t temperate;
PIDInstance *pid;

View File

@@ -130,15 +130,15 @@ static void DecodeDJIMotor(CANInstance *_instance)
{
rxbuff = _instance->rx_buff;
measure = &dji_motor_info[i]->motor_measure; // measure要多次使用,保存指针减小访存开销
uint8_t nice;
// resolve data and apply filter to current and speed
measure->last_ecd = measure->ecd;
measure->ecd = (uint16_t)(rxbuff[0] << 8 | rxbuff[1]);
measure->angle_single_round = ECD_ANGLE_COEF * measure->ecd;
measure->speed_angle_per_sec = (1 - SPEED_SMOOTH_COEF) * measure->speed_angle_per_sec +
RPM_2_ANGLE_PER_SEC * SPEED_SMOOTH_COEF * (int16_t)(rxbuff[2] << 8 | rxbuff[3]);
measure->given_current = (1 - CURRENT_SMOOTH_COEF) * measure->given_current +
RPM_2_ANGLE_PER_SEC * CURRENT_SMOOTH_COEF * (uint16_t)(rxbuff[4] << 8 | rxbuff[5]);
measure->ecd = ((uint16_t)rxbuff[0]) << 8 | rxbuff[1];
measure->angle_single_round = ECD_ANGLE_COEF * (float)measure->ecd;
measure->speed_aps = (1.0f - SPEED_SMOOTH_COEF) * measure->speed_aps + RPM_2_ANGLE_PER_SEC *
SPEED_SMOOTH_COEF *(float)((int16_t)(rxbuff[2] << 8 | rxbuff[3])) ;
measure->real_current = (1.0f - CURRENT_SMOOTH_COEF) * measure->real_current +
CURRENT_SMOOTH_COEF * (float)((int16_t)(rxbuff[4] << 8 | rxbuff[5]));
measure->temperate = rxbuff[6];
// multi rounds calc,计算的前提是两次采样间电机转过的角度小于180°
@@ -176,6 +176,7 @@ DJIMotorInstance *DJIMotorInit(Motor_Init_Config_s *config)
config->can_init_config.can_module_callback = DecodeDJIMotor; // set callback
dji_motor_info[idx]->motor_can_instance = CANRegister(&config->can_init_config);
DJIMotorEnable(dji_motor_info[idx]);
return dji_motor_info[idx++];
}
@@ -223,7 +224,7 @@ void DJIMotorControl()
static Motor_Control_Setting_s *motor_setting;
static Motor_Controller_s *motor_controller;
static DJI_Motor_Measure_s *motor_measure;
static float pid_measure,pid_ref;
static float pid_measure, pid_ref;
// 遍历所有电机实例,进行串级PID的计算并设置发送报文的值
for (size_t i = 0; i < idx; i++)
{
@@ -233,7 +234,7 @@ void DJIMotorControl()
motor_setting = &motor->motor_settings;
motor_controller = &motor->motor_controller;
motor_measure = &motor->motor_measure;
pid_ref=motor_controller->pid_ref; //保存设定值,防止motor_controller->pid_ref在计算过程中被修改
pid_ref = motor_controller->pid_ref; // 保存设定值,防止motor_controller->pid_ref在计算过程中被修改
// pid_ref会顺次通过被启用的闭环充当数据的载体
// 计算位置环,只有启用位置环且外层闭环为位置时会计算速度环输出
@@ -253,7 +254,7 @@ void DJIMotorControl()
if (motor_setting->speed_feedback_source == OTHER_FEED)
pid_measure = *motor_controller->other_speed_feedback_ptr;
else // MOTOR_FEED
pid_measure = motor_measure->speed_angle_per_sec;
pid_measure = motor_measure->speed_aps;
// 更新pid_ref进入下一个环
pid_ref = PID_Calculate(&motor_controller->speed_PID, pid_measure, pid_ref);
}
@@ -261,7 +262,7 @@ void DJIMotorControl()
// 计算电流环,只要启用了电流环就计算,不管外层闭环是什么,并且电流只有电机自身传感器的反馈
if (motor_setting->close_loop_type & CURRENT_LOOP)
{
pid_ref = PID_Calculate(&motor_controller->current_PID, motor_measure->given_current, pid_ref);
pid_ref = PID_Calculate(&motor_controller->current_PID, motor_measure->real_current, pid_ref);
}
// 获取最终输出
@@ -272,14 +273,14 @@ void DJIMotorControl()
// 分组填入发送数据
group = motor->sender_group;
num = motor->message_num;
sender_assignment[group].tx_buff[2 * num] = 0xff & set >> 8;
sender_assignment[group].tx_buff[2 * num + 1] = 0xff & set;
sender_assignment[group].tx_buff[2 * num] = (uint8_t)(set >> 8);
sender_assignment[group].tx_buff[2 * num + 1] = (uint8_t)(set & 0x00ff);
// 电机是否停止运行
// if (motor->stop_flag == MOTOR_STOP)
// { // 若该电机处于停止状态,直接将buff置零
// memset(sender_assignment[group].tx_buff + 2 * num, 0, 16u);
// }
if (motor->stop_flag == MOTOR_STOP)
{ // 若该电机处于停止状态,直接将buff置零
memset(sender_assignment[group].tx_buff + 2 * num, 0, 16u);
}
}
}

View File

@@ -29,14 +29,15 @@
/* DJI电机CAN反馈信息*/
typedef struct
{
uint16_t ecd; // 0-8191,刻度总共有8192格
uint16_t last_ecd; // 上一次读取的编码器值
float angle_single_round; // 单圈角度
float speed_angle_per_sec; // 角速度,单位为:度/秒 rounds per minute
int16_t given_current; // 实际电流
uint8_t temperate; // 温度 Celsius
int16_t total_round; // 总圈数,注意方向
int32_t total_angle; // 总角度,注意方向
uint16_t last_ecd; // 上一次读取的编码器值
uint16_t ecd; // 0-8191,刻度总共有8192格
float angle_single_round; // 单圈角度
float speed_aps; // 角速度,单位为:度/秒 rounds per minute
int16_t real_current; // 实际电流
uint8_t temperate; // 温度 Celsius
float total_angle; // 总角度,注意方向
int32_t total_round; // 总圈数,注意方向
} DJI_Motor_Measure_s;
/**

View File

@@ -9,6 +9,22 @@ static RC_ctrl_t rc_ctrl[2]; //[0]:当前数据,[1]:上一次的数据.用于按
// 遥控器拥有的串口实例
static USARTInstance *rc_usart_instance;
/**
* @brief 矫正遥控器摇杆的值
*
*/
static void RectifyRCjoystick()
{
for (uint8_t i = 0; i < 5; i++)
{
if(rc_ctrl[TEMP].rc.joystick[i]>660 || rc_ctrl[TEMP].rc.joystick[i]<-660)
rc_ctrl[TEMP].rc.joystick[i]=0;
}
}
/**
* @brief remote control protocol resolution
* @param[in] sbus_buf: raw data point
@@ -24,6 +40,7 @@ static void sbus_to_rc(volatile const uint8_t *sbus_buf)
rc_ctrl[TEMP].rc.joystick[2] = (((sbus_buf[2] >> 6) | (sbus_buf[3] << 2) | (sbus_buf[4] << 10)) & 0x07ff)- RC_CH_VALUE_OFFSET ; //!< Channel 2
rc_ctrl[TEMP].rc.joystick[3] = (((sbus_buf[4] >> 1) | (sbus_buf[5] << 7)) & 0x07ff)- RC_CH_VALUE_OFFSET ; //!< Channel 3
rc_ctrl[TEMP].rc.joystick[4] = ((sbus_buf[16] | (sbus_buf[17] << 8)) & 0x07FF)- RC_CH_VALUE_OFFSET; // 左侧拨轮
RectifyRCjoystick();
// 开关,0左1右
rc_ctrl[TEMP].rc.s[0] = ((sbus_buf[5] >> 4) & 0x0003); //!< Switch left
rc_ctrl[TEMP].rc.s[1] = ((sbus_buf[5] >> 4) & 0x000C) >> 2; //!< Switch right