diff --git a/.vscode/launch.json b/.vscode/launch.json index 5ebcf1e..1fef058 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -16,7 +16,7 @@ ".\\openocd.cfg", // 配置文件已经在根目录提供,若要修改以此类推 ], // path to your gcc-arm-none-eabi/arm-none-eabi-gdb.exe,如果在cortex-debug的设置中写入了全局路径,这里不需要再写 - "gdbPath": "D:\\gcc-arm-none-eabi\\bin\\arm-none-eabi-gdb.exe", + // "gdbPath": "D:\\gcc-arm-none-eabi\\bin\\arm-none-eabi-gdb.exe", //"preLaunchTask": "build task",//先运行Build任务,取消注释即可使用 }, // 使用j-link时的参考配置 diff --git a/.vscode/settings.json b/.vscode/settings.json index a1c3110..33c9f63 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,53 +1,8 @@ { - "C_Cpp.default.configurationProvider": "ms-vscode.makefile-tools", "files.associations": { - "arm_math.h": "c", - "task.h": "c", - "main.h": "c", - "cmsis_os.h": "c", - "freertos.h": "c", - "bmi088driver.h": "c", - "user_lib.h": "c", - "mpu_armv7.h": "c", - "stm32f4xx_hal.h": "c", - "stm32f4xx_hal_conf.h": "c", - "stm32_hal_legacy.h": "c", - "stm32f4xx.h": "c", - "cstdint": "c", - "tim.h": "c", - "struct_typedef.h": "c", - "bsp_can.h": "c", - "stdint.h": "c", - "bsp_temperature.h": "c", - "bsp_rc.h": "c", - "remote_control.h": "c", - "bsp_usart.h": "c", - "led_task.h": "c", - "can_receive.h": "c", - "can_process.h": "c", - "can.h": "c", - "stdlib.h": "c", - "lk9025.h": "c", - "dji_motor.h": "c", - "ht04.h": "c", - "controller.h": "c", "memory.h": "c", - "motor_task.h": "c", - "functional": "c", - "stdexcept": "c", - "tuple": "c", - "typeinfo": "c", - "chrono": "c", - "complex": "c", - "usb_device.h": "c", - "vofa_protocol.h": "c", - "master_process.h": "c", "stdint-gcc.h": "c", - "string.h": "c", - "motor_def.h": "c", - "stdio.h": "c", - "segger_rtt_conf.h": "c", - "segger_rtt.h": "c", - "bsp_log.h": "c" - }, + "led_task.h": "c", + "stdinf.h": "c" + },, } \ No newline at end of file diff --git a/HAL_N_Middlewares/Src/main.c b/HAL_N_Middlewares/Src/main.c index b0f421d..b8c8b3f 100644 --- a/HAL_N_Middlewares/Src/main.c +++ b/HAL_N_Middlewares/Src/main.c @@ -38,6 +38,7 @@ #include "can.h" #include "dji_motor.h" #include "motor_task.h" +#include "referee.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ @@ -118,13 +119,15 @@ int main(void) RC_init(&huart3); DWT_Init(168); Motor_Init_Config_s config = { - .motor_type = M3508, + .motor_type = M2006, .can_init_config = { .can_handle = &hcan1, .tx_id = 1}, .controller_setting_init_config = {.angle_feedback_source = MOTOR_FEED, .close_loop_type = SPEED_LOOP | CURRENT_LOOP, .speed_feedback_source = MOTOR_FEED, .reverse_flag = MOTOR_DIRECTION_NORMAL}, .controller_param_init_config = {.current_PID = {.Improve = 0, .Kp = 1, .Ki = 0, .Kd = 0, .DeadBand = 0, .MaxOut = 4000}, .speed_PID = {.Improve = 0, .Kp = 1, .Ki = 0, .Kd = 0, .DeadBand = 0, .MaxOut = 4000}}}; dji_motor_instance *djimotor = DJIMotorInit(config); + + referee_init(&huart6); /* USER CODE END 2 */ /* Call init function for freertos objects (in freertos.c) */ diff --git a/Makefile b/Makefile index 5b3867e..ebfc700 100644 --- a/Makefile +++ b/Makefile @@ -118,6 +118,7 @@ modules/motor/HT04.c \ modules/motor/LK9025.c \ modules/mode/step_motor.c \ modules/motor/motor_task.c \ +modules/referee/crc.c \ modules/referee/referee.c \ modules/referee/referee_UI.c \ modules/referee/referee_communication.c \ diff --git a/bsp/bsp_buzzer.h b/bsp/bsp_buzzer.h index 75e7c56..e93adec 100644 --- a/bsp/bsp_buzzer.h +++ b/bsp/bsp_buzzer.h @@ -4,7 +4,7 @@ #include void buzzer_init(); -extern void buzzer_on(uint16_t psc, uint16_t pwm, uint8_t level); +extern void buzzer_on(uint16_t psc, uint16_t pwm,uint8_t level); extern void buzzer_off(void); #endif diff --git a/bsp/bsp_usart.c b/bsp/bsp_usart.c index e33b0e7..3470139 100644 --- a/bsp/bsp_usart.c +++ b/bsp/bsp_usart.c @@ -10,6 +10,7 @@ */ #include "bsp_usart.h" #include "stdlib.h" +#include "memory.h" /* usart service instance, modules' info would be recoreded here using USARTRegister() */ /* usart服务实例,所有注册了usart的模块信息会被保存在这里 */ @@ -66,6 +67,8 @@ void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) if (huart == instance[i]->usart_handle) { instance[i]->module_callback(); + memset(instance[i]->recv_buff,0,instance[i]->recv_buff_size); + HAL_UARTEx_ReceiveToIdle_DMA(instance[i]->usart_handle, instance[i]->recv_buff, instance[i]->recv_buff_size); __HAL_DMA_DISABLE_IT(instance[i]->usart_handle->hdmarx, DMA_IT_HT); break; diff --git a/bsp/bsp_usart.h b/bsp/bsp_usart.h index ed4d2f1..9e8ff29 100644 --- a/bsp/bsp_usart.h +++ b/bsp/bsp_usart.h @@ -5,7 +5,7 @@ #include "main.h" #define DEVICE_USART_CNT 3 // C板至多分配3个串口 -#define USART_RXBUFF_LIMIT 128 // if your protocol needs bigger buff, modify here +#define USART_RXBUFF_LIMIT 256 // if your protocol needs bigger buff, modify here /* application callback,which resolves specific protocol,解析协议的回调函数 */ typedef void (*usart_module_callback)(); diff --git a/bsp/struct_typedef.h b/bsp/struct_typedef.h new file mode 100644 index 0000000..e2211fe --- /dev/null +++ b/bsp/struct_typedef.h @@ -0,0 +1,29 @@ +#ifndef STRUCT_TYPEDEF_H +#define STRUCT_TYPEDEF_H + +typedef signed char int8_t; +typedef signed short int int16_t; + +#ifndef _INT32_T_DECLARED +typedef signed int int32_t; +#define _INT32_T_DECLARED +#endif + +typedef signed long long int64_t; + +/* exact-width unsigned integer types */ +typedef unsigned char uint8_t; +typedef unsigned short int uint16_t; + +#ifndef _UINT32_T_DECLARED +typedef unsigned int uint32_t; +#define _UINT32_T_DECLARED +#endif + +typedef unsigned long long uint64_t; +typedef unsigned char bool_t; +typedef float float; +typedef double fp64; + +#endif + diff --git a/modules/motor/LK9025.h b/modules/motor/LK9025.h index e6086ba..bc0fca6 100644 --- a/modules/motor/LK9025.h +++ b/modules/motor/LK9025.h @@ -1,6 +1,7 @@ #ifndef LK9025_H #define LK9025_H +#include #include "bsp_can.h" #include "controller.h" #include "motor_def.h" diff --git a/modules/referee/crc.c b/modules/referee/crc.c new file mode 100644 index 0000000..a0cd359 --- /dev/null +++ b/modules/referee/crc.c @@ -0,0 +1,194 @@ +#include "crc.h" +#include +//裁判系统官方CRC校验 + +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); +} diff --git a/modules/referee/crc.h b/modules/referee/crc.h new file mode 100644 index 0000000..e97535a --- /dev/null +++ b/modules/referee/crc.h @@ -0,0 +1,18 @@ +#ifndef __CRC_H_ +#define __CRC_H_ + +#include + +#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 diff --git a/modules/referee/referee.c b/modules/referee/referee.c index e69de29..6e75f30 100644 --- a/modules/referee/referee.c +++ b/modules/referee/referee.c @@ -0,0 +1,140 @@ +#include "referee.h" +#include "string.h" +#include "crc.h" +#include "bsp_usart.h" +#include "dma.h" + + +//参考深圳大学 Infantry_X-master +#define RE_RX_BUFFER_SIZE 200 + +// static usart_instance referee_usart_instance; +usart_instance referee_usart_instance; + +/**************裁判系统数据******************/ +referee_info_t referee_info; +uint8_t Judge_Self_ID; //当前机器人的ID +uint16_t Judge_SelfClient_ID; //发送者机器人对应的客户端ID + + + +static void ReceiveCallback() +{ + Judge_Read_Data(referee_usart_instance.recv_buff); +} + +void referee_init(UART_HandleTypeDef *referee_usart_handle) +{ + referee_usart_instance.module_callback = ReceiveCallback; + referee_usart_instance.usart_handle = referee_usart_handle; + referee_usart_instance.recv_buff_size = RE_RX_BUFFER_SIZE; + USARTRegister(&referee_usart_instance); +} + + +/** + * @brief 读取裁判数据,中断中读取保证速度 + * @param 缓存数据 + * @retval 是否对正误判断做处理 + * @attention 在此判断帧头和CRC校验,无误再写入数据,不重复判断帧头 + */ +void Judge_Read_Data(uint8_t *ReadFromUsart) +{ + uint16_t judge_length; //统计一帧数据长度 +// referee_info.CmdID = 0; //数据命令码解析 + //空数据包,则不作任何处理 + if (ReadFromUsart == NULL) + { + return -1; + } + + //写入帧头数据(5-byte),用于判断是否开始存储裁判数据 + memcpy(&referee_info.FrameHeader, ReadFromUsart, LEN_HEADER); + + //判断帧头数据(0)是否为0xA5 + if (ReadFromUsart[SOF] == JUDGE_FRAME_HEADER) + { + //帧头CRC8校验 + if (Verify_CRC8_Check_Sum(ReadFromUsart, LEN_HEADER) == TRUE) + { + //统计一帧数据长度(byte),用于CR16校验 + judge_length = ReadFromUsart[DATA_LENGTH] + LEN_HEADER + LEN_CMDID + LEN_TAIL; + //帧尾CRC16校验 + if (Verify_CRC16_Check_Sum(ReadFromUsart, judge_length) == TRUE) + { + // 2个8位拼成16位int + referee_info.CmdID = (ReadFromUsart[6] << 8 | ReadFromUsart[5]); + //解析数据命令码,将数据拷贝到相应结构体中(注意拷贝数据的长度) + //第8个字节开始才是数据 data=7 + switch (referee_info.CmdID) + { + case ID_game_state: // 0x0001 + memcpy(&referee_info.GameState, (ReadFromUsart + DATA), LEN_game_state); + break; + + case ID_game_result: // 0x0002 + memcpy(&referee_info.GameResult, (ReadFromUsart + DATA), LEN_game_result); + break; + + case ID_game_robot_survivors: // 0x0003 + memcpy(&referee_info.GameRobotHP, (ReadFromUsart + DATA), LEN_game_robot_HP); + break; + + case ID_event_data: // 0x0101 + memcpy(&referee_info.EventData, (ReadFromUsart + DATA), LEN_event_data); + break; + + case ID_supply_projectile_action: // 0x0102 + memcpy(&referee_info.SupplyProjectileAction, (ReadFromUsart + DATA), LEN_supply_projectile_action); + break; + + case ID_game_robot_state: // 0x0201 + memcpy(&referee_info.GameRobotStat,(ReadFromUsart + DATA),LEN_game_robot_state); + break; + case ID_power_heat_data: // 0x0202 + memcpy(&referee_info.PowerHeatData, (ReadFromUsart + DATA), LEN_power_heat_data); + break; + + case ID_game_robot_pos: // 0x0203 + memcpy(&referee_info.GameRobotPos, (ReadFromUsart + DATA), LEN_game_robot_pos); + break; + + case ID_buff_musk: // 0x0204 + memcpy(&referee_info.BuffMusk, (ReadFromUsart + DATA), LEN_buff_musk); + break; + + case ID_aerial_robot_energy: // 0x0205 + memcpy(&referee_info.AerialRobotEnergy, (ReadFromUsart + DATA), LEN_aerial_robot_energy); + break; + + case ID_robot_hurt: // 0x0206 + memcpy(&referee_info.RobotHurt, (ReadFromUsart + DATA), LEN_robot_hurt); + break; + + case ID_shoot_data: // 0x0207 + memcpy(&referee_info.ShootData, (ReadFromUsart + DATA), LEN_shoot_data); + // JUDGE_ShootNumCount();//发弹量统计 + break; + } + } + } + //首地址加帧长度,指向CRC16下一字节,用来判断是否为0xA5,用来判断一个数据包是否有多帧数据 + if (*(ReadFromUsart + sizeof(xFrameHeader) + LEN_CMDID + referee_info.FrameHeader.DataLength + LEN_TAIL) == 0xA5) + { + //如果一个数据包出现了多帧数据,则再次读取 + Judge_Read_Data(ReadFromUsart + sizeof(xFrameHeader) + LEN_CMDID + referee_info.FrameHeader.DataLength + LEN_TAIL); + + } + } +} + +/** + * @brief 读取瞬时功率 + * @param void + * @retval 实时功率值 + * @attention + */ +float JUDGE_fGetChassisPower(void) +{ + return (referee_info.PowerHeatData.chassis_power); +} diff --git a/modules/referee/referee.h b/modules/referee/referee.h index 7f74007..c93d30f 100644 --- a/modules/referee/referee.h +++ b/modules/referee/referee.h @@ -1,9 +1,9 @@ /** * @file referee.h - * @author your name (you@domain.com) + * @author kidneygood (you@domain.com) * @brief * @version 0.1 - * @date 2022-11-04 + * @date 2022-11-18 * * @copyright Copyright (c) 2022 * @@ -15,8 +15,340 @@ #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; + +extern referee_info_t referee_info; + +void referee_init(UART_HandleTypeDef *referee_usart_handle); +void Judge_Read_Data(uint8_t *ReadFromUsart); +float JUDGE_fGetChassisPower(void); + +#endif // !REFEREE_H + + -#endif // !REFEREE_H \ No newline at end of file