banner
ホームページ / ブログ / Raspberry Pi で LiDAR を使用する方法
ブログ

Raspberry Pi で LiDAR を使用する方法

Nov 29, 2023Nov 29, 2023

自律走行車やロボットと近くの物体との間の距離を安価かつ正確に測定する機能は、ハッカーにとって難しい問題です。 障害物を回避するには距離を知ることが重要です。 小型ロボットであれば何かにぶつかるのは些細な問題かもしれませんが、自動運転車のような大型ロボットでは致命的な問題になる可能性があります。

障害物回避のための距離測定に興味を持ったのは、2013 年の NASA サンプル リターン ロボット (SRR) コンペティションに参加したことがきっかけです。 私は視覚処理に Web カメラを使用し、測定を行うためにさまざまな視覚的手法を試みましたが、あまり成功しませんでした。 コンテストでは、2 人の参加者がスキャニングライダーを使用しており、私はそれらに興味を持ちました。

LIDAR はレーザー距離測定装置です。 この名前は、LIght と raDAR という用語を組み合わせたものであり、一般に示唆されているように、その前身である「RAdio Detection And Ranging」と同様の方法で派生した頭字語ではありません。 メリアム・ウェブスターによれば、この用語は 1963 年に初めて使用されました。 ライダーの初期の用途には、アポロ 13 号による雲や月の表面の測定がありました。レーザーのサイズが小型化されると、軍事目的の距離計など、他の用途も発見されました。

1 つのレーザー ビームは 1 つの物体までしか到達できません。 航空機制御レーダーが空にビームを照射するのと同じように、走査型ライダーがレーザーを掃引します。 自律移動デバイスに LIDAR を適用するには、距離測定の点群を提供するために、垂直方向と水平方向の両方で広範囲をスキャンする必要があります。 前に見たように、同様のことが赤外線センサーで実行される可能性がありますが、精度はレーザーほど良くありません。

距離測定は複数の方法で行うことができますが、主に 2 つの方法が使用されます。 1 つはレーザー パルスの飛行時間を測定し、もう 1 つはレーザー ビームの偏向角を使用します。

あなたは基本的なレーダーとソナーの仕組み、つまりパルスを送信し、戻ってくる信号を受信するまでにかかる時間を測定する方法についてはよく知っています。 時間を光または音の速度で割ると、信号が往復した距離がわかります。 それを 2 で割ると、オブジェクトまでの距離が求められます。 それが飛行時間(ToF)測定です。

ご想像のとおり、光の速度を考えると物事は難しくなります。 コンピューターの先駆者であるグレース "アメイジング グレイス" ホッパー少将は、11.80 インチのワイヤーを配って、光が真空中をナノ秒で移動する距離を実証しました。ロボットでは、これが私たちが測定したいと考えている距離の大きさです。信号は約 7 ナノ秒で戻ってくるため、パルスだけを送信して戻り信号のタイミングを計るのは 1 メートル未満の測定は困難です。

これに関連する 1 つの手法は、振幅または周波数によって信号を継続的に変調することです。 送信信号と受信信号間の位相差は、物体までの距離に比例します。 変調を使用するライダーはセンチメートルまで測定できます。

ToF ベースのスキャニング LIDAR の商用プロバイダーは数多くありますが、その価格はほとんどの愛好家が費やすよりも少し高価です。 比較的新しい参入企業である PulsedLight は、ハッカーの価格帯でシングル ビーム ToF ライダーを提供しましたが、サプライヤーはすべて入荷待ちです。

三角測量ライダーは、ハッカーが長年使用してきたシャープの赤外線距離測定センサーと同じ技術を使用しています。 送信機は単一の送信元ですが、受信機は 1 次元または 2 次元の受信機アレイです。 送信機からの受信機要素のオフセットにより、三角形のベースラインが作成されます。 送信信号と戻り信号は、三角形の残りの 2 つの辺になります。 単純な三角法により、ベースラインからオブジェクトまでの距離が得られます。

Optical Society では、距離の測定に使用されるこれらの技術やその他の技術について説明しています。

2013 年の NASA SRR に参加したときに私が知らなかったのは、Neato Robotics が 2010 年に掃除機の周囲を感知するスキャンライダーを使用した掃除機をリリースしたということです。 これにより、以前のロボット掃除機のように障害物に衝突するのではなく、ロボットが障害物を回避できるようになります。

Sparkfun は真空を分解し、ライダーを調査しました。 2010 年 11 月に始まった長い議論が、ハッカーが LIDAR に細心の注意を払って真空を解剖する中、Trossen Robotic フォーラムで続きました。 LIDAR をハッキングすると、小さな賞品も提供されました。

残念ながら、そのスレッド内のリンクの多くはもう存在しませんが、多くの詳細がメッセージに記載されているため、読む価値はあります。 フォーラムの他のスレッドには追加情報があります。 特に興味深い発見の 1 つは、ネイト ライダーに先立って最終設計の基礎となった研究論文です。 Neato がエンジニアリング製品を作成するために必要な詳細を概説しました。

