Lidar Integration With Ros Noetic On The Nvidia Jetson Sbcs

Photo of shakhizat

Made by shakhizat / IoT

About the project

LiDAR integration with ROS Noetic using Docker containers on the Nvidia Jetson SBCs.

Project info

Difficulty: Difficult

Platforms: NVIDIA JetsonROS

Estimated time: 4 hours

License: MIT license (MIT)

Items used in this project

Hardware components

NVIDIA Jetson Xavier NX Developer KIT(Pre-order) NVIDIA Jetson Xavier NX Developer KIT(Pre-order) x 1
RPLIDAR A1M8 - 360 Degree Laser Scanner Development Kit RPLIDAR A1M8 - 360 Degree Laser Scanner Development Kit x 1

Story

Robot Operating System (ROS) is one of the popular open-source robotics software framework and its gained vast acceptance in the robotics community. ROS has been around for a long time and is widely used throughout the Robotics industry.

The Noetic Ninjemys is the new L.T.S release of ROS. It is going to be the 13thROS distribution. Noetic primary support is for Ubuntu 20.04 (Focal). The released date was May 23rd. 2020. You will get support for ROS Noetic up to 2025. What's nice about ROS Noetic is that it targets Python 3.

There are two ways of using ROS Noetic with the Nvidia Jetson boards:

  • Flash the Jetpack image with Ubuntu 18.04, upgrade Ubuntu to 20.04 and then install ROS Noetic normally using sudo apt-get install command.
  • The second option is to install using Dockerfile for building ROS Noetic from source for 18.04 on JetPack 4.4.

In this tutorial, you will learn how to connect and integrate your LiDAR with your remote computer using ROS Noetic middleware and Docker on the Nvidia Jetson board. We will be using Rviz which is a very powerful ROS tool for visualizing the status of your robot, sensor information, map building, navigation, and debugging.

Following this tutorial with the talker being your Nvidia Jetson board with ROS Noetic master and the listener being your remote laptop with ROS Melodic. In order to communicate with the Jetson board from remote laptop, a WiFi router is used. For this tutorial assume that the remote computer and the Nvidia Jetson board are connected to the same WIFI network.

Hardware required

Before you get started with this tutorial, you will need the following:

  • NVIDIA Jetson board
  • RPLidar A1M8 with connector. The connector is being used for charging, data transfer and controlling the device.
  • High-performance microSD card: 32GB minimum
  • MicroSD to SD adapter
  • A computer with an internet connection and the ability to flash your microSD card. Here we’ll be using laptop.
  • The Jetson Nano Developer Kit doesn’t include a WiFi module, so you have two options. You can either connect your Jetson Nano directly to your laptop using an ethernet cable and then set up a static IP and share your network, or you can add a USB WiFi adapter and connect the Nano to the same WiFi network that your laptop is using. Here we’ll be using a USB WiFi adapter.

Additional requirements
  • Some experience with ROS build system is helpful but not required.
  • Familiar with the Linux command line, a shell like bash, and an editor like nano.
  • ROS applications use a lot of compute resources and the heat sink may not be enough for the heat generated. Consider adding a cooling fan. I recommend you use the ICE Tower CPU Cooling Fan for Nvidia Jetson Nano.

NVIDIA Jetson Xavier NX Developer Kit

Here, I will be using Nvidia Xavier NX board. Compared to the Jetson Nano, the Xavier NX is anywhere between two to seven times faster, depending on the application.

Don't forget to check out my previous post about the NVIDIA Jetson Xavier NX Developer Kit.

RPLidar A1M8

RPLIDAR is a low-cost LIDAR sensor suitable for indoor robotic SLAM(Simultaneous localization and mapping) application. It can be used in the other applications such as:

  • General robot navigation and localization
  • Obstacle avoidance
  • Environment scanning and 3D modeling

RPLIDAR A1 Development Kit contains:

  • RPLIDAR A1
  • USB Adapter with communication cable
  • Documentation

The Micro-USB cable does not included. So, let's get started.

