#[repr(C)]
#[derive(Copy, Clone, Debug, Default)]
pub struct Range {
pub dist: u16,
pub confidence: u8,
}
#[derive(Copy, Clone, Debug, Default)]
pub(crate) struct PartialScan {
pub radar_speed: u16,
pub start_angle: f32,
pub data: [Range; 12],
pub end_angle: f32,
pub stamp: u16,
pub crc: u8,
}
#[repr(C)]
#[derive(Clone, Debug, Default)]
pub struct Scan {
pub radar_speed: u16,
pub start_angle: f32,
pub data: Vec<Range>,
pub end_angle: f32, pub stamp: u16,
}
impl Scan {
pub fn get_step(&self) -> f32 {
(self.end_angle - self.start_angle + 360.0) / (self.data.len() - 1) as f32
}
pub fn get_angle_of_reading(&self, reading_num: u16) -> f32 {
let angle = self.start_angle + self.get_step() * (reading_num) as f32;
let spins = (angle / 360.0).floor();
angle - 360.0 * spins
}
}
pub(crate) struct ScanBuilder {
initial_angle: f32,
buffer: Scan,
working_radar_speed: u64,
}
impl Default for ScanBuilder {
fn default() -> Self {
ScanBuilder {
initial_angle: f32::INFINITY,
buffer: Scan::default(),
working_radar_speed: 0,
}
}
}
impl ScanBuilder {
pub fn add_partial_scan(&mut self, partial: PartialScan) -> Option<Scan> {
if self.initial_angle == f32::INFINITY {
self.initial_angle = partial.start_angle;
self.buffer.start_angle = partial.start_angle;
self.buffer.stamp = partial.stamp;
self.buffer.data.extend_from_slice(&partial.data);
self.working_radar_speed += partial.radar_speed as u64;
return None;
}
self.buffer.data.extend_from_slice(&partial.data);
self.working_radar_speed += partial.radar_speed as u64;
if self.is_in_range(partial.start_angle, partial.end_angle) {
self.buffer.radar_speed =
(self.working_radar_speed / self.num_of_scans() as u64) as u16;
self.buffer.end_angle = partial.end_angle;
self.initial_angle = f32::INFINITY;
self.working_radar_speed = 0;
let mut new = Scan::default();
std::mem::swap(&mut new, &mut self.buffer);
Some(new)
} else {
None
}
}
fn is_in_range(&self, start: f32, end: f32) -> bool {
if start > end {
self.is_in_range(start, 360.0) || self.is_in_range(0.0, end)
} else {
self.initial_angle >= start && self.initial_angle <= end
}
}
#[inline(always)]
fn num_of_scans(&self) -> u8 {
(self.buffer.data.len() / 12) as u8
}
}