Files
ASER/App/preproc/corridor_preproc.c
2026-03-31 23:30:33 +08:00

119 lines
4.1 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 "corridor_preproc.h"
/**
* @brief 内部辅助函数:处理单个侧向 VL53L0X 测距
* @return true 表示数据合法且在量程内false 表示异常或超量程飞点
*/
static bool process_side_laser(const SensorItem_t *item, float *out_m)
{
// 驱动层报异常,直接抛弃
if (!item->is_valid) {
return false;
}
// 毫米转米
float dist_m = item->value / 1000.0f;
// 剔除硬件量程外的死区或异常噪点
if (dist_m > PREPROC_MAX_SIDE_RANGE_M || dist_m < PREPROC_MIN_SIDE_RANGE_M) {
return false;
}
*out_m = dist_m;
return true;
}
/**
* @brief 内部辅助函数:处理前后向互补雷达 (STP 远距离 + ATK 近盲区)
* @note 完美解决 STP-23L 的 7cm 物理盲区问题,防止“幽灵撞墙”
*/
static bool process_complementary_laser(const SensorItem_t *stp, const SensorItem_t *atk, float *out_m)
{
bool stp_ok = stp->is_valid && (stp->value > 0.0f);
bool atk_ok = atk->is_valid && (atk->value > 0.0f);
float stp_m = stp->value / 1000.0f;
float atk_m = atk->value / 1000.0f;
/* 1. 近距离补盲优先:如果 ATK 存活,且测距进入 8cm 内 (7cm盲区+1cm裕量) */
/* 此时 STP 的数据大概率是垃圾数据卡死在7cm或报错无条件信任 ATK */
if (atk_ok && atk_m <= PREPROC_BLIND_ZONE_M) {
*out_m = atk_m;
return true;
}
/* 2. 正常中远距离:两者都存活,取保守值防撞 */
if (stp_ok && atk_ok) {
// 如果 STP 读数等于 7cm 极限值,它可能已经瞎了,直接用 ATK 的值
if (stp_m <= 0.07f) {
*out_m = atk_m;
} else {
*out_m = (stp_m < atk_m) ? stp_m : atk_m; // 正常情况取两者中更近的
}
return true;
}
/* 3. 硬件单体降级:只剩下一个雷达活着 */
if (stp_ok) {
// 只有 STP 活着,但读数在盲区内。这数据极其危险(骗人的),宁可报失效触发急停!
if (stp_m <= 0.07f) {
return false;
}
*out_m = stp_m;
return true;
}
if (atk_ok) {
*out_m = atk_m;
return true;
}
/* 全挂了,通知上层失明 */
return false;
}
void CorridorPreproc_ExtractObs(const RobotBlackboard_t *board, uint32_t now_ms, CorridorObs_t *out_obs)
{
// 初始化输出结构体,清空掩码
out_obs->t_ms = now_ms;
out_obs->valid_mask = 0U;
out_obs->d_lf = 0.0f;
out_obs->d_lr = 0.0f;
out_obs->d_rf = 0.0f;
out_obs->d_rr = 0.0f;
out_obs->d_front = 0.0f;
out_obs->d_back = 0.0f;
/* --- 1. 独立清洗侧向 4 个 VL53L0X 数据 --- */
if (process_side_laser(&board->dist_left_f, &out_obs->d_lf)) {
out_obs->valid_mask |= CORRIDOR_OBS_MASK_LF;
}
if (process_side_laser(&board->dist_left_r, &out_obs->d_lr)) {
out_obs->valid_mask |= CORRIDOR_OBS_MASK_LR;
}
if (process_side_laser(&board->dist_right_f, &out_obs->d_rf)) {
out_obs->valid_mask |= CORRIDOR_OBS_MASK_RF;
}
if (process_side_laser(&board->dist_right_r, &out_obs->d_rr)) {
out_obs->valid_mask |= CORRIDOR_OBS_MASK_RR;
}
/* --- 2. 前向雷达:远近互补融合 --- */
if (process_complementary_laser(&board->dist_front_stp, &board->dist_front_atk, &out_obs->d_front)) {
/* 补偿传感器内缩:将"传感器到墙"转换为"车体前端到墙"
* d_body = d_sensor - front_laser_offset
* 当 offset > 0 时表示传感器在车体内部,车体前端比传感器更接近墙 */
out_obs->d_front -= PARAM_FRONT_LASER_OFFSET;
if (out_obs->d_front < 0.0f) out_obs->d_front = 0.0f; /* 安全下限 */
out_obs->valid_mask |= CORRIDOR_OBS_MASK_FRONT;
}
/* --- 3. 后向雷达:远近互补融合 --- */
if (process_complementary_laser(&board->dist_rear_stp, &board->dist_rear_atk, &out_obs->d_back)) {
/* 补偿传感器内缩:同前向逻辑 */
out_obs->d_back -= PARAM_REAR_LASER_OFFSET;
if (out_obs->d_back < 0.0f) out_obs->d_back = 0.0f;
out_obs->valid_mask |= CORRIDOR_OBS_MASK_BACK;
}
}