soft_can_yy.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692
  1. #include "board.h"
  2. #include "hpm_can_drv.h"
  3. #include "control_rate.h"
  4. #include "hpm_can_drv.h"
  5. #include "flight_mode.h"
  6. #include "helpler_funtions.h"
  7. #include "mode_gcs_tax_launch_run.h"
  8. #include "params.h"
  9. #include "soft_can.h"
  10. #include "soft_imu.h"
  11. #include "soft_time.h"
  12. #include "string.h"
  13. #include <math.h>
  14. #include "soft_can_yy.h"
  15. #include <stdint.h>
  16. static uint32_t last_tx_time = 0;
  17. static uint8_t tx_loop_on = 0;
  18. uint8_t status_broadcast = 0; // 广播当前指令状态位 默认b0-0未收到弹射准备
  19. static inline void memcpy_bigend(void *dst, const void *src, uint32_t length)
  20. {
  21. uint8_t *p_src = (uint8_t *)src;
  22. uint8_t *p_dst = (uint8_t *)dst;
  23. for (uint32_t i = 0; i < length; ++i)
  24. {
  25. p_dst[i] = p_src[length - i - 1];
  26. }
  27. }
  28. static inline void memcpy_smallend(void *dst, const void *src, uint32_t length)
  29. {
  30. uint8_t *p_src = (uint8_t *)src;
  31. uint8_t *p_dst = (uint8_t *)dst;
  32. for (uint32_t i = 0; i < length; ++i)
  33. {
  34. p_dst[i] = p_src[i];
  35. }
  36. }
  37. static struct yy_can_rx_msg_data __yy_can_data = {.txgl_yaw_sp = NAN, .txgl_alt_sp = NAN};
  38. const struct yy_can_rx_msg_data *yy_can_rx_data_get(void)
  39. {
  40. return &__yy_can_data;
  41. }
  42. static inline uint32_t __yy_id_comb(uint32_t tx_node, uint32_t rx_node, uint32_t msg_id)
  43. {
  44. uint32_t extid = 0;
  45. extid += (tx_node & 0xff) << 24;
  46. extid += (rx_node & 0xff) << 16;
  47. extid += (msg_id & 0xff) << 8;
  48. return extid;
  49. }
  50. static inline uint32_t __yy_id_get_tx_node(uint32_t extid)
  51. {
  52. return (extid >> 24) & 0xff;
  53. }
  54. static inline uint32_t __yy_id_get_rx_node(uint32_t extid)
  55. {
  56. return (extid >> 16) & 0xff;
  57. }
  58. static inline uint32_t __yy_id_get_msg_id(uint32_t extid)
  59. {
  60. return (extid >> 8) & 0xff;
  61. }
  62. void updata_cmd_status(enum yy_CAN_cmd_execute_bit bit, bool status)
  63. {
  64. if (status)
  65. {
  66. SET_STATUS_BIT(status_broadcast, bit);
  67. }
  68. else
  69. {
  70. CLEAR_STATUS_BIT(status_broadcast, bit);
  71. }
  72. }
  73. static void send_drone_selfcheck_msg(void)
  74. {
  75. struct drone_selfcheck_msg
  76. {
  77. uint8_t selfcheck_status;
  78. uint8_t error_code;
  79. uint8_t factory_info;
  80. uint8_t soft_stage;
  81. uint8_t soft_version;
  82. uint8_t identification_year;
  83. uint8_t identification_batch;
  84. uint8_t identification_order;
  85. };
  86. can_transmit_buf_t msg = {0};
  87. // msg.StdId = 0;
  88. msg.extend_id = 1;// 扩展ID模式
  89. msg.remote_frame = 0; // 数据帧
  90. msg.id = __yy_id_comb(NODE_WRJ, NODE_TXGL, MSG_DRONE_SELF_CHECK); // CAN ID
  91. msg.dlc = 8; // 数据长度
  92. struct drone_selfcheck_msg p = {.selfcheck_status = 0x01, // 自检结果 01正常
  93. .error_code = 0x00, // 故障信息 00默认 01IMU无连接
  94. .factory_info = 0x01, // 厂家信息 01云翼
  95. .soft_stage = 0x02, // 软件阶段 02初样03正样04批产
  96. .soft_version = 0x01, // 初始 01
  97. .identification_year = 24, // 2024年取24
  98. .identification_batch = 0x01, // 批次号
  99. .identification_order = 0x01}; // 产品编号
  100. p.identification_order = (uint8_t)verinf._serial_id;
  101. if (imu_link_status == COMP_NOEXIST)
  102. {
  103. p.selfcheck_status = 0x00;
  104. p.error_code = 0x01;
  105. }
  106. else if (imu_link_status == COMP_NORMAL)
  107. {
  108. p.selfcheck_status = 0x01;
  109. p.error_code = 0x00;
  110. }
  111. else
  112. {
  113. p.selfcheck_status = 0x11;
  114. p.error_code = 0x01;
  115. }
  116. memcpy(&msg.data, &p, msg.dlc);
  117. canSendMsg(&msg);
  118. }
  119. uint32_t cw_cmd_count = 0, ccw_cmd_count = 0;
  120. uint16_t hdw_can_delay = 0;
  121. bool debug_mode = false;
  122. uint32_t recv_alt_time = 0;
  123. bool alt_reached;
  124. bool yaw_reached;
  125. int YY_can_rx_decode(const can_receive_buf_t *rxmsg)
  126. {
  127. int ret = 0;
  128. static bool recv_tof = false;
  129. if (rxmsg->extend_id == 1)
  130. {
  131. /*调试模式*/
  132. if(0x011c0110 == rxmsg->id)
  133. {
  134. if(0 ==(rxmsg->data[0] & 0x01))
  135. {
  136. debug_mode = false;
  137. }
  138. else if(1 == (rxmsg->data[0] & 0x01))
  139. {
  140. debug_mode = true;
  141. }
  142. }
  143. uint32_t rx_node = __yy_id_get_rx_node(rxmsg->id);
  144. uint32_t msg_id = __yy_id_get_msg_id(rxmsg->id);
  145. if ((rx_node & NODE_WRJ) == NODE_WRJ)
  146. {
  147. switch (msg_id)
  148. {
  149. case MSG_IMU_SOLV:
  150. {
  151. struct imu_solv_msg
  152. {
  153. uint16_t yaw;
  154. int16_t pitch;
  155. int16_t roll;
  156. uint8_t solv_status; /* b0:0正欧拉 1-反欧拉 b1b2:01在线修正 10-纯惯导*/
  157. uint8_t align_status; /* 00-默认对准中 01-1级调平正常 03-2级调平正常 05-3级调平正常
  158. 02-1级调平异常 04-2级调平异常 06-3级调平异常 */
  159. };
  160. struct imu_solv_msg p = {0};
  161. int index = 0;
  162. memcpy_bigend(&p.yaw, &rxmsg->data[index], sizeof(p.yaw));
  163. index += sizeof(p.yaw);
  164. memcpy_bigend(&p.pitch, &rxmsg->data[index], sizeof(p.pitch));
  165. index += sizeof(p.pitch);
  166. memcpy_bigend(&p.roll, &rxmsg->data[index], sizeof(p.roll));
  167. index += sizeof(p.roll);
  168. p.solv_status = rxmsg->data[index];
  169. index += sizeof(p.solv_status);
  170. p.align_status = rxmsg->data[index];
  171. index += sizeof(p.align_status);
  172. // #error confirm yaw
  173. __yy_can_data.imu_yaw = p.yaw * 0.01f;
  174. __yy_can_data.imu_roll = p.roll * 0.01f;
  175. __yy_can_data.imu_pitch = p.pitch * 0.01f;
  176. __yy_can_data.imu_status = p.solv_status;
  177. }
  178. break;
  179. case MSG_IMU_A:
  180. {
  181. struct imu_a_msg
  182. {
  183. int32_t x_rate;
  184. int32_t y_rate;
  185. };
  186. struct imu_a_msg p = {0};
  187. int index = 0;
  188. memcpy_bigend(&p.x_rate, rxmsg->data + index, sizeof(p.x_rate));
  189. index += sizeof(p.x_rate);
  190. memcpy_bigend(&p.y_rate, rxmsg->data + index, sizeof(p.y_rate));
  191. __yy_can_data.imu_xyz_rate[0] = p.x_rate * 1e-6f;
  192. __yy_can_data.imu_xyz_rate[1] = p.y_rate * 1e-6f;
  193. }
  194. break;
  195. case MSG_IMU_B:
  196. {
  197. struct imu_b_msg
  198. {
  199. int32_t z_rate;
  200. int32_t x_acc;
  201. int8_t temp;
  202. };
  203. struct imu_b_msg p = {0};
  204. int index = 0;
  205. memcpy_bigend(&p.z_rate, &rxmsg->data[index], sizeof(p.z_rate));
  206. index += sizeof(p.z_rate);
  207. memcpy_bigend(&p.x_acc, &rxmsg->data[index], 3);
  208. index += 3;
  209. p.temp = rxmsg->data[index];
  210. __yy_can_data.imu_xyz_rate[2] = p.z_rate * 1e-6f;
  211. __yy_can_data.imu_xyz_acc[0] = (p.x_acc & 0xffffff) * 1e-4f;
  212. }
  213. break;
  214. case MSG_IMU_C:
  215. {
  216. int tmp_int = 0;
  217. memcpy_bigend(&tmp_int, rxmsg->data, 3);
  218. __yy_can_data.imu_xyz_acc[1] = tmp_int * 1e-4f;
  219. tmp_int = 0;
  220. memcpy_bigend(&tmp_int, rxmsg->data + 3, 3);
  221. __yy_can_data.imu_xyz_acc[2] = tmp_int * 1e-4f;
  222. __yy_can_data.mems_status = rxmsg->data[6] + (rxmsg->data[7] << 8);
  223. }
  224. break;
  225. case MSG_XLTB:
  226. {
  227. __yy_can_data.txgl_wk_stage = rxmsg->data[0];
  228. __yy_can_data.txgl_drone_cmd = rxmsg->data[1];
  229. __yy_can_data.txgl_radar_cmd = rxmsg->data[2];
  230. __yy_can_data.txgl_selfcheck = rxmsg->data[3];
  231. /*收到弹射准备指令*/
  232. if ((__yy_can_data.txgl_drone_cmd & CTL_RTO_CMD_MASK) == CTL_RTO_ACTION)
  233. {
  234. updata_cmd_status(TAX_READY, true);
  235. /*准备弹射指令每次上电只响应一次*/
  236. if(recv_tof == false)
  237. {
  238. recv_tof = true;
  239. control_mode = CONTROL_GCS;
  240. flight_mode_flag = GCS_VEHICLE_LAUNCH;
  241. }
  242. }
  243. /*收到弹射指令*/
  244. if ((__yy_can_data.txgl_drone_cmd & CTL_TO_CMD_MASK) == CTL_TO_ACTION)
  245. {
  246. updata_cmd_status(TAX_EXECUTE, true);
  247. __mode_state = __STATE_SELF_STABILITY;
  248. __time_stamp = micros();
  249. }
  250. /*收到顺时针旋转指令*/
  251. if ((__yy_can_data.txgl_drone_cmd & CTL_ROTATE_CMD_MASK) == CTL_CW_ROTATION)
  252. {
  253. if (pid_m_yaw.enable_cw_rotate == ROTATE_DEFAULT || pid_m_yaw.enable_cw_rotate == ROTATE_FINISH)
  254. {
  255. if (cw_cmd_count++ >= 50)
  256. {
  257. cw_cmd_count = 0;
  258. pid_m_yaw.enable_cw_rotate = ROTATE_START;
  259. pid_m_yaw.rotate_angle = 0;
  260. }
  261. }
  262. }
  263. if (pid_m_yaw.enable_cw_rotate == ROTATE_DEFAULT)
  264. {
  265. updata_cmd_status(CW_EXECUTE_COMPLETE, false);
  266. }
  267. else if (pid_m_yaw.enable_cw_rotate == ROTATE_START)
  268. {
  269. updata_cmd_status(CW_EXECUTE_COMPLETE, false);
  270. pid_m_yaw.enable_ccw_rotate = ROTATE_DEFAULT;
  271. }
  272. else if (pid_m_yaw.enable_cw_rotate == ROTATE_FINISH)
  273. {
  274. updata_cmd_status(CW_EXECUTE_COMPLETE, true);
  275. }
  276. /*收到逆时针旋转指令*/
  277. if ((__yy_can_data.txgl_drone_cmd & CTL_ROTATE_CMD_MASK) == CTL_CCW_ROTATION)
  278. {
  279. if (pid_m_yaw.enable_ccw_rotate == ROTATE_DEFAULT || pid_m_yaw.enable_ccw_rotate == ROTATE_FINISH)
  280. {
  281. if (ccw_cmd_count++ >= 50)
  282. {
  283. ccw_cmd_count = 0;
  284. pid_m_yaw.enable_ccw_rotate = ROTATE_START;
  285. pid_m_yaw.rotate_angle = 0;
  286. }
  287. }
  288. }
  289. if (pid_m_yaw.enable_ccw_rotate == ROTATE_DEFAULT)
  290. {
  291. updata_cmd_status(CCW_EXECUTE_COMPLETE, false);
  292. }
  293. else if (pid_m_yaw.enable_ccw_rotate == ROTATE_START)
  294. {
  295. pid_m_yaw.enable_cw_rotate = ROTATE_DEFAULT;
  296. updata_cmd_status(CCW_EXECUTE_COMPLETE, false);
  297. }
  298. else if (pid_m_yaw.enable_ccw_rotate == ROTATE_FINISH)
  299. {
  300. updata_cmd_status(CCW_EXECUTE_COMPLETE, true);
  301. }
  302. /*收到变高指令*/
  303. uint16_t alt_cmd = 0;
  304. static uint16_t alt_cmd_last = 0;
  305. if ((__yy_can_data.txgl_drone_cmd & CTL_ALT_CMD_MASK) == CTL_ALT_ACTION)
  306. {
  307. memcpy_bigend(&alt_cmd, &rxmsg->data[4], 2);
  308. if(alt_cmd != alt_cmd_last)
  309. {
  310. __yy_can_data.txgl_alt_sp = alt_cmd * 0.01f;
  311. updata_cmd_status(ALT_SETTING, true);
  312. updata_cmd_status(ALT_EXECUTE, false);
  313. recv_alt_time = micros();
  314. alt_reached = false;;
  315. }
  316. alt_cmd_last = alt_cmd;
  317. }
  318. /*收到变航向指令*/
  319. uint16_t yaw_cmd = 0;
  320. static uint16_t yaw_cmd_last = 0;
  321. if ((__yy_can_data.txgl_drone_cmd & CTL_YAW_CMD_MASK) == CTL_YAW_ACTION)
  322. {
  323. memcpy_bigend(&yaw_cmd, &rxmsg->data[6], 2);
  324. if(yaw_cmd != yaw_cmd_last)
  325. {
  326. __yy_can_data.txgl_yaw_sp = wrap_360(yaw_cmd * 0.01f);
  327. pid_m_yaw.enable_tyaw = true;
  328. updata_cmd_status(YAW_SETTING, true);
  329. updata_cmd_status(YAW_EXECUTE, false);
  330. yaw_reached = false;
  331. }
  332. yaw_cmd_last = yaw_cmd;
  333. }
  334. tx_loop_on = 1;
  335. last_tx_time = micros();
  336. }
  337. break;
  338. case MSG_GLOBAL_POS:
  339. {
  340. struct global_pos_msg
  341. {
  342. int lon; // 东经为正
  343. int lat; // 南纬为正
  344. };
  345. static struct global_pos_msg p = {0};
  346. memcpy(&p.lon, rxmsg->data, 4);
  347. memcpy(&p.lat, rxmsg->data + 4, 4);
  348. p.lon *= 10; // 转1e-7
  349. p.lat *= 10;
  350. __yy_can_data.txgl_lon = p.lon;
  351. __yy_can_data.txgl_lat = fabsf(p.lat); // 取反成北纬为正
  352. if ((__yy_can_data.temp_count & 0x02) != 0x02)
  353. {
  354. __yy_can_data.temp_count |= 0x02;
  355. }
  356. if (p.lon == 0)
  357. {
  358. __yy_can_data.temp_count |= 0x08;
  359. }
  360. else
  361. {
  362. __yy_can_data.temp_count &= ~0x08;
  363. }
  364. if (p.lat == 0)
  365. {
  366. __yy_can_data.temp_count |= 0x10;
  367. }
  368. else
  369. {
  370. __yy_can_data.temp_count &= ~0x10;
  371. }
  372. // 发送给IMU经纬度
  373. // send_imu_hdw_data(1, &p);
  374. }
  375. break;
  376. case MSG_GLOBAL_VEL:
  377. {
  378. struct global_vel_msg
  379. {
  380. int gps_alt_m; /* 海拔高度m */
  381. int16_t gps_vel_dm; /* 单位km/h,需要转换成dm/s */
  382. int16_t gps_yaw; /* GPS航向0~360*/
  383. uint8_t fix_status; /* b0b1:00-无定位 01-搜星中 10-定位成功 11-定位失败 */
  384. uint8_t gps_num; /* GPS星数 */
  385. };
  386. int16_t temp = 0;
  387. // #define KN2M 1852 / 3600 //海里/时 转 米/秒
  388. #define KM2M 1000 / 3600 // 千米/时 转 米/秒
  389. static struct global_vel_msg p = {0};
  390. memcpy_bigend(&p.gps_vel_dm, rxmsg->data, 2); // 卫导速度数据帧为大端在前
  391. memcpy_bigend(&p.gps_yaw, rxmsg->data + 2, 2);
  392. memcpy_bigend(&temp, rxmsg->data + 4, 2);
  393. memcpy(&p.fix_status, rxmsg->data + 6, 1);
  394. memcpy(&p.gps_num, rxmsg->data + 7, 1);
  395. p.gps_alt_m = temp;
  396. __yy_can_data.txgl_enu_vel[0] = p.gps_vel_dm * KM2M * 10; // 记录cm/s
  397. __yy_can_data.txgl_enu_vel[1] = wrap_180(p.gps_yaw);
  398. __yy_can_data.txgl_enu_vel[2] = p.gps_alt_m;
  399. p.gps_vel_dm = __yy_can_data.txgl_enu_vel[0] * 10; // 转mm/s发给IMU
  400. p.gps_yaw = __yy_can_data.txgl_enu_vel[1] * 10; // 转0.1度发给IMU
  401. p.gps_alt_m = __yy_can_data.txgl_enu_vel[2] * 1000; // 转mm发给IMU
  402. __yy_can_data.txgl_pos_fix_status = p.fix_status;
  403. __yy_can_data.txgl_gps_num = p.gps_num;
  404. if ((__yy_can_data.temp_count & 0x04) != 0x04)
  405. {
  406. __yy_can_data.temp_count |= 0x04;
  407. }
  408. // 发送给IMU卫星速度信息
  409. // send_imu_hdw_data(2, &p);
  410. }
  411. break;
  412. case MSG_POS_BIAS:
  413. {
  414. struct pos_bias_msg
  415. {
  416. int16_t e_pos_bias; // 现该成员为互定位延时时间,其他成员无意义
  417. int16_t n_pos_bias;
  418. int16_t u_pos_bias;
  419. uint16_t msl_alt;
  420. };
  421. struct pos_bias_msg p = {0};
  422. memcpy_bigend(&p.e_pos_bias, rxmsg->data, 2);
  423. memcpy_bigend(&p.n_pos_bias, rxmsg->data + 2, 2);
  424. memcpy_bigend(&p.u_pos_bias, rxmsg->data + 4, 2);
  425. memcpy_bigend(&p.msl_alt, rxmsg->data + 6, 2);
  426. hdw_can_delay = p.e_pos_bias;
  427. // 更新互定位延时时间并发送给IMU
  428. // send_imu_hdw_data(3, &p.e_pos_bias);
  429. }
  430. break;
  431. case MSG_HDW:
  432. {
  433. struct hdw_msg
  434. {
  435. int16_t e_rpos;
  436. int16_t n_rpos;
  437. uint16_t u_rpos;
  438. uint16_t status;
  439. };
  440. static struct hdw_msg p = {0};
  441. static struct hdw_msg p_last = {0};
  442. static uint32_t hdw_can_count = 0;
  443. memcpy_bigend(&p.e_rpos, rxmsg->data, 2);
  444. memcpy_bigend(&p.n_rpos, rxmsg->data + 2, 2);
  445. memcpy_bigend(&p.u_rpos, rxmsg->data + 4, 2);
  446. memcpy_bigend(&p.status, rxmsg->data + 6, 2);
  447. __yy_can_data.hdw_enu_rpos[0] = p.e_rpos * 0.1f;
  448. __yy_can_data.hdw_enu_rpos[1] = p.n_rpos * 0.1f;
  449. __yy_can_data.hdw_enu_rpos[2] = p.u_rpos * 0.1f;
  450. __yy_can_data.hdw_status = p.status;
  451. // 相机状态 0-正常 1-异常
  452. if ((__yy_can_data.temp_count & 0x01) != 0x01)
  453. {
  454. __yy_can_data.temp_count |= 0x01;
  455. }
  456. // 发送给IMU互定位偏差,互定位是100HZ,按照10HZ发送
  457. // if (hdw_can_count++ >= 10)
  458. {
  459. hdw_can_count = 0;
  460. send_imu_hdw_data(0, &p);
  461. }
  462. p_last = p;
  463. }
  464. break;
  465. case MSG_HDW_DRIFT:
  466. {
  467. struct hdw_drift_msg
  468. {
  469. int16_t e_rvel;
  470. int16_t n_rvel;
  471. int16_t u_rvel;
  472. uint16_t reserve;
  473. };
  474. struct hdw_drift_msg p = {0};
  475. memcpy_bigend(&p.e_rvel, rxmsg->data, 2);
  476. memcpy_bigend(&p.n_rvel, rxmsg->data + 2, 2);
  477. memcpy_bigend(&p.u_rvel, rxmsg->data + 4, 2);
  478. memcpy_bigend(&p.reserve, rxmsg->data + 6, 2);
  479. __yy_can_data.hdw_drift_vel[0] = p.n_rvel * 0.1f;
  480. __yy_can_data.hdw_drift_vel[1] = p.e_rvel * 0.1f;
  481. __yy_can_data.hdw_drift_vel[2] = p.u_rvel * 0.1f;
  482. }
  483. break;
  484. default:
  485. break;
  486. }
  487. }
  488. }
  489. return ret;
  490. }
  491. static void send_drone_status_msg(void)
  492. {
  493. #pragma pack(1)
  494. struct drone_status_msg
  495. {
  496. int16_t evel; // 单位0.01kn
  497. // uint16_t nvel;
  498. int16_t nvel;
  499. int16_t uvel;
  500. uint8_t salt; // 单位0.1m
  501. uint8_t status;
  502. };
  503. #pragma pack()
  504. #define M2KN 3600.0f / 1852.0f
  505. can_transmit_buf_t msg = {0};
  506. msg.extend_id = 1;// 扩展ID模式
  507. msg.remote_frame = 0; // 数据帧
  508. msg.id = __yy_id_comb(NODE_WRJ, NODE_TXGL, MSG_DRONE_STATUS);// CAN ID
  509. msg.dlc = 8; // 数据长度
  510. struct drone_status_msg p = {0};
  511. if (ins.insgps_ok == INSGPS)
  512. {
  513. // 放大成0.01kn
  514. p.evel = (pid_m_posx.vel_c) * 0.01f * M2KN * 100;
  515. p.nvel = (pid_m_posy.vel_c) * 0.01f * M2KN * 100;
  516. }
  517. else
  518. {
  519. p.evel = 0;
  520. p.nvel = 0;
  521. }
  522. // p.evel = (int16_t)(__yy_can_data.txgl_alt_sp * 100);
  523. // p.nvel = (uint16_t)(__yy_can_data.txgl_yaw_sp * 100);
  524. p.evel = (int16_t)(pid_m_pitch.angle_c * 100.0f);
  525. p.nvel = (int16_t)(pid_m_roll.angle_c * 100.0f);
  526. // 放大成0.01kn raw_sensor
  527. //p.uvel = (pid_m_alt.vel_c) * 0.01f * M2KN * 100; //气压计值 原始值 -80000 pa
  528. p.uvel = (int16_t)(raw_gps._auxiliary_gps_lon - 80000) ; //气压计值 原始值 -80000 pa
  529. if (pid_m_alt.loc_c > 0)
  530. {
  531. p.salt = fabsf(pid_m_alt.loc_c * 0.1f);
  532. }
  533. else
  534. {
  535. p.salt = 0;
  536. }
  537. p.status = status_broadcast;
  538. memcpy_smallend(msg.data, &p.evel, 2);
  539. memcpy_smallend(msg.data + 2, &p.nvel, 2);
  540. memcpy_smallend(msg.data + 4, &p.uvel, 2);
  541. msg.data[6] = p.salt;
  542. msg.data[7] = p.status;
  543. canSendMsg(&msg);
  544. }
  545. static void send_drone_euler_msg(void)
  546. {
  547. #pragma pack(1)
  548. struct drone_euler_msg
  549. {
  550. uint16_t yaw; // 单位0.01deg
  551. int16_t pitch; // 单位0.01deg
  552. int16_t roll; // 单位0.01deg
  553. int16_t reserved;
  554. };
  555. #pragma pack()
  556. can_transmit_buf_t msg = {0};
  557. // msg.StdId = 0;
  558. msg.extend_id = 1;// 扩展ID模式
  559. msg.remote_frame = 0; // 数据帧
  560. msg.id = __yy_id_comb(NODE_WRJ, NODE_TXGL, MSG_DRONE_STATUS) + 0x10; // CAN ID
  561. msg.dlc = 8; // 数据长度
  562. struct drone_euler_msg p = {0};
  563. p.yaw = (uint16_t)(pid_m_yaw.angle_c * 100.0f);
  564. p.pitch = (int)(pid_m_pitch.angle_c * 100.0f);
  565. p.roll = (int)(pid_m_roll.angle_c * 100.0f);
  566. memcpy_bigend(msg.data, &p.yaw, 2);
  567. memcpy_bigend(msg.data + 2, &p.pitch, 2);
  568. memcpy_bigend(msg.data + 4, &p.roll, 2);
  569. memcpy_bigend(msg.data + 6, &p.reserved, 2);
  570. canSendMsg(&msg);
  571. }
  572. bool can_connect = false;
  573. uint32_t send_euler_t = 0;
  574. void YY_tx_loop(void)
  575. {
  576. if (tx_loop_on)
  577. {
  578. if (micros() - last_tx_time >= 2 * 1000)
  579. {
  580. tx_loop_on = 0;
  581. if ((__yy_can_data.txgl_selfcheck & 0x01) == 0x01)
  582. {
  583. send_drone_selfcheck_msg();
  584. }
  585. else
  586. {
  587. send_drone_status_msg();
  588. }
  589. }
  590. can_connect = true;
  591. }
  592. else if(can_connect && micros() - send_euler_t >= 50 * 1000)
  593. {
  594. send_euler_t = micros();
  595. send_drone_euler_msg();
  596. }
  597. }