fix rotor
This commit is contained in:
parent
5ad9ef8f49
commit
9992ffba2d
@ -77,6 +77,7 @@ static void Chassis_ResetControllers(Chassis_t *c) {
|
|||||||
PID_Reset(&c->pid.leg_length[0]);
|
PID_Reset(&c->pid.leg_length[0]);
|
||||||
PID_Reset(&c->pid.leg_length[1]);
|
PID_Reset(&c->pid.leg_length[1]);
|
||||||
PID_Reset(&c->pid.yaw);
|
PID_Reset(&c->pid.yaw);
|
||||||
|
PID_Reset(&c->pid.rotor);
|
||||||
PID_Reset(&c->pid.roll);
|
PID_Reset(&c->pid.roll);
|
||||||
PID_Reset(&c->pid.roll_force);
|
PID_Reset(&c->pid.roll_force);
|
||||||
PID_Reset(&c->pid.tp[0]);
|
PID_Reset(&c->pid.tp[0]);
|
||||||
@ -143,6 +144,13 @@ static int8_t Chassis_SetMode(Chassis_t *c, Chassis_Mode_t mode) {
|
|||||||
return CHASSIS_OK;
|
return CHASSIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ROTOR -> BALANCE:启动退出过渡(减速→对齐),不立即切换 */
|
||||||
|
if (c->mode == CHASSIS_MODE_BALANCE_ROTOR &&
|
||||||
|
mode == CHASSIS_MODE_WHELL_LEG_BALANCE) {
|
||||||
|
c->rotor_state.exiting = true;
|
||||||
|
return CHASSIS_OK; /* 保持在 ROTOR 模式,由控制循环处理退出 */
|
||||||
|
}
|
||||||
|
|
||||||
Chassis_MotorEnable(c);
|
Chassis_MotorEnable(c);
|
||||||
Chassis_ResetControllers(c);
|
Chassis_ResetControllers(c);
|
||||||
Chassis_SelectYawZeroPoint(c);
|
Chassis_SelectYawZeroPoint(c);
|
||||||
@ -171,6 +179,12 @@ static int8_t Chassis_SetMode(Chassis_t *c, Chassis_Mode_t mode) {
|
|||||||
c->recover.state[1] = (fabsf(theta_r) > (float)M_PI_2) ? RECOVER_FLIP : RECOVER_STRETCH;
|
c->recover.state[1] = (fabsf(theta_r) > (float)M_PI_2) ? RECOVER_FLIP : RECOVER_STRETCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 进入小陀螺时重置旋转状态 */
|
||||||
|
if (mode == CHASSIS_MODE_BALANCE_ROTOR) {
|
||||||
|
c->rotor_state.current_spin_speed = 0.0f;
|
||||||
|
c->rotor_state.exiting = false;
|
||||||
|
}
|
||||||
|
|
||||||
c->mode = mode;
|
c->mode = mode;
|
||||||
return CHASSIS_OK;
|
return CHASSIS_OK;
|
||||||
}
|
}
|
||||||
@ -454,6 +468,7 @@ int8_t Chassis_Init(Chassis_t *c, Chassis_Params_t *param, float target_freq) {
|
|||||||
PID_Init(&c->pid.leg_length[0], KPID_MODE_CALC_D, target_freq, ¶m->leg_length);
|
PID_Init(&c->pid.leg_length[0], KPID_MODE_CALC_D, target_freq, ¶m->leg_length);
|
||||||
PID_Init(&c->pid.leg_length[1], KPID_MODE_CALC_D, target_freq, ¶m->leg_length);
|
PID_Init(&c->pid.leg_length[1], KPID_MODE_CALC_D, target_freq, ¶m->leg_length);
|
||||||
PID_Init(&c->pid.yaw, KPID_MODE_CALC_D, target_freq, ¶m->yaw);
|
PID_Init(&c->pid.yaw, KPID_MODE_CALC_D, target_freq, ¶m->yaw);
|
||||||
|
PID_Init(&c->pid.rotor, KPID_MODE_CALC_D, target_freq, ¶m->rotor);
|
||||||
PID_Init(&c->pid.roll, KPID_MODE_CALC_D, target_freq, ¶m->roll);
|
PID_Init(&c->pid.roll, KPID_MODE_CALC_D, target_freq, ¶m->roll);
|
||||||
PID_Init(&c->pid.roll_force, KPID_MODE_CALC_D, target_freq, ¶m->roll_force);
|
PID_Init(&c->pid.roll_force, KPID_MODE_CALC_D, target_freq, ¶m->roll_force);
|
||||||
PID_Init(&c->pid.tp[0], KPID_MODE_CALC_D, target_freq, ¶m->tp);
|
PID_Init(&c->pid.tp[0], KPID_MODE_CALC_D, target_freq, ¶m->tp);
|
||||||
@ -545,6 +560,10 @@ int8_t Chassis_Init(Chassis_t *c, Chassis_Params_t *param, float target_freq) {
|
|||||||
/* 初始化电机离线检测 */
|
/* 初始化电机离线检测 */
|
||||||
c->motor_status.any_offline = false;
|
c->motor_status.any_offline = false;
|
||||||
|
|
||||||
|
/* 初始化小陀螺状态 */
|
||||||
|
c->rotor_state.current_spin_speed = 0.0f;
|
||||||
|
c->rotor_state.exiting = false;
|
||||||
|
|
||||||
return CHASSIS_OK;
|
return CHASSIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -696,8 +715,6 @@ int8_t Chassis_Control(Chassis_t *c, const Chassis_CMD_t *c_cmd) {
|
|||||||
break;
|
break;
|
||||||
case CHASSIS_MODE_BALANCE_ROTOR:
|
case CHASSIS_MODE_BALANCE_ROTOR:
|
||||||
Chassis_LQRControl(c, c_cmd);
|
Chassis_LQRControl(c, c_cmd);
|
||||||
c->output.wheel[0] += c_cmd->move_vec.vy * 0.2f;
|
|
||||||
c->output.wheel[1] -= c_cmd->move_vec.vy * 0.2f;
|
|
||||||
Chassis_VMCControl(c, c_cmd);
|
Chassis_VMCControl(c, c_cmd);
|
||||||
Chassis_Output(c);
|
Chassis_Output(c);
|
||||||
break;
|
break;
|
||||||
@ -753,21 +770,18 @@ int8_t Chassis_LQRControl(Chassis_t *c, const Chassis_CMD_t *c_cmd) {
|
|||||||
if (c == NULL || c_cmd == NULL) return CHASSIS_ERR_NULL;
|
if (c == NULL || c_cmd == NULL) return CHASSIS_ERR_NULL;
|
||||||
|
|
||||||
/* ==================== 速度控制 ==================== */
|
/* ==================== 速度控制 ==================== */
|
||||||
// float raw_vx = c_cmd->move_vec.vx * 2.0f;
|
if (c_cmd->mode == CHASSIS_MODE_BALANCE_ROTOR) {
|
||||||
// float desired_velocity = c->yaw_control.is_reversed ? -raw_vx : raw_vx;
|
/* 小陀螺平移:将世界坐标系期望速度投影到机体坐标系 */
|
||||||
|
float yaw_angle = c->feedback.imu.euler.yaw;
|
||||||
// /* 加速度限制 */
|
float world_vx = c_cmd->move_vec.vx * c->param->rotor_ctrl.max_trans_speed;
|
||||||
// float velocity_change = desired_velocity - c->chassis_state.last_target_velocity_x;
|
c->chassis_state.target_velocity_x = world_vx * cosf(yaw_angle);
|
||||||
// float max_velocity_change = c->param->motion.max_acceleration * c->dt;
|
c->chassis_state.last_target_velocity_x = c->chassis_state.target_velocity_x;
|
||||||
// velocity_change = LIMIT(velocity_change, -max_velocity_change, max_velocity_change);
|
c->chassis_state.target_x += c->chassis_state.target_velocity_x * c->dt;
|
||||||
|
} else {
|
||||||
// float target_dot_x = c->chassis_state.last_target_velocity_x + velocity_change;
|
c->chassis_state.target_velocity_x = c_cmd->move_vec.vx * 2.0f;
|
||||||
// c->chassis_state.target_velocity_x = target_dot_x;
|
c->chassis_state.last_target_velocity_x = c->chassis_state.target_velocity_x;
|
||||||
// c->chassis_state.last_target_velocity_x = target_dot_x;
|
c->chassis_state.target_x += c->chassis_state.target_velocity_x * c->dt;
|
||||||
// c->chassis_state.target_x += target_dot_x * c->dt;
|
}
|
||||||
c->chassis_state.target_velocity_x = c_cmd->move_vec.vx * 2.0f;
|
|
||||||
c->chassis_state.last_target_velocity_x = c->chassis_state.target_velocity_x;
|
|
||||||
c->chassis_state.target_x += c->chassis_state.target_velocity_x * c->dt;
|
|
||||||
|
|
||||||
|
|
||||||
/* ==================== 状态更新 ==================== */
|
/* ==================== 状态更新 ==================== */
|
||||||
@ -801,7 +815,54 @@ int8_t Chassis_LQRControl(Chassis_t *c, const Chassis_CMD_t *c_cmd) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* ==================== Yaw轴控制 ==================== */
|
/* ==================== Yaw轴控制 ==================== */
|
||||||
if (c_cmd->mode!= CHASSIS_MODE_BALANCE_ROTOR || c_cmd->move_vec.vy == 0.0f) {
|
if (c_cmd->mode == CHASSIS_MODE_BALANCE_ROTOR || c->mode == CHASSIS_MODE_BALANCE_ROTOR) {
|
||||||
|
/* 小陀螺模式:PID跟踪目标角速度,带速度斜坡 */
|
||||||
|
float target_spin = c_cmd->move_vec.vy * c->param->rotor_ctrl.max_spin_speed;
|
||||||
|
|
||||||
|
if (c->rotor_state.exiting) {
|
||||||
|
/* 退出过渡:目标角速度为0,用减速斜坡 */
|
||||||
|
target_spin = 0.0f;
|
||||||
|
float decel_step = c->param->rotor_ctrl.spin_decel * c->dt;
|
||||||
|
if (c->rotor_state.current_spin_speed > decel_step) {
|
||||||
|
c->rotor_state.current_spin_speed -= decel_step;
|
||||||
|
} else if (c->rotor_state.current_spin_speed < -decel_step) {
|
||||||
|
c->rotor_state.current_spin_speed += decel_step;
|
||||||
|
} else {
|
||||||
|
/* 减速完成,检查yaw对齐 */
|
||||||
|
c->rotor_state.current_spin_speed = 0.0f;
|
||||||
|
Chassis_SelectYawZeroPoint(c);
|
||||||
|
float yaw_error = CircleError(c->yaw_control.target_yaw,
|
||||||
|
c->feedback.yaw.rotor_abs_angle, M_2PI);
|
||||||
|
if (fabsf(yaw_error) < c->param->rotor_ctrl.align_threshold) {
|
||||||
|
/* 对齐完成,切换到平衡模式 */
|
||||||
|
c->rotor_state.exiting = false;
|
||||||
|
c->mode = CHASSIS_MODE_WHELL_LEG_BALANCE;
|
||||||
|
Chassis_ResetControllers(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* 正常旋转:平滑加速斜坡 */
|
||||||
|
float accel_step = c->param->rotor_ctrl.spin_accel * c->dt;
|
||||||
|
if (c->rotor_state.current_spin_speed < target_spin - accel_step) {
|
||||||
|
c->rotor_state.current_spin_speed += accel_step;
|
||||||
|
} else if (c->rotor_state.current_spin_speed > target_spin + accel_step) {
|
||||||
|
c->rotor_state.current_spin_speed -= accel_step;
|
||||||
|
} else {
|
||||||
|
c->rotor_state.current_spin_speed = target_spin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 退出过渡减速完成后,用yaw PID对齐零点 */
|
||||||
|
if (c->rotor_state.exiting && c->rotor_state.current_spin_speed == 0.0f) {
|
||||||
|
c->yaw_control.yaw_force = PID_Calc(&c->pid.yaw, c->yaw_control.target_yaw,
|
||||||
|
c->feedback.yaw.rotor_abs_angle, 0.0f, c->dt);
|
||||||
|
} else {
|
||||||
|
float current_yaw_omega = c->feedback.imu.gyro.z;
|
||||||
|
c->yaw_control.yaw_force = PID_Calc(&c->pid.rotor, c->rotor_state.current_spin_speed,
|
||||||
|
current_yaw_omega, 0.0f, c->dt);
|
||||||
|
}
|
||||||
|
c->yaw_control.is_reversed = false;
|
||||||
|
} else {
|
||||||
c->yaw_control.current_yaw = c->feedback.yaw.rotor_abs_angle;
|
c->yaw_control.current_yaw = c->feedback.yaw.rotor_abs_angle;
|
||||||
|
|
||||||
float manual_offset = c_cmd->move_vec.vy * M_PI_2;
|
float manual_offset = c_cmd->move_vec.vy * M_PI_2;
|
||||||
|
|||||||
@ -103,6 +103,7 @@ typedef struct {
|
|||||||
LQR_GainMatrix_t lqr_gains; /* LQR增益矩阵参数 */
|
LQR_GainMatrix_t lqr_gains; /* LQR增益矩阵参数 */
|
||||||
|
|
||||||
KPID_Params_t yaw; /* yaw轴PID控制参数 */
|
KPID_Params_t yaw; /* yaw轴PID控制参数 */
|
||||||
|
KPID_Params_t rotor; /* 小陀螺角速度PID */
|
||||||
KPID_Params_t roll; /* roll轴腿长补偿PID */
|
KPID_Params_t roll; /* roll轴腿长补偿PID */
|
||||||
KPID_Params_t roll_force; /* roll轴力补偿PID */
|
KPID_Params_t roll_force; /* roll轴力补偿PID */
|
||||||
KPID_Params_t tp; /* 摆力矩PID */
|
KPID_Params_t tp; /* 摆力矩PID */
|
||||||
@ -146,6 +147,15 @@ typedef struct {
|
|||||||
float non_contact_theta; /* 离地时摆角目标 (rad) */
|
float non_contact_theta; /* 离地时摆角目标 (rad) */
|
||||||
} motion;
|
} motion;
|
||||||
|
|
||||||
|
/* 小陀螺参数 */
|
||||||
|
struct {
|
||||||
|
float max_spin_speed; /* 最大旋转角速度 (rad/s) */
|
||||||
|
float max_trans_speed; /* 小陀螺时最大平移速度 (m/s) */
|
||||||
|
float spin_accel; /* 旋转加速度 (rad/s²) */
|
||||||
|
float spin_decel; /* 退出减速度 (rad/s²) */
|
||||||
|
float align_threshold; /* 退出对齐阈值 (rad),yaw误差小于此值时回到BALANCE模式 */
|
||||||
|
} rotor_ctrl;
|
||||||
|
|
||||||
/* LQR 目标状态偏移 */
|
/* LQR 目标状态偏移 */
|
||||||
struct {
|
struct {
|
||||||
float theta;
|
float theta;
|
||||||
@ -200,6 +210,12 @@ typedef struct {
|
|||||||
bool is_reversed; /* 是否使用反转的零点(180度零点),影响前后方向 */
|
bool is_reversed; /* 是否使用反转的零点(180度零点),影响前后方向 */
|
||||||
} yaw_control;
|
} yaw_control;
|
||||||
|
|
||||||
|
/* 小陀螺状态 */
|
||||||
|
struct {
|
||||||
|
float current_spin_speed; /* 当前旋转速度 (rad/s),含斜坡 */
|
||||||
|
bool exiting; /* 正在退出小陀螺 */
|
||||||
|
} rotor_state;
|
||||||
|
|
||||||
/* 跳跃控制相关 */
|
/* 跳跃控制相关 */
|
||||||
struct {
|
struct {
|
||||||
Jump_State_t state; /* 跳跃状态 */
|
Jump_State_t state; /* 跳跃状态 */
|
||||||
@ -228,6 +244,7 @@ typedef struct {
|
|||||||
/* 反馈控制用的PID */
|
/* 反馈控制用的PID */
|
||||||
struct {
|
struct {
|
||||||
KPID_t yaw; /* 跟随云台用的PID */
|
KPID_t yaw; /* 跟随云台用的PID */
|
||||||
|
KPID_t rotor; /* 小陀螺角速度PID */
|
||||||
KPID_t roll; /* 横滚角腿长补偿PID */
|
KPID_t roll; /* 横滚角腿长补偿PID */
|
||||||
KPID_t roll_force; /* 横滚角力补偿PID */
|
KPID_t roll_force; /* 横滚角力补偿PID */
|
||||||
KPID_t tp[2];
|
KPID_t tp[2];
|
||||||
|
|||||||
@ -243,6 +243,17 @@ Config_RobotParam_t robot_config = {
|
|||||||
.range=M_2PI, /* 2*PI,用于处理角度循环误差 */
|
.range=M_2PI, /* 2*PI,用于处理角度循环误差 */
|
||||||
},
|
},
|
||||||
|
|
||||||
|
.rotor={
|
||||||
|
.k=1.0f,
|
||||||
|
.p=0.5f,
|
||||||
|
.i=0.0f,
|
||||||
|
.d=0.01f,
|
||||||
|
.i_limit=0.0f,
|
||||||
|
.out_limit=1.0f,
|
||||||
|
.d_cutoff_freq=30.0f,
|
||||||
|
.range=-1.0f, /* 角速度不需要循环误差处理 */
|
||||||
|
},
|
||||||
|
|
||||||
.roll={
|
.roll={
|
||||||
.k=0.15f,
|
.k=0.15f,
|
||||||
.p=0.3f, /* 横滚角腿长补偿比例系数 (降低避免抖动) */
|
.p=0.3f, /* 横滚角腿长补偿比例系数 (降低避免抖动) */
|
||||||
@ -383,6 +394,14 @@ Config_RobotParam_t robot_config = {
|
|||||||
.non_contact_theta = -0.01f, /* 离地摆角目标 (rad) */
|
.non_contact_theta = -0.01f, /* 离地摆角目标 (rad) */
|
||||||
},
|
},
|
||||||
|
|
||||||
|
.rotor_ctrl = {
|
||||||
|
.max_spin_speed = 0.05236f, /* 最大旋转角速度 (rad/s),0.5rpm */
|
||||||
|
.max_trans_speed = 1.5f, /* 小陀螺时最大平移速度 (m/s) */
|
||||||
|
.spin_accel = 5.0f, /* 旋转加速度 (rad/s²) */
|
||||||
|
.spin_decel = 8.0f, /* 退出减速度 (rad/s²),比加速更快 */
|
||||||
|
.align_threshold = 0.15f, /* 退出对齐阈值 (rad),约8.6° */
|
||||||
|
},
|
||||||
|
|
||||||
.vmc_param = {
|
.vmc_param = {
|
||||||
{ // 左腿
|
{ // 左腿
|
||||||
.leg_1 = 0.215f, // 后髋连杆长度 (L1) (m)
|
.leg_1 = 0.215f, // 后髋连杆长度 (L1) (m)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user