Skip to content
 
 

Latest commit

 

History

38 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

vtc_unity (ROS 2 Humble 対応版)

vtc_unity kashiwanoha

つくばチャレンジの環境を Unity 上で再現したシミュレータです。

本リポジトリは Field-Robotics-Japan/vtc_unity の派生版で、 ROS 2 Humble で動作させるための修正と、2D LiDAR / GNSS センサーの追加を行っています。

オリジナルの Virtual Tsukuba Challenge (Unreal Engine 版)fuRo によって開発されました。

利用している上流パッケージ:


動作環境

以下のバージョンで動作を確認しています。

項目 バージョン
OS Ubuntu 22.04.5 LTS
ROS ROS 2 Humble Hawksbill
Unity Editor 2021.3.45f1
Git LFS 3.0.2

必要な ROS 2 パッケージ

パッケージ 確認バージョン 用途
ros-humble-rosbridge-suite 2.0.0 Unity との WebSocket 通信
ros-humble-velodyne-msgs 2.5.1 Velodyne パケット型
ros-humble-velodyne-pointcloud 2.5.1 パケット → 点群 変換
ros-humble-tf2-ros 0.25.12 静的 TF の配信
ros-humble-rviz2 11.2.16 可視化
ros-humble-teleop-twist-keyboard 2.4.0 キーボード操作
sudo apt install ros-humble-rosbridge-suite ros-humble-velodyne \
                 ros-humble-tf2-ros ros-humble-rviz2 ros-humble-teleop-twist-keyboard

注意: 上流の README は ROS 1 (roslaunch, rosbridge_websocket.launch) を前提としています。 本リポジトリでは ROS 2 用の手順に置き換わっています。


本リポジトリでの変更点

1. ROS 2 対応 (header.seq 問題の解消)

本プロジェクトの Unity 側通信は ROS# (RosSharp) が担っており、ROS 1 形式のヘッダを送信します。 ROS 1 の std_msgs/Header には seq フィールドがありますが、ROS 2 には存在しません。 そのため rosbridge がヘッダ付きメッセージを全て拒否し、以下のエラーでセンサーデータが一切流れませんでした

[ERROR] [rosbridge_websocket]: [id: /imu] publish:
        Message type sensor_msgs/Imu does not have a field header.seq

対策として、seq のみを無視する rosbridge のパッチを用意しました (ros2/setup_rosbridge_patch.sh)。 seq 以外の未知フィールドは従来どおりエラーになるため、他の不具合を隠すことはありません。 /opt/ros は変更せず、パッチ済みコピーを PYTHONPATH で優先させる方式です。

なお、タイムスタンプ形式 (secs/nsecssec/nanosec) は rosbridge 側が変換に対応済みのため問題になりません。 ただし タイムスタンプは rosbridge の受信時刻で上書きされます。

2. 2D LiDAR (LRF) の追加

Assets/unit04_unity/Scripts/LiDAR/LrfScanPublisher.cs を新規追加し、 front_lrf_link / rear_lrf_link に取り付けました。sensor_msgs/LaserScan を配信します。

角度範囲とレイ数から角度分解能を自動計算し、測定範囲外は range_max + 1(ROS 上の無効値)を返します。

ROS# 付属の LaserScanPublisher + LaserScanReader も存在しますが、そちらは未計測のレイを 0 のままにし、 samplesangle_increment を手動で整合させる必要があるため、別実装としています。

3. GNSS (RTK) の追加

Assets/unit04_unity/Scripts/GNSS/GnssPublisher.cs を新規追加し、gps_link に取り付けました。 sensor_msgs/NavSatFix を配信します。実機 (u-blox) を想定した RTK シミュレーションに対応しています。

モード status 水平σ 垂直σ 想定状況
RtkFixed (既定) 2 (GBAS) 0.02 m 0.03 m 上空が開けた場所
RtkFloat 2 (GBAS) 0.30 m 0.50 m 樹木・建物の近く
Single 0 (FIX) 1.50 m 3.00 m 補正データ途絶
NoFix -1 - - 測位不能

