4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Unitree LiDAR L2 の点群データをRviz2で確認

Last updated at Posted at 2025-08-09

はじめに

最近本業でROS2を使ったロボットの開発を始めたので、夏休みの間に自分でもLiDARやROS2の扱いに慣れようと思ってUnitree LiDAR L2を買いました。

PXL_20250809_135931181[1].jpg

Aliexpressで買ったのですが、日本円で5万円台の激安3D LiDARです。
(安くてそこそこ高精度と評価の高いLivox Mid-360は安いとは言っても10万円ほどするので、個人が趣味で買うにはちょっと躊躇します。)

セットアップ方法は公式のUnilidar SKD2で説明されているのですが、細部まで記載されておらずちょっとハマったので自分がRviz2で点群データを確認できるところまでセットアップした流れを紹介します。

Screenshot from 2025-08-09 22-29-28.png

今回もいつものごとく、ハマったらClaude Codeに助けてもらっています。:sweat_smile:

前提条件

  • Ubuntu 20.04/22.04
  • ROS2 Humble
  • PCL-1.10
  • LiDAR IP: 192.168.1.62 <-出荷時の初期IPのようです。
  • ユーザーが dialout グループに所属していること
bash
# dialoutグループの確認
groups
# 必要に応じて追加
sudo usermod -a -G dialout $USER

1. Unilidar SDK2の入手

bash
cd ~
git clone https://github.com/unitreerobotics/unilidar_sdk2.git
cd unilidar_sdk2

2. UDP(イーサネット)接続での設定

2.1 ネットワーク設定の確認

LiDARのデフォルトIP(192.168.1.62)に接続できるよう、ローカルIPを設定します。

# 現在のIP設定確認
ip addr show

# LiDARとの接続確認
ping -c 3 192.168.1.62

2.2 UDP接続用ファイル修正

unilidar_sdk2/unitree_lidar_sdk/examples/example_lidar_udp.cpp
// 修正前
std::string local_ip = "192.168.1.2";
unsigned short local_port = 6201;

// 修正後(環境に合わせて調整)
std::string local_ip = "192.168.1.3";     // 実際のローカルIPに変更
unsigned short local_port = 6202;          // ポート競合を回避
unilidar_sdk2/unitree_lidar_ros2/src/unitree_lidar_ros2/launch/launch.py
# UDP接続用設定
def generate_launch_description():
    node1 = Node(
        parameters= [
            {'initialize_type': 2},          # UDP通信
            {'local_ip': '192.168.1.3'},     # 実際のローカルIPに変更
            {'local_port': 6203},            # ポート競合を回避
        ]
    )

2.3 UDP接続でのビルドと実行

bash
# C++ SDKのテスト
cd unilidar_sdk2/unitree_lidar_sdk/build
cmake .. && make -j2
cd ..
./bin/example_lidar_udp

# ROS2パッケージでの実行
cd unilidar_sdk2/unitree_lidar_ros2
colcon build
source /opt/ros/humble/setup.bash
source install/setup.bash
ros2 launch unitree_lidar_ros2 launch.py  # unitree lidarのROS2パッケージとRviz2が同時に起動します。

source /opt/ros/humble/setup.bashsource install/setup.bash~/.bashrcに追記しておくと毎回ターミナルを立ち上げるたびに実行しなくて済みます。

3. (必要に応じて)シリアルポート接続での設定

3.1 LiDARをシリアルモードに切り替え

重要: LiDARは工場出荷時にEthernetケーブルを使用するUDPモードで設定されているため、付属のUSB-Cケーブルで接続できるようにするにはまずUDP接続でシリアルモードに変更する必要があります。

bash
cd unilidar_sdk2/unitree_lidar_sdk
./bin/set_to_serial_mode

3.2 シリアルポート用ファイル修正

unilidar_sdk2/unitree_lidar_ros2/src/unitree_lidar_ros2/launch/launch.py
# シリアル接続用設定
def generate_launch_description():
    node1 = Node(
        parameters= [
            {'initialize_type': 1},          # シリアル通信
            {'serial_port': '/dev/ttyACM0'}, # シリアルポートデバイス
            {'baudrate': 4000000},           # ボーレート設定
        ]
    )

