Description: | Sample code provided for working with Ouster sensors |
---|
Contents:
This package is a part of a sample code provided by the manufacture that allows working with Ouster LiDAR sensor OS1 to publish the point cloud and IMU data.
To update and configure the static IP of the Ouster LiDAR sensor, see section Update the sensor settings. For instructions of compile, see section How to compile this package. To synchronize the timestamp of the sensor and the grandmaster PC (robot), see section Time synchronization between the Ouster LiDAR and the grandmaster PC. To check the time synchronization status, see section Check if the timestamping is available. Finally, to run this package see the last section To run this package.
This repository contains sample code for connecting to and configuring ouster sensors, reading and visualizing data, and interfacing with ROS.
- ouster_client contains an example C++ client for ouster sensors
- ouster_viz contains a basic point cloud visualizer
- ouster_ros contains example ROS nodes for publishing point cloud messages
To update the sensor firmware you need to first download the new firmware image from the manufacturer's website.
To do this:
- Access the sensor settings to click here or write
http://192.168.1.61
in your browser; - Go to the Firmware Update and click in Browse;
- Choose the image file downloaded;
- Click in Update.
In a few minutes, the update will be finished.
If necessary you can set a new static IP to the sensor. To do this paste the command in your terminal:
curl -i -X PUT http://x.x.x.x/api/v1/system/network/ipv4/override -H 'Content-Type: application/json' --data-raw '"y.y.y.y/24"'
change x.x.x.x to the current sensor IP and y.y.y.y to the new static IP.
Compile using Release build type to improve performance:
catkin build ouster_client --cmake-args -DCMAKE_BUILD_TYPE=Release catkin build ouster_viz --cmake-args -DCMAKE_BUILD_TYPE=Release catkin build ouster_ros --cmake-args -DCMAKE_BUILD_TYPE=Release
If the Release mode is not set, the ROS node will have problems for publishing LiDAR messages with a quality greater than 512x10.
The Precision Time Protocol (PTP) is a protocol used to synchronize clocks in a network. When used in conjunction with hardware support, PTP is capable of sub-microsecond accuracy, which is far better than is normally obtainable with other types of network time sincronization such as NTP.
The Ouster OS1 has the option of PTP time synchronization with the host by setting the timestamp_mode
to TIME_FROM_PTP_1588
.
For PTP synchronization three linux programs are used:
- The linuxptp is a package with the following components: - ptp4l daemon to manage hardware and participate as a PTP node; - phc2sys to synchronize the Ethernet controller’s hardware clock to the Linux system clock or shared memory region; - pmc to query the PTP nodes on the network.
- The chrony is a NTP and PTP time synchronization daemon. It can be configured to listen to both NTP time sources via the Internet and a PTP master clock such as one provided a GPS with PTP support. This will validate the time configuration makes sense given multiple time sources.
- The ethtool is a tool to query the hardware and driver capabilities of a given Ethernet interface.
To install this paste the the command in your terminal:
sudo apt install linuxptp chrony ethtool
** For more reading, please visit Software User Guide.
Before starting synchronization, you need to verify that your Ethernet interface has compatible features. To do this, run ethtool as in the command below:
sudo ethtool -T eno1
change eno1
to your interface name.
If your ethernet card supports time synchronization you will see something similar to the message below:
Time stamping parameters for eno1: Capabilities: hardware-transmit (SOF_TIMESTAMPING_TX_HARDWARE) software-transmit (SOF_TIMESTAMPING_TX_SOFTWARE) hardware-receive (SOF_TIMESTAMPING_RX_HARDWARE) software-receive (SOF_TIMESTAMPING_RX_SOFTWARE) software-system-clock (SOF_TIMESTAMPING_SOFTWARE) hardware-raw-clock (SOF_TIMESTAMPING_RAW_HARDWARE) PTP Hardware Clock: 0 Hardware Transmit Timestamp Modes: off (HWTSTAMP_TX_OFF) on (HWTSTAMP_TX_ON) Hardware Receive Filter Modes: none (HWTSTAMP_FILTER_NONE) all (HWTSTAMP_FILTER_ALL) ptpv1-l4-sync (HWTSTAMP_FILTER_PTP_V1_L4_SYNC) ptpv1-l4-delay-req (HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) ptpv2-l4-sync (HWTSTAMP_FILTER_PTP_V2_L4_SYNC) ptpv2-l4-delay-req (HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) ptpv2-l2-sync (HWTSTAMP_FILTER_PTP_V2_L2_SYNC) ptpv2-l2-delay-req (HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) ptpv2-event (HWTSTAMP_FILTER_PTP_V2_EVENT) ptpv2-sync (HWTSTAMP_FILTER_PTP_V2_SYNC) ptpv2-delay-req (HWTSTAMP_FILTER_PTP_V2_DELAY_REQ)
The ptp4l program implements the PTP threshold clock and the common clock. To configure the ptp4l service, first create a systemd drop-in directory to replace the system service file:
sudo mkdir -p /etc/systemd/system/ptp4l.service.d
After, create a file at /etc/systemd/system/ptp4l.service.d/override.conf
with the following contents:
[Service] ExecStart= ExecStart=/usr/sbin/ptp4l -f /etc/linuxptp/ptp4l.conf -i eno1
Edit the config file /etc/linuxptp/ptp4l.conf
and set:
#clockClass 248 clockClass 128
Restart the ptp4l service so the change takes effect:
sudo systemctl daemon-reload sudo systemctl enable ptp4l sudo systemctl restart ptp4l sudo systemctl status ptp4l
To synchronize the Linux system time to the the PTP hardware clock the phc2sys utility needs to be run. The following configuration will tell phc2sys to take the Linux CLOCK_REALTIME
and write that time to the PTP hardware clock in the Ethernet controller for your ethernet interface, e.g. eno1
. These interfaces are then connected to PTP slaves such as Ouster OS1 sensors.
To do this, first create a systemd drop-in directory to replace the system service file:
sudo mkdir -p /etc/systemd/system/phc2sys.service.d
After, create a file at /etc/systemd/system/phc2sys.service.d/override.conf
with the following contents:
[Service] ExecStart= ExecStart=/usr/sbin/phc2sys -w -s CLOCK_REALTIME -c eno1 -O 0
The -O 0
parameter is for overcoming a leap second offset (its 36 seconds).
Restart the phc2sys service so the change takes effect:
sudo systemctl daemon-reload sudo systemctl enable phc2sys sudo systemctl restart phc2sys sudo systemctl status phc2sys
Chrony is a Linux time service that can read from NTP and PTP and set the Linux system time using the most accurate source available. With a proper functioning PTP grandmaster the PTP time source will be selected and the error from the public time servers can be reviewed.
To do this, first create a file named /etc/systemd/system/phc2shm.service
with the following contents:
# /etc/systemd/system/phc2shm.service [Unit] Description=Synchronize PTP hardware clock (PHC) to NTP SHM Documentation=man:phc2sys After=ntpdate.service Requires=ptp4l.service After=ptp4l.service [Service] Type=simple ExecStart=/usr/sbin/phc2sys -s eno1 -E ntpshm -w [Install] WantedBy=multi-user.target
Then start the newly created service and check that it started:
sudo systemctl daemon-reload sudo systemctl start phc2shm sudo systemctl status phc2shm
Append the following to end of the /etc/chrony/chrony.conf
file:
refclock SHM 0 poll 1 refid ptp
Restart chrony so the updated configuration file takes effect:
sudo systemctl restart chrony sudo systemctl status chrony
After waiting a minute for the clock to synchronize, review the timing accuracy of the chrony client by writing the following command:
chronyc tracking
You see the message as below:
Reference ID : 70747000 (ptp) Stratum : 1 Ref time (UTC) : Thu Mar 14 02:22:58 2019 System time : 0.000000298 seconds slow of NTP time Last offset : -0.000000579 seconds RMS offset : 0.001319735 seconds Frequency : 0.502 ppm slow Residual freq : -0.028 ppm Skew : 0.577 ppm Root delay : 0.000000001 seconds Root dispersion : 0.000003448 seconds Update interval : 2.0 seconds Leap status : Normal
And writing the following command:
chronyc sources -v
You see the message as below:
210 Number of sources = 9 .-- Source mode '^' = server, '=' = peer, '#' = local clock. / .- Source state '*' = current synced, '+' = combined , '-' = not combined, | / '?' = unreachable, 'x' = time may be in error, '~' = time too variable. || .- xxxx [ yyyy ] +/- zzzz || Reachability register (octal) -. | xxxx = adjusted offset, || Log2(Polling interval) --. | | yyyy = measured offset, || \ | | zzzz = estimated error. || | \ MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== #* ptp 0 1 377 1 +27ns[ +34ns] +/- 932ns ^- chilipepper.canonical.com 2 6 377 61 -482us[ -482us] +/- 99ms ^- pugot.canonical.com 2 6 377 62 -498us[ -498us] +/- 112ms ^- golem.canonical.com 2 6 337 59 -467us[ -468us] +/- 95ms ^- alphyn.canonical.com 2 6 377 58 +957us[ +957us] +/- 95ms ^- legacy13.chi1.ntfo.org 3 6 377 62 -10ms[ -10ms] +/- 178ms ^- tesla.selinc.com 2 6 377 128 +429us[ +514us] +/- 42ms ^- io.crash-override.org 2 6 377 59 +441us[ +441us] +/- 58ms ^- hadb2.smatwebdesign.com 3 6 377 58 +1364us[+1364us] +/- 99ms
The delay must be less than 1:
rostopic delay /os1_cloud_node/imu
To verify if the hardware clock is synchronized with the computer run:
sudo phc_ctl eno1 get | grep -Po '[0-9\.]{10,30}' | xargs -I {} date -d @{} && date
The two dates must be equal:
espeleo@espeleo-robo:~$ sudo phc_ctl eno1 get | grep -Po '[0-9\.]{10,30}' | xargs -I {} date -d @{} && date
Example of message:
Sex Set 25 18:04:46 -03 2020 Sex Set 25 18:04:46 -03 2020
Acces the LiDAR web api time information using wget
command. First install the jq
command for visualizing the response in a clear way:
sudo apt install jq
Verify system clock:
wget -nv -O- http://192.168.1.61/api/v1/system/time/system | jq
Example:
{ "tracking": { "remote_host": "ptp", "last_offset": -1.0602e-05, "frequency": 11.014, "skew": 1.913, "root_delay": 1e-09, "rms_offset": 9.603e-06, "reference_id": "70747000", "system_time_offset": 3.09e-06, "residual_frequency": -0.016, "ref_time_utc": 1601068094.6893108, "leap_status": "normal", "root_dispersion": 0.000119325, "update_interval": 2, "stratum": 1 }, "monotonic": 1995.410123256, "realtime": 1601068097.5325494 }
Verify PTP configuration:
wget -nv -O- http://192.168.1.61/api/v1/system/time/ptp | jq
Exemple:
{ "port_data_set": { "port_identity": "bc0fa7.fffe.0007ae-1", "log_sync_interval": 0, "log_min_delay_req_interval": 0, "log_min_pdelay_req_interval": 0, "log_announce_interval": 1, "version_number": 2, "port_state": "SLAVE", "delay_mechanism": 1, "peer_mean_path_delay": 0, "announce_receipt_timeout": 3 }, "current_data_set": { "offset_from_master": -209938, "mean_path_delay": 11551, "steps_removed": 1 }, "time_properties_data_set": { "time_traceable": 0, "leap59": 0, "current_utc_offset_valid": 0, "time_source": 160, "current_utc_offset": 36, "frequency_traceable": 0, "leap61": 0, "ptp_timescale": 1 }, "time_status_np": { "gm_identity": "001b21.fffe.e0be7c", "gm_present": true, "master_offset": -209938, "cumulative_scaled_rate_offset": 0, "gm_time_base_indicator": 0, "ingress_time": 1640816356984356000, "scaled_last_gm_phase_change": 0, "last_gm_phase_change": "0x0000'0000000000000000.0000" }, "profile": "default", "parent_data_set": { "gm_clock_class": 128, "grandmaster_priority2": 128, "gm_clock_accuracy": 254, "grandmaster_priority1": 128, "gm_offset_scaled_log_variance": 65535, "grandmaster_identity": "001b21.fffe.e0be7c", "parent_port_identity": "001b21.fffe.e0be7c-1", "parent_stats": 0, "observed_parent_clock_phase_change_rate": 2147483647, "observed_parent_offset_scaled_log_variance": 65535 } }
To run this package write the following command in your terminal:
roslaunch ouster_ros ouster_os1.launch
Note:
When you run this launch the services 'ptp4l,' 'phc2sys', 'phc2shm', and 'chrony' are reset first and after 5 seconds the ouster nodes are beginning. The LiDAR synchronization is monitored every 30 seconds. If the status of the sensor is UNCALIBRATED, the 'ptp4l' service is reset.
In order for ptp_check to work properly, change your pc's password in the launch file.
- Sample sensor output usable with the provided ROS code is available here.