This commit is contained in:
xxxxm 2026-03-14 12:41:14 +08:00
parent 96da4ad6dc
commit abc8885795
5 changed files with 133 additions and 105 deletions

View File

@ -574,11 +574,6 @@ typedef struct {
osTimerId_t ui_slow_timer_id; osTimerId_t ui_slow_timer_id;
} Referee_t; } Referee_t;
/* Referee_ChassisUI_t 已移至 module/chassis.h */
/* Referee_CapUI_t 已移至 device/supercap.h */
/* Referee_GimbalUI_t 已移至 module/gimbal.h */
/* Referee_ShootUI_t 已移至 module/shoot.h */
typedef struct __packed { typedef struct __packed {
/* UI缓冲数据 */ /* UI缓冲数据 */
UI_Ele_t grapic[REF_UI_MAX_GRAPIC_NUM]; UI_Ele_t grapic[REF_UI_MAX_GRAPIC_NUM];

View File

@ -59,8 +59,8 @@ static void CMD_RC_BuildGimbalCmd(CMD_t *ctx) {
} }
/* 左摇杆控制云台 */ /* 左摇杆控制云台 */
ctx->output.gimbal.cmd.delta_yaw = -ctx->input.rc.joy_left.x * 4.0f; ctx->output.gimbal.cmd.delta_yaw = -ctx->input.rc.joy_right.x * 5.0f;
ctx->output.gimbal.cmd.delta_pit = -ctx->input.rc.joy_left.y * 2.5f; ctx->output.gimbal.cmd.delta_pit = ctx->input.rc.joy_right.y * 5.0f;
} }
#endif /* CMD_ENABLE_SRC_RC && CMD_ENABLE_MODULE_GIMBAL */ #endif /* CMD_ENABLE_SRC_RC && CMD_ENABLE_MODULE_GIMBAL */
@ -68,7 +68,7 @@ static void CMD_RC_BuildGimbalCmd(CMD_t *ctx) {
#if CMD_ENABLE_SRC_RC && CMD_ENABLE_MODULE_SHOOT #if CMD_ENABLE_SRC_RC && CMD_ENABLE_MODULE_SHOOT
static void CMD_RC_BuildShootCmd(CMD_t *ctx) { static void CMD_RC_BuildShootCmd(CMD_t *ctx) {
if (ctx->input.online[CMD_SRC_RC]) { if (ctx->input.online[CMD_SRC_RC]) {
ctx->output.shoot.cmd.mode = SHOOT_MODE_SINGLE; ctx->output.shoot.cmd.mode = SHOOT_MODE_BURST;
} else { } else {
ctx->output.shoot.cmd.mode = SHOOT_MODE_SAFE; ctx->output.shoot.cmd.mode = SHOOT_MODE_SAFE;
} }
@ -393,12 +393,13 @@ static void CMD_PC_BuildBalanceChassisCmd(CMD_t *ctx) {
float vx = 0.0f, wz = 0.0f; float vx = 0.0f, wz = 0.0f;
uint32_t kb = ctx->input.pc.keyboard.bitmap; uint32_t kb = ctx->input.pc.keyboard.bitmap;
if (kb & CMD_KEY_W) vx += sens->move_sens; //案件的命令要放到behavior里
if (kb & CMD_KEY_S) vx -= sens->move_sens; // if (kb & CMD_KEY_W) vx += sens->move_sens;
if (kb & CMD_KEY_A) wz += sens->move_sens; // if (kb & CMD_KEY_S) vx -= sens->move_sens;
if (kb & CMD_KEY_D) wz -= sens->move_sens; // if (kb & CMD_KEY_A) wz += sens->move_sens;
if (kb & CMD_KEY_SHIFT) { vx *= sens->move_fast_mult; wz *= sens->move_fast_mult; } // if (kb & CMD_KEY_D) wz -= sens->move_sens;
if (kb & CMD_KEY_CTRL) { vx *= sens->move_slow_mult; wz *= sens->move_slow_mult; } // if (kb & CMD_KEY_SHIFT) { vx *= sens->move_fast_mult; wz *= sens->move_fast_mult; }
// if (kb & CMD_KEY_CTRL) { vx *= sens->move_slow_mult; wz *= sens->move_slow_mult; }
ctx->output.balance_chassis.cmd.move_vec.vx = vx; ctx->output.balance_chassis.cmd.move_vec.vx = vx;
ctx->output.balance_chassis.cmd.move_vec.wz = wz; ctx->output.balance_chassis.cmd.move_vec.wz = wz;

View File

@ -110,19 +110,19 @@ Config_RobotParam_t robot_config = {
.projectileType=SHOOT_PROJECTILE_17MM, .projectileType=SHOOT_PROJECTILE_17MM,
.fric_num=2, .fric_num=2,
.extra_deceleration_ratio=1.0f, .extra_deceleration_ratio=1.0f,
.num_trig_tooth=5, .num_trig_tooth=8,
.shot_freq=1.0f, .shot_freq=1.0f,
.shot_burst_num=3, .shot_burst_num=3,
.ratio_multilevel = {1.0f}, .ratio_multilevel = {1.0f},
}, },
.jamDetection={ .jamDetection={
.enable=true, .enable=true,
.threshold=310.0f, .threshold=200.0f,
.suspectedTime=0.5f, .suspectedTime=0.5f,
}, },
.heatControl={ .heatControl={
.enable=true, .enable=true,
.nmax=2.0f, // 最大射频 Hz .nmax=18.0f, // 最大射频 Hz
.Hwarn=200.0f, // 热量预警值 .Hwarn=200.0f, // 热量预警值
.Hsatu=100.0f, // 热量饱和值 .Hsatu=100.0f, // 热量饱和值
.Hthres=50.0f, // 热量阈值 .Hthres=50.0f, // 热量阈值
@ -151,10 +151,10 @@ Config_RobotParam_t robot_config = {
} }
}, },
.trig = { .trig = {
.can = BSP_FDCAN_2, .can = BSP_CAN_1,
.id = 0x205, .id = 0x203,
.module = MOTOR_M3508, .module = MOTOR_M2006,
.reverse = false, .reverse = true,
.gear=true, .gear=true,
}, },
}, },
@ -180,12 +180,12 @@ Config_RobotParam_t robot_config = {
.range=-1.0f, .range=-1.0f,
}, },
.trig_2006 = { .trig_2006 = {
.k=2.5f, .k=1.0f,
.p=1.0f, .p=1.0f,
.i=0.1f, .i=0.1f,
.d=0.04f, .d=0.05f,
.i_limit=0.4f, .i_limit=0.8f,
.out_limit=1.0f, .out_limit=0.5f,
.d_cutoff_freq=-1.0f, .d_cutoff_freq=-1.0f,
.range=M_2PI, .range=M_2PI,
}, },
@ -195,7 +195,7 @@ Config_RobotParam_t robot_config = {
.i=0.3f, .i=0.3f,
.d=0.5f, .d=0.5f,
.i_limit=0.2f, .i_limit=0.2f,
.out_limit=1.0f, .out_limit=0.9f,
.d_cutoff_freq=-1.0f, .d_cutoff_freq=-1.0f,
.range=-1.0f, .range=-1.0f,
}, },

