feat(ui): 新增裁判系统自定义UI(0x0301)并打通键鼠→底盘链路
键鼠控制(此前 WASD 无反应): - 云台 robot_cmd_task:0x0304 与 USART3 帧内键鼠合并为共享视图 keyboard_merged(0x0304 优先); 键鼠模式由帧内键鼠动作进入,动云台左摇杆退出 - c_comm_task/c_comm:键鼠在控时底盘摇杆由 WASD+鼠标合成,改读共享视图(此前只认 0x0304) - dr16/调试输出:新增帧内键鼠原始字节诊断(key_lo/key_hi/mouse_*/s1/frames) 自定义UI(底盘板经裁判系统 USART6 绘制到选手端): - 新增 底盘/modules/comms/referee_ui.c|h:15 字节图形组包(带编译期断言), v5 卡片式 HUD = 俯仰梯(pitch) + 罗盘刻度带(底盘朝向) + 预估底盘功率 + 超级电容 + 摩擦轮 L/R 转速 + 小陀螺状态,yaw 在刻度带右侧;5Hz 刷新,约 50 图元/8 包 - referee.c 新增 referee_send_frame()(cmd 0x0301 机器人交互数据,CRC8+CRC16,USART6 TX DMA) - 新增 CToC 0x1B9:云台把 pitch 与摩擦轮转速带给底盘(底盘本地没有这两个量) - 版式避开官方保留区:顶部比分条/左下小地图/右下战车模块/中部两块官方保留 验证:云台 Code=99540 RO=1764 RW=420 ZI=62572;底盘 Code=99452 RO=1928 RW=416 ZI=62584;均 0 错误 0 警告。 未做实机验证(当前无板/无图传);UI 协议常量(UI_RECEIVER_ID/UI_SEND_HZ)与版式坐标集中在 referee_ui.h 宏区,便于按协议 PDF 一处校正。
This commit is contained in:
@@ -24,4 +24,13 @@ typedef struct
|
||||
|
||||
extern keyboard_data_t keyboard_data;
|
||||
|
||||
/* ---- 键鼠来源合并视图(2026-10-16) ----
|
||||
* 客户端键鼠既可能从裁判系统 0x0304 进来,也可能从 USART3 那 18 字节帧进来
|
||||
* (官方 18 字节控制帧里就带鼠标与按键,由 dr16 解析成 dr16.mouse_rl / dr16.key_w 等)。
|
||||
* robot_cmd_task 每周期把两路合并到下面这个视图:
|
||||
* 云台/发射控制 与 c_comm_task 的底盘摇杆合成 都读它,
|
||||
* 避免两处各判一次出现"云台跟鼠标、底盘却还在收遥控器原始摇杆"。 */
|
||||
extern keyboard_data_t keyboard_merged; /* 合并后的键鼠数据(0x0304 优先) */
|
||||
extern uint8_t keyboard_merged_online; /* 1=键鼠在控(0x0304 在线 或 帧内键鼠有动作) */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -33,28 +33,38 @@ void c_comm_task(void const * argument)
|
||||
for (;;)
|
||||
{
|
||||
#if defined(ROBOT_TYPE_GIMBAL)
|
||||
uint8_t kb_online = (keyboard_data.last_tick != 0 &&
|
||||
HAL_GetTick() - keyboard_data.last_tick < DEVICE_OFFLINE_TIME_MS * 10);
|
||||
/* 键鼠来源已由 robot_cmd_task 合并(0x0304 优先,否则 USART3 帧内键鼠)。
|
||||
* 直接用共享视图,保证"云台怎么控、底盘就怎么收"——否则 WASD 合成的
|
||||
* 底盘摇杆会因为这里只认 0x0304 而被整段跳过(客户端键鼠走帧内时平移失效)。 */
|
||||
uint8_t kb_online = keyboard_merged_online;
|
||||
uint8_t kb[12];
|
||||
kb[0] = (uint8_t)(keyboard_data.mouse_rl & 0xFF);
|
||||
kb[1] = (uint8_t)((uint16_t)keyboard_data.mouse_rl >> 8);
|
||||
kb[2] = (uint8_t)(keyboard_data.mouse_du & 0xFF);
|
||||
kb[3] = (uint8_t)((uint16_t)keyboard_data.mouse_du >> 8);
|
||||
kb[4] = (uint8_t)(keyboard_data.mouse_wheel & 0xFF);
|
||||
kb[5] = (uint8_t)((uint16_t)keyboard_data.mouse_wheel >> 8);
|
||||
kb[6] = keyboard_data.mouse_key_l;
|
||||
kb[7] = keyboard_data.mouse_key_r;
|
||||
kb[8] = (uint8_t)(keyboard_data.key_w | (keyboard_data.key_s << 1) |
|
||||
(keyboard_data.key_a << 2) | (keyboard_data.key_d << 3) |
|
||||
(keyboard_data.key_shift << 4) | (keyboard_data.key_ctrl << 5) |
|
||||
(keyboard_data.key_q << 6) | (keyboard_data.key_e << 7));
|
||||
kb[9] = (uint8_t)(keyboard_data.key_alpha1 | (keyboard_data.key_alpha2 << 1));
|
||||
kb[0] = (uint8_t)(keyboard_merged.mouse_rl & 0xFF);
|
||||
kb[1] = (uint8_t)((uint16_t)keyboard_merged.mouse_rl >> 8);
|
||||
kb[2] = (uint8_t)(keyboard_merged.mouse_du & 0xFF);
|
||||
kb[3] = (uint8_t)((uint16_t)keyboard_merged.mouse_du >> 8);
|
||||
kb[4] = (uint8_t)(keyboard_merged.mouse_wheel & 0xFF);
|
||||
kb[5] = (uint8_t)((uint16_t)keyboard_merged.mouse_wheel >> 8);
|
||||
kb[6] = keyboard_merged.mouse_key_l;
|
||||
kb[7] = keyboard_merged.mouse_key_r;
|
||||
kb[8] = (uint8_t)(keyboard_merged.key_w | (keyboard_merged.key_s << 1) |
|
||||
(keyboard_merged.key_a << 2) | (keyboard_merged.key_d << 3) |
|
||||
(keyboard_merged.key_shift << 4) | (keyboard_merged.key_ctrl << 5) |
|
||||
(keyboard_merged.key_q << 6) | (keyboard_merged.key_e << 7));
|
||||
kb[9] = (uint8_t)(keyboard_merged.key_alpha1 | (keyboard_merged.key_alpha2 << 1));
|
||||
kb[10] = 0;
|
||||
kb[11] = 0;
|
||||
|
||||
c_comm_master_send(kb_online, kb, gimbal_motor_offline(),
|
||||
cmd_robot.spin_flag); // 故障位+小陀螺使能位
|
||||
|
||||
/* 0x1B9 自定义UI 专用量:底盘本地没有 pitch 与摩擦轮转速,
|
||||
* 由云台随板间通讯带给它(见 底盘/modules/comms/referee_ui.c)。
|
||||
* pitch 取云台 pitch 环反馈 -att_deg_roll;摩擦轮转速取电机反馈 rpm。 */
|
||||
c_comm_master_send_ui(-att_deg_roll,
|
||||
(float)motor_friction_l.fdb.rotor_speed,
|
||||
(float)motor_friction_r.fdb.rotor_speed,
|
||||
cmd_robot.spin_flag);
|
||||
|
||||
/* 0x1A9 姿态帧:跟随符号自动综合的数据源
|
||||
* flags:bit0=att_ready bit1=tick增向CCW bit2=bit1有效 */
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* =============================================================================
|
||||
* debug_task.c - USB 虚拟串口(CDC)姿态输出(欧拉角 + 姿态链路诊断)
|
||||
* debug_task.c - USB 虚拟串口(CDC)姿态输出(欧拉角 + 姿态链路诊断 + 控制量)
|
||||
* 每 DEBUG_OUT_PERIOD_MS 输出一行。单位: 角度 ° / 加速度 m/s² / 角速度 rad/s
|
||||
*
|
||||
* ---- 欧拉角(QuaternionEKF 解算结果,见 modules/ins) ----
|
||||
@@ -25,7 +25,30 @@
|
||||
* se bmi088_spi_errors:SPI/DMA 出错次数;st=bmi088_spi_state()
|
||||
* (1=READY,非 1 说明 SPI 被卡住,数据路会因此停摆)
|
||||
*
|
||||
* 开关: DEBUG_ATT_HEALTH=0 只输出三个欧拉角;DEBUG_ATT_DIAG=0 去掉诊断位。
|
||||
* ---- 控制量(DEBUG_CMD_OUT=1 时追加;用于排查 控制源→cmd_robot→执行机构) ----
|
||||
* online 1=**遥控器(DR16)在线** —— 本板这一位只反映 DR16,键鼠不置位!
|
||||
* 没有遥控器时整段控制分支都不执行(见 robot_cmd_task.c 的 online 门控),
|
||||
* 所以"键鼠测试"也必须有遥控器在线,否则这里恒为 0。
|
||||
* src 0=遥控器 1=键鼠(判据:0x0304 在 1s 内到过 keyboard_data.last_tick)
|
||||
* spin 小陀螺使能(云台侧检测,随 0x189 下发给底盘)
|
||||
* yaw_d/pitch_d 本周期云台角度增量(°/2ms 任务周期,×500 即 °/s)
|
||||
* fric/fire/eject 发射机构开关 reset 云台角度复位请求
|
||||
* s2/ctrl 遥控器 S2 档位与 Ctrl 按下沿 —— 底盘就是靠这两个量推出
|
||||
* chassis_mode,所以本板不输出模式本身(本板该字段恒为 OFF)
|
||||
* wheel 遥控拨轮原始值(1000~1050 为中立)
|
||||
* --- 以下为 DR16 帧内容诊断(判断"键鼠数据到底有没有到机器人") ---
|
||||
* s1 左侧拨杆(1上 2下 3中)。注意官方 RoboRTS 的 dbus.c 与本工程一致:
|
||||
* sw2=bit44-45→s2, sw1=bit46-47→s1;若与实物相反,用本列与 s2 对照即可判定
|
||||
* mouse_rl/mouse_du/mouse_wheel 帧里 data[6..11] 解析出的鼠标三轴
|
||||
* mouse_l/mouse_r 帧里 data[12]/data[13](鼠标左右键)
|
||||
* key_lo/key_hi 帧里 data[14]/data[15] **原始字节**(不做位拆分)
|
||||
* ★ 按下 W 时 key_lo 应变 0x01;若恒为 0,说明帧里根本没有键鼠数据
|
||||
* frames dr16_frame_count;持续增长说明 USART3 一直在收帧
|
||||
* 无健康位(DEBUG_ATT_HEALTH=0)时输出为纯数字 CSV,列序即上面顺序,
|
||||
* 可被 Lissio FireWater 直接解析成通道绘图。
|
||||
*
|
||||
* 开关: DEBUG_ATT_HEALTH=0 只输出三个欧拉角;DEBUG_ATT_DIAG=0 去掉诊断位;
|
||||
* DEBUG_CMD_OUT=1 追加控制量字段。
|
||||
* ========================================================================== */
|
||||
#include "debug_task.h"
|
||||
#include "cmsis_os.h"
|
||||
@@ -37,6 +60,7 @@
|
||||
#include "bmi088.h"
|
||||
#include "gimbal.h"
|
||||
#include "dr16.h"
|
||||
#include "robot_typedef.h"
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
@@ -60,6 +84,8 @@
|
||||
#define DEBUG_ATT_DIAG 0
|
||||
/* 1-仅输出 Pitch 调参行(便于用 VOFA+/串口示波器绘图); 0-同时输出姿态行与 Pitch 调参行 */
|
||||
#define DEBUG_PITCH_ONLY 0
|
||||
/* 1-追加控制量字段(见文件头); 0-保持原姿态输出不变 */
|
||||
#define DEBUG_CMD_OUT 1
|
||||
|
||||
/* 输出周期(ms)。姿态观测建议 100ms(10Hz) */
|
||||
#define DEBUG_OUT_PERIOD_MS 100
|
||||
@@ -114,17 +140,68 @@ void debug_task(void const * argument)
|
||||
#endif
|
||||
|
||||
#if DEBUG_ATT_HEALTH
|
||||
#if DEBUG_CMD_OUT
|
||||
/* 健康位分支是文本格式,控制量就按 key=value 追加,便于人读 */
|
||||
char ctl[160];
|
||||
snprintf(ctl, sizeof(ctl),
|
||||
" online=%u src=%u spin=%u yaw_d=%.4f pitch_d=%.4f fric=%u fire=%u"
|
||||
" eject=%u reset=%u s2=%u ctrl=%u wheel=%d",
|
||||
(unsigned)cmd_robot.online, (unsigned)cmd_robot.source,
|
||||
(unsigned)cmd_robot.spin_flag,
|
||||
cmd_robot.gimbal_yaw_delta, cmd_robot.gimbal_pitch_delta,
|
||||
(unsigned)cmd_robot.friction_on, (unsigned)cmd_robot.fire,
|
||||
(unsigned)cmd_robot.eject, (unsigned)cmd_robot.gimbal_reset,
|
||||
(unsigned)dr16.s2, (unsigned)dr16.key_push_ctrl,
|
||||
(int)cmd_robot.thumb_wheel);
|
||||
#else
|
||||
const char * ctl = "";
|
||||
#endif
|
||||
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",
|
||||
"ecd=%u yaw=%.2f pitch=%.2f roll=%.2f cvg=%u rdy=%u imu=%u an=%.2f gn=%.3f%s%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);
|
||||
(unsigned)bmi088_online, an, gn, tail, ctl);
|
||||
#else
|
||||
#if DEBUG_CMD_OUT
|
||||
/* 纯数字 CSV。前 3 列保持原样(pitch_ecd, pitch_current, yaw_ecd),其余:
|
||||
* online,src,spin, yaw_d,pitch_d, fric,fire,eject,reset, s2,ctrl,wheel,
|
||||
* s1, mouse_rl,mouse_du,mouse_wheel,mouse_l,mouse_r, key_lo,key_hi,
|
||||
* dr16_frame_count
|
||||
* 末尾这 9 列是 DR16 帧内容诊断:key_lo/key_hi 就是帧里的 data[14]/data[15]。
|
||||
* 按住 W 时若它们仍为 0,说明帧里本就没有键鼠数据(不是解析问题)。 */
|
||||
int len = snprintf(line, sizeof(line),
|
||||
"%u,%.1f,%u,%u,%u,%u,%.4f,%.4f,%u,%u,%u,%u,%u,%u,%d,%u,%d,%d,%d,%u,%u,%u,%u,%lu\r\n",
|
||||
(unsigned)motor_pitch_gimbal.fdb.raw_angle,
|
||||
pitch_current,
|
||||
(unsigned)motor_yaw_gimbal.fdb.raw_angle,
|
||||
(unsigned)cmd_robot.online,
|
||||
(unsigned)cmd_robot.source,
|
||||
(unsigned)cmd_robot.spin_flag,
|
||||
cmd_robot.gimbal_yaw_delta,
|
||||
cmd_robot.gimbal_pitch_delta,
|
||||
(unsigned)cmd_robot.friction_on,
|
||||
(unsigned)cmd_robot.fire,
|
||||
(unsigned)cmd_robot.eject,
|
||||
(unsigned)cmd_robot.gimbal_reset,
|
||||
(unsigned)dr16.s2,
|
||||
(unsigned)dr16.key_push_ctrl,
|
||||
(int)cmd_robot.thumb_wheel,
|
||||
(unsigned)dr16.s1,
|
||||
(int)dr16.mouse_rl,
|
||||
(int)dr16.mouse_du,
|
||||
(int)dr16.mouse_wheel,
|
||||
(unsigned)dr16.mouse_key_l,
|
||||
(unsigned)dr16.mouse_key_r,
|
||||
(unsigned)dr16.key_code_lo,
|
||||
(unsigned)dr16.key_code_hi,
|
||||
(unsigned long)dr16_frame_count);
|
||||
#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
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* =============================================================================
|
||||
* robot_cmd_task.c - 控制源汇总(2ms),发布 cmd_robot_t(robot_typedef.h)
|
||||
* 云台板: DR16 遥控器 + 图传键鼠(0x0304,referee 键盘钩子填充 keyboard_data)
|
||||
* 云台板: DR16 遥控器 + 键鼠(0x0304 优先;USART3 的 18 字节帧里同样带键鼠,两路已合并,见 KB_FROM_DBUS_FRAME)
|
||||
* 键鼠/遥控互斥(与 legacy 一致);摇杆->云台增量与限位门控;
|
||||
* Q 摩擦轮/左键发射/E 退弹/拨轮;首帧触发 gimbal_reset
|
||||
* 底盘板: 从 ctoc_remote(0x149/0x189 解析结果)生成:
|
||||
@@ -31,6 +31,9 @@ volatile cmd_robot_t cmd_robot;
|
||||
#if defined(ROBOT_TYPE_GIMBAL)
|
||||
|
||||
keyboard_data_t keyboard_data;
|
||||
/* 键鼠来源合并视图(声明见 robot_cmd_task.h):云台控制与 c_comm_task 底盘摇杆合成共用 */
|
||||
keyboard_data_t keyboard_merged;
|
||||
uint8_t keyboard_merged_online = 0;
|
||||
static uint8_t keyboard_online = 0;
|
||||
|
||||
void dr16_frame_callback(const uint8_t * frame, uint16_t len)
|
||||
@@ -74,6 +77,15 @@ static void referee_keyboard_hook(const uint8_t data[12])
|
||||
keyboard_data.last_tick = HAL_GetTick();
|
||||
}
|
||||
|
||||
/* ---- 键鼠输入来源(2026-10-16 修) ----
|
||||
* 背景:客户端键鼠是从 USART3 那 18 字节帧进来的(data[6..15]),dr16_parse 早就
|
||||
* 解析进 dr16.mouse_rl / dr16.key_w 等字段,但控制逻辑只读 0x0304 填的
|
||||
* keyboard_data,于是"键鼠控制完全没用"。此开关让两路合并。
|
||||
* 1 = 除 0x0304 外同时接受帧内键鼠:见到键鼠动作即进入键鼠模式并保持,
|
||||
* 直到操作手去动云台左摇杆才交还遥控器(右摇杆在底盘,键鼠模式下仍要能用)。
|
||||
* 0 = 旧行为:只有 0x0304 在线才走键鼠。 */
|
||||
#define KB_FROM_DBUS_FRAME 1
|
||||
|
||||
void robot_cmd_task(void const * argument)
|
||||
{
|
||||
referee_set_keyboard_hook(referee_keyboard_hook);
|
||||
@@ -81,13 +93,80 @@ void robot_cmd_task(void const * argument)
|
||||
while (!app_ready)
|
||||
osDelay(2);
|
||||
|
||||
/* 键鼠模式状态:帧内键鼠动作置 1,左摇杆动作清 0 */
|
||||
static uint8_t kb_mode = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
keyboard_online = (keyboard_data.last_tick != 0 &&
|
||||
HAL_GetTick() - keyboard_data.last_tick < DEVICE_OFFLINE_TIME_MS * 10);
|
||||
|
||||
#if KB_FROM_DBUS_FRAME
|
||||
{
|
||||
uint8_t kb_act = 0, rc_act = 0;
|
||||
|
||||
/* 键鼠动作:鼠标移动 / 滚轮 / 左右键 / 任意按键(data[14]或data[15]非 0) */
|
||||
if (dr16.mouse_rl > 1 || dr16.mouse_rl < -1) kb_act = 1;
|
||||
if (dr16.mouse_du > 1 || dr16.mouse_du < -1) kb_act = 1;
|
||||
if (dr16.mouse_wheel != 0) kb_act = 1;
|
||||
if (dr16.mouse_key_l || dr16.mouse_key_r) kb_act = 1;
|
||||
if (dr16.key_code_lo || dr16.key_code_hi) kb_act = 1;
|
||||
|
||||
/* 遥控器动作:只认云台左摇杆 */
|
||||
if (dr16.rc_l_UD > 1050 || dr16.rc_l_UD < 1000) rc_act = 1;
|
||||
if (dr16.rc_l_RL > 1050 || dr16.rc_l_RL < 1000) rc_act = 1;
|
||||
|
||||
if (kb_act) kb_mode = 1;
|
||||
if (rc_act) kb_mode = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 是否键鼠在控:0x0304 在线时始终算键鼠(保持原有优先级) */
|
||||
uint8_t kb_active = (keyboard_online || kb_mode) ? 1 : 0;
|
||||
|
||||
/* ---- 合并成共享视图 keyboard_merged ----
|
||||
* 0x0304 在线 → 整份用 keyboard_data;否则用 USART3 帧里那一套。
|
||||
* 云台控制、发射机构、以及 c_comm_task 里 WASD→底盘摇杆的合成都读这个
|
||||
* 视图,避免两处各判一次导致"云台跟鼠标了、底盘却还在收遥控器原始摇杆"。 */
|
||||
if (keyboard_online)
|
||||
{
|
||||
keyboard_merged = keyboard_data;
|
||||
}
|
||||
else
|
||||
{
|
||||
keyboard_merged.mouse_rl = dr16.mouse_rl;
|
||||
keyboard_merged.mouse_du = dr16.mouse_du;
|
||||
keyboard_merged.mouse_wheel = dr16.mouse_wheel;
|
||||
keyboard_merged.mouse_key_l = dr16.mouse_key_l;
|
||||
keyboard_merged.mouse_key_r = dr16.mouse_key_r;
|
||||
keyboard_merged.key_w = dr16.key_w;
|
||||
keyboard_merged.key_s = dr16.key_s;
|
||||
keyboard_merged.key_a = dr16.key_a;
|
||||
keyboard_merged.key_d = dr16.key_d;
|
||||
keyboard_merged.key_shift = dr16.key_shift;
|
||||
keyboard_merged.key_ctrl = dr16.key_ctrl;
|
||||
keyboard_merged.key_q = dr16.key_q;
|
||||
keyboard_merged.key_e = dr16.key_e;
|
||||
/* alpha 键:dr16 侧那两位恒为 0(见 dr16.c 的 >>9/>>10),照搬保持语义 */
|
||||
keyboard_merged.key_alpha1 = dr16.key_alpha1;
|
||||
keyboard_merged.key_alpha2 = dr16.key_alpha2;
|
||||
keyboard_merged.key_push_q = dr16.key_push_q;
|
||||
keyboard_merged.key_push_e = dr16.key_push_e;
|
||||
keyboard_merged.key_push_shift = dr16.key_push_shift;
|
||||
keyboard_merged.key_push_ctrl = dr16.key_push_ctrl;
|
||||
keyboard_merged.last_tick = dr16_last_tick;
|
||||
}
|
||||
keyboard_merged_online = kb_active;
|
||||
|
||||
/* 控制逻辑用的简写(取自共享视图) */
|
||||
int16_t kb_mouse_rl = keyboard_merged.mouse_rl;
|
||||
int16_t kb_mouse_du = keyboard_merged.mouse_du;
|
||||
uint8_t kb_mouse_l = keyboard_merged.mouse_key_l;
|
||||
uint8_t kb_push_q = keyboard_merged.key_push_q;
|
||||
uint8_t kb_push_e = keyboard_merged.key_push_e;
|
||||
|
||||
cmd_robot.online = (dr16_status == 1 && !dr16_offline());
|
||||
cmd_robot.source = keyboard_online ? 1 : 0;
|
||||
cmd_robot.source = kb_active ? 1 : 0;
|
||||
|
||||
if (cmd_robot.online)
|
||||
{
|
||||
@@ -95,7 +174,7 @@ void robot_cmd_task(void const * argument)
|
||||
float yaw_delta = 0, pitch_delta = 0;
|
||||
uint16_t pos = motor_pitch_gimbal.fdb.raw_angle;
|
||||
|
||||
if (!keyboard_online)
|
||||
if (!kb_active)
|
||||
{
|
||||
/* 遥控器:左摇杆向上(>1050)为抬头(pitch_delta减小,pos向2260减小),门控须 pos > UPPER_LIMIT(2260);
|
||||
* 左摇杆向下(<1000)为低头(pitch_delta增大,pos向3950增大),门控须 pos < LOWER_LIMIT(3950) */
|
||||
@@ -114,23 +193,26 @@ void robot_cmd_task(void const * argument)
|
||||
else
|
||||
{
|
||||
/* 键鼠:鼠标前推(>8)为抬头(pitch_delta减小),门控须 pos > UPPER_LIMIT;鼠标后拉(<-8)为低头(pitch_delta增大),门控须 pos < LOWER_LIMIT */
|
||||
if (keyboard_data.mouse_du > 8 && pos > PITCH_GM6020_POSITION_UPPER_LIMIT)
|
||||
if (kb_mouse_du > 8 && pos > PITCH_GM6020_POSITION_UPPER_LIMIT)
|
||||
pitch_delta -= GIMBAL_PITCH_LEVER_RATE / 8192.0f * 360.0f *
|
||||
((float)keyboard_data.mouse_du * PC_MOUSE_DU_SENSITIVITY) / 660.0f;
|
||||
else if (keyboard_data.mouse_du < -8 && pos < PITCH_GM6020_POSITION_LOWER_LIMIT)
|
||||
((float)kb_mouse_du * PC_MOUSE_DU_SENSITIVITY) / 660.0f;
|
||||
else if (kb_mouse_du < -8 && pos < PITCH_GM6020_POSITION_LOWER_LIMIT)
|
||||
pitch_delta += GIMBAL_PITCH_LEVER_RATE / 8192.0f * 360.0f *
|
||||
(-(float)keyboard_data.mouse_du * PC_MOUSE_DU_SENSITIVITY) / 660.0f;
|
||||
(-(float)kb_mouse_du * PC_MOUSE_DU_SENSITIVITY) / 660.0f;
|
||||
|
||||
if (keyboard_data.mouse_rl != 0)
|
||||
if (kb_mouse_rl != 0)
|
||||
yaw_delta -= GIMBAL_LEVER_SPEED_MAP_RATE * GIMBAL_YAW_PITCH_SPEED_RATE *
|
||||
GIMBAL_YAW_PITCH_SPEED_RATE * 0.0439453125f *
|
||||
((float)keyboard_data.mouse_rl * PC_MOUSE_RL_SENSITIVITY / 660.0f * 2.0f);
|
||||
((float)kb_mouse_rl * PC_MOUSE_RL_SENSITIVITY / 660.0f * 2.0f);
|
||||
}
|
||||
cmd_robot.gimbal_yaw_delta = yaw_delta;
|
||||
cmd_robot.gimbal_pitch_delta = pitch_delta;
|
||||
|
||||
/* ---- 发射机构 ---- */
|
||||
if (!keyboard_online)
|
||||
/* ---- 发射机构 ----
|
||||
* 键鼠模式用 Q / 鼠标左键 / E(两路来源已合并进 kb_*,0x0304 优先);
|
||||
* 遥控模式用 S1 与拨轮。kb_push_* 是"按下翻转"的常驻状态,
|
||||
* 且键鼠模式只在动左摇杆时才退出,所以摩擦轮/E 的状态不会自己掉。 */
|
||||
if (!kb_active)
|
||||
{
|
||||
cmd_robot.friction_on = (dr16.s1 == 1);
|
||||
cmd_robot.fire = (dr16.thumb_wheel < 1000);
|
||||
@@ -138,9 +220,9 @@ void robot_cmd_task(void const * argument)
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd_robot.friction_on = keyboard_data.key_push_q;
|
||||
cmd_robot.fire = keyboard_data.mouse_key_l;
|
||||
cmd_robot.eject = keyboard_data.key_push_e;
|
||||
cmd_robot.friction_on = kb_push_q;
|
||||
cmd_robot.fire = kb_mouse_l;
|
||||
cmd_robot.eject = kb_push_e;
|
||||
}
|
||||
cmd_robot.thumb_wheel = dr16.thumb_wheel;
|
||||
}
|
||||
@@ -153,12 +235,13 @@ void robot_cmd_task(void const * argument)
|
||||
cmd_robot.eject = 0;
|
||||
}
|
||||
|
||||
/* 小陀螺使能:Ctrl 沿翻转(仅在遥控源检测,键鼠 TODO);
|
||||
/* 小陀螺使能:Ctrl 沿翻转。键鼠模式下取键鼠那一路的 Ctrl(0x0304 的
|
||||
* keyboard_data 或帧内 dr16.key_push_ctrl),遥控模式用遥控器 Ctrl。
|
||||
* 云台侧是数据源头,底盘只收状态位——重连瞬间保持态跳变不会在
|
||||
* 底盘误触发沿(修复"重连误开小陀螺疯转") */
|
||||
{
|
||||
static uint8_t spin_flag = 0, last_ctrl = 0;
|
||||
uint8_t ctrl_now = (!keyboard_online) ? dr16.key_push_ctrl : 0;
|
||||
uint8_t ctrl_now = keyboard_online ? keyboard_data.key_push_ctrl : dr16.key_push_ctrl;
|
||||
if (last_ctrl == 0 && ctrl_now == 1)
|
||||
spin_flag = !spin_flag;
|
||||
last_ctrl = ctrl_now;
|
||||
|
||||
@@ -139,6 +139,7 @@
|
||||
#define CTOC_SLAVE_ID1 0x149 // 云台->底盘:摇杆数据
|
||||
#define CTOC_SLAVE_ID2 0x189 // 云台->底盘:控制状态+故障/陀螺使能位
|
||||
#define CTOC_SLAVE_ID3 0x1A9 // 云台->底盘:云台世界系 yaw(float)+att_ready
|
||||
#define CTOC_SLAVE_ID4 0x1B9 // 云台->底盘:自定义UI 专用(pitch + 摩擦轮 L/R 转速)
|
||||
|
||||
/* ============================ CAN ID ============================ */
|
||||
/* 云台板:CAN1 = Pitch GM6020(0x206,0x1FE)+摩擦轮 M3508(0x201/0x202,0x200)
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
<bEvRecOn>1</bEvRecOn>
|
||||
<bSchkAxf>0</bSchkAxf>
|
||||
<bTchkAxf>0</bTchkAxf>
|
||||
<nTsel>2</nTsel>
|
||||
<nTsel>3</nTsel>
|
||||
<sDll></sDll>
|
||||
<sDllPa></sDllPa>
|
||||
<sDlgDll></sDlgDll>
|
||||
@@ -114,9 +114,14 @@
|
||||
<tDlgDll></tDlgDll>
|
||||
<tDlgPa></tDlgPa>
|
||||
<tIfile></tIfile>
|
||||
<pMon>BIN\CMSIS_AGDI.dll</pMon>
|
||||
<pMon>Segger\JL2CM3.dll</pMon>
|
||||
</DebugOpt>
|
||||
<TargetDriverDllRegistry>
|
||||
<SetRegEntry>
|
||||
<Number>0</Number>
|
||||
<Key>JL2CM3</Key>
|
||||
<Name>-U20090928 -O78 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32F4xx_1024.FLM -FS08000000 -FL0100000 -FP0($$Device:STM32F407IGHx$CMSIS\Flash\STM32F4xx_1024.FLM)</Name>
|
||||
</SetRegEntry>
|
||||
<SetRegEntry>
|
||||
<Number>0</Number>
|
||||
<Key>ARMRTXEVENTFLAGS</Key>
|
||||
|
||||
@@ -136,6 +136,26 @@ void c_comm_master_send(uint8_t keyboard_online, const uint8_t kb[12], uint8_t m
|
||||
c_comm_send_frame(&hcan2, CTOC_SLAVE_ID2, data);
|
||||
}
|
||||
|
||||
/* 0x1B9 云台->底盘:自定义UI 专用量(底盘本地没有,见 referee_ui)
|
||||
* [0..1] pitch(0.01°) [2..3] 左摩擦轮(rpm/100) [4..5] 右摩擦轮(rpm/100)
|
||||
* [6] bit0=小陀螺使能 */
|
||||
void c_comm_master_send_ui(float pitch_deg, float fric_l_rpm, float fric_r_rpm, uint8_t spin_on)
|
||||
{
|
||||
uint8_t data[8] = {0};
|
||||
int16_t p = (int16_t)(pitch_deg * 100.0f);
|
||||
int16_t fl = (int16_t)(fric_l_rpm / 100.0f);
|
||||
int16_t fr = (int16_t)(fric_r_rpm / 100.0f);
|
||||
|
||||
data[0] = (uint8_t)(p & 0xFF);
|
||||
data[1] = (uint8_t)((uint16_t)p >> 8);
|
||||
data[2] = (uint8_t)(fl & 0xFF);
|
||||
data[3] = (uint8_t)((uint16_t)fl >> 8);
|
||||
data[4] = (uint8_t)(fr & 0xFF);
|
||||
data[5] = (uint8_t)((uint16_t)fr >> 8);
|
||||
data[6] = spin_on ? 0x01 : 0;
|
||||
c_comm_send_frame(&hcan2, CTOC_SLAVE_ID4, data);
|
||||
}
|
||||
|
||||
#elif defined(ROBOT_TYPE_CHASSIS)
|
||||
|
||||
/* ============================ 底盘板(从机) ============================ */
|
||||
|
||||
@@ -63,6 +63,11 @@ extern volatile int8_t ctoc_encoder_ccw;
|
||||
/* 底盘板:0x1A9 帧是否新鲜(掉线检测) */
|
||||
extern uint8_t ctoc_att_fresh(void);
|
||||
|
||||
/* ---- 0x1B9 云台->底盘:自定义UI 专用数据 ---------------------------------
|
||||
* 底盘本地没有、但裁判系统自定义UI 需要的量(见 底盘/modules/comms/referee_ui):
|
||||
* pitch 角度与左右摩擦轮转速。接收侧解析见底盘 c_comm.c(c_comm_rx_0x1b9)。 */
|
||||
extern void c_comm_master_send_ui(float pitch_deg, float fric_l_rpm, float fric_r_rpm, uint8_t spin_on);
|
||||
|
||||
/* 注册 CAN 接收回调(can_start() 之后调用) */
|
||||
extern void c_comm_init(void);
|
||||
|
||||
|
||||
@@ -48,6 +48,12 @@ void dr16_parse(const uint8_t * data)
|
||||
dr16.key_alpha1 = (data[14] >> 9) & 0x01;
|
||||
dr16.key_alpha2 = (data[14] >> 10) & 0x01;
|
||||
|
||||
/* 原始按键字节。注意 data[14] 是 uint8_t:上面两条 >>9/>>10 恒为 0
|
||||
* (整型提升后 byte 值 <256,右移 9 位必然为 0),即 alpha 键从未被真正解析。
|
||||
* 官方 16 位 key_code 的高字节在 data[15],这里先原样存下来供诊断/后续解析。 */
|
||||
dr16.key_code_lo = data[14];
|
||||
dr16.key_code_hi = data[15];
|
||||
|
||||
dr16.thumb_wheel = (int16_t)(((uint16_t)data[17] << 8) | data[16]); // B[120:135]
|
||||
|
||||
/* 按键边沿检测(legacy 语义:Q/E/Shift/Ctrl 按下翻转,鼠标右键按下瞬间置 1) */
|
||||
|
||||
@@ -37,6 +37,13 @@ typedef struct
|
||||
uint8_t key_alpha1; // 图传扩展键
|
||||
uint8_t key_alpha2;
|
||||
|
||||
/* 原始按键字节(诊断用,不做位拆分) —— 用来判断"帧里到底有没有键鼠数据":
|
||||
* 官方 dbus.h 的 key_code 是 16 位:bit0..7 = W/S/A/D/Shift/Ctrl/Q/E(=data[14]),
|
||||
* bit8..15 = R/F/G/Z/X/C/V/B(=data[15])。本工程此前只读了 data[14]。
|
||||
* 拨键盘时这两个字节若非 0 说明数据确实到了;全 0 说明帧里就是空的。 */
|
||||
uint8_t key_code_lo; // data[14]
|
||||
uint8_t key_code_hi; // data[15]
|
||||
|
||||
int16_t thumb_wheel; // 遥控器拨轮
|
||||
|
||||
/* 按键边沿检测(legacy 语义) */
|
||||
|
||||
Reference in New Issue
Block a user