diff --git a/User/module/cmd_v2/cmd.c b/User/module/cmd_v2/cmd.c index f64b596..74b3093 100644 --- a/User/module/cmd_v2/cmd.c +++ b/User/module/cmd_v2/cmd.c @@ -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) { diff --git a/User/module/cmd_v2/cmd.h b/User/module/cmd_v2/cmd.h index fbed0a2..c70c46f 100644 --- a/User/module/cmd_v2/cmd.h +++ b/User/module/cmd_v2/cmd.h @@ -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 diff --git a/User/module/cmd_v2/cmd_adapter.c b/User/module/cmd_v2/cmd_adapter.c index a529620..bc7986e 100644 --- a/User/module/cmd_v2/cmd_adapter.c +++ b/User/module/cmd_v2/cmd_adapter.c @@ -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; } diff --git a/User/module/cmd_v2/cmd_behavior.c b/User/module/cmd_v2/cmd_behavior.c index f174565..1b0773f 100644 --- a/User/module/cmd_v2/cmd_behavior.c +++ b/User/module/cmd_v2/cmd_behavior.c @@ -3,6 +3,7 @@ */ #include "cmd_behavior.h" #include "cmd.h" +#include "module/gimbal.h" #include /* ========================================================================== */ @@ -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(¤t->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; } diff --git a/User/module/cmd_v2/cmd_behavior.h b/User/module/cmd_v2/cmd_behavior.h index 049cb7e..fda9074 100644 --- a/User/module/cmd_v2/cmd_behavior.h +++ b/User/module/cmd_v2/cmd_behavior.h @@ -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; /* 处理函数 */ diff --git a/User/module/cmd_v2/cmd_types.h b/User/module/cmd_v2/cmd_types.h index c009c88..961ea29 100644 --- a/User/module/cmd_v2/cmd_types.h +++ b/User/module/cmd_v2/cmd_types.h @@ -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, diff --git a/User/module/config.c b/User/module/config.c index fcc0719..8b5baef 100644 --- a/User/module/config.c +++ b/User/module/config.c @@ -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, diff --git a/ozone/hero.jdebug b/ozone/hero.jdebug index 8338e09..9b4610d 100644 --- a/ozone/hero.jdebug +++ b/ozone/hero.jdebug @@ -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); + } } \ No newline at end of file diff --git a/ozone/hero.jdebug.user b/ozone/hero.jdebug.user index f3a8f50..e69cc88 100644 --- a/ozone/hero.jdebug.user +++ b/ozone/hero.jdebug.user @@ -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 \ No newline at end of file +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 \ No newline at end of file