Hokuyo UST-10LX with ROS setup

Tags: , ,



10 minute read

Motivation and introduction

I have worked for quite a while with Softbank’s Pepper robot, which, unfortunately, does not feature the best onboard hardware. Specifically, it only employs three laser sensors that are aimed towards the ground at a slightly awkward angle [1]. These sensors are enough to do minimalistic obstacle avoidance, but not enough for Simultaneous Localization and Mapping (SLAM). As a consequence, at the KT group, we’ve decided to instead build an external mapping device, using the Hokuyo UST-10LX [2] laser sensor. However, the Hokuyo UST-10LX has to be connected to a host machine via ethernet cable to communicate its measurements with a host machine. This requires some network tinkering on that machine, which, in our case, is a Raspberry Pi 3. I found this setup not to be properly documented (or at least I couldn’t find anything on this). As such, below I describe how to configure a headless Raspi 3 running Ubuntu Server 20.04 to stream data from the Hokuyo laser sensor into your network.

Raspi setup and networking

The reason this sensors usability is not exactly at the plug-and-play level is that it, as already said, communicates with the host machine via ethernet cable, which in turn means that we can’t use the LAN port to connect the host machine to our trusted network. This is not necessarily a problem, but if we still want to remotely connect to and work on the said host machine, we have to configure our Raspi in such a way that it a) allows data to come in via the wired network interface while b) connects to the network/internet via the wireless interface. In the following steps, we do just that. Additionally, the ethernet wired network device has to be configured in the right way to communicate with the Hokuyo sensor which, also, I did not find to be well documented. Note that I did the following steps on the Ubuntu 20.04 server distro, I assume the steps work on all Debian-based Linux systems, but obviously, I did not test that.

