neast: retain position once decoded

This commit is contained in:
Astro 2021-11-09 19:04:05 +01:00
parent 4e3504259a
commit 64a508df25
4 changed files with 20 additions and 29 deletions

View File

@ -15,6 +15,7 @@ pub struct Entry {
pub altitude: Option<u16>,
cpr1: Option<(Instant, adsb::CPRFrame)>,
cpr2: Option<(Instant, adsb::CPRFrame)>,
pub position: Option<adsb::Position>,
pub heading: Option<f64>,
pub ground_speed: Option<f64>,
pub vertical_rate: Option<i16>,
@ -35,6 +36,21 @@ impl Entry {
self.cpr1 = self.cpr2.take();
}
self.cpr2 = Some((Instant::now(), cpr_frame));
match (&self.cpr1, &self.cpr2) {
(Some((time1, cpr1)), Some((time2, cpr2)))
if time2.duration_since(*time1) <= Duration::from_secs(MAX_CPR_INTERVAL) =>
{
if let Some(pos) = adsb::cpr::get_position((cpr1, cpr2)) {
if pos.latitude >= -90.0 && pos.latitude <= 90.0 &&
pos.longitude >= -180.0 && pos.longitude <= 180.0
{
self.position = Some(pos);
}
}
}
_ => {}
}
}
adsb::ADSBMessageKind::AirborneVelocity {
heading, ground_speed,
@ -56,25 +72,6 @@ impl Entry {
self.last_update = Some(Instant::now());
}
pub fn position(&self) -> Option<adsb::Position> {
match (&self.cpr1, &self.cpr2) {
(Some((time1, cpr1)), Some((time2, cpr2)))
if time2.duration_since(*time1) <= Duration::from_secs(MAX_CPR_INTERVAL) =>
{
let pos = adsb::cpr::get_position((cpr1, cpr2))?;
if pos.latitude >= -90.0 && pos.latitude <= 90.0 &&
pos.longitude >= -180.0 && pos.longitude <= 180.0
{
Some(pos)
} else {
None
}
}
_ =>
None
}
}
pub fn flight(&self) -> Option<&str> {
self.callsign.as_ref().map(|callsign| {
callsign.split(char::is_whitespace)

View File

@ -57,7 +57,7 @@ async fn main() {
update_min(&entry.ground_speed, &mut min_speed);
update_max(&entry.ground_speed, &mut max_speed);
if let Some(pos) = entry.position() {
if let Some(pos) = &entry.position {
let altitude_m = entry.altitude.unwrap_or(0) as f64 * 0.3048;
let distance_km = WGS84::from_degrees_and_meters(pos.latitude, pos.longitude, altitude_m)
.distance(&home) / 1000.0;

View File

@ -74,12 +74,7 @@ impl State {
self.info.altitude_m = Some(altitude_m);
}
let pos = if let Some(pos) = entry.position() {
pos
} else {
return None;
};
let pos = entry.position.as_ref()?;
let coord = geo::Coordinate { x: pos.longitude, y: pos.latitude };
if let Some(old_pos) = self.position.replace(pos.clone()) {
if old_pos.longitude != pos.longitude || old_pos.latitude != pos.latitude {

View File

@ -19,13 +19,12 @@ pub struct Aircraft {
impl Aircraft {
pub fn new(icao_address: &ICAOAddress, entry: &Entry) -> Self {
let pos = entry.position();
Aircraft {
hex: format!("{}", icao_address),
flight: entry.callsign.clone(),
category: entry.emitter_category.clone(),
lat: pos.as_ref().map(|pos| pos.latitude),
lon: pos.as_ref().map(|pos| pos.longitude),
lat: entry.position.as_ref().map(|pos| pos.latitude),
lon: entry.position.as_ref().map(|pos| pos.longitude),
altitude: entry.altitude.clone(),
track: entry.heading.map(|heading| heading as i16),
speed: entry.ground_speed.map(|speed| speed as u16),