Synchronizing Sensor Timestamps

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:

  1. Specify ptp with the reference_clock parameter in your sensor configuration file for the units whose timestamps you want synchronized.

    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
                
  2. Specify ptpd to start as master on one of the target boards (must be started prior to starting the sensor service).

    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
                      
    Note: Ensure that you start ptpd before you start sensor.
  3. Specify ptpd to start as slave on the other target boards (must be started prior to starting the sensor service).

    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
                         
    Note: Ensure that you start ptpd before you start sensor.

Example

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:

Target board A (master)
This target has a sensor configuration file that has:
  • a sensor unit of type configured (in a sensor configuration file called leddartech_vu8_capture_ptp.conf)to use reference_clock of ptp:
    ...
    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
    ...
                                
  • a sensor interim data unit configured (in a sensor configuration file called leddartech_vu8_capture_interim.conf) to receive sensor data information from the other target:
    ...
    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
    ...
                                
Its SLM configuration file specifies to run:
  • ptpd as master
  • sensor with a sensor configuration file and an interim data configuration file
  • pips_pubsub in subscriber mode to receive information from the slave target board
  • two instances sensor_example: one to process the stream of data from the configured sensor, and one to subscribe to the interim sensor data unit that represents the data from the sensor on the slave target.
    ...
    <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>
    ...
                                    
Target board B (slave)
This target has a sensor configuration file that has:
  • a sensor unit of type configured (in a sensor configuration file called leddartech_vu8_capture_ptp.conf)to use reference_clock of ptp:
    ...
    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
    ...
                                
Its SLM configuration file specifies to run:
  • ptpd as slave
  • sensor with a sensor configuration file
  • pips_pubsub in publisher mode to send information to the master target board
  • sensor_example: one to process the stream of data from the configured sensor
    ...
    <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.