This commit is contained in:
yxming66 2025-12-05 19:35:08 +08:00
parent d6e889b0a7
commit 14aef5da76
14 changed files with 497 additions and 464 deletions

13
.vscode/settings.json vendored
View File

@ -14,5 +14,16 @@
"starm-clangd", "starm-clangd",
"--query-driver=${env:CUBE_BUNDLE_PATH}/gnu-tools-for-stm32/13.3.1+st.9/bin/arm-none-eabi-gcc.exe", "--query-driver=${env:CUBE_BUNDLE_PATH}/gnu-tools-for-stm32/13.3.1+st.9/bin/arm-none-eabi-gcc.exe",
"--query-driver=${env:CUBE_BUNDLE_PATH}/gnu-tools-for-stm32/13.3.1+st.9/bin/arm-none-eabi-g++.exe" "--query-driver=${env:CUBE_BUNDLE_PATH}/gnu-tools-for-stm32/13.3.1+st.9/bin/arm-none-eabi-g++.exe"
] ],
"[c]": {
"editor.tabSize": 2,
"editor.insertSpaces": true,
"editor.detectIndentation": false
},
"[cpp]": {
"editor.tabSize": 2,
"editor.insertSpaces": true,
"editor.detectIndentation": false
}
} }

View File

@ -80,7 +80,7 @@ void AT9S_ParseRaw(const uint8_t raw[AT9S_FRAME_LEN], AT9S_t *out)
((v) >= 500 && (v) < 1500) ? AT9S_CMD_SW_MID : \ ((v) >= 500 && (v) < 1500) ? AT9S_CMD_SW_MID : \
((v) >= 1500 && (v) < 1700) ? AT9S_CMD_SW_UP : AT9S_CMD_SW_ERR ((v) >= 1500 && (v) < 1700) ? AT9S_CMD_SW_UP : AT9S_CMD_SW_ERR
#define MAP_SWITCH_2(v) \ #define MAP_SWITCH_RESERVE(v) \
((v) > 300 && (v) < 500) ? AT9S_CMD_SW_UP : \ ((v) > 300 && (v) < 500) ? AT9S_CMD_SW_UP : \
((v) >= 500 && (v) < 1500) ? AT9S_CMD_SW_MID : \ ((v) >= 500 && (v) < 1500) ? AT9S_CMD_SW_MID : \
((v) >= 1500 && (v) < 1700) ? AT9S_CMD_SW_DOWN : AT9S_CMD_SW_ERR ((v) >= 1500 && (v) < 1700) ? AT9S_CMD_SW_DOWN : AT9S_CMD_SW_ERR
@ -104,13 +104,13 @@ void AT9S_ParseRaw(const uint8_t raw[AT9S_FRAME_LEN], AT9S_t *out)
// out->data.ch_l_y = r.ch[2]; // out->data.ch_l_y = r.ch[2];
// out->data.ch_l_x = r.ch[3]; // out->data.ch_l_x = r.ch[3];
out->data.rc.key_A = MAP_SWITCH_2(r.sw[0]); out->data.rc.key_A = MAP_SWITCH_RESERVE(r.sw[0]);
out->data.rc.key_B = MAP_SWITCH_2(r.sw[1]); out->data.rc.key_B = MAP_SWITCH_RESERVE(r.sw[1]);
out->data.rc.key_C = MAP_SWITCH_2(r.sw[2]); out->data.rc.key_C = MAP_SWITCH_RESERVE(r.sw[2]);
out->data.rc.key_D = MAP_SWITCH(r.sw[3]); out->data.rc.key_D = MAP_SWITCH(r.sw[3]);
out->data.rc.key_E = MAP_SWITCH(r.sw[4]); out->data.rc.key_E = MAP_SWITCH(r.sw[4]);
out->data.rc.key_F = MAP_SWITCH(r.sw[5]); out->data.rc.key_F = MAP_SWITCH(r.sw[5]);
out->data.rc.key_G = MAP_SWITCH_2(r.sw[6]); out->data.rc.key_G = MAP_SWITCH_RESERVE(r.sw[6]);
out->data.rc.key_H = MAP_SWITCH(r.sw[7]); out->data.rc.key_H = MAP_SWITCH(r.sw[7]);
// out->knob_left = MAP_SWITCH(r.sw[6]); // out->knob_left = MAP_SWITCH(r.sw[6]);
// out->knob_right = MAP_SWITCH(r.sw[7]); // out->knob_right = MAP_SWITCH(r.sw[7]);

View File

