From 03ae284fca4cf2effed3ae655473f49ae7c08b2a Mon Sep 17 00:00:00 2001 From: kai <1797003616@qq.com> Date: Fri, 24 May 2024 20:49:07 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=98=E5=88=B6=E5=9F=BA=E7=A1=80UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/chassis/balance.c | 17 ++++- application/cmd/robot_cmd.c | 13 ++++ application/robot_def.h | 23 +++++- application/robot_task.h | 3 +- modules/referee/referee_task.c | 129 ++++++++++++++++++++------------- modules/referee/rm_referee.h | 10 +++ 6 files changed, 138 insertions(+), 57 deletions(-) diff --git a/application/chassis/balance.c b/application/chassis/balance.c index 0c35852..ff14728 100644 --- a/application/chassis/balance.c +++ b/application/chassis/balance.c @@ -441,6 +441,20 @@ static void WattLimitSet() /* 设定运动模态的输出 */ LKMotorSetRef(r_driven, 195.3125 * -r_side.T_wheel); } +// 裁判系统,双板通信,电容功率控制等 +static void CommNPower() +{ + // CANCommSend(cmd_can_comm, (void *)&chassis_feedback_data); + + /* 更新ui数据 */ + ui_data.direction = chassis_cmd_recv.direction; + ui_data.friction_mode = chassis_cmd_recv.friction_mode; + ui_data.loader_mode = chassis_cmd_recv.loader_mode; + ui_data.chassis_mode = chassis_cmd_recv.chassis_mode; + ui_data.ui_mode = chassis_cmd_recv.ui_mode; + ui_data.vision_mode = chassis_cmd_recv.vision_mode; +} + void BalanceTask() { del_t = DWT_GetDeltaT(&balance_dwt_cnt); @@ -450,6 +464,8 @@ void BalanceTask() ControlSwitch(); // 设置目标参数和工作模式 WokingStateSet(); + // 裁判系统,双板通信,电容功率控制等 + CommNPower(); // 参数组装 ParamAssemble(); // 将五连杆映射成单杆 @@ -479,5 +495,4 @@ void BalanceTask() // 运动模态,电机输出映射和限幅 WattLimitSet(); - // CANCommSend(cmd_can_comm, (void *)&chassis_feedback_data); } \ No newline at end of file diff --git a/application/cmd/robot_cmd.c b/application/cmd/robot_cmd.c index 84eaa1f..71b6005 100644 --- a/application/cmd/robot_cmd.c +++ b/application/cmd/robot_cmd.c @@ -249,6 +249,16 @@ static void MouseKeySet() else shoot_cmd_send.load_mode = LOAD_STOP; + switch (rc_data[TEMP].key[KEY_PRESS].z) // Z键刷新UI + { + case 0: + chassis_cmd_send.ui_mode = UI_KEEP; + break; + default: + chassis_cmd_send.ui_mode = UI_REFRESH; + break; + } + if (rc_data[TEMP].mouse.press_r) { gimbal_cmd_send.yaw = (vision_recv_data->yaw == 0 ? gimbal_cmd_send.yaw : vision_recv_data->yaw); @@ -330,6 +340,9 @@ void RobotCMDTask() EmergencyHandler(); // 处理模块离线和遥控器急停等紧急情况 chassis_cmd_send.direction = chassis_direction; + // UI数据 + chassis_cmd_send.friction_mode = shoot_cmd_send.friction_mode; + chassis_cmd_send.loader_mode = shoot_cmd_send.load_mode; CANCommSend(cmd_can_comm, (void *)&chassis_cmd_send); diff --git a/application/robot_def.h b/application/robot_def.h index 4906d5c..ad8f7e5 100644 --- a/application/robot_def.h +++ b/application/robot_def.h @@ -72,6 +72,13 @@ typedef enum APP_ERROR, } App_Status_e; +// UI模式设置 +typedef enum +{ + UI_KEEP = 0, + UI_REFRESH, +} ui_mode_e; + // 底盘模式设置 /** * @brief 后续考虑修改为云台跟随底盘,而不是让底盘去追云台,云台的惯量比底盘小. @@ -122,6 +129,13 @@ typedef enum LOAD_BURSTFIRE, // 连发 } loader_mode_e; +typedef enum +{ + UNLOCK = 0, // 未开启自瞄或视觉未锁定 + CONVERGE, // 视觉锁定过程中,正在校准 + LOCK, // 视觉锁定, 可以开火 +} vision_mode_e; + // 功率限制,从裁判系统获取,是否有必要保留? typedef struct { // 功率控制 @@ -151,11 +165,12 @@ typedef struct chassis_direction_e direction; // UI部分 - friction_mode_e friction_mode; - Target_State_e target_state; - loader_mode_e loader_mode; + Chassis_Power_Data_s super_cap; // 超级电容 + friction_mode_e friction_mode; // 摩擦轮状态 + vision_mode_e vision_mode; // 视觉状态 + ui_mode_e ui_mode; // UI状态 + loader_mode_e loader_mode; // 拨盘状态 - uint8_t ui_refresh_flag; } Chassis_Ctrl_Cmd_s; // cmd发布的云台控制数据,由gimbal订阅 diff --git a/application/robot_task.h b/application/robot_task.h index 378d966..5daa007 100644 --- a/application/robot_task.h +++ b/application/robot_task.h @@ -126,11 +126,12 @@ __attribute__((noreturn)) void StartROBOTTASK(void const *argument) __attribute__((noreturn)) void StartUITASK(void const *argument) { LOGINFO("[freeRTOS] UI Task Start"); - MyUIInit(); + // MyUIInit(); LOGINFO("[freeRTOS] UI Init Done, communication with ref has established"); for (;;) { // 每给裁判系统发送一包数据会挂起一次,详见UITask函数的refereeSend() + MyUIInit(); UITask(); osDelay(1); // 即使没有任何UI需要刷新,也挂起一次,防止卡在UITask中无法切换 } diff --git a/modules/referee/referee_task.c b/modules/referee/referee_task.c index e35ada2..63acc04 100644 --- a/modules/referee/referee_task.c +++ b/modules/referee/referee_task.c @@ -49,20 +49,25 @@ referee_info_t *UITaskInit(UART_HandleTypeDef *referee_usart_handle, Referee_Int void UITask() { - RobotModeTest(Interactive_data); // 测试用函数,实现模式自动变化,用于检查该任务和裁判系统是否连接正常 + // RobotModeTest(Interactive_data); // 测试用函数,实现模式自动变化,用于检查该任务和裁判系统是否连接正常 MyUIRefresh(referee_recv_info, Interactive_data); } static Graph_Data_t UI_shoot_line[10]; // 射击准线 static Graph_Data_t UI_Energy[3]; // 电容能量条 +static Graph_Data_t UI_Vision[3]; // 视觉标识框 static String_Data_t UI_State_sta[6]; // 机器人状态,静态只需画一次 static String_Data_t UI_State_dyn[6]; // 机器人状态,动态先add才能change -static uint32_t shoot_line_location[10] = {540, 960, 490, 515, 565}; +static uint32_t shoot_line_location[10] = {540, 960, 600, 460, 420, 350}; void MyUIInit() { if (!referee_recv_info->init_flag) vTaskDelete(NULL); // 如果没有初始化裁判系统则直接删除ui任务 + + if (Interactive_data->ui_mode == UI_KEEP) + return; + while (referee_recv_info->GameRobotState.robot_id == 0) osDelay(100); // 若还未收到裁判系统数据,等待一段时间后再检查 @@ -75,38 +80,39 @@ void MyUIInit() UILineDraw(&UI_shoot_line[2], "sl2", UI_Graph_ADD, 7, UI_Color_Yellow, 2, 810, shoot_line_location[2], 1110, shoot_line_location[2]); UILineDraw(&UI_shoot_line[3], "sl3", UI_Graph_ADD, 7, UI_Color_Yellow, 2, 810, shoot_line_location[3], 1110, shoot_line_location[3]); UILineDraw(&UI_shoot_line[4], "sl4", UI_Graph_ADD, 7, UI_Color_Yellow, 2, 810, shoot_line_location[4], 1110, shoot_line_location[4]); - UIGraphRefresh(&referee_recv_info->referee_id, 5, UI_shoot_line[0], UI_shoot_line[1], UI_shoot_line[2], UI_shoot_line[3], UI_shoot_line[4]); + UILineDraw(&UI_shoot_line[5], "sl5", UI_Graph_ADD, 7, UI_Color_Yellow, 2, 810, shoot_line_location[5], 1110, shoot_line_location[5]); + UIGraphRefresh(&referee_recv_info->referee_id, 7, UI_shoot_line[0], UI_shoot_line[1], UI_shoot_line[2], UI_shoot_line[3], UI_shoot_line[4], UI_shoot_line[5], UI_shoot_line[6]); // 绘制车辆状态标志指示 UICharDraw(&UI_State_sta[0], "ss0", UI_Graph_ADD, 8, UI_Color_Main, 15, 2, 150, 750, "chassis:"); UICharRefresh(&referee_recv_info->referee_id, UI_State_sta[0]); - UICharDraw(&UI_State_sta[1], "ss1", UI_Graph_ADD, 8, UI_Color_Yellow, 15, 2, 150, 700, "gimbal:"); + UICharDraw(&UI_State_sta[1], "ss1", UI_Graph_ADD, 8, UI_Color_Yellow, 15, 2, 150, 700, "frict:"); UICharRefresh(&referee_recv_info->referee_id, UI_State_sta[1]); - UICharDraw(&UI_State_sta[2], "ss2", UI_Graph_ADD, 8, UI_Color_Orange, 15, 2, 150, 650, "shoot:"); + UICharDraw(&UI_State_sta[2], "ss2", UI_Graph_ADD, 8, UI_Color_Orange, 15, 2, 150, 650, "vision:"); UICharRefresh(&referee_recv_info->referee_id, UI_State_sta[2]); - UICharDraw(&UI_State_sta[3], "ss3", UI_Graph_ADD, 8, UI_Color_Pink, 15, 2, 150, 600, "frict:"); - UICharRefresh(&referee_recv_info->referee_id, UI_State_sta[3]); - UICharDraw(&UI_State_sta[4], "ss4", UI_Graph_ADD, 8, UI_Color_Pink, 15, 2, 150, 550, "lid:"); + UICharDraw(&UI_State_sta[4], "ss4", UI_Graph_ADD, 8, UI_Color_Cyan, 15, 2, 150, 600, "loader:"); UICharRefresh(&referee_recv_info->referee_id, UI_State_sta[4]); // 绘制车辆状态标志,动态 // 由于初始化时xxx_last_mode默认为0,所以此处对应UI也应该设为0时对应的UI,防止模式不变的情况下无法置位flag,导致UI无法刷新 UICharDraw(&UI_State_dyn[0], "sd0", UI_Graph_ADD, 8, UI_Color_Main, 15, 2, 270, 750, "zeroforce"); UICharRefresh(&referee_recv_info->referee_id, UI_State_dyn[0]); - UICharDraw(&UI_State_dyn[1], "sd1", UI_Graph_ADD, 8, UI_Color_Yellow, 15, 2, 270, 700, "zeroforce"); + UICharDraw(&UI_State_dyn[1], "sd1", UI_Graph_ADD, 8, UI_Color_Pink, 15, 2, 270, 700, "off"); UICharRefresh(&referee_recv_info->referee_id, UI_State_dyn[1]); - UICharDraw(&UI_State_dyn[2], "sd2", UI_Graph_ADD, 8, UI_Color_Orange, 15, 2, 270, 650, "off"); + UICharDraw(&UI_State_dyn[2], "sd2", UI_Graph_ADD, 8, UI_Color_Orange, 15, 2, 270, 650, "unlock"); UICharRefresh(&referee_recv_info->referee_id, UI_State_dyn[2]); - UICharDraw(&UI_State_dyn[3], "sd3", UI_Graph_ADD, 8, UI_Color_Pink, 15, 2, 270, 600, "off"); - UICharRefresh(&referee_recv_info->referee_id, UI_State_dyn[3]); - UICharDraw(&UI_State_dyn[4], "sd4", UI_Graph_ADD, 8, UI_Color_Pink, 15, 2, 270, 550, "open "); + UICharDraw(&UI_State_dyn[4], "sd4", UI_Graph_ADD, 8, UI_Color_Cyan, 15, 2, 270, 600, "stop"); UICharRefresh(&referee_recv_info->referee_id, UI_State_dyn[4]); + // 绘制视觉标识框 + UIRectangleDraw(&UI_Vision[0], "sd3", UI_Graph_ADD, 9, UI_Color_Green, 2, 650, 700, 1270, 380); + UIGraphRefresh(&referee_recv_info->referee_id, 1, UI_Vision[0]); + // 底盘功率显示,静态 UICharDraw(&UI_State_sta[5], "ss5", UI_Graph_ADD, 7, UI_Color_Green, 18, 2, 620, 230, "Power:"); UICharRefresh(&referee_recv_info->referee_id, UI_State_sta[5]); // 能量条框 - UIRectangleDraw(&UI_Energy[0], "ss6", UI_Graph_ADD, 7, UI_Color_Green, 2, 720, 140, 1220, 180); + UIRectangleDraw(&UI_Energy[0], "ss6", UI_Graph_ADD, 7, UI_Color_Green, 2, 720, 140, 1420, 180); UIGraphRefresh(&referee_recv_info->referee_id, 1, UI_Energy[0]); // 底盘功率显示,动态 @@ -152,6 +158,7 @@ static void RobotModeTest(Referee_Interactive_info_t *_Interactive_data) // 测 } case 2: { + _Interactive_data->chassis_mode = CHASSIS_RESET; _Interactive_data->gimbal_mode = GIMBAL_GYRO_MODE; _Interactive_data->shoot_mode = SHOOT_ON; _Interactive_data->friction_mode = FRICTION_ON; @@ -187,6 +194,9 @@ static void MyUIRefresh(referee_info_t *referee_recv_info, Referee_Interactive_i UICharDraw(&UI_State_dyn[0], "sd0", UI_Graph_Change, 8, UI_Color_Main, 15, 2, 270, 750, "rotate "); // 此处注意字数对齐问题,字数相同才能覆盖掉 break; + case CHASSIS_RESET: + UICharDraw(&UI_State_dyn[0], "sd0", UI_Graph_Change, 8, UI_Color_Main, 15, 2, 270, 750, "reset "); + break; case CHASSIS_FOLLOW_GIMBAL_YAW: UICharDraw(&UI_State_dyn[0], "sd0", UI_Graph_Change, 8, UI_Color_Main, 15, 2, 270, 750, "follow "); break; @@ -194,50 +204,55 @@ static void MyUIRefresh(referee_info_t *referee_recv_info, Referee_Interactive_i UICharRefresh(&referee_recv_info->referee_id, UI_State_dyn[0]); _Interactive_data->Referee_Interactive_Flag.chassis_flag = 0; } - // gimbal - if (_Interactive_data->Referee_Interactive_Flag.gimbal_flag == 1) - { - switch (_Interactive_data->gimbal_mode) - { - case GIMBAL_ZERO_FORCE: - { - UICharDraw(&UI_State_dyn[1], "sd1", UI_Graph_Change, 8, UI_Color_Yellow, 15, 2, 270, 700, "zeroforce"); - break; - } - case GIMBAL_FREE_MODE: - { - UICharDraw(&UI_State_dyn[1], "sd1", UI_Graph_Change, 8, UI_Color_Yellow, 15, 2, 270, 700, "free "); - break; - } - case GIMBAL_GYRO_MODE: - { - UICharDraw(&UI_State_dyn[1], "sd1", UI_Graph_Change, 8, UI_Color_Yellow, 15, 2, 270, 700, "gyro "); - break; - } - } - UICharRefresh(&referee_recv_info->referee_id, UI_State_dyn[1]); - _Interactive_data->Referee_Interactive_Flag.gimbal_flag = 0; - } - // shoot - if (_Interactive_data->Referee_Interactive_Flag.shoot_flag == 1) - { - UICharDraw(&UI_State_dyn[2], "sd2", UI_Graph_Change, 8, UI_Color_Pink, 15, 2, 270, 650, _Interactive_data->shoot_mode == SHOOT_ON ? "on " : "off"); - UICharRefresh(&referee_recv_info->referee_id, UI_State_dyn[2]); - _Interactive_data->Referee_Interactive_Flag.shoot_flag = 0; - } // friction if (_Interactive_data->Referee_Interactive_Flag.friction_flag == 1) { - UICharDraw(&UI_State_dyn[3], "sd3", UI_Graph_Change, 8, UI_Color_Pink, 15, 2, 270, 600, _Interactive_data->friction_mode == FRICTION_ON ? "on " : "off"); - UICharRefresh(&referee_recv_info->referee_id, UI_State_dyn[3]); + UICharDraw(&UI_State_dyn[1], "sd1", UI_Graph_Change, 8, UI_Color_Pink, 15, 2, 270, 700, _Interactive_data->friction_mode == FRICTION_ON ? "on " : "off"); + UICharRefresh(&referee_recv_info->referee_id, UI_State_dyn[1]); _Interactive_data->Referee_Interactive_Flag.friction_flag = 0; } - // lid - if (_Interactive_data->Referee_Interactive_Flag.lid_flag == 1) + // vision + if (_Interactive_data->Referee_Interactive_Flag.vision_flag == 1) { - UICharDraw(&UI_State_dyn[4], "sd4", UI_Graph_Change, 8, UI_Color_Pink, 15, 2, 270, 550, _Interactive_data->lid_mode == LID_OPEN ? "open " : "close"); + switch (_Interactive_data->vision_mode) + { + case UNLOCK: + UICharDraw(&UI_State_dyn[2], "sd2", UI_Graph_Change, 8, UI_Color_Orange, 15, 2, 270, 650, "unlock "); + UIRectangleDraw(&UI_Vision[0], "sd3", UI_Graph_Change, 9, UI_Color_Green, 2, 650, 700, 1270, 380); + break; + case CONVERGE: + UICharDraw(&UI_State_dyn[2], "sd2", UI_Graph_Change, 8, UI_Color_Orange, 15, 2, 270, 650, "converge"); + UIRectangleDraw(&UI_Vision[0], "sd3", UI_Graph_Change, 9, UI_Color_Purplish_red, 2, 650, 700, 1270, 380); + break; + case LOCK: + UICharDraw(&UI_State_dyn[2], "sd2", UI_Graph_Change, 8, UI_Color_Orange, 15, 2, 270, 650, "lock "); + UIRectangleDraw(&UI_Vision[0], "sd3", UI_Graph_Change, 9, UI_Color_Purplish_red, 2, 650, 700, 1270, 380); + break; + } + UICharRefresh(&referee_recv_info->referee_id, UI_State_dyn[2]); + UIGraphRefresh(&referee_recv_info->referee_id, 1, UI_Vision[0]); + _Interactive_data->Referee_Interactive_Flag.vision_flag = 0; + } + // loader + if (_Interactive_data->Referee_Interactive_Flag.loader_flag == 1) + { + switch (_Interactive_data->loader_mode) + { + case LOAD_1_BULLET: + UICharDraw(&UI_State_dyn[4], "sd4", UI_Graph_Change, 8, UI_Color_Cyan, 15, 2, 270, 600, "1 bull"); + break; + case LOAD_3_BULLET: + UICharDraw(&UI_State_dyn[4], "sd4", UI_Graph_Change, 8, UI_Color_Purplish_red, 15, 2, 270, 600, "3 bull"); + break; + case LOAD_BURSTFIRE: + UICharDraw(&UI_State_dyn[4], "sd4", UI_Graph_Change, 8, UI_Color_Purplish_red, 15, 2, 270, 600, "burst "); + break; + case LOAD_STOP: + UICharDraw(&UI_State_dyn[4], "sd4", UI_Graph_Change, 8, UI_Color_Purplish_red, 15, 2, 270, 600, "stop "); + break; + } UICharRefresh(&referee_recv_info->referee_id, UI_State_dyn[4]); - _Interactive_data->Referee_Interactive_Flag.lid_flag = 0; + _Interactive_data->Referee_Interactive_Flag.loader_flag = 0; } // power if (_Interactive_data->Referee_Interactive_Flag.Power_flag == 1) @@ -292,4 +307,16 @@ static void UIChangeCheck(Referee_Interactive_info_t *_Interactive_data) _Interactive_data->Referee_Interactive_Flag.Power_flag = 1; _Interactive_data->Chassis_last_Power_Data.chassis_power_mx = _Interactive_data->Chassis_Power_Data.chassis_power_mx; } + + if(_Interactive_data->vision_mode != _Interactive_data->vision_last_mode) + { + _Interactive_data->Referee_Interactive_Flag.vision_flag = 1; + _Interactive_data->vision_last_mode = _Interactive_data->vision_mode; + } + + if (_Interactive_data->loader_mode != _Interactive_data->loader_last_mode) + { + _Interactive_data->Referee_Interactive_Flag.loader_flag = 1; + _Interactive_data->loader_last_mode = _Interactive_data->loader_mode; + } } diff --git a/modules/referee/rm_referee.h b/modules/referee/rm_referee.h index e935e94..e940851 100644 --- a/modules/referee/rm_referee.h +++ b/modules/referee/rm_referee.h @@ -54,6 +54,9 @@ typedef struct uint32_t lid_flag : 1; uint32_t friction_flag : 1; uint32_t Power_flag : 1; + uint32_t vision_flag : 1; + uint32_t loader_flag : 1; + uint32_t direction_flag : 1; } Referee_Interactive_Flag_t; // 此结构体包含UI绘制与机器人车间通信的需要的其他非裁判系统数据 @@ -67,6 +70,10 @@ typedef struct friction_mode_e friction_mode; // 摩擦轮关闭 lid_mode_e lid_mode; // 弹舱盖打开 Chassis_Power_Data_s Chassis_Power_Data; // 功率控制 + ui_mode_e ui_mode; // UI状态 + vision_mode_e vision_mode; // 视觉状态 + loader_mode_e loader_mode; // 拨盘模式 + chassis_direction_e direction; // 对齐状态 // 上一次的模式,用于flag判断 chassis_mode_e chassis_last_mode; @@ -75,6 +82,9 @@ typedef struct friction_mode_e friction_last_mode; lid_mode_e lid_last_mode; Chassis_Power_Data_s Chassis_last_Power_Data; + vision_mode_e vision_last_mode; + loader_mode_e loader_last_mode; + chassis_direction_e last_direction; } Referee_Interactive_info_t;