第一次提交
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
#include "crc_ref.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
const uint8_t CRC8_INIT = 0xff;
|
||||
const uint8_t CRC8_TAB[256] =
|
||||
{
|
||||
0x00, 0x5e, 0xbc, 0xe2, 0x61, 0x3f, 0xdd, 0x83, 0xc2, 0x9c, 0x7e, 0x20, 0xa3, 0xfd, 0x1f, 0x41,
|
||||
0x9d, 0xc3, 0x21, 0x7f, 0xfc, 0xa2, 0x40, 0x1e, 0x5f, 0x01, 0xe3, 0xbd, 0x3e, 0x60, 0x82, 0xdc,
|
||||
0x23, 0x7d, 0x9f, 0xc1, 0x42, 0x1c, 0xfe, 0xa0, 0xe1, 0xbf, 0x5d, 0x03, 0x80, 0xde, 0x3c, 0x62,
|
||||
0xbe, 0xe0, 0x02, 0x5c, 0xdf, 0x81, 0x63, 0x3d, 0x7c, 0x22, 0xc0, 0x9e, 0x1d, 0x43, 0xa1, 0xff,
|
||||
0x46, 0x18, 0xfa, 0xa4, 0x27, 0x79, 0x9b, 0xc5, 0x84, 0xda, 0x38, 0x66, 0xe5, 0xbb, 0x59, 0x07,
|
||||
0xdb, 0x85, 0x67, 0x39, 0xba, 0xe4, 0x06, 0x58, 0x19, 0x47, 0xa5, 0xfb, 0x78, 0x26, 0xc4, 0x9a,
|
||||
0x65, 0x3b, 0xd9, 0x87, 0x04, 0x5a, 0xb8, 0xe6, 0xa7, 0xf9, 0x1b, 0x45, 0xc6, 0x98, 0x7a, 0x24,
|
||||
0xf8, 0xa6, 0x44, 0x1a, 0x99, 0xc7, 0x25, 0x7b, 0x3a, 0x64, 0x86, 0xd8, 0x5b, 0x05, 0xe7, 0xb9,
|
||||
0x8c, 0xd2, 0x30, 0x6e, 0xed, 0xb3, 0x51, 0x0f, 0x4e, 0x10, 0xf2, 0xac, 0x2f, 0x71, 0x93, 0xcd,
|
||||
0x11, 0x4f, 0xad, 0xf3, 0x70, 0x2e, 0xcc, 0x92, 0xd3, 0x8d, 0x6f, 0x31, 0xb2, 0xec, 0x0e, 0x50,
|
||||
0xaf, 0xf1, 0x13, 0x4d, 0xce, 0x90, 0x72, 0x2c, 0x6d, 0x33, 0xd1, 0x8f, 0x0c, 0x52, 0xb0, 0xee,
|
||||
0x32, 0x6c, 0x8e, 0xd0, 0x53, 0x0d, 0xef, 0xb1, 0xf0, 0xae, 0x4c, 0x12, 0x91, 0xcf, 0x2d, 0x73,
|
||||
0xca, 0x94, 0x76, 0x28, 0xab, 0xf5, 0x17, 0x49, 0x08, 0x56, 0xb4, 0xea, 0x69, 0x37, 0xd5, 0x8b,
|
||||
0x57, 0x09, 0xeb, 0xb5, 0x36, 0x68, 0x8a, 0xd4, 0x95, 0xcb, 0x29, 0x77, 0xf4, 0xaa, 0x48, 0x16,
|
||||
0xe9, 0xb7, 0x55, 0x0b, 0x88, 0xd6, 0x34, 0x6a, 0x2b, 0x75, 0x97, 0xc9, 0x4a, 0x14, 0xf6, 0xa8,
|
||||
0x74, 0x2a, 0xc8, 0x96, 0x15, 0x4b, 0xa9, 0xf7, 0xb6, 0xe8, 0x0a, 0x54, 0xd7, 0x89, 0x6b, 0x35,
|
||||
};
|
||||
|
||||
|
||||
uint16_t CRC_INIT = 0xffff;
|
||||
const uint16_t wCRC_Table[256] =
|
||||
{
|
||||
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
|
||||
0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
|
||||
0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
|
||||
0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
|
||||
0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
|
||||
0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
|
||||
0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
|
||||
0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
|
||||
0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
|
||||
0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
|
||||
0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
|
||||
0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
|
||||
0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
|
||||
0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
|
||||
0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
|
||||
0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
|
||||
0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
|
||||
0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
|
||||
0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
|
||||
0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
|
||||
0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
|
||||
0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
|
||||
0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
|
||||
0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
|
||||
0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
|
||||
0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
|
||||
0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
|
||||
0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
|
||||
0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
|
||||
0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
|
||||
0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
|
||||
0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
|
||||
};
|
||||
|
||||
// CRC8
|
||||
void Append_CRC8_Check_Sum( uint8_t *pchMessage, uint16_t dwLength);
|
||||
uint32_t Verify_CRC8_Check_Sum( uint8_t *pchMessage, uint16_t dwLength);
|
||||
uint8_t Get_CRC8_Check_Sum( uint8_t *pchMessage, uint16_t dwLength, uint8_t ucCRC8 );
|
||||
|
||||
// CRC16
|
||||
void Append_CRC16_Check_Sum(uint8_t * pchMessage,uint32_t dwLength);
|
||||
uint32_t Verify_CRC16_Check_Sum(uint8_t *pchMessage, uint32_t dwLength);
|
||||
uint16_t Get_CRC16_Check_Sum(uint8_t *pchMessage,uint32_t dwLength,uint16_t wCRC);
|
||||
|
||||
|
||||
|
||||
|
||||
/* CRC校验 */
|
||||
|
||||
uint8_t Get_CRC8_Check_Sum( uint8_t *pchMessage, uint16_t dwLength, uint8_t ucCRC8 )
|
||||
{
|
||||
uint8_t ucIndex;
|
||||
|
||||
while (dwLength--)
|
||||
{
|
||||
ucIndex = ucCRC8^(*pchMessage++);
|
||||
ucCRC8 = CRC8_TAB[ucIndex];
|
||||
}
|
||||
return ucCRC8;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Descriptions: CRC8 Verify function
|
||||
** Input: Data to Verify,Stream length = Data + checksum
|
||||
** Output: True or False (CRC Verify Result)
|
||||
*/
|
||||
uint32_t Verify_CRC8_Check_Sum( uint8_t *pchMessage, uint16_t dwLength)
|
||||
{
|
||||
uint8_t ucExpected = 0;
|
||||
|
||||
if (pchMessage == 0 || dwLength <= 2)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ucExpected = Get_CRC8_Check_Sum( pchMessage, dwLength-1, CRC8_INIT);
|
||||
|
||||
return ( ucExpected == pchMessage[dwLength-1] );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Descriptions: append CRC8 to the end of data
|
||||
** Input: Data to CRC and append,Stream length = Data + checksum
|
||||
** Output: True or False (CRC Verify Result)
|
||||
*/
|
||||
void Append_CRC8_Check_Sum( uint8_t *pchMessage, uint16_t dwLength)
|
||||
{
|
||||
uint8_t ucCRC = 0;
|
||||
|
||||
if (pchMessage == 0 || dwLength <= 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ucCRC = Get_CRC8_Check_Sum( (uint8_t *)pchMessage, dwLength-1, CRC8_INIT);
|
||||
|
||||
pchMessage[dwLength-1] = ucCRC;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Descriptions: CRC16 checksum function
|
||||
** Input: Data to check,Stream length, initialized checksum
|
||||
** Output: CRC checksum
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Descriptions: CRC16 Verify function
|
||||
** Input: Data to Verify,Stream length = Data + checksum
|
||||
** Output: True or False (CRC Verify Result)
|
||||
*/
|
||||
uint32_t Verify_CRC16_Check_Sum(uint8_t *pchMessage, uint32_t dwLength)
|
||||
{
|
||||
uint16_t wExpected = 0;
|
||||
|
||||
if ((pchMessage == NULL) || (dwLength <= 2))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
wExpected = Get_CRC16_Check_Sum ( pchMessage, dwLength - 2, CRC_INIT);
|
||||
return ( (wExpected & 0xff) == pchMessage[dwLength - 2]
|
||||
&& ((wExpected >> 8) & 0xff) == pchMessage[dwLength - 1]);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Descriptions: append CRC16 to the end of data
|
||||
** Input: Data to CRC and append,Stream length = Data + checksum
|
||||
** Output: True or False (CRC Verify Result)
|
||||
*/
|
||||
void Append_CRC16_Check_Sum(uint8_t * pchMessage,uint32_t dwLength)
|
||||
{
|
||||
uint16_t wCRC = 0;
|
||||
|
||||
if ((pchMessage == NULL) || (dwLength <= 2))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
wCRC = Get_CRC16_Check_Sum ( (uint8_t *)pchMessage, dwLength-2, CRC_INIT );
|
||||
|
||||
pchMessage[dwLength-2] = (uint8_t)(wCRC & 0x00ff);
|
||||
pchMessage[dwLength-1] = (uint8_t)((wCRC >> 8)& 0x00ff);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef __CRC_H_
|
||||
#define __CRC_H_
|
||||
|
||||
// 裁判系统官方CRC校验,LUT和module/algorithms中的不同,后续需要统一实现crc,提供8/16/32的支持
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
// CRC8
|
||||
void Append_CRC8_Check_Sum(uint8_t *pchMessage, uint16_t dwLength);
|
||||
uint32_t Verify_CRC8_Check_Sum(uint8_t *pchMessage, uint16_t dwLength);
|
||||
uint8_t Get_CRC8_Check_Sum(uint8_t *pchMessage, uint16_t dwLength, uint8_t ucCRC8);
|
||||
|
||||
// CRC16
|
||||
void Append_CRC16_Check_Sum(uint8_t *pchMessage, uint32_t dwLength);
|
||||
uint32_t Verify_CRC16_Check_Sum(uint8_t *pchMessage, uint32_t dwLength);
|
||||
uint16_t Get_CRC16_Check_Sum(uint8_t *pchMessage, uint32_t dwLength, uint16_t wCRC);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,196 @@
|
||||
# referee
|
||||
|
||||
## referee运行流程
|
||||
|
||||
首先在chassis的初始化中调用裁判系统初始化函数,将要绘制的uidata的指针传递给接口,接口会返回裁判系统的反馈数据指针。然后,在refereeUItask里进行UI初始化,确定ui发送的目标并绘制初始化UI。完成后,uitask会以10hz的频率按顺序更新UI。
|
||||
|
||||
## 如何绘制你的自定义UI?以绘制超级电容能量条为例
|
||||
|
||||
UI的绘制包含初始化和TASK两个部分,初始化部分在`MyUIInit`函数中,TASK部分在`MyUIRefresh`函数中。
|
||||
|
||||
### 初始化部分
|
||||
|
||||
初始化部分的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
|
||||
UICharDraw(&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”发送即可:
|
||||
UICharRefresh(&referee_recv_info->referee_id, UI_State_sta[5]);
|
||||
```
|
||||
|
||||
### 绘制能量框
|
||||
|
||||
定义一个图形类结构体,用于绘制能量框:
|
||||
|
||||
```c
|
||||
static Graph_Data_t UI_energy_line[3]; // 电容能量条
|
||||
```
|
||||
|
||||
能量框参数设置以及发送函数:
|
||||
|
||||
```c
|
||||
UIRectangleDraw(&UI_energy_line[0],"ss6", UI_Graph_ADD, 7, UI_Color_Green,20, 720, 220, 820, 240)
|
||||
UIRefresh(&referee_recv_info->referee_id, 1,UI_energy_line[0]);
|
||||
```
|
||||
|
||||
### 绘制power的初始值
|
||||
|
||||
```c
|
||||
UIFloatDraw(&UI_Energy[1], "sd5", UI_Graph_ADD, 8, UI_Color_Green, 18, 2, 2, 750, 230, 24000);
|
||||
```
|
||||
|
||||
### 绘制能量条的初始值
|
||||
|
||||
```c
|
||||
UILineDraw(&UI_Energy[2], "sd6", UI_Graph_ADD, 8, UI_Color_Pink, 30, 720, 160, 1020, 160);
|
||||
```
|
||||
|
||||
将两个图形打包发送
|
||||
|
||||
```
|
||||
UIRefresh(&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 UIChangeCheck(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)
|
||||
{
|
||||
UIFloatDraw(&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);
|
||||
UILineDraw(&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);
|
||||
UIRefresh(&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
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,424 @@
|
||||
/**
|
||||
* @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_ref.h"
|
||||
#include "stdio.h"
|
||||
#include "rm_referee.h"
|
||||
|
||||
// 包序号
|
||||
/********************************************删除操作*************************************
|
||||
**参数:_id 对应的id结构体
|
||||
Del_Operate 对应头文件删除操作
|
||||
Del_Layer 要删除的层 取值0-9
|
||||
*****************************************************************************************/
|
||||
void UIDelete(referee_id_t *_id, uint8_t Del_Operate, uint8_t Del_Layer)
|
||||
{
|
||||
static 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 UILineDraw(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 UIRectangleDraw(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 UICircleDraw(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 UIOvalDraw(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 UIArcDraw(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 UIFloatDraw(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 UIIntDraw(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 开始坐标
|
||||
|
||||
**参数:*graph Graph_Data类型变量指针,用于存放图形数据
|
||||
fmt需要显示的字符串
|
||||
此函数的实现和具体使用类似于printf函数
|
||||
**********************************************************************************************************/
|
||||
void UICharDraw(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, ...)
|
||||
{
|
||||
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;
|
||||
|
||||
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 UIGraphRefresh(referee_id_t *_id, int cnt, ...)
|
||||
{
|
||||
UI_GraphReFresh_t UI_GraphReFresh_data;
|
||||
Graph_Data_t graphData;
|
||||
|
||||
uint8_t temp_datalength = LEN_HEADER + LEN_CMDID + Interactive_Data_LEN_Head + UI_Operate_LEN_PerDraw * cnt + LEN_TAIL; // 计算交互数据长度
|
||||
|
||||
static uint8_t buffer[512]; // 交互数据缓存
|
||||
|
||||
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;
|
||||
memcpy(buffer, (uint8_t *)&UI_GraphReFresh_data, LEN_HEADER + LEN_CMDID + Interactive_Data_LEN_Head); // 将帧头、命令码、交互数据帧头三部分复制到缓存中
|
||||
|
||||
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推送字符(使更改生效)*********************************/
|
||||
void UICharRefresh(referee_id_t *_id, String_Data_t string_Data)
|
||||
{
|
||||
static 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
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
#ifndef REFEREE_UI_H
|
||||
#define REFEREE_UI_H
|
||||
|
||||
#include "stdarg.h"
|
||||
#include "stdint.h"
|
||||
#include "referee_protocol.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 UIDelete(referee_id_t *_id, uint8_t Del_Operate, uint8_t Del_Layer);
|
||||
|
||||
void UILineDraw(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 UIRectangleDraw(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 UICircleDraw(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 UIOvalDraw(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 UIArcDraw(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 UIFloatDraw(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 UIIntDraw(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 UICharDraw(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 UIGraphRefresh(referee_id_t *_id, int cnt, ...);
|
||||
|
||||
void UICharRefresh(referee_id_t *_id, String_Data_t string_Data);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,392 @@
|
||||
/**
|
||||
* @file referee_protocol.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_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 // 自定义交互数据长度,该长度决定了我方发送和他方接收,自定义交互数据协议更改时只需要更改此宏定义即可
|
||||
|
||||
#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交互数据****************************/
|
||||
|
||||
/* 图形数据 */
|
||||
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
|
||||
@@ -0,0 +1,299 @@
|
||||
/**
|
||||
* @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"
|
||||
#include "cmsis_os.h"
|
||||
|
||||
static Referee_Interactive_info_t *Interactive_data; // UI绘制需要的机器人状态数据
|
||||
static referee_info_t *referee_recv_info; // 接收到的裁判系统数据
|
||||
uint8_t UI_Seq; // 包序号,供整个referee文件使用
|
||||
// @todo 不应该使用全局变量
|
||||
|
||||
/**
|
||||
* @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 MyUIRefresh(referee_info_t *referee_recv_info, Referee_Interactive_info_t *_Interactive_data);
|
||||
static void UIChangeCheck(Referee_Interactive_info_t *_Interactive_data); // 模式切换检测
|
||||
static void RobotModeTest(Referee_Interactive_info_t *_Interactive_data); // 测试用函数,实现模式自动变化
|
||||
|
||||
referee_info_t *UITaskInit(UART_HandleTypeDef *referee_usart_handle, Referee_Interactive_info_t *UI_data)
|
||||
{
|
||||
referee_recv_info = RefereeInit(referee_usart_handle); // 初始化裁判系统的串口,并返回裁判系统反馈数据指针
|
||||
Interactive_data = UI_data; // 获取UI绘制需要的机器人状态数据
|
||||
referee_recv_info->init_flag = 1;
|
||||
return referee_recv_info;
|
||||
}
|
||||
|
||||
void UITask()
|
||||
{
|
||||
RobotModeTest(Interactive_data); // 测试用函数,实现模式自动变化,用于检查该任务和裁判系统是否连接正常
|
||||
MyUIRefresh(referee_recv_info, Interactive_data);
|
||||
}
|
||||
|
||||
static Graph_Data_t UI_shoot_line[10]; // 射击准线
|
||||
static Graph_Data_t UI_Energy[3]; // 电容能量条
|
||||
static 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 MyUIInit()
|
||||
{
|
||||
if (!referee_recv_info->init_flag)
|
||||
vTaskDelete(NULL); // 如果没有初始化裁判系统则直接删除ui任务
|
||||
while (referee_recv_info->GameRobotState.robot_id == 0)
|
||||
osDelay(100); // 若还未收到裁判系统数据,等待一段时间后再检查
|
||||
|
||||
DeterminRobotID(); // 确定ui要发送到的目标客户端
|
||||
UIDelete(&referee_recv_info->referee_id, UI_Data_Del_ALL, 0); // 清空UI
|
||||
|
||||
// 绘制发射基准线
|
||||
UILineDraw(&UI_shoot_line[0], "sl0", UI_Graph_ADD, 7, UI_Color_White, 3, 710, shoot_line_location[0], 1210, shoot_line_location[0]);
|
||||
UILineDraw(&UI_shoot_line[1], "sl1", UI_Graph_ADD, 7, UI_Color_White, 3, shoot_line_location[1], 340, shoot_line_location[1], 740);
|
||||
UILineDraw(&UI_shoot_line[2], "sl2", UI_Graph_ADD, 7, UI_Color_Yellow, 2, 810, shoot_line_location[2], 1110, shoot_line_location[2]);
|
||||
UILineDraw(&UI_shoot_line[3], "sl3", UI_Graph_ADD, 7, UI_Color_Yellow, 2, 810, shoot_line_location[3], 1110, shoot_line_location[3]);
|
||||
UILineDraw(&UI_shoot_line[4], "sl4", UI_Graph_ADD, 7, UI_Color_Yellow, 2, 810, shoot_line_location[4], 1110, shoot_line_location[4]);
|
||||
UIGraphRefresh(&referee_recv_info->referee_id, 5, UI_shoot_line[0], UI_shoot_line[1], UI_shoot_line[2], UI_shoot_line[3], UI_shoot_line[4]);
|
||||
|
||||
// 绘制车辆状态标志指示
|
||||
UICharDraw(&UI_State_sta[0], "ss0", UI_Graph_ADD, 8, UI_Color_Main, 15, 2, 150, 750, "chassis:");
|
||||
UICharRefresh(&referee_recv_info->referee_id, UI_State_sta[0]);
|
||||
UICharDraw(&UI_State_sta[1], "ss1", UI_Graph_ADD, 8, UI_Color_Yellow, 15, 2, 150, 700, "gimbal:");
|
||||
UICharRefresh(&referee_recv_info->referee_id, UI_State_sta[1]);
|
||||
UICharDraw(&UI_State_sta[2], "ss2", UI_Graph_ADD, 8, UI_Color_Orange, 15, 2, 150, 650, "shoot:");
|
||||
UICharRefresh(&referee_recv_info->referee_id, UI_State_sta[2]);
|
||||
UICharDraw(&UI_State_sta[3], "ss3", UI_Graph_ADD, 8, UI_Color_Pink, 15, 2, 150, 600, "frict:");
|
||||
UICharRefresh(&referee_recv_info->referee_id, UI_State_sta[3]);
|
||||
UICharDraw(&UI_State_sta[4], "ss4", UI_Graph_ADD, 8, UI_Color_Pink, 15, 2, 150, 550, "lid:");
|
||||
UICharRefresh(&referee_recv_info->referee_id, UI_State_sta[4]);
|
||||
|
||||
// 绘制车辆状态标志,动态
|
||||
// 由于初始化时xxx_last_mode默认为0,所以此处对应UI也应该设为0时对应的UI,防止模式不变的情况下无法置位flag,导致UI无法刷新
|
||||
UICharDraw(&UI_State_dyn[0], "sd0", UI_Graph_ADD, 8, UI_Color_Main, 15, 2, 270, 750, "zeroforce");
|
||||
UICharRefresh(&referee_recv_info->referee_id, UI_State_dyn[0]);
|
||||
UICharDraw(&UI_State_dyn[1], "sd1", UI_Graph_ADD, 8, UI_Color_Yellow, 15, 2, 270, 700, "zeroforce");
|
||||
UICharRefresh(&referee_recv_info->referee_id, UI_State_dyn[1]);
|
||||
UICharDraw(&UI_State_dyn[2], "sd2", UI_Graph_ADD, 8, UI_Color_Orange, 15, 2, 270, 650, "off");
|
||||
UICharRefresh(&referee_recv_info->referee_id, UI_State_dyn[2]);
|
||||
UICharDraw(&UI_State_dyn[3], "sd3", UI_Graph_ADD, 8, UI_Color_Pink, 15, 2, 270, 600, "off");
|
||||
UICharRefresh(&referee_recv_info->referee_id, UI_State_dyn[3]);
|
||||
UICharDraw(&UI_State_dyn[4], "sd4", UI_Graph_ADD, 8, UI_Color_Pink, 15, 2, 270, 550, "open ");
|
||||
UICharRefresh(&referee_recv_info->referee_id, UI_State_dyn[4]);
|
||||
|
||||
// 底盘功率显示,静态
|
||||
UICharDraw(&UI_State_sta[5], "ss5", UI_Graph_ADD, 7, UI_Color_Green, 18, 2, 620, 230, "Power:");
|
||||
UICharRefresh(&referee_recv_info->referee_id, UI_State_sta[5]);
|
||||
// 能量条框
|
||||
UIRectangleDraw(&UI_Energy[0], "ss6", UI_Graph_ADD, 7, UI_Color_Green, 2, 720, 140, 1220, 180);
|
||||
UIGraphRefresh(&referee_recv_info->referee_id, 1, UI_Energy[0]);
|
||||
|
||||
// 底盘功率显示,动态
|
||||
UIFloatDraw(&UI_Energy[1], "sd5", UI_Graph_ADD, 8, UI_Color_Green, 18, 2, 2, 750, 230, 24000);
|
||||
// 能量条初始状态
|
||||
UILineDraw(&UI_Energy[2], "sd6", UI_Graph_ADD, 8, UI_Color_Pink, 30, 720, 160, 1020, 160);
|
||||
UIGraphRefresh(&referee_recv_info->referee_id, 2, UI_Energy[1], UI_Energy[2]);
|
||||
}
|
||||
|
||||
// 测试用函数,实现模式自动变化,用于检查该任务和裁判系统是否连接正常
|
||||
static uint8_t count = 0;
|
||||
static uint16_t count1 = 0;
|
||||
static void RobotModeTest(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 MyUIRefresh(referee_info_t *referee_recv_info, Referee_Interactive_info_t *_Interactive_data)
|
||||
{
|
||||
UIChangeCheck(_Interactive_data);
|
||||
// chassis
|
||||
if (_Interactive_data->Referee_Interactive_Flag.chassis_flag == 1)
|
||||
{
|
||||
switch (_Interactive_data->chassis_mode)
|
||||
{
|
||||
case CHASSIS_ZERO_FORCE:
|
||||
UICharDraw(&UI_State_dyn[0], "sd0", UI_Graph_Change, 8, UI_Color_Main, 15, 2, 270, 750, "zeroforce");
|
||||
break;
|
||||
case CHASSIS_ROTATE:
|
||||
UICharDraw(&UI_State_dyn[0], "sd0", UI_Graph_Change, 8, UI_Color_Main, 15, 2, 270, 750, "rotate ");
|
||||
// 此处注意字数对齐问题,字数相同才能覆盖掉
|
||||
break;
|
||||
case CHASSIS_NO_FOLLOW:
|
||||
UICharDraw(&UI_State_dyn[0], "sd0", UI_Graph_Change, 8, UI_Color_Main, 15, 2, 270, 750, "nofollow ");
|
||||
break;
|
||||
case CHASSIS_FOLLOW_GIMBAL_YAW:
|
||||
UICharDraw(&UI_State_dyn[0], "sd0", UI_Graph_Change, 8, UI_Color_Main, 15, 2, 270, 750, "follow ");
|
||||
break;
|
||||
}
|
||||
UICharRefresh(&referee_recv_info->referee_id, UI_State_dyn[0]);
|
||||
_Interactive_data->Referee_Interactive_Flag.chassis_flag = 0;
|
||||
}
|
||||
// gimbal
|
||||
if (_Interactive_data->Referee_Interactive_Flag.gimbal_flag == 1)
|
||||
{
|
||||
switch (_Interactive_data->gimbal_mode)
|
||||
{
|
||||
case GIMBAL_ZERO_FORCE:
|
||||
{
|
||||
UICharDraw(&UI_State_dyn[1], "sd1", UI_Graph_Change, 8, UI_Color_Yellow, 15, 2, 270, 700, "zeroforce");
|
||||
break;
|
||||
}
|
||||
case GIMBAL_FREE_MODE:
|
||||
{
|
||||
UICharDraw(&UI_State_dyn[1], "sd1", UI_Graph_Change, 8, UI_Color_Yellow, 15, 2, 270, 700, "free ");
|
||||
break;
|
||||
}
|
||||
case GIMBAL_GYRO_MODE:
|
||||
{
|
||||
UICharDraw(&UI_State_dyn[1], "sd1", UI_Graph_Change, 8, UI_Color_Yellow, 15, 2, 270, 700, "gyro ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
UICharRefresh(&referee_recv_info->referee_id, UI_State_dyn[1]);
|
||||
_Interactive_data->Referee_Interactive_Flag.gimbal_flag = 0;
|
||||
}
|
||||
// shoot
|
||||
if (_Interactive_data->Referee_Interactive_Flag.shoot_flag == 1)
|
||||
{
|
||||
UICharDraw(&UI_State_dyn[2], "sd2", UI_Graph_Change, 8, UI_Color_Pink, 15, 2, 270, 650, _Interactive_data->shoot_mode == SHOOT_ON ? "on " : "off");
|
||||
UICharRefresh(&referee_recv_info->referee_id, UI_State_dyn[2]);
|
||||
_Interactive_data->Referee_Interactive_Flag.shoot_flag = 0;
|
||||
}
|
||||
// friction
|
||||
if (_Interactive_data->Referee_Interactive_Flag.friction_flag == 1)
|
||||
{
|
||||
UICharDraw(&UI_State_dyn[3], "sd3", UI_Graph_Change, 8, UI_Color_Pink, 15, 2, 270, 600, _Interactive_data->friction_mode == FRICTION_ON ? "on " : "off");
|
||||
UICharRefresh(&referee_recv_info->referee_id, UI_State_dyn[3]);
|
||||
_Interactive_data->Referee_Interactive_Flag.friction_flag = 0;
|
||||
}
|
||||
// lid
|
||||
if (_Interactive_data->Referee_Interactive_Flag.lid_flag == 1)
|
||||
{
|
||||
UICharDraw(&UI_State_dyn[4], "sd4", UI_Graph_Change, 8, UI_Color_Pink, 15, 2, 270, 550, _Interactive_data->lid_mode == LID_OPEN ? "open " : "close");
|
||||
UICharRefresh(&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)
|
||||
{
|
||||
UIFloatDraw(&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);
|
||||
UILineDraw(&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);
|
||||
UIGraphRefresh(&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 UIChangeCheck(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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef REFEREE_H
|
||||
#define REFEREE_H
|
||||
|
||||
#include "rm_referee.h"
|
||||
#include "robot_def.h"
|
||||
|
||||
/**
|
||||
* @brief 初始化裁判系统交互任务(UI和多机通信)
|
||||
*
|
||||
*/
|
||||
referee_info_t *UITaskInit(UART_HandleTypeDef *referee_usart_handle, Referee_Interactive_info_t *UI_data);
|
||||
|
||||
/**
|
||||
* @brief 在referee task之前调用,添加在freertos.c中
|
||||
*
|
||||
*/
|
||||
void MyUIInit();
|
||||
|
||||
/**
|
||||
* @brief 裁判系统交互任务(UI和多机通信)
|
||||
*
|
||||
*/
|
||||
void UITask();
|
||||
|
||||
#endif // REFEREE_H
|
||||
@@ -0,0 +1,149 @@
|
||||
/**
|
||||
* @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 "task.h"
|
||||
#include "daemon.h"
|
||||
#include "bsp_log.h"
|
||||
#include "cmsis_os.h"
|
||||
|
||||
#define RE_RX_BUFFER_SIZE 255u // 裁判系统接收缓冲区大小
|
||||
|
||||
static USARTInstance *referee_usart_instance; // 裁判系统串口实例
|
||||
static DaemonInstance *referee_daemon; // 裁判系统守护进程
|
||||
static referee_info_t referee_info; // 裁判系统数据
|
||||
|
||||
/**
|
||||
* @brief 读取裁判数据,中断中读取保证速度
|
||||
* @param buff: 读取到的裁判系统原始数据
|
||||
* @retval 是否对正误判断做处理
|
||||
* @attention 在此判断帧头和CRC校验,无误再写入数据,不重复判断帧头
|
||||
*/
|
||||
static void JudgeReadData(uint8_t *buff)
|
||||
{
|
||||
uint16_t judge_length; // 统计一帧数据长度
|
||||
if (buff == NULL) // 空数据包,则不作任何处理
|
||||
return;
|
||||
|
||||
// 写入帧头数据(5-byte),用于判断是否开始存储裁判数据
|
||||
memcpy(&referee_info.FrameHeader, buff, LEN_HEADER);
|
||||
|
||||
// 判断帧头数据(0)是否为0xA5
|
||||
if (buff[SOF] == REFEREE_SOF)
|
||||
{
|
||||
// 帧头CRC8校验
|
||||
if (Verify_CRC8_Check_Sum(buff, LEN_HEADER) == TRUE)
|
||||
{
|
||||
// 统计一帧数据长度(byte),用于CR16校验
|
||||
judge_length = buff[DATA_LENGTH] + LEN_HEADER + LEN_CMDID + LEN_TAIL;
|
||||
// 帧尾CRC16校验
|
||||
if (Verify_CRC16_Check_Sum(buff, judge_length) == TRUE)
|
||||
{
|
||||
// 2个8位拼成16位int
|
||||
referee_info.CmdID = (buff[6] << 8 | buff[5]);
|
||||
// 解析数据命令码,将数据拷贝到相应结构体中(注意拷贝数据的长度)
|
||||
// 第8个字节开始才是数据 data=7
|
||||
switch (referee_info.CmdID)
|
||||
{
|
||||
case ID_game_state: // 0x0001
|
||||
memcpy(&referee_info.GameState, (buff + DATA_Offset), LEN_game_state);
|
||||
break;
|
||||
case ID_game_result: // 0x0002
|
||||
memcpy(&referee_info.GameResult, (buff + DATA_Offset), LEN_game_result);
|
||||
break;
|
||||
case ID_game_robot_survivors: // 0x0003
|
||||
memcpy(&referee_info.GameRobotHP, (buff + DATA_Offset), LEN_game_robot_HP);
|
||||
break;
|
||||
case ID_event_data: // 0x0101
|
||||
memcpy(&referee_info.EventData, (buff + DATA_Offset), LEN_event_data);
|
||||
break;
|
||||
case ID_supply_projectile_action: // 0x0102
|
||||
memcpy(&referee_info.SupplyProjectileAction, (buff + DATA_Offset), LEN_supply_projectile_action);
|
||||
break;
|
||||
case ID_game_robot_state: // 0x0201
|
||||
memcpy(&referee_info.GameRobotState, (buff + DATA_Offset), LEN_game_robot_state);
|
||||
break;
|
||||
case ID_power_heat_data: // 0x0202
|
||||
memcpy(&referee_info.PowerHeatData, (buff + DATA_Offset), LEN_power_heat_data);
|
||||
break;
|
||||
case ID_game_robot_pos: // 0x0203
|
||||
memcpy(&referee_info.GameRobotPos, (buff + DATA_Offset), LEN_game_robot_pos);
|
||||
break;
|
||||
case ID_buff_musk: // 0x0204
|
||||
memcpy(&referee_info.BuffMusk, (buff + DATA_Offset), LEN_buff_musk);
|
||||
break;
|
||||
case ID_aerial_robot_energy: // 0x0205
|
||||
memcpy(&referee_info.AerialRobotEnergy, (buff + DATA_Offset), LEN_aerial_robot_energy);
|
||||
break;
|
||||
case ID_robot_hurt: // 0x0206
|
||||
memcpy(&referee_info.RobotHurt, (buff + DATA_Offset), LEN_robot_hurt);
|
||||
break;
|
||||
case ID_shoot_data: // 0x0207
|
||||
memcpy(&referee_info.ShootData, (buff + DATA_Offset), LEN_shoot_data);
|
||||
break;
|
||||
case ID_student_interactive: // 0x0301 syhtodo接收代码未测试
|
||||
memcpy(&referee_info.ReceiveData, (buff + DATA_Offset), LEN_receive_data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 首地址加帧长度,指向CRC16下一字节,用来判断是否为0xA5,从而判断一个数据包是否有多帧数据
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*裁判系统串口接收回调函数,解析数据 */
|
||||
static void RefereeRxCallback()
|
||||
{
|
||||
DaemonReload(referee_daemon);
|
||||
JudgeReadData(referee_usart_instance->recv_buff);
|
||||
}
|
||||
// 裁判系统丢失回调函数,重新初始化裁判系统串口
|
||||
static void RefereeLostCallback(void *arg)
|
||||
{
|
||||
USARTServiceInit(referee_usart_instance);
|
||||
LOGWARNING("[rm_ref] lost referee data");
|
||||
}
|
||||
|
||||
/* 裁判系统通信初始化 */
|
||||
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; // mx 255(u8)
|
||||
referee_usart_instance = USARTRegister(&conf);
|
||||
|
||||
Daemon_Init_Config_s daemon_conf = {
|
||||
.callback = RefereeLostCallback,
|
||||
.owner_id = referee_usart_instance,
|
||||
.reload_count = 30, // 0.3s没有收到数据,则认为丢失,重启串口接收
|
||||
};
|
||||
referee_daemon = DaemonRegister(&daemon_conf);
|
||||
|
||||
return &referee_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 裁判系统数据发送函数
|
||||
* @param
|
||||
*/
|
||||
void RefereeSend(uint8_t *send, uint16_t tx_len)
|
||||
{
|
||||
USARTSend(referee_usart_instance, send, tx_len, USART_TRANSFER_DMA);
|
||||
osDelay(115);
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
#ifndef RM_REFEREE_H
|
||||
#define RM_REFEREE_H
|
||||
|
||||
#include "usart.h"
|
||||
#include "referee_protocol.h"
|
||||
#include "robot_def.h"
|
||||
#include "bsp_usart.h"
|
||||
#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,必须和本机器人同颜色
|
||||
} 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;
|
||||
|
||||
uint8_t init_flag;
|
||||
|
||||
} 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 裁判系统通信初始化,该函数会初始化裁判系统串口,开启中断
|
||||
*
|
||||
* @param referee_usart_handle 串口handle,C板一般用串口6
|
||||
* @return referee_info_t* 返回裁判系统反馈的数据,包括热量/血量/状态等
|
||||
*/
|
||||
referee_info_t *RefereeInit(UART_HandleTypeDef *referee_usart_handle);
|
||||
|
||||
/**
|
||||
* @brief UI绘制和交互数的发送接口,由UI绘制任务和多机通信函数调用
|
||||
* @note 内部包含了一个实时系统的延时函数,这是因为裁判系统接收CMD数据至高位10Hz
|
||||
*
|
||||
* @param send 发送数据首地址
|
||||
* @param tx_len 发送长度
|
||||
*/
|
||||
void RefereeSend(uint8_t *send, uint16_t tx_len);
|
||||
|
||||
#endif // !REFEREE_H
|
||||
Reference in New Issue
Block a user