@ -6,42 +6,23 @@
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include "bsp/time.h" #include "bsp/time.h"
#include "device/vt13.h" #include "module/gimbal.h"
#include "module/shoot.h"
/*************************************************************************************************************************************/ /*************************************************************************************************************************************/
/****************************************************************RC*******************************************************************/ /****************************************************************RC*******************************************************************/
/*************************************************************************************************************************************/ /*************************************************************************************************************************************/
/* 扩展接口 */
#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
/* Includes ----------------------------------------------------------------- */
#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
/* Private macro ------------------------------------------------------------ */ /* Private macro ------------------------------------------------------------ */
/* 声明外部rc数据变量 */ /* 声明外部rc数据变量 */
#define CMDMACRO_EXTERNAL_RCDATA(name, NAME) extern NAME##_t name; #define CMDMACRO_EXTERNAL_RCDATA(name, NAME) extern NAME##_t name;
#define CMDMACRO_NAME_EXPANSION_1(name, NAME) name
/* 声明CMD结构体的RC数据变量 */ /* 声明CMD结构体的RC数据变量 */
#define CMDMACRO_VAR_RCDATA(name, NAME) NAME##_DataRC_t name; #define CMDMACRO_VAR_RCDATA(name, NAME) NAME##_DataRC_t name;
/* 宏生成Cmd_RC_Get函数内容 */ /* 宏生成Cmd_RC_Get函数内容 */
#define CMDMACRO_Cmd_RC_Get(name, NAME) \ #define CMDMACRO_Cmd_RC_Get(name, NAME) \
bool online= name.header.online; \ c->input.rc.name= name.data.rc; \
rc_buffer.name= name.data.rc; \ c->input.rc.online=name.header.online; \
rc->online=online; \ c->input.rc.type=CMD_RCTypeTable_Index;
rc->type = CMD_RCTypeTable_Index;
union CMD_RC_Data_t{
CMD_RCType_TABLE(CMDMACRO_VAR_RCDATA)
};
CMD_RCType_TABLE(CMDMACRO_EXTERNAL_RCDATA) CMD_RCType_TABLE(CMDMACRO_EXTERNAL_RCDATA)
/* Private typedef ---------------------------------------------------------- */ /* Private typedef ---------------------------------------------------------- */
@ -49,10 +30,13 @@ CMD_RCType_TABLE(CMDMACRO_EXTERNAL_RCDATA)
/* Private variables -------------------------------------------------------- */ /* Private variables -------------------------------------------------------- */
/*静态缓冲区*/ /*静态缓冲区*/
CMD_RC_Data_t rc_buffer;
/* Private function -------------------------------------------------------- */ /* Private function -------------------------------------------------------- */
int8_t Cmd_RC_Get(CMD_Input_RC_t *rc){ 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); CMD_RCType_TABLE(CMDMACRO_Cmd_RC_Get);
return CMD_OK; return CMD_OK;
} }
@ -62,7 +46,7 @@ int8_t Cmd_RC_BuildChassisCommandFromInput(CMD_t *c) {
return CMD_ERR_NULL; // 参数错误 return CMD_ERR_NULL; // 参数错误
} }
#if CMD_RCTypeTable_Index == 0 #if CMD_RCTypeTable_Index == 0
switch (c->input.rc.data->dr16.sw_l) { switch (c->input.rc.dr16.sw_l) {
case DR16_SW_DOWN: case DR16_SW_DOWN:
c->output.chassis.cmd.mode = CHASSIS_MODE_ROTOR; c->output.chassis.cmd.mode = CHASSIS_MODE_ROTOR;
break; break;
@ -76,8 +60,8 @@ int8_t Cmd_RC_BuildChassisCommandFromInput(CMD_t *c) {
c->output.chassis.cmd.mode = CHASSIS_MODE_RELAX; c->output.chassis.cmd.mode = CHASSIS_MODE_RELAX;
break; break;
} }
c->output.chassis.cmd.ctrl_vec.vx = c->input.rc.data->dr16.ch_r_x; c->output.chassis.cmd.ctrl_vec.vx = c->input.rc.dr16.ch_r_x;
c->output.chassis.cmd.ctrl_vec.vy = c->input.rc.data->dr16.ch_r_y; c->output.chassis.cmd.ctrl_vec.vy = c->input.rc.dr16.ch_r_y;
#elif CMD_RCTypeTable_Index == 1 #elif CMD_RCTypeTable_Index == 1
switch (c->input.rc.data->at9s.key_E) { switch (c->input.rc.data->at9s.key_E) {
case AT9S_CMD_SW_DOWN: case AT9S_CMD_SW_DOWN:
@ -104,21 +88,21 @@ int8_t Cmd_RC_BuildGimbalCommandFromInput(CMD_t *c) {
return CMD_ERR_NULL; // 参数错误 return CMD_ERR_NULL; // 参数错误
} }
#if CMD_RCTypeTable_Index == 0 #if CMD_RCTypeTable_Index == 0
switch (c->input.rc.data->dr16.sw_l) { switch (c->input.rc.dr16.sw_l) {
case DR16_SW_DOWN: case DR16_SW_DOWN:
c->output.gimbal.cmd.mode = GIMBAL_MODE_ABSOLUTE; c->output.gimbal.cmd.mode = GIMBAL_MODE_RELATIVE;
c->output.gimbal.cmd.delta_yaw = 0.0f; c->output.gimbal.cmd.delta_yaw = -c->input.rc.dr16.ch_l_x * 2.0f;
c->output.gimbal.cmd.delta_pit = 0.0f; c->output.gimbal.cmd.delta_pit = -c->input.rc.dr16.ch_l_y * 1.5f;
break; break;
case DR16_SW_MID: case DR16_SW_MID:
c->output.gimbal.cmd.mode = GIMBAL_MODE_ABSOLUTE; c->output.gimbal.cmd.mode = GIMBAL_MODE_ABSOLUTE;
c->output.gimbal.cmd.delta_yaw = -c->input.rc.data->dr16.ch_l_x * 2.0f; c->output.gimbal.cmd.delta_yaw = -c->input.rc.dr16.ch_l_x * 2.0f;
c->output.gimbal.cmd.delta_pit = -c->input.rc.data->dr16.ch_l_y * 1.5f; c->output.gimbal.cmd.delta_pit = -c->input.rc.dr16.ch_l_y * 1.5f;
break; break;
case DR16_SW_UP: case DR16_SW_UP:
c->output.gimbal.cmd.mode = GIMBAL_MODE_RELAX; c->output.gimbal.cmd.mode = GIMBAL_MODE_ABSOLUTE;
c->output.gimbal.cmd.delta_yaw = -c->input.rc.data->dr16.ch_l_x * 2.0f; c->output.gimbal.cmd.delta_yaw = -c->input.rc.dr16.ch_l_x * 2.0f;
c->output.gimbal.cmd.delta_pit = -c->input.rc.data->dr16.ch_l_y * 1.5f; c->output.gimbal.cmd.delta_pit = -c->input.rc.dr16.ch_l_y * 1.5f;
break; break;
default: default:
c->output.gimbal.cmd.mode = GIMBAL_MODE_RELAX; c->output.gimbal.cmd.mode = GIMBAL_MODE_RELAX;
@ -159,13 +143,12 @@ int8_t Cmd_RC_BuildShootCommandFromInput(CMD_t *c) {
return CMD_ERR_NULL; // 参数错误 return CMD_ERR_NULL; // 参数错误
} }
#if CMD_RCTypeTable_Index == 0 #if CMD_RCTypeTable_Index == 0
c->output.shoot.cmd.online = c->input.rc.online; if (c->input.rc.online) {
if (c->output.shoot.cmd.online) {
c->output.shoot.cmd.mode=SHOOT_MODE_SINGLE; c->output.shoot.cmd.mode=SHOOT_MODE_SINGLE;
} else { } else {
c->output.shoot.cmd.mode=SHOOT_MODE_SAFE; c->output.shoot.cmd.mode=SHOOT_MODE_SAFE;
} }
switch (c->input.rc.data->dr16.sw_r) { switch (c->input.rc.dr16.sw_r) {
case DR16_SW_DOWN: case DR16_SW_DOWN:
c->output.shoot.cmd.ready = true; c->output.shoot.cmd.ready = true;
c->output.shoot.cmd.firecmd = true; c->output.shoot.cmd.firecmd = true;
@ -226,75 +209,107 @@ int8_t Cmd_RC_BuildShootCommandFromInput(CMD_t *c) {
#ifndef CMD_NOPC_FLAG #ifndef CMD_NOPC_FLAG
/* Private macro ------------------------------------------------------------ */ /* Private macro ------------------------------------------------------------ */
#define CMD_PCBehavior_TABLE(X) \ #define CMD_PCBehavior_TABLE(X) \
X(FORE, CMD_MODULE_CHASSIS) \ X(FORE, CMD_MODULE_CHASSIS) \
X(BACK, CMD_MODULE_CHASSIS) \ X(BACK, CMD_MODULE_CHASSIS) \
X(LEFT, CMD_MODULE_CHASSIS) \ X(LEFT, CMD_MODULE_CHASSIS) \
X(RIGHT, CMD_MODULE_CHASSIS) \ X(RIGHT, CMD_MODULE_CHASSIS) \
X(ACCELERATE, CMD_MODULE_CHASSIS) \ X(ACCELERATE, CMD_MODULE_CHASSIS) \
X(DECELEBRATE, CMD_MODULE_CHASSIS) \ X(DECELEBRATE, CMD_MODULE_CHASSIS) \
X(FIRE, CMD_MODULE_SHOOT) \ X(FIRE, CMD_MODULE_SHOOT) \
X(FIRE_MODE, CMD_MODULE_SHOOT) \ X(FIRE_MODE, CMD_MODULE_SHOOT) \
X(BUFF, CMD_MODULE_SHOOT) \ X(BUFF, CMD_MODULE_SHOOT) \
X(AUTOAIM, CMD_MODULE_GIMBAL | CMD_MODULE_SHOOT) \ X(AUTOAIM, CMD_MODULE_GIMBAL | CMD_MODULE_SHOOT) \
X(OPENCOVER, CMD_MODULE_SHOOT) \ X(OPENCOVER, CMD_MODULE_SHOOT) \
X(ROTOR, CMD_MODULE_CHASSIS) \ X(ROTOR, CMD_MODULE_CHASSIS) \
X(REVTRIG, CMD_MODULE_SHOOT) \ X(REVTRIG, CMD_MODULE_SHOOT) \
X(FOLLOWGIMBAL35, CMD_MODULE_CHASSIS) X(FOLLOWGIMBAL35, CMD_MODULE_CHASSIS) \
X(GIMBAL_MODE, CMD_MODULE_GIMBAL)
/* 行为处理函数声明宏 */ /* 行为处理函数声明宏 */
#define CMDMACRO_FOR_DECLARE_BEHAVIOR_HANDLER_FUNCTION(BEHAVIOR, MODULE_MASK) \ #define CMDMACRO_FOR_DECLARE_BEHAVIOR_HANDLER_FUNCTION(BEHAVIOR, MODULE_MASK) \
static int8_t Cmd_PC_HandleBehavior##BEHAVIOR(CMD_t *c); static int8_t Cmd_PC_HandleBehavior##BEHAVIOR(CMD_t *c);
/* 行为处理函数指针数组构建宏 */ /* 行为处理函数指针数组构建宏 */
#define CMDMACRO_FOR_BUILD_BEHAVIOR_HANDLER_ARRAY(BEHAVIOR, MODULE_MASK) \ #define CMDMACRO_FOR_BUILD_BEHAVIOR_HANDLER_ARRAY(BEHAVIOR, MODULE_MASK) \
{CMD_BEHAVIOR_##BEHAVIOR, Cmd_PC_HandleBehavior##BEHAVIOR}, {CMD_BEHAVIOR_##BEHAVIOR, Cmd_PC_HandleBehavior##BEHAVIOR},
/* 行为模块映射表构建宏 */ /* 行为模块映射表构建宏 */
#define CMDMACRO_FOR_BUILD_MODULE_TABLE(BEHAVIOR, MODULE_MASK) \ #define CMDMACRO_FOR_BUILD_MODULE_TABLE(BEHAVIOR, MODULE_MASK) \
[CMD_BEHAVIOR_##BEHAVIOR] = MODULE_MASK, [CMD_BEHAVIOR_##BEHAVIOR] = MODULE_MASK,
/* 行为处理函数声明 */ /* 行为处理函数声明 */
CMD_PCBehavior_TABLE(CMDMACRO_FOR_DECLARE_BEHAVIOR_HANDLER_FUNCTION) CMD_PCBehavior_TABLE(CMDMACRO_FOR_DECLARE_BEHAVIOR_HANDLER_FUNCTION)
#define CMDMACRO_VAR_PCDATA(name, NAME) NAME##_DataPC_t name;
/* 宏展开函数内容 */ /* 宏展开函数内容 */
#define CMDMACRO_Cmd_PC_Get(name, NAME) \ #define CMDMACRO_Cmd_PC_Get(name, NAME) \
bool online= name.header.online; \ c->input.pc.online=name.header.online;\
pc_buffer.name= name.data.pc; \ c->input.pc.name= name.data.pc;
pc->online=online; #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) \ #define CMDMACRO_PC_BuildChassisCommandFromInput(name, NAME) \
c->output.chassis.cmd.ctrl_vec.vx = 0.0f; \ if (c->input.pc.online) {c->output.chassis.cmd.mode = CHASSIS_MODE_FOLLOW_GIMBAL;} \
c->output.chassis.cmd.ctrl_vec.vy = 0.0f; \ else {c->output.chassis.cmd.mode = CHASSIS_MODE_RELAX;} \
for (size_t i = 0; i < CMD_BEHAVIOR_NUM; i++) { \ c->output.chassis.cmd.ctrl_vec.vx = 0.0f; \
CMD_ModuleMask_t moduleMask = behaviorModuleTable[i]; \ c->output.chassis.cmd.ctrl_vec.vy = 0.0f; \
if (CMD_PC_IsMaskMatch(c, moduleMask)) { \ for (size_t i = 0; i < CMD_BEHAVIOR_NUM; i++) { \
if (CMD_PC_IsBehaviorTriggered(c, i)) { \ CMD_ModuleMask_t moduleMask = behaviorModuleTable[i]; \
behaviorHandlerFuncTable[i].func(c); \ 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) \ #define CMDMACRO_PC_BuildGimbalCommandFromInput(name, NAME) \
c->output.gimbal.cmd.mode = GIMBAL_MODE_ABSOLUTE; \ static bool init = false; \
c->output.gimbal.cmd.delta_yaw = (float)c->input.pc.data->name.mouse.x * c->timer.dt * c->params->pc.sensitivity.sens_mouse; \ if (!init) {c->output.gimbal.cmd.mode = GIMBAL_MODE_ABSOLUTE;init=!init;}\
c->output.gimbal.cmd.delta_pit = (float)c->input.pc.data->name.mouse.y * c->timer.dt * c->params->pc.sensitivity.sens_mouse; \ if(!c->input.pc.online) {c->output.gimbal.cmd.mode = GIMBAL_MODE_RELAX;} \
for (size_t i = 0; i < CMD_BEHAVIOR_NUM; i++) { \ c->output.gimbal.cmd.delta_yaw = (float)-c->input.pc.name.mouse.x * c->timer.dt * c->params->pc.sensitivity.sens_mouse; \
CMD_ModuleMask_t moduleMask = behaviorModuleTable[i]; \ c->output.gimbal.cmd.delta_pit = (float)1.5f*c->input.pc.name.mouse.y * c->timer.dt * c->params->pc.sensitivity.sens_mouse; \
if (CMD_PC_IsMaskMatch(c, moduleMask)) { \ for (size_t i = 0; i < CMD_BEHAVIOR_NUM; i++) { \
if (CMD_PC_IsBehaviorTriggered(c, i)) { \ CMD_ModuleMask_t moduleMask = behaviorModuleTable[i]; \
behaviorHandlerFuncTable[i].func(c); \ 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) \ #define CMDMACRO_PC_BuildShootCommandFromInput(name, NAME) \
c->output.shoot.cmd.firecmd = false; \ if (!c->input.pc.online) {c->output.shoot.cmd.mode = SHOOT_MODE_SAFE;} \
for (size_t i = 0; i < CMD_BEHAVIOR_NUM; i++) { \ c->output.shoot.cmd.ready = true; \
CMD_ModuleMask_t moduleMask = behaviorModuleTable[i]; \ c->output.shoot.cmd.firecmd = false; \
if (CMD_PC_IsMaskMatch(c, moduleMask)) { \ for (size_t i = 0; i < CMD_BEHAVIOR_NUM; i++) { \
if (CMD_PC_IsBehaviorTriggered(c, i)) { \ CMD_ModuleMask_t moduleMask = behaviorModuleTable[i]; \
behaviorHandlerFuncTable[i].func(c); \ if (CMD_PC_IsMaskMatch(c, moduleMask)) { \
} \ if (CMD_PC_IsBehaviorTriggered(c, i)) { \
} \ behaviorHandlerFuncTable[i].func(c); \
} \ } \
memcpy(c->input.pc.lastData->name.keyboard.key, c->input.pc.data->name.keyboard.key, sizeof(c->input.pc.data->name.keyboard.key)); \ } \
c->input.pc.lastData->name.mouse.l_click = c->input.pc.data->name.mouse.l_click; \ } \
c->input.pc.lastData->name.mouse.r_click = c->input.pc.data->name.mouse.r_click; 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 ---------------------------------------------------------- */ /* Private typedef ---------------------------------------------------------- */
typedef int8_t (*CMD_BehaviorFunc)(CMD_t *c); typedef int8_t (*CMD_BehaviorFunc)(CMD_t *c);
typedef struct { typedef struct {
@ -302,65 +317,55 @@ typedef struct {
CMD_BehaviorFunc func; CMD_BehaviorFunc func;
} CMD_BehaviorHandlerFunc_t; } CMD_BehaviorHandlerFunc_t;
union CMD_PC_Data_t {
CMD_RCType_TABLE(CMDMACRO_VAR_PCDATA)
};
union CMD_PC_LastData_t {
CMD_RCType_TABLE(CMDMACRO_VAR_PCDATA)
};
/* Private variables -------------------------------------------------------- */ /* Private variables -------------------------------------------------------- */
/* 行为处理函数指针数组 */ /* 行为处理函数指针数组 */
CMD_BehaviorHandlerFunc_t behaviorHandlerFuncTable[CMD_BEHAVIOR_NUM] = { CMD_BehaviorHandlerFunc_t behaviorHandlerFuncTable[CMD_BEHAVIOR_NUM] = {
CMD_PCBehavior_TABLE(CMDMACRO_FOR_BUILD_BEHAVIOR_HANDLER_ARRAY) CMD_PCBehavior_TABLE(CMDMACRO_FOR_BUILD_BEHAVIOR_HANDLER_ARRAY)
}; };
/* 行为模块映射表 */ /* 行为模块映射表 */
static const CMD_ModuleMask_t behaviorModuleTable[CMD_BEHAVIOR_NUM] = { static const CMD_ModuleMask_t behaviorModuleTable[CMD_BEHAVIOR_NUM] = {
CMD_PCBehavior_TABLE(CMDMACRO_FOR_BUILD_MODULE_TABLE) CMD_PCBehavior_TABLE(CMDMACRO_FOR_BUILD_MODULE_TABLE)
}; };
/* 静态缓冲区 */
CMD_PC_Data_t pc_buffer;
CMD_PC_LastData_t pc_lastdata_buffer;
/* Private function -------------------------------------------------------- */ /* Private function -------------------------------------------------------- */
int8_t Cmd_PC_Get(CMD_Input_PC_t *pc){ int8_t Cmd_PC_Get(CMD_t *c, CMD_RCType_TABLE(CMDMACRO_NAME_EXPANSION)){
CMD_RCType_TABLE(CMDMACRO_Cmd_PC_Get); CMD_RCType_TABLE(CMDMACRO_Cmd_PC_Get);
return CMD_OK; return CMD_OK;
} }
static int8_t Cmd_PC_HandleBehaviorFORE(CMD_t *c){ static int8_t Cmd_PC_HandleBehaviorFORE(CMD_t *c){
c->output.chassis.cmd.ctrl_vec.vy += c->params->pc.sensitivity.move_sense; c->output.chassis.cmd.ctrl_vec.vy += c->params->pc.sensitivity.move_sense;
return CMD_OK; return CMD_OK;
} }
static int8_t Cmd_PC_HandleBehaviorBACK(CMD_t *c){ static int8_t Cmd_PC_HandleBehaviorBACK(CMD_t *c){
c->output.chassis.cmd.ctrl_vec.vy -= c->params->pc.sensitivity.move_sense; c->output.chassis.cmd.ctrl_vec.vy -= c->params->pc.sensitivity.move_sense;
return CMD_OK; return CMD_OK;
} }
static int8_t Cmd_PC_HandleBehaviorLEFT(CMD_t *c){ static int8_t Cmd_PC_HandleBehaviorLEFT(CMD_t *c){
c->output.chassis.cmd.ctrl_vec.vx -= c->params->pc.sensitivity.move_sense; c->output.chassis.cmd.ctrl_vec.vx -= c->params->pc.sensitivity.move_sense;
return CMD_OK; return CMD_OK;
} }
static int8_t Cmd_PC_HandleBehaviorRIGHT(CMD_t *c){ static int8_t Cmd_PC_HandleBehaviorRIGHT(CMD_t *c){
c->output.chassis.cmd.ctrl_vec.vx += c->params->pc.sensitivity.move_sense; c->output.chassis.cmd.ctrl_vec.vx += c->params->pc.sensitivity.move_sense;
return CMD_OK; return CMD_OK;
} }
static int8_t Cmd_PC_HandleBehaviorACCELERATE(CMD_t *c){ 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.vx *= c->params->pc.sensitivity.move_fast_sense;
c->output.chassis.cmd.ctrl_vec.vy *= c->params->pc.sensitivity.move_fast_sense; c->output.chassis.cmd.ctrl_vec.vy *= c->params->pc.sensitivity.move_fast_sense;
return CMD_OK; return CMD_OK;
} }
static int8_t Cmd_PC_HandleBehaviorDECELEBRATE(CMD_t *c){ 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.vx *= c->params->pc.sensitivity.move_slow_sense;
c->output.chassis.cmd.ctrl_vec.vy *= c->params->pc.sensitivity.move_slow_sense; c->output.chassis.cmd.ctrl_vec.vy *= c->params->pc.sensitivity.move_slow_sense;
return CMD_OK; return CMD_OK;
} }
static int8_t Cmd_PC_HandleBehaviorFIRE(CMD_t *c){ static int8_t Cmd_PC_HandleBehaviorFIRE(CMD_t *c){
c->output.shoot.cmd.firecmd = true; c->output.shoot.cmd.firecmd = true;
return CMD_OK; return CMD_OK;
} }
static int8_t Cmd_PC_HandleBehaviorFIRE_MODE(CMD_t *c){ static int8_t Cmd_PC_HandleBehaviorFIRE_MODE(CMD_t *c){
c->output.shoot.cmd.mode++; c->output.shoot.cmd.mode++;
c->output.shoot.cmd.mode %= SHOOT_MODE_NUM; c->output.shoot.cmd.mode %= SHOOT_MODE_NUM;
return CMD_OK; return CMD_OK;
} }
static int8_t Cmd_PC_HandleBehaviorBUFF(CMD_t *c){ static int8_t Cmd_PC_HandleBehaviorBUFF(CMD_t *c){
// if (cmd->ai_status == AI_STATUS_HITSWITCH) { // if (cmd->ai_status == AI_STATUS_HITSWITCH) {
@ -390,20 +395,27 @@ static int8_t Cmd_PC_HandleBehaviorAUTOAIM(CMD_t *c){
} }
static int8_t Cmd_PC_HandleBehaviorOPENCOVER(CMD_t *c){ static int8_t Cmd_PC_HandleBehaviorOPENCOVER(CMD_t *c){
// c->shoot.cover_open = !c->shoot.cover_open; // c->shoot.cover_open = !c->shoot.cover_open;
return CMD_OK; return CMD_OK;
} }
static int8_t Cmd_PC_HandleBehaviorROTOR(CMD_t *c){ static int8_t Cmd_PC_HandleBehaviorROTOR(CMD_t *c){
c->output.chassis.cmd.mode = CHASSIS_MODE_ROTOR; c->output.chassis.cmd.mode = CHASSIS_MODE_ROTOR;
c->output.chassis.cmd.mode_rotor = ROTOR_MODE_RAND; c->output.chassis.cmd.mode_rotor = ROTOR_MODE_RAND;
return CMD_OK; return CMD_OK;
} }
static int8_t Cmd_PC_HandleBehaviorREVTRIG(CMD_t *c){ static int8_t Cmd_PC_HandleBehaviorREVTRIG(CMD_t *c){
// c->output.shoot.cmd.reverse_trig = true; // c->output.shoot.cmd.reverse_trig = true;
return CMD_OK; return CMD_OK;
} }
static int8_t Cmd_PC_HandleBehaviorFOLLOWGIMBAL35(CMD_t *c){ static int8_t Cmd_PC_HandleBehaviorFOLLOWGIMBAL35(CMD_t *c){
c->output.chassis.cmd.mode = CHASSIS_MODE_FOLLOW_GIMBAL_35; c->output.chassis.cmd.mode = CHASSIS_MODE_FOLLOW_GIMBAL_35;
return CMD_OK; 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, static inline CMD_PCValue_t CMD_PC_BehaviorToValue(CMD_t *c,
@ -417,131 +429,67 @@ static inline CMD_TriggerType_t CMD_PC_BehaviorToActive(CMD_t *c,
} }
static inline bool CMD_PC_IsMaskMatch(CMD_t *c, CMD_ModuleMask_t module_mask) { static inline bool CMD_PC_IsMaskMatch(CMD_t *c, CMD_ModuleMask_t module_mask) {
/* 构建当前各模块输入源状态的掩码 */ /* 构建当前各模块输入源状态的掩码 */
CMD_ModuleMask_t current_pc_mask = 0; CMD_ModuleMask_t current_pc_mask = 0;
if (c->output.chassis.source == CMD_SRC_PC) current_pc_mask |= CMD_MODULE_CHASSIS; 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.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; 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) == module_mask;
/* 检测交集 */ /* 检测交集 */
// return (module_mask & current_pc_mask) != 0; // return (module_mask & current_pc_mask) != 0;
} }
static inline bool CMD_PC_IsBehaviorTriggered(CMD_t *c, CMD_Behavior_t behavior) { static inline bool CMD_PC_IsBehaviorTriggered(CMD_t *c, CMD_Behavior_t behavior) {
CMD_PCValue_t value = CMD_PC_BehaviorToValue(c, behavior); if (c == NULL) {
CMD_TriggerType_t active = CMD_PC_BehaviorToActive(c, behavior); return CMD_ERR_NULL; // 参数错误
bool now_key_pressed, last_key_pressed;
/* 按下按键为鼠标左、右键 */
if (value == CMD_L_CLICK) {
now_key_pressed = c->input.pc.data->dr16.mouse.l_click;
last_key_pressed = c->input.pc.lastData->dr16.mouse.l_click;
} else if (value == CMD_R_CLICK) {
now_key_pressed = c->input.pc.data->dr16.mouse.r_click;
last_key_pressed = c->input.pc.lastData->dr16.mouse.r_click;
} else {
/* 直接用布尔值 */
now_key_pressed = c->input.pc.data->dr16.keyboard.key[value];
last_key_pressed = c->input.pc.lastData->dr16.keyboard.key[value];
/* 或者用位掩码 */
// now_key_pressed = c->input.pc.data.keyboard.bitmask & (1u << value);
// last_key_pressed = c->input.pc.lastData.keyboard.bitmask & (1u << value);
} }
CMD_RCType_TABLE(CMDMACRO_PC_IsBehaviorTriggered);
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;
} }
static int8_t Cmd_PC_BuildChassisCommandFromInput(CMD_t *c) { static int8_t Cmd_PC_BuildChassisCommandFromInput(CMD_t *c) {
if (c == NULL) { if (c == NULL) {
return CMD_ERR_NULL; // 参数错误 return CMD_ERR_NULL; // 参数错误
} }
// c->output.chassis.cmd.ctrl_vec.vx = c->output.chassis.cmd.ctrl_vec.vy = 0.0f; CMD_RCType_TABLE(CMDMACRO_PC_BuildChassisCommandFromInput);
// for (size_t i = 0; i < CMD_RCType_TABLE(CMDMACRO_KEYNUM); i++) {
// CMD_ModuleMask_t moduleMask = behaviorModuleTable[i];
// if (CMD_PC_IsMaskMatch(c, moduleMask)) {
// if (CMD_PC_IsBehaviorTriggered(c, i)) {
// behaviorHandlerFuncTable[i].func(c);
// }
// }
// }
CMD_RCType_TABLE(CMDMACRO_PC_BuildChassisCommandFromInput);
return CMD_OK;
} }
static int8_t Cmd_PC_BuildGimbalCommandFromInput(CMD_t *c) { static int8_t Cmd_PC_BuildGimbalCommandFromInput(CMD_t *c) {
if (c == NULL) { if (c == NULL) {
return CMD_ERR_NULL; // 参数错误 return CMD_ERR_NULL; // 参数错误
} }
// c->output.gimbal.cmd.mode = GIMBAL_MODE_ABSOLUTE; CMD_RCType_TABLE(CMDMACRO_PC_BuildGimbalCommandFromInput);
// c->output.gimbal.cmd.delta_yaw = (float)c->input.pc.data->dr16.mouse.x * c->timer.dt * c->params->pc.sensitivity.sens_mouse;
// c->output.gimbal.cmd.delta_pit = (float)c->input.pc.data->dr16.mouse.y * c->timer.dt * c->params->pc.sensitivity.sens_mouse;
// for (size_t i = 0; i < CMD_RCType_TABLE(CMDMACRO_KEYNUM); i++) {
// CMD_ModuleMask_t moduleMask = behaviorModuleTable[i];
// if (CMD_PC_IsMaskMatch(c, moduleMask)) {
// if (CMD_PC_IsBehaviorTriggered(c, i)) {
// behaviorHandlerFuncTable[i].func(c);
// }
// }
// }
CMD_RCType_TABLE(CMDMACRO_PC_BuildGimbalCommandFromInput);
return CMD_OK;
} }
static int8_t Cmd_PC_BuildShootCommandFromInput(CMD_t *c) { static int8_t Cmd_PC_BuildShootCommandFromInput(CMD_t *c) {
if (c == NULL) { if (c == NULL) {
return CMD_ERR_NULL; // 参数错误 return CMD_ERR_NULL; // 参数错误
} }
// c->output.shoot.cmd.firecmd = false; CMD_RCType_TABLE(CMDMACRO_PC_BuildShootCommandFromInput);
// for (size_t i = 0; i < CMD_RCType_TABLE(CMDMACRO_KEYNUM); i++) {
// CMD_ModuleMask_t moduleMask = behaviorModuleTable[i];
// if (CMD_PC_IsMaskMatch(c, moduleMask)) {
// if (CMD_PC_IsBehaviorTriggered(c, i)) {
// behaviorHandlerFuncTable[i].func(c);
// }
// }
// }
// memcpy(c->input.pc.lastData->dr16.keyboard.key, c->input.pc.data->dr16.keyboard.key, sizeof(c->input.pc.data->dr16.keyboard.key));
// c->input.pc.lastData->dr16.mouse.l_click = c->input.pc.data->dr16.mouse.l_click;
// c->input.pc.lastData->dr16.mouse.r_click = c->input.pc.data->dr16.mouse.r_click;
CMD_RCType_TABLE(CMDMACRO_PC_BuildShootCommandFromInput);
return CMD_OK;
} }
#else #else
static int8_t Cmd_PC_Get(CMD_Input_PC_t *pc) { static int8_t Cmd_PC_Get(CMD_Input_PC_t *pc) {
pc->online=false; pc->online=false;
return CMD_OK; return CMD_OK;
} }
static int8_t Cmd_PC_BuildChassisCommandFromInput(CMD_t *c) { static int8_t Cmd_PC_BuildChassisCommandFromInput(CMD_t *c) {
if (c == NULL) { if (c == NULL) {
return CMD_ERR_NULL; // 参数错误 return CMD_ERR_NULL; // 参数错误
} }
return CMD_OK;
return CMD_OK;
} }
static int8_t Cmd_PC_BuildGimbalCommandFromInput(CMD_t *c) { static int8_t Cmd_PC_BuildGimbalCommandFromInput(CMD_t *c) {
if (c == NULL) { if (c == NULL) {
return CMD_ERR_NULL; // 参数错误 return CMD_ERR_NULL; // 参数错误
} }
return CMD_OK;
return CMD_OK;
} }
static int8_t Cmd_PC_BuildShootCommandFromInput(CMD_t *c) { static int8_t Cmd_PC_BuildShootCommandFromInput(CMD_t *c) {
if (c == NULL) { if (c == NULL) {
return CMD_ERR_NULL; // 参数错误 return CMD_ERR_NULL; // 参数错误
} }
return CMD_OK;
return CMD_OK;
} }
#endif #endif
@ -556,32 +504,29 @@ static int8_t Cmd_PC_BuildShootCommandFromInput(CMD_t *c) {
/* Private variables -------------------------------------------------------- */ /* Private variables -------------------------------------------------------- */
/* Private function -------------------------------------------------------- */ /* Private function -------------------------------------------------------- */
int8_t Cmd_NUC_Get(CMD_Input_NUC_t *nuc) { int8_t Cmd_NUC_Get(CMD_Input_NUC_t *nuc) {
nuc->online=0; nuc->online=0;
return CMD_OK; return CMD_OK;
} }
/* Exported functions ------------------------------------------------------- */ /* Exported functions ------------------------------------------------------- */
int8_t Cmd_NUC_BuildChassisCommandFromInput(CMD_t *c) { int8_t Cmd_NUC_BuildChassisCommandFromInput(CMD_t *c) {
if (c == NULL) { if (c == NULL) {
return CMD_ERR_NULL; // 参数错误 return CMD_ERR_NULL; // 参数错误
} }
return CMD_OK;
return CMD_OK;
} }
int8_t Cmd_NUC_BuildGimbalCommandFromInput(CMD_t *c) { int8_t Cmd_NUC_BuildGimbalCommandFromInput(CMD_t *c) {
if (c == NULL) { if (c == NULL) {
return CMD_ERR_NULL; // 参数错误 return CMD_ERR_NULL; // 参数错误
} }
return CMD_OK;
return CMD_OK;
} }
int8_t Cmd_NUC_BuildShootCommandFromInput(CMD_t *c) { int8_t Cmd_NUC_BuildShootCommandFromInput(CMD_t *c) {
if (c == NULL) { if (c == NULL) {
return CMD_ERR_NULL; // 参数错误 return CMD_ERR_NULL; // 参数错误
} }
return CMD_OK;
return CMD_OK;
} }
/*************************************************************************************************************************************/ /*************************************************************************************************************************************/
@ -595,32 +540,29 @@ int8_t Cmd_NUC_BuildShootCommandFromInput(CMD_t *c) {
/* Private variables -------------------------------------------------------- */ /* Private variables -------------------------------------------------------- */
/* Private function -------------------------------------------------------- */ /* Private function -------------------------------------------------------- */
int8_t Cmd_REF_Get(CMD_Input_REF_t *nuc) { int8_t Cmd_REF_Get(CMD_Input_REF_t *nuc) {
nuc->online=0; nuc->online=0;
return CMD_OK; return CMD_OK;
} }
/* Exported functions ------------------------------------------------------- */ /* Exported functions ------------------------------------------------------- */
int8_t Cmd_REF_BuildChassisCommandFromInput(CMD_t *c) { int8_t Cmd_REF_BuildChassisCommandFromInput(CMD_t *c) {
if (c == NULL) { if (c == NULL) {
return CMD_ERR_NULL; // 参数错误 return CMD_ERR_NULL; // 参数错误
} }
return CMD_OK;
return CMD_OK;
} }
int8_t Cmd_REF_BuildGimbalCommandFromInput(CMD_t *c) { int8_t Cmd_REF_BuildGimbalCommandFromInput(CMD_t *c) {
if (c == NULL) { if (c == NULL) {
return CMD_ERR_NULL; // 参数错误 return CMD_ERR_NULL; // 参数错误
} }
return CMD_OK;
return CMD_OK;
} }
int8_t Cmd_REF_BuildShootCommandFromInput(CMD_t *c) { int8_t Cmd_REF_BuildShootCommandFromInput(CMD_t *c) {
if (c == NULL) { if (c == NULL) {
return CMD_ERR_NULL; // 参数错误 return CMD_ERR_NULL; // 参数错误
} }
return CMD_OK;
return CMD_OK;
} }
/*************************************************************************************************************************************/ /*************************************************************************************************************************************/
/***************************************************************仲裁器****************************************************************/ /***************************************************************仲裁器****************************************************************/
@ -637,54 +579,53 @@ 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_isRCOnline(CMD_t *c){return c->input.rc.online;}
static inline bool Cmd_isPCOnline(CMD_t *c){return c->input.pc.online;} static inline bool Cmd_isPCOnline(CMD_t *c){return c->input.pc.online;}
CMD_InputSource_t Cmd_GetHighestPrioritySource(CMD_t *c) { CMD_InputSource_t Cmd_GetHighestPrioritySource(CMD_t *c) {
for (int i = 0; i < CMD_SRC_NUM; i++) { for (int i = 0; i < CMD_SRC_NUM; i++) {
CMD_InputSource_t source = c->params->sourcePriorityConfigs[i].source; CMD_InputSource_t source = c->params->sourcePriorityConfigs[i];
switch (source) { switch (source) {
case CMD_SRC_REF: case CMD_SRC_REF:
if (Cmd_isREFOnline(c)) { if (Cmd_isREFOnline(c)) {
return CMD_SRC_REF; 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_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_SRC_ERR; }
return CMD_ERR_SOURCE;
} }
int8_t Cmd_Arbiter(CMD_t *c) { int8_t Cmd_Arbiter(CMD_t *c) {
if (c == NULL) { if (c == NULL) {
return CMD_ERR_NULL; // 参数错误 return CMD_ERR_NULL; // 参数错误
} }
CMD_InputSource_t source = Cmd_GetHighestPrioritySource(c); CMD_InputSource_t source = Cmd_GetHighestPrioritySource(c);
c->output.chassis.source = source;
c->output.chassis.source = source; c->output.gimbal.source = source;
c->output.gimbal.source = source; c->output.shoot.source = source;
c->output.shoot.source = source; return CMD_OK;
return CMD_OK;
} }
int8_t Cmd_Switch_RCorPC(CMD_t *c) { int8_t Cmd_Switch_RCorPC(CMD_t *c) {
if (c == NULL) { if (c == NULL) {
return CMD_ERR_NULL; // 参数错误 return CMD_ERR_NULL; // 参数错误
} }
return CMD_OK; return CMD_OK;
} }
/*************************************************************************************************************************************/ /*************************************************************************************************************************************/
@ -695,62 +636,68 @@ int8_t Cmd_Switch_RCorPC(CMD_t *c) {
/* Private typedef ---------------------------------------------------------- */ /* Private typedef ---------------------------------------------------------- */
typedef int8_t (*CMD_BuildCommandFunc)(CMD_t *c); typedef int8_t (*CMD_BuildCommandFunc)(CMD_t *c);
typedef struct { typedef struct {
CMD_InputSource_t source; CMD_InputSource_t source;
CMD_BuildCommandFunc chassisFunc; CMD_BuildCommandFunc chassisFunc;
CMD_BuildCommandFunc gimbalFunc; CMD_BuildCommandFunc gimbalFunc;
CMD_BuildCommandFunc shootFunc; CMD_BuildCommandFunc shootFunc;
} CMD_SourceHandler_t; } CMD_SourceHandler_t;
/* Private macro ------------------------------------------------------------ */ /* Private macro ------------------------------------------------------------ */
/* Private variables -------------------------------------------------------- */ /* Private variables -------------------------------------------------------- */
CMD_SourceHandler_t sourceHandlers[CMD_SRC_NUM] = { CMD_SourceHandler_t sourceHandlers[CMD_SRC_NUM] = {
{CMD_SRC_RC, Cmd_RC_BuildChassisCommandFromInput, Cmd_RC_BuildGimbalCommandFromInput, Cmd_RC_BuildShootCommandFromInput}, {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_PC, Cmd_PC_BuildChassisCommandFromInput, Cmd_PC_BuildGimbalCommandFromInput, Cmd_PC_BuildShootCommandFromInput},
{CMD_SRC_NUC, Cmd_NUC_BuildChassisCommandFromInput, Cmd_NUC_BuildGimbalCommandFromInput, Cmd_NUC_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}, {CMD_SRC_REF, Cmd_REF_BuildChassisCommandFromInput, Cmd_REF_BuildGimbalCommandFromInput, Cmd_REF_BuildShootCommandFromInput},
}; };
/* Private function -------------------------------------------------------- */ /* Private function -------------------------------------------------------- */
int8_t Cmd_OFFLINE(CMD_t *c) { int8_t Cmd_OFFLINE(CMD_t *c) {
if (c == NULL) { if (c == NULL) {
return CMD_ERR_NULL; // 参数错误 return CMD_ERR_NULL; // 参数错误
} }
c->output.chassis.cmd.mode =CHASSIS_MODE_RELAX; c->output.chassis.cmd.mode =CHASSIS_MODE_RELAX;
c->output.gimbal.cmd.mode =GIMBAL_MODE_RELAX; c->output.gimbal.cmd.mode =GIMBAL_MODE_RELAX;
c->output.shoot.cmd.mode =SHOOT_MODE_SAFE; c->output.shoot.cmd.mode =SHOOT_MODE_SAFE;
return CMD_OK; return CMD_OK;
} }
/* Exported functions ------------------------------------------------------- */ /* Exported functions ------------------------------------------------------- */
int8_t Cmd_Init(CMD_t *c, CMD_Params_t *params) { 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;
}
if (c == NULL || params == NULL) { int8_t Cmd_Get(CMD_t *c,
return CMD_ERR_NULL; // 参数错误 CMD_RCType_TABLE(CMDMACRO_NAME_EXPANSION)){
} // CMD_Input_NUC_t *nuc,
c->params = params; // CMD_Input_REF_t *ref) {
c->input.rc.data=&rc_buffer; if (c == NULL) {
#ifndef CMD_NOPC_FLAG return CMD_ERR_NULL; // 参数错误
c->input.pc.lastData=&pc_lastdata_buffer; }
c->input.pc.data=&pc_buffer; Cmd_RC_Get(c,CMD_RCType_TABLE(CMDMACRO_NAME_EXPANSION_1));
#endif Cmd_PC_Get(c,CMD_RCType_TABLE(CMDMACRO_NAME_EXPANSION_1));
return CMD_OK; // Cmd_NUC_Get(&c->input.nuc);
// Cmd_REF_Get(&c->input.ref);
return CMD_OK;
} }
int8_t Cmd_GenerateCommand(CMD_t *c) { int8_t Cmd_GenerateCommand(CMD_t *c) {
if (c == NULL) { if (c == NULL) {
return CMD_ERR_NULL; // 参数错误 return CMD_ERR_NULL; // 参数错误
} }
Cmd_Arbiter(c); Cmd_Arbiter(c);
Cmd_RC_Get(&c->input.rc);
Cmd_PC_Get(&c->input.pc); c->timer.now =BSP_TIME_Get_us() / 1000000.0f;
Cmd_NUC_Get(&c->input.nuc); c->timer.dt =(BSP_TIME_Get_us() - c->timer.last) / 1000000.0f;
Cmd_REF_Get(&c->input.ref); c->timer.last =BSP_TIME_Get_us();
c->timer.now =BSP_TIME_Get_us() / 1000000.0f; if (c->output.chassis.source >= CMD_SRC_NUM || c->output.gimbal.source >= CMD_SRC_NUM || c->output.shoot.source >= CMD_SRC_NUM) {
c->timer.dt =(BSP_TIME_Get_us() - c->timer.last) / 1000000.0f; Cmd_OFFLINE(c);
c->timer.last =BSP_TIME_Get_us(); return CMD_ERR_SOURCE; // 输入源错误
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); sourceHandlers[c->output.chassis.source].chassisFunc(c);
return CMD_ERR_SOURCE; // 输入源错误 sourceHandlers[c->output.gimbal.source].gimbalFunc(c);
} sourceHandlers[c->output.shoot.source].shootFunc(c);
sourceHandlers[c->output.chassis.source].chassisFunc(c); return CMD_OK;
sourceHandlers[c->output.gimbal.source].gimbalFunc(c);
sourceHandlers[c->output.shoot.source].shootFunc(c);
return CMD_OK;
} }

View File

@ -7,44 +7,60 @@
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/* Includes ----------------------------------------------------------------- */
#include "module/chassis.h" #include "module/chassis.h"
#include "module/gimbal.h" #include "module/gimbal.h"
#include "module/shoot.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 ------------------------------------------------------- */ /* Exported constants ------------------------------------------------------- */
#define CMD_OK (0) /* 运行正常 */ #define CMD_OK (0) /* 运行正常 */
#define CMD_ERR_NULL (-1) /* 运行时发现NULL指针 */ #define CMD_ERR_NULL (-1) /* 运行时发现NULL指针 */
#define CMD_ERR_ERR (-2) /* 运行时发现了其他错误 */ #define CMD_ERR_ERR (-2) /* 运行时发现了其他错误 */
#define CMD_ERR_SOURCE (-3) /* 运行时配置了不存在的输入源 */ #define CMD_ERR_SOURCE (-3) /* 运行时配置了不存在的输入源 */
/* Exported macro ----------------------------------------------------------- */ /* Exported macro ----------------------------------------------------------- */
#define CMD_RCTypeTable_Index 0 /* 0:DR16 1:AT9S 2:VT13 */ #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 #if CMD_RCTypeTable_Index == 1
#define CMD_NOPC_FLAG #define CMD_NOPC_FLAG
#endif #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 ----------------------------------------------------------- */ /* Exported types ----------------------------------------------------------- */
typedef union CMD_RC_Data_t CMD_RC_Data_t;
#define CMD_REFEREE_MAX_NUM (3) /* 发送命令限定的最大数量 */ #define CMD_REFEREE_MAX_NUM (3) /* 发送命令限定的最大数量 */
/* 输入源枚举 */ /* 输入源枚举 */
typedef enum { typedef enum {
CMD_SRC_RC=0, /* 遥控器 */ CMD_SRC_RC=0, /* 遥控器 */
CMD_SRC_PC, /* 键盘鼠标 */ CMD_SRC_PC, /* 键盘鼠标 */
CMD_SRC_NUC, /* 上位机 */ CMD_SRC_NUC, /* 上位机 */
CMD_SRC_REF, /* 裁判系统 */ CMD_SRC_REF, /* 裁判系统 */
CMD_SRC_NUM, CMD_SRC_NUM
CMD_SRC_ERR
} CMD_InputSource_t; } CMD_InputSource_t;
/* RC part begin-------------------------------------- */ /* RC part begin-------------------------------------- */
typedef struct { typedef struct {
bool online; bool online;
enum {DR16=0, AT9S} type; enum {DR16=0, AT9S} type;
CMD_RC_Data_t *data; CMD_RCType_TABLE(CMDMACRO_VAR_RCDATA)
#undef CMDMACRO_VAR_RCDATA
} CMD_Input_RC_t;//或者这里直接把CMD_Input_RC_t前向声明了看哪个好看 } CMD_Input_RC_t;//或者这里直接把CMD_Input_RC_t前向声明了看哪个好看
/* RC part end---------------------------------------- */ /* RC part end---------------------------------------- */
@ -77,6 +93,7 @@ typedef enum {
CMD_KEY_B, CMD_KEY_B,
CMD_L_CLICK, CMD_L_CLICK,
CMD_R_CLICK, CMD_R_CLICK,
CMD_M_CLICK,
CMD_KEY_NUM, CMD_KEY_NUM,
} CMD_PCValue_t; } CMD_PCValue_t;
typedef enum { typedef enum {
@ -101,6 +118,7 @@ typedef enum {
CMD_BEHAVIOR_ROTOR, /* 小陀螺模式 */ CMD_BEHAVIOR_ROTOR, /* 小陀螺模式 */
CMD_BEHAVIOR_REVTRIG, /* 反转拨弹 */ CMD_BEHAVIOR_REVTRIG, /* 反转拨弹 */
CMD_BEHAVIOR_FOLLOWGIMBAL35, /* 跟随云台呈35度 */ CMD_BEHAVIOR_FOLLOWGIMBAL35, /* 跟随云台呈35度 */
CMD_BEHAVIOR_GIMBAL_MODE, /* 切换云台模式 */
CMD_BEHAVIOR_NUM, CMD_BEHAVIOR_NUM,
} CMD_Behavior_t; } CMD_Behavior_t;
typedef struct { typedef struct {
@ -125,13 +143,12 @@ typedef struct {
CMD_PC_Sensitivity_t sensitivity; /* PC灵敏度设置 */ CMD_PC_Sensitivity_t sensitivity; /* PC灵敏度设置 */
}CMD_PCParams_t; }CMD_PCParams_t;
#ifndef CMD_NOPC_FLAG #ifndef CMD_NOPC_FLAG
typedef union CMD_PC_Data_t CMD_PC_Data_t;
typedef union CMD_PC_LastData_t CMD_PC_LastData_t;
typedef struct { typedef struct {
bool online; bool online;
CMD_PC_Data_t *data; CMD_RCType_TABLE(CMDMACRO_VAR_PCDATA)
CMD_PC_LastData_t *lastData; CMD_RCType_TABLE(CMDMACRO_VAR_LASTPCDATA)
#undef CMDMACRO_VAR_PCDATA
#undef CMDMACRO_VAR_LASTPCDATA
}CMD_Input_PC_t; }CMD_Input_PC_t;
#else #else
typedef struct { typedef struct {
@ -143,6 +160,14 @@ typedef struct {
/* NUC part begin------------------------------------- */ /* NUC part begin------------------------------------- */
typedef struct { typedef struct {
bool online; bool online;
struct {
float delta_yaw;
float delta_pit;
}gimbal;
struct {
float expectedSpeed;
bool fire;
}shoot;
}CMD_Input_NUC_t; }CMD_Input_NUC_t;
/* NUC part end--------------------------------------- */ /* NUC part end--------------------------------------- */
@ -183,13 +208,9 @@ typedef struct {
CMD_Output_GIMBAL_t gimbal; CMD_Output_GIMBAL_t gimbal;
CMD_Output_SHOOT_t shoot; CMD_Output_SHOOT_t shoot;
} CMD_Output_t; } CMD_Output_t;
typedef struct {
CMD_InputSource_t source;
uint8_t priority;
} CMD_SourcePriorityConfig_t;
typedef struct { typedef struct {
CMD_SourcePriorityConfig_t sourcePriorityConfigs[CMD_SRC_NUM];/* 输入源优先级配置 */ CMD_InputSource_t sourcePriorityConfigs[CMD_SRC_NUM];/* 输入源优先级配置 */
CMD_PCParams_t pc; CMD_PCParams_t pc;
} CMD_Params_t; } CMD_Params_t;
@ -208,6 +229,7 @@ typedef struct {
/* Exported functions prototypes -------------------------------------------- */ /* Exported functions prototypes -------------------------------------------- */
int8_t Cmd_Init(CMD_t *c, CMD_Params_t *params); 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); int8_t Cmd_GenerateCommand(CMD_t *c);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -6,6 +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.h"
#include <stdbool.h> #include <stdbool.h>
/* Private typedef ---------------------------------------------------------- */ /* Private typedef ---------------------------------------------------------- */
/* Private define ----------------------------------------------------------- */ /* Private define ----------------------------------------------------------- */
@ -166,17 +167,17 @@ Config_RobotParam_t robot_config = {
.shoot_param = { .shoot_param = {
.basic={ .basic={
.projectileType=SHOOT_PROJECTILE_42MM, .projectileType=SHOOT_PROJECTILE_42MM,
.fric_num=6, .fric_num=6,
.extra_deceleration_ratio=1.0f, .extra_deceleration_ratio=1.0f,
.num_trig_tooth=5, .num_trig_tooth=5,
.shot_freq=1.0f, .shot_freq=1.0f,
.shot_burst_num=3, .shot_burst_num=3,
.ratio_multilevel = {0.8f, 1.0f}, .ratio_multilevel = {0.8f, 1.0f},
}, },
.jamDetection={ .jamDetection={
.enable=true, .enable=true,
.threshold=240.0f, .threshold=310.0f,
.suspectedTime=0.5f, .suspectedTime=0.5f,
}, },
.motor={ .motor={
@ -325,12 +326,12 @@ Config_RobotParam_t robot_config = {
}, },
.cmd_param={ .cmd_param={
.sourcePriorityConfigs={ .sourcePriorityConfigs={
{CMD_SRC_RC,1}, CMD_SRC_RC,
{CMD_SRC_PC,2}, CMD_SRC_PC,
{CMD_SRC_NUC,3}, CMD_SRC_NUC,
{CMD_SRC_REF,4} CMD_SRC_REF
}, },
.pc.map = { .pc.map = { /*1<<CMD_KEY_W记录一下不要忘了这个思路 */
.key_map[CMD_BEHAVIOR_FORE] = {CMD_KEY_W, CMD_ACTIVE_PRESSED}, .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_BACK] = {CMD_KEY_S, CMD_ACTIVE_PRESSED},
.key_map[CMD_BEHAVIOR_LEFT] = {CMD_KEY_A, CMD_ACTIVE_PRESSED}, .key_map[CMD_BEHAVIOR_LEFT] = {CMD_KEY_A, CMD_ACTIVE_PRESSED},
@ -342,12 +343,13 @@ Config_RobotParam_t robot_config = {
.key_map[CMD_BEHAVIOR_FOLLOWGIMBAL35] = {CMD_KEY_E, 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_OPENCOVER] = {CMD_KEY_F, CMD_ACTIVE_RISING_EDGE},
.key_map[CMD_BEHAVIOR_REVTRIG] = {CMD_KEY_R, 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_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={ .pc.sensitivity={
.move_sense=1.6f, .move_sense=0.1f,
.sens_mouse=0.06f, .sens_mouse=3.0f,
.move_fast_sense=2.4f, .move_fast_sense=2.4f,
.move_slow_sense=0.8f .move_slow_sense=0.8f
}, },

View File

@ -42,15 +42,16 @@ static int8_t Gimbal_SetMode(Gimbal_t *g, Gimbal_Mode_t mode) {
MOTOR_DM_Enable(&(g->param->pit_motor)); MOTOR_DM_Enable(&(g->param->pit_motor));
AHRS_ResetEulr(&(g->setpoint.eulr)); /* 切换模式后重置设定值 */ AHRS_ResetEulr(&(g->setpoint.eulr)); /* 切换模式后重置设定值 */
// if (g->mode == GIMBAL_MODE_RELAX) {
// if (mode == GIMBAL_MODE_ABSOLUTE) {
// g->setpoint.eulr.yaw = g->feedback.imu.eulr.yaw;
// } else if (mode == GIMBAL_MODE_RELATIVE) {
// g->setpoint.eulr.yaw = g->feedback.imu.eulr.yaw;
// }
// }
g->setpoint.eulr.pit = g->feedback.motor.pit.rotor_abs_angle; g->setpoint.eulr.pit = g->feedback.motor.pit.rotor_abs_angle;
g->setpoint.eulr.yaw = g->feedback.motor.yaw.rotor_abs_angle;
// g->setpoint.eulr.yaw = g->feedback.imu.eulr.yaw;
// g->setpoint.eulr.yaw = g->feedback.motor.yaw.rotor_abs_angle;
if (mode == GIMBAL_MODE_ABSOLUTE) {
g->setpoint.eulr.yaw = g->feedback.motor.yaw.rotor_abs_angle;
} else if (mode == GIMBAL_MODE_RELATIVE) {
g->setpoint.eulr.yaw = g->feedback.imu.eulr.yaw;
}
g->mode = mode; g->mode = mode;
return 0; return 0;
@ -165,7 +166,15 @@ int8_t Gimbal_Control(Gimbal_t *g, Gimbal_CMD_t *g_cmd) {
float delta_yaw = g_cmd->delta_yaw * g->dt * 1.5f; float delta_yaw = g_cmd->delta_yaw * g->dt * 1.5f;
if (g->param->travel.yaw > 0) { if (g->param->travel.yaw > 0) {
/* 计算当前电机角度与IMU角度的偏差 */ /* 计算当前电机角度与IMU角度的偏差 */
float motor_imu_offset = g->feedback.motor.yaw.rotor_abs_angle - g->feedback.motor.yaw.rotor_abs_angle; float motor_imu_offset;
switch (g->mode) {
case GIMBAL_MODE_ABSOLUTE:
motor_imu_offset = g->feedback.motor.yaw.rotor_abs_angle - g->feedback.motor.yaw.rotor_abs_angle;
break;
case GIMBAL_MODE_RELATIVE:
motor_imu_offset = g->feedback.motor.yaw.rotor_abs_angle - g->feedback.imu.eulr.yaw;
break;
}
/* 处理跨越±π的情况 */ /* 处理跨越±π的情况 */
if (motor_imu_offset > M_PI) motor_imu_offset -= M_2PI; if (motor_imu_offset > M_PI) motor_imu_offset -= M_2PI;
if (motor_imu_offset < -M_PI) motor_imu_offset += M_2PI; if (motor_imu_offset < -M_PI) motor_imu_offset += M_2PI;
@ -186,7 +195,15 @@ int8_t Gimbal_Control(Gimbal_t *g, Gimbal_CMD_t *g_cmd) {
float delta_pit = g_cmd->delta_pit * g->dt; float delta_pit = g_cmd->delta_pit * g->dt;
if (g->param->travel.pit > 0) { if (g->param->travel.pit > 0) {
/* 计算当前电机角度与IMU角度的偏差 */ /* 计算当前电机角度与IMU角度的偏差 */
float motor_imu_offset = g->feedback.motor.pit.rotor_abs_angle - g->feedback.motor.pit.rotor_abs_angle; float motor_imu_offset;
switch (g->mode) {
case GIMBAL_MODE_ABSOLUTE:
motor_imu_offset = g->feedback.motor.pit.rotor_abs_angle - g->feedback.motor.pit.rotor_abs_angle;
break;
case GIMBAL_MODE_RELATIVE:
motor_imu_offset = g->feedback.motor.pit.rotor_abs_angle - g->feedback.imu.eulr.pit;
break;
}
/* 处理跨越±π的情况 */ /* 处理跨越±π的情况 */
if (motor_imu_offset > M_PI) motor_imu_offset -= M_2PI; if (motor_imu_offset > M_PI) motor_imu_offset -= M_2PI;
if (motor_imu_offset < -M_PI) motor_imu_offset += M_2PI; if (motor_imu_offset < -M_PI) motor_imu_offset += M_2PI;
@ -202,7 +219,7 @@ int8_t Gimbal_Control(Gimbal_t *g, Gimbal_CMD_t *g_cmd) {
if (delta_pit < delta_min) delta_pit = delta_min; if (delta_pit < delta_min) delta_pit = delta_min;
} }
CircleAdd(&(g->setpoint.eulr.pit), delta_pit, M_2PI); CircleAdd(&(g->setpoint.eulr.pit), delta_pit, M_2PI);
g->setpoint.eulr.pit = (g_cmd->delta_pit)/3.0f + 2.98f + 1/3.0f; //2.98f为机械零点位置 // g->setpoint.eulr.pit = (g_cmd->delta_pit)/3.0f + 2.98f + 1/3.0f; //2.98f为机械零点位置
/* 控制相关逻辑 */ /* 控制相关逻辑 */
float yaw_omega_set_point, pit_omega_set_point; float yaw_omega_set_point, pit_omega_set_point;
@ -229,9 +246,19 @@ int8_t Gimbal_Control(Gimbal_t *g, Gimbal_CMD_t *g_cmd) {
break; break;
case GIMBAL_MODE_RELATIVE: case GIMBAL_MODE_RELATIVE:
/* 相对模式暂未实现 */ yaw_omega_set_point = PID_Calc(&(g->pid.yaw_angle), g->setpoint.eulr.yaw,
g->out.yaw = 0.0f; g->feedback.imu.eulr.yaw, 0.0f, g->dt);
g->out.pit = 0.0f; g->out.yaw = PID_Calc(&(g->pid.pit_omega), yaw_omega_set_point,
g->feedback.imu.gyro.z, 0.f, g->dt);
pit_omega_set_point = PID_Calc(&(g->pid.pit_angle), g->setpoint.eulr.pit,
g->feedback.imu.eulr.pit, 0.0f, g->dt);
g->out.pit = PID_Calc(&(g->pid.pit_omega), pit_omega_set_point,
g->feedback.imu.gyro.x, 0.f, g->dt);
/* 输出滤波 */
g->out.yaw = LowPassFilter2p_Apply(&g->filter_out.yaw, g->out.yaw);
g->out.pit = LowPassFilter2p_Apply(&g->filter_out.pit, g->out.pit);
break; break;
} }

View File

@ -29,6 +29,7 @@ typedef enum {
GIMBAL_MODE_RELAX, /* 放松模式,电机不输出。一般情况云台初始化之后的模式 */ GIMBAL_MODE_RELAX, /* 放松模式,电机不输出。一般情况云台初始化之后的模式 */
GIMBAL_MODE_ABSOLUTE, /* 绝对坐标系控制,控制在空间内的绝对姿态 */ GIMBAL_MODE_ABSOLUTE, /* 绝对坐标系控制,控制在空间内的绝对姿态 */
GIMBAL_MODE_RELATIVE, /* 相对坐标系控制,控制相对于底盘的姿态 */ GIMBAL_MODE_RELATIVE, /* 相对坐标系控制,控制相对于底盘的姿态 */
GIMBAL_MODE_NUM
} Gimbal_Mode_t; } Gimbal_Mode_t;
typedef struct { typedef struct {

View File

@ -40,9 +40,13 @@ void Task(void *argument) {
#include "component/user_math.h" #include "component/user_math.h"
/* Private typedef ---------------------------------------------------------- */ /* Private typedef ---------------------------------------------------------- */
/* Private define ----------------------------------------------------------- */ /* Private define ----------------------------------------------------------- */
#define MAX_FRIC_RPM 7000.0f
#define MAX_TRIG_RPM 1500.0f//这里可能也会影响最高发射频率,待测试
/* Private macro ------------------------------------------------------------ */ /* Private macro ------------------------------------------------------------ */
/* Private variables -------------------------------------------------------- */ /* Private variables -------------------------------------------------------- */
static bool last_firecmd; static bool last_firecmd;
float maxTrigrpm=1500.0f;
/* Private function -------------------------------------------------------- */ /* Private function -------------------------------------------------------- */
/** /**
@ -281,7 +285,7 @@ int8_t Shoot_UpdateFeedback(Shoot_t *s)
s->var_trig.trig_agl = M_2PI - s->var_trig.trig_agl; s->var_trig.trig_agl = M_2PI - s->var_trig.trig_agl;
} }
s->var_trig.fil_trig_rpm = LowPassFilter2p_Apply(&s->filter.trig.in, s->feedback.trig.feedback.rotor_speed); s->var_trig.fil_trig_rpm = LowPassFilter2p_Apply(&s->filter.trig.in, s->feedback.trig.feedback.rotor_speed);
s->var_trig.trig_rpm = s->feedback.trig.feedback.rotor_speed / MAX_TRIG_RPM; s->var_trig.trig_rpm = s->feedback.trig.feedback.rotor_speed / maxTrigrpm;
if(s->var_trig.trig_rpm>1.0f)s->var_trig.trig_rpm=1.0f; if(s->var_trig.trig_rpm>1.0f)s->var_trig.trig_rpm=1.0f;
if(s->var_trig.trig_rpm<-1.0f)s->var_trig.trig_rpm=-1.0f; if(s->var_trig.trig_rpm<-1.0f)s->var_trig.trig_rpm=-1.0f;
@ -303,15 +307,16 @@ int8_t Shoot_RunningFSM(Shoot_t *s, Shoot_CMD_t *cmd)
return SHOOT_ERR_NULL; // 参数错误 return SHOOT_ERR_NULL; // 参数错误
} }
uint8_t fric_num = s->param->basic.fric_num; uint8_t fric_num = s->param->basic.fric_num;
if(!s->online || s->mode==SHOOT_MODE_SAFE){ static float pos;
for(int i=0;i<fric_num;i++) if(s->mode==SHOOT_MODE_SAFE){
{ for(int i=0;i<fric_num;i++)
MOTOR_RM_Relax(&s->param->motor.fric[i].param); {
} MOTOR_RM_Relax(&s->param->motor.fric[i].param);
MOTOR_RM_Relax(&s->param->motor.trig); }
MOTOR_RM_Relax(&s->param->motor.trig);\
pos=s->target_variable.trig_angle=s->var_trig.trig_agl;
} }
else{ else{
static float pos;
switch(s->running_state) switch(s->running_state)
{ {
case SHOOT_STATE_IDLE:/*熄火等待*/ case SHOOT_STATE_IDLE:/*熄火等待*/
@ -454,9 +459,9 @@ int8_t Shoot_RunningFSM(Shoot_t *s, Shoot_CMD_t *cmd)
/* 检查状态机 */ /* 检查状态机 */
if(!cmd->firecmd) if(!cmd->firecmd)
{ {
s->running_state=SHOOT_STATE_READY; s->running_state=SHOOT_STATE_READY;
pos=s->var_trig.trig_agl; pos=s->var_trig.trig_agl;
s->var_trig.num_toShoot=0; s->var_trig.num_toShoot=0;
} }
break; break;
@ -637,7 +642,6 @@ int8_t Shoot_Control(Shoot_t *s, Shoot_CMD_t *cmd)
s->timer.now = BSP_TIME_Get_us() / 1000000.0f; s->timer.now = BSP_TIME_Get_us() / 1000000.0f;
s->timer.dt = (BSP_TIME_Get_us() - s->timer.lask_wakeup) / 1000000.0f; s->timer.dt = (BSP_TIME_Get_us() - s->timer.lask_wakeup) / 1000000.0f;
s->timer.lask_wakeup = BSP_TIME_Get_us(); s->timer.lask_wakeup = BSP_TIME_Get_us();
s->online = cmd->online;
Shoot_CaluTargetRPM(s,233); Shoot_CaluTargetRPM(s,233);
Shoot_JamDetectionFSM(s, cmd); Shoot_JamDetectionFSM(s, cmd);

View File

@ -13,18 +13,15 @@ extern "C" {
#include "component/pid.h" #include "component/pid.h"
#include "device/motor_rm.h" #include "device/motor_rm.h"
/* Exported constants ------------------------------------------------------- */ /* Exported constants ------------------------------------------------------- */
#define MAX_FRIC_NUM 6
#define MAX_NUM_MULTILEVEL 2 /* 多级发射级数 */
#define SHOOT_OK (0) /* 运行正常 */ #define SHOOT_OK (0) /* 运行正常 */
#define SHOOT_ERR_NULL (-1) /* 运行时发现NULL指针 */ #define SHOOT_ERR_NULL (-1) /* 运行时发现NULL指针 */
#define SHOOT_ERR_ERR (-2) /* 运行时发现了其他错误 */ #define SHOOT_ERR_ERR (-2) /* 运行时发现了其他错误 */
#define SHOOT_ERR_MODE (-3) /* 运行时配置了错误的Mode */ #define SHOOT_ERR_MODE (-3) /* 运行时配置了错误的Mode */
#define SHOOT_ERR_MOTOR (-4) /* 运行时配置了不存在的电机类型 */ #define SHOOT_ERR_MOTOR (-4) /* 运行时配置了不存在的电机类型 */
#define SHOOT_ERR_MALLOC (-5) /* 内存分配失败 */ #define SHOOT_ERR_MALLOC (-5) /* 内存分配失败 */
#define MAX_FRIC_RPM 7000.0f
#define MAX_TRIG_RPM 2000.0f//这里可能也会影响最高发射频率,待测试
#define MAX_FRIC_NUM 6
#define MAX_NUM_MULTILEVEL 2 /* 多级发射级数 */
/* Exported macro ----------------------------------------------------------- */ /* Exported macro ----------------------------------------------------------- */
/* Exported types ----------------------------------------------------------- */ /* Exported types ----------------------------------------------------------- */
typedef enum { typedef enum {
@ -69,9 +66,7 @@ typedef struct{
float normalized_fil_avgrpm[MAX_NUM_MULTILEVEL]; /* 归一化摩擦轮平均转速 */ float normalized_fil_avgrpm[MAX_NUM_MULTILEVEL]; /* 归一化摩擦轮平均转速 */
float coupled_control_weights; /* 耦合控制权重 */ float coupled_control_weights; /* 耦合控制权重 */
}Shoot_VARSForFricCtrl_t; }Shoot_VARSForFricCtrl_t;
// float fil_rpm[MAX_FRIC_NUM]; /* 滤波后的摩擦轮原始转速 */
// float normalized_fil_rpm[MAX_FRIC_NUM]; /* 归一化且滤波后的摩擦轮转速 */
// float normalized_fil_avgrpm; /* 归一化摩擦轮平均转速 */
typedef struct{ typedef struct{
float time_lastShoot;/* 上次射击时间 */ float time_lastShoot;/* 上次射击时间 */
uint16_t num_toShoot;/* 剩余待发射弹数 */ uint16_t num_toShoot;/* 剩余待发射弹数 */
@ -99,7 +94,6 @@ typedef struct {
}Shoot_Output_t; }Shoot_Output_t;
typedef struct { typedef struct {
bool online; /* 在线标志 */
Shoot_Mode_t mode;/* 射击模式 */ Shoot_Mode_t mode;/* 射击模式 */
bool ready; /* 准备射击 */ bool ready; /* 准备射击 */
bool firecmd; /* 射击 */ bool firecmd; /* 射击 */
@ -155,7 +149,6 @@ typedef struct {
* *
*/ */
typedef struct { typedef struct {
bool online; /*在线检测*/
Shoot_Timer_t timer; /* 计时器 */ Shoot_Timer_t timer; /* 计时器 */
Shoot_Params_t *param; /* 发射参数 */ Shoot_Params_t *param; /* 发射参数 */
/* 模块通用 */ /* 模块通用 */

View File

@ -21,6 +21,11 @@
/* Private macro ------------------------------------------------------------ */ /* Private macro ------------------------------------------------------------ */
/* Private variables -------------------------------------------------------- */ /* Private variables -------------------------------------------------------- */
/* USER STRUCT BEGIN */ /* USER STRUCT BEGIN */
#if CMD_RCTypeTable_Index == 0
DR16_t cmd_dr16;
#elif CMD_RCTypeTable_Index == 1
AT9S_t cmd_at9s;
#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;
@ -47,6 +52,12 @@ void Task_cmd(void *argument) {
while (1) { while (1) {
tick += delay_tick; /* 计算下一个唤醒时刻 */ tick += delay_tick; /* 计算下一个唤醒时刻 */
/* USER CODE BEGIN */ /* USER CODE BEGIN */
#if CMD_RCTypeTable_Index == 0
osMessageQueueGet(task_runtime.msgq.cmd.rc, &cmd_dr16, NULL, 0);
#elif CMD_RCTypeTable_Index == 1
osMessageQueueGet(task_runtime.msgq.cmd.rc, &cmd_at9s, NULL, 0);
#endif
Cmd_Get(&cmd,cmd_dr16);
Cmd_GenerateCommand(&cmd); Cmd_GenerateCommand(&cmd);
cmd_for_shoot=cmd.output.shoot.cmd; cmd_for_shoot=cmd.output.shoot.cmd;
cmd_for_chassis=cmd.output.chassis.cmd; cmd_for_chassis=cmd.output.chassis.cmd;

View File

@ -46,8 +46,11 @@ void Task_Init(void *argument) {
// 创建消息队列 // 创建消息队列
/* USER MESSAGE BEGIN */ /* USER MESSAGE BEGIN */
task_runtime.msgq.user_msg= osMessageQueueNew(2u, 10, NULL); task_runtime.msgq.user_msg= osMessageQueueNew(2u, 10, NULL);
#if CMD_RCTypeTable_Index == 0
task_runtime.msgq.cmd.rc= osMessageQueueNew(3u, sizeof(DR16_t), NULL);
#elif CMD_RCTypeTable_Index == 1
task_runtime.msgq.cmd.rc= osMessageQueueNew(3u, sizeof(AT9S_t), NULL); task_runtime.msgq.cmd.rc= osMessageQueueNew(3u, sizeof(AT9S_t), NULL);
task_runtime.msgq.cmd.pc= osMessageQueueNew(3u, sizeof(DR16_t), NULL); #endif
task_runtime.msgq.chassis.yaw = osMessageQueueNew(2u, sizeof(float), NULL); task_runtime.msgq.chassis.yaw = osMessageQueueNew(2u, sizeof(float), NULL);
task_runtime.msgq.chassis.cmd= osMessageQueueNew(3u, sizeof(Chassis_CMD_t), NULL); task_runtime.msgq.chassis.cmd= osMessageQueueNew(3u, sizeof(Chassis_CMD_t), NULL);
task_runtime.msgq.gimbal.imu= osMessageQueueNew(2u, sizeof(Gimbal_IMU_t), NULL); task_runtime.msgq.gimbal.imu= osMessageQueueNew(2u, sizeof(Gimbal_IMU_t), NULL);

View File

@ -3,8 +3,8 @@
*/ */
#define AT9S // #define AT9S
// #define DR16 #define DR16
/* Includes ----------------------------------------------------------------- */ /* Includes ----------------------------------------------------------------- */
#include "task/user_task.h" #include "task/user_task.h"
/* USER INCLUDE BEGIN */ /* USER INCLUDE BEGIN */
@ -70,6 +70,7 @@ void Task_rc(void *argument) {
} else { } else {
DR16_Offline(&dr16); DR16_Offline(&dr16);
} }
osMessageQueueReset(task_runtime.msgq.cmd.rc);
osMessageQueuePut(task_runtime.msgq.cmd.rc, &dr16, 0, 0); osMessageQueuePut(task_runtime.msgq.cmd.rc, &dr16, 0, 0);
#endif #endif
/* USER CODE END */ /* USER CODE END */

View File

@ -18,7 +18,7 @@ extern "C" {
#define BLINK_FREQ (100.0) #define BLINK_FREQ (100.0)
#define CTRL_CHASSIS_FREQ (500.0) #define CTRL_CHASSIS_FREQ (500.0)
#define CTRL_GIMBAL_FREQ (500.0) #define CTRL_GIMBAL_FREQ (500.0)
#define CTRL_SHOOT_FREQ (500.0) #define CTRL_SHOOT_FREQ (1000.0)
#define CMD_FREQ (500.0) #define CMD_FREQ (500.0)
/* 任务初始化延时ms */ /* 任务初始化延时ms */

View File

@ -1,29 +1,34 @@
Breakpoint=D:/CUBEMX/hero/god-yuan-hero/User/module/shoot.c:364:7, State=BP_STATE_DISABLED Breakpoint=D:/CUBEMX/hero/god-yuan-hero/User/module/shoot.c:367:7, State=BP_STATE_DISABLED
GraphedExpression="(((shoot).feedback).fric[0]).rotor_speed", Color=#e56a6f, Show=0 GraphedExpression="(((shoot).feedback).fric[0]).rotor_speed", Color=#e56a6f
GraphedExpression="(((shoot).feedback).fric[1]).rotor_speed", Color=#35792b, Show=0 GraphedExpression="(((shoot).feedback).fric[1]).rotor_speed", Color=#35792b
GraphedExpression="(((shoot).feedback).fric[3]).rotor_speed", Color=#769dda, Show=0 GraphedExpression="(((shoot).feedback).fric[2]).rotor_speed", Color=#769dda
GraphedExpression="(((shoot).feedback).fric[2]).rotor_speed", Color=#b14f0d, Show=0 GraphedExpression="(((shoot).feedback).fric[3]).rotor_speed", Color=#b14f0d
GraphedExpression="(((shoot).feedback).fric[4]).rotor_speed", Color=#b3c38e, Show=0 GraphedExpression="(((shoot).feedback).fric[4]).rotor_speed", Color=#b3c38e
GraphedExpression="(((shoot).feedback).fric[5]).rotor_speed", Color=#ab7b05, Show=0 GraphedExpression="(((shoot).feedback).fric[5]).rotor_speed", Color=#ab7b05
GraphedExpression="((((shoot).feedback).trig).feedback).rotor_speed", Color=#7fd3b7 GraphedExpression="(shoot).errtosee", Color=#7fd3b7, Show=0
GraphedExpression="((((shoot).feedback).trig).feedback).rotor_abs_angle", Color=#50328f
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="can.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/bsp/can.c", Line=69
OpenDocument="tasks.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/Middlewares/Third_Party/FreeRTOS/Source/tasks.c", Line=3419
OpenDocument="device.h", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/device/device.h", Line=5
OpenDocument="cmd.h", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/module/cmd.h", Line=60
OpenDocument="cmd.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/module/cmd.c", Line=416
OpenDocument="cmd.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/task/cmd.c", Line=0
OpenDocument="pid.h", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/component/pid.h", Line=53
OpenDocument="startup_stm32f407xx.s", FilePath="D:/CUBEMX/hero/god-yuan-hero/startup_stm32f407xx.s", Line=48 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="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="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="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=14 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="rc.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/task/rc.c", Line=0
OpenDocument="tasks.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/Middlewares/Third_Party/FreeRTOS/Source/tasks.c", Line=3419
OpenDocument="shoot.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/module/shoot.c", Line=346 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.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="config.h", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/module/config.h", Line=0
OpenDocument="cmd.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/task/cmd.c", Line=22 OpenDocument="chassis.h", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/module/chassis.h", Line=133
OpenDocument="cmd.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/module/cmd.c", Line=80 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_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="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="usart.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/Core/Src/usart.c", Line=179
@ -33,25 +38,25 @@ OpenDocument="ctrl_shoot.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/task/ct
OpenDocument="user_task.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/task/user_task.c", Line=0 OpenDocument="user_task.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/User/task/user_task.c", Line=0
OpenDocument="stm32f4xx_it.c", FilePath="D:/CUBEMX/hero/god-yuan-hero/Core/Src/stm32f4xx_it.c", Line=83 OpenDocument="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=521, TabPos=2, TopOfStack=0, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=0, FilteredItems=[], RefreshRate=1 OpenWindow="Registers 1", DockArea=RIGHT, x=0, y=1, w=726, h=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=397, 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=521, TabPos=1, 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=587, 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=1972, h=555, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=1, DataPaneShown=1, PowerPaneShown=0, CodePaneShown=0, PinCursor="Cursor Movable", TimePerDiv="2 s / Div", TimeStampFormat="Time", DataGraphDrawAsPoints=0, DataGraphLegendShown=1, DataGraphUniformSampleSpacing=0, DataGraphLegendPosition="0;165", DataGraphShowNamesAtCursor=0, PowerGraphDrawAsPoints=0, PowerGraphLegendShown=0, PowerGraphAvgFilterTime=Off, PowerGraphAvgFilterLen=Off, PowerGraphUniformSampleSpacing=0, PowerGraphLegendPosition="1059;-69", CodeGraphLegendShown=0, CodeGraphLegendPosition="1074;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=587, 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=521, TabPos=0, 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="Watched Data 2", SortCol="Expression", SortOrder="ASCENDING", VisibleCols=["Expression";"Value";"Location";"Refresh"], ColWidths=[100;100;100;426] TableHeader="Watched Data 2", SortCol="Expression", SortOrder="ASCENDING", VisibleCols=["Expression";"Value";"Location";"Refresh"], ColWidths=[170;352;100;104]
TableHeader="Watched Data 1", SortCol="Expression", SortOrder="ASCENDING", VisibleCols=["Expression";"Value";"Location";"Refresh"], ColWidths=[250;282;91;100] TableHeader="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="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="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="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="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[3]).rotor_speed";" (((shoot).feedback).fric[2]).rotor_speed";" (((shoot).feedback).fric[4]).rotor_speed";" (((shoot).feedback).fric[5]).rotor_speed";" ((((shoot).feedback).trig).feedback).rotor_speed";" ((((shoot).feedback).trig).feedback).rotor_abs_angle"], ColWidths=[100;100;100;100;100;100;100;100;100;100] 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;134;104;114;114;110;126;126] 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="0x20008DD8", Window=Watched Data 1 WatchedExpression="0x20008DD8", Window=Watched Data 1
WatchedExpression="cmd", RefreshRate=5, Window=Watched Data 1 WatchedExpression="cmd", RefreshRate=5, Window=Watched Data 1
@ -65,3 +70,9 @@ WatchedExpression="chassis_cmd", RefreshRate=5, Window=Watched Data 1
WatchedExpression="gimbal_cmd", RefreshRate=5, Window=Watched Data 1 WatchedExpression="gimbal_cmd", RefreshRate=5, Window=Watched Data 1
WatchedExpression="gimbal", RefreshRate=5, Window=Watched Data 1 WatchedExpression="gimbal", RefreshRate=5, Window=Watched Data 1
WatchedExpression="at9s_out", RefreshRate=5, Window=Watched Data 1 WatchedExpression="at9s_out", RefreshRate=5, Window=Watched Data 1
WatchedExpression="cmd_dr16", RefreshRate=5, Window=Watched Data 1
WatchedExpression="rc_buffer", RefreshRate=5, Window=Watched Data 1
WatchedExpression="cmd", RefreshRate=5, Window=Watched Data 2
WatchedExpression="cmd_dr16", Window=Watched Data 2
WatchedExpression="dr16", RefreshRate=5, Window=Watched Data 2
WatchedExpression="gimbal", RefreshRate=5, Window=Watched Data 2