did_GB_2025.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  1. #include "did_GB_2025.h"
  2. #include <stdio.h>
  3. /************************** 工具函数:字节序转换 **************************/
  4. void uav_put_uint16_le(uint16_t val, uint8_t *buf) {
  5. if (buf == NULL) return;
  6. buf[0] = val & 0xFF;
  7. buf[1] = (val >> 8) & 0xFF;
  8. }
  9. void uav_put_uint32_le(uint32_t val, uint8_t *buf) {
  10. if (buf == NULL) return;
  11. buf[0] = val & 0xFF;
  12. buf[1] = (val >> 8) & 0xFF;
  13. buf[2] = (val >> 16) & 0xFF;
  14. buf[3] = (val >> 24) & 0xFF;
  15. }
  16. uint16_t uav_get_uint16_le(const uint8_t *buf) {
  17. if (buf == NULL) return 0;
  18. return (uint16_t)buf[0] | ((uint16_t)buf[1] << 8);
  19. }
  20. uint32_t uav_get_uint32_le(const uint8_t *buf) {
  21. if (buf == NULL) return 0;
  22. return (uint32_t)buf[0] | ((uint32_t)buf[1] << 8) |
  23. ((uint32_t)buf[2] << 16) | ((uint32_t)buf[3] << 24);
  24. }
  25. /************************** 编码函数实现 **************************/
  26. uint32_t uav_enc_lat(double lat, bool is_valid)
  27. {
  28. // 未知或不可用
  29. if (!is_valid || isnan(lat) || isinf(lat)) {
  30. return 0xFFFFFFFF; // 0xFFFFFFFF
  31. }
  32. // 范围检查:经度±180°,纬度±90°
  33. if (lat > 90.0 || lat < -90.0) {
  34. return 0xFFFFFFFF;
  35. }
  36. // 编码:实际值 × 10^7,四舍五入
  37. double scaled = lat * LAT_LON_SCALE;
  38. int32_t enc = (int32_t)(scaled + (scaled >= 0 ? 0.5 : -0.5));
  39. return (uint32_t)enc; // 保持负数的位模式
  40. }
  41. /**
  42. * 经纬度编码(表3序号006/008)
  43. * 编码值 = 实际值 × 10^7,32位小端序
  44. * 西经、南纬以负值表示,未知/不可用时取"FFFFFFFF"
  45. */
  46. uint32_t uav_enc_lon(double lon, bool is_valid) {
  47. // 未知或不可用
  48. if (!is_valid || isnan(lon) || isinf(lon)) {
  49. return 0xFFFFFFFF; // 0xFFFFFFFF
  50. }
  51. // 范围检查:经度±180°,纬度±90°
  52. if (lon > 180.0 || lon < -180.0) {
  53. return 0xFFFFFFFF;
  54. }
  55. // 编码:实际值 × 10^7,四舍五入
  56. double scaled = lon * LAT_LON_SCALE;
  57. int32_t enc = (int32_t)(scaled + (scaled >= 0 ? 0.5 : -0.5));
  58. return (uint32_t)enc; // 保持负数的位模式
  59. }
  60. /**
  61. * 遥控站高度/大地高度/气压高度编码(表3序号007/013/014)
  62. * 编码值 = (实际值 + 1000) × 2,16位小端序
  63. * 分辨率0.5m,未知/不可用时取"0"
  64. */
  65. uint16_t uav_enc_geo_alt(double alt, bool is_valid) {
  66. // 未知或不可用
  67. if (!is_valid || isnan(alt) || isinf(alt)) {
  68. return 0; // 0
  69. }
  70. // 计算:(alt + 1000) × 2,四舍五入
  71. double calc = (alt + GEO_ALT_OFFSET) * GEO_ALT_SCALE;
  72. // 范围检查:必须能表示为16位无符号整数
  73. if (calc < 0.0 || calc > 65534.0) { // 保留0xFFFF,但标准用0表示未知
  74. return 0;
  75. }
  76. return (uint16_t)(calc + 0.5);
  77. }
  78. /**
  79. * 相对高度编码(表3序号011)
  80. * 编码值 = (实际值 + 9000) × 2,16位小端序
  81. * 分辨率0.5m,未知/不可用时取"0"
  82. */
  83. uint16_t uav_enc_rel_alt(double alt, bool is_valid) {
  84. // 未知或不可用
  85. if (!is_valid || isnan(alt) || isinf(alt)) {
  86. return 0; // 0
  87. }
  88. // 计算:(alt + 9000) × 2,四舍五入
  89. double calc = (alt + REL_ALT_OFFSET) * REL_ALT_SCALE;
  90. // 范围检查:-9000m ~ +23767m对应0~65534
  91. if (calc < 0.0 || calc > 65534.0) {
  92. return 0;
  93. }
  94. return (uint16_t)(calc + 0.5);
  95. }
  96. /**
  97. * 航迹角编码(表3序号009)
  98. * 编码值 = 实际值 × 10,16位小端序
  99. * 有效值0~3599,分辨率0.1°,未知/不可用时取"FFFF"
  100. */
  101. uint16_t uav_enc_track_angle(double angle, bool is_valid) {
  102. // 未知或不可用
  103. if (!is_valid || isnan(angle) || isinf(angle)) {
  104. return 0xFFFF; // 0xFFFF
  105. }
  106. // 有效范围:0~359.9°
  107. if (angle < 0.0 || angle >= 360.0) {
  108. return 0xFFFF;
  109. }
  110. // 编码:×10,向下取整(标准要求)
  111. uint16_t enc = (uint16_t)(angle * ANGLE_SPEED_SCALE);
  112. // 确保不超过3599
  113. return enc > 3599 ? 3599 : enc;
  114. }
  115. /**
  116. * 地速编码(表3序号010)
  117. * 编码值 = 实际值 × 10,16位小端序
  118. * 分辨率0.1m/s,向下取整,未知/不可用时取"FFFF"
  119. */
  120. uint16_t uav_enc_ground_speed(double speed, bool is_valid) {
  121. // 未知或不可用
  122. if (!is_valid || isnan(speed) || isinf(speed)) {
  123. return 0xFFFF; // 0xFFFF
  124. }
  125. // 速度不能为负
  126. if (speed < 0.0) {
  127. return 0xFFFF;
  128. }
  129. // 编码:×10,向下取整(标准要求)
  130. return (uint16_t)(speed * ANGLE_SPEED_SCALE);
  131. }
  132. /**
  133. * 垂直速度编码(表3序号012)
  134. * 第1位为标志位:0上升,1下降
  135. * 编码值0~127,实际值×2,分辨率0.5m/s
  136. * 未知/不可用时取"FF"
  137. */
  138. uint8_t uav_enc_vert_speed(double v_speed, bool is_valid) {
  139. // 未知或不可用
  140. if (!is_valid || isnan(v_speed) || isinf(v_speed)) {
  141. return 0xFF; // 0xFF
  142. }
  143. // 方向标志
  144. uint8_t enc = (v_speed < 0.0) ? 0x80 : 0x00;
  145. // 取绝对值
  146. double abs_speed = fabs(v_speed);
  147. // 范围限制:最大63.5 m/s (127/2)
  148. if (abs_speed > 63.5) {
  149. abs_speed = 63.5;
  150. }
  151. // 编码:×2,四舍五入
  152. uint8_t val = (uint8_t)(abs_speed * VERT_SPEED_SCALE + 0.5);
  153. return enc | (val & 0x7F);
  154. }
  155. /**
  156. * 时间戳编码(表3序号020)
  157. * Unix时间戳(ms),6字节小端序
  158. * 未知/不可用时取全0
  159. */
  160. void uav_enc_timestamp(uint64_t timestamp, bool is_valid, uint8_t *buf) {
  161. if (buf == NULL) return;
  162. // 未知或不可用
  163. if (!is_valid) {
  164. memset(buf, 0, 6);
  165. return;
  166. }
  167. // 6字节小端序
  168. buf[0] = (uint8_t)(timestamp >> 0);
  169. buf[1] = (uint8_t)(timestamp >> 8);
  170. buf[2] = (uint8_t)(timestamp >> 16);
  171. buf[3] = (uint8_t)(timestamp >> 24);
  172. buf[4] = (uint8_t)(timestamp >> 32);
  173. buf[5] = (uint8_t)(timestamp >> 40);
  174. }
  175. /**
  176. * 版本号编码(表1)
  177. * 第1~3位固定为"001",第4~8位为从版本号0~63
  178. */
  179. uint8_t uav_set_packet_version() {
  180. uint8_t ver = VERSION_ENCODE;
  181. return ver;
  182. }
  183. /************************** 解码函数实现 **************************/
  184. /**
  185. * 经纬度解码
  186. */
  187. double uav_dec_lat_lon(uint32_t enc_val) {
  188. if (enc_val == 0xFFFFFFFF) return 0.0;
  189. // 按有符号整数解释
  190. int32_t signed_val = (int32_t)enc_val;
  191. return (double)signed_val / LAT_LON_SCALE;
  192. }
  193. /**
  194. * 大地高度/气压高度解码
  195. */
  196. double uav_dec_geo_alt(uint16_t enc_val) {
  197. if (enc_val == 0) return 0.0;
  198. return (double)enc_val / GEO_ALT_SCALE - GEO_ALT_OFFSET;
  199. }
  200. /**
  201. * 相对高度解码
  202. */
  203. double uav_dec_rel_alt(uint16_t enc_val) {
  204. if (enc_val == 0) return 0.0;
  205. return (double)enc_val / REL_ALT_SCALE - REL_ALT_OFFSET;
  206. }
  207. /**
  208. * 航迹角解码
  209. */
  210. double uav_dec_track_angle(uint16_t enc_val) {
  211. if (enc_val == 0xFFFF) return -1.0;
  212. return (double)enc_val / ANGLE_SPEED_SCALE;
  213. }
  214. /**
  215. * 地速解码
  216. */
  217. double uav_dec_ground_speed(uint16_t enc_val) {
  218. if (enc_val == 0xFFFF) return -1.0;
  219. return (double)enc_val / ANGLE_SPEED_SCALE;
  220. }
  221. /**
  222. * 垂直速度解码
  223. */
  224. double uav_dec_vert_speed(uint8_t enc_val) {
  225. if (enc_val == 0xFF) return 0.0;
  226. double val = (double)(enc_val & 0x7F) / VERT_SPEED_SCALE;
  227. return (enc_val & 0x80) ? -val : val;
  228. }
  229. /**
  230. * 时间戳解码
  231. */
  232. uint64_t uav_dec_timestamp(const uint8_t *buf) {
  233. if (buf == NULL) return 0;
  234. // 检查是否全0(未知)
  235. bool is_unknown = true;
  236. for (int i = 0; i < 6; i++) {
  237. if (buf[i] != 0) {
  238. is_unknown = false;
  239. break;
  240. }
  241. }
  242. if (is_unknown) return 0;
  243. // 6字节小端序合并
  244. uint64_t ts = 0;
  245. ts |= (uint64_t)buf[0] << 0;
  246. ts |= (uint64_t)buf[1] << 8;
  247. ts |= (uint64_t)buf[2] << 16;
  248. ts |= (uint64_t)buf[3] << 24;
  249. ts |= (uint64_t)buf[4] << 32;
  250. ts |= (uint64_t)buf[5] << 40;
  251. return ts;
  252. }
  253. /************************** 辅助函数:原始数据初始化 **************************/
  254. void uav_identification_data_init(UavIdentificationData *data) {
  255. if (data == NULL) return;
  256. memset(data, 0, sizeof(UavIdentificationData));
  257. memset(data->unique_code, FILL_CHAR, 21);
  258. memset(data->register_id, FILL_CHAR, 9);
  259. // 所有有效性标志初始化为false
  260. data->is_station_pos_valid = false;
  261. data->is_uav_pos_valid = false;
  262. data->is_station_alt_valid = false;
  263. data->is_uav_geo_alt_valid = false;
  264. data->is_track_angle_valid = false;
  265. data->is_ground_speed_valid = false;
  266. data->is_timestamp_valid = false;
  267. data->is_rel_alt_valid = false;
  268. data->is_vert_speed_valid = false;
  269. data->is_press_alt_valid = false;
  270. // 可选字段接收标志初始化为false
  271. data->flag_run_class = false;
  272. data->flag_rel_alt = false;
  273. data->flag_vert_speed = false;
  274. data->flag_press_alt = false;
  275. }
  276. /************************** 核心函数:组包 (可选 必选 都进行组包)**************************/
  277. int8_t uav_identification_pack(UavIdentificationPacket *packet, const UavIdentificationData *data) {
  278. if (packet == NULL || data == NULL) return -1;
  279. memset(packet, 0, sizeof(UavIdentificationPacket));
  280. // 1. 固定头部填充 0xFF + 0x20+ len + 3 data descr + N data
  281. packet->data_type = PACKET_DATA_TYPE; // 报头
  282. packet->version = uav_set_packet_version(); // 版本
  283. uint8_t *content_ptr = packet->content; // 实际报文内容
  284. // 无论是否合法都强制发送所有报文 非法的发非法值 也就是数据描述字节依次是 0xFF 0xFF 0xFE 最后一位是确定下一位是描述还是载荷
  285. /********** 第1字节:控制001~007项(按分类顺序填充) **********/
  286. packet->data_flag[0] = BYTE1_ALL_FIELDS | MARK_BYTE_NEXT; // 所有项强制发送(含可选003项)
  287. // 001-唯一产品识别码 - 大端序
  288. for (int i = 0; i < 20; i++) {
  289. content_ptr[i] = data->unique_code[19 - i]; // 单片机是小端序
  290. }
  291. content_ptr += 20;
  292. // 002-实名登记标志 - 大端序 op id ??? 保留后8 byte
  293. for (int i = 0; i < 8; i++) {
  294. content_ptr[i] = data->register_id[7 - i];
  295. }
  296. content_ptr += 8;
  297. // 003-运行类别(O,强制发送,无需判断使能标志)
  298. *content_ptr++ = (uint8_t)data->run_class;
  299. // 004-无人机分类(M)
  300. *content_ptr++ = (uint8_t)data->uav_type;
  301. // 005-遥控站位置类型(M)
  302. *content_ptr++ = (uint8_t)data->station_type;
  303. // 006-遥控站位置(M):经纬度编码+小端序 其实不用转也行 默认小端序
  304. uint32_t enc_sta_lon = uav_enc_lon(data->station_lon, data->is_station_pos_valid); // 接口里面其实
  305. uint32_t enc_sta_lat = uav_enc_lat(data->station_lat, data->is_station_pos_valid);
  306. uav_put_uint32_le(enc_sta_lon, content_ptr); content_ptr += 4;
  307. uav_put_uint32_le(enc_sta_lat, content_ptr); content_ptr += 4;
  308. // 007-遥控站高度(M):大地高度编码+小端序
  309. uint16_t enc_sta_alt = uav_enc_geo_alt(data->station_geo_alt, data->is_station_alt_valid);
  310. uav_put_uint16_le(enc_sta_alt, content_ptr); content_ptr += 2;
  311. /********** 第2字节:控制008~014项(按分类顺序填充) **********/
  312. packet->data_flag[1] = BYTE2_ALL_FIELDS | MARK_BYTE_NEXT; // 所有项强制发送(含可选011/012/014项)
  313. // 008-无人机位置(M):经纬度编码+小端序
  314. uint32_t enc_uav_lon = uav_enc_lon(data->uav_lon, data->is_uav_pos_valid);
  315. uint32_t enc_uav_lat = uav_enc_lat(data->uav_lat, data->is_uav_pos_valid);
  316. uav_put_uint32_le(enc_uav_lon, content_ptr); content_ptr += 4;
  317. uav_put_uint32_le(enc_uav_lat, content_ptr); content_ptr += 4;
  318. // 009-航迹角(M):编码+小端序
  319. uint16_t enc_angle = uav_enc_track_angle(data->track_angle, data->is_track_angle_valid);
  320. uav_put_uint16_le(enc_angle, content_ptr); content_ptr += 2;
  321. // 010-地速(M):编码+小端序
  322. uint16_t enc_speed = uav_enc_ground_speed(data->ground_speed, data->is_ground_speed_valid);
  323. uav_put_uint16_le(enc_speed, content_ptr); content_ptr += 2;
  324. // 011-相对高度(O,强制发送):编码+小端序
  325. uint16_t enc_rel_alt = uav_enc_rel_alt(data->uav_rel_alt, data->is_rel_alt_valid);
  326. uav_put_uint16_le(enc_rel_alt, content_ptr); content_ptr += 2;
  327. // 012-垂直速度(O,强制发送):编码
  328. uint8_t enc_vert_speed = uav_enc_vert_speed(data->uav_vert_speed, data->is_vert_speed_valid);
  329. *content_ptr++ = enc_vert_speed;
  330. // 013-无人机大地高度(M):编码+小端序
  331. uint16_t enc_uav_geo_alt = uav_enc_geo_alt(data->uav_geo_alt, data->is_uav_geo_alt_valid);
  332. uav_put_uint16_le(enc_uav_geo_alt, content_ptr); content_ptr += 2;
  333. // 014-气压高度(O,强制发送):编码+小端序
  334. uint16_t enc_press_alt = uav_enc_geo_alt(data->uav_press_alt, data->is_press_alt_valid);
  335. uav_put_uint16_le(enc_press_alt, content_ptr); content_ptr += 2;
  336. /********** 第3字节:控制015~021项(按分类顺序填充) **********/
  337. packet->data_flag[2] = BYTE3_ALL_FIELDS; // 所有项强制发送(均为必选)
  338. // 015-运行状态(M)
  339. *content_ptr++ = (uint8_t)data->run_state;
  340. // 016-坐标系类型(M)
  341. *content_ptr++ = (uint8_t)data->coord_type;
  342. // 017-水平精度(M)
  343. *content_ptr++ = data->hori_accuracy;
  344. // 018-垂直精度(M)
  345. *content_ptr++ = data->vert_accuracy;
  346. // 019-速度精度(M)
  347. *content_ptr++ = data->speed_accuracy;
  348. // 020-时间戳(M):6字节小端序
  349. uav_enc_timestamp(data->timestamp, data->is_timestamp_valid, content_ptr);
  350. content_ptr += 6;
  351. // 021-时间戳精度(M)
  352. *content_ptr++ = data->time_accuracy;
  353. // 2. 长度校验与赋值
  354. uint8_t content_len = (uint8_t)(content_ptr - packet->content);
  355. if (content_len == 0 || content_len > MAX_CONTENT_BYTES) return -2;
  356. packet->content_len = content_len; // 填充数据包长度
  357. return 0;
  358. }
  359. /************************** 核心函数:解包 (根据标识位选择解包字节)**************************/
  360. int8_t uav_identification_unpack(UavIdentificationData *data, const UavIdentificationPacket *packet) {
  361. if (data == NULL || packet == NULL) return -1;
  362. if (packet->data_type != PACKET_DATA_TYPE || packet->content_len == 0 || packet->content_len > MAX_CONTENT_BYTES) return -2;
  363. uav_identification_data_init(data);
  364. const uint8_t *content_ptr = packet->content;
  365. const uint8_t *data_flag = packet->data_flag;
  366. /********** 第1字节:解析001~007项 **********/
  367. // 001-唯一产品识别码(M,必须存在) 大端序 如果是小端序单片机需要进行端转换 否则不需要
  368. if (!(data_flag[0] & BYTE1_MASK_001)) return -3;
  369. memcpy(data->unique_code, content_ptr, 20);
  370. content_ptr += 20;
  371. // 002-实名登记标志(M,必须存在) 大端序
  372. if (!(data_flag[0] & BYTE1_MASK_002)) return -3;
  373. memcpy(data->register_id, content_ptr, 8);
  374. content_ptr += 8;
  375. // // 001-唯一产品识别码(M,必须存在) 大端序 -> 需要反转回小端
  376. // if (!(data_flag[0] & BYTE1_MASK_001)) return -3;
  377. // for (int i = 0; i < 20; i++) {
  378. // data->unique_code[i] = content_ptr[19 - i]; // 反转回来
  379. // }
  380. // content_ptr += 20;
  381. // // 002-实名登记标志(M,必须存在) 大端序 -> 需要反转回小端
  382. // if (!(data_flag[0] & BYTE1_MASK_002)) return -3;
  383. // for (int i = 0; i < 8; i++) {
  384. // data->register_id[i] = content_ptr[7 - i]; // 反转回来
  385. // }
  386. // content_ptr += 8;
  387. // 003-运行类别(O,收到则置位接收标志)
  388. if (data_flag[0] & BYTE1_MASK_003) {
  389. data->flag_run_class = true;
  390. data->run_class = (UavRunClass)*content_ptr++;
  391. }
  392. // 004-无人机分类(M,必须存在)
  393. if (!(data_flag[0] & BYTE1_MASK_004)) return -3;
  394. data->uav_type = (UavType)*content_ptr++;
  395. // 005-遥控站位置类型(M,必须存在)
  396. if (!(data_flag[0] & BYTE1_MASK_005)) return -3;
  397. data->station_type = (UavStationType)*content_ptr++;
  398. // 006-遥控站位置(M,必须存在)
  399. if (!(data_flag[0] & BYTE1_MASK_006)) return -3;
  400. uint32_t enc_sta_lon = uav_get_uint32_le(content_ptr); content_ptr +=4;
  401. uint32_t enc_sta_lat = uav_get_uint32_le(content_ptr); content_ptr +=4;
  402. data->station_lon = uav_dec_lat_lon(enc_sta_lon);
  403. data->station_lat = uav_dec_lat_lon(enc_sta_lat);
  404. data->is_station_pos_valid = (enc_sta_lon != 0xFFFFFFFF) && (enc_sta_lat != 0xFFFFFFFF);
  405. // 007-遥控站高度(M,必须存在)
  406. if (!(data_flag[0] & BYTE1_MASK_007)) return -3;
  407. uint16_t enc_sta_alt = uav_get_uint16_le(content_ptr); content_ptr +=2;
  408. data->station_geo_alt = uav_dec_geo_alt(enc_sta_alt);
  409. data->is_station_alt_valid = (enc_sta_alt != 0);
  410. /********** 第2字节:解析008~014项 **********/
  411. // 008-无人机位置(M,必须存在)
  412. if (!(data_flag[1] & BYTE2_MASK_008)) return -3;
  413. uint32_t enc_uav_lon = uav_get_uint32_le(content_ptr); content_ptr +=4;
  414. uint32_t enc_uav_lat = uav_get_uint32_le(content_ptr); content_ptr +=4;
  415. data->uav_lon = uav_dec_lat_lon(enc_uav_lon);
  416. data->uav_lat = uav_dec_lat_lon(enc_uav_lat);
  417. data->is_uav_pos_valid = (enc_uav_lon != 0xFFFFFFFF) && (enc_uav_lat != 0xFFFFFFFF);
  418. // 009-航迹角(M,必须存在)
  419. if (!(data_flag[1] & BYTE2_MASK_009)) return -3;
  420. uint16_t enc_angle = uav_get_uint16_le(content_ptr); content_ptr +=2;
  421. data->track_angle = uav_dec_track_angle(enc_angle);
  422. data->is_track_angle_valid = (enc_angle != 0xFFFF);
  423. // 010-地速(M,必须存在)
  424. if (!(data_flag[1] & BYTE2_MASK_010)) return -3;
  425. uint16_t enc_speed = uav_get_uint16_le(content_ptr); content_ptr +=2;
  426. data->ground_speed = uav_dec_ground_speed(enc_speed);
  427. data->is_ground_speed_valid = (enc_speed != 0xFFFF);
  428. // 011-相对高度(O,收到则置位接收标志)
  429. if (data_flag[1] & BYTE2_MASK_011) {
  430. data->flag_rel_alt = true;
  431. uint16_t enc_rel_alt = uav_get_uint16_le(content_ptr); content_ptr +=2;
  432. data->uav_rel_alt = uav_dec_rel_alt(enc_rel_alt);
  433. data->is_rel_alt_valid = (enc_rel_alt != 0);
  434. }
  435. // 012-垂直速度(O,收到则置位接收标志)
  436. if (data_flag[1] & BYTE2_MASK_012) {
  437. data->flag_vert_speed = true;
  438. uint8_t enc_vert = *content_ptr++;
  439. data->uav_vert_speed = uav_dec_vert_speed(enc_vert);
  440. data->is_vert_speed_valid = (enc_vert != 0xFF);
  441. }
  442. // 013-无人机大地高度(M,必须存在)
  443. if (!(data_flag[1] & BYTE2_MASK_013)) return -3;
  444. uint16_t enc_uav_geo = uav_get_uint16_le(content_ptr); content_ptr +=2;
  445. data->uav_geo_alt = uav_dec_geo_alt(enc_uav_geo);
  446. data->is_uav_geo_alt_valid = (enc_uav_geo != 0);
  447. // 014-气压高度(O,收到则置位接收标志)
  448. if (data_flag[1] & BYTE2_MASK_014) {
  449. data->flag_press_alt = true;
  450. uint16_t enc_press = uav_get_uint16_le(content_ptr); content_ptr +=2;
  451. data->uav_press_alt = uav_dec_geo_alt(enc_press);
  452. data->is_press_alt_valid = (enc_press != 0);
  453. }
  454. /********** 第3字节:解析015~021项 **********/
  455. // 015-运行状态(M,必须存在)
  456. if (!(data_flag[2] & BYTE3_MASK_015)) return -3;
  457. data->run_state = (UavRunState)*content_ptr++;
  458. // 016-坐标系类型(M,必须存在)
  459. if (!(data_flag[2] & BYTE3_MASK_016)) return -3;
  460. data->coord_type = (UavCoordType)*content_ptr++;
  461. // 017-水平精度(M,必须存在)
  462. if (!(data_flag[2] & BYTE3_MASK_017)) return -3;
  463. data->hori_accuracy = (UavHorizontalAccuracy_t)*content_ptr++;
  464. // 018-垂直精度(M,必须存在)
  465. if (!(data_flag[2] & BYTE3_MASK_018)) return -3;
  466. data->vert_accuracy = (UavVerticalAccuracy_t)*content_ptr++;
  467. // 019-速度精度(M,必须存在)
  468. if (!(data_flag[2] & BYTE3_MASK_019)) return -3;
  469. data->speed_accuracy = (UAVSpeedAccuracy_t)*content_ptr++;
  470. // 020-时间戳(M,必须存在)
  471. if (!(data_flag[2] & BYTE3_MASK_020)) return -3;
  472. data->timestamp = uav_dec_timestamp(content_ptr); content_ptr +=6;
  473. data->is_timestamp_valid = (data->timestamp != 0);
  474. // 021-时间戳精度(M,必须存在)
  475. if (!(data_flag[2] & BYTE3_MASK_021)) return -3;
  476. data->time_accuracy = (UavTimestampAccuracy_t)*content_ptr++;
  477. return 0;
  478. }
  479. /************************** 调试函数:打印数据包 **************************/
  480. void uav_identification_packet_print(const UavIdentificationPacket *packet) {
  481. if (packet == NULL) return;
  482. uint8_t major = VERSION_DECODE_MAJOR(packet->version);
  483. uint8_t minor = VERSION_DECODE_MINOR(packet->version);
  484. printf("==================== UAV Packet (GB46750-2025) ====================\n");
  485. printf("Data Type: 0x%02X | Version: V%d.%d\n",
  486. packet->data_type, major, minor);
  487. printf("Content Len: %d Byte | Data Flag: 0x%02X 0x%02X 0x%02X\n",
  488. packet->content_len, packet->data_flag[0], packet->data_flag[1], packet->data_flag[2]);
  489. printf("Content (Hex): ");
  490. for (int i = 0; i < packet->content_len; i++) {
  491. printf("%02X ", packet->content[i]);
  492. if ((i+1) % 16 == 0) printf("\n\t\t\t");
  493. }
  494. printf("\n===================================================================\n");
  495. }
  496. /************************** 调试函数:打印原始数据 **************************/
  497. void uav_identification_data_print(const UavIdentificationData *data) {
  498. if (data == NULL) return;
  499. printf("==================== UAV Raw Data (Decoded) ====================\n");
  500. // 身份信息
  501. printf("Unique Code: %s | Register Flag: %s\n", data->unique_code, data->register_id);
  502. printf("UAV Type: %d | Run State: %d | Coord Type: %d\n",
  503. data->uav_type, data->run_state, data->coord_type);
  504. // 位置信息
  505. printf("Station Lon: %.7f° | Lat: %.7f° | Alt: %.1fm (Valid: %d)\n",
  506. data->station_lon, data->station_lat, data->station_geo_alt, data->is_station_pos_valid);
  507. printf("UAV Lon: %.7f° | Lat: %.7f° | Geo Alt: %.1fm (Valid: %d)\n",
  508. data->uav_lon, data->uav_lat, data->uav_geo_alt, data->is_uav_pos_valid);
  509. // 运动信息
  510. printf("Track Angle: %.1f° (Valid: %d) | Ground Speed: %.1fm/s (Valid: %d)\n",
  511. data->track_angle, data->is_track_angle_valid, data->ground_speed, data->is_ground_speed_valid);
  512. // 精度信息
  513. printf("Hori Acc: %d | Vert Acc: %d | Speed Acc: %d\n",
  514. data->hori_accuracy, data->vert_accuracy, data->speed_accuracy);
  515. printf("Timestamp: %llums | Time Acc: %d (Valid: %d)\n",
  516. (unsigned long long)data->timestamp, data->time_accuracy, data->is_timestamp_valid);
  517. // 可选信息(强制发送,必然存在)
  518. printf("Run Class: %d (Received: %d)\n", data->run_class, data->flag_run_class);
  519. printf("Relative Alt: %.1fm (Valid: %d)\n", data->uav_rel_alt, data->is_rel_alt_valid);
  520. printf("Vert Speed: %.1fm/s (Valid: %d)\n", data->uav_vert_speed, data->is_vert_speed_valid);
  521. printf("Press Alt: %.1fm (Valid: %d)\n", data->uav_press_alt, data->is_press_alt_valid);
  522. printf("==================================================================\n");
  523. }