NavSatStatus に RTK 専用の値が無いため、ROS ドライバの慣例に従い RTK Fixed / Float とも STATUS_GBAS_FIX とし、 精度差は共分散で表現しています。Inspector から実行中でも切り替えられます。

Unity 座標から WGS84 への変換は局所平面近似で行い、Unity の +x を東・+z を北・+y を上として扱います。

  • OriginLatitude / OriginLongitude : Unity 原点 (0,0,0) に対応する実座標。既定値は推定値で、 ロボット初期位置がつくば市役所前 (36.0833N / 140.0764E) になるよう逆算したものです。測量値ではありません。
  • OriginAltitude : 既定 40.0。シーンの Y 軸が実標高 (m) を持つため、 つくば周辺のジオイド高を加算して WGS84 楕円体高 (u-blox が出力する基準) に合わせています。

4. gps_link の有効化

unit04.prefabgps_linkm_IsActive: 0 (無効) だったため Start() が呼ばれず、 GNSS が advertise されませんでした。有効化しています (質量 0.25 kg・重力無効・FixedJoint 固定のため挙動への影響はありません)。

5. 静的 TF の追加

Unity 側は TF を配信しないため、rviz2 が全センサーのメッセージを破棄していました (Message Filter dropping message ... queue is full)。 prefab から実際のリンク位置を読み取り、静的 TF として配信する launch を追加しています (ros2/launch/unit04_tf.launch.xml)。


セットアップ

1. クローン (Git LFS 必須)

テクスチャとモデルは Git LFS で管理されています。LFS を入れずに clone すると、テクスチャが ポインタファイルのままになり、環境が白黒で表示されます。

sudo apt install git-lfs
git lfs install
git clone <this-repository>
cd vtc_unity
git lfs pull          # 約 840 MB

既に clone 済みで白黒になっている場合:

git lfs pull
rm -rf Library/       # インポート結果のキャッシュを破棄 (再インポートに 10-20 分)

Library/ は生成物なので削除して問題ありません。

2. Unity Editor のインストール

Unity Hub から 2021.3.45f1 をインストールします。

# Unity Hub (未導入の場合)
sudo apt install unityhub

Unity Hub でプロジェクト (vtc_unity ディレクトリ) を開きます。初回のインポートには時間がかかります。

3. rosbridge のパッチ適用 (初回のみ)

source /opt/ros/humble/setup.bash
./ros2/setup_rosbridge_patch.sh

ros2/rosbridge_patched/ にパッチ済みの rosbridge_library が生成されます (Git 管理外)。


実行手順

1. rosbridge を起動 (端末 1)

./ros2/run_rosbridge.sh

必ずこのスクリプトを使ってください。 素の ros2 launch rosbridge_server rosbridge_websocket_launch.xml で起動すると header.seq エラーで全センサーが止まります。

2. Unity で Play

Assets/vtc_unity/Scenes/VirtualTsukubaChallenge.unity を開き、▶ を押します。 (柏の葉キャンパスは Assets/vtc_unity/Scenes/KashiwaNoHa.unity)

rosbridge を再起動した場合は、Unity の Play を停止 → 再開してください。ROS# は自動再接続しません。

接続確認:

ros2 topic echo /client_count --once   # 1 以上なら接続済み

3. 静的 TF を起動 (端末 2)

ros2 launch ros2/launch/unit04_tf.launch.xml

4. 点群への変換 (端末 3、Velodyne を使う場合)

Unity が配信するのは生パケットなので、変換ノードが必要です。

ros2 launch velodyne_pointcloud velodyne_transform_node-VLP16-launch.py

5. ロボットの操作 (端末 4)

ros2 run teleop_twist_keyboard teleop_twist_keyboard \
  --ros-args -r /cmd_vel:=/diff_drive_controller/cmd_vel

リマップは必須です (Unity 側は /cmd_vel を購読していません)。