Step 1 - Flash the Jetpack image to the SD card and boot it up

The Jetson platform from NVIDIA runs a flavor of Debian called L4T (Linux for Tegra) which is based on Ubuntu 18.04. The OS along with the CUDA-X drivers and SDKs is packaged into JetPack, a comprehensive software stack for the Jetson family of products such as Jetson Nano and Jetson Xavier.

  • Start by downloading the most recent version of JetPack and flash your Jetson device with it. The Jetson image comes pre-installed with Docker Engine.
  • Write the image to your microSD card by the instructions according to the type of computer you are using: Windows, Mac, or Linux. I highly recommend to use balenaEtcher tool.
  • Power up your Jetson board.

I assume that you have already installed JetPack on the NVIDIA Jetson board.

Verify OS running on Jetson board using below command terminal prompt:

sudo cat /etc/os-release

You should get a response that looks like the one below.

NAME="Ubuntu"VERSION="18.04.5 LTS (Bionic Beaver)"ID=ubuntuID_LIKE=debianPRETTY_NAME="Ubuntu 18.04.5 LTS"VERSION_ID="18.04"HOME_URL="https://www.ubuntu.com/"SUPPORT_URL="https://help.ubuntu.com/"BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"VERSION_CODENAME=bionicUBUNTU_CODENAME=bionic

Check the version of Docker with the below command:

docker version

It shows the current version of the Docker Engine installed on the Jetson board.

Client:Version:  19.03.6API version:  1.40Go version: go1.12.17Git commit: 369ce74a3cBuilt:  Fri Feb 28 23:47:53 2020OS/Arch:  linux/arm64Experimental: falseServer:Engine:Version: 19.03.6API version: 1.40 (minimum version 1.12)Go version:  go1.12.17Git commit:  369ce74a3cBuilt: Wed Feb 19 01:06:16 2020OS/Arch: linux/arm64Experimental:  falsecontainerd:Version: 1.3.3-0ubuntu1~18.04.2GitCommit:runc:Version: spec: 1.0.1-devGitCommit:docker-init:Version: 0.18.0GitCommit:

As you could see, on the Jetpack there is already a version of the Docker Engine installed. Starting with JetPack 4.2, NVIDIA has introduced a container runtime with Docker integration. This custom runtime enables Docker containers to access the GPUs available in the Jetson family.

Step 2 - Add Swap Memory(optional, only for Jetson Nano)

You can skip this step, if you are using NVIDIA Jetson Xavier board.

By default the Ubuntu 18.04 distribution of Jetson Nano comes with 2 GB of Swap memory.

To increase it we need to open the terminal and type the line:

sudo apt-get install zram-config

The zram module, on the Jetson nano allocates by default 2gb of Swap memory, so now we’re going to extend the size to 4gb by changing the configuration file.

Just type on the terminal:

sudo gedit /usr/bin/init-zram-swapping

And Replace the line:

mem=$(((totalmem / 2 / ${NRDEVICES}) * 1024))

with this line:

mem=$(((totalmem / ${NRDEVICES}) * 1024))

And then reboot your Jetson Nano.

Step 3 - Choose a ROS Noetic Docker image on the Jetson board

Docker is a container tool that allows you to run ROS Noetic without being on Ubuntu 20.04, which is the first-class OS that ROS officially supports.

Nvidia has created Dockerfile for deploying ROS and ROS2 distributions with the latest version of Jetpack on the Nvidia Jetson platform. There are:

  • ROS Melodic
  • ROS Noetic
  • ROS2 Eloquent
  • ROS2 Foxy

The dockerfile are available here. Clone a git repository.

git clone https://github.com/dusty-nv/jetson-containers

It clones all the files from the remote Git repository. Then go to folder jetson-containers.

cd jetson-containers

Open Dockerfile using a text editor and enter the following lines before ENTRYPOINT.

COPY ./rplidar_ros_install.sh /WORKDIR /RUN chmod +x rplidar_ros_install.sh &&     ./rplidar_ros_install.sh

Then, create a shell script in the docker directory that runs the RPLIDAR application:

