Files
Simba-OmniInfantry/云台/Application/Task/Inc/shoot_detect_task.h
T

160 lines
5.7 KiB
C

/* =============================================================================
* shoot_detect_task.h - 摩擦轮电流/电压波动发射检测
*
* 检测原理:
* 当弹丸被挤压通过两高速旋转的摩擦轮(M3508)瞬间, 机械负荷剧增,
* 导致左右摩擦轮电机的转矩电流/控制输出在 5~15ms 内产生极其显著的脉冲尖峰。
* 算法利用自适应基线(一阶低通滤波)估计空载电流, 实时计算瞬时突变量:
* ΔI = |I_current| - I_baseline
* 当 ΔI 超过突变阈值, 且摩擦轮处于正常高转速状态时, 触发单发判定。
* 引入防抖不应期(Cooldown), 杜绝单发弹丸通过过程中的重复计数。
* ========================================================================== */
#ifndef SHOOT_DETECT_TASK_H
#define SHOOT_DETECT_TASK_H
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/* ============================ 默认参数配置 ============================ */
/* 电流突变触发阈值(A):
* M3508 空载稳态电流通常在 0.5A~1.5A 左右, 弹丸挤压通过时瞬时电流常达 3.5A~7A+。
* 建议突变量阈值设为 1.8A ~ 2.5A, 既能灵敏捕捉发弹, 又能避开空载抖动。 */
#ifndef SHOOT_DETECT_CURRENT_THRESHOLD_A
#define SHOOT_DETECT_CURRENT_THRESHOLD_A 2.0f
#endif
/* 摩擦轮启动加速稳定等待时间(ms):
* 开启摩擦轮后等待电机从 0 加速到 5500 RPM 并平稳进入空载稳态的时间,
* 期间处于 SPINUP 状态, 屏蔽加速满幅电流, 严防误触发 */
#ifndef SHOOT_DETECT_SPINUP_TIMEOUT_MS
#define SHOOT_DETECT_SPINUP_TIMEOUT_MS 500
#endif
/* 摩擦轮有效工作最低转速(RPM): 默认 4500 RPM(接近 5500 稳态转速) */
#ifndef SHOOT_DETECT_SPEED_MIN_RPM
#define SHOOT_DETECT_SPEED_MIN_RPM 4500.0f
#endif
/* 发射防抖不应期(ms):
* 单发弹丸通过摩擦轮通常持续 5~15ms, 设为 35ms 可确保同一发只计一次,
* 同时支持最高 25发/秒 的高射频(周期 40ms) */
#ifndef SHOOT_DETECT_COOLDOWN_MS
#define SHOOT_DETECT_COOLDOWN_MS 35
#endif
/* 空载基线平滑系数(0.0 ~ 1.0): 用于自适应跟踪温度和磨损带来的稳态电流漂移 */
#ifndef SHOOT_DETECT_BASELINE_ALPHA
#define SHOOT_DETECT_BASELINE_ALPHA 0.05f
#endif
/* ============================ 状态枚举 ============================ */
typedef enum
{
SHOOT_DETECT_STATE_STOPPED = 0, // 摩擦轮未启动: 检测器休眠/禁用, 不进行任何检测
SHOOT_DETECT_STATE_SPINUP, // 摩擦轮起转加速中: 等待转速达到工作点并稳定
SHOOT_DETECT_STATE_ACTIVE, // 摩擦轮已启动且稳态运行: 发射检测正式就绪激活
} shoot_detect_state_e;
/* ============================ 数据结构 ============================ */
typedef struct
{
/* 运行状态 */
shoot_detect_state_e state; // 当前状态(STOPPED / SPINUP / ACTIVE)
uint8_t is_ready; // 摩擦轮是否已完全启动并就绪(1=ACTIVE)
uint32_t spinup_start_tick; // 摩擦轮启动时刻(HAL_GetTick)
/* 发射统计 */
uint32_t shoot_count; // 累计发射弹丸总数
volatile uint8_t fired_pulse; // 单发脉冲标志(读取后自动清除或通过 API 清除)
float shoot_freq_hz; // 瞬时估算射频(Hz)
uint32_t last_shoot_tick; // 上次发射时间戳(HAL_GetTick)
/* 瞬时信号与基线(A) */
float current_l; // 左摩擦轮当前绝对电流
float current_r; // 右摩擦轮当前绝对电流
float baseline_l; // 左摩擦轮空载基线电流
float baseline_r; // 右摩擦轮空载基线电流
float delta_l; // 左摩擦轮电流突变量
float delta_r; // 右摩擦轮电流突变量
float delta_max; // 左右轮最大突变量
/* 配置阈值 */
float threshold_a; // 触发阈值(A)
uint32_t cooldown_ms; // 防抖不应期(ms)
float speed_min_rpm; // 最低有效转速(RPM)
uint32_t spinup_timeout_ms; // 起转稳定时间(ms)
} shoot_detect_t;
/* ============================ 接口函数 ============================ */
/**
* @brief 初始化发射检测模块
*/
void shoot_detect_init(void);
/**
* @brief 发射检测核心周期更新函数(推荐在 2ms shoot_task 中调用)
*/
void shoot_detect_update(void);
/**
* @brief 查询摩擦轮是否已启动并处于就绪检测状态
* @retval 1: 摩擦轮已启动且稳态运行, 检测器就绪
* 0: 摩擦轮未启动或正在加速启动中
*/
uint8_t shoot_detect_is_ready(void);
/**
* @brief 获取当前检测器状态(STOPPED/SPINUP/ACTIVE)
*/
shoot_detect_state_e shoot_detect_get_state(void);
/**
* @brief 查询是否有新的一发弹丸发射(单发脉冲)
* @retval 1: 检测到新发射(读取后内部自动清除标志)
* 0: 无新发射
*/
uint8_t shoot_detect_has_fired(void);
/**
* @brief 获取累计发射总发数
* @retval 累计发射数量
*/
uint32_t shoot_detect_get_count(void);
/**
* @brief 清零发射总发数计数器
*/
void shoot_detect_clear_count(void);
/**
* @brief 获取当前瞬时射频(Hz)
* @retval 射频
*/
float shoot_detect_get_freq(void);
/**
* @brief 获取完整检测器状态结构体指针(供调试和上位机打印)
*/
const shoot_detect_t * shoot_detect_get_data(void);
/**
* @brief 动态设置检测电流阈值(A)
*/
void shoot_detect_set_threshold(float threshold_a);
/**
* @brief 可选独立 FreeRTOS 任务实现(若用户希望作为单独任务运行)
*/
void shoot_detect_task(void const * argument);
#ifdef __cplusplus
}
#endif
#endif /* SHOOT_DETECT_TASK_H */