digitalsputnik / DS-Voyager-controller

Application to control Digital Sputnik Voyager lights
0 stars 0 forks source link

Create time synchronization offset calculation document #501

Open TaanielAI opened 3 years ago

TaanielAI commented 3 years ago

Is your feature request related to a problem? Please describe. Currently we don't know how time sync offset error is calculated

Describe the solution you'd like Description on how offset error is retrieved (i.e. how many samples) and calculated (can be pseudocode or mathematical formulation) in our current time sync implementation. This should be added to wiki.

Describe alternatives you've considered Creation of our own estimation but this would also mean re-implementing whole time synchronization.

Use cases In order to implement time sync over BLE and serial, we should have same calculation principles so we can compare time synchronization quality.

Additional context https://github.com/mlichvar/chrony/blob/master/ntp_core.c#L1467 - This is where it seems that it is implemented in code.

Olenjan commented 3 years ago

All of the required information is described in NTP specification rfc5905. Chrony is just an implementation of given specification.

5.1.2.1. How is Time synchronized? (http://www.ntp.org/ntpfaq/NTP-s-algo.htm)?
Synchronizing a client to a network server consists of several packet exchanges where each exchange is a pair of request and reply.
When sending out a request, the client stores its own time (originate timestamp) into the packet being sent.
When a server receives such a packet, it will in turn store its own time (receive timestamp) into the packet,
and the packet will be returned after putting a transmit timestamp into the packet. When receiving the reply,
the receiver will once more log its own receipt time to estimate the travelling time of the packet.
The travelling time (delay) is estimated to be half of "the total delay minus remote processing time",
assuming symmetrical delays.

There seem to be 2 main algorithms

1: on-wire algorithm
calculates packet time offset and round trip Lets say T1 = local clock, time request sent by client; T2 = server clock, time request received by server; T3 = server clock, time reply sent by server; T4 = local clock, time reply received by client

Then offset = [(T2 - T1) + (T3 - T4)] / 2 delay = (T4 - T1) - (T3 - T2).

2: Clock Filter Algorithm Chooses the best samples from series of latest on-wire algorithm offsets/round trips

Lets say theta = T(B) - T(A) = 1/2 * [(T2-T1) + (T3-T4)] = on-wire offset delta = T(ABA) = (T4-T1) - (T3-T2) = on-wire delay

The dispersion statistic epsilon(t) represents the maximum error due to the frequency tolerance and time since the last packet was sent. It is initialized epsilon(t_0) = r.rho + s.rho + PHI * (T4-T1)

In the next step, the shift register stages are copied to a temporary list and the list sorted by increasing delta. Let i index the stages starting with the lowest delta. If the first tuple epoch t_0 is not later than the last valid sample epoch tp, the routine exits without affecting the current peer variables. Otherwise, let epsilon_i be the dispersion of the ith entry, then image

Let the first stage offset in the sorted list be theta_0; then, for the other stages in any order, the jitter is the RMS average

image where n is the number of valid tuples in the filter (n > 1). In order to ensure consistency and avoid divide exceptions in other

[... Work in progress ...]

Olenjan commented 3 years ago

Clock Filter algorithm C example An article about Clock Filter algorithm

Olenjan commented 3 years ago

Basic implementation of the on-wire algorithm and packet communication on Client side

Olenjan commented 3 years ago

Simple NTP Server implementation using python

Server is the master that clients connect to. Its job is to just relay the message back with its own timestamps.

Olenjan commented 3 years ago

Clock Discipline Algorithm and Clock-Adjust Process seem to be the most complicated ones.

Clock Filter algorithm output is input of a Loop filter that predicts and adjusts system clock. image

Olenjan commented 3 years ago

Masters thesis of time synchronization over wireless sensor network.

The idea of hacking chrony into BLE/Serial would add a lot of non-deterministic jitter to timestamps. "Timestamping as close to the physical layer as possible would mean that the only difference between two nodes would be the propagation time". Propagation time is the most deterministic part of in OSI layer and causes the least jitter.

Since this is done through localhost and "Traffic to 127.0.0.1 will be looped back by the internet layer of the TCP/IP model", most of the jitter still remains. Additional jitter comes from BLE Stack. To my knowledge, serial should not add much of a jitter - This needs to be confirmed.

Information about current tracking state chronyc tracking

Reference ID    : 1.2.3.4 (a.b.c)
Stratum         : 3
Ref time (UTC)  : Fri Feb  3 15:00:29 2012
System time     : 0.000001501 seconds slow of NTP time
Last offset     : -0.000001632 seconds
RMS offset      : 0.000002360 seconds
Frequency       : 331.898 ppm fast
Residual freq   : 0.004 ppm
Skew            : 0.154 ppm
Root delay      : 0.373169 seconds
Root dispersion : 0.024780 seconds
Update interval : 64.2 seconds
Leap status     : Normal
Olenjan commented 3 years ago

chronyc sourcestats

210 Number of sources = 1
Name/IP Address            NP  NR  Span  Frequency  Freq Skew  Offset  Std Dev
===============================================================================
abc.def.ghi
Olenjan commented 3 years ago

NTP capture.zip

Some NTP packet capture between 2 Voyagers. client-server is mixed, sometimes one, sometimes another. capture 5 and 6 are Wireshark ready. Capture 5 contains both client and server for each capture. At some point, timesync decided to switch. capture 6 only contains one client-server.

Olenjan commented 3 years ago

Client information directly from Voyager on WAN:

source statistics:

Name/IP Address            NP  NR  Span  Frequency  Freq Skew  Offset  Std Dev
==============================================================================
192.168.0.36               11   7     7     -3.664    249.960  -5669ns   285us

Tracking:

Reference ID    : C0A80024 (192.168.0.36)
Stratum         : 11
Ref time (UTC)  : Fri Feb 12 16:56:50 2016
System time     : 0.000000000 seconds fast of NTP time
Last offset     : -0.000266590 seconds
RMS offset      : 0.000151955 seconds
Frequency       : 193.541 ppm slow
Residual freq   : -0.106 ppm
Skew            : 2.089 ppm
Root delay      : 0.004645942 seconds
Root dispersion : 0.000091752 seconds
Update interval : 64.3 seconds
Leap status     : Normal

Server: DS0264000400182 Client: DS0262000400004

Olenjan commented 3 years ago

With localhost chrony hack method, Voyager cannot be Client, otherwise it starts pinging itself. Voyager must be Server, BLE/Serial device needs to be the client.

On the other way round, when BLE/Serial controller device has itself as Server, it starts pinging itself as well. Does this NTP loopback ruin the statistics ?

Capturing and rerouting NTP packets causes chrony to receive loopback packets and our own rerouted packets. This causes chrony to have 2 different Source responses for 1 request.

We want Voyager to be client. This to match times for multiple voyagers as closely as possible. Drift still occurs.

Olenjan commented 3 years ago

Broadcast sync: https://en.wikipedia.org/wiki/Reference_Broadcast_Synchronization