nano runsrplidar_ros_install.sh

Add below code snippet into your runsrplidar_ros_install.sh file:

#!/bin/bash### init rossudo rosdep initrosdep updateecho "source /opt/ros/$ROS_DISTRO/setup.bash" >> ~/.bashrcsource ~/.bashrcsudo apt-get update &&     apt-get install -y git &&     apt-get install -y nano &&     apt-get install libeigen3-dev &&     apt-get install -y build-essential    sudo apt-get install -y ros-noetic-catkin python3-catkin-tools. "/opt/ros/$ROS_DISTRO/setup.bash"### Create a ROS Workspacemkdir -p ~/catkin_ws/srccd ~/catkin_ws/srccatkin_init_workspace### Clone the ROS node for the Lidar in the catkin workspace src dirgit clone https://github.com/robopeak/rplidar_ros.git### Build with catkincd ~/catkin_ws/catkin_make### Set environment when build is completesource devel/setup.bashrun./scripts/docker_build_ros.sh noetic

Then run below command to build the ROS Noetic container:

./scripts/docker_build_ros.sh noetic

It installs ROS Noetic base package, build and communication libraries. No any GUI tools will be installed. It is recommended for embedded computers, where you don’t have much hardware for graphical tools or real robots. It's installation process depends on how fast your internet is. If it's taking too long, it usually means either your internet is slow or slow SD card.

Once the process is completed, you should see the following output:

Successfully tagged ros:noetic-ros-base-l4t-r32.4.3

Now you have ROS Noetic Docker image. To see a list of Docker images on your machine, type:

sudo docker images

If everything goes correctly, you should see the following:

Then plug the USB cable to your RPLIDAR. Flashing green light indicates normal activity of sensor.

1 / 2

You can use the below command to check if that port file is writable and readable.

ls -l /dev | grep ttyUSB

Provide access to the ttyUSB0 by the following command:

sudo chmod 666 /dev/ttyUSB0

Run a Docker Container interactively using bellow command. You can use the --device flag that use can use to access USB devices without --privileged mode:

sudo docker run -it --device=/dev/ttyUSB0 IMAGE_ID bash

then run:

cd ~/catkin_ws/

Then run to source the environment with your current terminal. Don't close the terminal.

source devel/setup.bash

and start RPILIDAR launch file:

roslaunch rplidar_ros rplidar.launch

Roslaunch will automatically start a roscore. Let us first look at how raw data from LiDAR look like when they are published on topic /scan. Open another terminal window and run:

sudo docker exec -it CONTAINER_ID bash

You can check whether you have successfully set a container name by displaying a list of all containers with the command:

sudo docker ps -a

and finally run,

rostopic echo /scan

Now you should be able to see in the terminal the data from the LiDAR sensor.

header:   seq: 2669  stamp:     secs: 1604993333    nsecs: 617659834  frame_id: "laser"angle_min: -3.1241390705108643angle_max: 3.1415927410125732angle_increment: 0.01745329238474369time_increment: 0.00037774848169647157scan_time: 0.13561169803142548range_min: 0.15000000596046448range_max: 12.0

Our next step is to get data from LiDAR to show up in RVIZ. RVIZ is a ROS graphical interface that allows you to visualize a lot of information, using plugins for many kinds of available topics. To launch rviz, we need to open a new terminal window and run.

rviz

Output:

bash: rviz: command not found

We don't have support of GUI tools on ros base package. Workaround for the problem, you can install rviz outside of Docker container.

Installing rviz package on Ubuntu 18.04(JetPack) is as easy as running the following command on a new terminal:

sudo apt-get install -y rviz

and run rviz tool using below command.

rviz

You might see below an error message:

Close RPILIDAR terminal window. Press Ctrl-C to interrupt current session.

Then run it again with below command:

sudo docker run -it --device=/dev/ttyUSB0 --net=host IMAGE_ID bash -c "cd ~/catkin_ws/; source devel/setup.bash; roslaunch rplidar_ros rplidar.launch"

