YDLIDAR X4をROS 2 Jazzyで動かしてRViz2で周囲を確認する

要素実証

はじめに

今回は2D LiDARの YDLIDAR X4 をUbuntu 24.04 / ROS 2 Jazzy環境で動作させ、ROS 2の/scanトピックからRViz2で実際の壁などを確認するところまでを試してみます。

LiDARはSLAMや自律走行などにも利用できますが、今回はそこまでは行いません。

まずは、

「LiDARを接続して、実際の周囲がRViz2で見えるところまで確認する」

ことを目的とします。

今回使用するYDLIDAR X4

今回使用するのは、YDLIDARの2D LiDAR X4です。

X4は少し前の機種ですが、360度の2次元距離測定が可能なLiDARです。回転するスキャン部からレーザーを照射し、周囲の物体までの距離を連続的に測定します。

最近のLiDARと比較すると機械的な構造も分かりやすく、内部では小型モーターからベルトを介してスキャン部を回転させています。

今回は、このX4から取得した距離情報をROS 2のLaserScanとして受け取り、RViz2で可視化します。

今回確認すること

最終的な構成は次のようになります。

YDLIDAR X4
    ↓ USB
Ubuntu 24.04 / ROS 2 Jazzy
    ↓
/scan
    ↓
RViz2
    ↓
壁や周囲の物体を表示

単にX4のモーターが回転するだけではなく、次の段階まで確認します。

  1. UbuntuからX4のUSBインターフェースを認識できる
  2. YDLidar-SDKからX4へ接続して測距できる
  3. ROS 2から/scanを取得できる
  4. RViz2で周囲の壁などを表示できる
  5. LiDARの前に手をかざすと、RViz2上の測距点も追従する

ここまで確認できれば、2D LiDARとしての基本的な動作確認はできたと考えます。

検証環境

今回の環境は次のとおりです。

PC        :小型PC
OS        :Ubuntu 24.04
ROS 2     :Jazzy
LiDAR     :YDLIDAR X4
SDK       :YDLidar-SDK 1.2.20
ROS Driver:ydlidar_ros2_driver
接続      :USB

今回はRaspberry Piではなく、Ubuntu 24.04を起動した小型PCを使用しています。

実機検証

USB接続を確認する

まずROS 2を使用する前に、UbuntuからX4が認識されていることを確認します。

ls -l /dev/ttyUSB*

今回の環境では、

/dev/ttyUSB0

として認識されました。

さらに、

lsusb

を実行すると、USB-UARTとしてSilicon LabsのCP210xが認識されていることも確認できました。

また、シリアルポートを使用できるよう、実行ユーザーがdialoutグループに所属していることも確認しています。

ここまでで、「少なくともUbuntuからUSBシリアルデバイスとして認識されている」ことが確認できます。

まずYDLidar-SDKで動作確認する

いきなりROS 2ドライバを使用するのではなく、最初にYDLidar-SDKを使用してX4単体の動作を確認しました。

今回使用したYDLidar-SDKは1.2.20です。

SDKをビルドした後、付属のテストプログラムを使用して接続すると、

Lidar successfully connected [/dev/ttyUSB0:128000]
Lidar running correctly! The health status good
Model: X4

などが表示され、X4との通信自体はできていることを確認できました。

ただし、ここで少し問題がありました。

SDKに含まれるサンプルプログラムの設定を確認すると、そのままでは今回のX4に適していない設定が含まれていました。

X4に合わせてSDKの設定を確認する

例えば、確認したサンプルでは通信速度が512000、LiDAR TypeがTYPE_TOF、Sample Rateが20などとなっていました。

一方、同じYDLidar-SDKに含まれているtri_test.cppの設定を確認すると、X4では主に次のような設定が使用されていました。

Baudrate        : 128000
Lidar Type      : TYPE_TRIANGLE
Sample Rate     : 5
Single Channel  : false
Intensity       : false
Motor DTR Ctrl  : true
Fixed Resolution: false

そこでlidar_c_api_test.cについても、tri_test.cppを参考にX4向けの設定へ変更しました。

例えば通信速度とLiDAR Typeは次のように設定しました。

int i_optvalue = 128000;
setlidaropt(laser, LidarPropSerialBaudrate,
            &i_optvalue, sizeof(int));

i_optvalue = TYPE_TRIANGLE;
setlidaropt(laser, LidarPropLidarType,
            &i_optvalue, sizeof(int));

Sample Rateについても、

i_optvalue = 5;
setlidaropt(laser, LidarPropSampleRate,
            &i_optvalue, sizeof(int));

としました。

また、X4ではモーター制御について、

b_optval = true;
setlidaropt(laser, LidarPropSupportMotorDtrCtrl,
            &b_optval, sizeof(bool));

としています。

これらをX4向けに合わせて再度実行したところ、LiDARから連続してスキャンデータを取得できました。

今回の環境では、おおむね600点前後の距離データを連続して取得できました。

ここで重要なのは、SDKのサンプルプログラムだからといって、その初期設定がすべてのLiDARにそのまま適用できるわけではないことです。