3.3 シリアルポートデバイスの確認

bash
# シリアルポートデバイスの確認
ls -la /dev/ttyACM*
ls -la /dev/ttyUSB*

# 権限確認(dialoutグループに所属していることを確認)
groups

3.4 シリアル接続でのテストと実行

重要: シリアル通信では、LiDAR電源投入後に毎回C++ SDKでのテストが必要です。

bash
# 1. C++ SDKでのシリアル接続テスト(L2の電源投入後には必須)
cd unitree_lidar_sdk
./bin/example_lidar_serial

# 2. ROS2パッケージでの実行(シリアルテスト成功後)
cd unitree_lidar_ros2
colcon build
source /opt/ros/humble/setup.bash
source install/setup.bash
ros2 launch unitree_lidar_ros2 launch.py

3.5 シリアル通信でのC++ SDKテスト不要化

電源投入毎にC++ SDKテストが必要な原因は、ROS2ノードの初期化処理に重要なステップが不足しているためです。

ROS2ノードで不足している処理:

  1. startLidarRotation() - LiDARモーター回転開始
  2. resetLidar() - デバイスリセット
  3. コマンド間の適切な待機時間(1秒)

以下の修正を実施することで、C++ SDKテストの実行コマンドを省略(厳密にはunitree lidarのROS2パッケージとRviz2の起動と同時に上記の処理を実行する)できます。

3.5.1. unilidar_sdk2/unitree_lidar_ros2/src/unitree_lidar_ros2/launch/launch.pyの修正

unilidar_sdk2/unitree_lidar_ros2/src/unitree_lidar_ros2/launch/launch.py