then launch rviz again:

The visualization is not showing due to problems with the frame name. We now need to tell rviz which fixed frame we want to use. Change fixed frame to laser.

To add objects you want to visualize, click Add button located in the left bottom corner of the RViZ GUI and then select LaserScan object, and then set the topic of LaserScan object to /scan.

Now you should see the visualization of LiDAR sensor measurements in the RViZ GUI.

Rviz will open with a map of the RPLIDAR’s surroundings. Alright, so we can visualize the laser scan data using rviz. It is not recommended to run rviz on most ARM-based CPUs. They're generally too slow, and the version of OpenGL that is provided by the software (mesa) libraries it not new enough to start rviz.

So now the next step will be to run ROS Noetic headlessly on the Nvidia Jetson board and visualize data on remote machine.

To visualize data and interact with nodes through RViz you don't need to run it on the machine running your roscore (roslaunch), as long as the machine running RViz is able to connect to the master on your headless machine. You basically setup a two machine ROS network, with only RViz on your desktop.

Step 4 - Running GUI applications using Docker on remote PC (Mac, Linux and Windows)

Docker images are like virtual machines or systems already set up. There are servers that provide images like this, so the users only have to download them. The main server is Docker hub. There, it is possible to search for Docker images for different systems and configurations.

Before starting this tutorial please complete installation as described in Docker's installation instructions. Installation instructions are available for multiple operation systems including Ubuntu, Mac OS x, Debian, Fedora and even Microsoft Windows.

If you don’t need GUI related stuff, the default noetic image should be the go-to image.

docker pull ros:noetic-ros-base

You can’t use tools with GUI such as rviz or gazebo. Rviz and Gazebo needs OpenGL which doesn't work via X forwarding..

I found following docker image that provides Lightweight X11 Desktop Environment (LXDE) and HTML5 VNC interface. In our case, we are going to use ROS Melodic images already available.

docker run -p 6080:80 tiryoh/ros-desktop-vnc:melodic

When you use docker run it automatically downloads (pulls) images. Once the image is downloaded we are done with the basic setup and can kick over to running our Linux GUI application from your browser.

Now you can browse http://localhost:6080/to access the desktop.

Different distros of ROS (Noetic, Melodic, Kinetic, etc) can communicate with each other. As you maybe understood, we have the different version of ROS on both machines.

Step 5 - How to connect Docker containers on two different hosts connected by LAN

For the most part, it's usually not practical to run all your applications on a single machine and when it's not, you'll need an approach for distributing the applications across many machines. This is where a Docker Networking with Multiple Hostscomes in.

There are multiple options to do that:

In this article, we'll create a Weave network configuration to establish communication between local and remote computers.

The Nvidia Jetson board and remote computer must be configured to set up communications on the same network. Each computer's IP address should be identified and used to establish the ROS environment variable for the communication system. Following picture shows the setup we will be build in this example:

Establishing the network described above seems like a straightforward task. However, it is not as easy as it seems. After a lot of trial and error, I am presenting one possible way of establishing this network. This may not be the best approach, but this is what worked out for me. One more note: the networking procedure described here is not specific to the hardware used. The same procedure can be followed on other hardware to achieve the desired functionality.

Step 6 - Docker Networking – Weave

The first step is to setup Weave network to communicate between Nvidia Jetson board and the remote computer. Below are the steps that I did to make both computers communicate with each other.

Weave Net is a virtual network on Docker, which can connect distributed Docker services into a virtual service network, just like running in a local area network. Weave creates a virtual network that enables users to connect docker containers on different host and enable their auto-discovery.

Step 6.1 - Install Weave

To install Weave you can run the following commands:

sudo wget -O /usr/local/bin/weave  https://github.com/weaveworks/weave/releases/download/latest_release/weave

Then

sudo chmod a+x /usr/local/bin/weave

We will need to run the Weave install on both of the machines(remote and local computers) that we are going to use in this example.

Step 6.2 - Launch weave container

Now that we have installed Weave on both machines, let’s start it up.

