From b6e25e7d647837e8cc12c898152fdce27ac8b634 Mon Sep 17 00:00:00 2001 From: Tom Pittenger Date: Sun, 10 Jul 2016 16:53:19 -0700 Subject: [PATCH] AP_ADSB: add support for ADSB transceiver mavlink packets --- libraries/AP_ADSB/AP_ADSB.cpp | 300 ++++++++++++++++++++++++++++++++++ libraries/AP_ADSB/AP_ADSB.h | 51 +++++- 2 files changed, 347 insertions(+), 4 deletions(-) diff --git a/libraries/AP_ADSB/AP_ADSB.cpp b/libraries/AP_ADSB/AP_ADSB.cpp index 39ebe1bb42..6843b65584 100644 --- a/libraries/AP_ADSB/AP_ADSB.cpp +++ b/libraries/AP_ADSB/AP_ADSB.cpp @@ -24,6 +24,8 @@ #include #include "AP_ADSB.h" #include +#include // for sprintf +#include extern const AP_HAL::HAL& hal; @@ -58,6 +60,40 @@ const AP_Param::GroupInfo AP_ADSB::var_info[] = { // @User: Advanced AP_GROUPINFO("LIST_RADIUS", 3, AP_ADSB, in_state.list_radius, ADSB_LIST_RADIUS_DEFAULT), + // @Param: ICAO_ID + // @DisplayName: ICAO_ID vehicle identifaction number + // @Description: ICAO_ID unique vehicle identifaction number of this aircraft. This is a integer limited to 24bits. If set to 0 then one will be randomly generated. If set to -1 then static information is not sent, transceiver is assumed pre-programmed. + // @Range: -1 16777215 + // @User: Advanced + AP_GROUPINFO("ICAO_ID", 4, AP_ADSB, out_state.cfg.ICAO_id_param, 0), + + // @Param: EMIT_TYPE + // @DisplayName: Emitter type + // @Description: ADSB classification for the type of vehicle emitting the transponder signal. Default value is 14 (UAV). + // @Values: 0:NoInfo,1:Light,2:Small,3:Large,4:HighVortexlarge,5:Heavy,6:HighlyManuv,7:Rotocraft,8:RESERVED,9:Glider,10:LightAir,11:Parachute,12:UltraLight,13:RESERVED,14:UAV,15:Space,16:RESERVED,17:EmergencySurface,18:ServiceSurface,19:PointObstacle + // @User: Advanced + AP_GROUPINFO("EMIT_TYPE", 5, AP_ADSB, out_state.cfg.emitterType, ADSB_EMITTER_TYPE_UAV), + + // @Param: LEN_WIDTH + // @DisplayName: Aircraft length and width + // @Description: Aircraft length and width encoding. See ADSB_TRANSPONDER_STATIC_INPUT_ALW_ENCODE + // @User: Advanced + AP_GROUPINFO("LEN_WIDTH", 6, AP_ADSB, out_state.cfg.lengthWidth, ADSB_TRANSPONDER_AIRCRAFT_SIZE_NO_DATA), + + // @Param: OFFSET_LAT + // @DisplayName: GPS antenna lateral offset + // @Description: GPS antenna lateral offset. See ADSB_TRANSPONDER_STATIC_INPUT_GPS_LAT_OFFSET + // @User: Advanced + AP_GROUPINFO("OFFSET_LAT", 7, AP_ADSB, out_state.cfg.gpsLatOffset, ADSB_TRANSPONDER_GPS_LAT_OFFSET_NO_DATA), + + // @Param: OFFSET_LON + // @DisplayName: GPS antenna longitudinal offset + // @Description: GPS antenna longitudinal offset. See ADSB_TRANSPONDER_STATIC_INPUT_GPS_LON_OFFSET + // @User: Advanced + AP_GROUPINFO("OFFSET_LON", 8, AP_ADSB, out_state.cfg.gpsLonOffset, ADSB_TRANSPONDER_GPS_LON_OFFSET_NO_DATA), + + + AP_GROUPEND }; @@ -88,6 +124,9 @@ void AP_ADSB::init(void) avoid_state.highest_threat_distance = 0; avoid_state.another_vehicle_within_radius = false; avoid_state.is_evading_threat = false; + + // out_state + set_callsign("PING1234", false); } /* @@ -141,7 +180,73 @@ void AP_ADSB::update(void) } } +// ----------------------- + if (_my_loc.is_zero()) { + // if we don't have a GPS lock then there's nothing else to do + return; + } +// ----------------------- + + + perform_threat_detection(); + + // ensure it's positive 24bit but allow -1 + out_state.cfg.ICAO_id_param = constrain_int32(out_state.cfg.ICAO_id_param, -1, 0x00FFFFFF); + + // send dynamic data to transceiver, every 1s + if (now - out_state.last_report_ms >= 1000) { + out_state.last_report_ms = now; + // if the transceiver has been detected on a channel, use that channel. Else, broadcast to all + if (out_state.chan >= 0 && out_state.chan < MAVLINK_COMM_NUM_BUFFERS) { + send_dynamic_out((mavlink_channel_t)(MAVLINK_COMM_0 + out_state.chan)); + } else { + for (uint8_t i=0; i= 10000) { + + out_state.last_config_ms = now; + // if the transceiver has been detected on a channel, use that channel. Else, broadcast to all + if (out_state.chan >= 0 && out_state.chan < MAVLINK_COMM_NUM_BUFFERS) { + send_configure((mavlink_channel_t)(MAVLINK_COMM_0 + out_state.chan)); + } else { + for (uint8_t i=0; i> i) & 0x00000001); + } + return( (timeSum ^ M3) & 0x00FFFFFF); +} + +// assign a string to out_state.cfg.callsign but ensure it's null terminated +void AP_ADSB::set_callsign(const char* str, bool append_icao) +{ + bool zero_char_pad = false; + + // clean slate + memset(out_state.cfg.callsign, 0, sizeof(out_state.cfg.callsign)); + + // copy str to cfg.callsign but we can't use strncpy because we need + // to restrict values to only 'A' - 'Z' and '0' - '9' + for (uint8_t i=0; i