use crate::aws::realtime::ChunkMetadata;
const SWEEP_DURATION_BIAS_SECS: f64 = 0.67;
const INTER_SWEEP_BASE_GAP_SECS: f64 = 0.7;
const INTER_SWEEP_ELEVATION_RATE_SECS_PER_DEG: f64 = 0.08;
const INTER_VOLUME_GAP_SECS: f64 = 8.5;
pub struct ChunkTimingModel;
impl ChunkTimingModel {
pub fn sweep_duration_secs(azimuth_rate_dps: f64) -> Option<f64> {
if azimuth_rate_dps <= 0.0 {
return None;
}
Some((360.0 / azimuth_rate_dps) - SWEEP_DURATION_BIAS_SECS)
}
pub fn chunk_duration_secs(azimuth_rate_dps: f64, chunks_in_sweep: usize) -> Option<f64> {
if chunks_in_sweep == 0 {
return None;
}
Self::sweep_duration_secs(azimuth_rate_dps).map(|d| d / chunks_in_sweep as f64)
}
pub fn inter_sweep_gap_secs(from_elevation_deg: f64, to_elevation_deg: f64) -> f64 {
let elevation_change = (to_elevation_deg - from_elevation_deg).abs();
INTER_SWEEP_BASE_GAP_SECS + (elevation_change * INTER_SWEEP_ELEVATION_RATE_SECS_PER_DEG)
}
pub fn inter_volume_gap_secs() -> f64 {
INTER_VOLUME_GAP_SECS
}
pub fn estimate_chunk_interval_secs(previous: &ChunkMetadata, next: &ChunkMetadata) -> f64 {
if next.is_start_chunk() {
return Self::inter_volume_gap_secs();
}
let chunk_duration =
Self::chunk_duration_secs(next.azimuth_rate_dps(), next.chunks_in_sweep());
if next.is_first_in_sweep() {
let gap = Self::inter_sweep_gap_secs(
previous.elevation_angle_deg(),
next.elevation_angle_deg(),
);
return match chunk_duration {
Some(d) => d + gap,
None => gap + Self::fallback_chunk_duration_secs(),
};
}
chunk_duration.unwrap_or(Self::fallback_chunk_duration_secs())
}
fn fallback_chunk_duration_secs() -> f64 {
4.0
}
}