diff --git a/HAL_N_Middlewares/Src/freertos.c b/HAL_N_Middlewares/Src/freertos.c index 99e9a51..79c44b7 100644 --- a/HAL_N_Middlewares/Src/freertos.c +++ b/HAL_N_Middlewares/Src/freertos.c @@ -197,7 +197,7 @@ void StartROBOTTASK(void const * argument) { // 200Hz RobotTask(); - osDelay(5); + osDelay(10);//syh此处暂时将时间改为10ms,原因在于未使用缓冲区发送,发送时延时5ms } } diff --git a/Makefile b/Makefile index dc73895..7f97471 100644 --- a/Makefile +++ b/Makefile @@ -132,7 +132,7 @@ modules/motor/servo_motor/servo_motor.c \ modules/motor/motor_task.c \ modules/oled/oled.c \ modules/referee/crc_ref.c \ -modules/referee/referee.c \ +modules/referee/rm_referee.c \ modules/referee/referee_UI.c \ modules/referee/referee_communication.c \ modules/remote/remote_control.c \ @@ -144,6 +144,7 @@ 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 @@ -227,6 +228,7 @@ C_INCLUDES = \ -Iapplication/gimbal \ -Iapplication/cmd \ -Iapplication/balance_chassis \ +-Iapplication/referee \ -Iapplication \ -Ibsp/dwt \ -Ibsp/can \ diff --git a/application/chassis/chassis.c b/application/chassis/chassis.c index 62d2810..30a23d8 100644 --- a/application/chassis/chassis.c +++ b/application/chassis/chassis.c @@ -16,10 +16,15 @@ #include "dji_motor.h" #include "super_cap.h" #include "message_center.h" + +///////////////////////// #include "referee.h" +#include "rm_referee.h" +///////////////////////// + #include "general_def.h" #include "bsp_dwt.h" - +#include "referee_UI.h" #include "arm_math.h" /* 根据robot_def.h中的macro自动计算的参数 */ @@ -41,7 +46,7 @@ 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_info_t *referee_data; // 裁判系统相关数据 static SuperCapInstance *cap; // 超级电容 static DJIMotorInstance *motor_lf; // left right forward back static DJIMotorInstance *motor_rf; @@ -99,7 +104,11 @@ void ChassisInit() chassis_motor_config.controller_setting_init_config.reverse_flag = MOTOR_DIRECTION_NORMAL; motor_rb = DJIMotorInit(&chassis_motor_config); - referee_data = RefereeInit(&huart6); // 裁判系统初始化 + // referee_data = RefereeInit(&huart6); // 裁判系统初始化 + + // while (referee_data->GameRobotState.robot_id ==0); + // Referee_Interactive_init(referee_data); + SuperCap_Init_Config_s cap_conf = { .can_config = { @@ -236,12 +245,12 @@ void ChassisTask() // 根据电机的反馈速度和IMU(如果有)计算真实速度 EstimateSpeed(); - // 获取裁判系统数据 - // 我方颜色id小于7是红色,大于7是蓝色,注意这里发送的是对方的颜色, 0:blue , 1:red - chassis_feedback_data.enemy_color = referee_data->GameRobotStat.robot_id > 7 ? 1 : 0; - // 当前只做了17mm热量的数据获取,后续根据robot_def中的宏切换双枪管和英雄42mm的情况 - chassis_feedback_data.bullet_speed = referee_data->GameRobotStat.shooter_id1_17mm_speed_limit; - chassis_feedback_data.rest_heat = referee_data->PowerHeatData.shooter_heat0; + // // 获取裁判系统数据 建议将裁判系统与底盘分离,所以此处数据应使用消息中心发送 + // // 我方颜色id小于7是红色,大于7是蓝色,注意这里发送的是对方的颜色, 0:blue , 1:red + // chassis_feedback_data.enemy_color = referee_data->GameRobotState.robot_id > 7 ? 1 : 0; + // // 当前只做了17mm热量的数据获取,后续根据robot_def中的宏切换双枪管和英雄42mm的情况 + // chassis_feedback_data.bullet_speed = referee_data->GameRobotState.shooter_id1_17mm_speed_limit; + // chassis_feedback_data.rest_heat = referee_data->PowerHeatData.shooter_heat0; // 推送反馈消息 #ifdef ONE_BOARD diff --git a/application/referee/referee.c b/application/referee/referee.c new file mode 100644 index 0000000..57ab4c6 --- /dev/null +++ b/application/referee/referee.c @@ -0,0 +1,385 @@ +/** + * @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 new file mode 100644 index 0000000..d531d5a --- /dev/null +++ b/application/referee/referee.h @@ -0,0 +1,50 @@ +#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/robot.c b/application/robot.c index 72b014c..5e79041 100644 --- a/application/robot.c +++ b/application/robot.c @@ -10,6 +10,7 @@ #if defined(ONE_BOARD) || defined(CHASSIS_BOARD) #include "chassis.h" +#include "referee.h" #endif #if defined(ONE_BOARD) || defined(GIMBAL_BOARD) @@ -34,6 +35,7 @@ void RobotInit() #endif #if defined(ONE_BOARD) || defined(CHASSIS_BOARD) + Referee_Interactive_init(); ChassisInit(); #endif // 初始化完成,开启中断 @@ -50,5 +52,6 @@ void RobotTask() #if defined(ONE_BOARD) || defined(CHASSIS_BOARD) ChassisTask(); + Referee_Interactive_task(); #endif } diff --git a/application/robot_def.h b/application/robot_def.h index 2758616..d81df22 100644 --- a/application/robot_def.h +++ b/application/robot_def.h @@ -128,7 +128,6 @@ typedef enum // 功率限制,从裁判系统获取 typedef struct { // 功率控制 - } Chassis_Power_Data_s; /* ----------------CMD应用发布的控制数据,应当由gimbal/chassis/shoot订阅---------------- */ diff --git a/modules/referee/crc_ref.c b/modules/referee/crc_ref.c index edc870b..b22b6ac 100644 --- a/modules/referee/crc_ref.c +++ b/modules/referee/crc_ref.c @@ -136,20 +136,18 @@ void Append_CRC8_Check_Sum( uint8_t *pchMessage, uint16_t dwLength) */ uint16_t Get_CRC16_Check_Sum(uint8_t *pchMessage,uint32_t dwLength,uint16_t wCRC) { - uint8_t chData; - - if (pchMessage == NULL) - { - return 0xFFFF; - } - while(dwLength--) - { - chData = *pchMessage++; - (wCRC) = ((uint16_t)(wCRC) >> 8) ^ - wCRC_Table[((uint16_t)(wCRC) ^ (uint16_t)(chData)) & 0x00ff]; - } - - return wCRC; + uint8_t chData; + if (pchMessage == NULL) + { + return 0xFFFF; + } + while(dwLength--) + { + chData = *pchMessage++; + (wCRC) = ((uint16_t)(wCRC) >> 8) ^ + wCRC_Table[((uint16_t)(wCRC) ^ (uint16_t)(chData)) & 0x00ff]; + } + return wCRC; } diff --git a/modules/referee/referee.h b/modules/referee/referee.h deleted file mode 100644 index b2238c9..0000000 --- a/modules/referee/referee.h +++ /dev/null @@ -1,357 +0,0 @@ -/** - * @file referee.h - * @author kidneygood (you@domain.com) - * @brief - * @version 0.1 - * @date 2022-11-18 - * - * @copyright Copyright (c) 2022 - * - */ - -#ifndef REFEREE_H -#define REFEREE_H - -#include "bsp_usart.h" -#include "usart.h" - -#define FALSE 0 -#define TRUE 1 - -#define JUDGE_DATA_ERROR 0 -#define JUDGE_DATA_CORRECT 1 - -#define LEN_HEADER 5 // 帧头长 -#define LEN_CMDID 2 // 命令码长度 -#define LEN_TAIL 2 // 帧尾CRC16 - -// 起始字节,协议固定为0xA5 -#define JUDGE_FRAME_HEADER (0xA5) - -#pragma pack(1) - -/***************裁判系统数据接收********************/ - -typedef enum -{ - FRAME_HEADER = 0, - CMD_ID = 5, - DATA = 7, -} JudgeFrameOffset; - -// 5字节帧头,偏移位置 -typedef enum -{ - SOF = 0, // 起始位 - DATA_LENGTH = 1, // 帧内数据长度,根据这个来获取数据长度 - SEQ = 3, // 包序号 - CRC8 = 4 // CRC8 - -} FrameHeaderOffset; - -// 命令码ID,用来判断接收的是什么数据 -typedef enum -{ - ID_game_state = 0x0001, // 比赛状态数据 - ID_game_result = 0x0002, // 比赛结果数据 - ID_game_robot_survivors = 0x0003, // 比赛机器人血量数据 - ID_event_data = 0x0101, // 场地事件数据 - ID_supply_projectile_action = 0x0102, // 场地补给站动作标识数据 - ID_supply_projectile_booking = 0x0103, // 场地补给站预约子弹数据 - ID_game_robot_state = 0x0201, // 机器人状态数据 - ID_power_heat_data = 0x0202, // 实时功率热量数据 - ID_game_robot_pos = 0x0203, // 机器人位置数据 - ID_buff_musk = 0x0204, // 机器人增益数据 - ID_aerial_robot_energy = 0x0205, // 空中机器人能量状态数据 - ID_robot_hurt = 0x0206, // 伤害状态数据 - ID_shoot_data = 0x0207, // 实时射击数据 - -} CmdID; - -// 命令码数据段长,根据官方协议来定义长度 -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 = 15, // 0x0201 - 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 -} JudgeDataLength; - -/* 自定义帧头 */ -typedef struct -{ - uint8_t SOF; - uint16_t DataLength; - uint8_t Seq; - uint8_t CRC8; - -} xFrameHeader; - -/* ID: 0x0001 Byte: 3 比赛状态数据 */ -typedef struct -{ - uint8_t game_type : 4; - uint8_t game_progress : 4; - uint16_t stage_remain_time; -} ext_game_state_t; - -/* ID: 0x0002 Byte: 1 比赛结果数据 */ -typedef struct -{ - uint8_t winner; -} ext_game_result_t; - -/* ID: 0x0003 Byte: 32 比赛机器人血量数据 */ -typedef struct -{ - uint16_t red_1_robot_HP; - uint16_t red_2_robot_HP; - uint16_t red_3_robot_HP; - uint16_t red_4_robot_HP; - uint16_t red_5_robot_HP; - uint16_t red_7_robot_HP; - uint16_t red_outpost_HP; - uint16_t red_base_HP; - uint16_t blue_1_robot_HP; - uint16_t blue_2_robot_HP; - uint16_t blue_3_robot_HP; - uint16_t blue_4_robot_HP; - uint16_t blue_5_robot_HP; - uint16_t blue_7_robot_HP; - uint16_t blue_outpost_HP; - uint16_t blue_base_HP; -} ext_game_robot_HP_t; - -/* ID: 0x0101 Byte: 4 场地事件数据 */ -typedef struct -{ - uint32_t event_type; -} ext_event_data_t; - -/* ID: 0x0102 Byte: 3 场地补给站动作标识数据 */ -typedef struct -{ - uint8_t supply_projectile_id; - uint8_t supply_robot_id; - uint8_t supply_projectile_step; - uint8_t supply_projectile_num; -} ext_supply_projectile_action_t; - -/* ID: 0X0201 Byte: 27 机器人状态数据 */ -typedef struct -{ - uint8_t robot_id; - uint8_t robot_level; - uint16_t remain_HP; - uint16_t max_HP; - uint16_t shooter_id1_17mm_cooling_rate; - uint16_t shooter_id1_17mm_cooling_limit; - uint16_t shooter_id1_17mm_speed_limit; - uint16_t shooter_id2_17mm_cooling_rate; - uint16_t shooter_id2_17mm_cooling_limit; - uint16_t shooter_id2_17mm_speed_limit; - uint16_t shooter_id1_42mm_cooling_rate; - uint16_t shooter_id1_42mm_cooling_limit; - uint16_t shooter_id1_42mm_speed_limit; - uint16_t chassis_power_limit; - uint8_t mains_power_gimbal_output : 1; - uint8_t mains_power_chassis_output : 1; - uint8_t mains_power_shooter_output : 1; -} ext_game_robot_state_t; - -/* ID: 0X0202 Byte: 14 实时功率热量数据 */ -typedef struct -{ - uint16_t chassis_volt; - uint16_t chassis_current; - float chassis_power; // 瞬时功率 - uint16_t chassis_power_buffer; // 60焦耳缓冲能量 - uint16_t shooter_heat0; // 17mm - uint16_t shooter_heat1; -} ext_power_heat_data_t; - -/* ID: 0x0203 Byte: 16 机器人位置数据 */ -typedef struct -{ - float x; - float y; - float z; - float yaw; -} ext_game_robot_pos_t; - -/* ID: 0x0204 Byte: 1 机器人增益数据 */ -typedef struct -{ - uint8_t power_rune_buff; -} ext_buff_musk_t; - -/* ID: 0x0205 Byte: 1 空中机器人能量状态数据 */ -typedef struct -{ - uint8_t attack_time; -} aerial_robot_energy_t; - -/* ID: 0x0206 Byte: 1 伤害状态数据 */ -typedef struct -{ - uint8_t armor_id : 4; - uint8_t hurt_type : 4; -} ext_robot_hurt_t; - -/* ID: 0x0207 Byte: 7 实时射击数据 */ -typedef struct -{ - uint8_t bullet_type; - uint8_t shooter_id; - uint8_t bullet_freq; - float bullet_speed; -} ext_shoot_data_t; - -/***************裁判系统数据********************/ -/* - - 交互数据,包括一个统一的数据段头结构, - 包含了内容 ID,发送者以及接受者的 ID 和内容数据段, - 整个交互数据的包总共长最大为 128 个字节, - 减去 frame_header,cmd_id,frame_tail 以及数据段头结构的 6 个字节, - 故而发送的内容数据段最大为 113。 - 整个交互数据 0x0301 的包上行频率为 10Hz。 - - 机器人 ID: - 1,英雄(红); - 2,工程(红); - 3/4/5,步兵(红); - 6,空中(红); - 7,哨兵(红); - 11,英雄(蓝); - 12,工程(蓝); - 13/14/15,步兵(蓝); - 16,空中(蓝); - 17,哨兵(蓝)。 - 客户端 ID: - 0x0101 为英雄操作手客户端( 红) ; - 0x0102 ,工程操作手客户端 ((红 ); - 0x0103/0x0104/0x0105,步兵操作手客户端(红); - 0x0106,空中操作手客户端((红); - 0x0111,英雄操作手客户端(蓝); - 0x0112,工程操作手客户端(蓝); - 0x0113/0x0114/0x0115,操作手客户端步兵(蓝); - 0x0116,空中操作手客户端(蓝)。 -*/ -/* 交互数据接收信息:0x0301 */ -typedef struct -{ - uint16_t data_cmd_id; - uint16_t send_ID; - uint16_t receiver_ID; -} ext_student_interactive_header_data_t; - -/* - 客户端 客户端自定义数据:cmd_id:0x0301。内容 ID:0xD180 - 发送频率:上限 10Hz - 1. 客户端 客户端自定义数据:cmd_id:0x0301。内容 ID:0xD180。发送频率:上限 10Hz - 字节偏移量 大小 说明 备注 - 0 2 数据的内容 ID 0xD180 - 2 2 送者的 ID 需要校验发送者机器人的 ID 正确性 - 4 2 客户端的 ID 只能为发送者机器人对应的客户端 - 6 4 自定义浮点数据 1 - 10 4 自定义浮点数据 2 - 14 4 自定义浮点数据 3 - 18 1 自定义 8 位数据 4 - -*/ -typedef struct -{ - float data1; - float data2; - float data3; - uint8_t masks; -} client_custom_data_t; - -/* - 学生机器人间通信 cmd_id 0x0301,内容 ID:0x0200~0x02FF - 交互数据 机器人间通信:0x0301。 - 发送频率:上限 10Hz - - 字节偏移量 大小 说明 备注 - 0 2 数据的内容 ID 0x0200~0x02FF - 可以在以上 ID 段选取,具体 ID 含义由参赛队自定义 - - 2 2 发送者的 ID 需要校验发送者的 ID 正确性, - 4 2 接收者的 ID 需要校验接收者的 ID 正确性, - 例如不能发送到敌对机器人的ID - 6 n 数据段 n 需要小于 113 - -*/ -typedef struct -{ - uint8_t data[10]; // 数据段,n需要小于113 -} robot_interactive_data_t; - -// 发送给客户端的信息 -// 帧头 命令码 数据段头结构 数据段 帧尾 -typedef struct -{ - xFrameHeader txFrameHeader; // 帧头 - uint16_t CmdID; // 命令码 - ext_student_interactive_header_data_t dataFrameHeader; // 数据段头结构 - client_custom_data_t clientData; // 数据段 - uint16_t FrameTail; // 帧尾 -} ext_SendClientData_t; - -// 机器人交互信息 -typedef struct -{ - xFrameHeader txFrameHeader; // 帧头 - uint16_t CmdID; // 命令码 - ext_student_interactive_header_data_t dataFrameHeader; // 数据段头结构 - robot_interactive_data_t interactData; // 数据段 - uint16_t FrameTail; // 帧尾 -} ext_CommunatianData_t; - -// 裁判系统接收数据整合进一个结构体 -typedef struct -{ - xFrameHeader FrameHeader; // 接收到的帧头信息 - uint16_t CmdID; - ext_game_state_t GameState; // 0x0001 - ext_game_result_t GameResult; // 0x0002 - ext_game_robot_HP_t GameRobotHP; // 0x0003 - ext_event_data_t EventData; // 0x0101 - ext_supply_projectile_action_t SupplyProjectileAction; // 0x0102 - ext_game_robot_state_t GameRobotStat; // 0x0201 - ext_power_heat_data_t PowerHeatData; // 0x0202 - ext_game_robot_pos_t GameRobotPos; // 0x0203 - ext_buff_musk_t BuffMusk; // 0x0204 - aerial_robot_energy_t AerialRobotEnergy; // 0x0205 - ext_robot_hurt_t RobotHurt; // 0x0206 - ext_shoot_data_t ShootData; // 0x0207 - - ext_SendClientData_t ShowData; // 客户端信息 - ext_CommunatianData_t CommuData; // 队友通信信息 - -} referee_info_t; - -#pragma pack() - -/** - * @brief 初始化裁判系统,返回接收数据指针 - * - * @param referee_usart_handle - * @return referee_info_t* - */ -referee_info_t* RefereeInit(UART_HandleTypeDef *referee_usart_handle); - - - - -#endif // !REFEREE_H diff --git a/modules/referee/referee_UI.c b/modules/referee/referee_UI.c index e69de29..2dc3e36 100644 --- a/modules/referee/referee_UI.c +++ b/modules/referee/referee_UI.c @@ -0,0 +1,433 @@ +/** + * @file referee_UI.C + * @author kidneygood (you@domain.com) + * @brief + * @version 0.1 + * @date 2023-1-18 + * + * @copyright Copyright (c) 2022 + * + */ +#include "referee_UI.h" +#include "string.h" +#include "crc.h" +#include "stdio.h" +#include "rm_referee.h" + +// 包序号 +/********************************************删除操作************************************* +**参数:_id 对应的id结构体 + Del_Operate 对应头文件删除操作 + Del_Layer 要删除的层 取值0-9 +*****************************************************************************************/ +void UI_Delete(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_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.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.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); // 发送 + + 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坐标 +**********************************************************************************************************/ + +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) +{ + 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->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坐标 +**********************************************************************************************************/ +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) +{ + 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->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 圆形半径 +**********************************************************************************************************/ + +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) +{ + 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->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半轴长度 +**********************************************************************************************************/ +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) +{ + 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->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半轴长度 +**********************************************************************************************************/ + +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) +{ + 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->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; +**********************************************************************************************************/ + +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) +{ + + 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->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; +**********************************************************************************************************/ +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) +{ + 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 Graph_Data类型变量指针,用于存放图形数据 + graphname[3] 图片名称,用于标识更改 + Graph_Operate 图片操作,见头文件 + Graph_Layer 图层0-9 + Graph_Color 图形颜色 + Graph_Size 字号 + Graph_Width 图形线宽 + Start_x、Start_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) +{ + 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.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; +} + +/* 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; + + va_list ap; // 创建一个 va_list 类型变量 + va_start(ap, cnt); // 初始化 va_list 变量为一个参数列表 + + 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.CmdID = ID_student_interactive; + + 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.datahead.receiver_ID = _id->Cilent_ID; + UI_GraphReFresh_data.datahead.sender_ID = _id->Robot_ID; + + // 先发送帧头、命令码、交互数据帧头三部分,并计算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); + + 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); + } + + RefereeSend((uint8_t *)&UI_GraphReFresh_data.frametail, LEN_TAIL); // 发送CRC16校验值 + + va_end(ap); // 结束可变参数的获取 + UI_Seq++; // 包序号+1 +} + +/************************************************UI推送字符(使更改生效)*********************************/ +void Char_ReFresh(referee_id_t *_id, String_Data_t string_Data) +{ + UI_CharReFresh_t UI_CharReFresh_data; + + 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.CmdID = ID_student_interactive; + + 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.String_Data = string_Data; + + 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); // 发送 + + UI_Seq++; // 包序号+1 +} diff --git a/modules/referee/referee_UI.h b/modules/referee/referee_UI.h new file mode 100644 index 0000000..474b966 --- /dev/null +++ b/modules/referee/referee_UI.h @@ -0,0 +1,77 @@ +#ifndef REFEREE_UI_H +#define REFEREE_UI_H + +#include "stdarg.h" +#include "stdint.h" +#include "referee_def.h" +#include "rm_referee.h" + +#pragma pack(1) //按1字节对齐 + +/* 此处的定义只与UI绘制有关 */ +typedef struct +{ + xFrameHeader FrameHeader; + uint16_t CmdID; + ext_student_interactive_header_data_t datahead; + uint8_t Delete_Operate; //删除操作 + uint8_t Layer; + uint16_t frametail; +} UI_delete_t; + +typedef struct +{ + 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; + ext_student_interactive_header_data_t datahead; + String_Data_t String_Data; + uint16_t frametail; +} UI_CharReFresh_t; //打印字符串数据 + +#pragma pack() + + + + +void UI_Delete(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 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 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 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 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 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_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 index e69de29..d714605 100644 --- a/modules/referee/referee_communication.c +++ b/modules/referee/referee_communication.c @@ -0,0 +1,45 @@ +/** + * @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.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 new file mode 100644 index 0000000..cba2324 --- /dev/null +++ b/modules/referee/referee_communication.h @@ -0,0 +1,10 @@ +#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_def.h new file mode 100644 index 0000000..4c2312f --- /dev/null +++ b/modules/referee/referee_def.h @@ -0,0 +1,397 @@ +/** + * @file referee_def.h + * @author kidneygood (you@domain.com) + * @version 0.1 + * @date 2022-12-02 + * + * @copyright Copyright (c) HNU YueLu EC 2022 all rights reserved + * + */ + +#ifndef REFEREE_DEF_H +#define REFEREE_DEF_H + +#include "stdint.h" + +/****************************宏定义部分****************************/ +/****************************宏定义部分****************************/ + +#define REFEREE_SOF 0xA5 // 起始字节,协议固定为0xA5 +#define Robot_Red 0 +#define Robot_Blue 1 +#define Communicate_Data_LEN 5 //自定义交互数据长度,该长度决定了我方发送和他方接收,自定义交互数据协议更改时只需要更改此宏定义即可 + +#pragma pack(1) + +/****************************通信协议格式****************************/ +/****************************通信协议格式****************************/ + +/* 通信协议格式偏移,枚举类型,代替#define声明 */ +typedef enum +{ + FRAME_HEADER_Offset = 0, + CMD_ID_Offset = 5, + DATA_Offset = 7, +} JudgeFrameOffset_e; + +/* 通信协议长度 */ +typedef enum +{ + LEN_HEADER = 5, // 帧头长 + LEN_CMDID = 2, // 命令码长度 + LEN_TAIL = 2, // 帧尾CRC16 + + LEN_CRC8 = 4, // 帧头CRC8校验长度=帧头+数据长+包序号 +} JudgeFrameLength_e; + +/****************************帧头****************************/ +/****************************帧头****************************/ + +/* 帧头偏移 */ +typedef enum +{ + SOF = 0, // 起始位 + DATA_LENGTH = 1, // 帧内数据长度,根据这个来获取数据长度 + SEQ = 3, // 包序号 + CRC8 = 4 // CRC8 +} FrameHeaderOffset_e; + +/* 帧头定义 */ +typedef struct +{ + uint8_t SOF; + uint16_t DataLength; + uint8_t Seq; + uint8_t CRC8; +} xFrameHeader; + +/****************************cmd_id命令码说明****************************/ +/****************************cmd_id命令码说明****************************/ + +/* 命令码ID,用来判断接收的是什么数据 */ +typedef enum +{ + ID_game_state = 0x0001, // 比赛状态数据 + ID_game_result = 0x0002, // 比赛结果数据 + ID_game_robot_survivors = 0x0003, // 比赛机器人血量数据 + ID_event_data = 0x0101, // 场地事件数据 + ID_supply_projectile_action = 0x0102, // 场地补给站动作标识数据 + ID_supply_projectile_booking = 0x0103, // 场地补给站预约子弹数据 + ID_game_robot_state = 0x0201, // 机器人状态数据 + ID_power_heat_data = 0x0202, // 实时功率热量数据 + ID_game_robot_pos = 0x0203, // 机器人位置数据 + ID_buff_musk = 0x0204, // 机器人增益数据 + ID_aerial_robot_energy = 0x0205, // 空中机器人能量状态数据 + ID_robot_hurt = 0x0206, // 伤害状态数据 + ID_shoot_data = 0x0207, // 实时射击数据 + ID_student_interactive = 0x0301, // 机器人间交互数据 +} CmdID_e; + +/* 命令码数据段长,根据官方协议来定义长度,还有自定义数据长度 */ +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 + +} JudgeDataLength_e; + +/****************************接收数据的详细说明****************************/ +/****************************接收数据的详细说明****************************/ + +/* ID: 0x0001 Byte: 3 比赛状态数据 */ +typedef struct +{ + uint8_t game_type : 4; + uint8_t game_progress : 4; + uint16_t stage_remain_time; +} ext_game_state_t; + +/* ID: 0x0002 Byte: 1 比赛结果数据 */ +typedef struct +{ + uint8_t winner; +} ext_game_result_t; + +/* ID: 0x0003 Byte: 32 比赛机器人血量数据 */ +typedef struct +{ + uint16_t red_1_robot_HP; + uint16_t red_2_robot_HP; + uint16_t red_3_robot_HP; + uint16_t red_4_robot_HP; + uint16_t red_5_robot_HP; + uint16_t red_7_robot_HP; + uint16_t red_outpost_HP; + uint16_t red_base_HP; + uint16_t blue_1_robot_HP; + uint16_t blue_2_robot_HP; + uint16_t blue_3_robot_HP; + uint16_t blue_4_robot_HP; + uint16_t blue_5_robot_HP; + uint16_t blue_7_robot_HP; + uint16_t blue_outpost_HP; + uint16_t blue_base_HP; +} ext_game_robot_HP_t; + +/* ID: 0x0101 Byte: 4 场地事件数据 */ +typedef struct +{ + uint32_t event_type; +} ext_event_data_t; + +/* ID: 0x0102 Byte: 3 场地补给站动作标识数据 */ +typedef struct +{ + uint8_t supply_projectile_id; + uint8_t supply_robot_id; + uint8_t supply_projectile_step; + uint8_t supply_projectile_num; +} ext_supply_projectile_action_t; + +/* ID: 0X0201 Byte: 27 机器人状态数据 */ +typedef struct +{ + uint8_t robot_id; + uint8_t robot_level; + uint16_t remain_HP; + uint16_t max_HP; + uint16_t shooter_id1_17mm_cooling_rate; + uint16_t shooter_id1_17mm_cooling_limit; + uint16_t shooter_id1_17mm_speed_limit; + uint16_t shooter_id2_17mm_cooling_rate; + uint16_t shooter_id2_17mm_cooling_limit; + uint16_t shooter_id2_17mm_speed_limit; + uint16_t shooter_id1_42mm_cooling_rate; + uint16_t shooter_id1_42mm_cooling_limit; + uint16_t shooter_id1_42mm_speed_limit; + uint16_t chassis_power_limit; + uint8_t mains_power_gimbal_output : 1; + uint8_t mains_power_chassis_output : 1; + uint8_t mains_power_shooter_output : 1; +} ext_game_robot_state_t; + +/* ID: 0X0202 Byte: 14 实时功率热量数据 */ +typedef struct +{ + uint16_t chassis_volt; + uint16_t chassis_current; + float chassis_power; // 瞬时功率 + uint16_t chassis_power_buffer; // 60焦耳缓冲能量 + uint16_t shooter_heat0; // 17mm + uint16_t shooter_heat1; +} ext_power_heat_data_t; + +/* ID: 0x0203 Byte: 16 机器人位置数据 */ +typedef struct +{ + float x; + float y; + float z; + float yaw; +} ext_game_robot_pos_t; + +/* ID: 0x0204 Byte: 1 机器人增益数据 */ +typedef struct +{ + uint8_t power_rune_buff; +} ext_buff_musk_t; + +/* ID: 0x0205 Byte: 1 空中机器人能量状态数据 */ +typedef struct +{ + uint8_t attack_time; +} aerial_robot_energy_t; + +/* ID: 0x0206 Byte: 1 伤害状态数据 */ +typedef struct +{ + uint8_t armor_id : 4; + uint8_t hurt_type : 4; +} ext_robot_hurt_t; + +/* ID: 0x0207 Byte: 7 实时射击数据 */ +typedef struct +{ + uint8_t bullet_type; + uint8_t shooter_id; + uint8_t bullet_freq; + float bullet_speed; +} ext_shoot_data_t; + +/****************************机器人交互数据****************************/ +/****************************机器人交互数据****************************/ +/* 发送的内容数据段最大为 113 检测是否超出大小限制?实际上图形段不会超,数据段最多30个,也不会超*/ +/* 交互数据头结构 */ +typedef struct +{ + uint16_t data_cmd_id; //由于存在多个内容 ID,但整个cmd_id 上行频率最大为 10Hz,请合理安排带宽。注意交互部分的上行频率 + uint16_t sender_ID; + uint16_t receiver_ID; +} ext_student_interactive_header_data_t; + +/* 机器人id */ +typedef enum +{ + // 红方机器人ID + RobotID_RHero = 1, + RobotID_REngineer = 2, + RobotID_RStandard1 = 3, + RobotID_RStandard2 = 4, + RobotID_RStandard3 = 5, + RobotID_RAerial = 6, + RobotID_RSentry = 7, + RobotID_RRadar = 9, + // 蓝方机器人ID + RobotID_BHero = 101, + RobotID_BEngineer = 102, + RobotID_BStandard1 = 103, + RobotID_BStandard2 = 104, + RobotID_BStandard3 = 105, + RobotID_BAerial = 106, + RobotID_BSentry = 107, + RobotID_BRadar = 109, +} Robot_ID_e; + +/* 交互数据ID */ +typedef enum +{ + UI_Data_ID_Del = 0x100, + UI_Data_ID_Draw1 = 0x101, + UI_Data_ID_Draw2 = 0x102, + UI_Data_ID_Draw5 = 0x103, + UI_Data_ID_Draw7 = 0x104, + UI_Data_ID_DrawChar = 0x110, + + /* 自定义交互数据部分 */ + Communicate_Data_ID = 0x0200, + +} Interactive_Data_ID_e; +/* 交互数据长度 */ +typedef enum +{ + Interactive_Data_LEN_Head = 6, + UI_Operate_LEN_Del = 2, + UI_Operate_LEN_PerDraw = 15, + UI_Operate_LEN_DrawChar = 15 + 30, + + /* 自定义交互数据部分 */ + // Communicate_Data_LEN = 5, + +} Interactive_Data_Length_e; + +/****************************自定义交互数据****************************/ +/****************************自定义交互数据****************************/ +/* + 学生机器人间通信 cmd_id 0x0301,内容 ID:0x0200~0x02FF + 自定义交互数据 机器人间通信:0x0301。 + 发送频率:上限 10Hz +*/ +//自定义交互数据协议,可更改,更改后需要修改最上方宏定义数据长度的值 +typedef struct +{ + uint8_t data[Communicate_Data_LEN]; // 数据段,n需要小于113 +} robot_interactive_data_t; + +// 机器人交互信息_发送 +typedef struct +{ + xFrameHeader FrameHeader; + uint16_t CmdID; + ext_student_interactive_header_data_t datahead; + robot_interactive_data_t Data; // 数据段 + uint16_t frametail; +} Communicate_SendData_t; +// 机器人交互信息_接收 +typedef struct +{ + ext_student_interactive_header_data_t datahead; + robot_interactive_data_t Data; // 数据段 +} Communicate_ReceiveData_t; + + +/****************************UI交互数据****************************/ +/****************************UI交互数据****************************/ + +/* 图形数据 */ +typedef struct +{ + uint8_t graphic_name[3]; + uint32_t operate_tpye : 3; + uint32_t graphic_tpye : 3; + uint32_t layer : 4; + uint32_t color : 4; + uint32_t start_angle : 9; + uint32_t end_angle : 9; + uint32_t width : 10; + uint32_t start_x : 11; + uint32_t start_y : 11; + uint32_t radius : 10; + uint32_t end_x : 11; + uint32_t end_y : 11; +} Graph_Data_t; + +typedef struct +{ + Graph_Data_t Graph_Control; + uint8_t show_Data[30]; +} String_Data_t; // 打印字符串数据 + +/* 删除操作 */ +typedef enum +{ + UI_Data_Del_NoOperate = 0, + UI_Data_Del_Layer = 1, + UI_Data_Del_ALL = 2, // 删除全部图层,后面的参数已经不重要了。 +} UI_Delete_Operate_e; + +/* 图形配置参数__图形操作 */ +typedef enum +{ + UI_Graph_ADD = 1, + UI_Graph_Change = 2, + UI_Graph_Del = 3, +} UI_Graph_Operate_e; + +/* 图形配置参数__图形类型 */ +typedef enum +{ + UI_Graph_Line = 0, // 直线 + UI_Graph_Rectangle = 1, // 矩形 + UI_Graph_Circle = 2, // 整圆 + UI_Graph_Ellipse = 3, // 椭圆 + UI_Graph_Arc = 4, // 圆弧 + UI_Graph_Float = 5, // 浮点型 + UI_Graph_Int = 6, // 整形 + UI_Graph_Char = 7, // 字符型 + +} UI_Graph_Type_e; + +/* 图形配置参数__图形颜色 */ +typedef enum +{ + UI_Color_Main = 0, // 红蓝主色 + UI_Color_Yellow = 1, + UI_Color_Green = 2, + UI_Color_Orange = 3, + UI_Color_Purplish_red = 4, // 紫红色 + UI_Color_Pink = 5, + UI_Color_Cyan = 6, // 青色 + UI_Color_Black = 7, + UI_Color_White = 8, + +} UI_Graph_Color_e; + +#pragma pack() + +#endif diff --git a/modules/referee/referee.c b/modules/referee/rm_referee.c similarity index 57% rename from modules/referee/referee.c rename to modules/referee/rm_referee.c index 3abb972..e40297e 100644 --- a/modules/referee/referee.c +++ b/modules/referee/rm_referee.c @@ -1,18 +1,56 @@ -#include "referee.h" +/** + * @file rm_referee.C + * @author kidneygood (you@domain.com) + * @brief + * @version 0.1 + * @date 2022-11-18 + * + * @copyright Copyright (c) 2022 + * + */ + +#include "rm_referee.h" #include "string.h" #include "crc_ref.h" #include "bsp_usart.h" -#include "dma.h" -// 参考深圳大学 Infantry_X-master #define RE_RX_BUFFER_SIZE 200 -static USARTInstance *referee_usart_instance; +static USARTInstance *referee_usart_instance; // 暂时改为非静态变量 -/**************裁判系统数据******************/ static referee_info_t referee_info; -static uint8_t Judge_Self_ID; // 当前机器人的ID -static uint16_t Judge_SelfClient_ID; // 发送者机器人对应的客户端ID +static void JudgeReadData(uint8_t *ReadFromUsart); +static void RefereeRxCallback(); + +uint8_t UI_Seq = 0; // 包序号,供整个referee文件使用 + +/* 裁判系统通信初始化 */ +referee_info_t *RefereeInit(UART_HandleTypeDef *referee_usart_handle) +{ + USART_Init_Config_s conf; + conf.module_callback = RefereeRxCallback; + conf.usart_handle = referee_usart_handle; + conf.recv_buff_size = RE_RX_BUFFER_SIZE; + referee_usart_instance = USARTRegister(&conf); + return &referee_info; +} + +/** + * @brief 发送函数 + * @param send 待发送数据 + */ +void RefereeSend(uint8_t *send, uint16_t tx_len) +{ + USARTSend(referee_usart_instance, send, tx_len); + /* syhtodo DMA请求过快会导致数据发送丢失,考虑数据尽可能打成一个整包以及队列发送,并且发送函数添加缓冲区 */ + HAL_Delay(5); +} + +/*裁判系统串口接收回调函数,解析数据 */ +static void RefereeRxCallback() +{ + JudgeReadData(referee_usart_instance->recv_buff); +} /** * @brief 读取裁判数据,中断中读取保证速度 @@ -22,17 +60,15 @@ static uint16_t Judge_SelfClient_ID; // 发送者机器人对应的客户端ID */ static void JudgeReadData(uint8_t *ReadFromUsart) { - uint16_t judge_length; // 统计一帧数据长度 - // referee_info.CmdID = 0; //数据命令码解析 - // 空数据包,则不作任何处理 - if (ReadFromUsart == NULL) + uint16_t judge_length; // 统计一帧数据长度 + if (ReadFromUsart == NULL) // 空数据包,则不作任何处理 return; // 写入帧头数据(5-byte),用于判断是否开始存储裁判数据 memcpy(&referee_info.FrameHeader, ReadFromUsart, LEN_HEADER); // 判断帧头数据(0)是否为0xA5 - if (ReadFromUsart[SOF] == JUDGE_FRAME_HEADER) + if (ReadFromUsart[SOF] == REFEREE_SOF) { // 帧头CRC8校验 if (Verify_CRC8_Check_Sum(ReadFromUsart, LEN_HEADER) == TRUE) @@ -49,51 +85,43 @@ static void JudgeReadData(uint8_t *ReadFromUsart) switch (referee_info.CmdID) { case ID_game_state: // 0x0001 - memcpy(&referee_info.GameState, (ReadFromUsart + DATA), LEN_game_state); + memcpy(&referee_info.GameState, (ReadFromUsart + DATA_Offset), LEN_game_state); break; - case ID_game_result: // 0x0002 - memcpy(&referee_info.GameResult, (ReadFromUsart + DATA), LEN_game_result); + memcpy(&referee_info.GameResult, (ReadFromUsart + DATA_Offset), LEN_game_result); break; - case ID_game_robot_survivors: // 0x0003 - memcpy(&referee_info.GameRobotHP, (ReadFromUsart + DATA), LEN_game_robot_HP); + memcpy(&referee_info.GameRobotHP, (ReadFromUsart + DATA_Offset), LEN_game_robot_HP); break; - case ID_event_data: // 0x0101 - memcpy(&referee_info.EventData, (ReadFromUsart + DATA), LEN_event_data); + memcpy(&referee_info.EventData, (ReadFromUsart + DATA_Offset), LEN_event_data); break; - case ID_supply_projectile_action: // 0x0102 - memcpy(&referee_info.SupplyProjectileAction, (ReadFromUsart + DATA), LEN_supply_projectile_action); + memcpy(&referee_info.SupplyProjectileAction, (ReadFromUsart + DATA_Offset), LEN_supply_projectile_action); break; - case ID_game_robot_state: // 0x0201 - memcpy(&referee_info.GameRobotStat, (ReadFromUsart + DATA), LEN_game_robot_state); + memcpy(&referee_info.GameRobotState, (ReadFromUsart + DATA_Offset), LEN_game_robot_state); break; case ID_power_heat_data: // 0x0202 - memcpy(&referee_info.PowerHeatData, (ReadFromUsart + DATA), LEN_power_heat_data); + memcpy(&referee_info.PowerHeatData, (ReadFromUsart + DATA_Offset), LEN_power_heat_data); break; - case ID_game_robot_pos: // 0x0203 - memcpy(&referee_info.GameRobotPos, (ReadFromUsart + DATA), LEN_game_robot_pos); + memcpy(&referee_info.GameRobotPos, (ReadFromUsart + DATA_Offset), LEN_game_robot_pos); break; - case ID_buff_musk: // 0x0204 - memcpy(&referee_info.BuffMusk, (ReadFromUsart + DATA), LEN_buff_musk); + memcpy(&referee_info.BuffMusk, (ReadFromUsart + DATA_Offset), LEN_buff_musk); break; - case ID_aerial_robot_energy: // 0x0205 - memcpy(&referee_info.AerialRobotEnergy, (ReadFromUsart + DATA), LEN_aerial_robot_energy); + memcpy(&referee_info.AerialRobotEnergy, (ReadFromUsart + DATA_Offset), LEN_aerial_robot_energy); break; - case ID_robot_hurt: // 0x0206 - memcpy(&referee_info.RobotHurt, (ReadFromUsart + DATA), LEN_robot_hurt); + memcpy(&referee_info.RobotHurt, (ReadFromUsart + DATA_Offset), LEN_robot_hurt); break; - case ID_shoot_data: // 0x0207 - memcpy(&referee_info.ShootData, (ReadFromUsart + DATA), LEN_shoot_data); - // JUDGE_ShootNumCount();//发弹量统计 + memcpy(&referee_info.ShootData, (ReadFromUsart + DATA_Offset), LEN_shoot_data); + break; + case ID_student_interactive: // 0x0301 syhtodo接收代码未测试 + memcpy(&referee_info.ReceiveData, (ReadFromUsart + DATA_Offset), LEN_receive_data); break; } } @@ -106,22 +134,3 @@ static void JudgeReadData(uint8_t *ReadFromUsart) } } } - -/** - * @brief 裁判系统串口接收回调函数,解析数据 - * - */ -static void RefereeRxCallback() -{ - JudgeReadData(referee_usart_instance->recv_buff); -} - -referee_info_t *RefereeInit(UART_HandleTypeDef *referee_usart_handle) -{ - USART_Init_Config_s conf; - conf.module_callback = RefereeRxCallback; - conf.usart_handle = referee_usart_handle; - conf.recv_buff_size = RE_RX_BUFFER_SIZE; - referee_usart_instance = USARTRegister(&conf); - return &referee_info; -} \ No newline at end of file diff --git a/modules/referee/rm_referee.h b/modules/referee/rm_referee.h new file mode 100644 index 0000000..16fb381 --- /dev/null +++ b/modules/referee/rm_referee.h @@ -0,0 +1,60 @@ +#ifndef RM_REFEREE_H +#define RM_REFEREE_H + +#include "usart.h" +#include "referee_def.h" +#include "bsp_usart.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,必须和本机器人同颜色 +} referee_id_t; + +// 此结构体包含裁判系统接收数据以及UI绘制与机器人车间通信的相关信息 +typedef struct +{ + referee_id_t referee_id; + + xFrameHeader FrameHeader; // 接收到的帧头信息 + uint16_t CmdID; + ext_game_state_t GameState; // 0x0001 + ext_game_result_t GameResult; // 0x0002 + ext_game_robot_HP_t GameRobotHP; // 0x0003 + ext_event_data_t EventData; // 0x0101 + ext_supply_projectile_action_t SupplyProjectileAction; // 0x0102 + ext_game_robot_state_t GameRobotState; // 0x0201 + ext_power_heat_data_t PowerHeatData; // 0x0202 + ext_game_robot_pos_t GameRobotPos; // 0x0203 + ext_buff_musk_t BuffMusk; // 0x0204 + aerial_robot_energy_t AerialRobotEnergy; // 0x0205 + ext_robot_hurt_t RobotHurt; // 0x0206 + ext_shoot_data_t ShootData; // 0x0207 + + //自定义交互数据的接收 + Communicate_ReceiveData_t ReceiveData; + +} referee_info_t; + +#pragma pack() + +/** + * @brief 初始化裁判系统,返回接收数据指针 + * + * @param referee_usart_handle + * @return referee_info_t* + */ +referee_info_t *RefereeInit(UART_HandleTypeDef *referee_usart_handle); + +/** + * @brief 发送函数 + * @todo + * @param send 待发送数据 + */ +void RefereeSend(uint8_t *send, uint16_t tx_len); + +#endif // !REFEREE_H