The sensor service supports the use of Precision Time Protocol to synchronize the timestamps for sensors across multiple target boards.
The sensor service generates the timestamps for the sensors based on the target board where the Precision Time Protocol daemon (ptpd) was started as master. Other targets run (ptpd) as slave and timestamps for sensors are synchronized across the multiple target boards.
For more information on the Precision Time Protocol daemon, see ptpd.
When you use Precision Time Protocol to synchronize sensor timestamps, you need to:
In the sensor configuration file on each target board, you must specify the sensors to use Precision Time Protocol. For example:
begin SENSOR_UNIT_1 type = file_data name = vu8 address = /usr/share/sensor_data/adas_example_leddartech_vu8 direction = 0,0,0 position = 0,0,0 reference_clock = ptp end SENSOR_UNIT_1
To start ptpd as master on one of your QNX targets, you can add a component to the SLM configuration file on the target that's running as master. For example:
... <SLM:component name="ptpd-master"> <SLM:command>/base/scripts/ptpd-start-master.sh</SLM:command> <SLM:depend>settime</SLM:depend> <SLM:waitfor wait="pathname">/dev/ptpd</SLM:waitfor> </SLM:component> <SLM:component name="sensor"> <SLM:command>/base/bin/sensor</SLM:command> <SLM:args>-U 521:521,1001 -r /accounts/1000/shared/camera -c /base/etc/system/config/leddartech_vu8_capture_ptp.conf -d /base/etc/system/config/leddartech_vu8_capture_interim.conf</SLM:args> <SLM:depend>resarb</SLM:depend> <SLM:depend>ptpd-master</SLM:depend> <SLM:depend>screen-ready</SLM:depend> <SLM:waitfor wait="pathname">/dev/sensor/data1</SLM:waitfor> </SLM:component> ...where ptpd-start-master.sh is a script that starts ptpd in master mode. For example:
#!/bin/sh # start the PTP daemon in master mode ptpd -W -K -L -b $ETHERNET_IF_NAME
To start ptpd as slave on your other QNX targets, add a component to the SLM configuration file on each of the targets that are running as slave. For example:
... <SLM:component name="ptpd-slave"> <SLM:command>/base/scripts/ptpd-start-slave.sh</SLM:command> <SLM:depend>settime</SLM:depend> <SLM:waitfor wait="pathname">/dev/ptpd</SLM:waitfor> </SLM:component> <SLM:component name="sensor"> <SLM:command>/base/bin/sensor</SLM:command> <SLM:args>-U 521:521,1001 -r /accounts/1000/shared/camera -c /base/etc/system/config/leddartech_vu8_capture_ptp.conf</SLM:args> <SLM:depend>resarb</SLM:depend> <SLM:depend>ptpd-slave</SLM:depend> <SLM:depend>screen-ready</SLM:depend> <SLM:waitfor wait="pathname">/dev/sensor/sensor1</SLM:waitfor> </SLM:component> ...where ptpd-start-slave.sh is a script that starts ptpd in slave mode. For example:
#!/bin/sh # start the PTP daemon in slave mode ptpd -g -K -L -b $ETHERNET_IF_NAME
The following example illustrates how you can run ptpd and use it to synchronize the timestamps for sensors across two target boards. In this example, we have two target boards and use specific applications that are available in the ADAS reference images (pip_pubsub, sensor_example). You can use your own applications to receive and process information across multiple boards.
In this example, the target boards are configured follows:
... begin SENSOR_UNIT_1 type = file_data name = vu8 address = /usr/share/sensor_data/adas_example_leddartech_vu8 direction = 0,0,0 position = 0,0,0 reference_clock = ptp end SENSOR_UNIT_1 ...
... begin SENSOR_UNIT_1 name = vu8 data_format = SENSOR_FORMAT_LIDAR_POLAR num_buffers = 2 buffer_size = 10000 direction = 0,0,0 position = 0,0,0 end SENSOR_UNIT_1 ...
... <SLM:component name="ptpd-master"> <SLM:command>/base/scripts/ptpd-start-master.sh</SLM:command> <SLM:depend>settime</SLM:depend> <SLM:waitfor wait="pathname">/dev/ptpd</SLM:waitfor> </SLM:component> <SLM:component name="sensor"> <SLM:command>/base/bin/sensor</SLM:command> <SLM:args>-U 521:521,1001 -r /accounts/1000/shared/camera -c /base/etc/system/config/leddartech_vu8_capture_ptp.conf -d /base/etc/system/config/leddartech_vu8_capture_interim.conf</SLM:args> <SLM:depend>resarb</SLM:depend> <SLM:depend>ptpd-master</SLM:depend> <SLM:depend>screen-ready</SLM:depend> <SLM:waitfor wait="pathname">/dev/sensor/data1</SLM:waitfor> </SLM:component> <SLM:component name="pips_pubsub"> <SLM:command>/base/usr/bin/pips_pubsub</SLM:command> <SLM:args>-s</SLM:args> <SLM:depend>sensor</SLM:depend> <SLM:stop stop="signal">SIGTERM</SLM:stop> </SLM:component> <SLM:component name="sensor_example_sensor_stream"> <SLM:command>/base/usr/bin/sensor_example</SLM:command> <SLM:args>-e 1 -u 1 -b 0 -d</SLM:args> <SLM:depend>sensor</SLM:depend> <SLM:stop stop="signal">SIGTERM</SLM:stop> </SLM:component> <SLM:component name="sensor_example_data_subscriber"> <SLM:command>/base/usr/bin/sensor_example</SLM:command> <SLM:args>-e 4 -u 1 -b 0 -d</SLM:args> <SLM:depend>pips_pubsub</SLM:depend> <SLM:stop stop="signal">SIGTERM</SLM:stop> </SLM:component> ...
... begin SENSOR_UNIT_1 type = file_data name = vu8 address = /usr/share/sensor_data/adas_example_leddartech_vu8 direction = 0,0,0 position = 0,0,0 reference_clock = ptp end SENSOR_UNIT_1 ...
... <SLM:component name="ptpd-slave"> <SLM:command>/base/scripts/ptpd-start-slave.sh</SLM:command> <SLM:depend>settime</SLM:depend> <SLM:waitfor wait="pathname">/dev/ptpd</SLM:waitfor> </SLM:component> <SLM:component name="sensor"> <SLM:command>/base/bin/sensor</SLM:command> <SLM:args>-U 521:521,1001 -r /accounts/1000/shared/camera -c /base/etc/system/config/leddartech_vu8_capture_ptp.conf</SLM:args> <SLM:depend>resarb</SLM:depend> <SLM:depend>ptpd-slave</SLM:depend> <SLM:depend>screen-ready</SLM:depend> <SLM:waitfor wait="pathname">/dev/sensor/sensor1</SLM:waitfor> </SLM:component> <SLM:component name="pips_pubsub"> <SLM:command>/base/usr/bin/pips_pubsub</SLM:command> <SLM:args>-p</SLM:args> <SLM:depend>sensor</SLM:depend> <SLM:stop stop="signal">SIGTERM</SLM:stop> </SLM:component>; ...
In this example, when you start target board A, you see that an instance of sensor_example shows the sensor information (including the timestamp) for the local sensor on this board. For example:
... Dec 20 15:40:18.572 sensor_example.544794 0 Received buffer 29370 (58998us since previous): time 17935358 Dec 20 15:40:18.572 sensor_example.544794 0 Received buffer 29371 (57998us since previous): time 17993358 Dec 20 15:40:18.572 sensor_example.544794 0 Received buffer 29372 (57997us since previous): time 18051358 Dec 20 15:40:18.572 sensor_example.544794 0 Received buffer 29373 (58998us since previous): time 18110358 ...
When you start target board B, pips_pubsub on board B starts publishing its sensor data to board A. At this point, the second instance of sensor_example on board A starts showing sensor information from board B. For example:
... Dec 20 15:40:18.637 sensor_example.544793 0 Received buffer 34313 (57997us since previous): time 18175169 Dec 20 15:40:18.637 sensor_example.544793 0 Received buffer 34314 (57998us since previous): time 18233169 Dec 20 15:40:18.637 sensor_example.544793 0 Received buffer 34315 (57998us since previous): time 18291169 Dec 20 15:40:18.637 sensor_example.544793 0 Received buffer 34316 (58997us since previous): time 18350169 ...
Accounting for latency to publish the sensor data from the slave to the master, you should see the timestamps for both sensors synchronized to within a few hundredths of milliseconds.