LiDARのスキャン結果から、太陽光ノイズを除去する
開発環境
項目 | |
PC | Jetson Orin Nano |
OS | Ubuntu20.04 (Jetpack) |
ROS | ROS 2 foxy Fitzroy |
2D LiDAR | UST-20LX (北陽電機) |
はじめに
屋外でLiDARを使う場合、強い日差しや雨など、天候による影響を考慮する必要があります。 本記事では、太陽光による外乱光によるノイズを低減する方法について説明します。
laser_filterについて
ROS 2では、センサーデータを処理してロボットの制御や認識に利用するためのさまざまなパッケージが提供されています。その中でも、laser_filterパッケージはLiDARから得られるデータを効果的に処理するための便利なツールです。この記事では、ROS 2のlaser_filterパッケージの基本的な使い方や設定方法についてご紹介します。
インストール方法
端末を開き、ROS 2 のディストリビューション名に合わせてインストールします。
sudo apt install ros-<distro>-laser-filter
ROS 2 Foxyの場合は以下のコマンドになります。
sudo apt install ros-foxy-laser-filter
使い方
設定ファイルの準備
yaml形式の設定ファイルを準備する必要があります。 githubのexamplesを参考に作成すると良いです。
テンプレートは以下です。
scan_to_scan_filter_chain:ros__parameters:filter1:name:filter_nametype:filter_typeparams:parameter1:valueparameter2:value...filter2:...
LaserScan型のscanデータを処理し、同じデータ型でデータを配信する場合は、 scan_to_scan_filter_chain を指定します。
filterを1つだけ適用する場合はfilter1だけ, 2個以上適用する場合はテンプレートのような形式で追加していきます。
filter_nameには、わかりやすい名前をつけてください。 filter_typeには,ドキュメントを参考にフィルターの種類に応じたfilter_typeを指定してください。
フィルタータイプ | 説明 |
laser_filters/LaserScanFootprintFilter | footprintから指定された半径以内のデータを無効化するフィルター |
laser_filters/LaserScanMaskFilter | スキャンデータから、指定されたインデクス番号のデータを無効化するフィルター |
laser_filters/LaserArrayFilter | スキャンデータからrangeとintensity(強度)を分け、それぞれを個別に処理するフィルターメディアンフィルターを適用できる |
laser_filters/ScanShadowsFilter | 物体のエッジをスキャンした際に発生しうるベーリング効果などによるノイズを無効化するフィルター |
laser_filters/InterpolationFilter | スキャンデータに含まれる無効なデータを、良い感じの値で補間してくれるフィルター |
laser_filters/LaserScanIntensityFilter | intensityで指定範囲から外れたデータを無効化するフィルター |
laser_filters/LaserScanRangeFilter | スキャンデータの内、検出距離が指定範囲外であるデータを無効化するフィルター |
laser_filters/LaserScanAngularBoundsFilter | 指定された角度範囲内のみのデータを抽出するフィルター |
laser_filters/LaserScanAngularBoundsFilterInPlace | 指定された角度範囲内のデータを無効化するフィルター |
laser_filters/LaserScanBoxFilter | x,y,zのmax,minで指定されたボックス内に含まれるデータを無効化するフィルター |
laser_filters/LaserScanSpeckleFilter | ハズレ値をノイズとして無効化するフィルター |
太陽光ノイズを除去する場合はspeckle_filterが有効なので、speckle_filter用の設定ファイルを準備します。
scan_to_scan_filter_chain:ros__parameters:filter1:name:sun_filtertype:laser_filters/LaserScanSpeckleFilterparams:filter_type:0max_range:20.0max_range_difference:0.1filter_window:4
launchファイルの作成
laser_fiterを動かす際は、上記で準備した設定ファイルのパスを渡したり、場合によっては トピック名を変更するremappingを設定する必要があるので、launchファイルを作成することを おすすめします。
以下はlaunchファイルの例です。下記を想定しています。
上記の準備した設定ファイルのパス= /home/hayakawa/setting/speckle.yaml
from launch import LaunchDescription
from launch.substitutions import PathJoinSubstitution
from launch_ros.actions import Node
from ament_index_python.packages import get_package_share_directory
def generate_launch_description():return LaunchDescription([
Node(
package="laser_filters",
executable="scan_to_scan_filter_chain",
parameters=["/home/hayakawa/setting/speckle.yaml"],
)
])
デフォルトでは、/scanトピックを購読し、データ処理後に /scan_filteredトピックが配信されます。トピック名を変更したい場合は、下記のようにremappingを設定してください。
Node(
package="laser_filters",
executable="scan_to_scan_filter_chain",
parameters=["/home/hayakawa/setting/speckle.yaml"],
remappings=[('/scan', '/new_topic_name')],
)
実行方法
自作のパッケージにlaunchファイルを置いた場合は、端末上で以下のコマンドを実行します。
ros2 launch <パッケージ名> <launchファイル名>
launchファイルを直接起動したい場合はlaunchファイルと同じディレクトリに移動し、 端末上で以下のコマンドを実行します。
ros2 launch <launchファイル名>
スキャンデータにノイズを加える方法
ROS 2 ノードを自作しました。 スキャンデータを読み取り、 確率的に検出距離を検出距離以下のランダムな値に書き換える というアルゴリズムを適用しています。 注意点としては、検出距離がもともと短いデータに対して他データと同じ確率でノイズを追加すると、その部分だけノイズの密度が濃くなるので、ちょっとした工夫をしています。
固定出力のスキャンデータにノイズを追加した結果を示します。
参考 ノイズ除去実験
ノイズ除去の効果は設定ファイルのパラメータに拠る所が多いが、今回の設定ではノイズがほぼすべて除去されていることがわかります。 ただし、ノイズではない情報まで除去されているので、パラメータの調整作業が必要です。
Comments