Skip to content

Commit

Permalink
Refactored clock and filter interfaces.
Browse files Browse the repository at this point in the history
  • Loading branch information
davidv1992 committed Sep 15, 2023
1 parent d854419 commit 2065d1e
Show file tree
Hide file tree
Showing 4 changed files with 197 additions and 179 deletions.
49 changes: 29 additions & 20 deletions statime/src/filters/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
use fixed::traits::LossyInto;

use super::{Filter, FilterUpdate};
use crate::{port::Measurement, time::Duration, Clock};
use crate::{port::Measurement, time::Duration, Clock, Time};

#[derive(Debug)]
struct PrevStepData {
measurement: Measurement,
event_time: Time,
offset: Duration,
correction: Duration,
}

Expand Down Expand Up @@ -41,39 +42,50 @@ impl Filter for BasicFilter {
}

fn measurement<C: Clock>(&mut self, measurement: Measurement, clock: &mut C) -> FilterUpdate {
let mut update = FilterUpdate::default();

if let Some(delay) = measurement.delay {
update.mean_delay = Some(delay);
}

let Some(offset) = measurement.offset else {
// No measurement, so no further actions
return update;
};

// Reset on too-large difference
if measurement.master_offset.abs() > Duration::from_nanos(1_000_000_000) {
log::debug!("Offset too large, stepping {}", measurement.master_offset);
if offset.abs() > Duration::from_nanos(1_000_000_000) {
log::debug!("Offset too large, stepping {}", offset);
self.offset_confidence = Duration::from_nanos(1_000_000_000);
self.freq_confidence = 1e-4;

if let Err(error) = clock.step_clock(-measurement.master_offset) {
if let Err(error) = clock.step_clock(-offset) {
log::error!("Could not step clock: {:?}", error);
}
return Default::default();
return update;
}

// Determine offset
let mut offset = measurement.master_offset;
let mut clamped_offset = offset;
if offset.abs() > self.offset_confidence {
offset = offset.clamp(-self.offset_confidence, self.offset_confidence);
clamped_offset = offset.clamp(-self.offset_confidence, self.offset_confidence);
self.offset_confidence *= 2i32;
} else {
self.offset_confidence -= (self.offset_confidence - offset.abs()) * self.gain;
}

// And decide it's correction
let correction = -offset * self.gain;
let correction = -clamped_offset * self.gain;

let freq_corr = if let Some(last_step) = &self.last_step {
// Calculate interval for us
let interval_local: f64 =
(measurement.event_time - last_step.measurement.event_time - last_step.correction)
(measurement.event_time - last_step.event_time - last_step.correction)
.nanos()
.lossy_into();
// and for the master
let interval_master: f64 = ((measurement.event_time - measurement.master_offset)
- (last_step.measurement.event_time - last_step.measurement.master_offset))
let interval_master: f64 = ((measurement.event_time - offset)
- (last_step.event_time - last_step.offset))
.nanos()
.lossy_into();

Expand All @@ -98,16 +110,18 @@ impl Filter for BasicFilter {
0.0
};

// unwrap is ok here since we always have an offset
log::info!(
"Offset to master: {:e}ns, corrected with phase change {:e}ns and freq change {:e}ppm",
measurement.master_offset.nanos(),
offset.nanos(),
correction.nanos(),
freq_corr
);

// Store data for next time
self.last_step = Some(PrevStepData {
measurement,
event_time: measurement.event_time,
offset,
correction,
});

Expand All @@ -119,12 +133,7 @@ impl Filter for BasicFilter {
} else {
self.cur_freq += freq_corr;
}
Default::default()
}

fn delay(&mut self, delay: Duration) -> Duration {
// We dont filter delays
delay
update
}

fn demobilize<C: Clock>(self, _clock: &mut C) {
Expand Down
4 changes: 1 addition & 3 deletions statime/src/filters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::{port::Measurement, Clock, Duration};
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct FilterUpdate {
pub next_update: Option<core::time::Duration>,
pub mean_delay: Option<Duration>,
}

/// A filter for post-processing time measurements.
Expand All @@ -27,9 +28,6 @@ pub trait Filter {
/// The filter can then use this to adjust the clock
fn measurement<C: Clock>(&mut self, m: Measurement, clock: &mut C) -> FilterUpdate;

/// Handle a new measurement of the delay to the master.
fn delay(&mut self, delay: Duration) -> Duration;

/// Update initiated through [FilterUpdate::next_update] timeout.
fn update<C: Clock>(&mut self, clock: &mut C) -> FilterUpdate;

Expand Down
12 changes: 10 additions & 2 deletions statime/src/port/measurement.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
use crate::time::{Duration, Time};

/// A single measurement as produced by a PTP port.
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
/// Depending on what trigerred the measurements, not
/// all fields will be populated
#[derive(Default, Clone, Copy, Debug, Eq, PartialEq)]
pub struct Measurement {
/// Time this measurement was made.
pub event_time: Time,
/// Offset to the remote PTP node.
pub master_offset: Duration,
pub offset: Option<Duration>,
/// Delay to the remote PTP node.
pub delay: Option<Duration>,
/// Raw offset calculated from a sync message
pub raw_sync_offset: Option<Duration>,
/// Raw offset calculated from a delay message
pub raw_delay_offset: Option<Duration>,
}
Loading

0 comments on commit 2065d1e

Please sign in to comment.