良いニュースは、真空と LIDAR に関する情報をまとめた Wiki が存在することです。 積極的なハッキング参加者の 1 人である [Nicolas "Xevel" Saugnier] は、LIDAR に電力を供給し、シリアル インターフェイスに接続するための小型 USB インターフェイス ボードを作成しました。 2014 年の夏、私は 2015 NASA SRR への参加を目指して、いくつかの LIDAR ユニットとボードを入手しました。 [Xevel の] Python ソフトウェアとロボット オペレーティング システムで利用可能なパッケージを使用して、LIDAR ユニットを動作させることができました。

スキャニング LIDAR により、Neato Robotics は距離測定データを使用した同時位置特定とマッピング (SLAM) を実装できるようになりました。 これにより、ロボットは、以前の掃除機のような衝突やランダムな動き、つまり酔っぱらいの散歩を使用するのではなく、掃除経路を計画できるようになります。 これにより、ネイトはより早く部屋を完全に覆うことができます。 Neato のデモンストレーションのこのビデオでは、ロボットが自分がいた場所と遭遇した障害物の地図をどのように構築するかに注目してください。 特に、LIDAR データを使用して 1 つの障害物をきれいに囲む方法に注目してください。

SRRコンテストは諦めましたが、ロボットには今でも興味があります。 ライダーは棚の上に鎮座しており、まるで神話上のサイレンのように私を誘惑しています。 両方とも 3V3 レベルで動作するため、LiDAR シリアル インターフェイスが Raspberry Pi に完全に一致していることに気づいたとき、私は最終的に彼らの呼びかけに屈しました。 これにより、USB インターフェースが不要になります。 同様の取り組みは、2014 年の [Thomas Jesperson's] で、STM32F429 ボードを使用し、動作中の LIDAR のビデオを作成しました。

LIDAR は、一方の端にモーターがぶら下がっている密閉ユニットです。 モーターは約 300 rpm で回転するタレットを駆動します。 タレットにはレーザーと受信センサーが含まれており、回転することで周囲のエリアを 360 度スキャンします。 レーザーと受信センサーには、タレットからの 2 つの光学ポートがあります。 LIDAR からは JST コネクタが付いた 2 本の短いケーブルがあります。 2 ピン コネクタはモーターに電力を供給します。 4 ピン コネクタは、制御回路と 3V3 シリアル インターフェイスに 5V 電力を供給します。 ピン配置は次のとおりです。

真空中では、モーターは約 25% のデューティ サイクルで PWM を使用する 12V 電源から電力を供給されます。 これは、モーターが適切な速度で動作するには約 3V が必要であることを意味し、ハッカーによるその後のテストでは、これが真実であることが示されました。 USB インターフェイス ボードは、PID (比例積分微分) ループによって制御される PWM を使用して、USB コネクタからの 5V 入力から LIDAR を実行し、モーターの速度を維持します。 PWM と PID を使用する理由回転タレットが磨耗して汚れ、ほこり、その他の破片が溜まるときに、回転タレットの RPM を一定に維持するため。 私のテストでは、プラスとマイナスの接続に応じて、モーターが砲塔をどちらかの方向に回転させることに気づきました。 インターフェイスは引き続き正常に動作しますが、データ ポイントの順序は逆になります。 通常、砲塔は反時計回りに回転します。

注意: 一部の初期のユニットではインターフェイスに 3V3 が使用されていたため、5V に接続するとインターフェイスが破壊される可能性があります。

私が最初に Pi と LiDAR を接続したのは、迅速かつ汚いものでした。 モーターをPiの3V3出力に接続したところ、動作しました。 Pi 3V3 からの出力は仕様により 50 mA に制限されており、LiDAR Wiki にはモーターが 64 mA を消費すると記載されています。 私のものを測定したところ、かなり多くの描画が行われました。 また、インターフェイスの TX ピンを Pi の RX (ピン 10) に接続しました。 Raspbian Jessie で CuteCom を使用すると、砲塔を手動で回転させたときにデータを読み取ることができました。 基本的なテストが終わったので、もう少し真剣に取り組む時期が来ました。

私は、部品キャビネットで見つけた ULN2803A ダーリントン トランジスタ アレイをモーターの駆動に使用することにしました。 この IC は、モーターの駆動に必要な電流を容易に処理し、誘導性負荷の駆動に必要な保護ダイオードを備えています。 モーターのPWMを行うつもりはありませんでしたが、モーターをオフにしたりオンにしたりしたかったのです。 Piのピン2の5Vをモーターコネクタの赤いワイヤーに接続しました。 黒色の配線は、電圧を降下させるために 15 オームの抵抗を介して ULN2803A に接続されています。 このセットアップでは、モーターを制御するためのローサイド構成を設定します。 インターフェイス ケーブルは、Pi の 5V、グランド、および RX ピンに接続されます。

モーター制御をテストするために、ファイル システム ディレクトリ /sys/class/gpio への GPIO ピンのマッピングを使用しました。 ピンがエクスポートされると、ここで各 GPIO を制御できます。 その後、コマンドでピンの方向を設定し、ピンのオンとオフを切り替えることができます。 私が使用したコマンドは GPIO 18 (ピン 12) を制御しました。

エコーされたときの「0」と「1」は、それぞれピンをオフとオンにします。 これは機能し、CuteCom を使用してデータを確認できました。

シリアル ポートに接続し、インターフェイスに電力を供給すると、興味深い結果が 1 つ発生します。 LIDAR はウェルカム メッセージを生成します。

Piccolo レーザー距離スキャナー Copyright (c) 2009-2011 Neato Robotics, Inc. All Rights Reserved Loader\0x09V2.5.15295 CPU\0x09F2802x/c001 Serial\0x09KSH34313AA-0140854 LastCal\0x09[5371726C] Runtime\0x09V2.6.1 5295

また、タレットを手動で回転させると、「スピン」というメッセージが表示され、ブレークまたは 3 つの Esc 文字を送信することでコマンド機能が使用できることが通知されます。 コマンドに関する情報は Wiki で入手できます。

ここで、大まかなソフトウェアを作成して、これがどのように機能するかを確認します。 もちろん C++ を使用したので、Pi 2 用のツール チェーンをインストールしましたが、コンパイル速度は開発には十分であることがわかりました。 私は Geany プログラミング エディターとメイクファイルを使い始めました。 このセットアップは、LIDAR の Python コードを操作中に学んだものです。 複数のプログラミング言語を扱うことができ、私はこれを Ubuntu と Raspian の汎用テキスト エディタとして採用しました。 しかし、編集後に C++ コードが適切に再フォーマットされなかったため、最終的には Geany を放棄し、Eclipse CDT を Pi にインストールしました。 Eclipse は Pi 上で驚くほどうまく動作します。 Geany では、Eclipse での作業で失ってしまったメイクファイルの操作方法を再学習していたので、この切り替えには実は少しがっかりしました。

C++ を使用した GPIO のプログラミングに関する情報を探しているときに、[Gordon Henderson] による WiringPi ライブラリを見つけました。 生の GPIO プログラミングをサポートするだけでなく、多くの Pi ドーター ボードもサポートします。 私にとってのさらなる魅力は、シリアル ポート インターフェイスを備えているため、Linux 上でその詳細を説明する必要がなかったということですが、これは私にとって目新しいことでした。 最終的には、その単純なスレッド機能を使用して、非常に最小限のユーザー インターフェイスを処理することさえできました。 [Gordon] には、上で示したようにディレクトリに書き込むよりも完全にコマンド ラインからピンを制御するためにチェックすべきユーティリティもあります。

WiringPi で私が見つけた最後の部分は、Pi 上で実行できる 1 つの GPIO ピンでハードウェア PWM を実行できる機能です。 それが GPIO 18 です。もともとモーターの制御に GPIO 4 (ピン 7) を使用していましたが、この機能を見つけて切り替えました。 現在、コードは PWM に定数値を設定していますが、最終的には一定速度を維持するために PID (比例積分微分) 制御システム ループを追加 (および記事を書きたい) と考えています。 WiringPi、スレッド、GPIO 18 の PWM のセットアップは簡単です。

このスレッドは、単にキーが入力されたときにプログラムを停止し、ヒットを返すために存在します。 run が false に設定されている場合、シリアル入力を読み取るメイン スレッドが終了し、タレットの電源をオフにした後、プログラムが終了します。 実際のスレッドは非常に単純です:

シリアル入力の読み取りは文字を読み取るだけで簡単ですが、データ自体は簡単ではありますが、少し手間がかかります。 タレットの 1 回転あたり 360 のサンプルがあるため、1 秒あたり 5 回転のデータ量は膨大になります。 パケットは 90 個あり、それぞれに 4 つのデータ ポイントが含まれています。 各ポイントは、距離、信号強度、無効な距離ビット、無効な強度ビットの 4 バイトのデータで表されます。 さらに、各パケットは開始バイト、パケット番号であるインデックス バイト、およびタレットの回転速度を表す 2 バイトで始まります。 パケットは 2 つのチェックサム バイトで終了します。 そのデータを構造体にマッピングする方法は次のとおりです。

データ パケットの保存には手を出さず、データが正しく表示され、計算が適切であることを確認するためにパケットをレポートするだけでした。 距離データはミリメートルで報告される整数であり、インチに変換しました。 チェックサムのコードは Wiki にありますが、まだ実装していません。

これは Neato LIDAR の使用の始まりにすぎませんが、良いものです。 ハードウェアは正常に動作し、ソフトウェアの基本は理解できています。 データを取得して、それが有効であることを確認できます。 WiringPi ライブラリは、Pi の取り組みを続ける上で最適な発見です。

次のステップは、チェックサム ルーチンを動作させ、いわゆるユーザー インターフェイスを拡張してタレットの動作を制御できるようにし、一定の回転速度を維持するために PID ループを追加することです。 UNL2803A チップがあるので、それを使用してインターフェイスへの電力を制御します。 また、デスクトップからコードをクロスコンパイルしてリモート デバッグを実行することも検討したいと思います。 これらの変更を加えながら、コードをクラスに編成し、それをロボットでどのように使用できるかを確認します。

モーターケーブル インターフェースケーブル