View File

@ -46,7 +46,6 @@ void Task(void *argument) {
/* 发射检测参数 */ /* 发射检测参数 */
#define SHOT_DETECT_RPM_DROP_THRESHOLD 100.0f /* 摩擦轮转速下降阈值单位rpm */ #define SHOT_DETECT_RPM_DROP_THRESHOLD 100.0f /* 摩擦轮转速下降阈值单位rpm */
#define SHOT_DETECT_SUSPECTED_TIME 0.0005f /* 发射嫌疑持续时间阈值,单位秒 */ #define SHOT_DETECT_SUSPECTED_TIME 0.0005f /* 发射嫌疑持续时间阈值,单位秒 */
#define FRIC_READY_RPM_RATIO 0.95f /* 摩擦轮准备好的转速比例 */
/* Private macro ------------------------------------------------------------ */ /* Private macro ------------------------------------------------------------ */
/* Private variables -------------------------------------------------------- */ /* Private variables -------------------------------------------------------- */
@ -236,40 +235,6 @@ static float Shoot_CalcAvgFricRpm(Shoot_t *s)
return (fric_num > 0) ? (sum / fric_num) : 0.0f; return (fric_num > 0) ? (sum / fric_num) : 0.0f;
} }
/**
* \brief
*
* \param s
*
* \return
*/
static bool Shoot_DetectShotByRpmDrop(Shoot_t *s)
{
if (s == NULL) {
return false;
}
/* 只在READY和FIRE状态下检测避免停机时误判 */
if (s->running_state != SHOOT_STATE_READY &&
s->running_state != SHOOT_STATE_FIRE) {
return false;
}
/* 计算当前摩擦轮平均转速 */
s->heatcontrol.avgFricRpm = Shoot_CalcAvgFricRpm(s);
/* 计算当前转速与目标转速的差值(掉速量) */
s->heatcontrol.rpmDrop = s->target_variable.fric_rpm - s->heatcontrol.avgFricRpm;
/* 判断是否发生明显掉速 */
if (s->heatcontrol.rpmDrop > SHOT_DETECT_RPM_DROP_THRESHOLD) {
return true;
}
return false;
}
/** /**
* \brief * \brief
* *
@ -353,18 +318,29 @@ static int8_t Shoot_HeatDetectionFSM(Shoot_t *s)
/* 计算当前平均转速 */ /* 计算当前平均转速 */
s->heatcontrol.avgFricRpm = Shoot_CalcAvgFricRpm(s); s->heatcontrol.avgFricRpm = Shoot_CalcAvgFricRpm(s);
/* 检查摩擦轮是否达到目标转速的85%以上 */ /* 检查摩擦轮是否初步达到设定速度 */
if (s->heatcontrol.avgFricRpm >= s->target_variable.fric_rpm * FRIC_READY_RPM_RATIO) { if (s->target_variable.fric_rpm - s->heatcontrol.avgFricRpm < SHOT_DETECT_RPM_DROP_THRESHOLD * 0.8f) {
s->heatcontrol.detectState = SHOOT_HEAT_DETECT_READY; s->heatcontrol.detectState = SHOOT_HEAT_DETECT_READY;
s->heatcontrol.lastAvgFricRpm = s->heatcontrol.avgFricRpm; s->heatcontrol.baselineRpm = s->heatcontrol.avgFricRpm; // 记录初始基准转速
} }
} }
break; break;
case SHOOT_HEAT_DETECT_READY: case SHOOT_HEAT_DETECT_READY:
/* 准备检测状态:监测摩擦轮掉速 */ /* 准备检测状态:监测摩擦轮相对当前的基准发生掉速 */
/* 检测掉速(当前转速低于目标转速超过阈值) */ s->heatcontrol.avgFricRpm = Shoot_CalcAvgFricRpm(s);
if (Shoot_DetectShotByRpmDrop(s)) {
/* 动态更新平稳时的基准转速:若当前转速比基准高,迅速成为新基准;若更低,基准非常缓慢地衰减,以适应正常波动 */
if (s->heatcontrol.avgFricRpm > s->heatcontrol.baselineRpm) {
s->heatcontrol.baselineRpm = s->heatcontrol.avgFricRpm;
} else {
s->heatcontrol.baselineRpm = s->heatcontrol.baselineRpm * 0.999f + s->heatcontrol.avgFricRpm * 0.001f;
}
s->heatcontrol.rpmDrop = s->heatcontrol.baselineRpm - s->heatcontrol.avgFricRpm;
/* 检测掉速(当前转速低于动态基准超过阈值) */
if (s->heatcontrol.rpmDrop > SHOT_DETECT_RPM_DROP_THRESHOLD) {
s->heatcontrol.detectState = SHOOT_HEAT_DETECT_SUSPECTED; s->heatcontrol.detectState = SHOOT_HEAT_DETECT_SUSPECTED;
s->heatcontrol.detectTime = s->timer.now; /* 记录进入嫌疑状态的时间 */ s->heatcontrol.detectTime = s->timer.now; /* 记录进入嫌疑状态的时间 */
} }
@ -377,45 +353,47 @@ static int8_t Shoot_HeatDetectionFSM(Shoot_t *s)
case SHOOT_HEAT_DETECT_SUSPECTED: case SHOOT_HEAT_DETECT_SUSPECTED:
/* 发射嫌疑状态:持续检测掉速 */ /* 发射嫌疑状态:持续检测掉速 */
/* 更新掉速量 */
s->heatcontrol.avgFricRpm = Shoot_CalcAvgFricRpm(s); s->heatcontrol.avgFricRpm = Shoot_CalcAvgFricRpm(s);
s->heatcontrol.rpmDrop = s->target_variable.fric_rpm - s->heatcontrol.avgFricRpm; s->heatcontrol.rpmDrop = s->heatcontrol.baselineRpm - s->heatcontrol.avgFricRpm;
/* 若掉速消失(转速恢复正常),回到准备状态 */ /* 若掉速消失(转速刚掉下又马上弹回基准附近),回到准备状态 (阈值的 60%) */
if (s->heatcontrol.rpmDrop < SHOT_DETECT_RPM_DROP_THRESHOLD) { if (s->heatcontrol.rpmDrop < SHOT_DETECT_RPM_DROP_THRESHOLD * 0.6f) {
s->heatcontrol.detectState = SHOOT_HEAT_DETECT_READY; s->heatcontrol.detectState = SHOOT_HEAT_DETECT_READY;
} }
/* 若嫌疑状态持续超过阈值时间,确认发射 */ /* 若掉速状态持续超过设定的嫌疑时间,确认这是一次发射 */
else if ((s->timer.now - s->heatcontrol.detectTime) >= SHOT_DETECT_SUSPECTED_TIME) { else if ((s->timer.now - s->heatcontrol.detectTime) >= SHOT_DETECT_SUSPECTED_TIME) {
s->heatcontrol.detectState = SHOOT_HEAT_DETECT_CONFIRMED; s->heatcontrol.detectState = SHOOT_HEAT_DETECT_CONFIRMED;
} }
break; break;
case SHOOT_HEAT_DETECT_CONFIRMED: case SHOOT_HEAT_DETECT_CONFIRMED:
/* 确认发射状态:增加热量并返回准备状态 */ if (s->heatcontrol.unverified_shots > 0) {
/* 根据弹丸类型增加估计热量 */ s->heatcontrol.unverified_shots--;
switch (s->param->basic.projectileType) { }
case SHOOT_PROJECTILE_17MM: s->heatcontrol.detectState = SHOOT_HEAT_DETECT_RECOVERING;
s->heatcontrol.Hnow_estimated += 10.0f; s->heatcontrol.valleyRpm = s->heatcontrol.avgFricRpm; /* 记录进入此时的转速为谷底初值 */
break; break;
case SHOOT_PROJECTILE_42MM:
s->heatcontrol.Hnow_estimated += 100.0f; case SHOOT_HEAT_DETECT_RECOVERING:
break;
default: s->heatcontrol.avgFricRpm = Shoot_CalcAvgFricRpm(s);
s->heatcontrol.Hnow_estimated += s->heatcontrol.Hgen;
break; if (s->heatcontrol.avgFricRpm < s->heatcontrol.valleyRpm) {
s->heatcontrol.valleyRpm = s->heatcontrol.avgFricRpm;
} }
/* 限制估计热量不超过最大值 */ if ((s->heatcontrol.avgFricRpm - s->heatcontrol.valleyRpm > 30.0f) ||
if (s->heatcontrol.Hnow_estimated > s->heatcontrol.Hmax) { (s->target_variable.fric_rpm - s->heatcontrol.avgFricRpm < SHOT_DETECT_RPM_DROP_THRESHOLD * 0.8f)) {
s->heatcontrol.Hnow_estimated = s->heatcontrol.Hmax;
s->heatcontrol.detectState = SHOOT_HEAT_DETECT_READY;
s->heatcontrol.baselineRpm = s->heatcontrol.avgFricRpm;
} }
/* 增加发射计数 */ /* 如果摩擦轮停止 */
s->heatcontrol.shots_detected++; if (s->running_state == SHOOT_STATE_IDLE) {
s->heatcontrol.detectState = SHOOT_HEAT_DETECT_IDLE;
/* 返回准备检测状态 */ }
s->heatcontrol.detectState = SHOOT_HEAT_DETECT_READY;
break; break;
default: default:
@ -423,7 +401,7 @@ static int8_t Shoot_HeatDetectionFSM(Shoot_t *s)
break; break;
} }
/* 善后工作:热量冷却(每个周期都执行) */ /* 热量冷却*/
if (s->heatcontrol.Hnow_estimated > 0.0f && s->heatcontrol.Hcd > 0.0f) { if (s->heatcontrol.Hnow_estimated > 0.0f && s->heatcontrol.Hcd > 0.0f) {
s->heatcontrol.Hnow_estimated -= s->heatcontrol.Hcd * s->timer.dt; s->heatcontrol.Hnow_estimated -= s->heatcontrol.Hcd * s->timer.dt;
if (s->heatcontrol.Hnow_estimated < 0.0f) { if (s->heatcontrol.Hnow_estimated < 0.0f) {
@ -431,6 +409,36 @@ static int8_t Shoot_HeatDetectionFSM(Shoot_t *s)
} }
} }
/* 空弹链检测与修正拨盘触发后超过0.4秒内仍未有对应的摩擦轮掉速确认 */
if (s->heatcontrol.unverified_shots > 0 && (s->timer.now - s->var_trig.time_lastShoot) > 0.4f) {
/* 这些弹丸确定未射出(空发) */
float refund_heat = 0.0f;
switch (s->param->basic.projectileType) {
case SHOOT_PROJECTILE_17MM: refund_heat = 10.0f; break;
case SHOOT_PROJECTILE_42MM: refund_heat = 100.0f; break;
default: refund_heat = s->heatcontrol.Hgen; break;
}
refund_heat *= s->heatcontrol.unverified_shots;
s->heatcontrol.Hnow_estimated -= refund_heat;
if (s->heatcontrol.Hnow_estimated < 0.0f) {
s->heatcontrol.Hnow_estimated = 0.0f;
}
if (s->var_trig.num_shooted >= s->heatcontrol.unverified_shots) {
s->var_trig.num_shooted -= s->heatcontrol.unverified_shots;
} else {
s->var_trig.num_shooted = 0;
}
if (s->heatcontrol.shots_detected >= s->heatcontrol.unverified_shots) {
s->heatcontrol.shots_detected -= s->heatcontrol.unverified_shots;
} else {
s->heatcontrol.shots_detected = 0;
}
s->heatcontrol.unverified_shots = 0;
}
/* 数据融合 */ /* 数据融合 */
Shoot_FuseHeatData(s); Shoot_FuseHeatData(s);
@ -500,18 +508,22 @@ static float Shoot_CaluFreqByHeat(Shoot_t *s)
*/ */
int8_t Shoot_CaluTargetAngle(Shoot_t *s, Shoot_CMD_t *cmd) int8_t Shoot_CaluTargetAngle(Shoot_t *s, Shoot_CMD_t *cmd)
{ {
if (s == NULL || s->var_trig.num_toShoot == 0) { if (s == NULL) {
return SHOOT_ERR_NULL; return SHOOT_ERR_NULL;
} }
/* 更新热量控制数据 */ /* 更新热量控制数据 */
Shoot_UpdateHeatControl(s); Shoot_UpdateHeatControl(s);
if (s->var_trig.num_toShoot == 0) {
return SHOOT_OK; /* 即使没有弹丸待发,热量更新照常执行 */
}
/* 根据热量控制计算实际射频 */ /* 根据热量控制计算实际射频 */
float actual_freq = Shoot_CaluFreqByHeat(s); float actual_freq = Shoot_CaluFreqByHeat(s);
float dt = s->timer.now - s->var_trig.time_lastShoot; float dt = s->timer.now - s->var_trig.time_lastShoot;
float dpos; float dpos;
dpos = CircleError(s->target_variable.trig_angle, s->var_trig.trig_agl, M_2PI); dpos = CircleError(s->target_variable.trig_angle, s->var_trig.trig_agl, M_2PI);
/* 使用热量控制计算出的射频,而不是配置的固定射频 */ /* 使用热量控制计算出的射频,而不是配置的固定射频 */
@ -519,7 +531,24 @@ int8_t Shoot_CaluTargetAngle(Shoot_t *s, Shoot_CMD_t *cmd)
{ {
s->var_trig.time_lastShoot=s->timer.now; s->var_trig.time_lastShoot=s->timer.now;
CircleAdd(&s->target_variable.trig_angle, M_2PI/s->param->basic.num_trig_tooth, M_2PI); CircleAdd(&s->target_variable.trig_angle, M_2PI/s->param->basic.num_trig_tooth, M_2PI);
s->var_trig.num_toShoot--; s->var_trig.num_toShoot--;
s->var_trig.num_shooted++;
/* 预测性发射:拨盘拨动即认为弹丸会射出,立即增加热量与发射计数 */
float add_heat = 0.0f;
switch (s->param->basic.projectileType) {
case SHOOT_PROJECTILE_17MM: add_heat = 10.0f; break;
case SHOOT_PROJECTILE_42MM: add_heat = 100.0f; break;
default: add_heat = s->heatcontrol.Hgen; break;
}
s->heatcontrol.Hnow_estimated += add_heat;
if (s->heatcontrol.Hnow_estimated > s->heatcontrol.Hmax) {
s->heatcontrol.Hnow_estimated = s->heatcontrol.Hmax;
}
s->heatcontrol.shots_detected++;
/* 增加等待摩擦轮掉速确认的弹丸数 */
s->heatcontrol.unverified_shots++;
} }
return SHOOT_OK; return SHOOT_OK;
} }
@ -623,16 +652,17 @@ int8_t Shoot_RunningFSM(Shoot_t *s, Shoot_CMD_t *cmd)
return SHOOT_ERR_NULL; // 参数错误 return SHOOT_ERR_NULL; // 参数错误
} }
uint8_t fric_num = s->param->basic.fric_num; uint8_t fric_num = s->param->basic.fric_num;
static float pos;
if(s->mode==SHOOT_MODE_SAFE){ if(s->mode==SHOOT_MODE_SAFE){
for(int i=0;i<fric_num;i++) for(int i=0;i<fric_num;i++)
{ {
MOTOR_RM_Relax(&s->param->motor.fric[i].param); MOTOR_RM_Relax(&s->param->motor.fric[i].param);
} }
MOTOR_RM_Relax(&s->param->motor.trig);\ MOTOR_RM_Relax(&s->param->motor.trig);
pos=s->target_variable.trig_angle=s->var_trig.trig_agl; s->target_variable.trig_angle=s->var_trig.trig_agl;
} }
else{ else{
Shoot_CaluTargetAngle(s, cmd);
switch(s->running_state) switch(s->running_state)
{ {
case SHOOT_STATE_IDLE:/*熄火等待*/ case SHOOT_STATE_IDLE:/*熄火等待*/
@ -645,7 +675,7 @@ int8_t Shoot_RunningFSM(Shoot_t *s, Shoot_CMD_t *cmd)
MOTOR_RM_SetOutput(&s->param->motor.fric[i].param, s->output.lpfout_fric[i]); MOTOR_RM_SetOutput(&s->param->motor.fric[i].param, s->output.lpfout_fric[i]);
} }
s->output.outagl_trig =PID_Calc(&s->pid.trig,pos,s->var_trig.trig_agl,0,s->timer.dt); s->output.outagl_trig =PID_Calc(&s->pid.trig,s->target_variable.trig_angle,s->var_trig.trig_agl,0,s->timer.dt);
s->output.outomg_trig =PID_Calc(&s->pid.trig_omg,s->output.outagl_trig,s->var_trig.trig_rpm,0,s->timer.dt); s->output.outomg_trig =PID_Calc(&s->pid.trig_omg,s->output.outagl_trig,s->var_trig.trig_rpm,0,s->timer.dt);
s->output.outlpf_trig =LowPassFilter2p_Apply(&s->filter.trig.out, s->output.outomg_trig); s->output.outlpf_trig =LowPassFilter2p_Apply(&s->filter.trig.out, s->output.outomg_trig);
MOTOR_RM_SetOutput(&s->param->motor.trig, s->output.outlpf_trig); MOTOR_RM_SetOutput(&s->param->motor.trig, s->output.outlpf_trig);
@ -689,7 +719,7 @@ int8_t Shoot_RunningFSM(Shoot_t *s, Shoot_CMD_t *cmd)
} }
/* 设置拨弹电机输出 */ /* 设置拨弹电机输出 */
s->output.outagl_trig =PID_Calc(&s->pid.trig, s->output.outagl_trig =PID_Calc(&s->pid.trig,
pos, s->target_variable.trig_angle,
s->var_trig.trig_agl, s->var_trig.trig_agl,
0, 0,
s->timer.dt); s->timer.dt);
@ -731,7 +761,6 @@ int8_t Shoot_RunningFSM(Shoot_t *s, Shoot_CMD_t *cmd)
break; break;
case SHOOT_STATE_FIRE:/*射击*/ case SHOOT_STATE_FIRE:/*射击*/
Shoot_CaluTargetAngle(s, cmd);
for(int i=0;i<fric_num;i++) for(int i=0;i<fric_num;i++)
{ {
uint8_t level=s->param->motor.fric[i].level-1; uint8_t level=s->param->motor.fric[i].level-1;
@ -776,7 +805,7 @@ int8_t Shoot_RunningFSM(Shoot_t *s, Shoot_CMD_t *cmd)
if(!cmd->firecmd) if(!cmd->firecmd)
{ {
s->running_state=SHOOT_STATE_READY; s->running_state=SHOOT_STATE_READY;
pos=s->var_trig.trig_agl; s->target_variable.trig_angle=s->var_trig.trig_agl;
s->var_trig.num_toShoot=0; s->var_trig.num_toShoot=0;
} }
break; break;

View File

@ -35,7 +35,8 @@ typedef enum {
SHOOT_HEAT_DETECT_IDLE = 0, /* 停机状态 */ SHOOT_HEAT_DETECT_IDLE = 0, /* 停机状态 */
SHOOT_HEAT_DETECT_READY, /* 准备检测状态 */ SHOOT_HEAT_DETECT_READY, /* 准备检测状态 */
SHOOT_HEAT_DETECT_SUSPECTED, /* 发射嫌疑状态 */ SHOOT_HEAT_DETECT_SUSPECTED, /* 发射嫌疑状态 */
SHOOT_HEAT_DETECT_CONFIRMED /* 确认发射状态 */ SHOOT_HEAT_DETECT_CONFIRMED, /* 确认发射状态 */
SHOOT_HEAT_DETECT_RECOVERING /* 发射恢复状态 */
}Shoot_HeatDetectionFSM_State_t; }Shoot_HeatDetectionFSM_State_t;
typedef enum { typedef enum {
SHOOT_STATE_IDLE = 0,/* 熄火 */ SHOOT_STATE_IDLE = 0,/* 熄火 */
@ -114,7 +115,8 @@ typedef struct {
Shoot_HeatDetectionFSM_State_t detectState; // 检测状态 Shoot_HeatDetectionFSM_State_t detectState; // 检测状态
float detectTime; // 检测计时器 float detectTime; // 检测计时器
float avgFricRpm; // 摩擦轮平均转速 float avgFricRpm; // 摩擦轮平均转速
float lastAvgFricRpm; // 上次摩擦轮平均转速 float baselineRpm; // 动态基准转速,用于连发掉速检测的参照
float valleyRpm; // 掉速谷底转速,用于判断掉速回升
float rpmDrop; // 转速下降量 float rpmDrop; // 转速下降量
bool shotDetected; // 检测到发射标志 bool shotDetected; // 检测到发射标志
@ -123,6 +125,7 @@ typedef struct {
float Hnow_fused; // 融合后的热量值 float Hnow_fused; // 融合后的热量值
uint16_t shots_detected; // 检测到的发射数 uint16_t shots_detected; // 检测到的发射数
uint16_t shots_available;// 当前热量可发射弹数 uint16_t shots_available;// 当前热量可发射弹数
uint16_t unverified_shots; // 已经拨弹但等待摩擦轮掉速确认的弹丸数
}Shoot_HeatControl_t; }Shoot_HeatControl_t;
typedef struct { typedef struct {