4

悪いタイトルで申し訳ありませんが、それを簡単に説明する方法が本当にわかりません...

私のシナリオでは、ロボット アプリケーションの場合、1 ミリ秒ごとにモーターを制御するリアルタイム ループが必要です。同時に、パス プランニング、画像処理、オブジェクト認識など、リアルタイムの要件を持たないことを実行したい場合もあります。さらに、非リアルタイム タスクの結果の一部は、リアルタイム モーター制御に送信されます。ロボットを制御するためのループ。

リアルタイム部分については、Ubuntu と RT-Preempt Patch を使用しています。したがって、こちらのサンプル コードのように while ループでリアルタイム制御ループを実行できます。

ただし、非リアルタイム部分についてはわかりません。私の謙虚な意見では、同じプロセスで新しいスレッドを作成し、そのスレッドで非リアルタイム タスクを実行します。

私はリアルタイム プログラミングに非常に慣れていないので、自分の設計で何が問題になるのかわかりません。また、そのようなプログラムを設計するためのパラダイムがあるのだろうか?

- -編集 - -

私のアプリケーションに関するいくつかの詳細。

ロボットは、具体的にはロボットアームです。

リアルタイム部分については、順運動学、逆運動学、およびヤコビアンを計算します。次に、単純な PID コントローラーを使用して適切な出力コマンドを計算します。最後に、EtherCAT を使用して各モーターにモーター コマンドを送信します。

たとえば、非リアルタイム部分については、kinect から PointCloud ストリームを取得し、いくつかの前処理を行い、シーン内のオブジェクトのポーズを計算し、ロボット アームの適切な把握ポーズを決定し、最後にそれぞれのゴールを送信します。ロボットアームが実際にゴールに移動して物体をつかむように、モーターをリアルタイム部分に接続します。全体のプロセスには 10 秒ほどかかる場合があります。ただし、同時にリアルタイム ループを実行し続け、適切な力コマンドまたは位置コマンドを送信して、ロボット アームが元のポーズを保持して静止するようにする必要があります。

この 2 つの部分の間の通信に関しては、多くの場合、非リアルタイム部分から新しいアルゴリズムによってコマンドが生成され、それがリアルタイム部分に送られ、ロボット アームが動かされます。ただし、非リアルタイム部分のアルゴリズムは、エンド エフェクタの現在のポーズなどを知る必要がある場合があります。したがって、非リアルタイム パーツは、リアルタイム パーツに存在するフォワード キネマティクスから情報を取得する必要があります。

4

2 に答える 2

2

リアルタイムループは正確に何をしていますか? 私は推測しています(「1ミリ秒ごとにモーター制御を行う」と述べたので)非常に短い計算を行い、モーターデバイスに数バイトを出力します。

非リアルタイム部分は何をしていますか? ユーザーインターフェイスを想像しますか???

どんなロボット?

経路計画では、特にロボットが高速で移動している場合、強力なリアルタイムが必要になる場合があります。巡航ミサイルや Google Car は、ロボカップ用の小型ロボットと同じではありません。数ミリ秒の通信が失われると、巡航ミサイルや Google Car では人間が死亡する可能性がありますが、ロボカップでは許容されます。ゲームに負けるだけで、ロボットにわずかな損害を与える可能性があります。

40 m/s (時速 144 km、これはフランスの高速道路の制限速度 130 km/h をわずかに上回っています) では、2 ミリ秒は 8 cm を意味し、その 8 cm が人間の肉である場合、それは誰かを殺すことを意味する可能性があります。

2 つの部分はどのように相互作用していますか? リアルタイム部分は他の部分に何らかの情報を送信していますか?

おそらく、この 2 つの部分は、通信を伴ういくつかの異なるプロセス(スレッドではない) である可能性がありますか? おそらく、同期のためにセマフォで共有メモリを使用しています。次に、sem_overview(7)shm_overview(7 ) を見てください。

リアルタイム部分と「非リアルタイム」部分の間のインターフェースで、非リアルタイム部分も実際に「リアルタイム」になる可能性があることに注意してください。

要点は、2 つの部分 (リアルタイムと非リアルタイム) の間の概念的なインターフェイスを定義し、一部のデータと一部の同期 (2 つの部分間の通信) を失う余裕があるかどうかを判断することです。

非リアルタイム部分の役割が単に速度を表示または設定することである場合 (つまり、低しきい値と高しきい値)、データや同期が失われることがあります。しかし、問題は細部にあります (ロボットが、Google Car のようなハイウェイを走る本当の自律型自動車である場合、交換を失うわけにはいきません。両方の部分がリアルタイムになります!)。

于 2014-08-07T16:22:01.417 に答える
1

@Basile Starynkevitchが強調しているように、システム全体をリアルタイムと通常の部分にどのように分割するかは非常に重要です。

RT-Linux での実装に関して言えば、リアルタイム要件を持つシステムの部分は、カーネル内で実行されるリアルタイム スレッドになります。これにより、プリエンプションなしで実行できますが、大きな欠点が 1 つあります。それは、ユーザー空間で期待されるようになった保護がないことです。リアルタイム スレッド クラッシュは、システムがクラッシュしたことを意味します。この理由 (およびその他の理由) から、リアルタイム コンポーネントを可能な限り制限する必要があります。

システムの非リアルタイム コンポーネントは、通常の Linux プロセスとして実行されます。それらは、必要な高価な計画アルゴリズムと一緒にチャグすることができ、リアルタイムスレッドがそれらをプリエンプトし、必要に応じて実行します。注意が必要なのは通信で、FIFO と共有メモリの 2 つのメカニズムが用意されています。

FIFO は最も簡単で、単方向通信が可能です (双方向が必要な場合は 2 つ使用します)。これらはキャラクター デバイスであり、読み書きのオーバーラップを気にする必要はありません。詳細はtldp.orgから。

大量のデータを渡す場合は、共有メモリを使用することをお勧めします。これにより、2 つのプロセスが同じセクションをメモリにマップします。ただし、プロセス/スレッド間で調整して、別の書き込みの途中で読み取りを行わないようにする必要があります。当事者の 1 つがリアルタイム スレッドである場合、リアルタイム スレッドがプリエンプトされないことがわかっているため、これは実際には少し簡単に実行できます。もっと見るdrdobbs.com .

また、優先度の逆転にも注意する必要があります (たとえば、優先度の高いスレッドが優先度の低いスレッドが共有リソースを解放するのを待たなければならない場合)。

于 2014-08-09T12:07:22.150 に答える