On the Nvidia Jetson SBC, type the following commands:

sudo weave launch --ipalloc-range IP_ADDRESS/SUBNET

Substitute IP_ADDRESS/SUBNET with your corresponding IP address and Subnet mask. By default they are assigned out of the 172.30.0.0/16 network. Our two hosts must be sitting in the same 172.30.0.0/16 subnet.

This command will internally pull weave container and run it

2.7.0: Pulling from weaveworks/weave788aef77d06b: Pull complete5917c3de3c5b: Pull complete88a99a6ea9fa: Pull completebe5927527da8: Pull completedb2e561331f8: Pull complete815885509273: Pull completeDigest: sha256:be309a6d90bb8663c479e6873ffc9f6265c40decac64c6b602af5084d851aef6Status: Downloaded newer image for weaveworks/weave:2.7.0docker.io/weaveworks/weave:2.7.0latest: Pulling from weaveworks/weavedb4e2a4496fae2: Pull completeDigest: sha256:836c82b6bf5039c5d240af4c4ef5d2ce50f826a66fceaac370992db1a82b7bb0Status: Downloaded newer image for weaveworks/weavedb:latestdocker.io/weaveworks/weavedb:latestUnable to find image 'weaveworks/weaveexec:2.7.0' locally2.7.0: Pulling from weaveworks/weaveexec788aef77d06b: Already exists5917c3de3c5b: Already exists88a99a6ea9fa: Already existsbe5927527da8: Already existsdb2e561331f8: Already exists815885509273: Already exists949522ea63d0: Pull complete44a89c8cdead: Pull complete6ff462315dd0: Pull complete6f22a32ecc4a: Pull completeDigest: sha256:17e8d712976e574d68181159d62f45449ee1b7376c200a87f2edd48890fc5650Status: Downloaded newer image for weaveworks/weaveexec:2.7.0

then run:

eval $(weave env)

That command will set the DOCKER_HOST environment variable to point to the Weave network.

Then on the remote host run below command:

sudo weave launch --ipalloc-range IP_ADDRESS/SUBNET IP_ADDRESS_OF_JETSON

Substitute IP_ADDRESS_OF_JETSON with physical IP Address of your Jetson's either Ethernet or WIFI NIC IP address within your Local Area Network (LAN). IP_ADDRESS/SUBNET leave the same as before.

You should see something like this:

6271beca24106a845c330ada996378edf17c9c50de02d1dadf6d655cae07f33e

Run again,

eval $(weave env)

If you want to check the connectivity between the remote computer and Nvidia Jetson SBC we can run below command on both machines:

sudo weave status

You should see a similar response in terminal on the Nvidia Jetson SBC:

Version: 2.7.0 (up to date; next check at 2020/11/16 23:59:45)        Service: router       Protocol: weave 1..2           Name: 72:9d:b3:68:0f:08(jetson)     Encryption: disabled  PeerDiscovery: enabled        Targets: 0    Connections: 1 (1 established)          Peers: 2 (with 2 established connections) TrustedSubnets: none        Service: ipam         Status: idle          Range: 172.30.0.0/16  DefaultSubnet: 172.30.0.0/16        Service: dns         Domain: weave.local.       Upstream: 127.0.0.53            TTL: 1        Entries: 0        Service: proxy        Address: unix:///var/run/weave/weave.sock        Service: plugin (legacy)     DriverName: weave

And on the remote host:

Version: 2.7.0 (up to date; next check at 2020/11/17 01:04:00)        Service: router       Protocol: weave 1..2           Name: 9e:10:66:0a:f7:4f(docker-desktop)     Encryption: disabled  PeerDiscovery: enabled        Targets: 1    Connections: 1 (1 established)          Peers: 2 (with 2 established connections) TrustedSubnets: none        Service: ipam         Status: idle          Range: 172.30.0.0/16  DefaultSubnet: 172.30.0.0/16        Service: dns         Domain: weave.local.       Upstream: none            TTL: 1        Entries: 0        Service: proxy        Address: unix:///var/run/weave/weave.sock        Service: plugin (legacy)     DriverName: weave