Assuming you’ve freshly installed Ubuntu Server on your Raspi and plan to use it headless, you’ll have to do some initial configuration (including enabling ssh), which is widely covered, i.e. here. Once that is done and ready, simply log into your Raspi via ssh. Assuming your Raspi is currently connected to your network via ethernet cable, we now have to configure it to connect to WLAN, so that the ethernet port is available for the Hokuyo sensor. Do the following steps:

  • Get the name of your wireless network device (likely wlan0):
    $ ls /sys/class/net
    # enp8s0  lo  wlan0

    This outputs the names of all network devices on your system. Your wireless device is likely called wlan0, you can read more about network device naming conventions on ubuntu here.

  • Edit the netplan configuration file it is`/etc/netplan/50-cloud-init.yaml with your editor of choice. Add the following lines to it, but make sure they are properly intended (its a YAML file, which is sensitive to this).
          dhcp4: true
          optional: true
                  password: "<WiFi_password>"

    You have to enter your network information, so replace <your-wireless-device> with the name of your wireless network device (i.e. wlan0), <SSID_WiFi_name> with then name of your router and <WiFi_password> with the according password. The final file should look similar to this:

    # This file is generated from information provided by the datasource. Changes
    # to it will not persist across an instance reboot. To disable cloud-init's
    # network configuration capabilities, write a file
    # /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
    # network: {config: disabled}
              dhcp4: true
              optional: true
      version: 2
              dhcp4: true
              optional: true
                      password: "WiFi_password"
  • Now, bring up the wireless network card on the Raspi, if it is not already running:
    $  sudo ip link set <your-wireless-device> up

    Just executing this won’t break anything if your wireless card is already running, but later commands will fail if it is down. Again insert the name of your wireless network device (wlan0).

  • Now, run these commands to generate and apply the netplan configuration we entered into /etc/netplan/50-cloud-init.yaml:
    $ sudo netplan --debug try
    $ sudo netplan --debug generate
    $ sudo netplan --debug apply
    $ sudo reboot

    Finally, you can unplug the ethernet cable from your Raspi, and, assuming everything went well, the Raspi will connect to your WLAN after its reboot, in which case you can ssh onto it again.

Now, the internet traffic is being handled by the wireless network device and the wired ethernet port is available for the Hokuyo. In the next section, we install the Hokuyo ROS driver to bring up the laser sensor.

ROS and the Hokuyo driver

The remaining steps are more or less straightforward, but not trivial and not properly documented either (hence this post). Install ROS on your Raspi or the machine you plan to attach the Hokuyo to, by following the official installation instructions. Once you have ROS installed, install the ROS-driver for the Hokuyo UST-10LX sensor [3]:

$ sudo apt-get install ros-<ROS-VERSION>-urg-node

Here, replace <ROS-VERSION> with any of kinetic, melodic or noetic, as these are the only ROS versions currently supported by the package. Alternatively, you can compile the package yourself, but then you will have to take care of setting up the workspace and that all dependencies are satisfied, which I won’t describe here, as this process is well documented elsewhere [4]. With the drivers installed, now we just start ROS and can get our laser data, right? Well, not really, again because this specific Hokuyo laser sensor communicates with the host machine via ethernet cable. Furthermore, because of that, the instructions given for the urg_node package don’t work for us either. So, to get laser-data into our handy-dandy ROS topics, we have to assign an IPv4 address to the wired network interface (because the sensor is connected via cable), so that the IP address of the Hokuyo sensor falls into the subnet range of the wired network interface. From the Hokuyo’s datasheet (page 6), we know that the device has the default IP address of assigned. Thus, we can assign an IP address like to our wired network device. is in CIDR notation [5] and states that the first 24 bits (as indicated by the trailing /24) provide the network identifier, and whatever comes after that is the actual machine identifier. To assign a specific IP address to the wired network device, take the following steps:

  1. Get the name of your ethernet (wired) network device with the same command we used before:
    $ ls /sys/class/net
    # eth0  lo  wlan0

    lo is the loopback device, wlan0 (or similar) the WiFi card, so the remaining name is your wired network card (most likely called eth0, eno1 or enp2s0).

  2. Assign an IP address to your wired ethernet device that shares the network identifier with the IP of the Hokuyo sensor:
    $ sudo ip addr add broadcast dev eth0

    As above, replace the values in <>: with your values. You can verify that the command worked by inspecting the output of the ifconfig command. For the ethernet device you specified, it should show the IP address we just assigned to it. If your ethernet device does not show up in ifconfig but when you run ls /sys/class/net, it might be down. You can bring it up the same way we did with the wireless device earlier.

Now we have our regular traffic running over the wireless connection, while the ethernet wired device is configured to communicate with the Hokuyo sensor. Note, the IP address assignment with the ip addr add command we just did is not static, you will have to redo it after rebooting your device. You can look up how to configure this permanently by editing the netplan once again, i.e. here. Now, the final step is to get the laser data into a ROS topic via the ROS driver.

As usual in ROS, first, we start a roscore with the simple command roscore. Then, you need a new session on the same machine to start the urg_node driver for the Hokuyo sensor. Either ssh onto the server a second time or use a terminal multiplexer like tmux. With the roscore running in the other session, run the following command to bring up the Hokuyo laser:

$ rosrun urg_node urg_node _ip_address:=

With the _ip_address argument we pass the IP-address of the physical sensor to the ros node (see here). As mentioned already is the default value for the Hokuyo UST-10LX, you will have to adjust this if you assigned a different IP address to your sensor. If everything works, the node will output something like:

[ INFO] [1501672789.034051716]: Streaming data.

Now, in yet another terminal session, you can inspect this data, which is the laser point cloud returned by the sensor, by simply calling rostopic echo /scan, where /scan is the default name of the rostopic used by the urg_node driver.


You can also inspect the laser data in RVIZ, but this requires one two steps. RVIZ can only display data that is attached to a valid coordinate frame (which makes sense, because you need some point of reference if you want to visualize things in any space). Usually, the robot you are using will provide the coordinate frames via the ROS tf package, but given our current setup, we just have the Hokuyo sensor that is sorta floating in the void. If you inspect the data on the /scan topic, for example with rostopic info /scan, you will see that the data is associated with the coordinate frame laser. But this coordinate frame does not exist, so RVIZ can’t know where to put this data and will complain if you try to visualize the laser point cloud. To fix this, we simply broadcast a made-up coordinate frame, with the following command:

$ rosrun tf static_transform_publisher 0 0 0 0 0 0 1 map laser 10

Now we would be set, if our roscore would run on a system that features a graphical display session, but if you are running the roscore on a headless machine, as is the case for the Raspberry 3 Ubuntu server setup describe earlier, we can’t even display RVIZ, to begin with. Thus, you will have to do this on a different machine. Luckily, setting up a distributed ROS environment is very easy. Before starting the roscore on the headless machine, run the following command:

$ export ROS_MASTER_URI=http://<IP>:11311

Replace <IP> with the IP address of the network card. Obviously, when you restart the roscore, you will have to restart the urg_node as well. Now, in a terminal on your machine with a graphical desktop environment, run the same command, then rostopic list. This should show the rostopics that are running on the headless machine, assuming both machines are in the same network. For some reason, we can now see the rostopics, but no data in the topics, even though we are streaming it from the headless machine. I had to apply this weird fix in order to actually see the data in my ros topics on my main machine:

What finally solved my problem was adding all PCs with their hostnames and IP Addresses to the "/etc/hosts" file. Since then, everything works fine.

With that being taken care of and all nodes running (roscore, urg_node, static_transform_publisher), you should be able to visualize your laser data in RVIZ. Look at this nice laser data:


Alright, in this post we’ve configured a Raspberry Pi 3 running Ubuntu Server 20.04 to publish laser data into a network via WiFi, while the Hokuyo sensor is connected to the device via ethernet cable. We’ve installed the required software components and finally showed how to visualize the laser data in RVIZ on a different machine in the same network. Maybe someone finds this helpful :)


[1] Pepper laser specification
[2] Hokuyo UST-10LX
[3] URG_node Hokuyo driver
[4] Building ROS packages
[5] Wikipedia: Classless Inter-Domain Routing