# 動作モード修正前
def generate_launch_description():
    node1 = Node(
        parameters= [                
                {'work_mode': 0},
        ]

# 動作モード修正後
def generate_launch_description():
    node1 = Node(
        parameters= [                
                {'work_mode': 8},
        ]

3.5.2. unilidar_sdk2/unitree_lidar_ros2/src/unitree_lidar_ros2/include/unitree_lidar_ros2.hの149行目付近に追記:

unilidar_sdk2/unitree_lidar_ros2/src/unitree_lidar_ros2/include/unitree_lidar_ros2.h
lsdk_->setLidarWorkMode(work_mode_);

// シリアル通信用の追加初期化処理
if (initialize_type_ == 1) {  // シリアルモードのみ
    lsdk_->startLidarRotation();
    std::this_thread::sleep_for(std::chrono::seconds(1));
    
    lsdk_->resetLidar();
    std::this_thread::sleep_for(std::chrono::seconds(1));
}

修正後に下記を実行

cd unitree_lidar_ros2
colcon build
source /opt/ros/humble/setup.bash
source install/setup.bash
ros2 launch unitree_lidar_ros2 launch.py

4. Rviz2での可視化

4.1 Rviz2の起動

bash
# 自動でRviz2も起動される(launch.pyに含まれている)
ros2 launch unitree_lidar_ros2 launch.py

# または個別で起動
source /opt/ros/humble/setup.bash
rviz2 -d install/unitree_lidar_ros2/share/unitree_lidar_ros2/view.rviz

4.2 トピック確認

bash
# 利用可能なトピックの確認
ros2 topic list

# 期待されるトピック
# /unilidar/cloud (sensor_msgs/msg/PointCloud2)
# /unilidar/imu (sensor_msgs/msg/Imu)

# トピック情報の確認
ros2 topic info /unilidar/cloud
ros2 topic info /unilidar/imu

# データ頻度の確認
ros2 topic hz /unilidar/cloud
ros2 topic hz /unilidar/imu

5. 動作モードの設定

LiDARの動作モードはuint32_tの各ビットで制御されます:

ビット位置 機能 値0 値1
0 FOV切り替え 標準FOV (180°) 広角FOV (192°)
1 測定モード 3D測定モード 2D測定モード
2 IMU有効化 IMU有効 IMU無効
3 通信モード イーサネットモード シリアルモード
4 起動モード 電源投入時自動開始 電源投入時待機
cpp
// 例:シリアル通信 + 3D + IMU有効 + 自動開始
uint32_t workMode = 8;  // ビット3のみ1(シリアルモード)

// 例:UDP通信 + 3D + IMU有効 + 自動開始
uint32_t workMode = 0;  // すべて0(デフォルト)

5.1 ROS2での動作モード設定

unilidar_sdk2/unitree_lidar_ros2/src/unitree_lidar_ros2/launch/launch.py
# work_modeパラメータで設定(デフォルト値:0)
{'work_mode': 0},    # UDP通信 + 3D + IMU有効 + 自動開始

# 例:シリアル通信 + 2D測定モード + IMU無効
{'work_mode': 14},   # ビット1,2,3 = 1 (2D + IMU無効 + シリアル)

# 例:UDP通信 + 広角FOV + 3D測定
{'work_mode': 1},    # ビット0 = 1 (広角FOV)

5.2 C++ SDKでの動作モード設定

unilidar_sdk2/unitree_lidar_sdk/examples/example_lidar_udp.cpp
// setWorkModeメソッドで設定
unitree_lidar_sdk::UnitreeLidarReader lidar_reader;
uint32_t work_mode = 0;  // 設定したいモード値

// 接続後にモード設定を実行
lidar_reader.setWorkMode(work_mode);

5.3 動作モード設定の適用方法

bash
# 1. ROS2での設定変更
# launch.pyのwork_modeパラメータを編集後、再起動
cd unilidar_sdk2/unitree_lidar_ros2
colcon build
source install/setup.bash
ros2 launch unitree_lidar_ros2 launch.py

# 2. C++ SDKでの設定変更
# ソースコード編集後、リビルドして実行
cd unilidar_sdk2/unitree_lidar_sdk/build
cmake .. && make -j2
cd ..
./bin/example_lidar_udp

6. トラブルシューティング

6.1 UDP接続の問題

bash
# ポート使用状況の確認
sudo netstat -tuln | grep 6201

# ファイアウォール設定の確認
sudo ufw status

# LiDAR接続確認
ping -c 3 192.168.1.62

6.2 シリアル接続の問題

bash
# シリアルデバイスの確認
dmesg | grep ttyACM
ls -la /dev/ttyACM*

# 権限の確認
groups
ls -la /dev/ttyACM0

# 必要に応じて権限追加
sudo chmod 666 /dev/ttyACM0

6.3 ROS2の問題

bash
# ROS2デーモンのリスタート
ros2 daemon stop
ros2 daemon start

# ノードの確認
ros2 node list

# パッケージの再ビルド
colcon build --packages-select unitree_lidar_ros2

7. 座標系とデータフォーマット

7.1 座標系定義

  • LiDAR座標系: 右手座標系、原点は底面マウント部中央
  • IMU座標系: LiDAR座標系に対して平行移動のみ
  • 変換行列: LiDARからIMUへの変換は [-0.007698, -0.014655, 0.00667] の平行移動

↓はUnitree 4D LiDAR L2 User Manualからの引用です。
image.png

7.2 データ仕様

  • 点群データ: 18リング構成、最大100m測定範囲
  • IMUデータ: 6軸(加速度・角速度)+ クォータニオン
  • フレーム名: unilidar_lidar (点群), unilidar_imu (IMU)

8. 設定ファイルの保存場所

修正が必要な主要ファイル:

  1. unilidar_sdk2/unitree_lidar_sdk/examples/example_lidar_udp.cpp - UDP接続設定
  2. unilidar_sdk2/unitree_lidar_ros2/src/unitree_lidar_ros2/launch/launch.py - ROS2起動設定
  3. unilidar_sdk2/unitree_lidar_ros2/src/unitree_lidar_ros2/rviz/view.rviz - Rviz2設定

9.Docker化+ROS Bridge/Foxglove Bridge対応

ここまでの設定をローカル環境内で実施してもよいのですが、LiDARを持ち運び用のPCに接続して点群MAPを作成したりSLAMの実験を行うときには面倒な作業ですし、他のプログラムの環境に干渉する恐れもあります。
なので、Dockerコンテナ内でUnitree LiDAR L2を使えるようにしました。
ローカルネットワーク内の他のPCからもTOPICをPub/Subできるよう、ROS BridgeFoxglove Bridgeも組み込んでいます。

必要なファイル類は公式からフォークした https://github.com/todateman/unilidar_sdk2 に反映しているので、もし必要なら利用してみてください。

9.1. Dockerコンテナを利用してUnitree L2 LiDARをWSL2のUbuntuで使用できるようにする

もし持ち運び可能なUbuntuマシンがなくWindowsマシンしかない場合は、WSL2でUbuntu22.04の環境を構築し、この環境でL2 LiDARを使用することができます。

WSL2でUbuntu22.04、git、Docker、Docker composeがセットアップできている前提です。

まずはWSL2からホストマシンのUSBデバイスを使えるようにするを参考に、ホストPC(WindowsPC)で接続したUnitree L2 LiDARをWSL2側にマウントさせます。

powershell
# まずはWindows側で認識しているUSBデバイスを確認
> usbipd list
Connected:
BUSID  VID:PID    DEVICE                                                        STATE
1-3    04f2:b760  HP Wide Vision HD Camera, Camera DFU Device                   Not shared
1-4    04f3:0c00  ELAN WBF Fingerprint Sensor                                   Not shared
2-1    1a86:55d3  USB-Enhanced-SERIAL CH343 (COM4)                              Not shared
2-3    0489:e0f2  MediaTek Bluetooth Adapter                                    Not shared

usbipd: warning: USB filter 'USBPcap' is known to be incompatible with this software; 'bind --force' will be required.

# L2 LiDAR のBUS ID(2-1)をWSL2とシェアする
> usbipd bind --busid 2-1
usbipd: warning: USB filter 'USBPcap' is known to be incompatible with this software; 'bind --force' will be required.

> usbipd list
Connected:
BUSID  VID:PID    DEVICE                                                        STATE
1-3    04f2:b760  HP Wide Vision HD Camera, Camera DFU Device                   Not shared
1-4    04f3:0c00  ELAN WBF Fingerprint Sensor                                   Not shared
2-1    1a86:55d3  USB-Enhanced-SERIAL CH343 (COM4)                              Shared
2-3    0489:e0f2  MediaTek Bluetooth Adapter                                    Not shared

usbipd: warning: USB filter 'USBPcap' is known to be incompatible with this software; 'bind --force' will be required.

# L2 LiDAR のBUS ID(2-1)をWSL2にアタッチする
> usbipd attach --wsl --busid 2-1
usbipd: info: Using WSL distribution 'Ubuntu-22.04' to attach; the device will be available in all WSL 2 distributions.
usbipd: info: Detected networking mode 'nat'.
usbipd: info: Using IP address 172.31.128.1 to reach the host.

> usbipd list
Connected:
BUSID  VID:PID    DEVICE                                                        STATE
1-3    04f2:b760  HP Wide Vision HD Camera, Camera DFU Device                   Not shared
1-4    04f3:0c00  ELAN WBF Fingerprint Sensor                                   Not shared
2-1    1a86:55d3  USB-Enhanced-SERIAL CH343 (COM4)                              Attached
2-3    0489:e0f2  MediaTek Bluetooth Adapter                                    Not shared

usbipd: warning: USB filter 'USBPcap' is known to be incompatible with this software; 'bind --force' will be required.

WSL2(Ubuntu)側で確認

bash
# アタッチ前
$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

# アタッチ後
$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 1a86:55d3 QinHeng Electronics USB Single Serial
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

# 下記のコマンドでWSL2側で認識しているポート名が分かる
$ ls /dev/ttyACM*
/dev/ttyACM0

あとは https://github.com/todateman/unilidar_sdk2/ のリポジトリを

bash
git clone https://github.com/todateman/unilidar_sdk2.git

でクローンして、README_DOCKER_JP.mdの内容に沿ってDockerコンテナを立ち上げれば、あっけなくWindowsPCのWSL2で実行しているUbuntuで実行したDockerコンテナでUnitree L2 LiDARから取得した点群データが確認できるはず。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?