diff --git a/Makefile b/Makefile index 664d149..c551cca 100644 --- a/Makefile +++ b/Makefile @@ -145,7 +145,7 @@ modules/oled/oled.c \ modules/referee/crc_ref.c \ modules/referee/rm_referee.c \ modules/referee/referee_UI.c \ -modules/referee/referee_communication.c \ +modules/referee/referee_task.c \ modules/remote/remote_control.c \ modules/super_cap/super_cap.c \ modules/can_comm/can_comm.c \ @@ -155,7 +155,6 @@ modules/vofa/vofa.c \ application/gimbal/gimbal.c \ application/chassis/chassis.c \ application/shoot/shoot.c \ -application/referee/referee.c \ application/cmd/robot_cmd.c \ application/balance_chassis/balance.c \ application/robot.c @@ -237,7 +236,6 @@ C_INCLUDES = \ -Iapplication/gimbal \ -Iapplication/cmd \ -Iapplication/balance_chassis \ --Iapplication/referee \ -Iapplication \ -Ibsp/dwt \ -Ibsp/can \ diff --git a/Src/freertos.c b/Src/freertos.c index cb06e51..a743c86 100644 --- a/Src/freertos.c +++ b/Src/freertos.c @@ -1,20 +1,20 @@ /* USER CODE BEGIN Header */ /** - ****************************************************************************** - * File Name : freertos.c - * Description : Code for freertos applications - ****************************************************************************** - * @attention - * - * Copyright (c) 2023 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ + ****************************************************************************** + * File Name : freertos.c + * Description : Code for freertos applications + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ @@ -28,6 +28,7 @@ #include "ins_task.h" #include "motor_task.h" #include "led_task.h" +#include "referee_task.h" #include "daemon.h" #include "robot.h" /* USER CODE END Includes */ @@ -61,28 +62,32 @@ osThreadId uiTaskHandle; /* Private function prototypes -----------------------------------------------*/ /* USER CODE BEGIN FunctionPrototypes */ -void StartINSTASK(void const * argument); +void StartINSTASK(void const *argument); -void StartMOTORTASK(void const * argument); +void StartMOTORTASK(void const *argument); -void StartDAEMONTASK(void const* argument); +void StartDAEMONTASK(void const *argument); -void StartROBOTTASK(void const* argument); +void StartROBOTTASK(void const *argument); + +void StartROBOTTASK(void const *argument); + +void StartUITASK(void const *argument); /* USER CODE END FunctionPrototypes */ -void StartDefaultTask(void const * argument); +void StartDefaultTask(void const *argument); extern void MX_USB_DEVICE_Init(void); void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */ /* GetIdleTaskMemory prototype (linked to static allocation support) */ -void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ); +void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize); /* USER CODE BEGIN GET_IDLE_TASK_MEMORY */ static StaticTask_t xIdleTaskTCBBuffer; static StackType_t xIdleStack[configMINIMAL_STACK_SIZE]; -void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) +void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize) { *ppxIdleTaskTCBBuffer = &xIdleTaskTCBBuffer; *ppxIdleTaskStackBuffer = &xIdleStack[0]; @@ -92,11 +97,12 @@ void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackTy /* USER CODE END GET_IDLE_TASK_MEMORY */ /** - * @brief FreeRTOS initialization - * @param None - * @retval None - */ -void MX_FREERTOS_Init(void) { + * @brief FreeRTOS initialization + * @param None + * @retval None + */ +void MX_FREERTOS_Init(void) +{ /* USER CODE BEGIN Init */ /* USER CODE END Init */ @@ -134,25 +140,28 @@ void MX_FREERTOS_Init(void) { daemonTaskHandle = osThreadCreate(osThread(daemontask), NULL); osThreadDef(robottask, StartROBOTTASK, osPriorityNormal, 0, 1024); - robotTaskHandle = osThreadCreate(osThread(robottask), NULL); - /* USER CODE END RTOS_THREADS */ + defaultTaskHandle = osThreadCreate(osThread(robottask), NULL); + osThreadDef(uitask, StartUITASK, osPriorityNormal, 0, 512); + defaultTaskHandle = osThreadCreate(osThread(uitask), NULL); + + /* USER CODE END RTOS_THREADS */ } /* USER CODE BEGIN Header_StartDefaultTask */ /** - * @brief Function implementing the defaultTask thread. - * @param argument: Not used - * @retval None - */ + * @brief Function implementing the defaultTask thread. + * @param argument: Not used + * @retval None + */ /* USER CODE END Header_StartDefaultTask */ -void StartDefaultTask(void const * argument) +void StartDefaultTask(void const *argument) { /* init code for USB_DEVICE */ MX_USB_DEVICE_Init(); /* USER CODE BEGIN StartDefaultTask */ /* Infinite loop */ - for(;;) + for (;;) { osDelay(1); } @@ -161,43 +170,52 @@ void StartDefaultTask(void const * argument) /* Private application code --------------------------------------------------*/ /* USER CODE BEGIN Application */ -void StartINSTASK(void const * argument) +void StartINSTASK(void const *argument) { while (1) { - //1kHz - INS_Task(); + // 1kHz + // INS_Task(); osDelay(1); } } -void StartMOTORTASK(void const * argument) +void StartMOTORTASK(void const *argument) { while (1) { - //500Hz + // 500Hz MotorControlTask(); osDelay(2); } } -void StartDAEMONTASK(void const * argument) +void StartDAEMONTASK(void const *argument) { while (1) { - //100Hz + // 100Hz DaemonTask(); osDelay(10); } } -void StartROBOTTASK(void const * argument) +void StartROBOTTASK(void const *argument) { while (1) { // 200Hz RobotTask(); - osDelay(5);//syh此处暂时将时间改�?10ms,原因在于未使用缓冲区发送,发�?�时延时5ms + osDelay(5); // syh此处暂时将时间改�?10ms,原因在于未使用缓冲区发送,发�?�时延时5ms + } +} + +void StartUITASK(void const *argument) +{ + My_UI_init(); + while (1) + { + Referee_Interactive_task(); } } /* USER CODE END Application */ diff --git a/application/balance_chassis/balance.c b/application/balance_chassis/balance.c index f935571..7f9ec0e 100644 --- a/application/balance_chassis/balance.c +++ b/application/balance_chassis/balance.c @@ -7,11 +7,11 @@ #include "HT04.h" #include "LK9025.h" #include "bmi088.h" -#include "referee.h" #include "super_cap.h" #include "controller.h" #include "can_comm.h" #include "user_lib.h" +#include "rm_referee.h" // standard #include "stdint.h" #include "arm_math.h" // 需要用到较多三角函数 diff --git a/application/chassis/chassis.c b/application/chassis/chassis.c index 6b3cc54..0d70798 100644 --- a/application/chassis/chassis.c +++ b/application/chassis/chassis.c @@ -16,12 +16,7 @@ #include "dji_motor.h" #include "super_cap.h" #include "message_center.h" - -// referee需要移动到module层 -///////////////////////// - -#include "rm_referee.h" -///////////////////////// +#include "referee_task.h" #include "general_def.h" #include "bsp_dwt.h" @@ -47,6 +42,9 @@ static Subscriber_t *chassis_sub; // 用于订阅底盘的控 static Chassis_Ctrl_Cmd_s chassis_cmd_recv; // 底盘接收到的控制命令 static Chassis_Upload_Data_s chassis_feedback_data; // 底盘回传的反馈数据 +static referee_info_t* referee_data; // 用于获取裁判系统的数据 +static Referee_Interactive_info_t ui_data; // UI数据,将底盘中的数据传入此结构体的对应变量中,UI会自动检测是否变化,对应显示UI + static SuperCapInstance *cap; // 超级电容 static DJIMotorInstance *motor_lf, *motor_rf, *motor_lb, *motor_rb; // left right forward back @@ -105,10 +103,7 @@ void ChassisInit() chassis_motor_config.controller_setting_init_config.motor_reverse_flag = MOTOR_DIRECTION_REVERSE; motor_rb = DJIMotorInit(&chassis_motor_config); - // referee_data = RefereeInit(&huart6); // 裁判系统初始化 - - // while (referee_data->GameRobotState.robot_id ==0); - // Referee_Interactive_init(referee_data); + referee_data = Referee_Interactive_init(&huart6,&ui_data); // 裁判系统初始化 SuperCap_Init_Config_s cap_conf = { .can_config = { diff --git a/application/referee/referee.c b/application/referee/referee.c deleted file mode 100644 index 57ab4c6..0000000 --- a/application/referee/referee.c +++ /dev/null @@ -1,385 +0,0 @@ -/** - * @file referee.C - * @author kidneygood (you@domain.com) - * @brief - * @version 0.1 - * @date 2022-11-18 - * - * @copyright Copyright (c) 2022 - * - */ -#include "referee.h" -#include "robot_def.h" -#include "rm_referee.h" -#include "referee_UI.h" -#include "referee_communication.h" - -static Referee_Interactive_info_t Interactive_data; // 非裁判系统数据 -static referee_info_t *referee_data; // 裁判系统相关数据 -static robot_interactive_data_t *SendData; - -static void determine_ID(referee_info_t *_referee_info); -static void My_UI_init(referee_info_t *_referee_info); -static void My_UI_Refresh(referee_info_t *_referee_info, Referee_Interactive_info_t *_Interactive_data); -static void Mode_Change_Check(Referee_Interactive_info_t *_Interactive_data); // 模式切换检测 - -//syhtod 正式上车后需删除 -static void robot_mode_change(Referee_Interactive_info_t *_Interactive_data); // 测试用函数,实现模式自动变化 -static void UI_test_init(referee_info_t *_referee_info);//UI测试函数 - -void Referee_Interactive_init() -{ - referee_data = RefereeInit(&huart6); // 裁判系统初始化 - while (referee_data->GameRobotState.robot_id == 0) - ; - determine_ID(referee_data); - My_UI_init(referee_data); - //UI_test_init(referee_data); - - for (int i=0;idata[i]=i+1; - } - referee_data->referee_id.Receiver_Robot_ID = RobotID_BEngineer; // 机器人车间通信时接收者的ID暂时发给蓝色2 - Communicate_SendData(&referee_data->referee_id,SendData); -} - -void Referee_Interactive_task() -{ - robot_mode_change(&Interactive_data); // 测试用函数,实现模式自动变化 - My_UI_Refresh(referee_data, &Interactive_data); -} - -static Graph_Data_t UI_shoot_line[10]; // 射击准线 -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 void My_UI_init(referee_info_t *_referee_info) -{ - UI_Delete(&_referee_info->referee_id, UI_Data_Del_ALL, 0); - - // 绘制发射基准线 - Line_Draw(&UI_shoot_line[0], "sl0", UI_Graph_ADD, 7, UI_Color_White, 3, 710, shoot_line_location[0], 1210, shoot_line_location[0]); - Line_Draw(&UI_shoot_line[1], "sl1", UI_Graph_ADD, 7, UI_Color_White, 3, shoot_line_location[1], 340, shoot_line_location[1], 740); - Line_Draw(&UI_shoot_line[2], "sl2", UI_Graph_ADD, 7, UI_Color_Yellow, 2, 810, shoot_line_location[2], 1110, shoot_line_location[2]); - Line_Draw(&UI_shoot_line[3], "sl3", UI_Graph_ADD, 7, UI_Color_Yellow, 2, 810, shoot_line_location[3], 1110, shoot_line_location[3]); - Line_Draw(&UI_shoot_line[4], "sl4", UI_Graph_ADD, 7, UI_Color_Yellow, 2, 810, shoot_line_location[4], 1110, shoot_line_location[4]); - - UI_ReFresh(&_referee_info->referee_id, 5, UI_shoot_line[0], UI_shoot_line[1], UI_shoot_line[2], UI_shoot_line[3], UI_shoot_line[4]); - - // 绘制车辆状态标志,静态 - Char_Draw(&UI_State_sta[0], "ss0", UI_Graph_ADD, 8, UI_Color_Main, 15, 2, 150, 750); - Char_Write(&UI_State_sta[0], "chassis:"); - Char_ReFresh(&_referee_info->referee_id, UI_State_sta[0]); - - Char_Draw(&UI_State_sta[1], "ss1", UI_Graph_ADD, 8, UI_Color_Yellow, 15, 2, 150, 700); - Char_Write(&UI_State_sta[1], "gimbal:"); - Char_ReFresh(&_referee_info->referee_id, UI_State_sta[1]); - - Char_Draw(&UI_State_sta[2], "ss2", UI_Graph_ADD, 8, UI_Color_Orange, 15, 2, 150, 650); - Char_Write(&UI_State_sta[2], "shoot:"); - Char_ReFresh(&_referee_info->referee_id, UI_State_sta[2]); - - Char_Draw(&UI_State_sta[3], "ss3", UI_Graph_ADD, 8, UI_Color_Pink, 15, 2, 150, 600); - Char_Write(&UI_State_sta[3], "frict:"); - Char_ReFresh(&_referee_info->referee_id, UI_State_sta[3]); - - Char_Draw(&UI_State_sta[4], "ss4", UI_Graph_ADD, 8, UI_Color_Pink, 15, 2, 150, 550); - Char_Write(&UI_State_sta[4], "lid:"); - Char_ReFresh(&_referee_info->referee_id, UI_State_sta[4]); - - // 底盘功率显示,静态 - Char_Draw(&UI_State_sta[5], "ss5", UI_Graph_ADD, 8, UI_Color_Green, 18, 2, 720, 210); - Char_Write(&UI_State_sta[5], "Power:"); - Char_ReFresh(&_referee_info->referee_id, UI_State_sta[5]); - - // 绘制车辆状态标志,动态 - // 由于初始化时xxx_last_mode默认为0,所以此处对应UI也应该设为0时对应的UI,防止模式不变的情况下无法置位flag,导致UI无法刷新 - Char_Draw(&UI_State_dyn[0], "sd0", UI_Graph_ADD, 8, UI_Color_Main, 15, 2, 270, 750); - Char_Write(&UI_State_dyn[0], "zeroforce"); - Char_ReFresh(&_referee_info->referee_id, UI_State_dyn[0]); - - Char_Draw(&UI_State_dyn[1], "sd1", UI_Graph_ADD, 8, UI_Color_Yellow, 15, 2, 270, 700); - Char_Write(&UI_State_dyn[1], "zeroforce"); - Char_ReFresh(&_referee_info->referee_id, UI_State_dyn[1]); - - Char_Draw(&UI_State_dyn[2], "sd2", UI_Graph_ADD, 8, UI_Color_Orange, 15, 2, 270, 650); - Char_Write(&UI_State_dyn[2], "off"); - Char_ReFresh(&_referee_info->referee_id, UI_State_dyn[2]); - - Char_Draw(&UI_State_dyn[3], "sd3", UI_Graph_ADD, 8, UI_Color_Pink, 15, 2, 270, 600); - Char_Write(&UI_State_dyn[3], "off"); - Char_ReFresh(&_referee_info->referee_id, UI_State_dyn[3]); - - Char_Draw(&UI_State_dyn[4], "sd4", UI_Graph_ADD, 8, UI_Color_Pink, 15, 2, 270, 550); - Char_Write(&UI_State_dyn[4], "open "); - Char_ReFresh(&_referee_info->referee_id, UI_State_dyn[4]); - - // 底盘功率显示,动态 - Char_Draw(&UI_State_dyn[5], "sd5", UI_Graph_ADD, 8, UI_Color_Green, 18, 2, 840, 210); - Char_Write(&UI_State_dyn[5], "0000"); - Char_ReFresh(&_referee_info->referee_id, UI_State_dyn[5]); -} - -static uint8_t count = 0; -static uint16_t count1 = 0; -static void robot_mode_change(Referee_Interactive_info_t *_Interactive_data) // 测试用函数,实现模式自动变化 -{ - count++; - if (count >= 50) - { - count = 0; - count1++; - } - switch (count1 % 4) - { - case 0: - { - _Interactive_data->chassis_mode = CHASSIS_ZERO_FORCE; - _Interactive_data->gimbal_mode = GIMBAL_ZERO_FORCE; - _Interactive_data->shoot_mode = SHOOT_ON; - _Interactive_data->friction_mode = FRICTION_ON; - _Interactive_data->lid_mode = LID_OPEN; - break; - } - case 1: - { - ; - _Interactive_data->chassis_mode = CHASSIS_ROTATE; - _Interactive_data->gimbal_mode = GIMBAL_FREE_MODE; - _Interactive_data->shoot_mode = SHOOT_OFF; - _Interactive_data->friction_mode = FRICTION_OFF; - _Interactive_data->lid_mode = LID_CLOSE; - break; - } - case 2: - { - _Interactive_data->chassis_mode = CHASSIS_NO_FOLLOW; - _Interactive_data->gimbal_mode = GIMBAL_GYRO_MODE; - _Interactive_data->shoot_mode = SHOOT_ON; - _Interactive_data->friction_mode = FRICTION_ON; - _Interactive_data->lid_mode = LID_OPEN; - break; - } - case 3: - { - _Interactive_data->chassis_mode = CHASSIS_FOLLOW_GIMBAL_YAW; - _Interactive_data->gimbal_mode = GIMBAL_ZERO_FORCE; - _Interactive_data->shoot_mode = SHOOT_OFF; - _Interactive_data->friction_mode = FRICTION_OFF; - _Interactive_data->lid_mode = LID_CLOSE; - break; - } - default: - break; - } -} - -static void My_UI_Refresh(referee_info_t *_referee_info, Referee_Interactive_info_t *_Interactive_data) -{ - Mode_Change_Check(_Interactive_data); - // chassis - if (_Interactive_data->Referee_Interactive_Flag.chassis_flag == 1) - { - switch (_Interactive_data->chassis_mode) - { - case CHASSIS_ZERO_FORCE: - { - Char_Draw(&UI_State_dyn[0], "sd0", UI_Graph_Change, 8, UI_Color_Main, 15, 2, 270, 750); - Char_Write(&UI_State_dyn[0], "zeroforce"); - break; - } - case CHASSIS_ROTATE: - { - Char_Draw(&UI_State_dyn[0], "sd0", UI_Graph_Change, 8, UI_Color_Main, 15, 2, 270, 750); - Char_Write(&UI_State_dyn[0], "rotate "); // 此处注意字数对齐问题,字数相同才能覆盖掉 - break; - } - case CHASSIS_NO_FOLLOW: - { - Char_Draw(&UI_State_dyn[0], "sd0", UI_Graph_Change, 8, UI_Color_Main, 15, 2, 270, 750); - Char_Write(&UI_State_dyn[0], "nofollow "); - break; - } - case CHASSIS_FOLLOW_GIMBAL_YAW: - { - Char_Draw(&UI_State_dyn[0], "sd0", UI_Graph_Change, 8, UI_Color_Main, 15, 2, 270, 750); - Char_Write(&UI_State_dyn[0], "follow "); - break; - } - } - Char_ReFresh(&_referee_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: - { - Char_Draw(&UI_State_dyn[1], "sd1", UI_Graph_Change, 8, UI_Color_Yellow, 15, 2, 270, 700); - Char_Write(&UI_State_dyn[1], "zeroforce"); - break; - } - case GIMBAL_FREE_MODE: - { - Char_Draw(&UI_State_dyn[1], "sd1", UI_Graph_Change, 8, UI_Color_Yellow, 15, 2, 270, 700); - Char_Write(&UI_State_dyn[1], "free "); - break; - } - case GIMBAL_GYRO_MODE: - { - Char_Draw(&UI_State_dyn[1], "sd1", UI_Graph_Change, 8, UI_Color_Yellow, 15, 2, 270, 700); - Char_Write(&UI_State_dyn[1], "gyro "); - break; - } - } - Char_ReFresh(&_referee_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) - { - switch (_Interactive_data->shoot_mode) - { - case SHOOT_OFF: - { - Char_Draw(&UI_State_dyn[2], "sd2", UI_Graph_Change, 8, UI_Color_Orange, 15, 2, 270, 650); - Char_Write(&UI_State_dyn[2], "off"); - break; - } - case SHOOT_ON: - { - Char_Draw(&UI_State_dyn[2], "sd2", UI_Graph_Change, 8, UI_Color_Orange, 15, 2, 270, 650); - Char_Write(&UI_State_dyn[2], "on "); - break; - } - } - Char_ReFresh(&_referee_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) - { - switch (_Interactive_data->friction_mode) - { - case FRICTION_OFF: - { - Char_Draw(&UI_State_dyn[3], "sd3", UI_Graph_Change, 8, UI_Color_Pink, 15, 2, 270, 600); - Char_Write(&UI_State_dyn[3], "off"); - break; - } - case FRICTION_ON: - { - Char_Draw(&UI_State_dyn[3], "sd3", UI_Graph_Change, 8, UI_Color_Pink, 15, 2, 270, 600); - Char_Write(&UI_State_dyn[3], "on "); - break; - } - } - Char_ReFresh(&_referee_info->referee_id, UI_State_dyn[3]); - _Interactive_data->Referee_Interactive_Flag.friction_flag = 0; - } - // lid - if (_Interactive_data->Referee_Interactive_Flag.lid_flag == 1) - { - switch (_Interactive_data->lid_mode) - { - case LID_CLOSE: - { - Char_Draw(&UI_State_dyn[4], "sd4", UI_Graph_Change, 8, UI_Color_Pink, 15, 2, 270, 550); - Char_Write(&UI_State_dyn[4], "close"); - break; - } - case LID_OPEN: - { - Char_Draw(&UI_State_dyn[4], "sd4", UI_Graph_Change, 8, UI_Color_Pink, 15, 2, 270, 550); - Char_Write(&UI_State_dyn[4], "open "); - break; - } - } - Char_ReFresh(&_referee_info->referee_id, UI_State_dyn[4]); - _Interactive_data->Referee_Interactive_Flag.lid_flag = 0; - } -} - - -/** - * @brief 模式切换检测,模式发生切换时,对flag置位 - * @param Referee_Interactive_info_t *_Interactive_data - * @retval none - * @attention - */ -static void Mode_Change_Check(Referee_Interactive_info_t *_Interactive_data) -{ - if (_Interactive_data->chassis_mode != _Interactive_data->chassis_last_mode) - { - _Interactive_data->Referee_Interactive_Flag.chassis_flag = 1; - _Interactive_data->chassis_last_mode = _Interactive_data->chassis_mode; - } - - if (_Interactive_data->gimbal_mode != _Interactive_data->gimbal_last_mode) - { - _Interactive_data->Referee_Interactive_Flag.gimbal_flag = 1; - _Interactive_data->gimbal_last_mode = _Interactive_data->gimbal_mode; - } - - if (_Interactive_data->shoot_mode != _Interactive_data->shoot_last_mode) - { - _Interactive_data->Referee_Interactive_Flag.shoot_flag = 1; - _Interactive_data->shoot_last_mode = _Interactive_data->shoot_mode; - } - - if (_Interactive_data->friction_mode != _Interactive_data->friction_last_mode) - { - _Interactive_data->Referee_Interactive_Flag.friction_flag = 1; - _Interactive_data->friction_last_mode = _Interactive_data->friction_mode; - } - - if (_Interactive_data->lid_mode != _Interactive_data->lid_last_mode) - { - _Interactive_data->Referee_Interactive_Flag.lid_flag = 1; - _Interactive_data->lid_last_mode = _Interactive_data->lid_mode; - } -} - -/** - * @brief 判断各种ID,选择客户端ID - * @param referee_info_t *_referee_info - * @retval none - * @attention - */ -static void determine_ID(referee_info_t *_referee_info) -{ - // id小于7是红色,大于7是蓝色,0为红色,1为蓝色 #define Robot_Red 0 #define Robot_Blue 1 - _referee_info->referee_id.Robot_Color = _referee_info->GameRobotState.robot_id > 7 ? Robot_Blue : Robot_Red; - _referee_info->referee_id.Robot_ID = _referee_info->GameRobotState.robot_id; - _referee_info->referee_id.Cilent_ID = 0x0100 + _referee_info->referee_id.Robot_ID; // 计算客户端ID - _referee_info->referee_id.Receiver_Robot_ID = 0; -} - -/* 测试用函数 */ -static void UI_test_init(referee_info_t *_referee_info) -{ - Graph_Data_t graph[5]; - Graph_Data_t num[2]; - String_Data_t sdata[1]; - UI_Delete(&_referee_info->referee_id, UI_Data_Del_ALL, 0); - - Line_Draw(&graph[0],"s0",UI_Graph_ADD,0,UI_Color_White,3,710,540,1210,540); - Rectangle_Draw(&graph[1],"s1",UI_Graph_ADD,0,UI_Color_Yellow,4,600,200,800,500); - Circle_Draw(&graph[2],"s2",UI_Graph_ADD,0,UI_Color_Green,5,960,540,100); - Elliptical_Draw(&graph[3],"s3",UI_Graph_ADD,0,UI_Color_Orange,3,960,540,100,20); - Arc_Draw(&graph[4],"s4",UI_Graph_ADD,0,UI_Color_Purplish_red,30,160,3,1200,550,50,100); - - Float_Draw(&num[0],"s5",UI_Graph_ADD,0,UI_Color_Pink,50,3,5,1050,660,1245545); - Integer_Draw(&num[1],"s6",UI_Graph_ADD,0,UI_Color_Cyan,50,5,1050,460,12345); - UI_ReFresh(&_referee_info->referee_id,7,graph[0],graph[1],graph[2],graph[3],graph[4],num[0],num[1]); - - - Char_Draw(&sdata[0],"s7",UI_Graph_ADD,0,UI_Color_Green,20,2,620,710); - Char_Write(&sdata[0],"number:%d",123); - Char_ReFresh(&_referee_info->referee_id,sdata[0]); -} diff --git a/application/referee/referee.h b/application/referee/referee.h deleted file mode 100644 index d531d5a..0000000 --- a/application/referee/referee.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef REFEREE_H -#define REFEREE_H - -#include "rm_referee.h" -#include "robot_def.h" -#pragma pack(1) - -//模式是否切换标志位,0为未切换,1为切换,static定义默认为0 -typedef struct -{ - uint32_t chassis_flag : 1; - uint32_t gimbal_flag : 1; - uint32_t shoot_flag : 1; - uint32_t lid_flag : 1; - uint32_t friction_flag : 1; - uint32_t Power_flag : 1; -} Referee_Interactive_Flag_t; - - -// 此结构体包含UI绘制与机器人车间通信的需要的其他非裁判系统数据 -typedef struct -{ - Referee_Interactive_Flag_t Referee_Interactive_Flag; - //为UI绘制以及交互数据所用 - Robot_Status_e Robot_Status;// 机器人状态 - App_Status_e App_Status;// 应用状态 - chassis_mode_e chassis_mode;//底盘模式 - gimbal_mode_e gimbal_mode;//云台模式 - shoot_mode_e shoot_mode;//发射模式设置 - friction_mode_e friction_mode;//摩擦轮关闭 - lid_mode_e lid_mode;//弹舱盖打开 - loader_mode_e loader_mode;//单发...连发 - Chassis_Power_Data_s Chassis_Power_Data;// 功率控制 - - chassis_mode_e chassis_last_mode;//底盘模式 - gimbal_mode_e gimbal_last_mode;//云台模式 - shoot_mode_e shoot_last_mode;//发射模式设置 - friction_mode_e friction_last_mode;//摩擦轮关闭 - lid_mode_e lid_last_mode;//弹舱盖打开 - -} Referee_Interactive_info_t; - -#pragma pack() - -void Referee_Interactive_init(void); -void Referee_Interactive_task(void); -#endif // REFEREE_H - - - diff --git a/application/referee/referee.md b/application/referee/referee.md deleted file mode 100644 index 7e97160..0000000 --- a/application/referee/referee.md +++ /dev/null @@ -1,3 +0,0 @@ -# referee - -需要将此模块移动到module层,并新建一个rtos任务,以一定频率运行,用于ui刷新和多机通信 diff --git a/modules/referee/crc_ref.h b/modules/referee/crc_ref.h index 2b210fe..7ad1297 100644 --- a/modules/referee/crc_ref.h +++ b/modules/referee/crc_ref.h @@ -1,7 +1,7 @@ #ifndef __CRC_H_ #define __CRC_H_ -//裁判系统官方CRC校验,LUT和module/algorithms中的不同,后续需要统一实现crc,提供8/16/32的支持 +// 裁判系统官方CRC校验,LUT和module/algorithms中的不同,后续需要统一实现crc,提供8/16/32的支持 #include diff --git a/modules/referee/referee.md b/modules/referee/referee.md index d818026..395d999 100644 --- a/modules/referee/referee.md +++ b/modules/referee/referee.md @@ -1,3 +1,199 @@ # referee -当前模块组织较为混乱,后续统一为多机通信+裁判系统信息接收+UI绘制。UI绘制和多机通信的发送部分在referee任务中以一定的频率运行,信息的接收通过中断完成。 \ No newline at end of file +## referee运行流程 + +首先在chassis的初始化中调用裁判系统初始化函数,将要绘制的uidata的指针传递给接口,接口会返回裁判系统的反馈数据指针。然后,在refereeUItask里进行UI初始化,确定ui发送的目标并绘制初始化UI。完成后,uitask会以10hz的频率按顺序更新UI。 + + +## 如何绘制你的自定义UI?以绘制超级电容能量条为例: + +UI的绘制包含初始化和TASK两个部分,初始化部分在`My_UI_init`函数中,TASK部分在`My_UI_Refresh`函数中。 + +### 初始化部分: + +初始化部分的UI主要有两个目的:静态UI的绘制、为动态UI的绘制做准备。 + +分析超级电容能量条功能可知,此UI包含如下: +Power:xxx Power为静态不变的,冒号后的xxx为变化的量。 +方框以及方框内的能量条:方框为静态不变的,能量条为变化的量。(参考游戏血条) + +因而,静态UI的绘制包含如下: +绘制字符“Power:”、绘制矩形方框。 +为动态UI的准备如下: +绘制矩形方框内的初始能量条、绘制Power的初始值。 + +### 绘制字符“Power:”: + +设置绘制用结构体,此处使用数组是因为需要绘制多个字符。本次绘制的字符为“Power:”,只是用到了第6个,即xxx[5]: + +```c +static String_Data_t UI_State_sta[6]; // 静态 +``` + +字符格式以及内容设置: + +```c +Char_Draw(&UI_State_sta[5], "ss5", UI_Graph_ADD, 7, UI_Color_Green, 18, 2, 620, 230, "Power:"); + +//各参数意义如下,函数定义中有详细注释: + string String_Data类型变量指针,用于存放字符串数据 + stringname[3] 字符串名称,用于标识更改 + String_Operate 字符串操作,初始化时一般使用"UI_Graph_ADD" + String_Layer 图层0-9 + String_Color 字符串颜色 + String_Size 字号 + String_Width 字符串线宽 + Start_x、Start_y 开始坐标 + *stringdata 字符串数据 + +//设置完毕后,使用“Char_ReFresh”发送即可: +Char_ReFresh(&referee_recv_info->referee_id, UI_State_sta[5]); +``` + + + +### 绘制能量框: + +定义一个图形类结构体,用于绘制能量框: + +```c +static Graph_Data_t UI_energy_line[3]; // 电容能量条 +``` + +能量框参数设置以及发送函数: + +```c +Rectangle_Draw(&UI_energy_line[0],"ss6", UI_Graph_ADD, 7, UI_Color_Green,20, 720, 220, 820, 240) +UI_ReFresh(&referee_recv_info->referee_id, 1,UI_energy_line[0]); +``` + +### 绘制power的初始值: + +```c +Float_Draw(&UI_Energy[1], "sd5", UI_Graph_ADD, 8, UI_Color_Green, 18, 2, 2, 750, 230, 24000); +``` + +### 绘制能量条的初始值: + +```c +Line_Draw(&UI_Energy[2], "sd6", UI_Graph_ADD, 8, UI_Color_Pink, 30, 720, 160, 1020, 160); +``` + +将两个图形打包发送 + +``` +UI_ReFresh(&referee_recv_info->referee_id, 2, UI_Energy[1], UI_Energy[2]); +``` + +## TASK部分 + +task中UI处于动态变化,此时需要检测所画的UI是否发生变化,若发生变化,则刷新对应UI。 +### 添加变化检测: + +绘制功率部分UI,我们需要的是`Chassis_Power_Data_s`中的数据,我们定义`Chassis_Power_Data_s Chassis_Power_Data;`和`Chassis_Power_Data_s Chassis_last_Power_Data;`分别存储此次和上次的对应数据,本次和上次对应检测变化的需求。 + +```c +typedef struct +{ + Referee_Interactive_Flag_t Referee_Interactive_Flag; + // 为UI绘制以及交互数据所用 + chassis_mode_e chassis_mode; // 底盘模式 + gimbal_mode_e gimbal_mode; // 云台模式 + shoot_mode_e shoot_mode; // 发射模式设置 + friction_mode_e friction_mode; // 摩擦轮关闭 + lid_mode_e lid_mode; // 弹舱盖打开 + Chassis_Power_Data_s Chassis_Power_Data; // 功率控制 + + // 上一次的模式,用于flag判断 + chassis_mode_e chassis_last_mode; + gimbal_mode_e gimbal_last_mode; + shoot_mode_e shoot_last_mode; + friction_mode_e friction_last_mode; + lid_mode_e lid_last_mode; + Chassis_Power_Data_s Chassis_last_Power_Data; + +} Referee_Interactive_info_t; +``` + +添加功率变化标志位,`uint32_t Power_flag : 1;`,1为检测到变化,0为未检测到变换 + +``` +typedef struct +{ + uint32_t chassis_flag : 1; + uint32_t gimbal_flag : 1; + uint32_t shoot_flag : 1; + uint32_t lid_flag : 1; + uint32_t friction_flag : 1; + uint32_t Power_flag : 1; +} Referee_Interactive_Flag_t; +``` +在变化检测函数中增加对应判断,由于voltage和能量条的变化对应同一个参数`Chassis_last_Power_Data.chassis_power_mx`的变化,所以只需要一个参数即可: +``` +static void Mode_Change_Check(Referee_Interactive_info_t *_Interactive_data) +{ + if (_Interactive_data->chassis_mode != _Interactive_data->chassis_last_mode) + ...... + ...... + if (_Interactive_data->lid_mode != _Interactive_data->lid_last_mode) + { + _Interactive_data->Referee_Interactive_Flag.lid_flag = 1; + _Interactive_data->lid_last_mode = _Interactive_data->lid_mode; + } + + if (_Interactive_data->Chassis_Power_Data.chassis_power_mx != _Interactive_data->Chassis_last_Power_Data.chassis_power_mx) + { + _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; + } +} +``` +### 根据功率的变化绘制UI: + +在绘制变化的UI时,由于初始化时已经使用`UI_Graph_ADD`操作添加了UI,所以在绘制时,需要使用`UI_Graph_Change`操作,以便于刷新UI。 + +同时,完成UI刷新后,需要将对应的flag置0,以便于下次检测变化 +``` +if (_Interactive_data->Referee_Interactive_Flag.Power_flag == 1) +{ + Float_Draw(&UI_Energy[1], "sd5", UI_Graph_Change, 8, UI_Color_Green, 18, 2, 2, 750, 230, _Interactive_data->Chassis_Power_Data.chassis_power_mx * 1000); + Line_Draw(&UI_Energy[2], "sd6", UI_Graph_Change, 8, UI_Color_Pink, 30, 720, 160, (uint32_t)750 + _Interactive_data->Chassis_Power_Data.chassis_power_mx * 30, 160); + UI_ReFresh(&referee_recv_info->referee_id, 2, UI_Energy[1], UI_Energy[2]); + _Interactive_data->Referee_Interactive_Flag.Power_flag = 0; +} +``` + + + + + + +# +# +# +若需要进行多机交互,可增加此函数: +```c +void CommBetweenRobotSend(referee_id_t *_id, robot_interactive_data_t *_data) +{ + Communicate_SendData_t SendData; + uint8_t temp_datalength = Interactive_Data_LEN_Head + Communicate_Data_LEN; // 计算交互数据长度 6+n,n为交互数据长度 + + SendData.FrameHeader.SOF = REFEREE_SOF; + SendData.FrameHeader.DataLength = temp_datalength; + SendData.FrameHeader.Seq = UI_Seq; + SendData.FrameHeader.CRC8 = Get_CRC8_Check_Sum((uint8_t *)&SendData, LEN_CRC8, 0xFF); + + SendData.CmdID = ID_student_interactive; + + SendData.datahead.data_cmd_id = Communicate_Data_ID; + SendData.datahead.sender_ID = _id->Robot_ID; + SendData.datahead.receiver_ID = _id->Receiver_Robot_ID; + + SendData.Data = *_data; + + SendData.frametail = Get_CRC16_Check_Sum((uint8_t *)&SendData, LEN_HEADER + LEN_CMDID + temp_datalength, 0xFFFF); + + RefereeSend((uint8_t *)&SendData, LEN_HEADER + LEN_CMDID + temp_datalength + LEN_TAIL); // 发送 + UI_Seq++; // 包序号+1 +} +``` \ No newline at end of file diff --git a/modules/referee/referee_UI.c b/modules/referee/referee_UI.c index 2dc3e36..cd83ced 100644 --- a/modules/referee/referee_UI.c +++ b/modules/referee/referee_UI.c @@ -10,424 +10,415 @@ */ #include "referee_UI.h" #include "string.h" -#include "crc.h" +#include "crc_ref.h" #include "stdio.h" #include "rm_referee.h" // 包序号 /********************************************删除操作************************************* **参数:_id 对应的id结构体 - Del_Operate 对应头文件删除操作 - Del_Layer 要删除的层 取值0-9 + Del_Operate 对应头文件删除操作 + Del_Layer 要删除的层 取值0-9 *****************************************************************************************/ -void UI_Delete(referee_id_t *_id, uint8_t Del_Operate, uint8_t Del_Layer) +void UIDelete(referee_id_t *_id, uint8_t Del_Operate, uint8_t Del_Layer) { - UI_delete_t UI_delete_data; - uint8_t temp_datalength = Interactive_Data_LEN_Head + UI_Operate_LEN_Del; // 计算交互数据长度 + UI_delete_t UI_delete_data; + uint8_t temp_datalength = Interactive_Data_LEN_Head + UI_Operate_LEN_Del; // 计算交互数据长度 - UI_delete_data.FrameHeader.SOF = REFEREE_SOF; - UI_delete_data.FrameHeader.DataLength = temp_datalength; - UI_delete_data.FrameHeader.Seq = UI_Seq; - UI_delete_data.FrameHeader.CRC8 = Get_CRC8_Check_Sum((uint8_t *)&UI_delete_data, LEN_CRC8, 0xFF); + UI_delete_data.FrameHeader.SOF = REFEREE_SOF; + UI_delete_data.FrameHeader.DataLength = temp_datalength; + UI_delete_data.FrameHeader.Seq = UI_Seq; + UI_delete_data.FrameHeader.CRC8 = Get_CRC8_Check_Sum((uint8_t *)&UI_delete_data, LEN_CRC8, 0xFF); - UI_delete_data.CmdID = ID_student_interactive; + UI_delete_data.CmdID = ID_student_interactive; - UI_delete_data.datahead.data_cmd_id = UI_Data_ID_Del; - UI_delete_data.datahead.receiver_ID = _id->Cilent_ID; - UI_delete_data.datahead.sender_ID = _id->Robot_ID; + UI_delete_data.datahead.data_cmd_id = UI_Data_ID_Del; + UI_delete_data.datahead.receiver_ID = _id->Cilent_ID; + UI_delete_data.datahead.sender_ID = _id->Robot_ID; - UI_delete_data.Delete_Operate = Del_Operate; // 删除操作 - UI_delete_data.Layer = Del_Layer; + UI_delete_data.Delete_Operate = Del_Operate; // 删除操作 + UI_delete_data.Layer = Del_Layer; - UI_delete_data.frametail = Get_CRC16_Check_Sum((uint8_t *)&UI_delete_data, LEN_HEADER + LEN_CMDID + temp_datalength, 0xFFFF); - /* 填入0xFFFF,关于crc校验 */ + UI_delete_data.frametail = Get_CRC16_Check_Sum((uint8_t *)&UI_delete_data, LEN_HEADER + LEN_CMDID + temp_datalength, 0xFFFF); + /* 填入0xFFFF,关于crc校验 */ - RefereeSend((uint8_t *)&UI_delete_data, LEN_HEADER + LEN_CMDID + temp_datalength + LEN_TAIL); // 发送 + RefereeSend((uint8_t *)&UI_delete_data, LEN_HEADER + LEN_CMDID + temp_datalength + LEN_TAIL); // 发送 - UI_Seq++; // 包序号+1 + UI_Seq++; // 包序号+1 } /************************************************绘制直线************************************************* **参数:*graph Graph_Data类型变量指针,用于存放图形数据 - graphname[3] 图片名称,用于标识更改 - Graph_Operate 图片操作,见头文件 - Graph_Layer 图层0-9 - Graph_Color 图形颜色 - Graph_Width 图形线宽 - Start_x、Start_y 起点xy坐标 - End_x、End_y 终点xy坐标 + graphname[3] 图片名称,用于标识更改 + Graph_Operate 图片操作,见头文件 + Graph_Layer 图层0-9 + Graph_Color 图形颜色 + Graph_Width 图形线宽 + Start_x、Start_y 起点xy坐标 + End_x、End_y 终点xy坐标 **********************************************************************************************************/ void Line_Draw(Graph_Data_t *graph, char graphname[3], uint32_t Graph_Operate, uint32_t Graph_Layer, uint32_t Graph_Color, - uint32_t Graph_Width, uint32_t Start_x, uint32_t Start_y, uint32_t End_x, uint32_t End_y) + uint32_t Graph_Width, uint32_t Start_x, uint32_t Start_y, uint32_t End_x, uint32_t End_y) { - int i; - for (i = 0; i < 3 && graphname[i] != '\0'; i++) // 填充至‘0’为止 - { - graph->graphic_name[2 - i] = graphname[i]; // 按内存地址增大方向填充,所以会有i与2-i - } + int i; + for (i = 0; i < 3 && graphname[i] != '\0'; i++) // 填充至‘0’为止 + { + graph->graphic_name[2 - i] = graphname[i]; // 按内存地址增大方向填充,所以会有i与2-i + } - graph->operate_tpye = Graph_Operate; - graph->graphic_tpye = UI_Graph_Line; - graph->layer = Graph_Layer; - graph->color = Graph_Color; + graph->operate_tpye = Graph_Operate; + graph->graphic_tpye = UI_Graph_Line; + graph->layer = Graph_Layer; + graph->color = Graph_Color; - graph->start_angle = 0; - graph->end_angle = 0; - graph->width = Graph_Width; - graph->start_x = Start_x; - graph->start_y = Start_y; - graph->radius = 0; - graph->end_x = End_x; - graph->end_y = End_y; + graph->start_angle = 0; + graph->end_angle = 0; + graph->width = Graph_Width; + graph->start_x = Start_x; + graph->start_y = Start_y; + graph->radius = 0; + graph->end_x = End_x; + graph->end_y = End_y; } /************************************************绘制矩形************************************************* **参数:*graph Graph_Data类型变量指针,用于存放图形数据 - graphname[3] 图片名称,用于标识更改 - Graph_Operate 图片操作,见头文件 - Graph_Layer 图层0-9 - Graph_Color 图形颜色 - Graph_Width 图形线宽 - Start_x、Start_y 起点xy坐标 - End_x、End_y 对角顶点xy坐标 + graphname[3] 图片名称,用于标识更改 + Graph_Operate 图片操作,见头文件 + Graph_Layer 图层0-9 + Graph_Color 图形颜色 + Graph_Width 图形线宽 + Start_x、Start_y 起点xy坐标 + End_x、End_y 对角顶点xy坐标 **********************************************************************************************************/ void Rectangle_Draw(Graph_Data_t *graph, char graphname[3], uint32_t Graph_Operate, uint32_t Graph_Layer, uint32_t Graph_Color, - uint32_t Graph_Width, uint32_t Start_x, uint32_t Start_y, uint32_t End_x, uint32_t End_y) + uint32_t Graph_Width, uint32_t Start_x, uint32_t Start_y, uint32_t End_x, uint32_t End_y) { - int i; - for (i = 0; i < 3 && graphname[i] != '\0'; i++) - { - graph->graphic_name[2 - i] = graphname[i]; - } + int i; + for (i = 0; i < 3 && graphname[i] != '\0'; i++) + { + graph->graphic_name[2 - i] = graphname[i]; + } - graph->graphic_tpye = UI_Graph_Rectangle; - graph->operate_tpye = Graph_Operate; - graph->layer = Graph_Layer; - graph->color = Graph_Color; + graph->graphic_tpye = UI_Graph_Rectangle; + graph->operate_tpye = Graph_Operate; + graph->layer = Graph_Layer; + graph->color = Graph_Color; - graph->start_angle = 0; - graph->end_angle = 0; - graph->width = Graph_Width; - graph->start_x = Start_x; - graph->start_y = Start_y; - graph->radius = 0; - graph->end_x = End_x; - graph->end_y = End_y; + graph->start_angle = 0; + graph->end_angle = 0; + graph->width = Graph_Width; + graph->start_x = Start_x; + graph->start_y = Start_y; + graph->radius = 0; + graph->end_x = End_x; + graph->end_y = End_y; } /************************************************绘制整圆************************************************* **参数:*graph Graph_Data类型变量指针,用于存放图形数据 - graphname[3] 图片名称,用于标识更改 - Graph_Operate 图片操作,见头文件 - Graph_Layer 图层0-9 - Graph_Color 图形颜色 - Graph_Width 图形线宽 - Start_x、Start_y 圆心xy坐标 - Graph_Radius 圆形半径 + graphname[3] 图片名称,用于标识更改 + Graph_Operate 图片操作,见头文件 + Graph_Layer 图层0-9 + Graph_Color 图形颜色 + Graph_Width 图形线宽 + Start_x、Start_y 圆心xy坐标 + Graph_Radius 圆形半径 **********************************************************************************************************/ void Circle_Draw(Graph_Data_t *graph, char graphname[3], uint32_t Graph_Operate, uint32_t Graph_Layer, uint32_t Graph_Color, - uint32_t Graph_Width, uint32_t Start_x, uint32_t Start_y, uint32_t Graph_Radius) + uint32_t Graph_Width, uint32_t Start_x, uint32_t Start_y, uint32_t Graph_Radius) { - int i; - for (i = 0; i < 3 && graphname[i] != '\0'; i++) - { - graph->graphic_name[2 - i] = graphname[i]; - } + int i; + for (i = 0; i < 3 && graphname[i] != '\0'; i++) + { + graph->graphic_name[2 - i] = graphname[i]; + } - graph->graphic_tpye = UI_Graph_Circle; - graph->operate_tpye = Graph_Operate; - graph->layer = Graph_Layer; - graph->color = Graph_Color; + graph->graphic_tpye = UI_Graph_Circle; + graph->operate_tpye = Graph_Operate; + graph->layer = Graph_Layer; + graph->color = Graph_Color; - graph->start_angle = 0; - graph->end_angle = 0; - graph->width = Graph_Width; - graph->start_x = Start_x; - graph->start_y = Start_y; - graph->radius = Graph_Radius; - graph->end_x = 0; - graph->end_y = 0; + graph->start_angle = 0; + graph->end_angle = 0; + graph->width = Graph_Width; + graph->start_x = Start_x; + graph->start_y = Start_y; + graph->radius = Graph_Radius; + graph->end_x = 0; + graph->end_y = 0; } /************************************************绘制椭圆************************************************* **参数:*graph Graph_Data类型变量指针,用于存放图形数据 - graphname[3] 图片名称,用于标识更改 - Graph_Operate 图片操作,见头文件 - Graph_Layer 图层0-9 - Graph_Color 图形颜色 - Graph_Width 图形线宽 - Start_x、Start_y 圆心xy坐标 - End_x、End_y xy半轴长度 + graphname[3] 图片名称,用于标识更改 + Graph_Operate 图片操作,见头文件 + Graph_Layer 图层0-9 + Graph_Color 图形颜色 + Graph_Width 图形线宽 + Start_x、Start_y 圆心xy坐标 + End_x、End_y xy半轴长度 **********************************************************************************************************/ void Elliptical_Draw(Graph_Data_t *graph, char graphname[3], uint32_t Graph_Operate, uint32_t Graph_Layer, uint32_t Graph_Color, - uint32_t Graph_Width, uint32_t Start_x, uint32_t Start_y, uint32_t end_x, uint32_t end_y) + uint32_t Graph_Width, uint32_t Start_x, uint32_t Start_y, uint32_t end_x, uint32_t end_y) { - int i; - for (i = 0; i < 3 && graphname[i] != '\0'; i++) - { - graph->graphic_name[2 - i] = graphname[i]; - } + int i; + for (i = 0; i < 3 && graphname[i] != '\0'; i++) + { + graph->graphic_name[2 - i] = graphname[i]; + } - graph->graphic_tpye = UI_Graph_Ellipse; - graph->operate_tpye = Graph_Operate; - graph->layer = Graph_Layer; - graph->color = Graph_Color; - graph->width = Graph_Width; + graph->graphic_tpye = UI_Graph_Ellipse; + graph->operate_tpye = Graph_Operate; + graph->layer = Graph_Layer; + graph->color = Graph_Color; + graph->width = Graph_Width; - graph->start_angle = 0; - graph->end_angle = 0; - graph->width = Graph_Width; - graph->start_x = Start_x; - graph->start_y = Start_y; - graph->radius = 0; - graph->end_x = end_x; - graph->end_y = end_y; + graph->start_angle = 0; + graph->end_angle = 0; + graph->width = Graph_Width; + graph->start_x = Start_x; + graph->start_y = Start_y; + graph->radius = 0; + graph->end_x = end_x; + graph->end_y = end_y; } /************************************************绘制圆弧************************************************* **参数:*graph Graph_Data类型变量指针,用于存放图形数据 - graphname[3] 图片名称,用于标识更改 - Graph_Operate 图片操作,见头文件 - Graph_Layer 图层0-9 - Graph_Color 图形颜色 - Graph_StartAngle,Graph_EndAngle 起始终止角度 - Graph_Width 图形线宽 - Start_y,Start_y 圆心xy坐标 - x_Length,y_Length xy半轴长度 + graphname[3] 图片名称,用于标识更改 + Graph_Operate 图片操作,见头文件 + Graph_Layer 图层0-9 + Graph_Color 图形颜色 + Graph_StartAngle,Graph_EndAngle 起始终止角度 + Graph_Width 图形线宽 + Start_y,Start_y 圆心xy坐标 + x_Length,y_Length xy半轴长度 **********************************************************************************************************/ void Arc_Draw(Graph_Data_t *graph, char graphname[3], uint32_t Graph_Operate, uint32_t Graph_Layer, uint32_t Graph_Color, - uint32_t Graph_StartAngle, uint32_t Graph_EndAngle, uint32_t Graph_Width, uint32_t Start_x, uint32_t Start_y, - uint32_t end_x, uint32_t end_y) + uint32_t Graph_StartAngle, uint32_t Graph_EndAngle, uint32_t Graph_Width, uint32_t Start_x, uint32_t Start_y, + uint32_t end_x, uint32_t end_y) { - int i; - for (i = 0; i < 3 && graphname[i] != '\0'; i++) - { - graph->graphic_name[2 - i] = graphname[i]; - } + int i; + for (i = 0; i < 3 && graphname[i] != '\0'; i++) + { + graph->graphic_name[2 - i] = graphname[i]; + } - graph->graphic_tpye = UI_Graph_Arc; - graph->operate_tpye = Graph_Operate; - graph->layer = Graph_Layer; - graph->color = Graph_Color; + graph->graphic_tpye = UI_Graph_Arc; + graph->operate_tpye = Graph_Operate; + graph->layer = Graph_Layer; + graph->color = Graph_Color; - graph->start_angle = Graph_StartAngle; - graph->end_angle = Graph_EndAngle; - graph->width = Graph_Width; - graph->start_x = Start_x; - graph->start_y = Start_y; - graph->radius = 0; - graph->end_x = end_x; - graph->end_y = end_y; + graph->start_angle = Graph_StartAngle; + graph->end_angle = Graph_EndAngle; + graph->width = Graph_Width; + graph->start_x = Start_x; + graph->start_y = Start_y; + graph->radius = 0; + graph->end_x = end_x; + graph->end_y = end_y; } /************************************************绘制浮点型数据************************************************* **参数:*graph Graph_Data类型变量指针,用于存放图形数据 - graphname[3] 图片名称,用于标识更改 - Graph_Operate 图片操作,见头文件 - Graph_Layer 图层0-9 - Graph_Color 图形颜色 - Graph_Size 字号 - Graph_Digit 小数位数 - Graph_Width 图形线宽 - Start_x、Start_y 开始坐标 - radius=a&0x3FF; a为浮点数乘以1000后的32位整型数 - end_x=(a>>10)&0x7FF; - end_y=(a>>21)&0x7FF; + graphname[3] 图片名称,用于标识更改 + Graph_Operate 图片操作,见头文件 + Graph_Layer 图层0-9 + Graph_Color 图形颜色 + Graph_Size 字号 + Graph_Digit 小数位数 + Graph_Width 图形线宽 + Start_x、Start_y 开始坐标 + radius=a&0x3FF; a为浮点数乘以1000后的32位整型数 + end_x=(a>>10)&0x7FF; + end_y=(a>>21)&0x7FF; **********************************************************************************************************/ void Float_Draw(Graph_Data_t *graph, char graphname[3], uint32_t Graph_Operate, uint32_t Graph_Layer, uint32_t Graph_Color, - uint32_t Graph_Size, uint32_t Graph_Digit, uint32_t Graph_Width, uint32_t Start_x, uint32_t Start_y, int32_t Graph_Float) + uint32_t Graph_Size, uint32_t Graph_Digit, uint32_t Graph_Width, uint32_t Start_x, uint32_t Start_y, int32_t Graph_Float) { - int i; - for (i = 0; i < 3 && graphname[i] != '\0'; i++) - { - graph->graphic_name[2 - i] = graphname[i]; - } - graph->graphic_tpye = UI_Graph_Float; - graph->operate_tpye = Graph_Operate; - graph->layer = Graph_Layer; - graph->color = Graph_Color; + int i; + for (i = 0; i < 3 && graphname[i] != '\0'; i++) + { + graph->graphic_name[2 - i] = graphname[i]; + } + graph->graphic_tpye = UI_Graph_Float; + graph->operate_tpye = Graph_Operate; + graph->layer = Graph_Layer; + graph->color = Graph_Color; - graph->width = Graph_Width; - graph->start_x = Start_x; - graph->start_y = Start_y; - graph->start_angle = Graph_Size; - graph->end_angle = Graph_Digit; + graph->width = Graph_Width; + graph->start_x = Start_x; + graph->start_y = Start_y; + graph->start_angle = Graph_Size; + graph->end_angle = Graph_Digit; - graph->radius = Graph_Float & 0x3FF; - graph->end_x = (Graph_Float >> 10) & 0x7FF; - graph->end_y = (Graph_Float >> 21) & 0x7FF; + graph->radius = Graph_Float & 0x3FF; + graph->end_x = (Graph_Float >> 10) & 0x7FF; + graph->end_y = (Graph_Float >> 21) & 0x7FF; } /************************************************绘制整型数据************************************************* **参数:*graph Graph_Data类型变量指针,用于存放图形数据 - graphname[3] 图片名称,用于标识更改 - Graph_Operate 图片操作,见头文件 - Graph_Layer 图层0-9 - Graph_Color 图形颜色 - Graph_Size 字号 - Graph_Width 图形线宽 - Start_x、Start_y 开始坐标 - radius=a&0x3FF; a为32位整型数 - end_x=(a>>10)&0x7FF; - end_y=(a>>21)&0x7FF; + graphname[3] 图片名称,用于标识更改 + Graph_Operate 图片操作,见头文件 + Graph_Layer 图层0-9 + Graph_Color 图形颜色 + Graph_Size 字号 + Graph_Width 图形线宽 + Start_x、Start_y 开始坐标 + radius=a&0x3FF; a为32位整型数 + end_x=(a>>10)&0x7FF; + end_y=(a>>21)&0x7FF; **********************************************************************************************************/ void Integer_Draw(Graph_Data_t *graph, char graphname[3], uint32_t Graph_Operate, uint32_t Graph_Layer, uint32_t Graph_Color, - uint32_t Graph_Size, uint32_t Graph_Width, uint32_t Start_x, uint32_t Start_y, int32_t Graph_Integer) + uint32_t Graph_Size, uint32_t Graph_Width, uint32_t Start_x, uint32_t Start_y, int32_t Graph_Integer) { - int i; - for (i = 0; i < 3 && graphname[i] != '\0'; i++) - { - graph->graphic_name[2 - i] = graphname[i]; - } - graph->graphic_tpye = UI_Graph_Int; - graph->operate_tpye = Graph_Operate; - graph->layer = Graph_Layer; - graph->color = Graph_Color; + int i; + for (i = 0; i < 3 && graphname[i] != '\0'; i++) + { + graph->graphic_name[2 - i] = graphname[i]; + } + graph->graphic_tpye = UI_Graph_Int; + graph->operate_tpye = Graph_Operate; + graph->layer = Graph_Layer; + graph->color = Graph_Color; - graph->start_angle = Graph_Size; - graph->end_angle = 0; - graph->width = Graph_Width; - graph->start_x = Start_x; - graph->start_y = Start_y; - graph->radius = Graph_Integer & 0x3FF; - graph->end_x = (Graph_Integer >> 10) & 0x7FF; - graph->end_y = (Graph_Integer >> 21) & 0x7FF; + graph->start_angle = Graph_Size; + graph->end_angle = 0; + graph->width = Graph_Width; + graph->start_x = Start_x; + graph->start_y = Start_y; + graph->radius = Graph_Integer & 0x3FF; + graph->end_x = (Graph_Integer >> 10) & 0x7FF; + graph->end_y = (Graph_Integer >> 21) & 0x7FF; } /************************************************绘制字符型数据************************************************* **参数:*graph Graph_Data类型变量指针,用于存放图形数据 - graphname[3] 图片名称,用于标识更改 - Graph_Operate 图片操作,见头文件 - Graph_Layer 图层0-9 - Graph_Color 图形颜色 - Graph_Size 字号 - Graph_Width 图形线宽 - Start_x、Start_y 开始坐标 + graphname[3] 图片名称,用于标识更改 + Graph_Operate 图片操作,见头文件 + Graph_Layer 图层0-9 + Graph_Color 图形颜色 + Graph_Size 字号 + Graph_Width 图形线宽 + Start_x、Start_y 开始坐标 + +**参数:*graph Graph_Data类型变量指针,用于存放图形数据 + fmt需要显示的字符串 + 此函数的实现和具体使用类似于printf函数 **********************************************************************************************************/ void Char_Draw(String_Data_t *graph, char graphname[3], uint32_t Graph_Operate, uint32_t Graph_Layer, uint32_t Graph_Color, - uint32_t Graph_Size, uint32_t Graph_Width, uint32_t Start_x, uint32_t Start_y) + uint32_t Graph_Size, uint32_t Graph_Width, uint32_t Start_x, uint32_t Start_y, char *fmt, ...) { - int i; - for (i = 0; i < 3 && graphname[i] != '\0'; i++) - { - graph->Graph_Control.graphic_name[2 - i] = graphname[i]; - } + int i; + for (i = 0; i < 3 && graphname[i] != '\0'; i++) + { + graph->Graph_Control.graphic_name[2 - i] = graphname[i]; + } - graph->Graph_Control.graphic_tpye = UI_Graph_Char; - graph->Graph_Control.operate_tpye = Graph_Operate; - graph->Graph_Control.layer = Graph_Layer; - graph->Graph_Control.color = Graph_Color; + graph->Graph_Control.graphic_tpye = UI_Graph_Char; + graph->Graph_Control.operate_tpye = Graph_Operate; + graph->Graph_Control.layer = Graph_Layer; + graph->Graph_Control.color = Graph_Color; - graph->Graph_Control.width = Graph_Width; - graph->Graph_Control.start_x = Start_x; - graph->Graph_Control.start_y = Start_y; - graph->Graph_Control.start_angle = Graph_Size; - graph->Graph_Control.radius = 0; - graph->Graph_Control.end_x = 0; - graph->Graph_Control.end_y = 0; -} + graph->Graph_Control.width = Graph_Width; + graph->Graph_Control.start_x = Start_x; + graph->Graph_Control.start_y = Start_y; + graph->Graph_Control.start_angle = Graph_Size; + graph->Graph_Control.radius = 0; + graph->Graph_Control.end_x = 0; + graph->Graph_Control.end_y = 0; -/************************************************绘制字符型数据************************************************* -**参数:*graph Graph_Data类型变量指针,用于存放图形数据 - fmt需要显示的字符串 - 此函数的实现和具体使用类似于printf函数 -**********************************************************************************************************/ -void Char_Write(String_Data_t *graph, char *fmt, ...) -{ - uint16_t i = 0; - va_list ap; - va_start(ap, fmt); - vsprintf((char *)graph->show_Data, fmt, ap); // 使用参数列表进行格式化并输出到字符串 - va_end(ap); - i = strlen((const char *)graph->show_Data); - graph->Graph_Control.end_angle = i; + va_list ap; + va_start(ap, fmt); + vsprintf((char *)graph->show_Data, fmt, ap); // 使用参数列表进行格式化并输出到字符串 + va_end(ap); + graph->Graph_Control.end_angle = strlen((const char *)graph->show_Data); } /* UI推送函数(使更改生效) 参数: cnt 图形个数 - ... 图形变量参数 + ... 图形变量参数 Tips::该函数只能推送1,2,5,7个图形,其他数目协议未涉及 */ void UI_ReFresh(referee_id_t *_id, int cnt, ...) { - int i; - UI_GraphReFresh_t UI_GraphReFresh_data; - Graph_Data_t graphData; + UI_GraphReFresh_t UI_GraphReFresh_data; + Graph_Data_t graphData; - va_list ap; // 创建一个 va_list 类型变量 - va_start(ap, cnt); // 初始化 va_list 变量为一个参数列表 + uint8_t temp_datalength = LEN_HEADER + LEN_CMDID + Interactive_Data_LEN_Head + UI_Operate_LEN_PerDraw * cnt + LEN_TAIL; // 计算交互数据长度 - UI_GraphReFresh_data.FrameHeader.SOF = REFEREE_SOF; - UI_GraphReFresh_data.FrameHeader.DataLength = Interactive_Data_LEN_Head + cnt * UI_Operate_LEN_PerDraw; - UI_GraphReFresh_data.FrameHeader.Seq = UI_Seq; - UI_GraphReFresh_data.FrameHeader.CRC8 = Get_CRC8_Check_Sum((uint8_t *)&UI_GraphReFresh_data, LEN_CRC8, 0xFF); + uint8_t buffer[temp_datalength]; // 交互数据缓存 - UI_GraphReFresh_data.CmdID = ID_student_interactive; + va_list ap; // 创建一个 va_list 类型变量 + va_start(ap, cnt); // 初始化 va_list 变量为一个参数列表 - switch (cnt) - { - case 1: - UI_GraphReFresh_data.datahead.data_cmd_id = UI_Data_ID_Draw1; - break; - case 2: - UI_GraphReFresh_data.datahead.data_cmd_id = UI_Data_ID_Draw2; - break; - case 5: - UI_GraphReFresh_data.datahead.data_cmd_id = UI_Data_ID_Draw5; - break; - case 7: - UI_GraphReFresh_data.datahead.data_cmd_id = UI_Data_ID_Draw7; - break; - } + UI_GraphReFresh_data.FrameHeader.SOF = REFEREE_SOF; + UI_GraphReFresh_data.FrameHeader.DataLength = Interactive_Data_LEN_Head + cnt * UI_Operate_LEN_PerDraw; + UI_GraphReFresh_data.FrameHeader.Seq = UI_Seq; + UI_GraphReFresh_data.FrameHeader.CRC8 = Get_CRC8_Check_Sum((uint8_t *)&UI_GraphReFresh_data, LEN_CRC8, 0xFF); - UI_GraphReFresh_data.datahead.receiver_ID = _id->Cilent_ID; - UI_GraphReFresh_data.datahead.sender_ID = _id->Robot_ID; + UI_GraphReFresh_data.CmdID = ID_student_interactive; - // 先发送帧头、命令码、交互数据帧头三部分,并计算CRC16校验值 - UI_GraphReFresh_data.frametail = Get_CRC16_Check_Sum((uint8_t *)&UI_GraphReFresh_data, LEN_HEADER + LEN_CMDID + Interactive_Data_LEN_Head, 0xFFFF); - RefereeSend((uint8_t *)&UI_GraphReFresh_data, LEN_HEADER + LEN_CMDID + Interactive_Data_LEN_Head); + switch (cnt) + { + case 1: + UI_GraphReFresh_data.datahead.data_cmd_id = UI_Data_ID_Draw1; + break; + case 2: + UI_GraphReFresh_data.datahead.data_cmd_id = UI_Data_ID_Draw2; + break; + case 5: + UI_GraphReFresh_data.datahead.data_cmd_id = UI_Data_ID_Draw5; + break; + case 7: + UI_GraphReFresh_data.datahead.data_cmd_id = UI_Data_ID_Draw7; + break; + } - for (i = 0; i < cnt; i++) // 发送交互数据的数据帧,并计算CRC16校验值 - { - graphData = va_arg(ap, Graph_Data_t); // 访问参数列表中的每个项,第二个参数是你要返回的参数的类型,在取值时需要将其强制转化为指定类型的变量 - // 发送并计算CRC16 - RefereeSend((uint8_t *)&graphData, UI_Operate_LEN_PerDraw); - UI_GraphReFresh_data.frametail = Get_CRC16_Check_Sum((uint8_t *)&graphData, UI_Operate_LEN_PerDraw, UI_GraphReFresh_data.frametail); - } + UI_GraphReFresh_data.datahead.receiver_ID = _id->Cilent_ID; + UI_GraphReFresh_data.datahead.sender_ID = _id->Robot_ID; + memcpy(buffer, (uint8_t *)&UI_GraphReFresh_data, LEN_HEADER + LEN_CMDID + Interactive_Data_LEN_Head); // 将帧头、命令码、交互数据帧头三部分复制到缓存中 - RefereeSend((uint8_t *)&UI_GraphReFresh_data.frametail, LEN_TAIL); // 发送CRC16校验值 + for (uint8_t i = 0; i < cnt; i++) // 发送交互数据的数据帧,并计算CRC16校验值 + { + graphData = va_arg(ap, Graph_Data_t); // 访问参数列表中的每个项,第二个参数是你要返回的参数的类型,在取值时需要将其强制转化为指定类型的变量 + memcpy(buffer + (LEN_HEADER + LEN_CMDID + Interactive_Data_LEN_Head + UI_Operate_LEN_PerDraw * i), (uint8_t *)&graphData, UI_Operate_LEN_PerDraw); + } + Append_CRC16_Check_Sum(buffer, temp_datalength); + RefereeSend(buffer, temp_datalength); - va_end(ap); // 结束可变参数的获取 - UI_Seq++; // 包序号+1 + va_end(ap); // 结束可变参数的获取 } /************************************************UI推送字符(使更改生效)*********************************/ void Char_ReFresh(referee_id_t *_id, String_Data_t string_Data) { - UI_CharReFresh_t UI_CharReFresh_data; + UI_CharReFresh_t UI_CharReFresh_data; - uint8_t temp_datalength = Interactive_Data_LEN_Head + UI_Operate_LEN_DrawChar; // 计算交互数据长度 + uint8_t temp_datalength = Interactive_Data_LEN_Head + UI_Operate_LEN_DrawChar; // 计算交互数据长度 - UI_CharReFresh_data.FrameHeader.SOF = REFEREE_SOF; - UI_CharReFresh_data.FrameHeader.DataLength = temp_datalength; - UI_CharReFresh_data.FrameHeader.Seq = UI_Seq; - UI_CharReFresh_data.FrameHeader.CRC8 = Get_CRC8_Check_Sum((uint8_t *)&UI_CharReFresh_data, LEN_CRC8, 0xFF); + UI_CharReFresh_data.FrameHeader.SOF = REFEREE_SOF; + UI_CharReFresh_data.FrameHeader.DataLength = temp_datalength; + UI_CharReFresh_data.FrameHeader.Seq = UI_Seq; + UI_CharReFresh_data.FrameHeader.CRC8 = Get_CRC8_Check_Sum((uint8_t *)&UI_CharReFresh_data, LEN_CRC8, 0xFF); - UI_CharReFresh_data.CmdID = ID_student_interactive; + UI_CharReFresh_data.CmdID = ID_student_interactive; - UI_CharReFresh_data.datahead.data_cmd_id = UI_Data_ID_DrawChar; + UI_CharReFresh_data.datahead.data_cmd_id = UI_Data_ID_DrawChar; - UI_CharReFresh_data.datahead.receiver_ID = _id->Cilent_ID; - UI_CharReFresh_data.datahead.sender_ID = _id->Robot_ID; + UI_CharReFresh_data.datahead.receiver_ID = _id->Cilent_ID; + UI_CharReFresh_data.datahead.sender_ID = _id->Robot_ID; - UI_CharReFresh_data.String_Data = string_Data; + UI_CharReFresh_data.String_Data = string_Data; - UI_CharReFresh_data.frametail = Get_CRC16_Check_Sum((uint8_t *)&UI_CharReFresh_data, LEN_HEADER + LEN_CMDID + temp_datalength, 0xFFFF); + UI_CharReFresh_data.frametail = Get_CRC16_Check_Sum((uint8_t *)&UI_CharReFresh_data, LEN_HEADER + LEN_CMDID + temp_datalength, 0xFFFF); - RefereeSend((uint8_t *)&UI_CharReFresh_data, LEN_HEADER + LEN_CMDID + temp_datalength + LEN_TAIL); // 发送 + RefereeSend((uint8_t *)&UI_CharReFresh_data, LEN_HEADER + LEN_CMDID + temp_datalength + LEN_TAIL); // 发送 - UI_Seq++; // 包序号+1 + UI_Seq++; // 包序号+1 } diff --git a/modules/referee/referee_UI.h b/modules/referee/referee_UI.h index 474b966..cc7125c 100644 --- a/modules/referee/referee_UI.h +++ b/modules/referee/referee_UI.h @@ -3,75 +3,70 @@ #include "stdarg.h" #include "stdint.h" -#include "referee_def.h" +#include "referee_protocol.h" #include "rm_referee.h" -#pragma pack(1) //按1字节对齐 +#pragma pack(1) // 按1字节对齐 /* 此处的定义只与UI绘制有关 */ typedef struct { - xFrameHeader FrameHeader; - uint16_t CmdID; + xFrameHeader FrameHeader; + uint16_t CmdID; ext_student_interactive_header_data_t datahead; - uint8_t Delete_Operate; //删除操作 - uint8_t Layer; + uint8_t Delete_Operate; // 删除操作 + uint8_t Layer; uint16_t frametail; } UI_delete_t; typedef struct { - xFrameHeader FrameHeader; - uint16_t CmdID; + xFrameHeader FrameHeader; + uint16_t CmdID; ext_student_interactive_header_data_t datahead; uint16_t frametail; } UI_GraphReFresh_t; typedef struct { - xFrameHeader FrameHeader; - uint16_t CmdID; + xFrameHeader FrameHeader; + uint16_t CmdID; ext_student_interactive_header_data_t datahead; String_Data_t String_Data; - uint16_t frametail; -} UI_CharReFresh_t; //打印字符串数据 + uint16_t frametail; +} UI_CharReFresh_t; // 打印字符串数据 #pragma pack() +void UIDelete(referee_id_t *_id, uint8_t Del_Operate, uint8_t Del_Layer); +void Line_Draw(Graph_Data_t *graph, char graphname[3], uint32_t Graph_Operate, uint32_t Graph_Layer, uint32_t Graph_Color, + uint32_t Graph_Width, uint32_t Start_x, uint32_t Start_y, uint32_t End_x, uint32_t End_y); +void Rectangle_Draw(Graph_Data_t *graph, char graphname[3], uint32_t Graph_Operate, uint32_t Graph_Layer, uint32_t Graph_Color, + uint32_t Graph_Width, uint32_t Start_x, uint32_t Start_y, uint32_t End_x, uint32_t End_y); -void UI_Delete(referee_id_t *_id,uint8_t Del_Operate,uint8_t Del_Layer); +void Circle_Draw(Graph_Data_t *graph, char graphname[3], uint32_t Graph_Operate, uint32_t Graph_Layer, uint32_t Graph_Color, + uint32_t Graph_Width, uint32_t Start_x, uint32_t Start_y, uint32_t Graph_Radius); -void Line_Draw(Graph_Data_t *graph,char graphname[3],uint32_t Graph_Operate,uint32_t Graph_Layer,uint32_t Graph_Color, - uint32_t Graph_Width,uint32_t Start_x,uint32_t Start_y,uint32_t End_x,uint32_t End_y); +void Elliptical_Draw(Graph_Data_t *graph, char graphname[3], uint32_t Graph_Operate, uint32_t Graph_Layer, uint32_t Graph_Color, + uint32_t Graph_Width, uint32_t Start_x, uint32_t Start_y, uint32_t end_x, uint32_t end_y); -void Rectangle_Draw(Graph_Data_t *graph,char graphname[3],uint32_t Graph_Operate,uint32_t Graph_Layer,uint32_t Graph_Color, - uint32_t Graph_Width,uint32_t Start_x,uint32_t Start_y,uint32_t End_x,uint32_t End_y); +void Arc_Draw(Graph_Data_t *graph, char graphname[3], uint32_t Graph_Operate, uint32_t Graph_Layer, uint32_t Graph_Color, + uint32_t Graph_StartAngle, uint32_t Graph_EndAngle, uint32_t Graph_Width, uint32_t Start_x, uint32_t Start_y, + uint32_t end_x, uint32_t end_y); -void Circle_Draw(Graph_Data_t *graph,char graphname[3],uint32_t Graph_Operate,uint32_t Graph_Layer,uint32_t Graph_Color, - uint32_t Graph_Width,uint32_t Start_x,uint32_t Start_y,uint32_t Graph_Radius); +void Float_Draw(Graph_Data_t *graph, char graphname[3], uint32_t Graph_Operate, uint32_t Graph_Layer, uint32_t Graph_Color, + uint32_t Graph_Size, uint32_t Graph_Digit, uint32_t Graph_Width, uint32_t Start_x, uint32_t Start_y, int32_t Graph_Float); -void Elliptical_Draw(Graph_Data_t *graph,char graphname[3],uint32_t Graph_Operate,uint32_t Graph_Layer,uint32_t Graph_Color, - uint32_t Graph_Width,uint32_t Start_x,uint32_t Start_y,uint32_t end_x,uint32_t end_y); +void Integer_Draw(Graph_Data_t *graph, char graphname[3], uint32_t Graph_Operate, uint32_t Graph_Layer, uint32_t Graph_Color, + uint32_t Graph_Size, uint32_t Graph_Width, uint32_t Start_x, uint32_t Start_y, int32_t Graph_Integer); -void Arc_Draw(Graph_Data_t *graph,char graphname[3],uint32_t Graph_Operate,uint32_t Graph_Layer,uint32_t Graph_Color, - uint32_t Graph_StartAngle,uint32_t Graph_EndAngle,uint32_t Graph_Width,uint32_t Start_x,uint32_t Start_y, - uint32_t end_x,uint32_t end_y); +void Char_Draw(String_Data_t *graph, char graphname[3], uint32_t Graph_Operate, uint32_t Graph_Layer, uint32_t Graph_Color, + uint32_t Graph_Size, uint32_t Graph_Width, uint32_t Start_x, uint32_t Start_y, char *fmt, ...); -void Float_Draw(Graph_Data_t *graph,char graphname[3],uint32_t Graph_Operate,uint32_t Graph_Layer,uint32_t Graph_Color, - uint32_t Graph_Size,uint32_t Graph_Digit,uint32_t Graph_Width,uint32_t Start_x,uint32_t Start_y,int32_t Graph_Float); - -void Integer_Draw(Graph_Data_t *graph,char graphname[3],uint32_t Graph_Operate,uint32_t Graph_Layer,uint32_t Graph_Color, - uint32_t Graph_Size,uint32_t Graph_Width,uint32_t Start_x,uint32_t Start_y,int32_t Graph_Integer); +void UI_ReFresh(referee_id_t *_id, int cnt, ...); -void Char_Draw(String_Data_t *graph,char graphname[3],uint32_t Graph_Operate,uint32_t Graph_Layer,uint32_t Graph_Color, - uint32_t Graph_Size,uint32_t Graph_Width,uint32_t Start_x,uint32_t Start_y); +void Char_ReFresh(referee_id_t *_id, String_Data_t string_Data); -void Char_Write(String_Data_t *graph,char* fmt, ...); - -void UI_ReFresh(referee_id_t *_id,int cnt,...); - -void Char_ReFresh(referee_id_t *_id,String_Data_t string_Data); - #endif diff --git a/modules/referee/referee_communication.c b/modules/referee/referee_communication.c deleted file mode 100644 index 3896700..0000000 --- a/modules/referee/referee_communication.c +++ /dev/null @@ -1,45 +0,0 @@ -/** - * @file referee_communication.h - * @author kidneygood (you@domain.com) - * @version 0.1 - * @date 2022-12-02 - * - * @copyright Copyright (c) HNU YueLu EC 2022 all rights reserved - * - */ - -#include "referee_communication.h" -#include "crc_ref.h" -#include "stdio.h" -#include "rm_referee.h" - -/** - * @brief 发送机器人间的交互数据 - * @param referee_id_t *_id sender为本机器人,receiver为接收方机器人,发送前设置Receiver_Robot_ID再调用该函数 - * robot_interactive_data_t *data 数据段 - * @retval none - * @attention - */ -void Communicate_SendData(referee_id_t *_id,robot_interactive_data_t *_data) -{ - Communicate_SendData_t SendData; - uint8_t temp_datalength = Interactive_Data_LEN_Head + Communicate_Data_LEN; // 计算交互数据长度 6+n,n为交互数据长度 - - SendData.FrameHeader.SOF = REFEREE_SOF; - SendData.FrameHeader.DataLength = temp_datalength; - SendData.FrameHeader.Seq = UI_Seq; - SendData.FrameHeader.CRC8 = Get_CRC8_Check_Sum((uint8_t *)&SendData, LEN_CRC8, 0xFF); - - SendData.CmdID = ID_student_interactive; - - SendData.datahead.data_cmd_id = Communicate_Data_ID; - SendData.datahead.sender_ID = _id->Robot_ID; - SendData.datahead.receiver_ID = _id->Receiver_Robot_ID; - - SendData.Data = *_data; - - SendData.frametail = Get_CRC16_Check_Sum((uint8_t *)&SendData,LEN_HEADER+LEN_CMDID+temp_datalength,0xFFFF); - - RefereeSend((uint8_t *)&SendData,LEN_HEADER+LEN_CMDID+temp_datalength+LEN_TAIL); //发送 - UI_Seq++; // 包序号+1 -} diff --git a/modules/referee/referee_communication.h b/modules/referee/referee_communication.h deleted file mode 100644 index cba2324..0000000 --- a/modules/referee/referee_communication.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef REFEREE_COMMUNICATION_H -#define REFEREE_COMMUNICATION_H - -#include "stdint.h" -#include "referee_def.h" -#include "rm_referee.h" - -void Communicate_SendData(referee_id_t *_id,robot_interactive_data_t *_data); - -#endif \ No newline at end of file diff --git a/modules/referee/referee_def.h b/modules/referee/referee_protocol.h similarity index 86% rename from modules/referee/referee_def.h rename to modules/referee/referee_protocol.h index 4c2312f..22416b3 100644 --- a/modules/referee/referee_def.h +++ b/modules/referee/referee_protocol.h @@ -1,5 +1,5 @@ /** - * @file referee_def.h + * @file referee_protocol.h * @author kidneygood (you@domain.com) * @version 0.1 * @date 2022-12-02 @@ -8,22 +8,20 @@ * */ -#ifndef REFEREE_DEF_H -#define REFEREE_DEF_H +#ifndef referee_protocol_H +#define referee_protocol_H #include "stdint.h" -/****************************宏定义部分****************************/ /****************************宏定义部分****************************/ #define REFEREE_SOF 0xA5 // 起始字节,协议固定为0xA5 #define Robot_Red 0 #define Robot_Blue 1 -#define Communicate_Data_LEN 5 //自定义交互数据长度,该长度决定了我方发送和他方接收,自定义交互数据协议更改时只需要更改此宏定义即可 +#define Communicate_Data_LEN 5 // 自定义交互数据长度,该长度决定了我方发送和他方接收,自定义交互数据协议更改时只需要更改此宏定义即可 -#pragma pack(1) +#pragma pack(1) -/****************************通信协议格式****************************/ /****************************通信协议格式****************************/ /* 通信协议格式偏移,枚举类型,代替#define声明 */ @@ -90,19 +88,19 @@ typedef enum /* 命令码数据段长,根据官方协议来定义长度,还有自定义数据长度 */ typedef enum { - LEN_game_state = 3, // 0x0001 - LEN_game_result = 1, // 0x0002 - LEN_game_robot_HP = 2, // 0x0003 - LEN_event_data = 4, // 0x0101 - LEN_supply_projectile_action = 4, // 0x0102 - LEN_game_robot_state = 27, // 0x0201 - LEN_power_heat_data = 14, // 0x0202 - LEN_game_robot_pos = 16, // 0x0203 - LEN_buff_musk = 1, // 0x0204 - LEN_aerial_robot_energy = 1, // 0x0205 - LEN_robot_hurt = 1, // 0x0206 - LEN_shoot_data = 7, // 0x0207 - LEN_receive_data = 6+Communicate_Data_LEN, //0x0301 + LEN_game_state = 3, // 0x0001 + LEN_game_result = 1, // 0x0002 + LEN_game_robot_HP = 2, // 0x0003 + LEN_event_data = 4, // 0x0101 + LEN_supply_projectile_action = 4, // 0x0102 + LEN_game_robot_state = 27, // 0x0201 + LEN_power_heat_data = 14, // 0x0202 + LEN_game_robot_pos = 16, // 0x0203 + LEN_buff_musk = 1, // 0x0204 + LEN_aerial_robot_energy = 1, // 0x0205 + LEN_robot_hurt = 1, // 0x0206 + LEN_shoot_data = 7, // 0x0207 + LEN_receive_data = 6 + Communicate_Data_LEN, // 0x0301 } JudgeDataLength_e; @@ -235,7 +233,7 @@ typedef struct /* 交互数据头结构 */ typedef struct { - uint16_t data_cmd_id; //由于存在多个内容 ID,但整个cmd_id 上行频率最大为 10Hz,请合理安排带宽。注意交互部分的上行频率 + uint16_t data_cmd_id; // 由于存在多个内容 ID,但整个cmd_id 上行频率最大为 10Hz,请合理安排带宽。注意交互部分的上行频率 uint16_t sender_ID; uint16_t receiver_ID; } ext_student_interactive_header_data_t; @@ -244,7 +242,7 @@ typedef struct typedef enum { // 红方机器人ID - RobotID_RHero = 1, + RobotID_RHero = 1, RobotID_REngineer = 2, RobotID_RStandard1 = 3, RobotID_RStandard2 = 4, @@ -290,14 +288,13 @@ typedef enum } Interactive_Data_Length_e; -/****************************自定义交互数据****************************/ /****************************自定义交互数据****************************/ /* 学生机器人间通信 cmd_id 0x0301,内容 ID:0x0200~0x02FF 自定义交互数据 机器人间通信:0x0301。 发送频率:上限 10Hz */ -//自定义交互数据协议,可更改,更改后需要修改最上方宏定义数据长度的值 +// 自定义交互数据协议,可更改,更改后需要修改最上方宏定义数据长度的值 typedef struct { uint8_t data[Communicate_Data_LEN]; // 数据段,n需要小于113 @@ -319,8 +316,6 @@ typedef struct robot_interactive_data_t Data; // 数据段 } Communicate_ReceiveData_t; - -/****************************UI交互数据****************************/ /****************************UI交互数据****************************/ /* 图形数据 */ @@ -339,7 +334,7 @@ typedef struct uint32_t radius : 10; uint32_t end_x : 11; uint32_t end_y : 11; -} Graph_Data_t; +} Graph_Data_t; typedef struct { diff --git a/modules/referee/referee_task.c b/modules/referee/referee_task.c new file mode 100644 index 0000000..53a104f --- /dev/null +++ b/modules/referee/referee_task.c @@ -0,0 +1,292 @@ +/** + * @file referee.C + * @author kidneygood (you@domain.com) + * @brief + * @version 0.1 + * @date 2022-11-18 + * + * @copyright Copyright (c) 2022 + * + */ +#include "referee_task.h" +#include "robot_def.h" +#include "rm_referee.h" +#include "referee_UI.h" +#include "string.h" +static Referee_Interactive_info_t *Interactive_data; // UI绘制需要的机器人状态数据 +static referee_info_t *referee_recv_info; // 接收到的裁判系统数据 + +/** + * @brief 判断各种ID,选择客户端ID + * @param referee_info_t *referee_recv_info + * @retval none + * @attention + */ +static void DeterminRobotID() +{ + // id小于7是红色,大于7是蓝色,0为红色,1为蓝色 #define Robot_Red 0 #define Robot_Blue 1 + referee_recv_info->referee_id.Robot_Color = referee_recv_info->GameRobotState.robot_id > 7 ? Robot_Blue : Robot_Red; + referee_recv_info->referee_id.Robot_ID = referee_recv_info->GameRobotState.robot_id; + referee_recv_info->referee_id.Cilent_ID = 0x0100 + referee_recv_info->referee_id.Robot_ID; // 计算客户端ID + referee_recv_info->referee_id.Receiver_Robot_ID = 0; +} + +static void My_UI_Refresh(referee_info_t *referee_recv_info, Referee_Interactive_info_t *_Interactive_data); +static void Mode_Change_Check(Referee_Interactive_info_t *_Interactive_data); // 模式切换检测 + +// syhtod 正式上车后需删除 +static void robot_mode_change(Referee_Interactive_info_t *_Interactive_data); // 测试用函数,实现模式自动变化 + +referee_info_t *Referee_Interactive_init(UART_HandleTypeDef *referee_usart_handle, Referee_Interactive_info_t *UI_data) +{ + referee_recv_info = RefereeInit(referee_usart_handle); // 初始化裁判系统的串口,并返回裁判系统反馈数据指针 + Interactive_data = UI_data; // 获取UI绘制需要的机器人状态数据 + return referee_recv_info; +} + +void Referee_Interactive_task() +{ + robot_mode_change(Interactive_data); // 测试用函数,实现模式自动变化 + My_UI_Refresh(referee_recv_info, Interactive_data); +} + +static Graph_Data_t UI_shoot_line[10]; // 射击准线 +static Graph_Data_t UI_Energy[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}; + +void My_UI_init() +{ + while (referee_recv_info->GameRobotState.robot_id == 0) + ; + DeterminRobotID(); + UIDelete(&referee_recv_info->referee_id, UI_Data_Del_ALL, 0); // 清空UI + + // 绘制发射基准线 + Line_Draw(&UI_shoot_line[0], "sl0", UI_Graph_ADD, 7, UI_Color_White, 3, 710, shoot_line_location[0], 1210, shoot_line_location[0]); + Line_Draw(&UI_shoot_line[1], "sl1", UI_Graph_ADD, 7, UI_Color_White, 3, shoot_line_location[1], 340, shoot_line_location[1], 740); + Line_Draw(&UI_shoot_line[2], "sl2", UI_Graph_ADD, 7, UI_Color_Yellow, 2, 810, shoot_line_location[2], 1110, shoot_line_location[2]); + Line_Draw(&UI_shoot_line[3], "sl3", UI_Graph_ADD, 7, UI_Color_Yellow, 2, 810, shoot_line_location[3], 1110, shoot_line_location[3]); + Line_Draw(&UI_shoot_line[4], "sl4", UI_Graph_ADD, 7, UI_Color_Yellow, 2, 810, shoot_line_location[4], 1110, shoot_line_location[4]); + UI_ReFresh(&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]); + + // 绘制车辆状态标志指示 + Char_Draw(&UI_State_sta[0], "ss0", UI_Graph_ADD, 8, UI_Color_Main, 15, 2, 150, 750, "chassis:"); + Char_ReFresh(&referee_recv_info->referee_id, UI_State_sta[0]); + Char_Draw(&UI_State_sta[1], "ss1", UI_Graph_ADD, 8, UI_Color_Yellow, 15, 2, 150, 700, "gimbal:"); + Char_ReFresh(&referee_recv_info->referee_id, UI_State_sta[1]); + Char_Draw(&UI_State_sta[2], "ss2", UI_Graph_ADD, 8, UI_Color_Orange, 15, 2, 150, 650, "shoot:"); + Char_ReFresh(&referee_recv_info->referee_id, UI_State_sta[2]); + Char_Draw(&UI_State_sta[3], "ss3", UI_Graph_ADD, 8, UI_Color_Pink, 15, 2, 150, 600, "frict:"); + Char_ReFresh(&referee_recv_info->referee_id, UI_State_sta[3]); + Char_Draw(&UI_State_sta[4], "ss4", UI_Graph_ADD, 8, UI_Color_Pink, 15, 2, 150, 550, "lid:"); + Char_ReFresh(&referee_recv_info->referee_id, UI_State_sta[4]); + + // 绘制车辆状态标志,动态 + // 由于初始化时xxx_last_mode默认为0,所以此处对应UI也应该设为0时对应的UI,防止模式不变的情况下无法置位flag,导致UI无法刷新 + Char_Draw(&UI_State_dyn[0], "sd0", UI_Graph_ADD, 8, UI_Color_Main, 15, 2, 270, 750, "zeroforce"); + Char_ReFresh(&referee_recv_info->referee_id, UI_State_dyn[0]); + Char_Draw(&UI_State_dyn[1], "sd1", UI_Graph_ADD, 8, UI_Color_Yellow, 15, 2, 270, 700, "zeroforce"); + Char_ReFresh(&referee_recv_info->referee_id, UI_State_dyn[1]); + Char_Draw(&UI_State_dyn[2], "sd2", UI_Graph_ADD, 8, UI_Color_Orange, 15, 2, 270, 650, "off"); + Char_ReFresh(&referee_recv_info->referee_id, UI_State_dyn[2]); + Char_Draw(&UI_State_dyn[3], "sd3", UI_Graph_ADD, 8, UI_Color_Pink, 15, 2, 270, 600, "off"); + Char_ReFresh(&referee_recv_info->referee_id, UI_State_dyn[3]); + Char_Draw(&UI_State_dyn[4], "sd4", UI_Graph_ADD, 8, UI_Color_Pink, 15, 2, 270, 550, "open "); + Char_ReFresh(&referee_recv_info->referee_id, UI_State_dyn[4]); + + // 底盘功率显示,静态 + Char_Draw(&UI_State_sta[5], "ss5", UI_Graph_ADD, 7, UI_Color_Green, 18, 2, 620, 230, "Power:"); + Char_ReFresh(&referee_recv_info->referee_id, UI_State_sta[5]); + // 能量条框 + Rectangle_Draw(&UI_Energy[0], "ss6", UI_Graph_ADD, 7, UI_Color_Green, 2, 720, 140, 1220, 180); + UI_ReFresh(&referee_recv_info->referee_id, 1, UI_Energy[0]); + + // 底盘功率显示,动态 + Float_Draw(&UI_Energy[1], "sd5", UI_Graph_ADD, 8, UI_Color_Green, 18, 2, 2, 750, 230, 24000); + // 能量条初始状态 + Line_Draw(&UI_Energy[2], "sd6", UI_Graph_ADD, 8, UI_Color_Pink, 30, 720, 160, 1020, 160); + UI_ReFresh(&referee_recv_info->referee_id, 2, UI_Energy[1], UI_Energy[2]); +} + +static uint8_t count = 0; +static uint16_t count1 = 0; +static void robot_mode_change(Referee_Interactive_info_t *_Interactive_data) // 测试用函数,实现模式自动变化 +{ + count++; + if (count >= 50) + { + count = 0; + count1++; + } + switch (count1 % 4) + { + case 0: + { + _Interactive_data->chassis_mode = CHASSIS_ZERO_FORCE; + _Interactive_data->gimbal_mode = GIMBAL_ZERO_FORCE; + _Interactive_data->shoot_mode = SHOOT_ON; + _Interactive_data->friction_mode = FRICTION_ON; + _Interactive_data->lid_mode = LID_OPEN; + _Interactive_data->Chassis_Power_Data.chassis_power_mx += 3.5; + if (_Interactive_data->Chassis_Power_Data.chassis_power_mx >= 18) + _Interactive_data->Chassis_Power_Data.chassis_power_mx = 0; + break; + } + case 1: + { + _Interactive_data->chassis_mode = CHASSIS_ROTATE; + _Interactive_data->gimbal_mode = GIMBAL_FREE_MODE; + _Interactive_data->shoot_mode = SHOOT_OFF; + _Interactive_data->friction_mode = FRICTION_OFF; + _Interactive_data->lid_mode = LID_CLOSE; + break; + } + case 2: + { + _Interactive_data->chassis_mode = CHASSIS_NO_FOLLOW; + _Interactive_data->gimbal_mode = GIMBAL_GYRO_MODE; + _Interactive_data->shoot_mode = SHOOT_ON; + _Interactive_data->friction_mode = FRICTION_ON; + _Interactive_data->lid_mode = LID_OPEN; + break; + } + case 3: + { + _Interactive_data->chassis_mode = CHASSIS_FOLLOW_GIMBAL_YAW; + _Interactive_data->gimbal_mode = GIMBAL_ZERO_FORCE; + _Interactive_data->shoot_mode = SHOOT_OFF; + _Interactive_data->friction_mode = FRICTION_OFF; + _Interactive_data->lid_mode = LID_CLOSE; + break; + } + default: + break; + } +} + +static void My_UI_Refresh(referee_info_t *referee_recv_info, Referee_Interactive_info_t *_Interactive_data) +{ + Mode_Change_Check(_Interactive_data); + // chassis + if (_Interactive_data->Referee_Interactive_Flag.chassis_flag == 1) + { + switch (_Interactive_data->chassis_mode) + { + case CHASSIS_ZERO_FORCE: + Char_Draw(&UI_State_dyn[0], "sd0", UI_Graph_Change, 8, UI_Color_Main, 15, 2, 270, 750, "zeroforce"); + break; + case CHASSIS_ROTATE: + Char_Draw(&UI_State_dyn[0], "sd0", UI_Graph_Change, 8, UI_Color_Main, 15, 2, 270, 750, "rotate "); + // 此处注意字数对齐问题,字数相同才能覆盖掉 + break; + case CHASSIS_NO_FOLLOW: + Char_Draw(&UI_State_dyn[0], "sd0", UI_Graph_Change, 8, UI_Color_Main, 15, 2, 270, 750, "nofollow "); + break; + case CHASSIS_FOLLOW_GIMBAL_YAW: + Char_Draw(&UI_State_dyn[0], "sd0", UI_Graph_Change, 8, UI_Color_Main, 15, 2, 270, 750, "follow "); + break; + } + Char_ReFresh(&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: + { + Char_Draw(&UI_State_dyn[1], "sd1", UI_Graph_Change, 8, UI_Color_Yellow, 15, 2, 270, 700, "zeroforce"); + break; + } + case GIMBAL_FREE_MODE: + { + Char_Draw(&UI_State_dyn[1], "sd1", UI_Graph_Change, 8, UI_Color_Yellow, 15, 2, 270, 700, "free "); + break; + } + case GIMBAL_GYRO_MODE: + { + Char_Draw(&UI_State_dyn[1], "sd1", UI_Graph_Change, 8, UI_Color_Yellow, 15, 2, 270, 700, "gyro "); + break; + } + } + Char_ReFresh(&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) + { + Char_Draw(&UI_State_dyn[2], "sd2", UI_Graph_Change, 8, UI_Color_Pink, 15, 2, 270, 650, _Interactive_data->shoot_mode == SHOOT_ON ? "on " : "off"); + Char_ReFresh(&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) + { + Char_Draw(&UI_State_dyn[3], "sd3", UI_Graph_Change, 8, UI_Color_Pink, 15, 2, 270, 600, _Interactive_data->friction_mode == FRICTION_ON ? "on " : "off"); + Char_ReFresh(&referee_recv_info->referee_id, UI_State_dyn[3]); + _Interactive_data->Referee_Interactive_Flag.friction_flag = 0; + } + // lid + if (_Interactive_data->Referee_Interactive_Flag.lid_flag == 1) + { + Char_Draw(&UI_State_dyn[4], "sd4", UI_Graph_Change, 8, UI_Color_Pink, 15, 2, 270, 550, _Interactive_data->lid_mode == LID_OPEN ? "open " : "close"); + Char_ReFresh(&referee_recv_info->referee_id, UI_State_dyn[4]); + _Interactive_data->Referee_Interactive_Flag.lid_flag = 0; + } + // power + if (_Interactive_data->Referee_Interactive_Flag.Power_flag == 1) + { + Float_Draw(&UI_Energy[1], "sd5", UI_Graph_Change, 8, UI_Color_Green, 18, 2, 2, 750, 230, _Interactive_data->Chassis_Power_Data.chassis_power_mx * 1000); + Line_Draw(&UI_Energy[2], "sd6", UI_Graph_Change, 8, UI_Color_Pink, 30, 720, 160, (uint32_t)750 + _Interactive_data->Chassis_Power_Data.chassis_power_mx * 30, 160); + UI_ReFresh(&referee_recv_info->referee_id, 2, UI_Energy[1], UI_Energy[2]); + _Interactive_data->Referee_Interactive_Flag.Power_flag = 0; + } +} + +/** + * @brief 模式切换检测,模式发生切换时,对flag置位 + * @param Referee_Interactive_info_t *_Interactive_data + * @retval none + * @attention + */ +static void Mode_Change_Check(Referee_Interactive_info_t *_Interactive_data) +{ + if (_Interactive_data->chassis_mode != _Interactive_data->chassis_last_mode) + { + _Interactive_data->Referee_Interactive_Flag.chassis_flag = 1; + _Interactive_data->chassis_last_mode = _Interactive_data->chassis_mode; + } + + if (_Interactive_data->gimbal_mode != _Interactive_data->gimbal_last_mode) + { + _Interactive_data->Referee_Interactive_Flag.gimbal_flag = 1; + _Interactive_data->gimbal_last_mode = _Interactive_data->gimbal_mode; + } + + if (_Interactive_data->shoot_mode != _Interactive_data->shoot_last_mode) + { + _Interactive_data->Referee_Interactive_Flag.shoot_flag = 1; + _Interactive_data->shoot_last_mode = _Interactive_data->shoot_mode; + } + + if (_Interactive_data->friction_mode != _Interactive_data->friction_last_mode) + { + _Interactive_data->Referee_Interactive_Flag.friction_flag = 1; + _Interactive_data->friction_last_mode = _Interactive_data->friction_mode; + } + + if (_Interactive_data->lid_mode != _Interactive_data->lid_last_mode) + { + _Interactive_data->Referee_Interactive_Flag.lid_flag= 1; + _Interactive_data->lid_last_mode = _Interactive_data->lid_mode; + } + + if (_Interactive_data->Chassis_Power_Data.chassis_power_mx != _Interactive_data->Chassis_last_Power_Data.chassis_power_mx) + { + _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; + } +} diff --git a/modules/referee/referee_task.h b/modules/referee/referee_task.h new file mode 100644 index 0000000..c6c8ff2 --- /dev/null +++ b/modules/referee/referee_task.h @@ -0,0 +1,25 @@ +#ifndef REFEREE_H +#define REFEREE_H + +#include "rm_referee.h" +#include "robot_def.h" + +/** + * @brief 初始化裁判系统交互任务(UI和多机通信) + * + */ +referee_info_t *Referee_Interactive_init(UART_HandleTypeDef *referee_usart_handle, Referee_Interactive_info_t *UI_data); + +/** + * @brief 在referee task之前调用,添加在freertos.c中 + * + */ +void My_UI_init(); + +/** + * @brief 裁判系统交互任务(UI和多机通信) + * + */ +void Referee_Interactive_task(); + +#endif // REFEREE_H diff --git a/modules/referee/rm_referee.c b/modules/referee/rm_referee.c index 7d5e329..41b9484 100644 --- a/modules/referee/rm_referee.c +++ b/modules/referee/rm_referee.c @@ -13,14 +13,15 @@ #include "string.h" #include "crc_ref.h" #include "bsp_usart.h" +#include "task.h" #define RE_RX_BUFFER_SIZE 200 -static USARTInstance *referee_usart_instance; // 暂时改为非静态变量 +static USARTInstance *referee_usart_instance; // 裁判系统串口实例 +static referee_info_t referee_info; // 裁判系统数据 -static referee_info_t referee_info; -static void JudgeReadData(uint8_t *ReadFromUsart); static void RefereeRxCallback(); +static void JudgeReadData(uint8_t *buff); uint8_t UI_Seq = 0; // 包序号,供整个referee文件使用 @@ -35,15 +36,17 @@ referee_info_t *RefereeInit(UART_HandleTypeDef *referee_usart_handle) return &referee_info; } + + /** - * @brief 发送函数 - * @param send 待发送数据 + * @brief 裁判系统数据发送函数,由于使用 + * @param */ void RefereeSend(uint8_t *send, uint16_t tx_len) { - USARTSend(referee_usart_instance, send, tx_len,USART_TRANSFER_IT); - /* syhtodo DMA请求过快会导致数据发送丢失,考虑数据尽可能打成一个整包以及队列发送,并且发送函数添加缓冲区 */ - HAL_Delay(5); + static TickType_t xLastWakeTime; + USARTSend(referee_usart_instance, send, tx_len, USART_TRANSFER_DMA); + vTaskDelayUntil(&xLastWakeTime, 120); } /*裁判系统串口接收回调函数,解析数据 */ @@ -54,83 +57,82 @@ static void RefereeRxCallback() /** * @brief 读取裁判数据,中断中读取保证速度 - * @param ReadFromUsart: 读取到的裁判系统原始数据 + * @param buff: 读取到的裁判系统原始数据 * @retval 是否对正误判断做处理 * @attention 在此判断帧头和CRC校验,无误再写入数据,不重复判断帧头 */ -static void JudgeReadData(uint8_t *ReadFromUsart) +static void JudgeReadData(uint8_t *buff) { - uint16_t judge_length; // 统计一帧数据长度 - if (ReadFromUsart == NULL) // 空数据包,则不作任何处理 + uint16_t judge_length; // 统计一帧数据长度 + if (buff == NULL) // 空数据包,则不作任何处理 return; // 写入帧头数据(5-byte),用于判断是否开始存储裁判数据 - memcpy(&referee_info.FrameHeader, ReadFromUsart, LEN_HEADER); + memcpy(&referee_info.FrameHeader, buff, LEN_HEADER); // 判断帧头数据(0)是否为0xA5 - if (ReadFromUsart[SOF] == REFEREE_SOF) + if (buff[SOF] == REFEREE_SOF) { // 帧头CRC8校验 - if (Verify_CRC8_Check_Sum(ReadFromUsart, LEN_HEADER) == TRUE) + if (Verify_CRC8_Check_Sum(buff, LEN_HEADER) == TRUE) { // 统计一帧数据长度(byte),用于CR16校验 - judge_length = ReadFromUsart[DATA_LENGTH] + LEN_HEADER + LEN_CMDID + LEN_TAIL; + judge_length = buff[DATA_LENGTH] + LEN_HEADER + LEN_CMDID + LEN_TAIL; // 帧尾CRC16校验 - if (Verify_CRC16_Check_Sum(ReadFromUsart, judge_length) == TRUE) + if (Verify_CRC16_Check_Sum(buff, judge_length) == TRUE) { // 2个8位拼成16位int - referee_info.CmdID = (ReadFromUsart[6] << 8 | ReadFromUsart[5]); + referee_info.CmdID = (buff[6] << 8 | buff[5]); // 解析数据命令码,将数据拷贝到相应结构体中(注意拷贝数据的长度) // 第8个字节开始才是数据 data=7 switch (referee_info.CmdID) { case ID_game_state: // 0x0001 - memcpy(&referee_info.GameState, (ReadFromUsart + DATA_Offset), LEN_game_state); + memcpy(&referee_info.GameState, (buff + DATA_Offset), LEN_game_state); break; case ID_game_result: // 0x0002 - memcpy(&referee_info.GameResult, (ReadFromUsart + DATA_Offset), LEN_game_result); + memcpy(&referee_info.GameResult, (buff + DATA_Offset), LEN_game_result); break; case ID_game_robot_survivors: // 0x0003 - memcpy(&referee_info.GameRobotHP, (ReadFromUsart + DATA_Offset), LEN_game_robot_HP); + memcpy(&referee_info.GameRobotHP, (buff + DATA_Offset), LEN_game_robot_HP); break; case ID_event_data: // 0x0101 - memcpy(&referee_info.EventData, (ReadFromUsart + DATA_Offset), LEN_event_data); + memcpy(&referee_info.EventData, (buff + DATA_Offset), LEN_event_data); break; case ID_supply_projectile_action: // 0x0102 - memcpy(&referee_info.SupplyProjectileAction, (ReadFromUsart + DATA_Offset), LEN_supply_projectile_action); + memcpy(&referee_info.SupplyProjectileAction, (buff + DATA_Offset), LEN_supply_projectile_action); break; case ID_game_robot_state: // 0x0201 - memcpy(&referee_info.GameRobotState, (ReadFromUsart + DATA_Offset), LEN_game_robot_state); + memcpy(&referee_info.GameRobotState, (buff + DATA_Offset), LEN_game_robot_state); break; case ID_power_heat_data: // 0x0202 - memcpy(&referee_info.PowerHeatData, (ReadFromUsart + DATA_Offset), LEN_power_heat_data); + memcpy(&referee_info.PowerHeatData, (buff + DATA_Offset), LEN_power_heat_data); break; case ID_game_robot_pos: // 0x0203 - memcpy(&referee_info.GameRobotPos, (ReadFromUsart + DATA_Offset), LEN_game_robot_pos); + memcpy(&referee_info.GameRobotPos, (buff + DATA_Offset), LEN_game_robot_pos); break; case ID_buff_musk: // 0x0204 - memcpy(&referee_info.BuffMusk, (ReadFromUsart + DATA_Offset), LEN_buff_musk); + memcpy(&referee_info.BuffMusk, (buff + DATA_Offset), LEN_buff_musk); break; case ID_aerial_robot_energy: // 0x0205 - memcpy(&referee_info.AerialRobotEnergy, (ReadFromUsart + DATA_Offset), LEN_aerial_robot_energy); + memcpy(&referee_info.AerialRobotEnergy, (buff + DATA_Offset), LEN_aerial_robot_energy); break; case ID_robot_hurt: // 0x0206 - memcpy(&referee_info.RobotHurt, (ReadFromUsart + DATA_Offset), LEN_robot_hurt); + memcpy(&referee_info.RobotHurt, (buff + DATA_Offset), LEN_robot_hurt); break; case ID_shoot_data: // 0x0207 - memcpy(&referee_info.ShootData, (ReadFromUsart + DATA_Offset), LEN_shoot_data); + memcpy(&referee_info.ShootData, (buff + DATA_Offset), LEN_shoot_data); break; case ID_student_interactive: // 0x0301 syhtodo接收代码未测试 - memcpy(&referee_info.ReceiveData, (ReadFromUsart + DATA_Offset), LEN_receive_data); + memcpy(&referee_info.ReceiveData, (buff + DATA_Offset), LEN_receive_data); break; } } } // 首地址加帧长度,指向CRC16下一字节,用来判断是否为0xA5,从而判断一个数据包是否有多帧数据 - if (*(ReadFromUsart + sizeof(xFrameHeader) + LEN_CMDID + referee_info.FrameHeader.DataLength + LEN_TAIL) == 0xA5) - { - // 如果一个数据包出现了多帧数据,则再次调用解析函数,直到所有数据包解析完毕 - JudgeReadData(ReadFromUsart + sizeof(xFrameHeader) + LEN_CMDID + referee_info.FrameHeader.DataLength + LEN_TAIL); + if (*(buff + sizeof(xFrameHeader) + LEN_CMDID + referee_info.FrameHeader.DataLength + LEN_TAIL) == 0xA5) + { // 如果一个数据包出现了多帧数据,则再次调用解析函数,直到所有数据包解析完毕 + JudgeReadData(buff + sizeof(xFrameHeader) + LEN_CMDID + referee_info.FrameHeader.DataLength + LEN_TAIL); } } } diff --git a/modules/referee/rm_referee.h b/modules/referee/rm_referee.h index 16fb381..1cf83b2 100644 --- a/modules/referee/rm_referee.h +++ b/modules/referee/rm_referee.h @@ -2,22 +2,25 @@ #define RM_REFEREE_H #include "usart.h" -#include "referee_def.h" +#include "referee_protocol.h" +#include "robot_def.h" #include "bsp_usart.h" -extern uint8_t UI_Seq; +#include "FreeRTOS.h" + +extern uint8_t UI_Seq; #pragma pack(1) typedef struct { - uint8_t Robot_Color; //机器人颜色 - uint16_t Robot_ID; //本机器人ID - uint16_t Cilent_ID; //本机器人对应的客户端ID - uint16_t Receiver_Robot_ID; //机器人车间通信时接收者的ID,必须和本机器人同颜色 + uint8_t Robot_Color; // 机器人颜色 + uint16_t Robot_ID; // 本机器人ID + uint16_t Cilent_ID; // 本机器人对应的客户端ID + uint16_t Receiver_Robot_ID; // 机器人车间通信时接收者的ID,必须和本机器人同颜色 } referee_id_t; // 此结构体包含裁判系统接收数据以及UI绘制与机器人车间通信的相关信息 typedef struct -{ +{ referee_id_t referee_id; xFrameHeader FrameHeader; // 接收到的帧头信息 @@ -35,25 +38,60 @@ typedef struct ext_robot_hurt_t RobotHurt; // 0x0206 ext_shoot_data_t ShootData; // 0x0207 - //自定义交互数据的接收 + // 自定义交互数据的接收 Communicate_ReceiveData_t ReceiveData; } referee_info_t; +// 模式是否切换标志位,0为未切换,1为切换,static定义默认为0 +typedef struct +{ + uint32_t chassis_flag : 1; + uint32_t gimbal_flag : 1; + uint32_t shoot_flag : 1; + uint32_t lid_flag : 1; + uint32_t friction_flag : 1; + uint32_t Power_flag : 1; +} Referee_Interactive_Flag_t; + +// 此结构体包含UI绘制与机器人车间通信的需要的其他非裁判系统数据 +typedef struct +{ + Referee_Interactive_Flag_t Referee_Interactive_Flag; + // 为UI绘制以及交互数据所用 + chassis_mode_e chassis_mode; // 底盘模式 + gimbal_mode_e gimbal_mode; // 云台模式 + shoot_mode_e shoot_mode; // 发射模式设置 + friction_mode_e friction_mode; // 摩擦轮关闭 + lid_mode_e lid_mode; // 弹舱盖打开 + Chassis_Power_Data_s Chassis_Power_Data; // 功率控制 + + // 上一次的模式,用于flag判断 + chassis_mode_e chassis_last_mode; + gimbal_mode_e gimbal_last_mode; + shoot_mode_e shoot_last_mode; + friction_mode_e friction_last_mode; + lid_mode_e lid_last_mode; + Chassis_Power_Data_s Chassis_last_Power_Data; + +} Referee_Interactive_info_t; + #pragma pack() /** - * @brief 初始化裁判系统,返回接收数据指针 + * @brief 裁判系统通信初始化,该函数会初始化裁判系统串口,开启中断 * - * @param referee_usart_handle - * @return referee_info_t* + * @param referee_usart_handle 串口handle,C板一般用串口6 + * @return referee_info_t* 返回裁判系统反馈的数据,包括热量/血量/状态等 */ referee_info_t *RefereeInit(UART_HandleTypeDef *referee_usart_handle); /** - * @brief 发送函数 - * @todo - * @param send 待发送数据 + * @brief UI绘制和交互数的发送接口,由UI绘制任务和多机通信函数调用 + * @note 内部包含了一个实时系统的延时函数,这是因为裁判系统接收CMD数据至高位10Hz + * + * @param send 发送数据首地址 + * @param tx_len 发送长度 */ void RefereeSend(uint8_t *send, uint16_t tx_len);