Now you successfully setup a weave connection between two nodes, we need some containers to talk to.

Step 6.3 - Launch ROS containers on both machines

This section aims to establish ROS communication across both networks (Wired and WiFi) so that remote PC can view ROS Master topics. We will use the Nvidia Jetson SBC as the ROS master, by setting the ROS_MASTER_URI and ROS_IP variables.

Use the following docker command to start a container that roscore to work:

A=$(sudo docker run -e WEAVE_CIDR=net:IP_ADDRESS/SUBNET -dti -p 11311:11311  --device=/dev/ttyUSB0 CONTAINER_ID bash -c "cd ~/catkin_ws/; source devel/setup.bash; export ROS_MASTER_URI=http://IP_ADDRESS:11311; export ROS_IP=IP_ADDRESS; roslaunch rplidar_ros rplidar.launch")

You will see no output returned to the terminal. This should launch a roscore instance, connect to the sensor, start the motor spinning, and begin broadcasting data on the /scan topic.

Then run the following command

weave attach $A

Use this command to get the IP address.

IP_ADDRESS

In my case, it is 172.30.0.1. You can also use the docker inspect command to find the IP address of your container.

If the container is successfully running, a quick command docker ps can verify this.

Now start up your docker container on the remote host:

B=$(docker run -it -e WEAVE_CIDR=net:172.30.0.2/16 -p 6080:80 -d CONTAINER_ID)

then run below command:

weave attach $B

Output:

REMOTE_IP_ADDRESS

In my case, it is 172.30.192.0. Now you can open the web browser and go to

http://localhost:6080.

You should now see a screen like this on your web browser:

Open the Command Prompt from the Start menu.

On the remote computer we need to set the ROS_MASTER_URI to the Jetson's IP and the ROS_IP to the remote computer IP. Open a new terminal and type the following:

export ROS_MASTER_URI=http://IP_ADDRESS:11311

after that run:

export ROS_IP=REMOTE_IP_ADDRESS

These are all the steps to make both computers communicate and share nodes, topics, and services.

To check that the remote computer can access the robot's topics you can run:

rostopic list

If this command return the robot list of topics than the remote connection is successful. You can also try to publish commands to operate the robot.

/rosout/rosout_agg/scan

Listen to the topic /scan:

rostopic echo /scan

Now you should be able to see in the terminal the data from the LiDAR sensor.

header:   seq: 2669  stamp:     secs: 1604993333    nsecs: 617659834  frame_id: "laser"angle_min: -3.1241390705108643angle_max: 3.1415927410125732angle_increment: 0.01745329238474369time_increment: 0.00037774848169647157scan_time: 0.13561169803142548range_min: 0.15000000596046448range_max: 12.0

Once you’ve verified the basics (list, echo) from the prompt, try launching some of the standard visual ROS GUI tools:

Open a new terminal window and run the following command:

rviz

You'll see the rviz window pops out.

Change fixed frame to laser. Then click Add button located in the left bottom corner of the RViZ GUI and then select LaserScan object, and then set the topic of LaserScan object to /scan.

Now you should see the visualization of LiDAR sensor measurements in the RViZ GUI.

If all went well, you should be seeing something similar to the above. If not, you will want to check your ROS connectivity

Let me summarize, Weave is a good networking management tools for Docker and provides the most functions compared with other solutions. In some applications, it might be necessary to have, not one, but multiple computers connected via either Ethernet cable or WiFi. Also, ROS is a good framework in which we made the map around the RPLIDAR. It is a great tool for build robot software systems which can be useful to a variety of hardware platforms, research settings, and runtime requirements.

That’s it for today! You have ROS Noetic installed and ready to use!

I hope you found this guide useful and thanks for reading. If you have any questions or feedback? Leave a comment below. Stay tuned!

Resources

Credits

Photo of shakhizat

shakhizat

I am a hardcore robotics and IoT enthusiast. You can reach me through email: shahizat005@gmail.com

   

Leave your feedback...