applogic: Move to generic position state interface
This commit is contained in:
parent
055b03850b
commit
f32887df61
2 changed files with 61 additions and 36 deletions
|
|
@ -47,11 +47,7 @@ pub struct State {
|
||||||
time: chrono::NaiveDateTime,
|
time: chrono::NaiveDateTime,
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
position: geo_types::Point,
|
pos: PositionState,
|
||||||
#[allow(unused)]
|
|
||||||
heading_deg: Option<f32>,
|
|
||||||
#[allow(unused)]
|
|
||||||
speed_mps: Option<f32>,
|
|
||||||
|
|
||||||
#[cfg(feature = "spat")]
|
#[cfg(feature = "spat")]
|
||||||
last_prune: chrono::NaiveDateTime,
|
last_prune: chrono::NaiveDateTime,
|
||||||
|
|
@ -122,6 +118,41 @@ pub enum SignalPhase {
|
||||||
Yellow,
|
Yellow,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
|
#[derive(Debug, Default, Clone, PartialEq)]
|
||||||
|
pub struct GnssFix {
|
||||||
|
pub time: Option<chrono::NaiveDateTime>,
|
||||||
|
pub latitude_deg: f64,
|
||||||
|
pub longitude_deg: f64,
|
||||||
|
pub heading_deg: Option<f32>,
|
||||||
|
pub speed_mps: Option<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
|
#[derive(Debug, Default, Clone, PartialEq)]
|
||||||
|
pub struct PositionState {
|
||||||
|
pub position: geo_types::Point,
|
||||||
|
pub heading_deg: Option<f32>,
|
||||||
|
pub speed_mps: Option<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&GnssFix> for PositionState {
|
||||||
|
fn from(value: &GnssFix) -> Self {
|
||||||
|
let position = geo_types::Point::new(value.longitude_deg, value.latitude_deg);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
position,
|
||||||
|
heading_deg: value.heading_deg,
|
||||||
|
speed_mps: value.speed_mps,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl From<GnssFix> for PositionState {
|
||||||
|
fn from(value: GnssFix) -> Self {
|
||||||
|
(&value).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "spat")]
|
#[cfg(feature = "spat")]
|
||||||
impl core::fmt::Display for SignalPhase {
|
impl core::fmt::Display for SignalPhase {
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
|
|
@ -179,9 +210,7 @@ impl State {
|
||||||
Self {
|
Self {
|
||||||
initialized: false,
|
initialized: false,
|
||||||
time: chrono::NaiveDateTime::default(),
|
time: chrono::NaiveDateTime::default(),
|
||||||
position: geo_types::Point::default(),
|
pos: PositionState::default(),
|
||||||
heading_deg: None,
|
|
||||||
speed_mps: None,
|
|
||||||
#[cfg(feature = "spat")]
|
#[cfg(feature = "spat")]
|
||||||
last_prune: chrono::NaiveDateTime::default(),
|
last_prune: chrono::NaiveDateTime::default(),
|
||||||
#[cfg(feature = "spat")]
|
#[cfg(feature = "spat")]
|
||||||
|
|
@ -191,23 +220,11 @@ impl State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(feature = "esp", feature = "gnss"))]
|
#[allow(unused)]
|
||||||
pub fn update_with_gpsfix(&mut self, fix: &embassy_gps::types::GpsFix) {
|
#[cfg(feature = "esp")]
|
||||||
self.position = geo_types::Point::new(fix.longitude_deg, fix.latitude_deg);
|
pub fn update_with_gpsfix(&mut self, fix: &GnssFix) {
|
||||||
|
self.pos = fix.into();
|
||||||
if let Some(heading) = fix.true_course_deg {
|
if let Some(time) = fix.time {
|
||||||
self.heading_deg = Some(heading);
|
|
||||||
} else {
|
|
||||||
warn!("State: Course missing from GpsFix");
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(speed) = fix.speed_over_ground {
|
|
||||||
self.speed_mps = Some(speed);
|
|
||||||
} else {
|
|
||||||
warn!("State: Speed missing from GpsFix");
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(time) = fix.get_timestamp() {
|
|
||||||
self.time = time;
|
self.time = time;
|
||||||
|
|
||||||
if !self.initialized {
|
if !self.initialized {
|
||||||
|
|
@ -217,18 +234,19 @@ impl State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "gnss")]
|
#[allow(unused)]
|
||||||
pub fn print_fix(&self) -> alloc::string::String {
|
pub fn print_fix(&self) -> alloc::string::String {
|
||||||
alloc::format!(
|
alloc::format!(
|
||||||
"{:?}, {:.4} N, {:.4} E, {:.0}°, {:.2} m/s",
|
"{:?}, {:.4} N, {:.4} E, {:.0}°, {:.2} m/s",
|
||||||
self.time,
|
self.time,
|
||||||
self.position.y(),
|
self.pos.position.y(),
|
||||||
self.position.x(),
|
self.pos.position.x(),
|
||||||
self.heading_deg.unwrap_or_default(),
|
self.pos.heading_deg.unwrap_or_default(),
|
||||||
self.speed_mps.unwrap_or_default(),
|
self.pos.speed_mps.unwrap_or_default(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::unused_self)]
|
||||||
pub fn prune(&mut self) {
|
pub fn prune(&mut self) {
|
||||||
#[cfg(feature = "spat")]
|
#[cfg(feature = "spat")]
|
||||||
if self.last_prune + PRUNE_INTERVAL < self.time {
|
if self.last_prune + PRUNE_INTERVAL < self.time {
|
||||||
|
|
@ -252,7 +270,7 @@ impl State {
|
||||||
|
|
||||||
#[cfg(feature = "spat")]
|
#[cfg(feature = "spat")]
|
||||||
pub fn run_glosa(&mut self) -> GlosaOutput {
|
pub fn run_glosa(&mut self) -> GlosaOutput {
|
||||||
let Some(own_heading) = self.heading_deg else {
|
let Some(own_heading) = self.pos.heading_deg else {
|
||||||
use alloc::string::ToString;
|
use alloc::string::ToString;
|
||||||
|
|
||||||
return GlosaOutput::Error("Heading unknown".to_string());
|
return GlosaOutput::Error("Heading unknown".to_string());
|
||||||
|
|
@ -268,7 +286,7 @@ impl State {
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(search_result) =
|
if let Some(search_result) =
|
||||||
Self::find_intersection(&self.position, own_heading, &self.tlc_cache)
|
Self::find_intersection(&self.pos.position, own_heading, &self.tlc_cache)
|
||||||
{
|
{
|
||||||
info!(
|
info!(
|
||||||
"GLOSA: Approach has signal groups: {:?}",
|
"GLOSA: Approach has signal groups: {:?}",
|
||||||
|
|
@ -315,7 +333,7 @@ impl State {
|
||||||
&intersection,
|
&intersection,
|
||||||
info.lane_id,
|
info.lane_id,
|
||||||
info.approach_id,
|
info.approach_id,
|
||||||
&self.position,
|
&self.pos.position,
|
||||||
) {
|
) {
|
||||||
info!("GLOSA: Intersection was left -> back to idle");
|
info!("GLOSA: Intersection was left -> back to idle");
|
||||||
(
|
(
|
||||||
|
|
|
||||||
13
src/main.rs
13
src/main.rs
|
|
@ -40,8 +40,7 @@ const WIFI_CHANNEL: radio::Channel = 180;
|
||||||
esp_bootloader_esp_idf::esp_app_desc!();
|
esp_bootloader_esp_idf::esp_app_desc!();
|
||||||
|
|
||||||
#[cfg(feature = "gnss")]
|
#[cfg(feature = "gnss")]
|
||||||
static GNSS_UPDATE: Mutex<RefCell<Option<embassy_gps::types::GpsFix>>> =
|
static GNSS_UPDATE: Mutex<RefCell<Option<applogic::GnssFix>>> = Mutex::new(RefCell::new(None));
|
||||||
Mutex::new(RefCell::new(None));
|
|
||||||
static WIFI_RX_QUEUE: Mutex<RefCell<Option<ArrayQueue<Vec<u8>>>>> = Mutex::new(RefCell::new(None));
|
static WIFI_RX_QUEUE: Mutex<RefCell<Option<ArrayQueue<Vec<u8>>>>> = Mutex::new(RefCell::new(None));
|
||||||
|
|
||||||
#[allow(
|
#[allow(
|
||||||
|
|
@ -341,9 +340,17 @@ async fn gnss_task(
|
||||||
fix_drop_message = !fix_drop_message;
|
fix_drop_message = !fix_drop_message;
|
||||||
if fix_drop_message {
|
if fix_drop_message {
|
||||||
// send to main thread
|
// send to main thread
|
||||||
|
let pos_state = applogic::GnssFix {
|
||||||
|
time: fix.get_timestamp(),
|
||||||
|
latitude_deg: fix.latitude_deg,
|
||||||
|
longitude_deg: fix.longitude_deg,
|
||||||
|
heading_deg: fix.true_course_deg,
|
||||||
|
speed_mps: fix.speed_over_ground,
|
||||||
|
};
|
||||||
|
|
||||||
critical_section::with(|cs| {
|
critical_section::with(|cs| {
|
||||||
let gnss_update_ref = GNSS_UPDATE.borrow(cs);
|
let gnss_update_ref = GNSS_UPDATE.borrow(cs);
|
||||||
gnss_update_ref.replace(Some(fix));
|
gnss_update_ref.replace(Some(pos_state));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue