Main Content

buildMap

LIDAR スキャンから占有マップを作成

説明

map = buildMap(scans,poses,mapResolution,maxRange) は、指定された poses で LIDAR scans を挿入することによって occupancyMap マップを作成します。結果のマップの分解能 mapResolution と、LIDAR センサーの最大範囲 maxRange を指定します。

すべて折りたたむ

関数buildMapは、占有マップをlidarScanオブジェクトとして作成するために LIDAR スキャンの読み取り値と関連付けられている姿勢を受け取り、occupancyMapを作成するために関連付けられている姿勢 [x y theta] を受け取ります。

ある駐車場のロボットに搭載されたセンサーから収集したスキャンと姿勢の推定を読み込みます。収集されたデータはlidarSLAMアルゴリズムを使用して相互に関連付けられます。このアルゴリズムはスキャン マッチングを実行してスキャンを関連付け、ロボットの軌跡全体で姿勢を調整します。スキャンと姿勢の長さが同じであることを確認してください。

load scansAndPoses.mat
length(scans) == length(poses)
ans = logical
   1

マップを作成します。関数buildMapでスキャンと姿勢を指定し、目的のマップ分解能 (1 メートルあたり 10 セル) と LIDAR の最大範囲 (19.2 メートル) を含めます。各スキャンは関連付けられた姿勢に追加され、占有グリッドの確率値が更新されます。

occMap = buildMap(scans,poses,10,19.2);
figure
show(occMap)
title('Occupancy Map of Garage')

Figure contains an axes object. The axes object with title Occupancy Map of Garage contains an object of type image.

lidarSLAM オブジェクトを使用して LIDAR スキャンの追加および比較を繰り返し、ロボットの軌跡の最適化された姿勢グラフを作成します。関連付けられている姿勢およびスキャンから占有マップを取得するには、関数buildMapを使用します。

データの読み込みと SLAM アルゴリズムの設定

lidarScanオブジェクトの cell 配列を読み込みます。この LIDAR スキャンは、ある駐車場で、ClearPath Robotics® 製の Husky® ロボットで収集されました。通常、LIDAR スキャンは高周波数で取得され、個々のスキャンが SLAM に必要なわけではありません。したがって、40 番目、次の 40 番目というようにスキャンを繰り返し選択して、スキャンをダウン サンプリングします。

load garage_fl1_southend.mat scans
scans = scans(1:40:end);

SLAM アルゴリズムを設定するには、LIDAR の範囲、マップの分解能、ループ クロージャのしきい値および探索半径を指定します。これらのパラメーターを、実際のロボットと環境に合わせて調整します。次のパラメーターを指定して lidarSLAM オブジェクトを作成します。

maxRange = 19.2; % meters
resolution = 10; % cells per meter

slamObj = lidarSLAM(resolution,maxRange);
slamObj.LoopClosureThreshold = 360;
slamObj.LoopClosureSearchRadius = 8;

スキャンを繰り返し追加

for ループを使用して、SLAM オブジェクトにスキャンを追加します。オブジェクトでは、スキャン マッチングを使用して、追加された各スキャンを以前に追加されたスキャンと比較します。マップを改善するために、オブジェクトはループ クロージャを検出するたびに姿勢グラフを最適化します。スキャン 10 個ごとに、保存された姿勢とスキャンを表示します。

for i = 1:numel(scans)

    addScan(slamObj,scans{i});
    
    if rem(i,10) == 0
        show(slamObj);
    end
end

Figure contains an axes object. The axes object contains 121 objects of type line.

占有マップの表示

すべてのスキャンを SLAM オブジェクトに追加した後、スキャンと姿勢を指定してbuildMapを呼び出すことにより、occupancyMapマップを作成します。SLAM オブジェクトで使用したものと同じマップ分解能および最大範囲を使用します。

[scansSLAM,poses] = scansAndPoses(slamObj);
occMap = buildMap(scansSLAM,poses,resolution,maxRange);
figure
show(occMap)
title('Occupancy Map of Garage')

Figure contains an axes object. The axes object with title Occupancy Map of Garage contains an object of type image.

入力引数

すべて折りたたむ

マップの作成に使用する LIDAR スキャン。lidarScan オブジェクトの cell 配列として指定します。

LIDAR スキャンの姿勢。n 行 3 列の行列として指定します。各行は、スキャンの xy 位置と向きの角度を表す [x y theta] ベクトルです。

出力 occupancyMap マップの分解能。1 メートルあたりのセル数を示す正の整数として指定します。

LIDAR センサーの最大範囲。メートル単位の正のスカラーとして指定します。この範囲を外れる scans 内の点は無視されます。

名前と値の引数

オプションの引数のペアを Name1=Value1,...,NameN=ValueN として指定します。ここで、Name は引数名、Value は対応する値です。名前と値の引数は他の引数の後に表示されなければなりませんが、ペアの順序は重要ではありません。

R2021a より前は、名前と値をそれぞれコンマを使って区切り、Name引用符で囲みます。

例: ['MapWidth',10]

占有グリッドの幅。'MapWidth' と正のスカラーからなるコンマ区切りのペアとして指定します。この値が指定されていない場合、マップはすべてのレーザー スキャンに適合するよう自動的にスケーリングされます。

占有グリッドの高さ。'MapHeight' と正のスカラーからなるコンマ区切りのペアとして指定します。この値が指定されていない場合、マップはすべてのレーザー スキャンに適合するよう自動的にスケーリングされます。

出力引数

すべて折りたたむ

占有マップ。occupancyMap オブジェクトとして返されます。

バージョン履歴

R2019b で導入