Compare commits
No commits in common. "50bb9d8619eb3983b6e6c467aa5df9dd1e48456d" and "c17f41b2679efa20e3561db809af95ef1216de49" have entirely different histories.
50bb9d8619
...
c17f41b267
@ -41,7 +41,7 @@ add_subdirectory(cmake/stm32cubemx)
|
|||||||
target_link_directories(${CMAKE_PROJECT_NAME} PRIVATE
|
target_link_directories(${CMAKE_PROJECT_NAME} PRIVATE
|
||||||
# Add user defined library search paths
|
# Add user defined library search paths
|
||||||
)
|
)
|
||||||
file(GLOB SINGLE_CHAR_FILES "User/module/cmd_v2/*.c")
|
|
||||||
# Add sources to executable
|
# Add sources to executable
|
||||||
target_sources(${CMAKE_PROJECT_NAME} PRIVATE
|
target_sources(${CMAKE_PROJECT_NAME} PRIVATE
|
||||||
# Add user sources here
|
# Add user sources here
|
||||||
@ -77,7 +77,7 @@ target_sources(${CMAKE_PROJECT_NAME} PRIVATE
|
|||||||
User/module/config.c
|
User/module/config.c
|
||||||
User/module/gimbal.c
|
User/module/gimbal.c
|
||||||
User/module/shoot.c
|
User/module/shoot.c
|
||||||
${SINGLE_CHAR_FILES}
|
User/module/cmd.c
|
||||||
# User/task sources
|
# User/task sources
|
||||||
User/task/atti_esti.c
|
User/task/atti_esti.c
|
||||||
User/task/blink.c
|
User/task/blink.c
|
||||||
|
|||||||
@ -88,8 +88,9 @@ typedef struct{
|
|||||||
bool r_click; /* 右键 */
|
bool r_click; /* 右键 */
|
||||||
} mouse; /* 鼠标值 */
|
} mouse; /* 鼠标值 */
|
||||||
|
|
||||||
struct {
|
union {
|
||||||
bool key[DR16_KEY_NUM]; /* 键盘按键值 */
|
bool key[DR16_KEY_NUM]; /* 键盘按键值 */
|
||||||
|
uint16_t value; /* 键盘按键值的位映射 */
|
||||||
} keyboard;
|
} keyboard;
|
||||||
}DR16_DataPC_t;
|
}DR16_DataPC_t;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
@ -100,8 +100,9 @@ typedef struct {
|
|||||||
bool r_click; /* 右键 */
|
bool r_click; /* 右键 */
|
||||||
} mouse; /* 鼠标值 */
|
} mouse; /* 鼠标值 */
|
||||||
|
|
||||||
struct {
|
union {
|
||||||
bool key[VT13_KEY_NUM]; /* 键盘按键值 */
|
bool key[VT13_KEY_NUM]; /* 键盘按键值 */
|
||||||
|
uint16_t value; /* 键盘按键值的位映射 */
|
||||||
} keyboard;
|
} keyboard;
|
||||||
|
|
||||||
uint16_t res; /* 保留,未启用 */
|
uint16_t res; /* 保留,未启用 */
|
||||||
|
|||||||
703
User/module/cmd.c
Normal file
703
User/module/cmd.c
Normal file
@ -0,0 +1,703 @@
|
|||||||
|
/*
|
||||||
|
控制命令
|
||||||
|
*/
|
||||||
|
#include "module/cmd.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "bsp/time.h"
|
||||||
|
#include "module/gimbal.h"
|
||||||
|
|
||||||
|
/*************************************************************************************************************************************/
|
||||||
|
/****************************************************************RC*******************************************************************/
|
||||||
|
/*************************************************************************************************************************************/
|
||||||
|
/* Private macro ------------------------------------------------------------ */
|
||||||
|
/* 声明外部rc数据变量 */
|
||||||
|
#define CMDMACRO_EXTERNAL_RCDATA(name, NAME) extern NAME##_t name;
|
||||||
|
|
||||||
|
#define CMDMACRO_NAME_EXPANSION_1(name, NAME) name
|
||||||
|
/* 声明CMD结构体的RC数据变量 */
|
||||||
|
#define CMDMACRO_VAR_RCDATA(name, NAME) NAME##_DataRC_t name;
|
||||||
|
/* 宏生成Cmd_RC_Get函数内容 */
|
||||||
|
#define CMDMACRO_Cmd_RC_Get(name, NAME) \
|
||||||
|
c->input.rc.name= name.data.rc; \
|
||||||
|
c->input.rc.online=name.header.online; \
|
||||||
|
c->input.rc.type=CMD_RCTypeTable_Index;
|
||||||
|
|
||||||
|
CMD_RCType_TABLE(CMDMACRO_EXTERNAL_RCDATA)
|
||||||
|
/* Private typedef ---------------------------------------------------------- */
|
||||||
|
/* Private define ----------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Private variables -------------------------------------------------------- */
|
||||||
|
/*静态缓冲区*/
|
||||||
|
|
||||||
|
/* Private function -------------------------------------------------------- */
|
||||||
|
int8_t Cmd_RC_Get(CMD_t *c, CMD_RCType_TABLE(CMDMACRO_NAME_EXPANSION)){
|
||||||
|
// bool online= dr16->header.online;
|
||||||
|
// rc_buffer.dr16=dr16->data.rc;
|
||||||
|
// c->input.rc.online=online;
|
||||||
|
// c->input.rc.type=CMD_RCTypeTable_Index;
|
||||||
|
CMD_RCType_TABLE(CMDMACRO_Cmd_RC_Get);
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t Cmd_RC_BuildChassisCommandFromInput(CMD_t *c) {
|
||||||
|
if (c == NULL) {
|
||||||
|
return CMD_ERR_NULL; // 参数错误
|
||||||
|
}
|
||||||
|
#if CMD_RCTypeTable_Index == 0
|
||||||
|
switch (c->input.rc.dr16.sw_l) {
|
||||||
|
case DR16_SW_DOWN:
|
||||||
|
c->output.chassis.cmd.mode = CHASSIS_MODE_ROTOR;
|
||||||
|
break;
|
||||||
|
case DR16_SW_MID:
|
||||||
|
c->output.chassis.cmd.mode = CHASSIS_MODE_FOLLOW_GIMBAL;
|
||||||
|
break;
|
||||||
|
case DR16_SW_UP:
|
||||||
|
c->output.chassis.cmd.mode = CHASSIS_MODE_BREAK;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
c->output.chassis.cmd.mode = CHASSIS_MODE_RELAX;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
c->output.chassis.cmd.ctrl_vec.vx = c->input.rc.dr16.ch_r_x;
|
||||||
|
c->output.chassis.cmd.ctrl_vec.vy = c->input.rc.dr16.ch_r_y;
|
||||||
|
#elif CMD_RCTypeTable_Index == 1
|
||||||
|
switch (c->input.rc.data->at9s.key_E) {
|
||||||
|
case AT9S_CMD_SW_DOWN:
|
||||||
|
c->output.chassis.cmd.mode = CHASSIS_MODE_RELAX;
|
||||||
|
break;
|
||||||
|
case AT9S_CMD_SW_MID:
|
||||||
|
c->output.chassis.cmd.mode = CHASSIS_MODE_FOLLOW_GIMBAL;
|
||||||
|
break;
|
||||||
|
case AT9S_CMD_SW_UP:
|
||||||
|
c->output.chassis.cmd.mode = CHASSIS_MODE_ROTOR;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
c->output.chassis.cmd.mode = CHASSIS_MODE_RELAX;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
c->output.chassis.cmd.ctrl_vec.vx = c->input.rc.data->at9s.ch_r_x;
|
||||||
|
c->output.chassis.cmd.ctrl_vec.vy = c->input.rc.data->at9s.ch_r_y;
|
||||||
|
#endif
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t Cmd_RC_BuildGimbalCommandFromInput(CMD_t *c) {
|
||||||
|
if (c == NULL) {
|
||||||
|
return CMD_ERR_NULL; // 参数错误
|
||||||
|
}
|
||||||
|
#if CMD_RCTypeTable_Index == 0
|
||||||
|
switch (c->input.rc.dr16.sw_l) {
|
||||||
|
case DR16_SW_DOWN:
|
||||||
|
c->output.gimbal.cmd.mode = GIMBAL_MODE_RELATIVE;
|
||||||
|
c->output.gimbal.cmd.delta_yaw = -c->input.rc.dr16.ch_l_x * 2.0f;
|
||||||
|
c->output.gimbal.cmd.delta_pit = -c->input.rc.dr16.ch_l_y * 1.5f;
|
||||||
|
break;
|
||||||
|
case DR16_SW_MID:
|
||||||
|
c->output.gimbal.cmd.mode = GIMBAL_MODE_ABSOLUTE;
|
||||||
|
c->output.gimbal.cmd.delta_yaw = -c->input.rc.dr16.ch_l_x * 2.0f;
|
||||||
|
c->output.gimbal.cmd.delta_pit = -c->input.rc.dr16.ch_l_y * 1.5f;
|
||||||
|
break;
|
||||||
|
case DR16_SW_UP:
|
||||||
|
c->output.gimbal.cmd.mode = GIMBAL_MODE_ABSOLUTE;
|
||||||
|
c->output.gimbal.cmd.delta_yaw = -c->input.rc.dr16.ch_l_x * 2.0f;
|
||||||
|
c->output.gimbal.cmd.delta_pit = -c->input.rc.dr16.ch_l_y * 1.5f;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
c->output.gimbal.cmd.mode = GIMBAL_MODE_RELAX;
|
||||||
|
c->output.gimbal.cmd.delta_yaw = 0.0f;
|
||||||
|
c->output.gimbal.cmd.delta_pit = 0.0f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#elif CMD_RCTypeTable_Index == 1
|
||||||
|
switch (c->input.rc.data->at9s.key_G) {
|
||||||
|
case AT9S_CMD_SW_DOWN:
|
||||||
|
c->output.gimbal.cmd.mode = GIMBAL_MODE_RELAX;
|
||||||
|
c->output.gimbal.cmd.delta_yaw = 0.0f;
|
||||||
|
c->output.gimbal.cmd.delta_pit = 0.0f;
|
||||||
|
break;
|
||||||
|
case AT9S_CMD_SW_MID:
|
||||||
|
c->output.gimbal.cmd.mode = GIMBAL_MODE_ABSOLUTE;
|
||||||
|
c->output.gimbal.cmd.delta_yaw = -c->input.rc.data->at9s.ch_l_x * 2.0f;
|
||||||
|
c->output.gimbal.cmd.delta_pit = -c->input.rc.data->at9s.ch_l_y * 1.5f;
|
||||||
|
break;
|
||||||
|
case AT9S_CMD_SW_UP:
|
||||||
|
c->output.gimbal.cmd.mode = GIMBAL_MODE_ABSOLUTE;
|
||||||
|
c->output.gimbal.cmd.delta_yaw = -c->input.rc.data->at9s.ch_l_x * 2.0f;
|
||||||
|
c->output.gimbal.cmd.delta_pit = -c->input.rc.data->at9s.ch_l_y * 1.5f;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
c->output.gimbal.cmd.mode = GIMBAL_MODE_RELAX;
|
||||||
|
c->output.gimbal.cmd.delta_yaw = 0.0f;
|
||||||
|
c->output.gimbal.cmd.delta_pit = 0.0f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int8_t Cmd_RC_BuildShootCommandFromInput(CMD_t *c) {
|
||||||
|
if (c == NULL) {
|
||||||
|
return CMD_ERR_NULL; // 参数错误
|
||||||
|
}
|
||||||
|
#if CMD_RCTypeTable_Index == 0
|
||||||
|
if (c->input.rc.online) {
|
||||||
|
c->output.shoot.cmd.mode=SHOOT_MODE_SINGLE;
|
||||||
|
} else {
|
||||||
|
c->output.shoot.cmd.mode=SHOOT_MODE_SAFE;
|
||||||
|
}
|
||||||
|
switch (c->input.rc.dr16.sw_r) {
|
||||||
|
case DR16_SW_DOWN:
|
||||||
|
c->output.shoot.cmd.ready = true;
|
||||||
|
c->output.shoot.cmd.firecmd = true;
|
||||||
|
break;
|
||||||
|
case DR16_SW_MID:
|
||||||
|
c->output.shoot.cmd.ready = true;
|
||||||
|
c->output.shoot.cmd.firecmd = false;
|
||||||
|
break;
|
||||||
|
case DR16_SW_UP:
|
||||||
|
c->output.shoot.cmd.ready = false;
|
||||||
|
c->output.shoot.cmd.firecmd = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
c->output.shoot.cmd.ready = false;
|
||||||
|
c->output.shoot.cmd.firecmd = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#elif CMD_RCTypeTable_Index == 1
|
||||||
|
c->output.shoot.cmd.online = c->input.rc.online;
|
||||||
|
switch (c->input.rc.data->at9s.key_C) {
|
||||||
|
case AT9S_CMD_SW_DOWN:
|
||||||
|
c->output.shoot.cmd.ready = true;
|
||||||
|
c->output.shoot.cmd.firecmd = true;
|
||||||
|
break;
|
||||||
|
case AT9S_CMD_SW_MID:
|
||||||
|
c->output.shoot.cmd.ready = true;
|
||||||
|
c->output.shoot.cmd.firecmd = false;
|
||||||
|
break;
|
||||||
|
case AT9S_CMD_SW_UP:
|
||||||
|
c->output.shoot.cmd.ready = false;
|
||||||
|
c->output.shoot.cmd.firecmd = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
c->output.shoot.cmd.ready = false;
|
||||||
|
c->output.shoot.cmd.firecmd = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (c->input.rc.data->at9s.key_D) {
|
||||||
|
case AT9S_CMD_SW_DOWN:
|
||||||
|
c->output.shoot.cmd.mode=SHOOT_MODE_SINGLE;
|
||||||
|
break;
|
||||||
|
case AT9S_CMD_SW_UP:
|
||||||
|
c->output.shoot.cmd.mode=SHOOT_MODE_BURST;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
c->output.shoot.cmd.mode=SHOOT_MODE_SAFE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
/* Exported functions ------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************************************************************************/
|
||||||
|
/*****************************************************************PC******************************************************************/
|
||||||
|
/*************************************************************************************************************************************/
|
||||||
|
#ifndef CMD_NOPC_FLAG
|
||||||
|
/* Private macro ------------------------------------------------------------ */
|
||||||
|
#define CMD_PCBehavior_TABLE(X) \
|
||||||
|
X(FORE, CMD_MODULE_CHASSIS) \
|
||||||
|
X(BACK, CMD_MODULE_CHASSIS) \
|
||||||
|
X(LEFT, CMD_MODULE_CHASSIS) \
|
||||||
|
X(RIGHT, CMD_MODULE_CHASSIS) \
|
||||||
|
X(ACCELERATE, CMD_MODULE_CHASSIS) \
|
||||||
|
X(DECELEBRATE, CMD_MODULE_CHASSIS) \
|
||||||
|
X(FIRE, CMD_MODULE_SHOOT) \
|
||||||
|
X(FIRE_MODE, CMD_MODULE_SHOOT) \
|
||||||
|
X(BUFF, CMD_MODULE_SHOOT) \
|
||||||
|
X(AUTOAIM, CMD_MODULE_GIMBAL | CMD_MODULE_SHOOT) \
|
||||||
|
X(OPENCOVER, CMD_MODULE_SHOOT) \
|
||||||
|
X(ROTOR, CMD_MODULE_CHASSIS) \
|
||||||
|
X(REVTRIG, CMD_MODULE_SHOOT) \
|
||||||
|
X(FOLLOWGIMBAL35, CMD_MODULE_CHASSIS) \
|
||||||
|
X(GIMBAL_MODE, CMD_MODULE_GIMBAL)
|
||||||
|
|
||||||
|
/* 行为处理函数声明宏 */
|
||||||
|
#define CMDMACRO_FOR_DECLARE_BEHAVIOR_HANDLER_FUNCTION(BEHAVIOR, MODULE_MASK) \
|
||||||
|
static int8_t Cmd_PC_HandleBehavior##BEHAVIOR(CMD_t *c);
|
||||||
|
/* 行为处理函数指针数组构建宏 */
|
||||||
|
#define CMDMACRO_FOR_BUILD_BEHAVIOR_HANDLER_ARRAY(BEHAVIOR, MODULE_MASK) \
|
||||||
|
{CMD_BEHAVIOR_##BEHAVIOR, Cmd_PC_HandleBehavior##BEHAVIOR},
|
||||||
|
/* 行为模块映射表构建宏 */
|
||||||
|
#define CMDMACRO_FOR_BUILD_MODULE_TABLE(BEHAVIOR, MODULE_MASK) \
|
||||||
|
[CMD_BEHAVIOR_##BEHAVIOR] = MODULE_MASK,
|
||||||
|
/* 行为处理函数声明 */
|
||||||
|
CMD_PCBehavior_TABLE(CMDMACRO_FOR_DECLARE_BEHAVIOR_HANDLER_FUNCTION)
|
||||||
|
|
||||||
|
/* 宏展开函数内容 */
|
||||||
|
#define CMDMACRO_Cmd_PC_Get(name, NAME) \
|
||||||
|
c->input.pc.online=name.header.online;\
|
||||||
|
c->input.pc.name= name.data.pc;
|
||||||
|
#define CMDMACRO_PC_IsBehaviorTriggered(name, NAME) \
|
||||||
|
CMD_PCValue_t value = CMD_PC_BehaviorToValue(c, behavior); \
|
||||||
|
CMD_TriggerType_t active = CMD_PC_BehaviorToActive(c, behavior); \
|
||||||
|
bool now_key_pressed, last_key_pressed; \
|
||||||
|
/* 按下按键为鼠标左、右键 */ \
|
||||||
|
if (value == CMD_L_CLICK) { \
|
||||||
|
now_key_pressed = c->input.pc.name.mouse.l_click; \
|
||||||
|
last_key_pressed = c->input.pc.last##name.mouse.l_click; \
|
||||||
|
} else if (value == CMD_R_CLICK) { \
|
||||||
|
now_key_pressed = c->input.pc.name.mouse.r_click; \
|
||||||
|
last_key_pressed = c->input.pc.last##name.mouse.r_click; \
|
||||||
|
} else { \
|
||||||
|
now_key_pressed = c->input.pc.name.keyboard.key[value]; \
|
||||||
|
last_key_pressed = c->input.pc.last##name.keyboard.key[value]; \
|
||||||
|
} \
|
||||||
|
switch (active) { \
|
||||||
|
case CMD_ACTIVE_RISING_EDGE: \
|
||||||
|
return !now_key_pressed && last_key_pressed; \
|
||||||
|
case CMD_ACTIVE_FALLING_EDGE: \
|
||||||
|
return now_key_pressed && !last_key_pressed; \
|
||||||
|
case CMD_ACTIVE_PRESSED: \
|
||||||
|
return now_key_pressed; \
|
||||||
|
} \
|
||||||
|
return false;
|
||||||
|
#define CMDMACRO_PC_BuildChassisCommandFromInput(name, NAME) \
|
||||||
|
if (c->input.pc.online) {c->output.chassis.cmd.mode = CHASSIS_MODE_FOLLOW_GIMBAL;} \
|
||||||
|
else {c->output.chassis.cmd.mode = CHASSIS_MODE_RELAX;} \
|
||||||
|
c->output.chassis.cmd.ctrl_vec.vx = 0.0f; \
|
||||||
|
c->output.chassis.cmd.ctrl_vec.vy = 0.0f; \
|
||||||
|
for (size_t i = 0; i < CMD_BEHAVIOR_NUM; i++) { \
|
||||||
|
CMD_ModuleMask_t moduleMask = behaviorModuleTable[i]; \
|
||||||
|
if (CMD_PC_IsMaskMatch(c, moduleMask)) { \
|
||||||
|
if (CMD_PC_IsBehaviorTriggered(c, i)) { \
|
||||||
|
behaviorHandlerFuncTable[i].func(c); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
}\
|
||||||
|
return CMD_OK;
|
||||||
|
#define CMDMACRO_PC_BuildGimbalCommandFromInput(name, NAME) \
|
||||||
|
static bool init = false; \
|
||||||
|
if (!init) {c->output.gimbal.cmd.mode = GIMBAL_MODE_ABSOLUTE;init=!init;}\
|
||||||
|
if(!c->input.pc.online) {c->output.gimbal.cmd.mode = GIMBAL_MODE_RELAX;} \
|
||||||
|
c->output.gimbal.cmd.delta_yaw = (float)-c->input.pc.name.mouse.x * c->timer.dt * c->params->pc.sensitivity.sens_mouse; \
|
||||||
|
c->output.gimbal.cmd.delta_pit = (float)1.5f*c->input.pc.name.mouse.y * c->timer.dt * c->params->pc.sensitivity.sens_mouse; \
|
||||||
|
for (size_t i = 0; i < CMD_BEHAVIOR_NUM; i++) { \
|
||||||
|
CMD_ModuleMask_t moduleMask = behaviorModuleTable[i]; \
|
||||||
|
if (CMD_PC_IsMaskMatch(c, moduleMask)) { \
|
||||||
|
if (CMD_PC_IsBehaviorTriggered(c, i)) { \
|
||||||
|
behaviorHandlerFuncTable[i].func(c); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
}\
|
||||||
|
return CMD_OK;
|
||||||
|
#define CMDMACRO_PC_BuildShootCommandFromInput(name, NAME) \
|
||||||
|
if (!c->input.pc.online) {c->output.shoot.cmd.mode = SHOOT_MODE_SAFE;} \
|
||||||
|
c->output.shoot.cmd.ready = true; \
|
||||||
|
c->output.shoot.cmd.firecmd = false; \
|
||||||
|
for (size_t i = 0; i < CMD_BEHAVIOR_NUM; i++) { \
|
||||||
|
CMD_ModuleMask_t moduleMask = behaviorModuleTable[i]; \
|
||||||
|
if (CMD_PC_IsMaskMatch(c, moduleMask)) { \
|
||||||
|
if (CMD_PC_IsBehaviorTriggered(c, i)) { \
|
||||||
|
behaviorHandlerFuncTable[i].func(c); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
return CMD_OK;\
|
||||||
|
memcpy(c->input.pc.last##name.keyboard.key, c->input.pc.name.keyboard.key, sizeof(c->input.pc.name.keyboard.key)); \
|
||||||
|
c->input.pc.last##name.mouse.l_click = c->input.pc.name.mouse.l_click; \
|
||||||
|
c->input.pc.last##name.mouse.r_click = c->input.pc.name.mouse.r_click;
|
||||||
|
/* Private typedef ---------------------------------------------------------- */
|
||||||
|
typedef int8_t (*CMD_BehaviorFunc)(CMD_t *c);
|
||||||
|
typedef struct {
|
||||||
|
CMD_Behavior_t behavior;
|
||||||
|
CMD_BehaviorFunc func;
|
||||||
|
} CMD_BehaviorHandlerFunc_t;
|
||||||
|
|
||||||
|
/* Private variables -------------------------------------------------------- */
|
||||||
|
/* 行为处理函数指针数组 */
|
||||||
|
CMD_BehaviorHandlerFunc_t behaviorHandlerFuncTable[CMD_BEHAVIOR_NUM] = {
|
||||||
|
CMD_PCBehavior_TABLE(CMDMACRO_FOR_BUILD_BEHAVIOR_HANDLER_ARRAY)
|
||||||
|
};
|
||||||
|
/* 行为模块映射表 */
|
||||||
|
static const CMD_ModuleMask_t behaviorModuleTable[CMD_BEHAVIOR_NUM] = {
|
||||||
|
CMD_PCBehavior_TABLE(CMDMACRO_FOR_BUILD_MODULE_TABLE)
|
||||||
|
};
|
||||||
|
/* Private function -------------------------------------------------------- */
|
||||||
|
int8_t Cmd_PC_Get(CMD_t *c, CMD_RCType_TABLE(CMDMACRO_NAME_EXPANSION)){
|
||||||
|
CMD_RCType_TABLE(CMDMACRO_Cmd_PC_Get);
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int8_t Cmd_PC_HandleBehaviorFORE(CMD_t *c){
|
||||||
|
c->output.chassis.cmd.ctrl_vec.vy += c->params->pc.sensitivity.move_sense;
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
static int8_t Cmd_PC_HandleBehaviorBACK(CMD_t *c){
|
||||||
|
c->output.chassis.cmd.ctrl_vec.vy -= c->params->pc.sensitivity.move_sense;
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
static int8_t Cmd_PC_HandleBehaviorLEFT(CMD_t *c){
|
||||||
|
c->output.chassis.cmd.ctrl_vec.vx -= c->params->pc.sensitivity.move_sense;
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
static int8_t Cmd_PC_HandleBehaviorRIGHT(CMD_t *c){
|
||||||
|
c->output.chassis.cmd.ctrl_vec.vx += c->params->pc.sensitivity.move_sense;
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
static int8_t Cmd_PC_HandleBehaviorACCELERATE(CMD_t *c){
|
||||||
|
c->output.chassis.cmd.ctrl_vec.vx *= c->params->pc.sensitivity.move_fast_sense;
|
||||||
|
c->output.chassis.cmd.ctrl_vec.vy *= c->params->pc.sensitivity.move_fast_sense;
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
static int8_t Cmd_PC_HandleBehaviorDECELEBRATE(CMD_t *c){
|
||||||
|
c->output.chassis.cmd.ctrl_vec.vx *= c->params->pc.sensitivity.move_slow_sense;
|
||||||
|
c->output.chassis.cmd.ctrl_vec.vy *= c->params->pc.sensitivity.move_slow_sense;
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
static int8_t Cmd_PC_HandleBehaviorFIRE(CMD_t *c){
|
||||||
|
c->output.shoot.cmd.firecmd = true;
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
static int8_t Cmd_PC_HandleBehaviorFIRE_MODE(CMD_t *c){
|
||||||
|
c->output.shoot.cmd.mode++;
|
||||||
|
c->output.shoot.cmd.mode %= SHOOT_MODE_NUM;
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
static int8_t Cmd_PC_HandleBehaviorBUFF(CMD_t *c){
|
||||||
|
// if (cmd->ai_status == AI_STATUS_HITSWITCH) {
|
||||||
|
// CMD_RefereeAdd(&(cmd->referee), CMD_UI_HIT_SWITCH_STOP);
|
||||||
|
// cmd->host_overwrite = false;
|
||||||
|
// cmd->ai_status = AI_STATUS_STOP;
|
||||||
|
// } else if (cmd->ai_status == AI_STATUS_AUTOAIM) {
|
||||||
|
// // 自瞄模式中切换失败提醒
|
||||||
|
// } else {
|
||||||
|
// CMD_RefereeAdd(&(cmd->referee), CMD_UI_HIT_SWITCH_START);
|
||||||
|
// cmd->ai_status = AI_STATUS_HITSWITCH;
|
||||||
|
// cmd->host_overwrite = true;
|
||||||
|
// }
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
static int8_t Cmd_PC_HandleBehaviorAUTOAIM(CMD_t *c){
|
||||||
|
// if (cmd->ai_status == AI_STATUS_AUTOAIM) {
|
||||||
|
// cmd->host_overwrite = false;
|
||||||
|
// cmd->ai_status = AI_STATUS_STOP;
|
||||||
|
// CMD_RefereeAdd(&(cmd->referee), CMD_UI_AUTO_AIM_STOP);
|
||||||
|
// } else {
|
||||||
|
// cmd->ai_status = AI_STATUS_AUTOAIM;
|
||||||
|
// cmd->host_overwrite = true;
|
||||||
|
// CMD_RefereeAdd(&(cmd->referee), CMD_UI_AUTO_AIM_START);
|
||||||
|
// }
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
static int8_t Cmd_PC_HandleBehaviorOPENCOVER(CMD_t *c){
|
||||||
|
// c->shoot.cover_open = !c->shoot.cover_open;
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
static int8_t Cmd_PC_HandleBehaviorROTOR(CMD_t *c){
|
||||||
|
c->output.chassis.cmd.mode = CHASSIS_MODE_ROTOR;
|
||||||
|
c->output.chassis.cmd.mode_rotor = ROTOR_MODE_RAND;
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
static int8_t Cmd_PC_HandleBehaviorREVTRIG(CMD_t *c){
|
||||||
|
// c->output.shoot.cmd.reverse_trig = true;
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
static int8_t Cmd_PC_HandleBehaviorFOLLOWGIMBAL35(CMD_t *c){
|
||||||
|
c->output.chassis.cmd.mode = CHASSIS_MODE_FOLLOW_GIMBAL_35;
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
static int8_t Cmd_PC_HandleBehaviorGIMBAL_MODE(CMD_t *c){
|
||||||
|
|
||||||
|
c->output.gimbal.cmd.mode++;
|
||||||
|
c->output.gimbal.cmd.mode %= GIMBAL_MODE_NUM;
|
||||||
|
while (c->output.gimbal.cmd.mode<=0) {c->output.gimbal.cmd.mode++;}
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline CMD_PCValue_t CMD_PC_BehaviorToValue(CMD_t *c,
|
||||||
|
CMD_Behavior_t behavior) {
|
||||||
|
return c->params->pc.map.key_map[behavior].key;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline CMD_TriggerType_t CMD_PC_BehaviorToActive(CMD_t *c,
|
||||||
|
CMD_Behavior_t behavior) {
|
||||||
|
return c->params->pc.map.key_map[behavior].trigger_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool CMD_PC_IsMaskMatch(CMD_t *c, CMD_ModuleMask_t module_mask) {
|
||||||
|
/* 构建当前各模块输入源状态的掩码 */
|
||||||
|
CMD_ModuleMask_t current_pc_mask = 0;
|
||||||
|
if (c->output.chassis.source == CMD_SRC_PC) current_pc_mask |= CMD_MODULE_CHASSIS;
|
||||||
|
if (c->output.gimbal.source == CMD_SRC_PC) current_pc_mask |= CMD_MODULE_GIMBAL;
|
||||||
|
if (c->output.shoot.source == CMD_SRC_PC) current_pc_mask |= CMD_MODULE_SHOOT;
|
||||||
|
|
||||||
|
/* 检测并集 */
|
||||||
|
return (module_mask & current_pc_mask) == module_mask;
|
||||||
|
/* 检测交集 */
|
||||||
|
// return (module_mask & current_pc_mask) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool CMD_PC_IsBehaviorTriggered(CMD_t *c, CMD_Behavior_t behavior) {
|
||||||
|
if (c == NULL) {
|
||||||
|
return CMD_ERR_NULL; // 参数错误
|
||||||
|
}
|
||||||
|
CMD_RCType_TABLE(CMDMACRO_PC_IsBehaviorTriggered);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int8_t Cmd_PC_BuildChassisCommandFromInput(CMD_t *c) {
|
||||||
|
if (c == NULL) {
|
||||||
|
return CMD_ERR_NULL; // 参数错误
|
||||||
|
}
|
||||||
|
CMD_RCType_TABLE(CMDMACRO_PC_BuildChassisCommandFromInput);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int8_t Cmd_PC_BuildGimbalCommandFromInput(CMD_t *c) {
|
||||||
|
if (c == NULL) {
|
||||||
|
return CMD_ERR_NULL; // 参数错误
|
||||||
|
}
|
||||||
|
CMD_RCType_TABLE(CMDMACRO_PC_BuildGimbalCommandFromInput);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int8_t Cmd_PC_BuildShootCommandFromInput(CMD_t *c) {
|
||||||
|
if (c == NULL) {
|
||||||
|
return CMD_ERR_NULL; // 参数错误
|
||||||
|
}
|
||||||
|
CMD_RCType_TABLE(CMDMACRO_PC_BuildShootCommandFromInput);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static int8_t Cmd_PC_Get(CMD_Input_PC_t *pc) {
|
||||||
|
pc->online=false;
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
static int8_t Cmd_PC_BuildChassisCommandFromInput(CMD_t *c) {
|
||||||
|
if (c == NULL) {
|
||||||
|
return CMD_ERR_NULL; // 参数错误
|
||||||
|
}
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
static int8_t Cmd_PC_BuildGimbalCommandFromInput(CMD_t *c) {
|
||||||
|
if (c == NULL) {
|
||||||
|
return CMD_ERR_NULL; // 参数错误
|
||||||
|
}
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
static int8_t Cmd_PC_BuildShootCommandFromInput(CMD_t *c) {
|
||||||
|
if (c == NULL) {
|
||||||
|
return CMD_ERR_NULL; // 参数错误
|
||||||
|
}
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*************************************************************************************************************************************/
|
||||||
|
/****************************************************************NUC******************************************************************/
|
||||||
|
/*************************************************************************************************************************************/
|
||||||
|
|
||||||
|
/* Includes ----------------------------------------------------------------- */
|
||||||
|
/* Private typedef ---------------------------------------------------------- */
|
||||||
|
/* Private define ----------------------------------------------------------- */
|
||||||
|
/* Private macro ------------------------------------------------------------ */
|
||||||
|
/* Private variables -------------------------------------------------------- */
|
||||||
|
/* Private function -------------------------------------------------------- */
|
||||||
|
int8_t Cmd_NUC_Get(CMD_Input_NUC_t *nuc) {
|
||||||
|
nuc->online=0;
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
/* Exported functions ------------------------------------------------------- */
|
||||||
|
|
||||||
|
int8_t Cmd_NUC_BuildChassisCommandFromInput(CMD_t *c) {
|
||||||
|
if (c == NULL) {
|
||||||
|
return CMD_ERR_NULL; // 参数错误
|
||||||
|
}
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t Cmd_NUC_BuildGimbalCommandFromInput(CMD_t *c) {
|
||||||
|
if (c == NULL) {
|
||||||
|
return CMD_ERR_NULL; // 参数错误
|
||||||
|
}
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
int8_t Cmd_NUC_BuildShootCommandFromInput(CMD_t *c) {
|
||||||
|
if (c == NULL) {
|
||||||
|
return CMD_ERR_NULL; // 参数错误
|
||||||
|
}
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************************************************************************/
|
||||||
|
/***************************************************************REF*******************************************************************/
|
||||||
|
/*************************************************************************************************************************************/
|
||||||
|
|
||||||
|
/* Includes ----------------------------------------------------------------- */
|
||||||
|
/* Private typedef ---------------------------------------------------------- */
|
||||||
|
/* Private define ----------------------------------------------------------- */
|
||||||
|
/* Private macro ------------------------------------------------------------ */
|
||||||
|
/* Private variables -------------------------------------------------------- */
|
||||||
|
/* Private function -------------------------------------------------------- */
|
||||||
|
int8_t Cmd_REF_Get(CMD_Input_REF_t *nuc) {
|
||||||
|
nuc->online=0;
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
/* Exported functions ------------------------------------------------------- */
|
||||||
|
|
||||||
|
int8_t Cmd_REF_BuildChassisCommandFromInput(CMD_t *c) {
|
||||||
|
if (c == NULL) {
|
||||||
|
return CMD_ERR_NULL; // 参数错误
|
||||||
|
}
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t Cmd_REF_BuildGimbalCommandFromInput(CMD_t *c) {
|
||||||
|
if (c == NULL) {
|
||||||
|
return CMD_ERR_NULL; // 参数错误
|
||||||
|
}
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
int8_t Cmd_REF_BuildShootCommandFromInput(CMD_t *c) {
|
||||||
|
if (c == NULL) {
|
||||||
|
return CMD_ERR_NULL; // 参数错误
|
||||||
|
}
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
/*************************************************************************************************************************************/
|
||||||
|
/***************************************************************仲裁器****************************************************************/
|
||||||
|
/*************************************************************************************************************************************/
|
||||||
|
|
||||||
|
/* Includes ----------------------------------------------------------------- */
|
||||||
|
/* Private typedef ---------------------------------------------------------- */
|
||||||
|
/* Private define ----------------------------------------------------------- */
|
||||||
|
/* Private macro ------------------------------------------------------------ */
|
||||||
|
/* Private variables -------------------------------------------------------- */
|
||||||
|
/* Private function -------------------------------------------------------- */
|
||||||
|
static inline bool Cmd_isREFOnline(CMD_t *c){return c->input.ref.online;}
|
||||||
|
static inline bool Cmd_isNUCOnline(CMD_t *c){return c->input.nuc.online;}
|
||||||
|
static inline bool Cmd_isRCOnline(CMD_t *c){return c->input.rc.online;}
|
||||||
|
static inline bool Cmd_isPCOnline(CMD_t *c){return c->input.pc.online;}
|
||||||
|
CMD_InputSource_t Cmd_GetHighestPrioritySource(CMD_t *c) {
|
||||||
|
for (int i = 0; i < CMD_SRC_NUM; i++) {
|
||||||
|
CMD_InputSource_t source = c->params->sourcePriorityConfigs[i];
|
||||||
|
switch (source) {
|
||||||
|
case CMD_SRC_REF:
|
||||||
|
if (Cmd_isREFOnline(c)) {
|
||||||
|
return CMD_SRC_REF;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CMD_SRC_NUC:
|
||||||
|
if (Cmd_isNUCOnline(c)) {
|
||||||
|
return CMD_SRC_NUC;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CMD_SRC_RC:
|
||||||
|
if (Cmd_isRCOnline(c)) {
|
||||||
|
return CMD_SRC_RC;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CMD_SRC_PC:
|
||||||
|
if (Cmd_isPCOnline(c)) {
|
||||||
|
return CMD_SRC_PC;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CMD_SRC_NUM:
|
||||||
|
return CMD_ERR_SOURCE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CMD_ERR_SOURCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t Cmd_Arbiter(CMD_t *c) {
|
||||||
|
if (c == NULL) {
|
||||||
|
return CMD_ERR_NULL; // 参数错误
|
||||||
|
}
|
||||||
|
CMD_InputSource_t source = Cmd_GetHighestPrioritySource(c);
|
||||||
|
c->output.chassis.source = source;
|
||||||
|
c->output.gimbal.source = source;
|
||||||
|
c->output.shoot.source = source;
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t Cmd_Switch_RCorPC(CMD_t *c) {
|
||||||
|
if (c == NULL) {
|
||||||
|
return CMD_ERR_NULL; // 参数错误
|
||||||
|
}
|
||||||
|
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************************************************************************/
|
||||||
|
/***************************************************************主结构*****************************************************************/
|
||||||
|
/*************************************************************************************************************************************/
|
||||||
|
|
||||||
|
/* Includes ----------------------------------------------------------------- */
|
||||||
|
/* Private typedef ---------------------------------------------------------- */
|
||||||
|
typedef int8_t (*CMD_BuildCommandFunc)(CMD_t *c);
|
||||||
|
typedef struct {
|
||||||
|
CMD_InputSource_t source;
|
||||||
|
CMD_BuildCommandFunc chassisFunc;
|
||||||
|
CMD_BuildCommandFunc gimbalFunc;
|
||||||
|
CMD_BuildCommandFunc shootFunc;
|
||||||
|
} CMD_SourceHandler_t;
|
||||||
|
/* Private macro ------------------------------------------------------------ */
|
||||||
|
/* Private variables -------------------------------------------------------- */
|
||||||
|
CMD_SourceHandler_t sourceHandlers[CMD_SRC_NUM] = {
|
||||||
|
{CMD_SRC_RC, Cmd_RC_BuildChassisCommandFromInput, Cmd_RC_BuildGimbalCommandFromInput, Cmd_RC_BuildShootCommandFromInput},
|
||||||
|
{CMD_SRC_PC, Cmd_PC_BuildChassisCommandFromInput, Cmd_PC_BuildGimbalCommandFromInput, Cmd_PC_BuildShootCommandFromInput},
|
||||||
|
{CMD_SRC_NUC, Cmd_NUC_BuildChassisCommandFromInput, Cmd_NUC_BuildGimbalCommandFromInput, Cmd_NUC_BuildShootCommandFromInput},
|
||||||
|
{CMD_SRC_REF, Cmd_REF_BuildChassisCommandFromInput, Cmd_REF_BuildGimbalCommandFromInput, Cmd_REF_BuildShootCommandFromInput},
|
||||||
|
};
|
||||||
|
/* Private function -------------------------------------------------------- */
|
||||||
|
int8_t Cmd_OFFLINE(CMD_t *c) {
|
||||||
|
if (c == NULL) {
|
||||||
|
return CMD_ERR_NULL; // 参数错误
|
||||||
|
}
|
||||||
|
c->output.chassis.cmd.mode =CHASSIS_MODE_RELAX;
|
||||||
|
c->output.gimbal.cmd.mode =GIMBAL_MODE_RELAX;
|
||||||
|
c->output.shoot.cmd.mode =SHOOT_MODE_SAFE;
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
/* Exported functions ------------------------------------------------------- */
|
||||||
|
int8_t Cmd_Init(CMD_t *c, CMD_Params_t *params) {
|
||||||
|
if (c == NULL || params == NULL) {
|
||||||
|
return CMD_ERR_NULL; // 参数错误
|
||||||
|
}
|
||||||
|
c->params = params;
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t Cmd_Get(CMD_t *c,
|
||||||
|
CMD_RCType_TABLE(CMDMACRO_NAME_EXPANSION)){
|
||||||
|
// CMD_Input_NUC_t *nuc,
|
||||||
|
// CMD_Input_REF_t *ref) {
|
||||||
|
if (c == NULL) {
|
||||||
|
return CMD_ERR_NULL; // 参数错误
|
||||||
|
}
|
||||||
|
Cmd_RC_Get(c,CMD_RCType_TABLE(CMDMACRO_NAME_EXPANSION_1));
|
||||||
|
Cmd_PC_Get(c,CMD_RCType_TABLE(CMDMACRO_NAME_EXPANSION_1));
|
||||||
|
// Cmd_NUC_Get(&c->input.nuc);
|
||||||
|
// Cmd_REF_Get(&c->input.ref);
|
||||||
|
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t Cmd_GenerateCommand(CMD_t *c) {
|
||||||
|
if (c == NULL) {
|
||||||
|
return CMD_ERR_NULL; // 参数错误
|
||||||
|
}
|
||||||
|
Cmd_Arbiter(c);
|
||||||
|
|
||||||
|
c->timer.now =BSP_TIME_Get_us() / 1000000.0f;
|
||||||
|
c->timer.dt =(BSP_TIME_Get_us() - c->timer.last) / 1000000.0f;
|
||||||
|
c->timer.last =BSP_TIME_Get_us();
|
||||||
|
if (c->output.chassis.source >= CMD_SRC_NUM || c->output.gimbal.source >= CMD_SRC_NUM || c->output.shoot.source >= CMD_SRC_NUM) {
|
||||||
|
Cmd_OFFLINE(c);
|
||||||
|
return CMD_ERR_SOURCE; // 输入源错误
|
||||||
|
}
|
||||||
|
sourceHandlers[c->output.chassis.source].chassisFunc(c);
|
||||||
|
sourceHandlers[c->output.gimbal.source].gimbalFunc(c);
|
||||||
|
sourceHandlers[c->output.shoot.source].shootFunc(c);
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
236
User/module/cmd.h
Normal file
236
User/module/cmd.h
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
/*
|
||||||
|
控制命令
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/* Includes ----------------------------------------------------------------- */
|
||||||
|
#include "module/chassis.h"
|
||||||
|
#include "module/gimbal.h"
|
||||||
|
#include "module/shoot.h"
|
||||||
|
#if CMD_RCTypeTable_Index == 0
|
||||||
|
#include "device/dr16.h"
|
||||||
|
#elif CMD_RCTypeTable_Index == 1
|
||||||
|
#include "device/at9s_pro.h"
|
||||||
|
#elif CMD_RCTypeTable_Index == 2
|
||||||
|
#include "device/vt13.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Exported constants ------------------------------------------------------- */
|
||||||
|
#define CMD_OK (0) /* 运行正常 */
|
||||||
|
#define CMD_ERR_NULL (-1) /* 运行时发现NULL指针 */
|
||||||
|
#define CMD_ERR_ERR (-2) /* 运行时发现了其他错误 */
|
||||||
|
#define CMD_ERR_SOURCE (-3) /* 运行时配置了不存在的输入源 */
|
||||||
|
|
||||||
|
/* Exported macro ----------------------------------------------------------- */
|
||||||
|
#define CMD_RCTypeTable_Index 0 /* 0:DR16 1:AT9S 2:VT13 */
|
||||||
|
|
||||||
|
#if CMD_RCTypeTable_Index == 0
|
||||||
|
#define CMD_RCType_TABLE(X) X(dr16, DR16)
|
||||||
|
#elif CMD_RCTypeTable_Index == 1
|
||||||
|
#define CMD_RCType_TABLE(X) X(at9s, AT9S)
|
||||||
|
#elif CMD_RCTypeTable_Index == 2
|
||||||
|
#define CMD_RCType_TABLE(X) X(vt13, VT13)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CMD_RCTypeTable_Index == 1
|
||||||
|
#define CMD_NOPC_FLAG
|
||||||
|
#endif
|
||||||
|
#define CMDMACRO_NAME_EXPANSION(name, NAME) NAME##_t name
|
||||||
|
#define CMDMACRO_VAR_RCDATA(name, NAME) NAME##_DataRC_t name;
|
||||||
|
#define CMDMACRO_VAR_PCDATA(name, NAME) NAME##_DataPC_t name;
|
||||||
|
#define CMDMACRO_VAR_LASTPCDATA(name, NAME) NAME##_DataPC_t last##name;
|
||||||
|
/* Exported types ----------------------------------------------------------- */
|
||||||
|
#define CMD_REFEREE_MAX_NUM (3) /* 发送命令限定的最大数量 */
|
||||||
|
/* 输入源枚举 */
|
||||||
|
typedef enum {
|
||||||
|
CMD_SRC_RC=0, /* 遥控器 */
|
||||||
|
CMD_SRC_PC, /* 键盘鼠标 */
|
||||||
|
CMD_SRC_NUC, /* 上位机 */
|
||||||
|
CMD_SRC_REF, /* 裁判系统 */
|
||||||
|
CMD_SRC_NUM
|
||||||
|
} CMD_InputSource_t;
|
||||||
|
|
||||||
|
/* RC part begin-------------------------------------- */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool online;
|
||||||
|
enum {DR16=0, AT9S} type;
|
||||||
|
CMD_RCType_TABLE(CMDMACRO_VAR_RCDATA)
|
||||||
|
#undef CMDMACRO_VAR_RCDATA
|
||||||
|
} CMD_Input_RC_t;//或者这里直接把CMD_Input_RC_t前向声明了,看哪个好看
|
||||||
|
|
||||||
|
/* RC part end---------------------------------------- */
|
||||||
|
|
||||||
|
/* PC part begin-------------------------------------- */
|
||||||
|
typedef enum {
|
||||||
|
CMD_MODULE_NONE = 0,
|
||||||
|
CMD_MODULE_CHASSIS = (1 << 0),
|
||||||
|
CMD_MODULE_GIMBAL = (1 << 1),
|
||||||
|
CMD_MODULE_SHOOT = (1 << 2),
|
||||||
|
CMD_MODULE_ALL = (CMD_MODULE_CHASSIS | CMD_MODULE_GIMBAL | CMD_MODULE_SHOOT)
|
||||||
|
} CMD_ModuleMask_t;
|
||||||
|
/* 键盘按键值 */
|
||||||
|
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_L_CLICK,
|
||||||
|
CMD_R_CLICK,
|
||||||
|
CMD_M_CLICK,
|
||||||
|
CMD_KEY_NUM,
|
||||||
|
} CMD_PCValue_t;
|
||||||
|
typedef enum {
|
||||||
|
CMD_ACTIVE_RISING_EDGE, /* 按下时触发 */
|
||||||
|
CMD_ACTIVE_FALLING_EDGE, /* 抬起时触发 */
|
||||||
|
CMD_ACTIVE_PRESSED, /* 按住时触发 */
|
||||||
|
} CMD_TriggerType_t;
|
||||||
|
|
||||||
|
/* 行为值序列 */
|
||||||
|
typedef enum {
|
||||||
|
CMD_BEHAVIOR_FORE = 0, /* 向前 */
|
||||||
|
CMD_BEHAVIOR_BACK, /* 向后 */
|
||||||
|
CMD_BEHAVIOR_LEFT, /* 向左 */
|
||||||
|
CMD_BEHAVIOR_RIGHT, /* 向右 */
|
||||||
|
CMD_BEHAVIOR_ACCELERATE, /* 加速 */
|
||||||
|
CMD_BEHAVIOR_DECELEBRATE, /* 减速 */
|
||||||
|
CMD_BEHAVIOR_FIRE, /* 开火 */
|
||||||
|
CMD_BEHAVIOR_FIRE_MODE, /* 切换开火模式 */
|
||||||
|
CMD_BEHAVIOR_BUFF, /* 打符模式 */
|
||||||
|
CMD_BEHAVIOR_AUTOAIM, /* 自瞄模式 */
|
||||||
|
CMD_BEHAVIOR_OPENCOVER, /* 弹舱盖开关 */
|
||||||
|
CMD_BEHAVIOR_ROTOR, /* 小陀螺模式 */
|
||||||
|
CMD_BEHAVIOR_REVTRIG, /* 反转拨弹 */
|
||||||
|
CMD_BEHAVIOR_FOLLOWGIMBAL35, /* 跟随云台呈35度 */
|
||||||
|
CMD_BEHAVIOR_GIMBAL_MODE, /* 切换云台模式 */
|
||||||
|
CMD_BEHAVIOR_NUM,
|
||||||
|
} CMD_Behavior_t;
|
||||||
|
typedef struct {
|
||||||
|
CMD_PCValue_t key;
|
||||||
|
CMD_TriggerType_t trigger_type;
|
||||||
|
} CMD_KeyMapItem_t;
|
||||||
|
|
||||||
|
/* 行为映射的对应按键数组 */
|
||||||
|
typedef struct {
|
||||||
|
CMD_KeyMapItem_t key_map[CMD_BEHAVIOR_NUM];
|
||||||
|
} CMD_KeyMap_Params_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float sens_mouse; /* 鼠标灵敏度 */
|
||||||
|
float move_sense; /* 移动灵敏度 */
|
||||||
|
float move_fast_sense; /* 快速移动灵敏度 */
|
||||||
|
float move_slow_sense; /* 慢速移动灵敏度 */
|
||||||
|
} CMD_PC_Sensitivity_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
CMD_KeyMap_Params_t map; /* 按键映射行为命令 */
|
||||||
|
CMD_PC_Sensitivity_t sensitivity; /* PC灵敏度设置 */
|
||||||
|
}CMD_PCParams_t;
|
||||||
|
#ifndef CMD_NOPC_FLAG
|
||||||
|
typedef struct {
|
||||||
|
bool online;
|
||||||
|
CMD_RCType_TABLE(CMDMACRO_VAR_PCDATA)
|
||||||
|
CMD_RCType_TABLE(CMDMACRO_VAR_LASTPCDATA)
|
||||||
|
#undef CMDMACRO_VAR_PCDATA
|
||||||
|
#undef CMDMACRO_VAR_LASTPCDATA
|
||||||
|
}CMD_Input_PC_t;
|
||||||
|
#else
|
||||||
|
typedef struct {
|
||||||
|
bool online;
|
||||||
|
}CMD_Input_PC_t;
|
||||||
|
#endif
|
||||||
|
/* PC part end---------------------------------------- */
|
||||||
|
|
||||||
|
/* NUC part begin------------------------------------- */
|
||||||
|
typedef struct {
|
||||||
|
bool online;
|
||||||
|
struct {
|
||||||
|
float delta_yaw;
|
||||||
|
float delta_pit;
|
||||||
|
}gimbal;
|
||||||
|
struct {
|
||||||
|
float expectedSpeed;
|
||||||
|
bool fire;
|
||||||
|
}shoot;
|
||||||
|
}CMD_Input_NUC_t;
|
||||||
|
|
||||||
|
/* NUC part end--------------------------------------- */
|
||||||
|
|
||||||
|
/* REF part begin------------------------------------- */
|
||||||
|
typedef struct {
|
||||||
|
bool online;
|
||||||
|
}CMD_Input_REF_t;
|
||||||
|
|
||||||
|
/* REF part begin------------------------------------- */
|
||||||
|
|
||||||
|
/* 底盘控制命令 */
|
||||||
|
typedef struct {
|
||||||
|
CMD_InputSource_t source;
|
||||||
|
Chassis_CMD_t cmd;
|
||||||
|
} CMD_Output_CHASSIS_t;
|
||||||
|
|
||||||
|
/* 云台控制命令 */
|
||||||
|
typedef struct {
|
||||||
|
CMD_InputSource_t source;
|
||||||
|
Gimbal_CMD_t cmd;
|
||||||
|
} CMD_Output_GIMBAL_t;
|
||||||
|
|
||||||
|
/* 射击控制命令 */
|
||||||
|
typedef struct {
|
||||||
|
CMD_InputSource_t source;
|
||||||
|
Shoot_CMD_t cmd;
|
||||||
|
} CMD_Output_SHOOT_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
CMD_Input_RC_t rc;
|
||||||
|
CMD_Input_PC_t pc;
|
||||||
|
CMD_Input_NUC_t nuc;
|
||||||
|
CMD_Input_REF_t ref;
|
||||||
|
} CMD_Input_t;
|
||||||
|
typedef struct {
|
||||||
|
CMD_Output_CHASSIS_t chassis;
|
||||||
|
CMD_Output_GIMBAL_t gimbal;
|
||||||
|
CMD_Output_SHOOT_t shoot;
|
||||||
|
} CMD_Output_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
CMD_InputSource_t sourcePriorityConfigs[CMD_SRC_NUM];/* 输入源优先级配置 */
|
||||||
|
CMD_PCParams_t pc;
|
||||||
|
} CMD_Params_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float now;
|
||||||
|
float dt;
|
||||||
|
uint64_t last;
|
||||||
|
} CMD_Timer_t;
|
||||||
|
typedef struct {
|
||||||
|
CMD_Timer_t timer;
|
||||||
|
CMD_Params_t *params;
|
||||||
|
|
||||||
|
CMD_Input_t input;
|
||||||
|
CMD_Output_t output;
|
||||||
|
} CMD_t;
|
||||||
|
|
||||||
|
/* Exported functions prototypes -------------------------------------------- */
|
||||||
|
int8_t Cmd_Init(CMD_t *c, CMD_Params_t *params);
|
||||||
|
int8_t Cmd_Get(CMD_t *c, CMD_RCType_TABLE(CMDMACRO_NAME_EXPANSION));
|
||||||
|
int8_t Cmd_GenerateCommand(CMD_t *c);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@ -11,145 +11,164 @@
|
|||||||
/* ========================================================================== */
|
/* ========================================================================== */
|
||||||
|
|
||||||
/* 从RC输入生成底盘命令 */
|
/* 从RC输入生成底盘命令 */
|
||||||
static void CMD_RC_BuildChassisCmd(CMD_t *ctx) {
|
static void CMD_RC_BuildChassisCmd(CMD_Context_t *ctx, const CMD_RawInput_t *input) {
|
||||||
CMD_RCModeMap_t *map = &ctx->config->rc_mode_map;
|
CMD_RCModeMap_t *map = &ctx->config->rc_mode_map;
|
||||||
|
|
||||||
/* 根据左拨杆位置选择模式 */
|
/* 根据左拨杆位置选择模式 */
|
||||||
switch (ctx->input.rc.sw[0]) {
|
switch (input->sw[0]) {
|
||||||
case CMD_SW_UP:
|
case CMD_SW_UP:
|
||||||
ctx->output.chassis.cmd.mode = map->sw_left_up;
|
ctx->chassis.cmd.mode = map->sw_left_up;
|
||||||
break;
|
break;
|
||||||
case CMD_SW_MID:
|
case CMD_SW_MID:
|
||||||
ctx->output.chassis.cmd.mode = map->sw_left_mid;
|
ctx->chassis.cmd.mode = map->sw_left_mid;
|
||||||
break;
|
break;
|
||||||
case CMD_SW_DOWN:
|
case CMD_SW_DOWN:
|
||||||
ctx->output.chassis.cmd.mode = map->sw_left_down;
|
ctx->chassis.cmd.mode = map->sw_left_down;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ctx->output.chassis.cmd.mode = CHASSIS_MODE_RELAX;
|
ctx->chassis.cmd.mode = CHASSIS_MODE_RELAX;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 摇杆控制移动 */
|
/* 摇杆控制移动 */
|
||||||
ctx->output.chassis.cmd.ctrl_vec.vx = ctx->input.rc.joy_right.x;
|
ctx->chassis.cmd.ctrl_vec.vx = input->joy_right.x;
|
||||||
ctx->output.chassis.cmd.ctrl_vec.vy = ctx->input.rc.joy_right.y;
|
ctx->chassis.cmd.ctrl_vec.vy = input->joy_right.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 从RC输入生成云台命令 */
|
/* 从RC输入生成云台命令 */
|
||||||
static void CMD_RC_BuildGimbalCmd(CMD_t *ctx) {
|
static void CMD_RC_BuildGimbalCmd(CMD_Context_t *ctx, const CMD_RawInput_t *input) {
|
||||||
CMD_RCModeMap_t *map = &ctx->config->rc_mode_map;
|
CMD_RCModeMap_t *map = &ctx->config->rc_mode_map;
|
||||||
|
|
||||||
/* 根据拨杆选择云台模式 */
|
/* 根据拨杆选择云台模式 */
|
||||||
switch (ctx->input.rc.sw[0]) {
|
switch (input->sw[0]) {
|
||||||
case CMD_SW_UP:
|
case CMD_SW_UP:
|
||||||
ctx->output.gimbal.cmd.mode = map->gimbal_sw_up;
|
ctx->gimbal.cmd.mode = map->gimbal_sw_up;
|
||||||
break;
|
break;
|
||||||
case CMD_SW_MID:
|
case CMD_SW_MID:
|
||||||
ctx->output.gimbal.cmd.mode = map->gimbal_sw_mid;
|
ctx->gimbal.cmd.mode = map->gimbal_sw_mid;
|
||||||
break;
|
break;
|
||||||
case CMD_SW_DOWN:
|
case CMD_SW_DOWN:
|
||||||
ctx->output.gimbal.cmd.mode = map->gimbal_sw_down;
|
ctx->gimbal.cmd.mode = map->gimbal_sw_down;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ctx->output.gimbal.cmd.mode = GIMBAL_MODE_RELAX;
|
ctx->gimbal.cmd.mode = GIMBAL_MODE_RELAX;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 左摇杆控制云台 */
|
/* 左摇杆控制云台 */
|
||||||
ctx->output.gimbal.cmd.delta_yaw = -ctx->input.rc.joy_left.x * 2.0f;
|
ctx->gimbal.cmd.delta_yaw = -input->joy_left.x * 2.0f;
|
||||||
ctx->output.gimbal.cmd.delta_pit = -ctx->input.rc.joy_left.y * 1.5f;
|
ctx->gimbal.cmd.delta_pit = -input->joy_left.y * 1.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 从RC输入生成射击命令 */
|
/* 从RC输入生成射击命令 */
|
||||||
static void CMD_RC_BuildShootCmd(CMD_t *ctx) {
|
static void CMD_RC_BuildShootCmd(CMD_Context_t *ctx, const CMD_RawInput_t *input) {
|
||||||
if (ctx->input.online[CMD_SRC_RC]) {
|
if (input->online) {
|
||||||
ctx->output.shoot.cmd.mode = SHOOT_MODE_SINGLE;
|
ctx->shoot.cmd.mode = SHOOT_MODE_SINGLE;
|
||||||
} else {
|
} else {
|
||||||
ctx->output.shoot.cmd.mode = SHOOT_MODE_SAFE;
|
ctx->shoot.cmd.mode = SHOOT_MODE_SAFE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 根据右拨杆控制射击 */
|
/* 根据右拨杆控制射击 */
|
||||||
switch (ctx->input.rc.sw[1]) {
|
switch (input->sw[1]) {
|
||||||
case CMD_SW_DOWN:
|
case CMD_SW_DOWN:
|
||||||
ctx->output.shoot.cmd.ready = true;
|
ctx->shoot.cmd.ready = true;
|
||||||
ctx->output.shoot.cmd.firecmd = true;
|
ctx->shoot.cmd.firecmd = true;
|
||||||
break;
|
break;
|
||||||
case CMD_SW_MID:
|
case CMD_SW_MID:
|
||||||
ctx->output.shoot.cmd.ready = true;
|
ctx->shoot.cmd.ready = true;
|
||||||
ctx->output.shoot.cmd.firecmd = false;
|
ctx->shoot.cmd.firecmd = false;
|
||||||
break;
|
break;
|
||||||
case CMD_SW_UP:
|
case CMD_SW_UP:
|
||||||
default:
|
default:
|
||||||
ctx->output.shoot.cmd.ready = false;
|
ctx->shoot.cmd.ready = false;
|
||||||
ctx->output.shoot.cmd.firecmd = false;
|
ctx->shoot.cmd.firecmd = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 从PC输入生成底盘命令 */
|
/* 从PC输入生成底盘命令 */
|
||||||
static void CMD_PC_BuildChassisCmd(CMD_t *ctx) {
|
static void CMD_PC_BuildChassisCmd(CMD_Context_t *ctx, const CMD_RawInput_t *input) {
|
||||||
|
CMD_Sensitivity_t *sens = &ctx->config->sensitivity;
|
||||||
|
|
||||||
if (!ctx->input.online[CMD_SRC_PC]) {
|
if (!input->online) {
|
||||||
ctx->output.chassis.cmd.mode = CHASSIS_MODE_RELAX;
|
ctx->chassis.cmd.mode = CHASSIS_MODE_RELAX;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->output.chassis.cmd.mode = CHASSIS_MODE_FOLLOW_GIMBAL;
|
ctx->chassis.cmd.mode = CHASSIS_MODE_FOLLOW_GIMBAL;
|
||||||
|
|
||||||
/* WASD控制移动 */
|
/* WASD控制移动 */
|
||||||
ctx->output.chassis.cmd.ctrl_vec.vx = 0.0f;
|
ctx->chassis.cmd.ctrl_vec.vx = 0.0f;
|
||||||
ctx->output.chassis.cmd.ctrl_vec.vy = 0.0f;
|
ctx->chassis.cmd.ctrl_vec.vy = 0.0f;
|
||||||
CMD_Behavior_ProcessAll(ctx, &ctx->input, &ctx->last_input, CMD_MODULE_CHASSIS);
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 从PC输入生成云台命令 */
|
/* 从PC输入生成云台命令 */
|
||||||
static void CMD_PC_BuildGimbalCmd(CMD_t *ctx) {
|
static void CMD_PC_BuildGimbalCmd(CMD_Context_t *ctx, const CMD_RawInput_t *input) {
|
||||||
CMD_Sensitivity_t *sens = &ctx->config->sensitivity;
|
CMD_Sensitivity_t *sens = &ctx->config->sensitivity;
|
||||||
|
|
||||||
if (!ctx->input.online[CMD_SRC_PC]) {
|
if (!input->online) {
|
||||||
ctx->output.gimbal.cmd.mode = GIMBAL_MODE_RELAX;
|
ctx->gimbal.cmd.mode = GIMBAL_MODE_RELAX;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->output.gimbal.cmd.mode = GIMBAL_MODE_ABSOLUTE;
|
ctx->gimbal.cmd.mode = GIMBAL_MODE_ABSOLUTE;
|
||||||
|
|
||||||
/* 鼠标控制云台 */
|
/* 鼠标控制云台 */
|
||||||
ctx->output.gimbal.cmd.delta_yaw = (float)-ctx->input.pc.mouse.x * ctx->timer.dt * sens->mouse_sens;
|
ctx->gimbal.cmd.delta_yaw = (float)-input->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;
|
ctx->gimbal.cmd.delta_pit = (float)input->mouse.y * ctx->timer.dt * sens->mouse_sens * 1.5f;
|
||||||
CMD_Behavior_ProcessAll(ctx, &ctx->input, &ctx->last_input, CMD_MODULE_GIMBAL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 从PC输入生成射击命令 */
|
/* 从PC输入生成射击命令 */
|
||||||
static void CMD_PC_BuildShootCmd(CMD_t *ctx) {
|
static void CMD_PC_BuildShootCmd(CMD_Context_t *ctx, const CMD_RawInput_t *input) {
|
||||||
if (!ctx->input.online[CMD_SRC_PC]) {
|
if (!input->online) {
|
||||||
ctx->output.shoot.cmd.mode = SHOOT_MODE_SAFE;
|
ctx->shoot.cmd.mode = SHOOT_MODE_SAFE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->output.shoot.cmd.ready = true;
|
ctx->shoot.cmd.ready = true;
|
||||||
ctx->output.shoot.cmd.firecmd = ctx->input.pc.mouse.l_click;
|
ctx->shoot.cmd.firecmd = input->mouse.l_click;
|
||||||
|
|
||||||
CMD_Behavior_ProcessAll(ctx, &ctx->input, &ctx->last_input, CMD_MODULE_SHOOT);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 离线安全模式 */
|
/* 离线安全模式 */
|
||||||
static void CMD_SetOfflineMode(CMD_t *ctx) {
|
static void CMD_SetOfflineMode(CMD_Context_t *ctx) {
|
||||||
ctx->output.chassis.cmd.mode = CHASSIS_MODE_RELAX;
|
ctx->chassis.cmd.mode = CHASSIS_MODE_RELAX;
|
||||||
ctx->output.gimbal.cmd.mode = GIMBAL_MODE_RELAX;
|
ctx->gimbal.cmd.mode = GIMBAL_MODE_RELAX;
|
||||||
ctx->output.shoot.cmd.mode = SHOOT_MODE_SAFE;
|
ctx->shoot.cmd.mode = SHOOT_MODE_SAFE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================== */
|
/* ========================================================================== */
|
||||||
/* 公开API实现 */
|
/* 公开API实现 */
|
||||||
/* ========================================================================== */
|
/* ========================================================================== */
|
||||||
|
|
||||||
int8_t CMD_Init(CMD_t *ctx, CMD_Config_t *config) {
|
int8_t CMD_Init(CMD_Context_t *ctx, CMD_Config_t *config) {
|
||||||
if (ctx == NULL || config == NULL) {
|
if (ctx == NULL || config == NULL) {
|
||||||
return CMD_ERR_NULL;
|
return CMD_ERR_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(ctx, 0, sizeof(CMD_t));
|
memset(ctx, 0, sizeof(CMD_Context_t));
|
||||||
ctx->config = config;
|
ctx->config = config;
|
||||||
|
|
||||||
/* 初始化适配器 */
|
/* 初始化适配器 */
|
||||||
@ -161,118 +180,109 @@ int8_t CMD_Init(CMD_t *ctx, CMD_Config_t *config) {
|
|||||||
return CMD_OK;
|
return CMD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t CMD_UpdateInput(CMD_t *ctx) {
|
int8_t CMD_UpdateInput(CMD_Context_t *ctx) {
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
return CMD_ERR_NULL;
|
return CMD_ERR_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 保存上一帧输入 */
|
/* 保存上一帧输入 */
|
||||||
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++) {
|
for (int i = 0; i < CMD_SRC_NUM; i++) {
|
||||||
CMD_Adapter_GetInput((CMD_InputSource_t)i, &ctx->input);
|
CMD_Adapter_GetInput((CMD_InputSource_t)i, &ctx->input[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CMD_OK;
|
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] = {
|
int8_t CMD_Arbitrate(CMD_Context_t *ctx) {
|
||||||
{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) {
|
if (ctx == NULL) {
|
||||||
return CMD_ERR_NULL;
|
return CMD_ERR_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 自动仲裁:优先级 PC > RC > NUC */
|
/* 智能仲裁算法:优先级 PC > RC > NUC */
|
||||||
CMD_InputSource_t candidates[] = {CMD_SRC_PC, CMD_SRC_RC, CMD_SRC_NUC};
|
CMD_InputSource_t candidates[] = {CMD_SRC_PC, CMD_SRC_RC, CMD_SRC_NUC};
|
||||||
const int num_candidates = sizeof(candidates) / sizeof(candidates[0]);
|
const int num_candidates = sizeof(candidates) / sizeof(candidates[0]);
|
||||||
|
|
||||||
/* 如果当前输入源仍然在线且有效,保持使用 */
|
/* 如果当前输入源仍然在线且有效,保持使用 */
|
||||||
if (ctx->active_source < CMD_SRC_NUM &&
|
if (ctx->active_source < CMD_SRC_NUM &&
|
||||||
ctx->active_source != CMD_SRC_REF &&
|
ctx->active_source != CMD_SRC_REF &&
|
||||||
ctx->input.online[ctx->active_source]) {
|
ctx->input[ctx->active_source].online) {
|
||||||
goto seize;
|
goto seize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 否则选择第一个可用的控制输入源 */
|
/* 否则选择第一个可用的控制输入源 */
|
||||||
for (int i = 0; i < num_candidates; i++) {
|
for (int i = 0; i < num_candidates; i++) {
|
||||||
CMD_InputSource_t src = candidates[i];
|
CMD_InputSource_t src = candidates[i];
|
||||||
if (ctx->input.online[src]) {
|
if (ctx->input[src].online) {
|
||||||
ctx->active_source = src;
|
ctx->active_source = src;
|
||||||
break;
|
|
||||||
}else {
|
|
||||||
ctx->active_source = CMD_SRC_NUM;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx->output.chassis.source = ctx->active_source;
|
ctx->chassis.source = ctx->active_source;
|
||||||
ctx->output.gimbal.source = ctx->active_source;
|
ctx->gimbal.source = ctx->active_source;
|
||||||
ctx->output.shoot.source = ctx->active_source;
|
ctx->shoot.source = ctx->active_source;
|
||||||
|
|
||||||
/* 优先级抢占逻辑 */
|
|
||||||
seize:
|
seize:
|
||||||
// 检查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;
|
|
||||||
|
|
||||||
|
|
||||||
|
/* 没有可用输入源 */
|
||||||
|
ctx->active_source = CMD_SRC_NUM;
|
||||||
|
return CMD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t CMD_GenerateCommands(CMD_t *ctx) {
|
int8_t CMD_GenerateCommands(CMD_Context_t *ctx) {
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
return CMD_ERR_NULL;
|
return CMD_ERR_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 更新时间 */
|
/* 更新时间 */
|
||||||
uint64_t now_us = BSP_TIME_Get_us();
|
uint64_t now_us = BSP_TIME_Get_us();
|
||||||
ctx->timer.now = now_us / 1000000.0f;
|
ctx->timer.now = now_us / 1000000.0f;
|
||||||
ctx->timer.dt = (now_us - ctx->timer.last_us) / 1000000.0f;
|
ctx->timer.dt = (now_us - ctx->timer.last_us) / 1000000.0f;
|
||||||
ctx->timer.last_us = now_us;
|
ctx->timer.last_us = now_us;
|
||||||
|
|
||||||
/* 没有有效输入源 */
|
/* 没有有效输入源 */
|
||||||
if (ctx->active_source >= CMD_SRC_NUM) {
|
if (ctx->active_source >= CMD_SRC_NUM) {
|
||||||
CMD_SetOfflineMode(ctx);
|
CMD_SetOfflineMode(ctx);
|
||||||
return CMD_ERR_NO_INPUT;
|
return CMD_ERR_NO_INPUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceHandlers[ctx->output.gimbal.source].gimbalFunc(ctx);
|
const CMD_RawInput_t *active_input = &ctx->input[ctx->active_source];
|
||||||
sourceHandlers[ctx->output.chassis.source].chassisFunc(ctx);
|
const CMD_RawInput_t *last_input = &ctx->last_input[ctx->active_source];
|
||||||
sourceHandlers[ctx->output.shoot.source].shootFunc(ctx);
|
|
||||||
return CMD_OK;
|
/* 根据输入源类型生成命令 */
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t CMD_Update(CMD_t *ctx) {
|
int8_t CMD_Update(CMD_Context_t *ctx) {
|
||||||
int8_t ret;
|
int8_t ret;
|
||||||
|
|
||||||
ret = CMD_UpdateInput(ctx);
|
ret = CMD_UpdateInput(ctx);
|
||||||
|
|||||||
@ -74,6 +74,8 @@ typedef struct {
|
|||||||
/* RC模式映射 */
|
/* RC模式映射 */
|
||||||
CMD_RCModeMap_t rc_mode_map;
|
CMD_RCModeMap_t rc_mode_map;
|
||||||
|
|
||||||
|
/* 是否启用PC输入 */
|
||||||
|
bool enable_pc_input;
|
||||||
} CMD_Config_t;
|
} CMD_Config_t;
|
||||||
|
|
||||||
/* ========================================================================== */
|
/* ========================================================================== */
|
||||||
@ -83,7 +85,7 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
float now;
|
float now;
|
||||||
float dt;
|
float dt;
|
||||||
uint32_t last_us;
|
uint64_t last_us;
|
||||||
} CMD_Timer_t;
|
} CMD_Timer_t;
|
||||||
|
|
||||||
typedef struct CMD_Context {
|
typedef struct CMD_Context {
|
||||||
@ -94,19 +96,18 @@ typedef struct CMD_Context {
|
|||||||
CMD_Timer_t timer;
|
CMD_Timer_t timer;
|
||||||
|
|
||||||
/* 当前帧和上一帧的原始输入 */
|
/* 当前帧和上一帧的原始输入 */
|
||||||
CMD_RawInput_t input;
|
CMD_RawInput_t input[CMD_SRC_NUM];
|
||||||
CMD_RawInput_t last_input;
|
CMD_RawInput_t last_input[CMD_SRC_NUM];
|
||||||
|
|
||||||
/* 仲裁后的活跃输入源 */
|
/* 仲裁后的活跃输入源 */
|
||||||
CMD_InputSource_t active_source;
|
CMD_InputSource_t active_source;
|
||||||
|
|
||||||
/* 输出 */
|
/* 输出 */
|
||||||
struct {
|
|
||||||
CMD_ChassisOutput_t chassis;
|
CMD_ChassisOutput_t chassis;
|
||||||
CMD_GimbalOutput_t gimbal;
|
CMD_GimbalOutput_t gimbal;
|
||||||
CMD_ShootOutput_t shoot;
|
CMD_ShootOutput_t shoot;
|
||||||
} output;
|
|
||||||
} CMD_t;
|
} CMD_Context_t;
|
||||||
|
|
||||||
/* ========================================================================== */
|
/* ========================================================================== */
|
||||||
/* 主API接口 */
|
/* 主API接口 */
|
||||||
@ -118,53 +119,53 @@ typedef struct CMD_Context {
|
|||||||
* @param config 配置指针
|
* @param config 配置指针
|
||||||
* @return CMD_OK成功,其他失败
|
* @return CMD_OK成功,其他失败
|
||||||
*/
|
*/
|
||||||
int8_t CMD_Init(CMD_t *ctx, CMD_Config_t *config);
|
int8_t CMD_Init(CMD_Context_t *ctx, CMD_Config_t *config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 更新所有输入源的数据
|
* @brief 更新所有输入源的数据
|
||||||
* @param ctx CMD上下文
|
* @param ctx CMD上下文
|
||||||
* @return CMD_OK成功
|
* @return CMD_OK成功
|
||||||
*/
|
*/
|
||||||
int8_t CMD_UpdateInput(CMD_t *ctx);
|
int8_t CMD_UpdateInput(CMD_Context_t *ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 执行仲裁,决定使用哪个输入源
|
* @brief 执行仲裁,决定使用哪个输入源
|
||||||
* @param ctx CMD上下文
|
* @param ctx CMD上下文
|
||||||
* @return 选中的输入源
|
* @return 选中的输入源
|
||||||
*/
|
*/
|
||||||
int8_t CMD_Arbitrate(CMD_t *ctx);
|
int8_t CMD_Arbitrate(CMD_Context_t *ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 生成所有模块的控制命令
|
* @brief 生成所有模块的控制命令
|
||||||
* @param ctx CMD上下文
|
* @param ctx CMD上下文
|
||||||
* @return CMD_OK成功
|
* @return CMD_OK成功
|
||||||
*/
|
*/
|
||||||
int8_t CMD_GenerateCommands(CMD_t *ctx);
|
int8_t CMD_GenerateCommands(CMD_Context_t *ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 一键更新(包含UpdateInput + Arbitrate + GenerateCommands)
|
* @brief 一键更新(包含UpdateInput + Arbitrate + GenerateCommands)
|
||||||
* @param ctx CMD上下文
|
* @param ctx CMD上下文
|
||||||
* @return CMD_OK成功
|
* @return CMD_OK成功
|
||||||
*/
|
*/
|
||||||
int8_t CMD_Update(CMD_t *ctx);
|
int8_t CMD_Update(CMD_Context_t *ctx);
|
||||||
|
|
||||||
/* ========================================================================== */
|
/* ========================================================================== */
|
||||||
/* 输出获取接口 */
|
/* 输出获取接口 */
|
||||||
/* ========================================================================== */
|
/* ========================================================================== */
|
||||||
|
|
||||||
/* 获取底盘命令 */
|
/* 获取底盘命令 */
|
||||||
static inline Chassis_CMD_t* CMD_GetChassisCmd(CMD_t *ctx) {
|
static inline Chassis_CMD_t* CMD_GetChassisCmd(CMD_Context_t *ctx) {
|
||||||
return &ctx->output.chassis.cmd;
|
return &ctx->chassis.cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 获取云台命令 */
|
/* 获取云台命令 */
|
||||||
static inline Gimbal_CMD_t* CMD_GetGimbalCmd(CMD_t *ctx) {
|
static inline Gimbal_CMD_t* CMD_GetGimbalCmd(CMD_Context_t *ctx) {
|
||||||
return &ctx->output.gimbal.cmd;
|
return &ctx->gimbal.cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 获取射击命令 */
|
/* 获取射击命令 */
|
||||||
static inline Shoot_CMD_t* CMD_GetShootCmd(CMD_t *ctx) {
|
static inline Shoot_CMD_t* CMD_GetShootCmd(CMD_Context_t *ctx) {
|
||||||
return &ctx->output.shoot.cmd;
|
return &ctx->shoot.cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@ -7,8 +7,8 @@
|
|||||||
/* ========================================================================== */
|
/* ========================================================================== */
|
||||||
/* 适配器存储 */
|
/* 适配器存储 */
|
||||||
/* ========================================================================== */
|
/* ========================================================================== */
|
||||||
// static CMD_InputAdapter_t *g_adapters[CMD_SRC_NUM] = {0};
|
static CMD_InputAdapter_t *g_adapters[CMD_SRC_NUM] = {0};
|
||||||
CMD_InputAdapter_t *g_adapters[CMD_SRC_NUM] = {0};
|
|
||||||
/* ========================================================================== */
|
/* ========================================================================== */
|
||||||
/* DR16 适配器实现 */
|
/* DR16 适配器实现 */
|
||||||
/* ========================================================================== */
|
/* ========================================================================== */
|
||||||
@ -22,32 +22,32 @@ int8_t CMD_DR16_Init(void *data) {
|
|||||||
int8_t CMD_DR16_RC_GetInput(void *data, CMD_RawInput_t *output) {
|
int8_t CMD_DR16_RC_GetInput(void *data, CMD_RawInput_t *output) {
|
||||||
DR16_t *dr16 = (DR16_t *)data;
|
DR16_t *dr16 = (DR16_t *)data;
|
||||||
|
|
||||||
memset(&output->rc, 0, sizeof(CMD_RawInput_RC_t));
|
memset(output, 0, sizeof(CMD_RawInput_t));
|
||||||
|
|
||||||
output->online[CMD_SRC_RC] = dr16->header.online;
|
output->online = dr16->header.online;
|
||||||
|
|
||||||
/* 遥控器摇杆映射 */
|
/* 遥控器摇杆映射 */
|
||||||
output->rc.joy_left.x = dr16->data.rc.ch_l_x;
|
output->joy_left.x = dr16->data.rc.ch_l_x;
|
||||||
output->rc.joy_left.y = dr16->data.rc.ch_l_y;
|
output->joy_left.y = dr16->data.rc.ch_l_y;
|
||||||
output->rc.joy_right.x = dr16->data.rc.ch_r_x;
|
output->joy_right.x = dr16->data.rc.ch_r_x;
|
||||||
output->rc.joy_right.y = dr16->data.rc.ch_r_y;
|
output->joy_right.y = dr16->data.rc.ch_r_y;
|
||||||
|
|
||||||
/* 拨杆映射 */
|
/* 拨杆映射 */
|
||||||
switch (dr16->data.rc.sw_l) {
|
switch (dr16->data.rc.sw_l) {
|
||||||
case DR16_SW_UP: output->rc.sw[0] = CMD_SW_UP; break;
|
case DR16_SW_UP: output->sw[0] = CMD_SW_UP; break;
|
||||||
case DR16_SW_MID: output->rc.sw[0] = CMD_SW_MID; break;
|
case DR16_SW_MID: output->sw[0] = CMD_SW_MID; break;
|
||||||
case DR16_SW_DOWN: output->rc.sw[0] = CMD_SW_DOWN; break;
|
case DR16_SW_DOWN: output->sw[0] = CMD_SW_DOWN; break;
|
||||||
default: output->rc.sw[0] = CMD_SW_ERR; break;
|
default: output->sw[0] = CMD_SW_ERR; break;
|
||||||
}
|
}
|
||||||
switch (dr16->data.rc.sw_r) {
|
switch (dr16->data.rc.sw_r) {
|
||||||
case DR16_SW_UP: output->rc.sw[1] = CMD_SW_UP; break;
|
case DR16_SW_UP: output->sw[1] = CMD_SW_UP; break;
|
||||||
case DR16_SW_MID: output->rc.sw[1] = CMD_SW_MID; break;
|
case DR16_SW_MID: output->sw[1] = CMD_SW_MID; break;
|
||||||
case DR16_SW_DOWN: output->rc.sw[1] = CMD_SW_DOWN; break;
|
case DR16_SW_DOWN: output->sw[1] = CMD_SW_DOWN; break;
|
||||||
default: output->rc.sw[1] = CMD_SW_ERR; break;
|
default: output->sw[1] = CMD_SW_ERR; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 拨轮映射 */
|
/* 拨轮映射 */
|
||||||
output->rc.dial = dr16->data.rc.ch_res;
|
output->dial = dr16->data.rc.ch_res;
|
||||||
|
|
||||||
return CMD_OK;
|
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) {
|
int8_t CMD_DR16_PC_GetInput(void *data, CMD_RawInput_t *output) {
|
||||||
DR16_t *dr16 = (DR16_t *)data;
|
DR16_t *dr16 = (DR16_t *)data;
|
||||||
|
|
||||||
memset(&output->pc, 0, sizeof(CMD_RawInput_PC_t));
|
memset(output, 0, sizeof(CMD_RawInput_t));
|
||||||
|
|
||||||
output->online[CMD_SRC_PC] = dr16->header.online;
|
output->online = dr16->header.online;
|
||||||
|
|
||||||
/* PC端鼠标映射 */
|
/* PC端鼠标映射 */
|
||||||
output->pc.mouse.x = dr16->data.pc.mouse.x;
|
output->mouse.x = dr16->data.pc.mouse.x;
|
||||||
output->pc.mouse.y = dr16->data.pc.mouse.y;
|
output->mouse.y = dr16->data.pc.mouse.y;
|
||||||
output->pc.mouse.l_click = dr16->data.pc.mouse.l_click;
|
output->mouse.l_click = dr16->data.pc.mouse.l_click;
|
||||||
output->pc.mouse.r_click = dr16->data.pc.mouse.r_click;
|
output->mouse.r_click = dr16->data.pc.mouse.r_click;
|
||||||
|
|
||||||
/* 键盘映射 */
|
/* 键盘映射 */
|
||||||
output->pc.keyboard.bitmap = dr16->raw_data.key;
|
output->keyboard.bitmap = dr16->data.pc.keyboard.value;
|
||||||
|
|
||||||
return CMD_OK;
|
return CMD_OK;
|
||||||
}
|
}
|
||||||
@ -75,10 +75,10 @@ bool CMD_DR16_IsOnline(void *data) {
|
|||||||
DR16_t *dr16 = (DR16_t *)data;
|
DR16_t *dr16 = (DR16_t *)data;
|
||||||
return dr16->header.online;
|
return dr16->header.online;
|
||||||
}
|
}
|
||||||
extern DR16_t cmd_dr16;
|
|
||||||
/* 定义适配器实例 */
|
/* 定义适配器实例 */
|
||||||
CMD_DEFINE_ADAPTER(DR16_RC, cmd_dr16, CMD_SRC_RC, CMD_DR16_Init, CMD_DR16_RC_GetInput, CMD_DR16_IsOnline)
|
CMD_DEFINE_ADAPTER(DR16_RC, dr16, CMD_SRC_RC, CMD_DR16_Init, CMD_DR16_RC_GetInput, CMD_DR16_IsOnline)
|
||||||
CMD_DEFINE_ADAPTER(DR16_PC, cmd_dr16, CMD_SRC_PC, CMD_DR16_Init, CMD_DR16_PC_GetInput, CMD_DR16_IsOnline)
|
CMD_DEFINE_ADAPTER(DR16_PC, dr16, CMD_SRC_PC, CMD_DR16_Init, CMD_DR16_PC_GetInput, CMD_DR16_IsOnline)
|
||||||
|
|
||||||
#endif /* CMD_RC_DEVICE_TYPE == 0 */
|
#endif /* CMD_RC_DEVICE_TYPE == 0 */
|
||||||
|
|
||||||
@ -95,9 +95,9 @@ int8_t CMD_AT9S_Init(void *data) {
|
|||||||
int8_t CMD_AT9S_GetInput(void *data, CMD_RawInput_t *output) {
|
int8_t CMD_AT9S_GetInput(void *data, CMD_RawInput_t *output) {
|
||||||
AT9S_t *at9s = (AT9S_t *)data;
|
AT9S_t *at9s = (AT9S_t *)data;
|
||||||
|
|
||||||
memset(output, 0, sizeof(CMD_RawInput_RC_t));
|
memset(output, 0, sizeof(CMD_RawInput_t));
|
||||||
|
|
||||||
output->online[CMD_SRC_RC] = at9s->header.online;
|
output->online = at9s->header.online;
|
||||||
|
|
||||||
/* TODO: 按照AT9S的数据格式进行映射 */
|
/* TODO: 按照AT9S的数据格式进行映射 */
|
||||||
output->joy_left.x = at9s->data.rc.ch_l_x;
|
output->joy_left.x = at9s->data.rc.ch_l_x;
|
||||||
@ -159,7 +159,8 @@ int8_t CMD_Adapter_GetInput(CMD_InputSource_t source, CMD_RawInput_t *output) {
|
|||||||
|
|
||||||
CMD_InputAdapter_t *adapter = g_adapters[source];
|
CMD_InputAdapter_t *adapter = g_adapters[source];
|
||||||
if (adapter == NULL || adapter->get_input == NULL) {
|
if (adapter == NULL || adapter->get_input == NULL) {
|
||||||
output->online[adapter->source] = false;
|
memset(output, 0, sizeof(CMD_RawInput_t));
|
||||||
|
output->online = false;
|
||||||
return CMD_ERR_NO_INPUT;
|
return CMD_ERR_NO_INPUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
#include "cmd_behavior.h"
|
#include "cmd_behavior.h"
|
||||||
#include "cmd.h"
|
#include "cmd.h"
|
||||||
#include "module/gimbal.h"
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/* ========================================================================== */
|
/* ========================================================================== */
|
||||||
@ -11,82 +10,69 @@
|
|||||||
/* ========================================================================== */
|
/* ========================================================================== */
|
||||||
|
|
||||||
/* 行为处理函数实现 */
|
/* 行为处理函数实现 */
|
||||||
int8_t CMD_Behavior_Handle_FORE(CMD_t *ctx) {
|
int8_t CMD_Behavior_Handle_FORE(CMD_Context_t *ctx) {
|
||||||
ctx->output.chassis.cmd.ctrl_vec.vy += ctx->config->sensitivity.move_sens;
|
ctx->chassis.cmd.ctrl_vec.vy += ctx->config->sensitivity.move_sens;
|
||||||
return CMD_OK;
|
return CMD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t CMD_Behavior_Handle_BACK(CMD_t *ctx) {
|
int8_t CMD_Behavior_Handle_BACK(CMD_Context_t *ctx) {
|
||||||
ctx->output.chassis.cmd.ctrl_vec.vy -= ctx->config->sensitivity.move_sens;
|
ctx->chassis.cmd.ctrl_vec.vy -= ctx->config->sensitivity.move_sens;
|
||||||
return CMD_OK;
|
return CMD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t CMD_Behavior_Handle_LEFT(CMD_t *ctx) {
|
int8_t CMD_Behavior_Handle_LEFT(CMD_Context_t *ctx) {
|
||||||
ctx->output.chassis.cmd.ctrl_vec.vx -= ctx->config->sensitivity.move_sens;
|
ctx->chassis.cmd.ctrl_vec.vx -= ctx->config->sensitivity.move_sens;
|
||||||
return CMD_OK;
|
return CMD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t CMD_Behavior_Handle_RIGHT(CMD_t *ctx) {
|
int8_t CMD_Behavior_Handle_RIGHT(CMD_Context_t *ctx) {
|
||||||
ctx->output.chassis.cmd.ctrl_vec.vx += ctx->config->sensitivity.move_sens;
|
ctx->chassis.cmd.ctrl_vec.vx += ctx->config->sensitivity.move_sens;
|
||||||
return CMD_OK;
|
return CMD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t CMD_Behavior_Handle_ACCELERATE(CMD_t *ctx) {
|
int8_t CMD_Behavior_Handle_ACCELERATE(CMD_Context_t *ctx) {
|
||||||
ctx->output.chassis.cmd.ctrl_vec.vx *= ctx->config->sensitivity.move_fast_mult;
|
ctx->chassis.cmd.ctrl_vec.vx *= ctx->config->sensitivity.move_fast_mult;
|
||||||
ctx->output.chassis.cmd.ctrl_vec.vy *= ctx->config->sensitivity.move_fast_mult;
|
ctx->chassis.cmd.ctrl_vec.vy *= ctx->config->sensitivity.move_fast_mult;
|
||||||
return CMD_OK;
|
return CMD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t CMD_Behavior_Handle_DECELERATE(CMD_t *ctx) {
|
int8_t CMD_Behavior_Handle_DECELERATE(CMD_Context_t *ctx) {
|
||||||
ctx->output.chassis.cmd.ctrl_vec.vx *= ctx->config->sensitivity.move_slow_mult;
|
ctx->chassis.cmd.ctrl_vec.vx *= ctx->config->sensitivity.move_slow_mult;
|
||||||
ctx->output.chassis.cmd.ctrl_vec.vy *= ctx->config->sensitivity.move_slow_mult;
|
ctx->chassis.cmd.ctrl_vec.vy *= ctx->config->sensitivity.move_slow_mult;
|
||||||
return CMD_OK;
|
return CMD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t CMD_Behavior_Handle_FIRE(CMD_t *ctx) {
|
int8_t CMD_Behavior_Handle_FIRE(CMD_Context_t *ctx) {
|
||||||
ctx->output.shoot.cmd.firecmd = true;
|
ctx->shoot.cmd.firecmd = true;
|
||||||
return CMD_OK;
|
return CMD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t CMD_Behavior_Handle_FIRE_MODE(CMD_t *ctx) {
|
int8_t CMD_Behavior_Handle_FIRE_MODE(CMD_Context_t *ctx) {
|
||||||
ctx->output.shoot.cmd.mode = (ctx->output.shoot.cmd.mode + 1) % SHOOT_MODE_NUM;
|
ctx->shoot.cmd.mode = (ctx->shoot.cmd.mode + 1) % SHOOT_MODE_NUM;
|
||||||
return CMD_OK;
|
return CMD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t CMD_Behavior_Handle_ROTOR(CMD_t *ctx) {
|
int8_t CMD_Behavior_Handle_ROTOR(CMD_Context_t *ctx) {
|
||||||
ctx->output.chassis.cmd.mode = CHASSIS_MODE_ROTOR;
|
if (ctx->chassis.cmd.mode == CHASSIS_MODE_ROTOR) {
|
||||||
ctx->output.chassis.cmd.mode_rotor = ROTOR_MODE_RAND;
|
ctx->chassis.cmd.mode = CHASSIS_MODE_FOLLOW_GIMBAL;
|
||||||
ctx->output.gimbal.cmd.mode = GIMBAL_MODE_RELATIVE;
|
} else {
|
||||||
return CMD_OK;
|
ctx->chassis.cmd.mode = CHASSIS_MODE_ROTOR;
|
||||||
}
|
ctx->chassis.cmd.mode_rotor = ROTOR_MODE_RAND;
|
||||||
|
|
||||||
int8_t CMD_Behavior_Handle_AUTOAIM(CMD_t *ctx) {
|
|
||||||
/* TODO: 自瞄模式切换 */
|
|
||||||
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;
|
return CMD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int8_t CMD_Behavior_Handle_AUTOAIM(CMD_Context_t *ctx) {
|
||||||
|
/* TODO: 自瞄模式切换 */
|
||||||
|
return CMD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/* 行为配置表 - 由宏生成 */
|
/* 行为配置表 - 由宏生成 */
|
||||||
static const CMD_BehaviorConfig_t g_behavior_configs[] = {
|
static const CMD_BehaviorConfig_t g_behavior_configs[] = {
|
||||||
CMD_BEHAVIOR_TABLE(BUILD_BEHAVIOR_CONFIG)
|
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实现 */
|
/* API实现 */
|
||||||
@ -104,40 +90,54 @@ bool CMD_Behavior_IsTriggered(const CMD_RawInput_t *current,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool now_pressed = false;
|
bool now_pressed = false;
|
||||||
bool last_pressed = false;
|
bool last_pressed = false;
|
||||||
|
|
||||||
// 鼠标特殊按键处理
|
/* 处理特殊按键 */
|
||||||
if (config->key == (CMD_KEY_L_CLICK)) {
|
switch (config->key) {
|
||||||
now_pressed = current->pc.mouse.l_click;
|
case CMD_KEY_NONE:
|
||||||
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;
|
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_KEY_L_CLICK:
|
||||||
case CMD_ACTIVE_PRESSED:
|
now_pressed = current->mouse.l_click;
|
||||||
return now_pressed;
|
last_pressed = last ? last->mouse.l_click : false;
|
||||||
case CMD_ACTIVE_RISING_EDGE:
|
break;
|
||||||
return now_pressed && !last_pressed;
|
|
||||||
case CMD_ACTIVE_FALLING_EDGE:
|
case CMD_KEY_R_CLICK:
|
||||||
return !now_pressed && last_pressed;
|
now_pressed = current->mouse.r_click;
|
||||||
default:
|
last_pressed = last ? last->mouse.r_click : false;
|
||||||
return 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t CMD_Behavior_ProcessAll(CMD_t *ctx,
|
int8_t CMD_Behavior_ProcessAll(CMD_Context_t *ctx,
|
||||||
const CMD_RawInput_t *current,
|
const CMD_RawInput_t *current,
|
||||||
const CMD_RawInput_t *last,
|
const CMD_RawInput_t *last,
|
||||||
CMD_ModuleMask_t active_modules) {
|
CMD_ModuleMask_t active_modules) {
|
||||||
@ -148,7 +148,7 @@ int8_t CMD_Behavior_ProcessAll(CMD_t *ctx,
|
|||||||
for (size_t i = 0; i < BEHAVIOR_CONFIG_COUNT; i++) {
|
for (size_t i = 0; i < BEHAVIOR_CONFIG_COUNT; i++) {
|
||||||
const CMD_BehaviorConfig_t *config = &g_behavior_configs[i];
|
const CMD_BehaviorConfig_t *config = &g_behavior_configs[i];
|
||||||
|
|
||||||
/* 过滤模块掩码 */
|
/* 检查模块掩码 */
|
||||||
if ((config->module_mask & active_modules) == 0) {
|
if ((config->module_mask & active_modules) == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,7 +21,7 @@ typedef int8_t (*CMD_BehaviorHandler)(struct CMD_Context *ctx);
|
|||||||
/* 行为配置项 */
|
/* 行为配置项 */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
CMD_Behavior_t behavior; /* 行为枚举 */
|
CMD_Behavior_t behavior; /* 行为枚举 */
|
||||||
uint32_t key; /* 绑定的按键 */
|
uint8_t key; /* 绑定的按键 */
|
||||||
CMD_TriggerType_t trigger; /* 触发类型 */
|
CMD_TriggerType_t trigger; /* 触发类型 */
|
||||||
CMD_ModuleMask_t module_mask; /* 影响的模块 */
|
CMD_ModuleMask_t module_mask; /* 影响的模块 */
|
||||||
CMD_BehaviorHandler handler; /* 处理函数 */
|
CMD_BehaviorHandler handler; /* 处理函数 */
|
||||||
|
|||||||
@ -11,6 +11,14 @@
|
|||||||
|
|
||||||
/* 默认配置 */
|
/* 默认配置 */
|
||||||
static CMD_Config_t g_cmd_config = {
|
static CMD_Config_t g_cmd_config = {
|
||||||
|
/* 输入源优先级:RC > PC > NUC > REF */
|
||||||
|
.source_priority = {
|
||||||
|
CMD_SRC_RC,
|
||||||
|
CMD_SRC_PC,
|
||||||
|
CMD_SRC_NUC,
|
||||||
|
CMD_SRC_REF,
|
||||||
|
},
|
||||||
|
|
||||||
/* 灵敏度设置 */
|
/* 灵敏度设置 */
|
||||||
.sensitivity = {
|
.sensitivity = {
|
||||||
.mouse_sens = 0.8f,
|
.mouse_sens = 0.8f,
|
||||||
@ -32,10 +40,11 @@ static CMD_Config_t g_cmd_config = {
|
|||||||
.gimbal_sw_down = GIMBAL_MODE_RELATIVE,
|
.gimbal_sw_down = GIMBAL_MODE_RELATIVE,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
.enable_pc_input = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* CMD上下文 */
|
/* CMD上下文 */
|
||||||
static CMD_t g_cmd_ctx;
|
static CMD_Context_t g_cmd_ctx;
|
||||||
|
|
||||||
/* ========================================================================== */
|
/* ========================================================================== */
|
||||||
/* 任务示例 */
|
/* 任务示例 */
|
||||||
@ -139,6 +148,6 @@ void Example_CMD_Task(void) {
|
|||||||
*
|
*
|
||||||
* ### 添加新输出模块
|
* ### 添加新输出模块
|
||||||
* 1. 在 CMD_OUTPUT_MODULE_TABLE 添加条目
|
* 1. 在 CMD_OUTPUT_MODULE_TABLE 添加条目
|
||||||
* 2. 在 CMD_t 中添加输出成员
|
* 2. 在 CMD_Context_t 中添加输出成员
|
||||||
* 3. 实现对应的 BuildXXXCmd 函数
|
* 3. 实现对应的 BuildXXXCmd 函数
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -28,10 +28,10 @@ extern "C" {
|
|||||||
* 格式: X(枚举名, 优先级, 适配器初始化函数, 获取数据函数)
|
* 格式: X(枚举名, 优先级, 适配器初始化函数, 获取数据函数)
|
||||||
*/
|
*/
|
||||||
#define CMD_INPUT_SOURCE_TABLE(X) \
|
#define CMD_INPUT_SOURCE_TABLE(X) \
|
||||||
X(RC, CMD_RC_AdapterInit, CMD_RC_GetInput) \
|
X(RC, 0, CMD_RC_AdapterInit, CMD_RC_GetInput) \
|
||||||
X(PC, CMD_PC_AdapterInit, CMD_PC_GetInput) \
|
X(PC, 1, CMD_PC_AdapterInit, CMD_PC_GetInput) \
|
||||||
X(NUC, CMD_NUC_AdapterInit, CMD_NUC_GetInput) \
|
X(NUC, 2, CMD_NUC_AdapterInit, CMD_NUC_GetInput) \
|
||||||
X(REF, CMD_REF_AdapterInit, CMD_REF_GetInput)
|
X(REF, 3, CMD_REF_AdapterInit, CMD_REF_GetInput)
|
||||||
|
|
||||||
/* 输出模块配置宏表 */
|
/* 输出模块配置宏表 */
|
||||||
#define CMD_OUTPUT_MODULE_TABLE(X) \
|
#define CMD_OUTPUT_MODULE_TABLE(X) \
|
||||||
@ -39,17 +39,6 @@ extern "C" {
|
|||||||
X(GIMBAL, Gimbal_CMD_t, gimbal) \
|
X(GIMBAL, Gimbal_CMD_t, gimbal) \
|
||||||
X(SHOOT, Shoot_CMD_t, shoot)
|
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
|
|
||||||
|
|
||||||
/* ========================================================================== */
|
/* ========================================================================== */
|
||||||
/* 统一输入数据结构 */
|
/* 统一输入数据结构 */
|
||||||
/* ========================================================================== */
|
/* ========================================================================== */
|
||||||
@ -85,10 +74,10 @@ typedef struct {
|
|||||||
|
|
||||||
/* 键盘按键索引 */
|
/* 键盘按键索引 */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CMD_KEY_W = (1 << 0), CMD_KEY_S = (1 << 1), CMD_KEY_A = (1 << 2), CMD_KEY_D = (1 << 3),
|
CMD_KEY_W = 0, CMD_KEY_S, CMD_KEY_A, CMD_KEY_D,
|
||||||
CMD_KEY_SHIFT = (1 << 4), CMD_KEY_CTRL = (1 << 5), CMD_KEY_Q = (1 << 6), CMD_KEY_E = (1 << 7),
|
CMD_KEY_SHIFT, CMD_KEY_CTRL, CMD_KEY_Q, CMD_KEY_E,
|
||||||
CMD_KEY_R = (1 << 8), CMD_KEY_F = (1 << 9), CMD_KEY_G = (1 << 10), CMD_KEY_Z = (1 << 11),
|
CMD_KEY_R, CMD_KEY_F, CMD_KEY_G, CMD_KEY_Z,
|
||||||
CMD_KEY_X = (1 << 12), CMD_KEY_C = (1 << 13), CMD_KEY_V = (1 << 14), CMD_KEY_B = (1 << 15),
|
CMD_KEY_X, CMD_KEY_C, CMD_KEY_V, CMD_KEY_B,
|
||||||
CMD_KEY_NUM
|
CMD_KEY_NUM
|
||||||
} CMD_KeyIndex_t;
|
} CMD_KeyIndex_t;
|
||||||
|
|
||||||
@ -97,72 +86,64 @@ typedef struct {
|
|||||||
uint8_t game_status; /* 比赛状态 */
|
uint8_t game_status; /* 比赛状态 */
|
||||||
} CMD_Referee_t;
|
} 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 {
|
typedef struct {
|
||||||
bool online[CMD_SRC_NUM];
|
bool online;
|
||||||
|
|
||||||
/* 遥控器部分 */
|
/* 遥控器部分 */
|
||||||
CMD_RawInput_RC_t rc;
|
CMD_Joystick_t joy_left; /* 左摇杆 */
|
||||||
|
CMD_Joystick_t joy_right; /* 右摇杆 */
|
||||||
|
CMD_SwitchPos_t sw[4]; /* 最多4个拨杆 */
|
||||||
|
float dial; /* 拨轮 */
|
||||||
|
|
||||||
/* PC部分 */
|
/* PC部分 */
|
||||||
CMD_RawInput_PC_t pc;
|
CMD_Mouse_t mouse;
|
||||||
|
CMD_Keyboard_t keyboard;
|
||||||
|
|
||||||
/* NUC部分 */
|
/* NUC部分 */
|
||||||
/* 暂无定义,预留扩展 */
|
/* 暂无定义,预留扩展 */
|
||||||
CMD_RawInput_NUC_t nuc;
|
|
||||||
|
|
||||||
/* REF部分 - 裁判系统数据 */
|
/* REF部分 - 裁判系统数据 */
|
||||||
CMD_RawInput_REF_t ref;
|
CMD_Referee_t referee;
|
||||||
} CMD_RawInput_t;
|
} CMD_RawInput_t;
|
||||||
|
|
||||||
|
/* ========================================================================== */
|
||||||
|
/* 输入源枚举 */
|
||||||
|
/* ========================================================================== */
|
||||||
|
#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
|
||||||
|
|
||||||
/* ========================================================================== */
|
/* ========================================================================== */
|
||||||
/* 模块掩码 */
|
/* 模块掩码 */
|
||||||
/* ========================================================================== */
|
/* ========================================================================== */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CMD_MODULE_NONE = (1 << 0),
|
CMD_MODULE_NONE = 0,
|
||||||
CMD_MODULE_CHASSIS = (1 << 1),
|
CMD_MODULE_CHASSIS = (1 << 0),
|
||||||
CMD_MODULE_GIMBAL = (1 << 2),
|
CMD_MODULE_GIMBAL = (1 << 1),
|
||||||
CMD_MODULE_SHOOT = (1 << 3),
|
CMD_MODULE_SHOOT = (1 << 2),
|
||||||
CMD_MODULE_ALL = 0x0E
|
CMD_MODULE_ALL = 0x07
|
||||||
} CMD_ModuleMask_t;
|
} CMD_ModuleMask_t;
|
||||||
|
|
||||||
/* ========================================================================== */
|
/* ========================================================================== */
|
||||||
/* 行为定义 */
|
/* 行为定义 */
|
||||||
/* ========================================================================== */
|
/* ========================================================================== */
|
||||||
/* 行为-按键映射宏表 */
|
/* 行为-按键映射宏表 */
|
||||||
#define BEHAVIOR_CONFIG_COUNT (11)
|
|
||||||
#define CMD_BEHAVIOR_TABLE(X) \
|
#define CMD_BEHAVIOR_TABLE(X) \
|
||||||
X(FORE, CMD_KEY_W, CMD_ACTIVE_PRESSED, CMD_MODULE_CHASSIS) \
|
X(FORE, CMD_KEY_W, CMD_ACTIVE_PRESSED, CMD_MODULE_CHASSIS) \
|
||||||
X(BACK, CMD_KEY_S, 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(LEFT, CMD_KEY_A, CMD_ACTIVE_PRESSED, CMD_MODULE_CHASSIS) \
|
||||||
X(RIGHT, CMD_KEY_D, 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(ACCELERATE, CMD_KEY_SHIFT, CMD_ACTIVE_PRESSED, CMD_MODULE_CHASSIS) \
|
||||||
X(DECELERATE, CMD_KEY_CTRL, 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, CMD_KEY_NONE, CMD_ACTIVE_PRESSED, CMD_MODULE_SHOOT) \
|
||||||
X(FIRE_MODE, CMD_KEY_B, CMD_ACTIVE_RISING_EDGE, 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(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(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 {
|
typedef enum {
|
||||||
CMD_ACTIVE_PRESSED, /* 按住时触发 */
|
CMD_ACTIVE_PRESSED, /* 按住时触发 */
|
||||||
@ -172,9 +153,9 @@ typedef enum {
|
|||||||
|
|
||||||
/* 特殊按键值 */
|
/* 特殊按键值 */
|
||||||
#define CMD_KEY_NONE 0xFF
|
#define CMD_KEY_NONE 0xFF
|
||||||
#define CMD_KEY_L_CLICK (1 << 31)
|
#define CMD_KEY_L_CLICK 0xFE
|
||||||
#define CMD_KEY_R_CLICK (1 << 30)
|
#define CMD_KEY_R_CLICK 0xFD
|
||||||
#define CMD_KEY_M_CLICK (1 << 29)
|
#define CMD_KEY_M_CLICK 0xFC
|
||||||
|
|
||||||
/* 行为枚举 - 由宏表自动生成 */
|
/* 行为枚举 - 由宏表自动生成 */
|
||||||
#define ENUM_BEHAVIOR(name, key, trigger, mask) CMD_BEHAVIOR_##name,
|
#define ENUM_BEHAVIOR(name, key, trigger, mask) CMD_BEHAVIOR_##name,
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
#include "module/config.h"
|
#include "module/config.h"
|
||||||
#include "bsp/can.h"
|
#include "bsp/can.h"
|
||||||
#include "device/motor_dm.h"
|
#include "device/motor_dm.h"
|
||||||
#include "module/cmd_v2/cmd.h"
|
#include "module/cmd.h"
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
/* Private typedef ---------------------------------------------------------- */
|
/* Private typedef ---------------------------------------------------------- */
|
||||||
/* Private define ----------------------------------------------------------- */
|
/* Private define ----------------------------------------------------------- */
|
||||||
@ -189,7 +189,7 @@ Config_RobotParam_t robot_config = {
|
|||||||
.gyro = 1000.0f,
|
.gyro = 1000.0f,
|
||||||
},
|
},
|
||||||
.pit_motor ={
|
.pit_motor ={
|
||||||
.can = BSP_CAN_1,
|
.can = BSP_CAN_2,
|
||||||
.can_id = 0x2,
|
.can_id = 0x2,
|
||||||
.master_id = 0x12,
|
.master_id = 0x12,
|
||||||
.module = MOTOR_DM_J4310,
|
.module = MOTOR_DM_J4310,
|
||||||
@ -363,59 +363,40 @@ Config_RobotParam_t robot_config = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// .cmd_param={
|
|
||||||
// .sourcePriorityConfigs={
|
|
||||||
// CMD_SRC_RC,
|
|
||||||
// CMD_SRC_PC,
|
|
||||||
// CMD_SRC_NUC,
|
|
||||||
// CMD_SRC_REF
|
|
||||||
// },
|
|
||||||
// .pc.map = { /*1<<CMD_KEY_W记录一下不要忘了这个思路 */
|
|
||||||
// .key_map[CMD_BEHAVIOR_FORE] = {CMD_KEY_W, CMD_ACTIVE_PRESSED},
|
|
||||||
// .key_map[CMD_BEHAVIOR_BACK] = {CMD_KEY_S, CMD_ACTIVE_PRESSED},
|
|
||||||
// .key_map[CMD_BEHAVIOR_LEFT] = {CMD_KEY_A, CMD_ACTIVE_PRESSED},
|
|
||||||
// .key_map[CMD_BEHAVIOR_RIGHT] = {CMD_KEY_D, CMD_ACTIVE_PRESSED},
|
|
||||||
// .key_map[CMD_BEHAVIOR_ACCELERATE] = {CMD_KEY_SHIFT, CMD_ACTIVE_PRESSED},
|
|
||||||
// .key_map[CMD_BEHAVIOR_DECELEBRATE] = {CMD_KEY_CTRL, CMD_ACTIVE_PRESSED},
|
|
||||||
// .key_map[CMD_BEHAVIOR_FIRE] = {CMD_L_CLICK, CMD_ACTIVE_PRESSED},
|
|
||||||
// .key_map[CMD_BEHAVIOR_FIRE_MODE] = {CMD_R_CLICK, CMD_ACTIVE_RISING_EDGE},
|
|
||||||
// .key_map[CMD_BEHAVIOR_FOLLOWGIMBAL35] = {CMD_KEY_E, CMD_ACTIVE_RISING_EDGE},
|
|
||||||
// .key_map[CMD_BEHAVIOR_OPENCOVER] = {CMD_KEY_F, CMD_ACTIVE_RISING_EDGE},
|
|
||||||
// .key_map[CMD_BEHAVIOR_REVTRIG] = {CMD_KEY_R, CMD_ACTIVE_RISING_EDGE},
|
|
||||||
// .key_map[CMD_BEHAVIOR_ROTOR] = {CMD_KEY_G, CMD_ACTIVE_PRESSED},
|
|
||||||
// .key_map[CMD_BEHAVIOR_GIMBAL_MODE] = {CMD_KEY_V, CMD_ACTIVE_RISING_EDGE},
|
|
||||||
// },
|
|
||||||
// .pc.sensitivity={
|
|
||||||
|
|
||||||
// .move_sense=0.1f,
|
|
||||||
// .sens_mouse=3.0f,
|
|
||||||
// .move_fast_sense=2.4f,
|
|
||||||
// .move_slow_sense=0.8f
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
.cmd_param={
|
.cmd_param={
|
||||||
.source_priority = {
|
.sourcePriorityConfigs={
|
||||||
CMD_SRC_RC,
|
CMD_SRC_RC,
|
||||||
CMD_SRC_PC,
|
CMD_SRC_PC,
|
||||||
CMD_SRC_NUC,
|
CMD_SRC_NUC,
|
||||||
CMD_SRC_REF,
|
CMD_SRC_REF
|
||||||
},
|
},
|
||||||
.sensitivity = {
|
.pc.map = { /*1<<CMD_KEY_W记录一下不要忘了这个思路 */
|
||||||
.mouse_sens = 0.8f,
|
.key_map[CMD_BEHAVIOR_FORE] = {CMD_KEY_W, CMD_ACTIVE_PRESSED},
|
||||||
.move_sens = 1.0f,
|
.key_map[CMD_BEHAVIOR_BACK] = {CMD_KEY_S, CMD_ACTIVE_PRESSED},
|
||||||
.move_fast_mult = 1.5f,
|
.key_map[CMD_BEHAVIOR_LEFT] = {CMD_KEY_A, CMD_ACTIVE_PRESSED},
|
||||||
.move_slow_mult = 0.5f,
|
.key_map[CMD_BEHAVIOR_RIGHT] = {CMD_KEY_D, CMD_ACTIVE_PRESSED},
|
||||||
},
|
.key_map[CMD_BEHAVIOR_ACCELERATE] = {CMD_KEY_SHIFT, CMD_ACTIVE_PRESSED},
|
||||||
.rc_mode_map = {
|
.key_map[CMD_BEHAVIOR_DECELEBRATE] = {CMD_KEY_CTRL, CMD_ACTIVE_PRESSED},
|
||||||
.sw_left_up = CHASSIS_MODE_BREAK,
|
.key_map[CMD_BEHAVIOR_FIRE] = {CMD_L_CLICK, CMD_ACTIVE_PRESSED},
|
||||||
.sw_left_mid = CHASSIS_MODE_FOLLOW_GIMBAL,
|
.key_map[CMD_BEHAVIOR_FIRE_MODE] = {CMD_R_CLICK, CMD_ACTIVE_RISING_EDGE},
|
||||||
.sw_left_down = CHASSIS_MODE_ROTOR,
|
.key_map[CMD_BEHAVIOR_FOLLOWGIMBAL35] = {CMD_KEY_E, CMD_ACTIVE_RISING_EDGE},
|
||||||
.gimbal_sw_up = GIMBAL_MODE_ABSOLUTE,
|
.key_map[CMD_BEHAVIOR_OPENCOVER] = {CMD_KEY_F, CMD_ACTIVE_RISING_EDGE},
|
||||||
.gimbal_sw_mid = GIMBAL_MODE_ABSOLUTE,
|
.key_map[CMD_BEHAVIOR_REVTRIG] = {CMD_KEY_R, CMD_ACTIVE_RISING_EDGE},
|
||||||
.gimbal_sw_down = GIMBAL_MODE_RELATIVE,
|
.key_map[CMD_BEHAVIOR_ROTOR] = {CMD_KEY_G, CMD_ACTIVE_PRESSED},
|
||||||
|
.key_map[CMD_BEHAVIOR_GIMBAL_MODE] = {CMD_KEY_V, CMD_ACTIVE_RISING_EDGE},
|
||||||
|
},
|
||||||
|
.pc.sensitivity={
|
||||||
|
|
||||||
|
.move_sense=0.1f,
|
||||||
|
.sens_mouse=3.0f,
|
||||||
|
.move_fast_sense=2.4f,
|
||||||
|
.move_slow_sense=0.8f
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
power_model_t cha=
|
power_model_t cha=
|
||||||
|
|||||||
@ -16,14 +16,14 @@ extern "C" {
|
|||||||
#include "module/gimbal.h"
|
#include "module/gimbal.h"
|
||||||
#include "module/chassis.h"
|
#include "module/chassis.h"
|
||||||
#include "module/track.h"
|
#include "module/track.h"
|
||||||
#include "module/cmd_v2/cmd.h"
|
#include "module/cmd.h"
|
||||||
#include "component/PowerControl.h"
|
#include "component/PowerControl.h"
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Shoot_Params_t shoot_param;
|
Shoot_Params_t shoot_param;
|
||||||
Gimbal_Params_t gimbal_param;
|
Gimbal_Params_t gimbal_param;
|
||||||
Chassis_Params_t chassis_param;
|
Chassis_Params_t chassis_param;
|
||||||
Track_Params_t track_param;
|
Track_Params_t track_param;
|
||||||
CMD_Config_t cmd_param;
|
CMD_Params_t cmd_param;
|
||||||
} Config_RobotParam_t;
|
} Config_RobotParam_t;
|
||||||
|
|
||||||
extern power_model_t cha;
|
extern power_model_t cha;
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
#include "module/chassis.h"
|
#include "module/chassis.h"
|
||||||
#include "module/gimbal.h"
|
#include "module/gimbal.h"
|
||||||
#include "module/shoot.h"
|
#include "module/shoot.h"
|
||||||
#include "module/cmd_v2/cmd.h"
|
#include "module/cmd.h"
|
||||||
//#define DEAD_AREA 0.05f
|
//#define DEAD_AREA 0.05f
|
||||||
/* USER INCLUDE END */
|
/* USER INCLUDE END */
|
||||||
|
|
||||||
@ -26,11 +26,11 @@ DR16_t cmd_dr16;
|
|||||||
#elif CMD_RCTypeTable_Index == 1
|
#elif CMD_RCTypeTable_Index == 1
|
||||||
AT9S_t cmd_at9s;
|
AT9S_t cmd_at9s;
|
||||||
#endif
|
#endif
|
||||||
Shoot_CMD_t *cmd_for_shoot;
|
Shoot_CMD_t cmd_for_shoot;
|
||||||
Chassis_CMD_t *cmd_for_chassis;
|
Chassis_CMD_t cmd_for_chassis;
|
||||||
Gimbal_CMD_t *cmd_for_gimbal;
|
Gimbal_CMD_t cmd_for_gimbal;
|
||||||
|
|
||||||
static CMD_t cmd;
|
CMD_t cmd;
|
||||||
/* USER STRUCT END */
|
/* USER STRUCT END */
|
||||||
|
|
||||||
/* Private function --------------------------------------------------------- */
|
/* Private function --------------------------------------------------------- */
|
||||||
@ -46,7 +46,7 @@ void Task_cmd(void *argument) {
|
|||||||
|
|
||||||
uint32_t tick = osKernelGetTickCount(); /* 控制任务运行频率的计时 */
|
uint32_t tick = osKernelGetTickCount(); /* 控制任务运行频率的计时 */
|
||||||
/* USER CODE INIT BEGIN */
|
/* USER CODE INIT BEGIN */
|
||||||
CMD_Init(&cmd, &Config_GetRobotParam()->cmd_param);
|
Cmd_Init(&cmd, &Config_GetRobotParam()->cmd_param);
|
||||||
/* USER CODE INIT END */
|
/* USER CODE INIT END */
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -57,18 +57,17 @@ void Task_cmd(void *argument) {
|
|||||||
#elif CMD_RCTypeTable_Index == 1
|
#elif CMD_RCTypeTable_Index == 1
|
||||||
osMessageQueueGet(task_runtime.msgq.cmd.rc, &cmd_at9s, NULL, 0);
|
osMessageQueueGet(task_runtime.msgq.cmd.rc, &cmd_at9s, NULL, 0);
|
||||||
#endif
|
#endif
|
||||||
CMD_Update(&cmd);
|
Cmd_Get(&cmd,cmd_dr16);
|
||||||
|
Cmd_GenerateCommand(&cmd);
|
||||||
/* 获取命令发送到各模块 */
|
cmd_for_shoot=cmd.output.shoot.cmd;
|
||||||
cmd_for_chassis = CMD_GetChassisCmd(&cmd);
|
cmd_for_chassis=cmd.output.chassis.cmd;
|
||||||
cmd_for_gimbal = CMD_GetGimbalCmd(&cmd);
|
cmd_for_gimbal=cmd.output.gimbal.cmd;
|
||||||
cmd_for_shoot = CMD_GetShootCmd(&cmd);
|
|
||||||
osMessageQueueReset(task_runtime.msgq.gimbal.cmd);
|
osMessageQueueReset(task_runtime.msgq.gimbal.cmd);
|
||||||
osMessageQueuePut(task_runtime.msgq.gimbal.cmd, cmd_for_gimbal, 0, 0);
|
osMessageQueuePut(task_runtime.msgq.gimbal.cmd, &cmd_for_gimbal, 0, 0);
|
||||||
osMessageQueueReset(task_runtime.msgq.shoot.cmd);
|
osMessageQueueReset(task_runtime.msgq.shoot.cmd);
|
||||||
osMessageQueuePut(task_runtime.msgq.shoot.cmd, cmd_for_shoot, 0, 0);
|
osMessageQueuePut(task_runtime.msgq.shoot.cmd, &cmd_for_shoot, 0, 0);
|
||||||
osMessageQueueReset(task_runtime.msgq.chassis.cmd);
|
osMessageQueueReset(task_runtime.msgq.chassis.cmd);
|
||||||
osMessageQueuePut(task_runtime.msgq.chassis.cmd, cmd_for_chassis, 0, 0);
|
osMessageQueuePut(task_runtime.msgq.chassis.cmd, &cmd_for_chassis, 0, 0);
|
||||||
/* USER CODE END */
|
/* USER CODE END */
|
||||||
osDelayUntil(tick); /* 运行结束,等待下一次唤醒 */
|
osDelayUntil(tick); /* 运行结束,等待下一次唤醒 */
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
File :
|
File :
|
||||||
Created : 16. Dec 2025 21:10
|
Created : 02. Nov 2025 13:12
|
||||||
Ozone Version : V3.40b
|
Ozone Version : V3.40b
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -32,6 +32,7 @@ void OnProjectLoad (void) {
|
|||||||
//
|
//
|
||||||
// User settings
|
// User settings
|
||||||
//
|
//
|
||||||
|
Edit.SysVar (VAR_HSS_SPEED, "200 Hz");
|
||||||
File.Open ("D:/CUBEMX/hero/god-yuan-hero/build/Debug/hero.elf");
|
File.Open ("D:/CUBEMX/hero/god-yuan-hero/build/Debug/hero.elf");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -337,25 +338,8 @@ void AfterTargetDownload (void) {
|
|||||||
**********************************************************************
|
**********************************************************************
|
||||||
*/
|
*/
|
||||||
void _SetupTarget(void) {
|
void _SetupTarget(void) {
|
||||||
unsigned int SP;
|
|
||||||
unsigned int PC;
|
|
||||||
unsigned int VectorTableAddr;
|
|
||||||
|
|
||||||
VectorTableAddr = Elf.GetBaseAddr();
|
|
||||||
//
|
//
|
||||||
// Set up initial stack pointer
|
// this function is intentionally empty because both inital PC and
|
||||||
|
// initial SP were chosen not to be set
|
||||||
//
|
//
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -1,56 +1,78 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
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/shoot.c:367:7, State=BP_STATE_DISABLED
|
||||||
Breakpoint=D:/CUBEMX/hero/god-yuan-hero/User/module/cmd_v2/cmd.c:249:16, State=BP_STATE_DISABLED
|
GraphedExpression="(((shoot).feedback).fric[0]).rotor_speed", Color=#e56a6f
|
||||||
GraphedExpression="(cmd).active_source", DisplayFormat=DISPLAY_FORMAT_DEC, Color=#e56a6f
|
GraphedExpression="(((shoot).feedback).fric[1]).rotor_speed", Color=#35792b
|
||||||
GraphedExpression="(((cmd).output).chassis).source", DisplayFormat=DISPLAY_FORMAT_DEC, Color=#35792b
|
GraphedExpression="(((shoot).feedback).fric[2]).rotor_speed", Color=#769dda
|
||||||
GraphedExpression="((((cmd).input).pc).keyboard).bitmap", DisplayFormat=DISPLAY_FORMAT_DEC, Color=#769dda, Show=0
|
GraphedExpression="(((shoot).feedback).fric[3]).rotor_speed", Color=#b14f0d
|
||||||
GraphedExpression="((dr16).raw_data).key", DisplayFormat=DISPLAY_FORMAT_DEC, Color=#b14f0d, Show=0
|
GraphedExpression="(((shoot).feedback).fric[4]).rotor_speed", Color=#b3c38e
|
||||||
OpenDocument="stm32f4xx_hal_can.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c", Line=1614
|
GraphedExpression="(((shoot).feedback).fric[5]).rotor_speed", Color=#ab7b05
|
||||||
OpenDocument="startup_stm32f407xx.s", FilePath="D:/CUBEMX/hero/god-yuan-hero/startup_stm32f407xx.s", Line=48
|
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="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="can.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/bsp/can.c", Line=69
|
||||||
OpenDocument="ctrl_shoot.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/task/ctrl_shoot.c", Line=2
|
|
||||||
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="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="device.h", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/device/device.h", Line=5
|
||||||
OpenDocument="cmd_adapter.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/module/cmd_v2/cmd_adapter.c", Line=88
|
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_v2/cmd.c", Line=81
|
OpenDocument="cmd.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/module/cmd.c", Line=416
|
||||||
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=0
|
||||||
OpenDocument="cmd.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/task/cmd.c", Line=28
|
OpenDocument="pid.h", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/component/pid.h", Line=53
|
||||||
OpenDocument="rc.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/task/rc.c", Line=0
|
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="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="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
|
||||||
OpenToolbar="Debug", Floating=0, x=0, y=0
|
OpenToolbar="Debug", Floating=0, x=0, y=0
|
||||||
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="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="Source Files", DockArea=LEFT, x=0, y=0, w=301, h=919, TabPos=0, TopOfStack=1, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=0
|
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=409, 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=509, TabPos=0, TopOfStack=1, 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="Functions", DockArea=LEFT, x=0, y=0, w=301, h=919, TabPos=1, TopOfStack=0, 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=984, h=536, TabPos=0, TopOfStack=1, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=0, VisibleTab=0, UniformSampleSpacing=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=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="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=984, h=536, TabPos=1, TopOfStack=0, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=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
|
||||||
SmartViewPlugin="", Page="", Toolbar="Hidden", Window="SmartView 1"
|
SmartViewPlugin="", Page="", Toolbar="Hidden", Window="SmartView 1"
|
||||||
TableHeader="Registers 1", SortCol="Name", SortOrder="ASCENDING", VisibleCols=["Name";"Value";"Description"], ColWidths=[120;144;294]
|
TableHeader="Watched Data 2", SortCol="Expression", SortOrder="ASCENDING", VisibleCols=["Expression";"Value";"Location";"Refresh"], ColWidths=[170;352;100;104]
|
||||||
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";" (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="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="RegisterSelectionDialog", SortCol="None", SortOrder="ASCENDING", VisibleCols=[], ColWidths=[]
|
||||||
|
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="TargetExceptionDialog", SortCol="Name", SortOrder="ASCENDING", VisibleCols=["Name";"Value";"Address";"Description"], ColWidths=[200;100;100;366]
|
TableHeader="TargetExceptionDialog", SortCol="Name", SortOrder="ASCENDING", VisibleCols=["Name";"Value";"Address";"Description"], ColWidths=[200;100;100;366]
|
||||||
WatchedExpression="dr16", RefreshRate=5, Window=Watched Data 1
|
WatchedExpression="0x20008DD8", Window=Watched Data 1
|
||||||
WatchedExpression="cmd_dr16", RefreshRate=5, Window=Watched Data 1
|
|
||||||
WatchedExpression="cmd", RefreshRate=5, Window=Watched Data 1
|
WatchedExpression="cmd", RefreshRate=5, Window=Watched Data 1
|
||||||
WatchedExpression="g_adapters", RefreshRate=5, Window=Watched Data 1
|
WatchedExpression="robot_config", RefreshRate=5, Window=Watched Data 1
|
||||||
WatchedExpression="cmd_for_chassis", 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="shoot_cmd", RefreshRate=5, Window=Watched Data 1
|
||||||
WatchedExpression="cmd_for_gimbal", RefreshRate=5, Window=Watched Data 1
|
WatchedExpression="chassis", RefreshRate=5, Window=Watched Data 1
|
||||||
WatchedExpression="last_shift", Window=Watched Data 1
|
WatchedExpression="chassis_cmd", RefreshRate=5, Window=Watched Data 1
|
||||||
WatchedExpression="now_shift", Window=Watched Data 1
|
WatchedExpression="gimbal_cmd", RefreshRate=5, Window=Watched Data 1
|
||||||
WatchedExpression="last_v", Window=Watched Data 1
|
WatchedExpression="gimbal", RefreshRate=5, Window=Watched Data 1
|
||||||
WatchedExpression="now_v", 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
|
||||||
Loading…
Reference in New Issue
Block a user