Files
Simba-OmniInfantry/云台/Application/Task/Src/debug_task.c
T

137 lines
6.5 KiB
C

/* =============================================================================
* debug_task.c - USB 虚拟串口(CDC)姿态输出(欧拉角 + 姿态链路诊断)
* 每 DEBUG_OUT_PERIOD_MS 输出一行。单位: 角度 ° / 加速度 m/s² / 角速度 rad/s
*
* ---- 欧拉角(QuaternionEKF 解算结果,见 modules/ins) ----
* yaw 多圈连续偏航角 (att_deg_yaw = INS.YawTotalAngle,云台 Yaw 环反馈)
* pitch 绕 y 轴角 (att_deg_pitch = QEKF_INS.Roll )
* roll 绕 x 轴角 (att_deg_roll = QEKF_INS.Pitch,云台 Pitch 环反馈)
* QEKF 内部 Pitch/Roll 命名与航空惯例互换,映射与原因见 attitude.c 文件头。
* 注意 yaw 无绝对基准(纯陀螺积分),上电静止时恒为该次上电的相对 0 点。
*
* ---- 健康位 / 诊断位(排查"角度不动或自漂"时必须一起看) ----
* cvg 1-INS.ConvergeFlag:EKF 卡方检验通过、姿态可信(与原诊断输出同义,
* 不要改成别的量,否则会丢掉"是否真的收敛"这一唯一判据)
* rdy 1-att_ready:ins_update() 至少执行过一次,只说明"在跑",不代表可信
* imu 1-bmi088_online:IMU 初始化成功;0=ID 检测失败,姿态必然全 0
* an |bmi088_accel|:静止时≈9.8;≈0 说明 IMU 根本没给出数据
* gn |bmi088_gyro|:原始陀螺模长(**未减零偏**),静止时≈0
* gx/gy/gz 原始陀螺三分量(rad/s) —— 与 gn 一起可判断数据是否冻结
* zo ins_gyro_z_offset:上电静止标定得到的 z 零偏(rad/s)。**关键**:
* 实际进入滤波器的 gyro_z = gz - zo。若 zo 与 gz 量级相近甚至更大,
* 而 yaw 又匀速自漂,即标定窗口内车体在动把零偏标歪了
* ck ins_z_cal_ok:1-标定时全程静止,zo 可信;0-三轮都在动,zo 存疑
* ca/cg 加速度/陀螺采样计数:停止增长即数据路已死(数值冻结时它们不涨)
* se bmi088_spi_errors:SPI/DMA 出错次数;st=bmi088_spi_state()
* (1=READY,非 1 说明 SPI 被卡住,数据路会因此停摆)
*
* 开关: DEBUG_ATT_HEALTH=0 只输出三个欧拉角;DEBUG_ATT_DIAG=0 去掉诊断位。
* ========================================================================== */
#include "debug_task.h"
#include "cmsis_os.h"
#include "FreeRTOS.h"
#include "task.h"
#include "usbd_cdc_if.h"
#include "attitude.h"
#include "ins.h"
#include "bmi088.h"
#include "gimbal.h"
#include "dr16.h"
#include <stdio.h>
#include <math.h>
#include <string.h>
/* ===== 2026-10-15 台架调参临时遥测(已停用,保留备查) =====
* 启用时把 #if 0 改 #if 1:本任务改为输出 5 列 CSV
* setpoint_deg, actual_deg, out_current, ecd_deg, gyro_x_dps
* (逗号分隔+换行,可被 Lissio FireWater 自动识别为 5 通道),采样率提到 200Hz,
* 用于定量观测阶跃响应与判断"轴是否真的在转动"。 */
#if 0
#include "robot_param.h"
#define DEBUG_PITCH_TUNE 1
#if DEBUG_PITCH_TUNE
#define DEBUG_OUT_PERIOD_MS 5 /* 200Hz:2ms 控制环的阶跃响应需 ≥100Hz 采样才量得准 */
#endif
#endif
/* 1-输出健康位(cvg/rdy/imu/an/gn); 0-只输出三个欧拉角 */
#define DEBUG_ATT_HEALTH 0
/* 1-再附加原始陀螺/零偏/采样计数(排障用); 0-只留上面的通用健康位 */
#define DEBUG_ATT_DIAG 0
/* 1-仅输出 Pitch 调参行(便于用 VOFA+/串口示波器绘图); 0-同时输出姿态行与 Pitch 调参行 */
#define DEBUG_PITCH_ONLY 0
/* 输出周期(ms)。姿态观测建议 100ms(10Hz) */
#define DEBUG_OUT_PERIOD_MS 100
void debug_task(void const * argument)
{
char line[384];
char tail[112];
char pitch_line[128];
for (;;)
{
#if 0
/* ===== 2026-10-15 台架 Pitch 调参遥测(已停用,保留备查) =====
* 5 列 CSV → Lissio FireWater 直接成 5 通道:
* setpoint(位置环设定值含台架偏置), actual(-att_deg_roll),
* out(最终电流), ecd_deg(编码器机械角), gyro_x_dps(陀螺 x 轴角速度) */
const float tune_ecd_deg = ((float)motor_pitch_gimbal.fdb.raw_angle -
(float)PITCH_GM6020_ENCODER_ZERO) * (360.0f / 8192.0f);
const float tune_gyro_dps = bmi088_gyro[0] * 57.29578f;
int len = snprintf(line, sizeof(line), "%.3f,%.3f,%.1f,%.3f,%.2f\n",
gimbal_pitch_setpoint_deg(),
-att_deg_roll,
pitch_current,
tune_ecd_deg,
tune_gyro_dps);
#endif
#if DEBUG_PITCH_ONLY
/* 仅输出 Pitch 调参数据(编码值、roll、PID最后输出值、遥控pitch杆量) */
int len = snprintf(line, sizeof(line),
"p_ecd=%u roll=%.2f p_out=%.1f rc_pitch=%u\r\n",
(unsigned)motor_pitch_gimbal.fdb.raw_angle,
att_deg_roll,
pitch_current,
(unsigned)dr16.rc_l_UD);
#else
const float an = sqrtf(bmi088_accel[0] * bmi088_accel[0] +
bmi088_accel[1] * bmi088_accel[1] +
bmi088_accel[2] * bmi088_accel[2]);
const float gn = sqrtf(bmi088_gyro[0] * bmi088_gyro[0] +
bmi088_gyro[1] * bmi088_gyro[1] +
bmi088_gyro[2] * bmi088_gyro[2]);
tail[0] = '\0';
#if DEBUG_ATT_HEALTH && DEBUG_ATT_DIAG
snprintf(tail, sizeof(tail),
" gx=%.4f gy=%.4f gz=%.4f zo=%.4f ck=%u ca=%lu cg=%lu se=%lu st=%u",
bmi088_gyro[0], bmi088_gyro[1], bmi088_gyro[2],
ins_gyro_z_offset, (unsigned)ins_z_cal_ok,
(unsigned long)bmi088_accel_cnt, (unsigned long)bmi088_gyro_cnt,
(unsigned long)bmi088_spi_errors, (unsigned)bmi088_spi_state());
#endif
#if DEBUG_ATT_HEALTH
int len = snprintf(line, sizeof(line),
"ecd=%u yaw=%.2f pitch=%.2f roll=%.2f cvg=%u rdy=%u imu=%u an=%.2f gn=%.3f%s\r\n",
(unsigned)motor_yaw_gimbal.fdb.raw_angle,
att_deg_yaw, att_deg_pitch, att_deg_roll,
(unsigned)INS.ConvergeFlag, (unsigned)att_ready,
(unsigned)bmi088_online, an, gn, tail);
#else
int len = snprintf(line, sizeof(line), "%u,%.1f,%u\r\n",
(unsigned)motor_pitch_gimbal.fdb.raw_angle,
pitch_current,(unsigned)motor_yaw_gimbal.fdb.raw_angle);
#endif
#endif
if (len > 0)
CDC_Transmit_FS((uint8_t *)line, (uint16_t)len);
osDelay(DEBUG_OUT_PERIOD_MS);
}
}