R2_UP/User/Module/up.c
2025-03-13 19:07:44 +08:00

152 lines
4.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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; /*初始化参数 */
GO_M8010_init();
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 ;
}
}