mavlink.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /*
  2. mavlink class for handling OpenDroneID messages
  3. */
  4. #include <Arduino.h>
  5. #include "mavlink.h"
  6. #include "board_config.h"
  7. #include "version.h"
  8. #define SERIAL_BAUD 115200
  9. static HardwareSerial *serial_ports[MAVLINK_COMM_NUM_BUFFERS];
  10. #include <generated/mavlink_helpers.h>
  11. mavlink_system_t mavlink_system = {0,MAV_COMP_ID_ODID_TXRX_1};
  12. /*
  13. send a buffer out a MAVLink channel
  14. */
  15. void comm_send_buffer(mavlink_channel_t chan, const uint8_t *buf, uint8_t len)
  16. {
  17. if (chan >= MAVLINK_COMM_NUM_BUFFERS || serial_ports[uint8_t(chan)] == nullptr) {
  18. return;
  19. }
  20. auto &serial = *serial_ports[uint8_t(chan)];
  21. serial.write(buf, len);
  22. }
  23. /*
  24. abstraction for MAVLink on a serial port
  25. */
  26. MAVLinkSerial::MAVLinkSerial(HardwareSerial &_serial, mavlink_channel_t _chan) :
  27. serial(_serial),
  28. chan(_chan)
  29. {
  30. serial_ports[uint8_t(_chan - MAVLINK_COMM_0)] = &serial;
  31. }
  32. void MAVLinkSerial::init(void)
  33. {
  34. // print banner at startup
  35. serial.printf("ArduRemoteID version %u.%u %08x\n",
  36. FW_VERSION_MAJOR, FW_VERSION_MINOR, GIT_VERSION);
  37. }
  38. void MAVLinkSerial::update(void)
  39. {
  40. if (mavlink_system.sysid != 0) {
  41. update_send();
  42. } else if (millis() - last_hb_warn_ms >= 2000) {
  43. last_hb_warn_ms = millis();
  44. serial.printf("Waiting for heartbeat\n");
  45. }
  46. update_receive();
  47. }
  48. void MAVLinkSerial::update_send(void)
  49. {
  50. uint32_t now_ms = millis();
  51. if (now_ms - last_hb_ms >= 1000) {
  52. last_hb_ms = now_ms;
  53. mavlink_msg_heartbeat_send(
  54. chan,
  55. MAV_TYPE_ODID,
  56. MAV_AUTOPILOT_ARDUPILOTMEGA,
  57. 0,
  58. 0,
  59. 0);
  60. // send arming status
  61. arm_status_send();
  62. }
  63. }
  64. void MAVLinkSerial::update_receive(void)
  65. {
  66. // receive new packets
  67. mavlink_message_t msg;
  68. mavlink_status_t status;
  69. status.packet_rx_drop_count = 0;
  70. const uint16_t nbytes = serial.available();
  71. for (uint16_t i=0; i<nbytes; i++) {
  72. const uint8_t c = (uint8_t)serial.read();
  73. // Try to get a new message
  74. if (mavlink_parse_char(chan, c, &msg, &status)) {
  75. process_packet(status, msg);
  76. }
  77. }
  78. }
  79. /*
  80. printf via MAVLink STATUSTEXT for debugging
  81. */
  82. void MAVLinkSerial::mav_printf(uint8_t severity, const char *fmt, ...)
  83. {
  84. va_list arg_list;
  85. char text[MAVLINK_MSG_STATUSTEXT_FIELD_TEXT_LEN+1] {};
  86. va_start(arg_list, fmt);
  87. vsnprintf(text, sizeof(text), fmt, arg_list);
  88. va_end(arg_list);
  89. mavlink_msg_statustext_send(chan,
  90. severity,
  91. text,
  92. 0, 0);
  93. }
  94. void MAVLinkSerial::process_packet(mavlink_status_t &status, mavlink_message_t &msg)
  95. {
  96. const uint32_t now_ms = millis();
  97. switch (msg.msgid) {
  98. case MAVLINK_MSG_ID_HEARTBEAT: {
  99. mavlink_heartbeat_t hb;
  100. if (mavlink_system.sysid == 0) {
  101. mavlink_msg_heartbeat_decode(&msg, &hb);
  102. if (msg.sysid > 0 && hb.type != MAV_TYPE_GCS) {
  103. mavlink_system.sysid = msg.sysid;
  104. }
  105. }
  106. break;
  107. }
  108. case MAVLINK_MSG_ID_OPEN_DRONE_ID_LOCATION: {
  109. mavlink_msg_open_drone_id_location_decode(&msg, &location);
  110. last_location_ms = now_ms;
  111. break;
  112. }
  113. case MAVLINK_MSG_ID_OPEN_DRONE_ID_BASIC_ID: {
  114. mavlink_msg_open_drone_id_basic_id_decode(&msg, &basic_id);
  115. last_basic_id_ms = now_ms;
  116. break;
  117. }
  118. case MAVLINK_MSG_ID_OPEN_DRONE_ID_AUTHENTICATION: {
  119. mavlink_msg_open_drone_id_authentication_decode(&msg, &authentication);
  120. break;
  121. }
  122. case MAVLINK_MSG_ID_OPEN_DRONE_ID_SELF_ID: {
  123. mavlink_msg_open_drone_id_self_id_decode(&msg, &self_id);
  124. last_self_id_ms = now_ms;
  125. break;
  126. }
  127. case MAVLINK_MSG_ID_OPEN_DRONE_ID_SYSTEM: {
  128. mavlink_msg_open_drone_id_system_decode(&msg, &system);
  129. last_system_ms = now_ms;
  130. break;
  131. }
  132. case MAVLINK_MSG_ID_OPEN_DRONE_ID_SYSTEM_UPDATE: {
  133. mavlink_open_drone_id_system_update_t pkt_system_update;
  134. mavlink_msg_open_drone_id_system_update_decode(&msg, &pkt_system_update);
  135. system.operator_latitude = pkt_system_update.operator_latitude;
  136. system.operator_longitude = pkt_system_update.operator_longitude;
  137. system.operator_altitude_geo = pkt_system_update.operator_altitude_geo;
  138. system.timestamp = pkt_system_update.timestamp;
  139. if (last_system_ms != 0) {
  140. // we can only mark system as updated if we have the other
  141. // information already
  142. last_system_ms = now_ms;
  143. }
  144. break;
  145. }
  146. case MAVLINK_MSG_ID_OPEN_DRONE_ID_OPERATOR_ID: {
  147. mavlink_msg_open_drone_id_operator_id_decode(&msg, &operator_id);
  148. last_operator_id_ms = now_ms;
  149. break;
  150. }
  151. default:
  152. // we don't care about other packets
  153. break;
  154. }
  155. }
  156. void MAVLinkSerial::arm_status_send(void)
  157. {
  158. const uint8_t status = parse_fail==nullptr?MAV_ODID_GOOD_TO_ARM:MAV_ODID_PRE_ARM_FAIL_GENERIC;
  159. const char *reason = parse_fail==nullptr?"":parse_fail;
  160. mavlink_msg_open_drone_id_arm_status_send(
  161. chan,
  162. status,
  163. reason);
  164. }