#include "up.h" #include "gpio.h" #include "user_math.h" #include "bsp_buzzer.h" #include "bsp_delay.h" #define GEAR_RATIO (36) // 2006减速比 #define CAN_MOTOR_ENC_RES 8191 // 编码器分辨率 #define MOTOR2006_ECD_TO_ANGLE (360.0 / 8191.0 / (GEAR_RATIO)) //2006编码值转轴角度 int8_t up_init(UP_t *u,const UP_Param_t *param,float target_freq) { u->param = param; /*初始化参数 */ PID_init (&u->pid.VESC_5065_M1 ,PID_POSITION ,&(u->param ->VESC_5065_M1_param )); PID_init (&u->pid.VESC_5065_M2 ,PID_POSITION ,&(u->param ->VESC_5065_M2_param )); PID_init (&u->pid .M2006_angle ,PID_POSITION ,&(u->param->M2006_angle_param )); PID_init (&u->pid .M2006_speed ,PID_POSITION ,&(u->param->M2006_speed_param )); PID_init (&u->pid .GM6020_speed,PID_POSITION ,&(u->param ->UP_GM6020_speed_param )); PID_init (&u->pid .GM6020_angle,PID_POSITION ,&(u->param ->UP_GM6020_angle_param )); for(int i=0;i<3;i++){ PID_init (&u->pid .M3508_speed[i] ,PID_POSITION ,&(u->param ->M3508_speed_param )); } } int8_t UP_UpdateFeedback(UP_t *u, const CAN_t *can) { u->motorfeedback .M2006_angle=can ->motor .motor3508 .as_array [0].rotor_ecd ; u->motorfeedback .M2006_rpm =can ->motor .motor3508 . as_array [0].rotor_speed ; u->motorfeedback .VESC_5065_M1_rpm =can ->motor .chassis5065 .as_array [0].rotor_speed ; u->motorfeedback .VESC_5065_M2_rpm =can ->motor .chassis5065 .as_array [1].rotor_speed ; u->motorfeedback .rotor_pit6020ecd =can ->motor .chassis6020.as_array [2].rotor_ecd ; u->motorfeedback .rotor_pit6020rpm =can ->motor .chassis6020.as_array [2].rotor_speed ; for(int i=0;i<3;i++){ u->motorfeedback .M3508_speed[i] =can ->motor .motor3508 .as_array [i+1].rotor_speed ; } } int8_t cnt=0; /*上层电机控制*/ int8_t UP_M2006_angle(UP_t *u, fp32 target_angle) { // 获取当前编码器角度 float angle = u->motorfeedback.M2006_angle; // 初始化阶段:前50次循环记录初始值 if (u->M2006.init_cnt < 50) { u->M2006.orig_angle = angle; // 记录初始编码器值 u->M2006.last_angle = angle; // 初始化上一次角度 u->M2006.init_cnt++; // 初始化计数器递增 return 0; // 初始化阶段不执行控制 } // 计算角度差值(处理编码器溢出) float delta = angle - u->M2006.last_angle; if (delta > 4096) { u->M2006.round_cnt--; // 逆时针跨圈 } else if (delta < -4096) { u->M2006.round_cnt++; // 顺时针跨圈 } u->M2006.last_angle = angle; // 计算总角度(基于初始偏移和圈数) float total_angle = (u->M2006.round_cnt * 8191 + (angle - u->M2006.orig_angle)) * MOTOR2006_ECD_TO_ANGLE; u->M2006 .total_angle =total_angle; // PID控制计算 float delta_angle = PID_calc(&u->pid.M2006_angle, total_angle, target_angle); float delta_speed = PID_calc(&u->pid.M2006_speed, u->motorfeedback.M2006_rpm, delta_angle); u->motor_target.M2006_angle = target_angle; u->final_out .final_2006out =delta_speed; return 0; } int8_t UP_M3508_speed(UP_t *u,fp32 speed) { u->motor_target .M3508_speed =speed; for(int i=0;i<3;i++){ u->final_out .final_3508out [i] = PID_calc (&(u->pid .M3508_speed[i] ),u->motorfeedback .M3508_speed [i],speed ); } } int8_t VESC_M5065_Control(UP_t *u,fp32 speed) { u->motor_target .VESC_5065_M1_rpm =speed; u->motor_target .VESC_5065_M2_rpm =speed; u->final_out .final_VESC_5065_M1out =u->motor_target .VESC_5065_M1_rpm; u->final_out .final_VESC_5065_M2out =u->motor_target .VESC_5065_M2_rpm; } int8_t GM6020_control(UP_t *u,fp32 angle) { fp32 delat_speed; Clip(&angle,90,270); delat_speed = PID_calc (&(u->pid .GM6020_angle ),u->motorfeedback .rotor_pit6020ecd ,(angle /360*8191)); u->final_out .final_pitchout = PID_calc (&(u->pid .GM6020_speed ),u->motorfeedback.rotor_pit6020rpm ,delat_speed); u->motor_target .rotor_pit6020angle =angle ; } int8_t ALL_Motor_Control(UP_t *u,CAN_Output_t *out) { //电机控制 ,传进can out ->motor3508 .as_array [0]=u->final_out .final_2006out ; for(int i=1;i<4;i++){ out ->motor3508 .as_array[i]=u->final_out.final_3508out [i-1] ; } out ->chassis5065 .erpm [0]=u->final_out .final_VESC_5065_M1out ; out ->chassis5065 .erpm [1]=u->final_out .final_VESC_5065_M2out ; out ->chassis6020 .as_array [2]=u->final_out .final_pitchout ; } int8_t UP_control(UP_t *u,CAN_Output_t *out) { // if(u ==NULL) return 0; // if(u ==NULL) return 0; // UP_M2006_angle(u,2500); switch (u->ctrl) { case STATE_IDLE : break ; case STATE_PRE_DRIBBLE : break ; case STATE_POST_DRIBBLE : break ; case STATE_PRE_LAUNCH : break ; case STATE_POST_LAUNCH : break ; } }