Time Synchronization

Open in Claude

Timing Overview Diagram

Signal path with MULTIPURPOSE_IO set as input Signal path with MULTIPURPOSE_IO set as output

Sensor Time Source

  • All lidar and IMU data shares a common timer with 10 ns precision.

  • The timer runs from one of three clock sources:

  • An internal clock derived from a high accuracy, low drift oscillator.

  • An opto-isolated digital input from the external connector for timing off an external hardware trigger such as a GPS. The polarity of this input signal is programmable. For instance, both a GPS PPS pulse and a 30 Hz frame sync from an industrial camera can supply a timing signal to the sensor.

  • The IEEE 1588 Precision Time Protocol. PTP provides the convenience of configuring timing over a network that supports IEEE 1588 with no additional hardware signals.

Setting Ouster Sensor Time Source

The source for measurement timestamps can be configured using the timestamp_mode. The available modes are described below:

CommandResponse
TIME_FROM_INTERNAL_OSCUse the internal clock. Free running counter based on the sensor’s internal oscillator. Counts seconds and nanoseconds since sensor turn on, reported at ns resolution (both a second and nanosecond register in every UDP packet), but minimum increment is on the order of 10 ns.
TIME_FROM_SYNC_PULSE_INA free running counter synced to the SYNC_PULSE_IN input counts seconds (# of pulses) and nanoseconds since sensor turn on. If multipurpose_io_mode is set to INPUT_NMEA_UART then the seconds register jumps to time extracted from a NMEA $GPRMC message read on the multipurpose_io port. Reported at ns resolution (both a second and nanosecond register in every UDP packet), but minimum increment is on the order of 10 ns.
TIME_FROM_PTP_1588Synchronize with an external PTP master. A monotonically increasing counter that will begin counting seconds and nanoseconds since startup. As soon as a 1588 sync event happens, the time will be updated to seconds and nanoseconds since 1970. The counter must always count forward in time. If another 1588 sync event happens the counter will either jump forward to match the new time, or slow itself down. It is reported at ns resolution (there is both a second and nanosecond register in every UDP packet), but the minimum increment varies.

When synchronizing from an external sync pulse, specify the pulse polarity as described in the Sensor-configuration section. The input frequency is assumed to be 1 Hz. The following POST commands configure an active-low pulse with the seconds timestamp tracking pulse count since startup:

  • time-stamp-mode
  • sync_pulse_in_polarity

To accept an external NMEA UART message, set multipurpose_io_mode to INPUT_NMEA_UART as described in the external-clock section. When the sensor receives a valid UART message, the seconds timestamp snaps to the received value. The following commands configure an active-high NMEA input at 115200 bps with 27 leap seconds, ignoring the valid-character flag:

  • time-sync-multipurpose-io-mode
  • nmea-in-polarity
  • nmea-baud-rate
  • nmea-leap-seconds
  • nmea_ignore_valid_char

External Trigger Clock Source

The sensor can also output a SYNC_PULSE_OUT signal from various sources. See the http-api section for example commands. Output pulses are always evenly spaced.

Enable this via the multipurpose_io_mode configuration parameter.

ConfigurationResponse
OFFDo not output a SYNC_PULSE_OUT signal.
INPUT_NMEA_UARTReconfigures the MULTIPURPOSE_IO port as an input. See setting-sensor-time for more information.
OUTPUT_FROM_INTERNAL_OSCOutput a SYNC_PULSE_OUT signal synchronized with the internal clock.
OUTPUT_FROM_SYNC_PULSE_INOutput a SYNC_PULSE_OUT signal synchronized with a SYNC_PULSE_IN provided to the unit.
OUTPUT_FROM_PTP_1588Output a SYNC_PULSE_OUT signal synchronized with an external PTP IEEE 1588 master.
OUTPUT_FROM_ENCODER_ANGLEOutput a SYNC_PULSE_OUT signal with a user defined rate in an integer number of degrees.

When multipurpose_io_mode is OUTPUT_FROM_INTERNAL_OSC, OUTPUT_FROM_SYNC_PULSE_IN, or OUTPUT_FROM_PTP_1588, set the output rate using sync_pulse_out_frequency (Hz). Defaults to 1 Hz. Must be greater than 0 Hz; maximum is limited by the criterion below.

When multipurpose_io_mode is OUTPUT_FROM_ENCODER_ANGLE, set sync_pulse_out_angle (degrees) to pulse at each multiple of that angle, indexed from the 0° crossing. Must be an integer between 0 and 360, inclusive; the minimum is also limited by the criterion below.

In all modes, sync_pulse_out_pulse_width (ms) sets the output pulse width.

Note: If sync_pulse_out_pulse_width x sync_pulse_out_frequency is close to 1 second, the output pulses will not function (will not return to 0). For example, at 10 Hz rotation and a 10 ms pulse width, the limitation on the number of pulses per rotation is 9.

Examples

Examples below assume lidar_mode = 1024x10 and sync_pulse_out_pulse_width = 10 ms. For full POST command syntax, see the http-api section.

Configuration (POST /api/v1/sensor/config)Response
multipurpose_io_mode=OUTPUT_FROM_SYNC_PULSE_IN
sync_pulse_out_pulse_width=10
sync_pulse_out_frequency=1
The output pulse frequency is 1 Hz. Each pulse is 10 ms wide. sync_pulse_out_pulse_width and sync_pulse_out_frequency commands are optional because they just re-command the default values.
multipurpose_io_mode=OUTPUT_FROM_SYNC_PULSE_IN
sync_pulse_out_frequency=50
The output pulse frequency is 50 Hz. Each pulse is 10 ms wide.
multipurpose_io_mode=OUTPUT_FROM_ENCODER_ANGLE
sync_pulse_out_angle=360
The output pulse frequency is 10 Hz, since the sensor is in 10 Hz mode (10 rotations/sec) and the angle is set to 360°, a full rotation. Each pulse is 10 ms wide.
multipurpose_io_mode=OUTPUT_FROM_ENCODER_ANGLE
sync_pulse_out_angle=45
The output pulse frequency is 80 Hz, since the sensor is in 10 Hz mode (10 rotations/sec) and the angle is set to 45°. Each full rotation will have 8 pulses. Each pulse is 10 ms wide.

NMEA Message Format

The sensor expects a standard NMEA GPRMCUARTmessage.EachsentenceisanASCIIstringstartingwithGPRMC UART message. Each sentence is an ASCII string starting with `and ending with a return character. Fields are comma-separated; the last field (checksum) is delimited by*`.

Standard messages are up to 80 characters. The sensor accepts non-standard messages up to 85 characters (see Example 2).

The sensor derives time from seconds since 1970-01-01 00:00:00 UTC. nmea_leap_seconds defaults to 0 (Unix Epoch time, no leap second correction). As of February 2019, UTC lags TAI by 37 s (10 s initial offset + 27 accumulated leap seconds). Setting nmea_leap_seconds to 37 aligns timestamps with TAI.

nmea_in_polarity defaults to ACTIVE_HIGH (start bit after a falling edge). For RS-232 (inverted polarity, start bit after a rising edge), set nmea_in_polarity to ACTIVE_LOW.

Example 1 Message:

$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A

FieldDescription
$GPRMCRecommended Minimum sentence C
123519Fix taken at 12:35:19 UTC
AStatus A=active or V=Void
4807.038Latitude 48 deg 07.038’
NLatitude cardinal reference
01131.000Longitude 11 deg 31.000’
ELongitude cardinal reference
022.4Speed over the ground in knots
084.4Track angle in degrees True
230394Date - 23rd of March 1994
003.1Magnetic Variation
WMagnetic cardinal reference
A[Optional] A=autonomous, D=differential, E=Estimated, N=not valid, S=Simulator
*6AThe checksum data, always begins with *

Example 2 Message:

$GPRMC,042901.00,A,3745.871698,N,12224.825960,W,0.874,327.72,130219,13.39,E,A,*60

FieldDescription
$GPRMCRecommended Minimum sentence C
042901.00Fix taken at 4:29:01 UTC
AStatus A=active or V=Void
3745.871698Latitude 37 deg 45.871698’
NLatitude cardinal reference
12224.825960Longitude 12 deg 24.825960’
WLongitude cardinal reference
0.874Speed over the ground in knots
327.72Track angle in degrees True
130219Date - 13th of February 2019
13.39Magnetic Variation
EMagnetic cardinal reference
A[Optional] A=autonomous, D=differential, E=Estimated, N=not valid, S=Simulator
*60The checksum data, always begins with *