NTP(Network Time Protocol)
The OVP8xx (and M04239) time system is based on the Unix base time
. Unix base time
started on the first of January, 1970. Get more information from Wikipedia.
By default, the OVP8xx (and M04239) will be reset every time a reboot occurs to an arbitrary time: for example 1581090786002917000
.
NTP
might be the right choice, to provide the same base time
to all O3R systems per facility and to repeatably set the current time.
This whitepaper explains the application of NTP
on an O3R system.
What is NTP
Network Time Protocol(https://en.wikipedia.org/wiki/Network_Time_Protocol) is a network protocol for time synchronization between network systems/participants.
To synchronize different systems, an NTP
server is needed (for example chrony). An NTP
client (O3R) can connect to the NTP
server and apply the provided time from the NTP
server. To provide stable synchronization, some systems are connected with several NTP
servers to also have a fallback NTP
server if the lead
server goes offline.
Why use NTP with the O3R?
Receiving data - 3D images, occupancy grid, diagnosis - is meaningless if it cannot be seen in the same time context as the system in the same location as this O3R (for example AGV). Typically, timestamps (for frames etc.) are measured in seconds, milliseconds or even nanoseconds. For (3D) image processing and other time-critical information, time synchronization is needed. One way could be measuring the start time for different systems, or synchronizing these systems with each other.
If no NTP connection is established the systems default time will be set to a similar value at startup: 1581090786002917000
This Unix base time timestamp is equivalent to Fri Feb 07, 2020, 15:53:06 GMT+0000
for example: The received occupancy grid frame contains a timestamp based on the OVP8xx time. The AGV logs information about special events - like a detected object (detected by LIDAR and/or ODS). If both events, the AGV log and the ODS data are not within the same time frame, it is hard or near impossible to reference both to each other.
The O3R platform can be synchronized to a central clock using Simple NTP
- Wikipedia.
When the SNTP
synchronization is active, the timestamps of all the images sent from the connected camera heads will be synchronized to the defined clock.
Note
Note that enabling synchronization through NTP requires that you consider the general architecture of your system.
The Time Serving machine needs to be fully booted before the O3R is started, to avoid having to perform a time jump.
Also, NTP servers have different levels of accuracy and the O3R might fail to synchronize with one if the accuracy is considered too low.
An alternative approach to (S)NTP is a time “translator” like: https://github.com/ethz-asl/cuckoo_time_translator
How to activate NTP
The NTP
configuration is located within the clock parameter of the device configuration (JSON).
The JSON configuration can be retrieved by ifm3d/ifm3dpy CLI.
{
"device": {
"clock": {
"currentTime": 1581091007595569376,
"sntp": {
"active": true,
"activeServerAddress": "",
"activeServerName": "time1.google.com",
"availableServers": [],
"systemClockSynchronized": false
}
}
}
}
A NTP
address is not provided by default - "systemClockSynchronized": false
via ifmVIsionAssistant
.. warning:: It is not yet possible to provide the NTP server address to the O3R via the ifmVisionAssistant.
via ifm3d API
Receive the currently provided NTP server addresses and the currently used NTP address:
from ifm3dpy.device import O3R
o3r = O3R()
print(o3r.get(["/device/clock"]))
To connect the O3R to an NTP
server, provide the server address - availableServers
:
# Output available servers --> No Servers
print(o3r.get(["/device/clock/sntp/availableServers"]))
#set your local IP as an available server
o3r.set({'device': {'clock': {'sntp': {'availableServers': ["192.168.0.110"]}}}})
o3r.get(["/device/clock/sntp/availableServers"])
# Output: {'device': {'clock': {'sntp': {'availableServers': ['192.168.0.110']}}}}
After providing a valid NTP
address:
{
"device": {
"clock": {
"currentTime": 1676038117923030927,
"sntp": {
"active": true,
"activeServerAddress": "192.168.0.110",
"activeServerName": "192.168.0.110",
"availableServers": [
"192.168.0.110"
],
"systemClockSynchronized": true
}
}
}
}
Evaluating NTP configuration
After the NTP synchronization, the current time
on the OVP8xx should reflect the NTP time.
Without an NTP connection:
o3r.get(["/device/clock/currentTime"])
# Output of above line: {'device': {'clock': {"currentTime": 1581091007595569376}}}
datetime.datetime.utcfromtimestamp(o3r.get(["/device/clock/currentTime"])["device"]["clock"]["currentTime"] // 1000000000)
datetime.datetime(2020, 2, 7, 15, 56, 47) # System time without NTP connection
With NTP connection:
o3r.get(["/device/clock/sntp/availableServers"])
# Output of above line: {'device': {'clock': {'sntp': {'availableServers': []}}}}
o3r.set({'device': {'clock': {'sntp': {'availableServers': ["192.168.0.110"]}}}})
o3r.get(["/device/clock/sntp/availableServers"])
# Output of above line: {'device': {'clock': {'sntp': {'availableServers': ['192.168.0.110']}}}}
o3r.get(["/device/clock/currentTime"])
# Output of above line: {'device': {'clock': {'currentTime': 1676037142019902053}}}
print(datetime.datetime.utcfromtimestamp(o3r.get(["/device/clock/currentTime"])["device"]["clock"]["currentTime"] // 1000000000))
print(datetime.datetime(2023, 2, 10, 14, 2, 12) # System time with NTP connection)
The system time itself is not enough to verify the time synchronization. It is important to see if the timestamp provided by an data frame is also synchronized.
from ifm3dpy.device import O3R
from ifm3dpy.framegrabber import FrameGrabber, buffer_id
import datetime
fg = FrameGrabber(O3R(),50012)
fg.start([buffer_id.NORM_AMPLITUDE_IMAGE])
[ok, frame] = fg.wait_for_frame().wait_for(1500)
if ok:
print(frame.timestamps())
print(datetime.datetime(2023, 2, 10, 15, 22, 43, 608748))