6. 可視化

rviz2

Fixed Frame は base_footprint に設定してください。


トピック一覧

方向 トピック frame_id
ROS → Unity /diff_drive_controller/cmd_vel geometry_msgs/Twist -
Unity → ROS velodyne_packets velodyne_msgs/VelodyneScan velodyne
Unity → ROS /front_lrf/scan sensor_msgs/LaserScan front_lrf_link
Unity → ROS /rear_lrf/scan sensor_msgs/LaserScan rear_lrf_link
Unity → ROS /gps/fix sensor_msgs/NavSatFix gps_link
Unity → ROS /imu sensor_msgs/Imu Unity
Unity → ROS /camera0/compressed sensor_msgs/CompressedImage Camera

ロボットは差動二輪 (車輪半径 0.20316 m / トレッド 0.43515 m) で、cmd_vel を左右ホイールの速度に変換して走行します。

IMU とカメラの frame_id は上流由来で Unity / Camera という汎用名のままです。


負荷の調整

重い場合は以下を調整してください (いずれも Inspector から変更できます)。

対象 設定項目 既定値 備考
Unity 全体 Quality Settings - Edit > Project Settings > Quality を下げるのが最も手軽
Velodyne Lidar.numberOfIncrements 3600 1800 で負荷が半減。24 の倍数にすること (パケット構造の制約)
2D LiDAR LrfScanPublisher.NumberOfRays 1081 271 (1度刻み) で 1/4 に
2D LiDAR LrfScanPublisher.ScanRateHz 40 20 Hz でも多くの用途では十分
カメラ CameraSensor - レート制限が無く毎フレーム JPEG 圧縮するため、未使用なら無効化

Raycast 数の目安: Velodyne が 16 × 3600 × 10 Hz = 576,000 本/秒、2D LiDAR が 1081 × 40 Hz = 43,240 本/秒 (1台あたり)。


トラブルシューティング

環境が白黒 / テクスチャが表示されない

Git LFS のファイルがポインタのままです。

git lfs pull
rm -rf Library/

Library/ を削除して開き直すと、シーンが読み込まれず空の状態で起動します。 Project ウィンドウからシーンファイルを開き直してください。

センサーのトピックは出るがデータが流れない

素の rosbridge が起動している可能性があります。

grep -c "header.seq" $(ls -t ~/.ros/log/python3_*.log | head -1)   # 0 なら正常
pgrep -c -f "lib/rosbridge_server/rosbridge_websocket"             # 1 なら正常

./ros2/run_rosbridge.sh で起動し直してください。

rviz2 に何も表示されない

Message Filter dropping message ... queue is full が出る場合は TF がありません。 ros2 launch ros2/launch/unit04_tf.launch.xml を起動し、Fixed Frame を base_footprint にしてください。

Unity で Play しても接続されない

ss -ltn | grep 9090                    # rosbridge が待ち受けているか
ros2 topic echo /client_count --once   # 0 なら Unity が未接続

rosbridge の再起動後は Unity の Play を停止 → 再開してください。


既知の制限

  • オドメトリと TF が Unity から配信されません。 そのため rviz2 上でロボットは移動しません (odom → base_footprint が存在しないため)。センサーはロボット座標系で正しく表示されます。
  • タイムスタンプは rosbridge の受信時刻であり、Unity のシミュレーション時刻ではありません。
  • GNSS の原点座標は推定値です。実コースの実測データがあれば GnssPublisherOriginLatitude / OriginLongitude を修正してください。
  • Packages/manifest.json に ROS-TCP-Connector と UnitySensors が含まれていますが、 シーンでは使用していません (通信は全て ROS# 経由)。

LICENSE Dependencies

From Unity Asset store

We utilize following Assets from Unity Asset Store.
Every package are Free now (2020/05/13). We partly modify and utilize those Assets.

LICENSE

Copyright [2020] Ryodo Tanaka groadpg@gmail.com

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

About

Virtual Tsukuba Challenge package on Unity

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages