
Self Driving and ROS 2 - Learn by Doing! Map & Localization: レーザースキャン (セクション8-3/11)
レーザースキャンメッセージの構造とデータ変換(極座標からデカルト座標、地図フレームへの変換)について学習。
PythonとC++でのスキャンコールバック関数の修正を通じて、LiDARセンサーによる障害物の位置をオキュパンシーグリッドにマーク。
シミュレーションとRVizを用いて、ロボットの移動に伴うリアルタイムのオキュパンシーグリッド更新を可視化。
このレッスンでは、LiDARセンサーが提供するレーザースキャンメッセージの詳細な構造について学びました。これは正確なオキュパンシーグリッドを作成するために非常に重要です。レーザースキャンメッセージは`sensor_msgs`パッケージの一部であり、angle_min、angle_max、angle_increment、ranges、強度データなどの重要な情報を含んでいます。これらは、ロボットの周囲の障害物までの距離を解釈するのに役立ちます。
レッスン107: オキュパンシーグリッドに障害物を描く
この実験セッションでは、レーザースキャンメッセージを使用してオキュパンシーグリッドに障害物をマークする方法に焦点を当てました。以下は、私たちが行った手順の概要です:
1. Visual Studio Codeを開く:
バンパーボットマッピングパッケージに移動し、サブフォルダ内の`mapping_with_known_poses`ファイルを開きます。
2. スキャンコールバック関数の修正:
既存のスクリプトを更新し、レーザースキャンデータを使用して地図上の障害物の位置をマークします。
3. 範囲ベクトルの反復処理:
スキャンメッセージの`ranges`ベクトルを反復処理するためにforループを使用します。このベクトルにはレーザースキャンのすべての距離測定値が含まれています。
4. 無効な読み取り値のフィルタリング:
`math`ライブラリを使用して無効なLiDAR読み取り値(無限の距離など)をフィルタリングし、`math.isinf`を使用してチェックします。
5. 極座標からデカルト座標への変換:
各ビームの角度θを次の式で計算します:
$${[
θ = \text{angle_min} + (\text{angle_increment} \times i)
]}$$
LiDAR読み取り値を極座標からデカルト座標に変換します:
$${[
p_x = d \cdot \cos(θ)
]}$$
$${[
p_y = d \cdot \sin(θ)
]}$$
6. 地図フレームへの座標の変換:
クォータニオン形式からオイラー角への変換を行い、地図フレーム内の角度θにヨー角を加えます。
7. オキュパンシーグリッドに障害物をマーク:
極座標をデカルト座標に変換し、それを地図フレームに変換します:
$${[
p_x = d \cdot \cos(θ + \text{yaw}) + T_x
]}$$
$${[
p_y = d \cdot \sin(θ + \text{yaw}) + T_y
]}$$
これらの座標を使用してオキュパンシーグリッドマップに障害物をマークします。デカルト座標を地図ポーズに変換し、ポーズが地図の境界内にあることを確認します。
ポーズを地図の特定のセルに変換し、それらのセルを100(占有)に設定します。
8. 最適化と仕上げ:
パフォーマンスを最適化するためにヨー角の変換をforループの外側に移動します。
ファイルを保存し、新しい依存関係(tf_transformations)を含むようにpackage.xmlファイルを更新します。
レッスン108: C++でオキュパンシーグリッドに障害物を描く
このレッスンでは、前のレッスンの手順をC++で実装しました。プロセスには以下が含まれます:
1. C++ノードを開く:
`mapping_with_known_poses.cpp`ファイルに移動し、Visual Studio Codeで開きます。
2. スキャンコールバック関数の修正:
関数を更新し、レーザースキャンデータを使用して地図上の障害物の位置をマークします。
3. 範囲ベクトルの反復処理:
スキャンメッセージの`ranges`ベクトルを反復処理するためにforループを使用します。
4. 無効な読み取り値のフィルタリング:
数学ライブラリを使用して無効なLiDAR読み取り値をフィルタリングします。
5. 極座標からデカルト座標への変換:
各ビームの角度θを計算し、LiDAR読み取り値をデカルト座標に変換します。
6. 地図フレームへの座標の変換:
クォータニオン形式からオイラー角への変換を行い、地図フレーム内の角度θにヨー角を加えます。
7. オキュパンシーグリッドに障害物をマーク:
極座標をデカルト座標に変換し、それを地図フレームに変換します。これらの座標を使用してオキュパンシーグリッドマップに障害物をマークします。
レッスン109: C++でオキュパンシーグリッドに障害物を描く(続き)
このレッスンでは、レッスン108の手順を続け、C++実装を完成させました。
レッスン110: オキュパンシーグリッドの実行と可視化
このレッスンでは、オキュパンシーグリッドの実行とRVizを使用した可視化に焦点を当てました。手順は以下の通りです:
1. シミュレーションの起動:
小さな家の環境でシミュレーションを開始します。
2. ノードの実行:
`mapping_with_known_poses`ノードを実行し、オキュパンシーグリッドに障害物をマークし始めます。
3. RVizでのオキュパンシーグリッドの可視化:
固定フレームを`odom`に設定し、マップとレーザースキャンの可視化をRVizに追加します。
レーザースキャナーが検出した障害物がオキュパンシーグリッドに正確にマークされていることを確認します。
4. ロボットの移動:
ジョイスティックを使用してロボットを移動させ、オキュパンシーグリッドが新しい障害物の位置でどのように更新されるかを観察します。
これらのレッスンの終わりには、LiDARセンサーによって検出された障害物をオキュパンシーグリッドに正確にマークし、自律システムにおけるロボットのマッピング機能を強化しました。このプロセスは、将来のより高度なマッピングおよびローカライゼーションタスクの基礎を築くものであり、正確で信頼性の高い地図作成に不可欠です。