Watch
0
0
Fork
You've already forked esp32-c_its-companion
0

Move core ESP32 V2X to own repo

This commit is contained in:
Jannik Beyerstedt 2026-07-31 16:01:43 +02:00
commit 666499c240
11 changed files with 118 additions and 615 deletions

View file

@ -11,6 +11,45 @@ const PH_MAX_LENGHT_M: f32 = 500.;
const PH_MAX_ITEMS: usize = 23;
const PH_MIN_DIST_M: f32 = 20.;
/// Stand-alone CAM generator
///
/// Generates CAM messages from time and [`PosVel`] updates
///
/// # Send a message
/// ```
/// use esp32_cits_core::tx::GnItsPayload as _;
///
/// let (mut seq_no, mac_bytes) = {
/// // unwrap is fine since [`esp_hal::efuse::MacAddress`] is just an `[u8; 6]`
/// let mac_bytes = mac.as_bytes().try_into().unwrap();
///
/// (0, mac_bytes)
/// };
///
/// let mut cam = {
/// let station_id = make_station_id(mac);
/// info!("V2X Station ID: {station_id}");
///
/// applogic::cam_tx::CamState::new(
/// station_id,
/// OWN_STATION_TYPE,
/// OWN_VEHICLE_LENGTH,
/// OWN_VEHICLE_WIDTH,
/// )
/// };
///
/// cam.update(time, fix.clone().into());
/// match cam.encode_packet(mac_bytes, pos_vel, time, GN_IS_MOBILE, &mut seq_no) {
/// Ok(data) => {
/// if let Err(err) =
/// radio::send_80211_bcast_frame(&mut wlan_iface, &mac_bytes.clone(), &data)
/// {
/// warn!("Failed to send 802.11 frame: {err}");
/// }
/// }
/// Err(err) => warn!("Failed to create CAM: {err}"),
/// }
/// ```
#[derive(Debug)]
pub struct CamState {
station_id: u32,
@ -20,7 +59,7 @@ pub struct CamState {
vehicle_width_dm: u8, // vehicle width is in 10cm steps
time: chrono::DateTime<chrono::Utc>,
pos_state: super::PositionState,
pos_state: esp32_cits_core::PosVel,
/// database for path history, oldest item at the back of the vector
path_history: Vec<PathPoint>,
@ -35,7 +74,7 @@ struct PathPoint {
}
impl PathPoint {
fn new_from_pos(pos: &super::PositionState, time: chrono::DateTime<chrono::Utc>) -> Self {
fn new_from_pos(pos: &esp32_cits_core::PosVel, time: chrono::DateTime<chrono::Utc>) -> Self {
Self {
pos: pos.position,
time,
@ -44,7 +83,7 @@ impl PathPoint {
}
fn new_from_pos_with_dist(
pos: &super::PositionState,
pos: &esp32_cits_core::PosVel,
time: chrono::DateTime<chrono::Utc>,
dist_m: f32,
) -> Self {
@ -69,12 +108,12 @@ impl CamState {
vehicle_length_dm,
vehicle_width_dm,
time: chrono::DateTime::<chrono::Utc>::default(),
pos_state: super::PositionState::default(),
pos_state: esp32_cits_core::PosVel::default(),
path_history: Vec::with_capacity(PH_MAX_ITEMS + 1),
}
}
pub fn update(&mut self, time: chrono::DateTime<chrono::Utc>, pos: super::PositionState) {
pub fn update(&mut self, time: chrono::DateTime<chrono::Utc>, pos: esp32_cits_core::PosVel) {
self.time = time;
self.pos_state = pos;
@ -86,7 +125,7 @@ impl CamState {
fn update_ph(
path_history: &mut Vec<PathPoint>,
time: chrono::DateTime<chrono::Utc>,
pos: &super::PositionState,
pos: &esp32_cits_core::PosVel,
) {
// Update path history
if path_history.is_empty() {
@ -293,11 +332,11 @@ impl CamState {
}
}
impl crate::v2x_tx::GnItsPayload for CamState {
impl esp32_cits_core::tx::GnItsPayload for CamState {
fn make_eh(
&self,
address: [u8; 6],
own_position: &crate::applogic::PositionState,
own_position: &esp32_cits_core::PosVel,
time: chrono::DateTime<chrono::Utc>,
_seq_no: &mut u16,
) -> Result<
@ -313,7 +352,7 @@ impl crate::v2x_tx::GnItsPayload for CamState {
// CAM always uses SHB, hop-limit 1
Ok((
crate::v2x_tx::gn::make_shb_eh(address, station_type, own_position, time),
esp32_cits_core::tx::gn::make_shb_eh(address, station_type, own_position, time)?,
None,
1,
))
@ -336,8 +375,8 @@ mod tests {
use super::*;
use crate::init_test_env_logger;
fn posstate_from_pos(position: geo_types::Point) -> crate::applogic::PositionState {
crate::applogic::PositionState {
fn posstate_from_pos(position: geo_types::Point) -> esp32_cits_core::PosVel {
esp32_cits_core::PosVel {
position,
heading_deg: None,
speed_mps: None,

View file

@ -49,7 +49,7 @@ pub struct State {
time: chrono::NaiveDateTime,
#[allow(unused)]
pos: PositionState,
pos: esp32_cits_core::PosVel,
#[cfg(feature = "spat")]
last_prune: chrono::NaiveDateTime,
@ -130,15 +130,7 @@ pub struct GnssFix {
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 {
impl From<&GnssFix> for esp32_cits_core::PosVel {
fn from(value: &GnssFix) -> Self {
let position = geo_types::Point::new(value.longitude_deg, value.latitude_deg);
@ -149,7 +141,7 @@ impl From<&GnssFix> for PositionState {
}
}
}
impl From<GnssFix> for PositionState {
impl From<GnssFix> for esp32_cits_core::PosVel {
fn from(value: GnssFix) -> Self {
(&value).into()
}
@ -212,7 +204,7 @@ impl State {
Self {
initialized: false,
time: chrono::NaiveDateTime::default(),
pos: PositionState::default(),
pos: esp32_cits_core::PosVel::default(),
#[cfg(feature = "spat")]
last_prune: chrono::NaiveDateTime::default(),
#[cfg(feature = "spat")]
@ -641,7 +633,7 @@ impl State {
}
#[allow(unused)]
pub fn pos(&self) -> &PositionState {
pub fn pos(&self) -> &esp32_cits_core::PosVel {
&self.pos
}
}