mirror of
https://gitee.com/dlmu-cone/bf_original_balance_chassis
synced 2026-07-24 03:27:45 +08:00
Merge remote-tracking branch 'origin/master'
# Conflicts: # .vscode/launch.json # application/gimbal/gimbal.c # application/robot.c # bsp/usart/bsp_usart.c # bsp/usart/bsp_usart.h # modules/master_machine/master_process.c # modules/master_machine/seasky_protocol.c
This commit is contained in:
@@ -12,12 +12,15 @@
|
||||
#include "bsp_usart.h"
|
||||
#include "usart.h"
|
||||
#include "seasky_protocol.h"
|
||||
#include "daemon.h"
|
||||
#include "bsp_log.h"
|
||||
|
||||
static Vision_Recv_s recv_data;
|
||||
// @todo:由于后续需要进行IMU-Cam的硬件触发采集控制,因此可能需要将发送设置为定时任务,或由IMU采集完成产生的中断唤醒的任务,
|
||||
// 后者显然更nice,使得时间戳对齐. 因此,在send_data中设定其他的标志位数据,让ins_task填充姿态值.
|
||||
// static Vision_Send_s send_data;
|
||||
static USARTInstance *vision_usart_instance;
|
||||
static DaemonInstance *vision_daemon_instance;
|
||||
|
||||
/**
|
||||
* @brief 接收解包回调函数,将在bsp_usart.c中被usart rx callback调用
|
||||
@@ -27,9 +30,23 @@ static USARTInstance *vision_usart_instance;
|
||||
static void DecodeVision()
|
||||
{
|
||||
static uint16_t flag_register;
|
||||
DaemonReload(vision_daemon_instance); // 喂狗
|
||||
get_protocol_info(vision_usart_instance->recv_buff, &flag_register, (uint8_t *)&recv_data.pitch);
|
||||
|
||||
// TODO: code to resolve flag_register;
|
||||
PrintLog("decode vision");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 离线回调函数,将在daemon.c中被daemon task调用
|
||||
* @attention 由于HAL库的设计问题,串口开启DMA接收之后同时发送有概率出现__HAL_LOCK()导致的死锁,使得无法
|
||||
* 进入接收中断.通过daemon判断数据更新,重新调用服务启动函数以解决此问题.
|
||||
*
|
||||
* @param id vision_usart_instance的地址,此处没用.
|
||||
*/
|
||||
static void VisionOfflineCallback(void *id)
|
||||
{
|
||||
USARTServiceInit(vision_usart_instance);
|
||||
}
|
||||
|
||||
/* 视觉通信初始化 */
|
||||
@@ -39,8 +56,16 @@ Vision_Recv_s *VisionInit(UART_HandleTypeDef *_handle)
|
||||
conf.module_callback = DecodeVision;
|
||||
conf.recv_buff_size = VISION_RECV_SIZE;
|
||||
conf.usart_handle = _handle;
|
||||
|
||||
vision_usart_instance = USARTRegister(&conf);
|
||||
|
||||
// 为master process注册daemon,用于判断视觉通信是否离线
|
||||
Daemon_Init_Config_s daemon_conf = {
|
||||
.callback = VisionOfflineCallback, // 离线时调用的回调函数,会重启串口接收
|
||||
.owner_id = vision_usart_instance,
|
||||
.reload_count = 10,
|
||||
};
|
||||
vision_daemon_instance = DaemonRegister(&daemon_conf);
|
||||
|
||||
return &recv_data;
|
||||
}
|
||||
|
||||
@@ -59,13 +84,11 @@ void VisionSend(Vision_Send_s *send)
|
||||
static uint8_t send_buff[VISION_SEND_SIZE];
|
||||
static uint16_t tx_len;
|
||||
// TODO: code to set flag_register
|
||||
flag_register = 0x0001;
|
||||
|
||||
// 将数据转化为seasky协议的数据包
|
||||
get_protocol_send_data(0x02, flag_register, &send->yaw, 3, send_buff, &tx_len);
|
||||
USARTSend(vision_usart_instance, send_buff, tx_len,USART_TRANSFER_IT);
|
||||
// if(vision_usart_instance->usart_handle->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
|
||||
// {HAL_UARTEx_ReceiveToIdle_DMA(vision_usart_instance->usart_handle, vision_usart_instance->recv_buff, vision_usart_instance->recv_buff_size);
|
||||
// __HAL_DMA_DISABLE_IT(vision_usart_instance->usart_handle->hdmarx, DMA_IT_HT);
|
||||
|
||||
// }
|
||||
USARTSend(vision_usart_instance, send_buff, tx_len, USART_TRANSFER_DMA); // 和视觉通信使用IT,防止和接收使用的DMA冲突
|
||||
// 此处为HAL设计的缺陷,DMASTOP会停止发送和接收,导致再也无法进入接收中断.
|
||||
// 也可在发送完成中断中重新启动DMA接收,但较为复杂.因此,此处使用IT发送.
|
||||
// 若使用了daemon,则也可以使用DMA发送.
|
||||
}
|
||||
@@ -56,7 +56,7 @@ static uint8_t protocol_heade_Check(protocol_rm_struct *pro, uint8_t *rx_buf)
|
||||
pro->header.sof = rx_buf[0];
|
||||
if (CRC8_Check_Sum(&rx_buf[0], 4))
|
||||
{
|
||||
pro->header.data_length = ((rx_buf[2] << 8) | rx_buf[1]);
|
||||
pro->header.data_length = (rx_buf[2] << 8) | rx_buf[1];
|
||||
pro->header.crc_check = rx_buf[3];
|
||||
pro->cmd_id = (rx_buf[5] << 8) | rx_buf[4];
|
||||
return 1;
|
||||
@@ -125,9 +125,9 @@ uint16_t get_protocol_info(uint8_t *rx_buf, // 接收到的原始数据
|
||||
if (CRC16_Check_Sum(&rx_buf[0], date_length))
|
||||
{
|
||||
*flags_register = (rx_buf[7] << 8) | rx_buf[6];
|
||||
memcpy(rx_data, rx_buf + 8, (pro.header.data_length - 2));
|
||||
memcpy(rx_data, rx_buf + 8, pro.header.data_length - 2);
|
||||
return pro.cmd_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2,78 +2,11 @@
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
|
||||
/* 消息初始化用 */
|
||||
static char pname[MAX_EVENT_COUNT][MAX_EVENT_NAME_LEN + 1];
|
||||
static char sname[MAX_EVENT_COUNT][MAX_EVENT_NAME_LEN + 1];
|
||||
static void *p_ptr[MAX_EVENT_COUNT] = {NULL};
|
||||
static void **s_pptr[MAX_EVENT_COUNT] = {NULL}; // 因为要修改指针,所以需要二重指针
|
||||
|
||||
/* ----------------------------------第三方指针传递版的实现,deprecated----------------------------------- */
|
||||
|
||||
void MessageInit()
|
||||
{
|
||||
// pub必须唯一,即消息名称不能重复,不得有多个pub发布相同消息名称
|
||||
// 对每一个subscriber,寻找相同消息名称的publisher,可能有多个sub从相同pub获取消息
|
||||
for (size_t i = 0; i < MAX_EVENT_COUNT; ++i)
|
||||
{
|
||||
if (s_pptr[i] != NULL)
|
||||
{
|
||||
for (size_t j = 0; j < MAX_EVENT_COUNT; ++j) // 遍历publisher
|
||||
{
|
||||
if (p_ptr[j] != NULL) // 不为空
|
||||
{
|
||||
if (strcmp(sname[i], pname[j]) == 0) // 比较消息名是否一致
|
||||
{
|
||||
*s_pptr[i] = p_ptr[j]; // 将sub的指针指向pub的数据
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // 到结尾,退出
|
||||
{
|
||||
while (1)
|
||||
; // 如果你卡在这里,说明没有找到消息发布者!请确认消息名称是否键入错误
|
||||
}
|
||||
}
|
||||
}
|
||||
else // 说明已经遍历完所有的subs
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 传入数据地址 */
|
||||
void PublisherRegister(char *name, void *data)
|
||||
{
|
||||
static uint8_t idx;
|
||||
for (size_t i = 0; i < idx; ++i)
|
||||
{
|
||||
if (strcmp(pname[i], name) == 0)
|
||||
while (1)
|
||||
; // 运行至此说明pub的消息发布名称冲突
|
||||
}
|
||||
strcpy(pname[idx], name);
|
||||
p_ptr[idx++] = data;
|
||||
}
|
||||
|
||||
/* 注意传入的是指针的地址,传参时使用&对数据指针取地址 */
|
||||
void SubscribeEvent(char *name, void **data_ptr)
|
||||
{
|
||||
static uint8_t idx;
|
||||
strcpy(sname[idx], name);
|
||||
s_pptr[idx++] = data_ptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ----------------------------------链表-队列版的实现----------------------------------- */
|
||||
|
||||
/* message_center是fake head node,是方便链表编写的技巧,这样就不需要处理链表头的特殊情况 */
|
||||
static Publisher_t message_center = {
|
||||
.event_name = "Message_Manager",
|
||||
.first_subs = NULL,
|
||||
.next_event_node = NULL
|
||||
};
|
||||
.next_event_node = NULL};
|
||||
|
||||
static void CheckName(char *name)
|
||||
{
|
||||
@@ -112,18 +45,18 @@ Subscriber_t *SubRegister(char *name, uint8_t data_len)
|
||||
{ // 给消息队列的每一个元素分配空间,queue里保存的实际上是数据执指针,这样可以兼容不同的数据长度
|
||||
ret->queue[i] = malloc(sizeof(data_len));
|
||||
}
|
||||
//如果是第一个订阅者,特殊处理一下
|
||||
if(node->first_subs==NULL)
|
||||
// 如果是第一个订阅者,特殊处理一下
|
||||
if (node->first_subs == NULL)
|
||||
{
|
||||
node->first_subs=ret;
|
||||
node->first_subs = ret;
|
||||
return ret;
|
||||
}
|
||||
// 遍历订阅者链表,直到到达尾部
|
||||
Subscriber_t *sub = node->first_subs; // 作为iterator
|
||||
while (sub->next_subs_queue) // 遍历订阅了该事件的订阅者链表
|
||||
while (sub->next_subs_queue) // 遍历订阅了该事件的订阅者链表
|
||||
{
|
||||
sub = sub->next_subs_queue; // 移动到下一个订阅者,遇到空指针停下,说明到了链表尾部
|
||||
}
|
||||
}
|
||||
sub->next_subs_queue = ret; // 把刚刚创建的订阅者接上
|
||||
return ret;
|
||||
}
|
||||
@@ -157,6 +90,7 @@ Publisher_t *PubRegister(char *name, uint8_t data_len)
|
||||
if (strcmp(node->event_name, name) == 0) // 如果已经注册了相同的事件,直接返回结点指针
|
||||
{
|
||||
CheckLen(data_len, node->data_len);
|
||||
node->pub_registered_flag = 1;
|
||||
return node;
|
||||
}
|
||||
} // 遍历完发现尚未创建name对应的事件
|
||||
@@ -165,6 +99,7 @@ Publisher_t *PubRegister(char *name, uint8_t data_len)
|
||||
memset(node->next_event_node, 0, sizeof(Publisher_t));
|
||||
node->next_event_node->data_len = data_len;
|
||||
strcpy(node->next_event_node->event_name, name);
|
||||
node->pub_registered_flag = 1;
|
||||
return node->next_event_node;
|
||||
}
|
||||
|
||||
@@ -189,7 +124,7 @@ uint8_t PubPushMessage(Publisher_t *pub, void *data_ptr)
|
||||
while (iter)
|
||||
{
|
||||
if (iter->temp_size == QUEUE_SIZE) // 如果队列已满,则需要删除最老的数据(头部),再填入
|
||||
{
|
||||
{
|
||||
// 队列头索引前移动,相当于抛弃前一个位置的数据,被抛弃的位置稍后会被写入新的数据
|
||||
iter->front_idx = (iter->front_idx + 1) % QUEUE_SIZE;
|
||||
iter->temp_size--; // 相当于出队,size-1
|
||||
|
||||
@@ -19,30 +19,6 @@
|
||||
#define MAX_EVENT_COUNT 12 // 最多支持的事件数量
|
||||
#define QUEUE_SIZE 1
|
||||
|
||||
/**
|
||||
* @brief 在所有应用初始化结束之后调用,当作app的"回调函数"
|
||||
*
|
||||
*/
|
||||
void MessageInit();
|
||||
|
||||
/**
|
||||
* @brief 注册成为消息发布者
|
||||
*
|
||||
* @param name 消息标识名,注意不要超过MAX_EVENT_NAME_LEN
|
||||
* @param data 发布者的数据地址
|
||||
*/
|
||||
void PublisherRegister(char *name, void *data);
|
||||
|
||||
/**
|
||||
* @brief 订阅消息,成为消息订阅者
|
||||
*
|
||||
* @param name 消息标识名
|
||||
* @param data 保存数据的指针的地址,注意这是一个二级指针,传入的时候对数据指针取地址(&)
|
||||
*/
|
||||
void SubscribeEvent(char *name, void **data);
|
||||
|
||||
#endif // !PUBSUB_H
|
||||
|
||||
typedef struct mqt
|
||||
{
|
||||
/* 用数组模拟FIFO队列 */
|
||||
@@ -69,6 +45,7 @@ typedef struct ent
|
||||
Subscriber_t *first_subs;
|
||||
/* 指向下一个Publisher的指针 */
|
||||
struct ent *next_event_node;
|
||||
uint8_t pub_registered_flag; // 用于标记该发布者是否已经注册
|
||||
} Publisher_t;
|
||||
|
||||
/**
|
||||
@@ -105,3 +82,5 @@ uint8_t SubGetMessage(Subscriber_t *sub, void *data_ptr);
|
||||
* @return uint8_t 新消息成功推送给几个订阅者
|
||||
*/
|
||||
uint8_t PubPushMessage(Publisher_t *pub, void *data_ptr);
|
||||
|
||||
#endif // !PUBSUB_H
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "dji_motor.h"
|
||||
#include "general_def.h"
|
||||
#include "bsp_log.h"
|
||||
|
||||
static uint8_t idx = 0; // register idx,是该文件的全局电机索引,在注册时使用
|
||||
|
||||
@@ -32,16 +33,6 @@ static CANInstance sender_assignment[6] = {
|
||||
*/
|
||||
static uint8_t sender_enable_flag[6] = {0};
|
||||
|
||||
/**
|
||||
* @brief 当注册的电机id冲突时,会进入这个函数并提示冲突的ID
|
||||
* @todo 通过segger jlink 发送日志
|
||||
*/
|
||||
static void IDcrash_Handler(uint8_t conflict_motor_idx, uint8_t temp_motor_idx)
|
||||
{
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 根据电调/拨码开关上的ID,根据说明书的默认id分配方式计算发送ID和接收ID,
|
||||
* 并对电机进行分组以便处理多电机控制命令
|
||||
@@ -79,7 +70,10 @@ static void MotorSenderGrouping(DJIMotorInstance *motor, CAN_Init_Config_s *conf
|
||||
for (size_t i = 0; i < idx; ++i)
|
||||
{
|
||||
if (dji_motor_instance[i]->motor_can_instance->can_handle == config->can_handle && dji_motor_instance[i]->motor_can_instance->rx_id == config->rx_id)
|
||||
IDcrash_Handler(i, idx);
|
||||
{
|
||||
LOGERROR("[dji_motor] ID crash. Check in debug mode, add dji_motor_instance to watch to get more information."); // 后续可以把id和CAN打印出来
|
||||
while (1); // 6020的id 1-4和2006/3508的id 5-8会发生冲突(若有注册,即1!5,2!6,3!7,4!8) (1!5!,LTC! (((不是)
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -103,7 +97,10 @@ static void MotorSenderGrouping(DJIMotorInstance *motor, CAN_Init_Config_s *conf
|
||||
for (size_t i = 0; i < idx; ++i)
|
||||
{
|
||||
if (dji_motor_instance[i]->motor_can_instance->can_handle == config->can_handle && dji_motor_instance[i]->motor_can_instance->rx_id == config->rx_id)
|
||||
IDcrash_Handler(i, idx);
|
||||
{
|
||||
LOGERROR("[dji_motor] ID crash. Check in debug mode, add dji_motor_instance to watch to get more information.");
|
||||
while (1); // 6020的id 1-4和2006/3508的id 5-8会发生冲突(若有注册,即1!5,2!6,3!7,4!8)
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -126,6 +123,7 @@ static void DecodeDJIMotor(CANInstance *_instance)
|
||||
static DJI_Motor_Measure_s *measure;
|
||||
rxbuff = _instance->rx_buff;
|
||||
// 这里对can instance的id进行了强制转换,从而获得电机的instance实例地址
|
||||
// _instance指针指向的id是对应电机instance的地址,通过强制转换为电机instance的指针,再通过->运算符访问电机的成员motor_measure,最后取地址获得指针
|
||||
measure = &(((DJIMotorInstance *)_instance->id)->motor_measure); // measure要多次使用,保存指针减小访存开销
|
||||
|
||||
// 解析数据并对电流和速度进行滤波,电机的反馈报文具体格式见电机说明手册
|
||||
@@ -138,7 +136,7 @@ static void DecodeDJIMotor(CANInstance *_instance)
|
||||
CURRENT_SMOOTH_COEF * (float)((int16_t)(rxbuff[4] << 8 | rxbuff[5]));
|
||||
measure->temperate = rxbuff[6];
|
||||
|
||||
// 多圈角度计算,前提是两次采样间电机转过的角度小于180°,高速转动时可能会出现问题,自己画个图就清楚计算过程了
|
||||
// 多圈角度计算,前提是假设两次采样间电机转过的角度小于180°,自己画个图就清楚计算过程了
|
||||
if (measure->ecd - measure->last_ecd > 4096)
|
||||
measure->total_round--;
|
||||
else if (measure->ecd - measure->last_ecd < -4096)
|
||||
@@ -190,8 +188,7 @@ void DJIMotorChangeFeed(DJIMotorInstance *motor, Closeloop_Type_e loop, Feedback
|
||||
}
|
||||
else
|
||||
{
|
||||
while (1)
|
||||
; // LOOP TYPE ERROR!!!检查是否传入了正确的LOOP类型,或发生了指针越界
|
||||
LOGERROR("[dji_motor] loop type error, check memory access and func param");// 检查是否传入了正确的LOOP类型,或发生了指针越界
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
> 1. 给不同的电机设置不同的低通滤波器惯性系数而不是统一使用宏
|
||||
> 2. 为M2006和M3508增加开环的零位校准函数
|
||||
|
||||
---
|
||||
|
||||
> 建议将电机的反馈频率通过RoboMaster Assistant统一设置为500Hz。当前默认的`MotorTask()`执行频率为500Hz,若不修改电机反馈频率可能导致单条总线挂载的电机数量有限,且容易出现帧错误和仲裁失败的情况。
|
||||
|
||||
## 总览和封装说明
|
||||
|
||||
> 如果你不需要理解该模块的工作原理,你只需要查看这一小节。
|
||||
@@ -19,7 +23,7 @@ dji_motor模块对DJI智能电机,包括M2006,M3508以及GM6020进行了详
|
||||
|
||||
2. ==速度环为角速度,单位为**度/每秒**(deg/sec)==
|
||||
|
||||
3. ==电流环为mA==
|
||||
3. ==电流环为A==
|
||||
|
||||
4. ==GM6020的输入设定为**力矩**,待测量(-30000~30000)==
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ static void LKMotorDecode(CANInstance *_instance)
|
||||
static LKMotor_Measure_t *measure;
|
||||
static uint8_t *rx_buff;
|
||||
rx_buff = _instance->rx_buff;
|
||||
measure = &((LKMotorInstance *)_instance)->measure; // 通过caninstance保存的id获取对应的motorinstance
|
||||
measure = &(((LKMotorInstance *)_instance->id)->measure); // 通过caninstance保存的id获取对应的motorinstance
|
||||
|
||||
measure->last_ecd = measure->ecd;
|
||||
measure->ecd = (uint16_t)((rx_buff[7] << 8) | rx_buff[6]);
|
||||
@@ -59,7 +59,10 @@ LKMotorInstance *LKMotorInit(Motor_Init_Config_s *config)
|
||||
motor->motor_can_ins = CANRegister(&config->can_init_config);
|
||||
|
||||
if (idx == 0) // 用第一个电机的can instance发送数据
|
||||
{
|
||||
sender_instance = motor->motor_can_ins;
|
||||
sender_instance->tx_id = 0x280; // 修改tx_id为0x280,用于多电机发送,不用管其他LKMotorInstance的tx_id,它们仅作初始化用
|
||||
}
|
||||
|
||||
LKMotorEnable(motor);
|
||||
lkmotor_instance[idx++] = motor;
|
||||
|
||||
@@ -2,4 +2,6 @@
|
||||
|
||||
这是瓴控电机的模块封装说明文档。关于LK电机的控制报文和反馈报文值,详见LK电机的说明文档,由于电机实例已经自带三环PID计算,一般来说**我们能用到的只有单电机的力矩指令和多电机指令。**
|
||||
|
||||
注意LK电机在使用多电机发送的时候,只支持一条总线上至多4个电机,多电机模式下LK仅支持发送id 0x280为接收ID为0x140+id.
|
||||
注意LK电机在使用多电机发送的时候,只支持一条总线上至多4个电机,多电机模式下LK仅支持发送id 0x280为接收ID为0x140+id.
|
||||
|
||||
要设置为多电机模式,请通过串口连接电机,并使用该文件夹下的LK motor tool.exe进行配置。
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -0,0 +1,3 @@
|
||||
# referee
|
||||
|
||||
当前模块组织较为混乱,后续统一为多机通信+裁判系统信息接收+UI绘制。UI绘制和多机通信的发送部分在referee任务中以一定的频率运行,信息的接收通过中断完成。
|
||||
@@ -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
|
||||
}
|
||||
|
||||
77
modules/referee/referee_UI.h
Normal file
77
modules/referee/referee_UI.h
Normal file
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
|
||||
10
modules/referee/referee_communication.h
Normal file
10
modules/referee/referee_communication.h
Normal file
@@ -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
|
||||
397
modules/referee/referee_def.h
Normal file
397
modules/referee/referee_def.h
Normal file
@@ -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
|
||||
@@ -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,USART_TRANSFER_IT);
|
||||
/* 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;
|
||||
}
|
||||
60
modules/referee/rm_referee.h
Normal file
60
modules/referee/rm_referee.h
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user