diff --git a/firmware/application/apps/ui_adsb_rx.cpp b/firmware/application/apps/ui_adsb_rx.cpp index ba080481..66b7900b 100644 --- a/firmware/application/apps/ui_adsb_rx.cpp +++ b/firmware/application/apps/ui_adsb_rx.cpp @@ -205,7 +205,7 @@ void ADSBRxView::on_frame(const ADSBFrameMessage * message) { auto frame = message->frame; uint32_t ICAO_address = frame.get_ICAO_address(); - if (frame.check_CRC() && frame.get_ICAO_address()) { + if (frame.check_CRC() && ICAO_address) { rtcGetTime(&RTCD1, &datetime); auto& entry = ::on_packet(recent, ICAO_address); frame.set_rx_timestamp(datetime.minute() * 60 + datetime.second()); @@ -222,11 +222,14 @@ void ADSBRxView::on_frame(const ADSBFrameMessage * message) { uint8_t msg_sub = frame.get_msg_sub(); uint8_t * raw_data = frame.get_raw_data(); - if ((msg_type >= 1) && (msg_type <= 4)) { + if ((msg_type >= AIRCRAFT_ID_L) && (msg_type <= AIRCRAFT_ID_H)) { callsign = decode_frame_id(frame); entry.set_callsign(callsign); logentry+=callsign+" "; - } else if (((msg_type >= 9) && (msg_type <= 18)) || ((msg_type >= 20) && (msg_type <= 22))) { + } + // + else if (((msg_type >= AIRBORNE_POS_BARO_L) && (msg_type <= AIRBORNE_POS_BARO_H)) || + ((msg_type >= AIRBORNE_POS_GPS_L) && (msg_type <= AIRBORNE_POS_GPS_H))) { entry.set_frame_pos(frame, raw_data[6] & 4); if (entry.pos.valid) { @@ -242,7 +245,7 @@ void ADSBRxView::on_frame(const ADSBFrameMessage * message) { if (send_updates) details_view->update(entry); } - } else if(msg_type == 19 && msg_sub >= 1 && msg_sub <= 4){ + } else if(msg_type == AIRBORNE_VEL && msg_sub >= VEL_GND_SUBSONIC && msg_sub <= VEL_AIR_SUPERSONIC){ entry.set_frame_velo(frame); logentry += "Type:" + to_string_dec_uint(msg_sub) + " Hdg:" + to_string_dec_uint(entry.velo.heading) + diff --git a/firmware/application/apps/ui_adsb_rx.hpp b/firmware/application/apps/ui_adsb_rx.hpp index bb474e83..a63b7eb2 100644 --- a/firmware/application/apps/ui_adsb_rx.hpp +++ b/firmware/application/apps/ui_adsb_rx.hpp @@ -36,9 +36,33 @@ using namespace adsb; namespace ui { -#define ADSB_DECAY_A 10 // In seconds -#define ADSB_DECAY_B 30 -#define ADSB_DECAY_C 60 // Can be used for removing old entries, RecentEntries already caps to 64 +#define ADSB_DECAY_A 10 // In seconds +#define ADSB_DECAY_B 30 +#define ADSB_DECAY_C 60 // Can be used for removing old entries, RecentEntries already caps to 64 + +#define AIRCRAFT_ID_L 1 // aircraft ID message type (lowest type id) +#define AIRCRAFT_ID_H 4 // aircraft ID message type (highest type id) + +#define SURFACE_POS_L 5 // surface position (lowest type id) +#define SURFACE_POS_H 8 // surface position (highest type id) + +#define AIRBORNE_POS_BARO_L 9 // airborne position (lowest type id) +#define AIRBORNE_POS_BARO_H 18 // airborne position (highest type id) + +#define AIRBORNE_VEL 19 // airborne velocities + +#define AIRBORNE_POS_GPS_L 20 // airborne position (lowest type id) +#define AIRBORNE_POS_GPS_H 22 // airborne position (highest type id) + +#define RESERVED_L 23 // reserved for other uses +#define RESERVED_H 31 // reserved for other uses + +#define VEL_GND_SUBSONIC 1 +#define VEL_GND_SUPERSONIC 2 +#define VEL_AIR_SUBSONIC 3 +#define VEL_AIR_SUPERSONIC 4 + +#define O_E_FRAME_TIMEOUT 20 // timeout between odd and even frames struct AircraftRecentEntry { using Key = uint32_t; @@ -82,7 +106,7 @@ struct AircraftRecentEntry { frame_pos_odd = frame; if (!frame_pos_even.empty() && !frame_pos_odd.empty()) { - if (abs(frame_pos_even.get_rx_timestamp() - frame_pos_odd.get_rx_timestamp()) < 20) + if (abs(frame_pos_even.get_rx_timestamp() - frame_pos_odd.get_rx_timestamp()) < O_E_FRAME_TIMEOUT) pos = decode_frame_pos(frame_pos_even, frame_pos_odd); } } diff --git a/firmware/common/adsb.cpp b/firmware/common/adsb.cpp index 862e375d..335c6d21 100644 --- a/firmware/common/adsb.cpp +++ b/firmware/common/adsb.cpp @@ -141,7 +141,11 @@ float cpr_mod(float a, float b) { return a - (b * floor(a / b)); } -int cpr_NL(float lat) { +int cpr_NL_precise(float lat) { + return (int) floor(2 * PI / acos(1 - ((1 - cos(PI / (2 * NZ))) / pow(cos(PI * lat / 180), 2)))); +} + +int cpr_NL_approx(float lat) { if (lat < 0) lat = -lat; // Symmetry @@ -150,7 +154,11 @@ int cpr_NL(float lat) { return 59 - c; } - return 1; + return 1; +} + +int cpr_NL(float lat) { + return cpr_NL_precise(lat); } int cpr_N(float lat, int is_odd) { @@ -258,7 +266,7 @@ adsb_pos decode_frame_pos(ADSBFrame& frame_even, ADSBFrame& frame_odd) { // Compute longitude if (time_even > time_odd) { - // Use even frame + // Use even frame2 ni = cpr_N(latE, 0); Dlon = 360.0 / ni; @@ -279,7 +287,7 @@ adsb_pos decode_frame_pos(ADSBFrame& frame_even, ADSBFrame& frame_odd) { position.latitude = latO; } - if (position.longitude > 180) position.longitude -= 360; + if (position.longitude >= 180) position.longitude -= 360; position.valid = true; diff --git a/firmware/common/adsb.hpp b/firmware/common/adsb.hpp index 82d177e4..f3a2f3ac 100644 --- a/firmware/common/adsb.hpp +++ b/firmware/common/adsb.hpp @@ -83,6 +83,10 @@ const float adsb_lat_lut[58] = { 86.53536998, 87.00000000 }; +const float PI = 3.14159265358979323846; + +const float NZ = 15; + void make_frame_adsb(ADSBFrame& frame, const uint32_t ICAO_address); void encode_frame_id(ADSBFrame& frame, const uint32_t ICAO_address, const std::string& callsign);