YDLidar-SDKは複数のLiDARを扱えるため、使用する機種に合わせて通信速度、LiDAR Type、Sample Rateなどを確認する必要があります。

今回は同じSDKに含まれているtri_test.cppと比較することで、X4に必要な設定を確認しました。

ROS 2ドライバをビルドする

SDKレベルでX4からデータを取得できたため、次にROS 2から使用します。今回はydlidar_ros2_driverを使用しました。

ワークスペースでビルドします。

cd ~/ros2_ws
colcon build --symlink-install

ビルド後、

source /opt/ros/jazzy/setup.bash
source ~/ros2_ws/install/setup.bash

を実行します。

ydlidar_ros2_driverにはX4用のパラメータファイルとして、

params/X4.yaml

が用意されています。

このファイルには、

port: /dev/ttyUSB0
baudrate: 128000
lidar_type: 1
device_type: 0
sample_rate: 5
isSingleChannel: false
intensity: false
support_motor_dtr: true
frequency: 10.0

など、X4用の設定が記述されています。

SDK単体テストで確認した設定とも対応していることが分かります。

ROS 2からX4を起動する

今回は次のlaunchファイルを使用しました。

ros2 launch ydlidar_ros2_driver ydlidar_launch_view.py \
  params_file:=$HOME/ros2_ws/src/ydlidar_ros2_driver/params/X4.yaml

実行するとX4のモーターが回転し、RViz2も起動しました。

別のターミナルから、

ros2 topic list

を実行すると、

/scan

が存在することを確認できます。

さらに、

ros2 topic hz /scan

を実行しました。

今回の環境では、おおむね8Hz程度で/scanがPublishされていることを確認できました。

また、

ros2 topic echo /scan --once

とすると、LaserScanのデータを直接確認できます。

例えば、

frame_id: laser_frame
range_min: 0.1
range_max: 12.0
ranges:
  ...

のように、実際の距離データがrangesへ格納されています。

ここまでで、

「X4から取得した測距データがROS 2の/scanとしてPublishされている」

ことが確認できました。

/scanは出ているのにRViz2に表示されない

ところが、ここでもう一つ問題がありました。

/scanは存在しています。

ros2 topic hz /scanでもデータが流れていることを確認できます。

それにもかかわらず、RViz2にはLaserScanが表示されませんでした。

RViz2のLaserScanの状態を確認すると、

Showing [0] points from [0] messages

となっていました。

つまり、/scanというトピック自体は存在しているものの、RViz2ではメッセージを受信できていません。

そこでRViz2のLaserScan設定から、

Topic
  └ Reliability Policy

を確認し、

System Default

から、

Best Effort

へ変更しました。

すると/scanのメッセージを受信するようになり、RViz2上にLaserScanが表示されました。

ROS 2ではPublisherとSubscriberの間で、データ配送条件をQoS(Quality of Service)として指定できます。

LiDARなどの連続したセンサーデータでは、古いデータを確実に再送することよりも、最新データを継続的に取得することを優先するため、Best Effortが利用される場合があります。

そのため、

「トピックが存在している=RViz2で必ず受信できる」

とは限りません。

今回の場合は、RViz2側のReliability PolicyをBest Effortへ変更することで表示できました。

RViz2で壁を確認する

RViz2では、Global OptionsのFixed Frameを、

base_link

としました。

LaserScanについては、

Topic              : /scan
Reliability Policy : Best Effort

としています。

これで、X4が測定した周囲の壁などが赤い点としてRViz2上に表示されました。

さらにX4の前に手をかざして動かすと、それに合わせてRViz2上の測距点も動きました。

これで、

実際の物体
   ↓
YDLIDAR X4
   ↓
距離測定
   ↓
ROS 2 /scan
   ↓
RViz2

という一連の流れを実機で確認できました。

まとめ

今回はYDLIDAR X4をUbuntu 24.04 / ROS 2 Jazzy環境へ接続し、最終的にRViz2で周囲の壁などを表示するところまで確認しました。

今回行った確認をまとめると、

USBデバイスとして認識
        ↓
YDLidar-SDKで通信確認
        ↓
機種に合わせた設定を確認
        ↓
SDKでスキャンデータ取得
        ↓
ROS 2ドライバを起動
        ↓
/scanを確認
        ↓
RViz2でLaserScanを表示

という流れになります。

今回はYDLIDAR X4を使用しましたが、LiDARの機種が異なっても、OSでのデバイス認識 → SDKやドライバでの単体確認 → ROS 2のトピック確認 → RViz2での可視化と段階を分けて確認することで、問題が発生した場所を切り分けやすくなります。

また、/scanが正常にPublishされていてもRViz2に表示されない場合には、QoS設定も確認する必要があることが分かりました。

今回はまず、**「LiDARで実際の壁を見る」**ところまでを確認しました。ここまで確認できれば、2D LiDARをROS 2で利用するための最初の動作確認としては十分です。今後はこの/scanを利用して、地図作成などの検証にもつなげることができます。