cmdV2成功

This commit is contained in:
yxming66 2025-12-18 02:51:36 +08:00
parent f1a4099554
commit 50bb9d8619
9 changed files with 344 additions and 341 deletions

View File

@ -11,152 +11,133 @@
/* ========================================================================== */
/* 从RC输入生成底盘命令 */
static void CMD_RC_BuildChassisCmd(CMD_t *ctx, const CMD_RawInput_t *input) {
static void CMD_RC_BuildChassisCmd(CMD_t *ctx) {
CMD_RCModeMap_t *map = &ctx->config->rc_mode_map;
/* 根据左拨杆位置选择模式 */
switch (input->sw[0]) {
switch (ctx->input.rc.sw[0]) {
case CMD_SW_UP:
ctx->chassis.cmd.mode = map->sw_left_up;
ctx->output.chassis.cmd.mode = map->sw_left_up;
break;
case CMD_SW_MID:
ctx->chassis.cmd.mode = map->sw_left_mid;
ctx->output.chassis.cmd.mode = map->sw_left_mid;
break;
case CMD_SW_DOWN:
ctx->chassis.cmd.mode = map->sw_left_down;
ctx->output.chassis.cmd.mode = map->sw_left_down;
break;
default:
ctx->chassis.cmd.mode = CHASSIS_MODE_RELAX;
ctx->output.chassis.cmd.mode = CHASSIS_MODE_RELAX;
break;
}
/* 摇杆控制移动 */
ctx->chassis.cmd.ctrl_vec.vx = input->joy_right.x;
ctx->chassis.cmd.ctrl_vec.vy = input->joy_right.y;
ctx->output.chassis.cmd.ctrl_vec.vx = ctx->input.rc.joy_right.x;
ctx->output.chassis.cmd.ctrl_vec.vy = ctx->input.rc.joy_right.y;
}
/* 从RC输入生成云台命令 */
static void CMD_RC_BuildGimbalCmd(CMD_t *ctx, const CMD_RawInput_t *input) {
static void CMD_RC_BuildGimbalCmd(CMD_t *ctx) {
CMD_RCModeMap_t *map = &ctx->config->rc_mode_map;
/* 根据拨杆选择云台模式 */
switch (input->sw[0]) {
switch (ctx->input.rc.sw[0]) {
case CMD_SW_UP:
ctx->gimbal.cmd.mode = map->gimbal_sw_up;
ctx->output.gimbal.cmd.mode = map->gimbal_sw_up;
break;
case CMD_SW_MID:
ctx->gimbal.cmd.mode = map->gimbal_sw_mid;
ctx->output.gimbal.cmd.mode = map->gimbal_sw_mid;
break;
case CMD_SW_DOWN:
ctx->gimbal.cmd.mode = map->gimbal_sw_down;
ctx->output.gimbal.cmd.mode = map->gimbal_sw_down;
break;
default:
ctx->gimbal.cmd.mode = GIMBAL_MODE_RELAX;
ctx->output.gimbal.cmd.mode = GIMBAL_MODE_RELAX;
break;
}
/* 左摇杆控制云台 */
ctx->gimbal.cmd.delta_yaw = -input->joy_left.x * 2.0f;
ctx->gimbal.cmd.delta_pit = -input->joy_left.y * 1.5f;
ctx->output.gimbal.cmd.delta_yaw = -ctx->input.rc.joy_left.x * 2.0f;
ctx->output.gimbal.cmd.delta_pit = -ctx->input.rc.joy_left.y * 1.5f;
}
/* 从RC输入生成射击命令 */
static void CMD_RC_BuildShootCmd(CMD_t *ctx, const CMD_RawInput_t *input) {
if (input->online) {
ctx->shoot.cmd.mode = SHOOT_MODE_SINGLE;
static void CMD_RC_BuildShootCmd(CMD_t *ctx) {
if (ctx->input.online[CMD_SRC_RC]) {
ctx->output.shoot.cmd.mode = SHOOT_MODE_SINGLE;
} else {
ctx->shoot.cmd.mode = SHOOT_MODE_SAFE;
ctx->output.shoot.cmd.mode = SHOOT_MODE_SAFE;
}
/* 根据右拨杆控制射击 */
switch (input->sw[1]) {
switch (ctx->input.rc.sw[1]) {
case CMD_SW_DOWN:
ctx->shoot.cmd.ready = true;
ctx->shoot.cmd.firecmd = true;
ctx->output.shoot.cmd.ready = true;
ctx->output.shoot.cmd.firecmd = true;
break;
case CMD_SW_MID:
ctx->shoot.cmd.ready = true;
ctx->shoot.cmd.firecmd = false;
ctx->output.shoot.cmd.ready = true;
ctx->output.shoot.cmd.firecmd = false;
break;
case CMD_SW_UP:
default:
ctx->shoot.cmd.ready = false;
ctx->shoot.cmd.firecmd = false;
ctx->output.shoot.cmd.ready = false;
ctx->output.shoot.cmd.firecmd = false;
break;
}
}
/* 从PC输入生成底盘命令 */
static void CMD_PC_BuildChassisCmd(CMD_t *ctx, const CMD_RawInput_t *input) {
CMD_Sensitivity_t *sens = &ctx->config->sensitivity;
static void CMD_PC_BuildChassisCmd(CMD_t *ctx) {
if (!input->online) {
ctx->chassis.cmd.mode = CHASSIS_MODE_RELAX;
if (!ctx->input.online[CMD_SRC_PC]) {
ctx->output.chassis.cmd.mode = CHASSIS_MODE_RELAX;
return;
}
ctx->chassis.cmd.mode = CHASSIS_MODE_FOLLOW_GIMBAL;
ctx->output.chassis.cmd.mode = CHASSIS_MODE_FOLLOW_GIMBAL;
/* WASD控制移动 */
ctx->chassis.cmd.ctrl_vec.vx = 0.0f;
ctx->chassis.cmd.ctrl_vec.vy = 0.0f;
if (CMD_KEY_PRESSED(&input->keyboard, CMD_KEY_W)) {
ctx->chassis.cmd.ctrl_vec.vy += sens->move_sens;
}
if (CMD_KEY_PRESSED(&input->keyboard, CMD_KEY_S)) {
ctx->chassis.cmd.ctrl_vec.vy -= sens->move_sens;
}
if (CMD_KEY_PRESSED(&input->keyboard, CMD_KEY_A)) {
ctx->chassis.cmd.ctrl_vec.vx -= sens->move_sens;
}
if (CMD_KEY_PRESSED(&input->keyboard, CMD_KEY_D)) {
ctx->chassis.cmd.ctrl_vec.vx += sens->move_sens;
}
/* 加速/减速 */
if (CMD_KEY_PRESSED(&input->keyboard, CMD_KEY_SHIFT)) {
ctx->chassis.cmd.ctrl_vec.vx *= sens->move_fast_mult;
ctx->chassis.cmd.ctrl_vec.vy *= sens->move_fast_mult;
}
if (CMD_KEY_PRESSED(&input->keyboard, CMD_KEY_CTRL)) {
ctx->chassis.cmd.ctrl_vec.vx *= sens->move_slow_mult;
ctx->chassis.cmd.ctrl_vec.vy *= sens->move_slow_mult;
}
ctx->output.chassis.cmd.ctrl_vec.vx = 0.0f;
ctx->output.chassis.cmd.ctrl_vec.vy = 0.0f;
CMD_Behavior_ProcessAll(ctx, &ctx->input, &ctx->last_input, CMD_MODULE_CHASSIS);
}
/* 从PC输入生成云台命令 */
static void CMD_PC_BuildGimbalCmd(CMD_t *ctx, const CMD_RawInput_t *input) {
static void CMD_PC_BuildGimbalCmd(CMD_t *ctx) {
CMD_Sensitivity_t *sens = &ctx->config->sensitivity;
if (!input->online) {
ctx->gimbal.cmd.mode = GIMBAL_MODE_RELAX;
if (!ctx->input.online[CMD_SRC_PC]) {
ctx->output.gimbal.cmd.mode = GIMBAL_MODE_RELAX;
return;
}
ctx->gimbal.cmd.mode = GIMBAL_MODE_ABSOLUTE;
ctx->output.gimbal.cmd.mode = GIMBAL_MODE_ABSOLUTE;
/* 鼠标控制云台 */
ctx->gimbal.cmd.delta_yaw = (float)-input->mouse.x * ctx->timer.dt * sens->mouse_sens;
ctx->gimbal.cmd.delta_pit = (float)input->mouse.y * ctx->timer.dt * sens->mouse_sens * 1.5f;
ctx->output.gimbal.cmd.delta_yaw = (float)-ctx->input.pc.mouse.x * ctx->timer.dt * sens->mouse_sens;
ctx->output.gimbal.cmd.delta_pit = (float)ctx->input.pc.mouse.y * ctx->timer.dt * sens->mouse_sens * 1.5f;
CMD_Behavior_ProcessAll(ctx, &ctx->input, &ctx->last_input, CMD_MODULE_GIMBAL);
}
/* 从PC输入生成射击命令 */
static void CMD_PC_BuildShootCmd(CMD_t *ctx, const CMD_RawInput_t *input) {
if (!input->online) {
ctx->shoot.cmd.mode = SHOOT_MODE_SAFE;
static void CMD_PC_BuildShootCmd(CMD_t *ctx) {
if (!ctx->input.online[CMD_SRC_PC]) {
ctx->output.shoot.cmd.mode = SHOOT_MODE_SAFE;
return;
}
ctx->shoot.cmd.ready = true;
ctx->shoot.cmd.firecmd = input->mouse.l_click;
ctx->output.shoot.cmd.ready = true;
ctx->output.shoot.cmd.firecmd = ctx->input.pc.mouse.l_click;
CMD_Behavior_ProcessAll(ctx, &ctx->input, &ctx->last_input, CMD_MODULE_SHOOT);
}
/* 离线安全模式 */
static void CMD_SetOfflineMode(CMD_t *ctx) {
ctx->chassis.cmd.mode = CHASSIS_MODE_RELAX;
ctx->gimbal.cmd.mode = GIMBAL_MODE_RELAX;
ctx->shoot.cmd.mode = SHOOT_MODE_SAFE;
ctx->output.chassis.cmd.mode = CHASSIS_MODE_RELAX;
ctx->output.gimbal.cmd.mode = GIMBAL_MODE_RELAX;
ctx->output.shoot.cmd.mode = SHOOT_MODE_SAFE;
}
/* ========================================================================== */
@ -186,16 +167,32 @@ int8_t CMD_UpdateInput(CMD_t *ctx) {
}
/* 保存上一帧输入 */
memcpy(ctx->last_input, ctx->input, sizeof(ctx->input));
memcpy(&ctx->last_input, &ctx->input, sizeof(ctx->input));
/* 更新所有输入源 */
for (int i = 0; i < CMD_SRC_NUM; i++) {
CMD_Adapter_GetInput((CMD_InputSource_t)i, &ctx->input[i]);
CMD_Adapter_GetInput((CMD_InputSource_t)i, &ctx->input);
}
return CMD_OK;
}
typedef void (*CMD_BuildCommandFunc)(CMD_t *cmd);
typedef struct {
CMD_InputSource_t source;
CMD_BuildCommandFunc chassisFunc;
CMD_BuildCommandFunc gimbalFunc;
CMD_BuildCommandFunc shootFunc;
} CMD_SourceHandler_t;
CMD_SourceHandler_t sourceHandlers[CMD_SRC_NUM] = {
{CMD_SRC_RC, CMD_RC_BuildChassisCmd, CMD_RC_BuildGimbalCmd, CMD_RC_BuildShootCmd},
{CMD_SRC_PC, CMD_PC_BuildChassisCmd, CMD_PC_BuildGimbalCmd, CMD_PC_BuildShootCmd},
{CMD_SRC_NUC, NULL, NULL, NULL},
{CMD_SRC_REF, NULL, NULL, NULL},
};
uint8_t last_shift = 0, last_v = 0;
uint8_t now_shift = 0, now_v = 0;
int8_t CMD_Arbitrate(CMD_t *ctx) {
if (ctx == NULL) {
return CMD_ERR_NULL;
@ -208,14 +205,14 @@ int8_t CMD_Arbitrate(CMD_t *ctx) {
/* 如果当前输入源仍然在线且有效,保持使用 */
if (ctx->active_source < CMD_SRC_NUM &&
ctx->active_source != CMD_SRC_REF &&
ctx->input[ctx->active_source].online) {
ctx->input.online[ctx->active_source]) {
goto seize;
}
/* 否则选择第一个可用的控制输入源 */
for (int i = 0; i < num_candidates; i++) {
CMD_InputSource_t src = candidates[i];
if (ctx->input[src].online) {
if (ctx->input.online[src]) {
ctx->active_source = src;
break;
}else {
@ -223,63 +220,56 @@ int8_t CMD_Arbitrate(CMD_t *ctx) {
continue;
}
}
ctx->chassis.source = ctx->active_source;
ctx->gimbal.source = ctx->active_source;
ctx->shoot.source = ctx->active_source;
ctx->output.chassis.source = ctx->active_source;
ctx->output.gimbal.source = ctx->active_source;
ctx->output.shoot.source = ctx->active_source;
/* 优先级抢占逻辑 */
seize:
return CMD_OK;
// 检查PC输入按下一次shift和v切换active_source在RC和PC之间
CMD_Behavior_ProcessAll(ctx, &ctx->input, &ctx->last_input, CMD_MODULE_NONE);
// if (ctx->input.online[CMD_SRC_PC]) {
// now_shift = CMD_KEY_PRESSED(&ctx->input.pc.keyboard, CMD_KEY_SHIFT);
// now_v = CMD_KEY_PRESSED(&ctx->input.pc.keyboard, CMD_KEY_V);
// // 检测本帧按下(上升沿)
// if (now_shift && !last_shift && now_v && !last_v) {
// if (ctx->active_source == CMD_SRC_PC && ctx->input.online[CMD_SRC_RC]) {
// ctx->active_source = CMD_SRC_RC;
// } else if (ctx->active_source == CMD_SRC_RC && ctx->input.online[CMD_SRC_PC]) {
// ctx->active_source = CMD_SRC_PC;
// }
// ctx->output.chassis.source = ctx->active_source;
// ctx->output.gimbal.source = ctx->active_source;
// ctx->output.shoot.source = ctx->active_source;
// }
// last_shift = now_shift;
// last_v = now_v;
// }
return CMD_OK;
}
int8_t CMD_GenerateCommands(CMD_t *ctx) {
if (ctx == NULL) {
return CMD_ERR_NULL;
}
/* 更新时间 */
uint64_t now_us = BSP_TIME_Get_us();
ctx->timer.now = now_us / 1000000.0f;
ctx->timer.dt = (now_us - ctx->timer.last_us) / 1000000.0f;
ctx->timer.last_us = now_us;
/* 没有有效输入源 */
if (ctx->active_source >= CMD_SRC_NUM) {
CMD_SetOfflineMode(ctx);
return CMD_ERR_NO_INPUT;
}
const CMD_RawInput_t *active_input = &ctx->input[ctx->active_source];
const CMD_RawInput_t *last_input = &ctx->last_input[ctx->active_source];
/* 根据输入源类型生成命令 */
switch (ctx->active_source) {
case CMD_SRC_RC:
CMD_RC_BuildChassisCmd(ctx, active_input);
CMD_RC_BuildGimbalCmd(ctx, active_input);
CMD_RC_BuildShootCmd(ctx, active_input);
break;
case CMD_SRC_PC:
CMD_PC_BuildChassisCmd(ctx, active_input);
CMD_PC_BuildGimbalCmd(ctx, active_input);
CMD_PC_BuildShootCmd(ctx, active_input);
/* 处理行为 */
CMD_Behavior_ProcessAll(ctx, active_input, last_input, CMD_MODULE_ALL);
break;
case CMD_SRC_NUC:
/* TODO: NUC输入处理 */
break;
default:
CMD_SetOfflineMode(ctx);
return CMD_ERR_SOURCE;
}
return CMD_OK;
if (ctx == NULL) {
return CMD_ERR_NULL;
}
/* 更新时间 */
uint64_t now_us = BSP_TIME_Get_us();
ctx->timer.now = now_us / 1000000.0f;
ctx->timer.dt = (now_us - ctx->timer.last_us) / 1000000.0f;
ctx->timer.last_us = now_us;
/* 没有有效输入源 */
if (ctx->active_source >= CMD_SRC_NUM) {
CMD_SetOfflineMode(ctx);
return CMD_ERR_NO_INPUT;
}
sourceHandlers[ctx->output.gimbal.source].gimbalFunc(ctx);
sourceHandlers[ctx->output.chassis.source].chassisFunc(ctx);
sourceHandlers[ctx->output.shoot.source].shootFunc(ctx);
return CMD_OK;
}
int8_t CMD_Update(CMD_t *ctx) {

View File

@ -83,7 +83,7 @@ typedef struct {
typedef struct {
float now;
float dt;
uint64_t last_us;
uint32_t last_us;
} CMD_Timer_t;
typedef struct CMD_Context {
@ -94,17 +94,18 @@ typedef struct CMD_Context {
CMD_Timer_t timer;
/* 当前帧和上一帧的原始输入 */
CMD_RawInput_t input[CMD_SRC_NUM];
CMD_RawInput_t last_input[CMD_SRC_NUM];
CMD_RawInput_t input;
CMD_RawInput_t last_input;
/* 仲裁后的活跃输入源 */
CMD_InputSource_t active_source;
/* 输出 */
struct {
CMD_ChassisOutput_t chassis;
CMD_GimbalOutput_t gimbal;
CMD_ShootOutput_t shoot;
} output;
} CMD_t;
/* ========================================================================== */
@ -153,17 +154,17 @@ int8_t CMD_Update(CMD_t *ctx);
/* 获取底盘命令 */
static inline Chassis_CMD_t* CMD_GetChassisCmd(CMD_t *ctx) {
return &ctx->chassis.cmd;
}
return &ctx->output.chassis.cmd;
}
/* 获取云台命令 */
static inline Gimbal_CMD_t* CMD_GetGimbalCmd(CMD_t *ctx) {
return &ctx->gimbal.cmd;
return &ctx->output.gimbal.cmd;
}
/* 获取射击命令 */
static inline Shoot_CMD_t* CMD_GetShootCmd(CMD_t *ctx) {
return &ctx->shoot.cmd;
return &ctx->output.shoot.cmd;
}
#ifdef __cplusplus

View File

@ -22,32 +22,32 @@ int8_t CMD_DR16_Init(void *data) {
int8_t CMD_DR16_RC_GetInput(void *data, CMD_RawInput_t *output) {
DR16_t *dr16 = (DR16_t *)data;
memset(output, 0, sizeof(CMD_RawInput_t));
memset(&output->rc, 0, sizeof(CMD_RawInput_RC_t));
output->online = dr16->header.online;
output->online[CMD_SRC_RC] = dr16->header.online;
/* 遥控器摇杆映射 */
output->joy_left.x = dr16->data.rc.ch_l_x;
output->joy_left.y = dr16->data.rc.ch_l_y;
output->joy_right.x = dr16->data.rc.ch_r_x;
output->joy_right.y = dr16->data.rc.ch_r_y;
output->rc.joy_left.x = dr16->data.rc.ch_l_x;
output->rc.joy_left.y = dr16->data.rc.ch_l_y;
output->rc.joy_right.x = dr16->data.rc.ch_r_x;
output->rc.joy_right.y = dr16->data.rc.ch_r_y;
/* 拨杆映射 */
switch (dr16->data.rc.sw_l) {
case DR16_SW_UP: output->sw[0] = CMD_SW_UP; break;
case DR16_SW_MID: output->sw[0] = CMD_SW_MID; break;
case DR16_SW_DOWN: output->sw[0] = CMD_SW_DOWN; break;
default: output->sw[0] = CMD_SW_ERR; break;
case DR16_SW_UP: output->rc.sw[0] = CMD_SW_UP; break;
case DR16_SW_MID: output->rc.sw[0] = CMD_SW_MID; break;
case DR16_SW_DOWN: output->rc.sw[0] = CMD_SW_DOWN; break;
default: output->rc.sw[0] = CMD_SW_ERR; break;
}
switch (dr16->data.rc.sw_r) {
case DR16_SW_UP: output->sw[1] = CMD_SW_UP; break;
case DR16_SW_MID: output->sw[1] = CMD_SW_MID; break;
case DR16_SW_DOWN: output->sw[1] = CMD_SW_DOWN; break;
default: output->sw[1] = CMD_SW_ERR; break;
case DR16_SW_UP: output->rc.sw[1] = CMD_SW_UP; break;
case DR16_SW_MID: output->rc.sw[1] = CMD_SW_MID; break;
case DR16_SW_DOWN: output->rc.sw[1] = CMD_SW_DOWN; break;
default: output->rc.sw[1] = CMD_SW_ERR; break;
}
/* 拨轮映射 */
output->dial = dr16->data.rc.ch_res;
output->rc.dial = dr16->data.rc.ch_res;
return CMD_OK;
}
@ -55,18 +55,18 @@ int8_t CMD_DR16_RC_GetInput(void *data, CMD_RawInput_t *output) {
int8_t CMD_DR16_PC_GetInput(void *data, CMD_RawInput_t *output) {
DR16_t *dr16 = (DR16_t *)data;
memset(output, 0, sizeof(CMD_RawInput_t));
memset(&output->pc, 0, sizeof(CMD_RawInput_PC_t));
output->online = dr16->header.online;
output->online[CMD_SRC_PC] = dr16->header.online;
/* PC端鼠标映射 */
output->mouse.x = dr16->data.pc.mouse.x;
output->mouse.y = dr16->data.pc.mouse.y;
output->mouse.l_click = dr16->data.pc.mouse.l_click;
output->mouse.r_click = dr16->data.pc.mouse.r_click;
output->pc.mouse.x = dr16->data.pc.mouse.x;
output->pc.mouse.y = dr16->data.pc.mouse.y;
output->pc.mouse.l_click = dr16->data.pc.mouse.l_click;
output->pc.mouse.r_click = dr16->data.pc.mouse.r_click;
/* 键盘映射 */
output->keyboard.bitmap = dr16->raw_data.key;
output->pc.keyboard.bitmap = dr16->raw_data.key;
return CMD_OK;
}
@ -95,9 +95,9 @@ int8_t CMD_AT9S_Init(void *data) {
int8_t CMD_AT9S_GetInput(void *data, CMD_RawInput_t *output) {
AT9S_t *at9s = (AT9S_t *)data;
memset(output, 0, sizeof(CMD_RawInput_t));
memset(output, 0, sizeof(CMD_RawInput_RC_t));
output->online = at9s->header.online;
output->online[CMD_SRC_RC] = at9s->header.online;
/* TODO: 按照AT9S的数据格式进行映射 */
output->joy_left.x = at9s->data.rc.ch_l_x;
@ -159,8 +159,7 @@ int8_t CMD_Adapter_GetInput(CMD_InputSource_t source, CMD_RawInput_t *output) {
CMD_InputAdapter_t *adapter = g_adapters[source];
if (adapter == NULL || adapter->get_input == NULL) {
memset(output, 0, sizeof(CMD_RawInput_t));
output->online = false;
output->online[adapter->source] = false;
return CMD_ERR_NO_INPUT;
}

View File

@ -3,6 +3,7 @@
*/
#include "cmd_behavior.h"
#include "cmd.h"
#include "module/gimbal.h"
#include <string.h>
/* ========================================================================== */
@ -11,55 +12,52 @@
/* 行为处理函数实现 */
int8_t CMD_Behavior_Handle_FORE(CMD_t *ctx) {
ctx->chassis.cmd.ctrl_vec.vy += ctx->config->sensitivity.move_sens;
ctx->output.chassis.cmd.ctrl_vec.vy += ctx->config->sensitivity.move_sens;
return CMD_OK;
}
int8_t CMD_Behavior_Handle_BACK(CMD_t *ctx) {
ctx->chassis.cmd.ctrl_vec.vy -= ctx->config->sensitivity.move_sens;
ctx->output.chassis.cmd.ctrl_vec.vy -= ctx->config->sensitivity.move_sens;
return CMD_OK;
}
int8_t CMD_Behavior_Handle_LEFT(CMD_t *ctx) {
ctx->chassis.cmd.ctrl_vec.vx -= ctx->config->sensitivity.move_sens;
ctx->output.chassis.cmd.ctrl_vec.vx -= ctx->config->sensitivity.move_sens;
return CMD_OK;
}
int8_t CMD_Behavior_Handle_RIGHT(CMD_t *ctx) {
ctx->chassis.cmd.ctrl_vec.vx += ctx->config->sensitivity.move_sens;
ctx->output.chassis.cmd.ctrl_vec.vx += ctx->config->sensitivity.move_sens;
return CMD_OK;
}
int8_t CMD_Behavior_Handle_ACCELERATE(CMD_t *ctx) {
ctx->chassis.cmd.ctrl_vec.vx *= ctx->config->sensitivity.move_fast_mult;
ctx->chassis.cmd.ctrl_vec.vy *= ctx->config->sensitivity.move_fast_mult;
ctx->output.chassis.cmd.ctrl_vec.vx *= ctx->config->sensitivity.move_fast_mult;
ctx->output.chassis.cmd.ctrl_vec.vy *= ctx->config->sensitivity.move_fast_mult;
return CMD_OK;
}
int8_t CMD_Behavior_Handle_DECELERATE(CMD_t *ctx) {
ctx->chassis.cmd.ctrl_vec.vx *= ctx->config->sensitivity.move_slow_mult;
ctx->chassis.cmd.ctrl_vec.vy *= ctx->config->sensitivity.move_slow_mult;
ctx->output.chassis.cmd.ctrl_vec.vx *= ctx->config->sensitivity.move_slow_mult;
ctx->output.chassis.cmd.ctrl_vec.vy *= ctx->config->sensitivity.move_slow_mult;
return CMD_OK;
}
int8_t CMD_Behavior_Handle_FIRE(CMD_t *ctx) {
ctx->shoot.cmd.firecmd = true;
ctx->output.shoot.cmd.firecmd = true;
return CMD_OK;
}
int8_t CMD_Behavior_Handle_FIRE_MODE(CMD_t *ctx) {
ctx->shoot.cmd.mode = (ctx->shoot.cmd.mode + 1) % SHOOT_MODE_NUM;
ctx->output.shoot.cmd.mode = (ctx->output.shoot.cmd.mode + 1) % SHOOT_MODE_NUM;
return CMD_OK;
}
int8_t CMD_Behavior_Handle_ROTOR(CMD_t *ctx) {
if (ctx->chassis.cmd.mode == CHASSIS_MODE_ROTOR) {
ctx->chassis.cmd.mode = CHASSIS_MODE_FOLLOW_GIMBAL;
} else {
ctx->chassis.cmd.mode = CHASSIS_MODE_ROTOR;
ctx->chassis.cmd.mode_rotor = ROTOR_MODE_RAND;
}
return CMD_OK;
ctx->output.chassis.cmd.mode = CHASSIS_MODE_ROTOR;
ctx->output.chassis.cmd.mode_rotor = ROTOR_MODE_RAND;
ctx->output.gimbal.cmd.mode = GIMBAL_MODE_RELATIVE;
return CMD_OK;
}
int8_t CMD_Behavior_Handle_AUTOAIM(CMD_t *ctx) {
@ -67,12 +65,28 @@ int8_t CMD_Behavior_Handle_AUTOAIM(CMD_t *ctx) {
return CMD_OK;
}
int8_t CMD_Behavior_Handle_CHECKSOURCERCPC(CMD_t *ctx) {
/* TODO: 切换RC和PC输入源 */
if (ctx->active_source == CMD_SRC_PC) {
ctx->active_source = CMD_SRC_RC;
ctx->output.chassis.source = CMD_SRC_RC;
ctx->output.gimbal.source = CMD_SRC_RC;
ctx->output.shoot.source = CMD_SRC_RC;
} else if(ctx->active_source == CMD_SRC_RC) {
ctx->active_source = CMD_SRC_PC;
ctx->output.chassis.source = CMD_SRC_PC;
ctx->output.gimbal.source = CMD_SRC_PC;
ctx->output.shoot.source = CMD_SRC_PC;
}
return CMD_OK;
}
/* 行为配置表 - 由宏生成 */
static const CMD_BehaviorConfig_t g_behavior_configs[] = {
CMD_BEHAVIOR_TABLE(BUILD_BEHAVIOR_CONFIG)
};
#define BEHAVIOR_CONFIG_COUNT (sizeof(g_behavior_configs) / sizeof(g_behavior_configs[0]))
// #define BEHAVIOR_CONFIG_COUNT (sizeof(g_behavior_configs) / sizeof(g_behavior_configs[0]))
/* ========================================================================== */
/* API实现 */
@ -90,51 +104,37 @@ bool CMD_Behavior_IsTriggered(const CMD_RawInput_t *current,
return false;
}
bool now_pressed = false;
bool last_pressed = false;
/* 处理特殊按键 */
switch (config->key) {
case CMD_KEY_NONE:
bool now_pressed = false;
bool last_pressed = false;
// 鼠标特殊按键处理
if (config->key == (CMD_KEY_L_CLICK)) {
now_pressed = current->pc.mouse.l_click;
last_pressed = last ? last->pc.mouse.l_click : false;
} else if (config->key == (CMD_KEY_R_CLICK)) {
now_pressed = current->pc.mouse.r_click;
last_pressed = last ? last->pc.mouse.r_click : false;
} else if (config->key == (CMD_KEY_M_CLICK)) {
now_pressed = current->pc.mouse.m_click;
last_pressed = last ? last->pc.mouse.m_click : false;
} else if (config->key == 0) {
return false;
case CMD_KEY_L_CLICK:
now_pressed = current->mouse.l_click;
last_pressed = last ? last->mouse.l_click : false;
break;
case CMD_KEY_R_CLICK:
now_pressed = current->mouse.r_click;
last_pressed = last ? last->mouse.r_click : false;
break;
case CMD_KEY_M_CLICK:
now_pressed = current->mouse.m_click;
last_pressed = last ? last->mouse.m_click : false;
break;
default:
if (config->key < CMD_KEY_NUM) {
now_pressed = CMD_KEY_PRESSED(&current->keyboard, config->key);
last_pressed = last ? CMD_KEY_PRESSED(&last->keyboard, config->key) : false;
}
break;
}
/* 根据触发类型判断 */
switch (config->trigger) {
case CMD_ACTIVE_PRESSED:
return now_pressed;
case CMD_ACTIVE_RISING_EDGE:
return now_pressed && !last_pressed;
case CMD_ACTIVE_FALLING_EDGE:
return !now_pressed && last_pressed;
default:
return false;
}
} else {
// 多按键组合检测
now_pressed = ((current->pc.keyboard.bitmap & config->key) == config->key);
last_pressed = last ? ((last->pc.keyboard.bitmap & config->key) == config->key) : false;
}
switch (config->trigger) {
case CMD_ACTIVE_PRESSED:
return now_pressed;
case CMD_ACTIVE_RISING_EDGE:
return now_pressed && !last_pressed;
case CMD_ACTIVE_FALLING_EDGE:
return !now_pressed && last_pressed;
default:
return false;
}
}
int8_t CMD_Behavior_ProcessAll(CMD_t *ctx,
@ -148,7 +148,7 @@ int8_t CMD_Behavior_ProcessAll(CMD_t *ctx,
for (size_t i = 0; i < BEHAVIOR_CONFIG_COUNT; i++) {
const CMD_BehaviorConfig_t *config = &g_behavior_configs[i];
/* 检查模块掩码 */
/* 过滤模块掩码 */
if ((config->module_mask & active_modules) == 0) {
continue;
}

View File

@ -21,7 +21,7 @@ typedef int8_t (*CMD_BehaviorHandler)(struct CMD_Context *ctx);
/* 行为配置项 */
typedef struct {
CMD_Behavior_t behavior; /* 行为枚举 */
uint8_t key; /* 绑定的按键 */
uint32_t key; /* 绑定的按键 */
CMD_TriggerType_t trigger; /* 触发类型 */
CMD_ModuleMask_t module_mask; /* 影响的模块 */
CMD_BehaviorHandler handler; /* 处理函数 */

View File

@ -39,6 +39,17 @@ extern "C" {
X(GIMBAL, Gimbal_CMD_t, gimbal) \
X(SHOOT, Shoot_CMD_t, shoot)
/* ========================================================================== */
/* 输入源枚举 */
/* ========================================================================== */
#define ENUM_INPUT_SOURCE(name, ...) CMD_SRC_##name,
typedef enum {
CMD_INPUT_SOURCE_TABLE(ENUM_INPUT_SOURCE)
CMD_SRC_NUM
} CMD_InputSource_t;
#undef ENUM_INPUT_SOURCE
/* ========================================================================== */
/* 统一输入数据结构 */
/* ========================================================================== */
@ -74,10 +85,10 @@ typedef struct {
/* 键盘按键索引 */
typedef enum {
CMD_KEY_W = 0, CMD_KEY_S, CMD_KEY_A, CMD_KEY_D,
CMD_KEY_SHIFT, CMD_KEY_CTRL, CMD_KEY_Q, CMD_KEY_E,
CMD_KEY_R, CMD_KEY_F, CMD_KEY_G, CMD_KEY_Z,
CMD_KEY_X, CMD_KEY_C, CMD_KEY_V, CMD_KEY_B,
CMD_KEY_W = (1 << 0), CMD_KEY_S = (1 << 1), CMD_KEY_A = (1 << 2), CMD_KEY_D = (1 << 3),
CMD_KEY_SHIFT = (1 << 4), CMD_KEY_CTRL = (1 << 5), CMD_KEY_Q = (1 << 6), CMD_KEY_E = (1 << 7),
CMD_KEY_R = (1 << 8), CMD_KEY_F = (1 << 9), CMD_KEY_G = (1 << 10), CMD_KEY_Z = (1 << 11),
CMD_KEY_X = (1 << 12), CMD_KEY_C = (1 << 13), CMD_KEY_V = (1 << 14), CMD_KEY_B = (1 << 15),
CMD_KEY_NUM
} CMD_KeyIndex_t;
@ -86,64 +97,72 @@ typedef struct {
uint8_t game_status; /* 比赛状态 */
} CMD_Referee_t;
typedef struct {
CMD_Joystick_t joy_left; /* 左摇杆 */
CMD_Joystick_t joy_right; /* 右摇杆 */
CMD_SwitchPos_t sw[4]; /* 4个拨杆 */
float dial; /* 拨轮 */
} CMD_RawInput_RC_t;
typedef struct {
CMD_Mouse_t mouse;
CMD_Keyboard_t keyboard;
} CMD_RawInput_PC_t;
typedef struct {
int a;
} CMD_RawInput_NUC_t;
typedef struct {
CMD_Referee_t referee;
} CMD_RawInput_REF_t;
/* 统一的原始输入结构 - 所有设备适配后都转换成这个格式 */
typedef struct {
bool online;
bool online[CMD_SRC_NUM];
/* 遥控器部分 */
CMD_Joystick_t joy_left; /* 左摇杆 */
CMD_Joystick_t joy_right; /* 右摇杆 */
CMD_SwitchPos_t sw[4]; /* 最多4个拨杆 */
float dial; /* 拨轮 */
CMD_RawInput_RC_t rc;
/* PC部分 */
CMD_Mouse_t mouse;
CMD_Keyboard_t keyboard;
CMD_RawInput_PC_t pc;
/* NUC部分 */
/* 暂无定义,预留扩展 */
/* REF部分 - 裁判系统数据 */
CMD_Referee_t referee;
} CMD_RawInput_t;
CMD_RawInput_NUC_t nuc;
/* ========================================================================== */
/* 输入源枚举 */
/* ========================================================================== */
#define ENUM_INPUT_SOURCE(name, ...) CMD_SRC_##name,
typedef enum {
CMD_INPUT_SOURCE_TABLE(ENUM_INPUT_SOURCE)
CMD_SRC_NUM
} CMD_InputSource_t;
#undef ENUM_INPUT_SOURCE
/* REF部分 - 裁判系统数据 */
CMD_RawInput_REF_t ref;
} CMD_RawInput_t;
/* ========================================================================== */
/* 模块掩码 */
/* ========================================================================== */
typedef enum {
CMD_MODULE_NONE = 0,
CMD_MODULE_CHASSIS = (1 << 0),
CMD_MODULE_GIMBAL = (1 << 1),
CMD_MODULE_SHOOT = (1 << 2),
CMD_MODULE_ALL = 0x07
CMD_MODULE_NONE = (1 << 0),
CMD_MODULE_CHASSIS = (1 << 1),
CMD_MODULE_GIMBAL = (1 << 2),
CMD_MODULE_SHOOT = (1 << 3),
CMD_MODULE_ALL = 0x0E
} CMD_ModuleMask_t;
/* ========================================================================== */
/* 行为定义 */
/* ========================================================================== */
/* 行为-按键映射宏表 */
#define BEHAVIOR_CONFIG_COUNT (11)
#define CMD_BEHAVIOR_TABLE(X) \
X(FORE, CMD_KEY_W, CMD_ACTIVE_PRESSED, CMD_MODULE_CHASSIS) \
X(BACK, CMD_KEY_S, CMD_ACTIVE_PRESSED, CMD_MODULE_CHASSIS) \
X(LEFT, CMD_KEY_A, CMD_ACTIVE_PRESSED, CMD_MODULE_CHASSIS) \
X(RIGHT, CMD_KEY_D, CMD_ACTIVE_PRESSED, CMD_MODULE_CHASSIS) \
X(ACCELERATE, CMD_KEY_SHIFT, CMD_ACTIVE_PRESSED, CMD_MODULE_CHASSIS) \
X(DECELERATE, CMD_KEY_CTRL, CMD_ACTIVE_PRESSED, CMD_MODULE_CHASSIS) \
X(FIRE, CMD_KEY_L_CLICK, CMD_ACTIVE_PRESSED, CMD_MODULE_SHOOT) \
X(FIRE_MODE, CMD_KEY_B, CMD_ACTIVE_RISING_EDGE, CMD_MODULE_SHOOT) \
X(ROTOR, CMD_KEY_E, CMD_ACTIVE_RISING_EDGE, CMD_MODULE_CHASSIS) \
X(AUTOAIM, CMD_KEY_R, CMD_ACTIVE_RISING_EDGE, CMD_MODULE_GIMBAL | CMD_MODULE_SHOOT)
X(FORE, CMD_KEY_W, CMD_ACTIVE_PRESSED, CMD_MODULE_CHASSIS) \
X(BACK, CMD_KEY_S, CMD_ACTIVE_PRESSED, CMD_MODULE_CHASSIS) \
X(LEFT, CMD_KEY_A, CMD_ACTIVE_PRESSED, CMD_MODULE_CHASSIS) \
X(RIGHT, CMD_KEY_D, CMD_ACTIVE_PRESSED, CMD_MODULE_CHASSIS) \
X(ACCELERATE, CMD_KEY_SHIFT, CMD_ACTIVE_PRESSED, CMD_MODULE_CHASSIS) \
X(DECELERATE, CMD_KEY_CTRL, CMD_ACTIVE_PRESSED, CMD_MODULE_CHASSIS) \
X(FIRE, CMD_KEY_L_CLICK, CMD_ACTIVE_PRESSED, CMD_MODULE_SHOOT) \
X(FIRE_MODE, CMD_KEY_B, CMD_ACTIVE_RISING_EDGE, CMD_MODULE_SHOOT) \
X(ROTOR, CMD_KEY_E, CMD_ACTIVE_PRESSED, CMD_MODULE_CHASSIS) \
X(AUTOAIM, CMD_KEY_R, CMD_ACTIVE_RISING_EDGE, CMD_MODULE_GIMBAL | CMD_MODULE_SHOOT) \
X(CHECKSOURCERCPC, CMD_KEY_CTRL|CMD_KEY_SHIFT|CMD_KEY_V, CMD_ACTIVE_RISING_EDGE, CMD_MODULE_NONE)
/* 触发类型 */
typedef enum {
CMD_ACTIVE_PRESSED, /* 按住时触发 */
@ -153,9 +172,9 @@ typedef enum {
/* 特殊按键值 */
#define CMD_KEY_NONE 0xFF
#define CMD_KEY_L_CLICK 0xFE
#define CMD_KEY_R_CLICK 0xFD
#define CMD_KEY_M_CLICK 0xFC
#define CMD_KEY_L_CLICK (1 << 31)
#define CMD_KEY_R_CLICK (1 << 30)
#define CMD_KEY_M_CLICK (1 << 29)
/* 行为枚举 - 由宏表自动生成 */
#define ENUM_BEHAVIOR(name, key, trigger, mask) CMD_BEHAVIOR_##name,

View File

@ -189,14 +189,14 @@ Config_RobotParam_t robot_config = {
.gyro = 1000.0f,
},
.pit_motor ={
.can = BSP_CAN_2,
.can = BSP_CAN_1,
.can_id = 0x2,
.master_id = 0x12,
.module = MOTOR_DM_J4310,
.reverse = false,
},
.yaw_motor = {
.can = BSP_CAN_2,
.can = BSP_CAN_1,
.can_id = 0x50,
.master_id = 0x60,
.module = MOTOR_DM_J4310,

View File

@ -5,7 +5,7 @@
**********************************************************************
File :
Created : 02. Nov 2025 13:12
Created : 16. Dec 2025 21:10
Ozone Version : V3.40b
*/
@ -32,7 +32,6 @@ void OnProjectLoad (void) {
//
// User settings
//
Edit.SysVar (VAR_HSS_SPEED, "200 Hz");
File.Open ("D:/CUBEMX/hero/god-yuan-hero/build/Debug/hero.elf");
}
@ -338,8 +337,25 @@ void AfterTargetDownload (void) {
**********************************************************************
*/
void _SetupTarget(void) {
unsigned int SP;
unsigned int PC;
unsigned int VectorTableAddr;
VectorTableAddr = Elf.GetBaseAddr();
//
// this function is intentionally empty because both inital PC and
// initial SP were chosen not to be set
// Set up initial stack pointer
//
SP = Target.ReadU32(VectorTableAddr);
if (SP != 0xFFFFFFFF) {
Target.SetReg("SP", SP);
}
//
// Set up entry point PC
//
PC = Elf.GetEntryPointPC();
if (PC != 0xFFFFFFFF) {
Target.SetReg("PC", PC);
} else {
Util.Error("Project script error: failed to set up entry point PC", 1);
}
}

View File

@ -1,78 +1,56 @@
Breakpoint=D:/CUBEMX/hero/god-yuan-hero/User/module/shoot.c:367:7, State=BP_STATE_DISABLED
GraphedExpression="(((shoot).feedback).fric[0]).rotor_speed", Color=#e56a6f
GraphedExpression="(((shoot).feedback).fric[1]).rotor_speed", Color=#35792b
GraphedExpression="(((shoot).feedback).fric[2]).rotor_speed", Color=#769dda
GraphedExpression="(((shoot).feedback).fric[3]).rotor_speed", Color=#b14f0d
GraphedExpression="(((shoot).feedback).fric[4]).rotor_speed", Color=#b3c38e
GraphedExpression="(((shoot).feedback).fric[5]).rotor_speed", Color=#ab7b05
GraphedExpression="(shoot).errtosee", Color=#7fd3b7, Show=0
OpenDocument="memcpy.c", FilePath="/build/gnu-tools-for-stm32_13.3.rel1.20250523-0900/src/newlib/newlib/libc/string/memcpy.c", Line=0
OpenDocument="can.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/bsp/can.c", Line=69
OpenDocument="tasks.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/Middlewares/Third_Party/FreeRTOS/Source/tasks.c", Line=3419
OpenDocument="device.h", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/device/device.h", Line=5
OpenDocument="cmd.h", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/module/cmd.h", Line=60
OpenDocument="cmd.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/module/cmd.c", Line=416
OpenDocument="cmd.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/task/cmd.c", Line=0
OpenDocument="pid.h", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/component/pid.h", Line=53
Breakpoint=D:/CUBEMX/hero/god-yuan-hero/User/module/cmd_v2/cmd_adapter.c:32, State=BP_STATE_DISABLED
Breakpoint=D:/CUBEMX/hero/god-yuan-hero/User/module/cmd_v2/cmd.c:249:16, State=BP_STATE_DISABLED
GraphedExpression="(cmd).active_source", DisplayFormat=DISPLAY_FORMAT_DEC, Color=#e56a6f
GraphedExpression="(((cmd).output).chassis).source", DisplayFormat=DISPLAY_FORMAT_DEC, Color=#35792b
GraphedExpression="((((cmd).input).pc).keyboard).bitmap", DisplayFormat=DISPLAY_FORMAT_DEC, Color=#769dda, Show=0
GraphedExpression="((dr16).raw_data).key", DisplayFormat=DISPLAY_FORMAT_DEC, Color=#b14f0d, Show=0
OpenDocument="stm32f4xx_hal_can.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c", Line=1614
OpenDocument="startup_stm32f407xx.s", FilePath="D:/CUBEMX/hero/god-yuan-hero/startup_stm32f407xx.s", Line=48
OpenDocument="motor_dm.h", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/device/motor_dm.h", Line=45
OpenDocument="can.h", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/bsp/can.h", Line=0
OpenDocument="shoot.h", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/module/shoot.h", Line=78
OpenDocument="ctrl_gimbal.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/task/ctrl_gimbal.c", Line=11
OpenDocument="main.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/Core/Src/main.c", Line=60
OpenDocument="rc.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/task/rc.c", Line=0
OpenDocument="shoot.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/module/shoot.c", Line=346
OpenDocument="config.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/module/config.c", Line=0
OpenDocument="config.h", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/module/config.h", Line=0
OpenDocument="chassis.h", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/module/chassis.h", Line=133
OpenDocument="stm32f4xx_hal_dma.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c", Line=710
OpenDocument="stm32f4xx_hal_can.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c", Line=1994
OpenDocument="stm32f4xx_hal_msp.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/Core/Src/stm32f4xx_hal_msp.c", Line=28
OpenDocument="usart.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/Core/Src/usart.c", Line=179
OpenDocument="ctrl_chassis.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/task/ctrl_chassis.c", Line=6
OpenDocument="gimbal.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/module/gimbal.c", Line=0
OpenDocument="memcpy.c", FilePath="/build/gnu-tools-for-stm32_13.3.rel1.20250523-0900/src/newlib/newlib/libc/string/memcpy.c", Line=0
OpenDocument="dma.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/Core/Src/dma.c", Line=21
OpenDocument="ctrl_shoot.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/task/ctrl_shoot.c", Line=2
OpenDocument="user_task.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/task/user_task.c", Line=0
OpenDocument="stm32f4xx_it.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/Core/Src/stm32f4xx_it.c", Line=83
OpenDocument="pid.h", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/component/pid.h", Line=60
OpenDocument="can.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/bsp/can.c", Line=60
OpenDocument="cmsis_os2.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c", Line=382
OpenDocument="time.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/bsp/time.c", Line=18
OpenDocument="tasks.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/Middlewares/Third_Party/FreeRTOS/Source/tasks.c", Line=3419
OpenDocument="queue.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/Middlewares/Third_Party/FreeRTOS/Source/queue.c", Line=1425
OpenDocument="cmd_adapter.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/module/cmd_v2/cmd_adapter.c", Line=88
OpenDocument="cmd.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/module/cmd_v2/cmd.c", Line=81
OpenDocument="cmd_behavior.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/module/cmd_v2/cmd_behavior.c", Line=43
OpenDocument="cmd.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/task/cmd.c", Line=28
OpenDocument="rc.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/task/rc.c", Line=0
OpenDocument="main.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/Core/Src/main.c", Line=60
OpenToolbar="Debug", Floating=0, x=0, y=0
OpenWindow="Registers 1", DockArea=RIGHT, x=0, y=1, w=726, h=515, TabPos=2, TopOfStack=0, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=0, FilteredItems=[], RefreshRate=1
OpenWindow="Registers 1", DockArea=RIGHT, x=0, y=1, w=726, h=509, TabPos=1, TopOfStack=0, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=0, FilteredItems=[], RefreshRate=1
OpenWindow="Source Files", DockArea=LEFT, x=0, y=0, w=301, h=919, TabPos=0, TopOfStack=1, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=0
OpenWindow="Disassembly", DockArea=RIGHT, x=0, y=0, w=726, h=403, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=0
OpenWindow="Watched Data 1", DockArea=RIGHT, x=0, y=1, w=726, h=515, TabPos=1, TopOfStack=1, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=0
OpenWindow="Disassembly", DockArea=RIGHT, x=0, y=0, w=726, h=409, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=0
OpenWindow="Watched Data 1", DockArea=RIGHT, x=0, y=1, w=726, h=509, TabPos=0, TopOfStack=1, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=0
OpenWindow="Functions", DockArea=LEFT, x=0, y=0, w=301, h=919, TabPos=1, TopOfStack=0, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=0
OpenWindow="Data Sampling", DockArea=BOTTOM, x=1, y=0, w=291, h=536, TabPos=0, TopOfStack=1, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=0, VisibleTab=0, UniformSampleSpacing=0
OpenWindow="Timeline", DockArea=BOTTOM, x=0, y=0, w=2268, h=555, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=1, DataPaneShown=1, PowerPaneShown=0, CodePaneShown=0, PinCursor="Cursor Movable", TimePerDiv="500 ms / Div", TimeStampFormat="Time", DataGraphDrawAsPoints=0, DataGraphLegendShown=1, DataGraphUniformSampleSpacing=0, DataGraphLegendPosition="34;98", DataGraphShowNamesAtCursor=0, PowerGraphDrawAsPoints=0, PowerGraphLegendShown=0, PowerGraphAvgFilterTime=Off, PowerGraphAvgFilterLen=Off, PowerGraphUniformSampleSpacing=0, PowerGraphLegendPosition="1266;0", CodeGraphLegendShown=0, CodeGraphLegendPosition="1282;0"
OpenWindow="Console", DockArea=BOTTOM, x=1, y=0, w=291, h=536, TabPos=1, TopOfStack=0, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=0
OpenWindow="Watched Data 2", DockArea=RIGHT, x=0, y=1, w=726, h=515, TabPos=0, TopOfStack=0, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=0
OpenWindow="Data Sampling", DockArea=BOTTOM, x=1, y=0, w=984, h=536, TabPos=0, TopOfStack=1, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=0, VisibleTab=0, UniformSampleSpacing=0
OpenWindow="Timeline", DockArea=BOTTOM, x=0, y=0, w=1575, h=555, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=1, DataPaneShown=1, PowerPaneShown=0, CodePaneShown=0, PinCursor="Cursor Movable", TimePerDiv="1 s / Div", TimeStampFormat="Time", DataGraphDrawAsPoints=0, DataGraphLegendShown=1, DataGraphUniformSampleSpacing=0, DataGraphLegendPosition="91;96", DataGraphShowNamesAtCursor=0, PowerGraphDrawAsPoints=0, PowerGraphLegendShown=0, PowerGraphAvgFilterTime=Off, PowerGraphAvgFilterLen=Off, PowerGraphUniformSampleSpacing=0, PowerGraphLegendPosition="1630;0", CodeGraphLegendShown=0, CodeGraphLegendPosition="1581;0"
OpenWindow="Console", DockArea=BOTTOM, x=1, y=0, w=984, h=536, TabPos=1, TopOfStack=0, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=0
SmartViewPlugin="", Page="", Toolbar="Hidden", Window="SmartView 1"
TableHeader="Watched Data 2", SortCol="Expression", SortOrder="ASCENDING", VisibleCols=["Expression";"Value";"Location";"Refresh"], ColWidths=[170;352;100;104]
TableHeader="Watched Data 1", SortCol="Expression", SortOrder="ASCENDING", VisibleCols=["Expression";"Value";"Location";"Refresh"], ColWidths=[250;282;91;100]
TableHeader="Registers 1", SortCol="Name", SortOrder="ASCENDING", VisibleCols=["Name";"Value";"Description"], ColWidths=[120;144;462]
TableHeader="Functions", SortCol="Name", SortOrder="ASCENDING", VisibleCols=["Name";"Address";"Size";"#Insts";"Source"], ColWidths=[1594;104;100;100;100]
TableHeader="Power Sampling", SortCol="None", SortOrder="ASCENDING", VisibleCols=["Index";"Time";"Ch 0"], ColWidths=[100;100;100]
TableHeader="RegisterSelectionDialog", SortCol="None", SortOrder="ASCENDING", VisibleCols=[], ColWidths=[]
TableHeader="Registers 1", SortCol="Name", SortOrder="ASCENDING", VisibleCols=["Name";"Value";"Description"], ColWidths=[120;144;294]
TableHeader="Functions", SortCol="Name", SortOrder="ASCENDING", VisibleCols=["Name";"Address";"Size";"#Insts";"Source"], ColWidths=[1594;104;100;100;798]
TableHeader="Source Files", SortCol="File", SortOrder="ASCENDING", VisibleCols=["File";"Status";"Size";"#Insts";"Path"], ColWidths=[215;100;100;100;1014]
TableHeader="Data Sampling Table", SortCol="None", SortOrder="ASCENDING", VisibleCols=["Index";"Time";" (((shoot).feedback).fric[0]).rotor_speed";" (((shoot).feedback).fric[1]).rotor_speed";" (((shoot).feedback).fric[2]).rotor_speed";" (((shoot).feedback).fric[3]).rotor_speed";" (((shoot).feedback).fric[4]).rotor_speed";" (((shoot).feedback).fric[5]).rotor_speed";" (shoot).errtosee"], ColWidths=[100;100;100;100;100;100;100;100;100]
TableHeader="Data Sampling Setup", SortCol="Expression", SortOrder="ASCENDING", VisibleCols=["Expression";"Type";"Value";"Min";"Max";"Average";"# Changes";"Min. Change";"Max. Change"], ColWidths=[118;100;100;100;100;124;110;126;126]
TableHeader="Data Sampling Table", SortCol="None", SortOrder="ASCENDING", VisibleCols=["Index";"Time";" (cmd).active_source";" (((cmd).output).chassis).source";" ((((cmd).input).pc).keyboard).bitmap";" ((dr16).raw_data).key"], ColWidths=[100;100;100;100;100;100]
TableHeader="Data Sampling Setup", SortCol="Expression", SortOrder="ASCENDING", VisibleCols=["Expression";"Type";"Value";"Min";"Max";"Average";"# Changes";"Min. Change";"Max. Change"], ColWidths=[118;234;100;100;100;124;110;144;126]
TableHeader="Power Sampling", SortCol="None", SortOrder="ASCENDING", VisibleCols=["Index";"Time";"Ch 0"], ColWidths=[100;100;100]
TableHeader="Watched Data 1", SortCol="Expression", SortOrder="ASCENDING", VisibleCols=["Expression";"Value";"Location";"Refresh"], ColWidths=[250;282;91;100]
TableHeader="RegisterSelectionDialog", SortCol="None", SortOrder="ASCENDING", VisibleCols=[], ColWidths=[]
TableHeader="TargetExceptionDialog", SortCol="Name", SortOrder="ASCENDING", VisibleCols=["Name";"Value";"Address";"Description"], ColWidths=[200;100;100;366]
WatchedExpression="0x20008DD8", Window=Watched Data 1
WatchedExpression="cmd", RefreshRate=5, Window=Watched Data 1
WatchedExpression="robot_config", RefreshRate=5, Window=Watched Data 1
WatchedExpression="shoot", RefreshRate=5, Window=Watched Data 1
WatchedExpression="at9s", RefreshRate=5, Window=Watched Data 1
WatchedExpression="dr16", RefreshRate=5, Window=Watched Data 1
WatchedExpression="shoot_cmd", RefreshRate=5, Window=Watched Data 1
WatchedExpression="chassis", RefreshRate=5, Window=Watched Data 1
WatchedExpression="chassis_cmd", RefreshRate=5, Window=Watched Data 1
WatchedExpression="gimbal_cmd", RefreshRate=5, Window=Watched Data 1
WatchedExpression="gimbal", RefreshRate=5, Window=Watched Data 1
WatchedExpression="at9s_out", RefreshRate=5, Window=Watched Data 1
WatchedExpression="cmd_dr16", RefreshRate=5, Window=Watched Data 1
WatchedExpression="rc_buffer", RefreshRate=5, Window=Watched Data 1
WatchedExpression="cmd", RefreshRate=5, Window=Watched Data 2
WatchedExpression="cmd_dr16", Window=Watched Data 2
WatchedExpression="dr16", RefreshRate=5, Window=Watched Data 2
WatchedExpression="gimbal", RefreshRate=5, Window=Watched Data 2
WatchedExpression="cmd", RefreshRate=5, Window=Watched Data 1
WatchedExpression="g_adapters", RefreshRate=5, Window=Watched Data 1
WatchedExpression="cmd_for_chassis", RefreshRate=5, Window=Watched Data 1
WatchedExpression="shoot_cmd", RefreshRate=5, Window=Watched Data 1
WatchedExpression="cmd_for_gimbal", RefreshRate=5, Window=Watched Data 1
WatchedExpression="last_shift", Window=Watched Data 1
WatchedExpression="now_shift", Window=Watched Data 1
WatchedExpression="last_v", Window=Watched Data 1
WatchedExpression="now_v", Window=Watched Data 1