4

私は Ubuntu の C/C++ でモバイル ロボティクス アプリケーションを作成しています。現在、レーザー センサーを使用して環境をスキャンし、ロボットの移動時にオブジェクトとの衝突を検出しています。

このレーザーのスキャン範囲は 270°、最大半径は 4000mm です。この範囲内の物体を検出し、センサーからの距離を報告することができます。

各距離は平面座標であるため、より読みやすいデータを得るために、それらを平面座標からデカルト座標に変換し、テキスト ファイルに出力してから、MatLab でプロットして、レーザーが検出したものを確認します。

この図は、デカルト座標での典型的な検出を示しています。 ここに画像の説明を入力 値はメートル単位なので、0.75 は 75 センチメートル、2 は 2 メートルです。連続する青い点は検出されたすべてのオブジェクトですが、(0,0) に近い点はレーザー位置を参照し、破棄する必要があります。レーザー スキャン領域が 270° であるため、y < 0 の下の青い点が生成されます。赤い線の正方形 (1.5 x 2 メートル) を追加して、衝突チェックを実装したい領域を決定しました。そのため、その領域内にポイント (オブジェクト) があるかどうかをリアルタイムで検出し、ある場合はいくつかの関数を呼び出したいと考えています。これは少しトリッキーです。なぜなら、このチェックでは、決定する連続したポイントがあるかどうかも検出できるはずだからです。オブジェクトが実在するかどうか (つまり、点を検出した場合、最も近い点を検索して、それらがオブジェクトを構成しているかどうか、または検出エラーの可能性がある単なる点であるかどうかを判断する必要があります)。

これは、単一のスキャンを実行するために使用する関数です。

struct point pt[limit*URG_POINTS];
//..
 for(i = 0; i < limit; i++){
 for(j = 0; j < URG_POINTS; j++){
  ang2 = kDeg2Rad*((j*240/(double)URG_POINTS)-120);
  offset = 0.03;     //it depends on sensor module [m]

  dis = (double) dist[cnt] / 1000.0;
  //THRESHOLD of RANGE
  //      if(dis > MAX_RANGE) dis = 0;  //MAX RANGE = 4[m]
  //      if(dis < MIN_RANGE) dis = 0;
  pt[cnt].x = dis * cos(ang2) * cos(ang1) + (offset*sin(ang1)); // <-- X POINTS
  pt[cnt].y = dis * sin(ang2); // <-- Y POINTS
 // pt[cnt].z = dis * cos(ang2) * sin(ang1) - (offset*cos(ang1)); <- I disabled 3D mapping at the moment
  cnt++;
}
ang1 += diff;
}

1 回のスキャンごとに、ptには検出されたすべての点が xy 座標で含まれます。

私はこのようなことをしたいと思います:

  • 単一のスキャンを実行し、最後に、
  • 各 pt.x および pt.y に衝突チェックを適用する
  • 内側の領域にポイントが見つかった場合は、他の近くのポイントを確認し、そうであればロボットを停止します。
  • そうでない場合、または他の近くのポイントが見つからない場合は、別のスキャンを開始します

以前に定義された領域内のオブジェクト (複数の単一点で構成される) を簡単にチェックする方法を知りたいです。

助けてくれませんか?私にはとても難しいようです:(

4

1 に答える 1

3

私は完全な答えを出すことができるとは思いませんが、それがどこに行くことができるかについていくつかの考えがあります。

リアルタイムとはどういう意味ですか?特定のアルゴリズムの実行にはどのくらい時間がかかりますか?そして、あなたのプログラムはどのプロセッサで実行されていますか?

検出範囲内にあるポイントのフィルタリングは、とをチェックするだけで非常に簡単にabs(x) < 0.75なりy< 2 && y > 0ます。さらに、0から十分に離れているポイントのみを考慮する必要がありますx^2 + y^2 > d。しかし、それは些細な部分であるはずです。

さらに興味深いのは、ポイントのグループを検出することです。DBSCANは、ポイントの2次元グループを検出するためのかなり優れたクラスタリングアルゴリズムであることが証明されています。ここでの重要な問題は、DBSCANがリアルタイムアプリケーションに対して十分に高速であるかどうかです。そうでない場合は、アルゴリズムの最適化を検討する必要があるかもしれません(いくつかの巧妙なインデックス構造を使用して、その複雑さをn * log(n)に押すことができます)。

さらに、前回の反復で得た知識をどのように組み込むことができるかを検討する価値があるかもしれません(高頻度であると仮定すると、データポイントはそれほど変化しないはずです)。

他のロボットプロジェクトを見る価値があるかもしれません-センサーデータを解釈して周囲の情報を構築する問題はかなり一般的な問題だと想像できます。

アップデート

問題にDBSCANを適用する際にどこでつまずいたかを知らずに、適切なアドバイスを提供することはかなり困難です。しかし、アルゴリズムがどのように機能するかを段階的にガイドしてみましょう。

  • 受け取ったデータポイントごとに、それが観察したい領域にあるかどうかを確認します。(私が上で与えた条件はうまくいくはずです)。
  • データポイントがリージョン内にある場合は、それをある種のリストに保存します
  • すべてのデータポイントを読み取った後、リストが空かどうかを確認します。もしそうなら、すべてが良いです。それ以外の場合は、ナビゲートする必要のあるデータポイントのより大きなグループがあるかどうかを確認する必要があります。

今、より難しい部分が来ます。そのポイントにDBSCANをスローし、ポイントのグループを見つけようとします。どのパラメータが私が知らないアルゴリズムで機能するか-それは試してみる必要があります。その後、ポイントのクラスターがいくつかあるはずです。グループで何をするかは完全にはわかりません。極座標で最小および最大の次数を持つ各グループのポイントを検出するというアイデアがあります。そうすれば、あなたはあなたがあなたの車をどこまで回さなければならないかを決めることができます。2つのグループが非常に接近しているため、それらの間のギャップをナビゲートできない場合は、特別な注意を払う必要があります。

DBSCANの実装については、ここで行うか、Googleにサポートを依頼することができます。これは、何千回もコーディングされてきたかなり一般的なアルゴリズムです。速度に関するさらなる最適化については、独自の実装を作成すると役立つ場合があります。ただし、見つけた実装の1つが使用可能であると思われる場合は、最初にそれを試してから、すべてを実行して自分で実装します。

アルゴリズムの実装中に特定の問題に遭遇した場合は、新しい質問を作成することをお勧めします。これは、この質問から遠く離れており、喜んで手伝ってくれる人が増える可能性があるためです。

物事がもう少し明確になったことを願っています。そうでない場合は、疑問がある正確な点を教えてください。

于 2012-05-05T10:27:23.167 に答える