工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Manufacturing Technology >> 製造プロセス

自律型タンク

レゴEV3セットを使用して、カーターとカヤのデザインリファレンスにはるかに安価な代替品を追加します。

このプロジェクトでは、Lego Technicの部品とモーターで作成され、LiDARで強化され、最新のIsaacSDKを実行するJetsonNanoボードによって制御される装軌車両の構築について説明します。 パート8 にジャンプします または 10 自律航法の完全なデモについては。

プロジェクトは休閑中のコンポーネントで構成されています:

ROSではなくIsaacSDKを使用する理由

レゴパーツを選ぶ理由

このパスを選択すると、いくつかの課題が発生します:

パート1:はじめに

1。 Isaac SDK

2。音声認識(オプション)

3。 Ev3devイメージ

EV3の最新イメージ(ev3dev-stretch)をダウンロードして、microSDまたはmicroSDHCカードにフラッシュします。 MicroSDXCフォーマットはEV3ブリックではサポートされていません。

4。 ev3dev用のARMクロスコンパイラ

  $ sudo apt-get install gcc-arm-linux-gnueabi g ++-arm-linux-gnueabi  

この部分は特に正しくセットアップするのが困難でした。 Ubuntu 18.04(ホストコンピューターとJetson Nano)はGLIBC_2.28を使用していますが、ev3devはDebianstretchとGLIBC_2.24を使用しています。デフォルトのarm-linux-gnueabi-g ++コンパイラ構成でコンパイルされたものはすべてGLIBC_2.28に依存しており、EV3では実行されません。静的リンクは、helloworldがsegfaultを引き起こしていたよりも複雑なものとしては機能しませんでした。私が見つけた解決策は、数学ライブラリを除くすべてを動的にリンクすることでした。詳細については、jetson-ev3 / toolchain / CROSSTOOLファイルを参照してください。もう1つの解決策は、Debian9のDockerイメージを使用することです。

5。 Jetson + EV3ワークスペース

  $ git clone https://github.com/andrei-ace/jetson-ev3.git  
  local_repository(
name ="com_nvidia_isaac"、
path ="/ home / andrei / ml / isaac"
  • jetson-ev3 / toolchain / CROSSTOOLを編集し、このファイルがあるディレクトリへのパスを設定します。
 #ツールチェーンへのパスで編集
linker_flag: "-L / home / andrei / ml / jetson-ev3 / toolchain"

6。 JetsonNanoをEV3に接続する

次のパートでは、たくさんのLinuxコマンドを投稿します。関係するシステムは3つあるので、ターミナルで表示されるのとまったく同じように投稿します。つまり、

  [email protected]:〜/ ml / jetson-ev3 $#これは私のPCで実行されます
[email protected]:〜$#これはオンですJetson Nano
[メール保護]:〜$ $ #this in EV3

私のJetsonNanoのIPは192.168.0.173(イーサネット)と192.168.0.218(WiFi)なので、これらの値を使用するコマンドが表示されたら、それらを自分の値に置き換えてください。

USB A-ミニケーブルを使用して、これらの手順を使用してJetsonボードをEV3ブリックに接続しました。

JetsonボードからSSHで接続してみてください:

  [email protected]:〜$ ssh [email protected]  

デフォルトのパスワードはmakerです。

7。ピンポンチュートリアル

Isaacには、非常に単純なコードレットを説明するチュートリアルがあります。このチュートリアルを最初に行うことをお勧めします。 Isaacで実行されるアプリを構築するために必要な概念を紹介します。

次に、jetson-ev3 / apps / ev3 / ping_pong /ディレクトリに移動します。これは前のチュートリアルの修正バージョンであり、ひねりを加えて、pingをEV3ブリックに送信します。

ほとんどのファイルは、前のチュートリアルでおなじみです。 JetsonとEV3間の通話には、Cap’n ProtoRPCを使用します。 Cap’n Protoは、さまざまなIsaacコンポーネント間の通信に頻繁に使用されるため、ここで使用するのが理にかなっています。このために、いくつかの新しいファイルが必要です:

  • jetson-ev3 / apps / ev3 / ping_pong / ping.capnp –これは、Isaac RobotEngineで実行されるクライアントとEV3で実行されるサーバー間のインターフェースを定義します。
  • jetson-ev3 / apps / ev3 / ping_pong / PongEv3Server.cppこれは、EV3ブリックで実行されるサーバーです
  • jetson-ev3 / apps / ev3 / ping_pong / Pong.cppこれは、EV3で実行されているPongサーバーを呼び出すように変更されました

ev3_pongサーバーをコンパイルします:

  [email protected]:〜/ ml / jetson-ev3 $ bazel build --config =ev3dev // apps / ev3 / ping_pong:ev3_pong  

最初にscpを使用してEV3にコピーし、次にEV3にコピーします。

ピンポンの例を作成してJetsonにデプロイします:

  [email protected]:〜/ ml / jetson-ev3 $  /engine/build/deploy.sh --remote_user  -p // apps / ev3 / ping_pong:ping_pong-pkg -d jetpack43 -h   

Jetsonでアプリをデプロイして実行する方法の詳細については、こちらをご覧ください。

両方のアプリを実行します:

  [email protected]:〜$ ./ev3_pong ev3dev.local:9999 
[email protected]:〜/ deploy / andrei / ping_pong-pkg $。 / apps / ev3 / ping_pong

すべてが機能した場合は、PingコンポーネントからEV3のスピーカーに送信されたメッセージが聞こえるはずです。

8.Isaacからモーターを制御する

同じ原則ですが、もう少し複雑です。アイザックの別のチュートリアルを使用して、EV3モーターを操作しました:

チュートリアルでは、SegwayRMPベースを使用します。横になっているものや購入するのに10000ドルがないので、代わりにEV3モーターを制御するドライバーを作成しました。コードはこちらです。

EV3で実行されるサーバーはここにあり、次のコマンドでビルドして実行できます:

  [email protected]:〜/ ml / jetson-ev3 $ bazel build --config =ev3dev // packages / ev3 / ev3dev:ev3_control_server 
[email保護された]:〜$ ./ev3_control_server ev3dev.local:9000

ここで説明するように、Sightの仮想ジョイスティックを使用しました。

9.EV3のDifferentialBase

Ev3ControlServerサーバーは2つの呼び出しに応答します:

  • command(cmd:Control)–線形速度と角速度をパラメーターとして受け取り、両方のモーターを制御して、要求された速度を達成します
  • state()->(state:Dynamics); –ロボットの実際の線形速度と角速度を返します

キネマティクスについては、こちらとこちらで詳しく説明しています。

私はproportional_control_cppサンプルアプリを使用してロボットを1m駆動し、EV3のオドメトリ(線形および角速度)データを1秒あたりの回転パルス(タコカウント)で報告しました。計算された移動距離(Isaacによる)を使用して実際の距離を測定し、実際の結果と一致するように報告された値を調整するための定数を考え出しました。これはうまく機能し、結果は直線だけでなく何度も再現可能でした。この値は、ホイール(またはこの場合はトラック)の半径を使用して計算することもできます。

パート2:ロボットの構築

ベースは、EV3キットの公式モデルの1つであるレゴのEV3 Track3rと非常によく似ています:https://www.lego.com/biassets/bi/6124045.pdf

Jetson Nanoのケースはここからです:https://github.com/3D-printable-lego-technic/PELA-blocks

パート3:Isaacアプリ

Isaacアプリは、次の3つの主要部分で構成されています。

  • グラフ–ノード:この部分は、アプリを構成するすべてのコンポーネントを定義します。ノードは、別のファイルで定義された別のグラフにすることもできます。例の「voice_detection」ノードはサブグラフです。
  • グラフ–エッジ:この部分は、ノード間のメッセージのフローを定義します。エッジにはソースとターゲットがあります。たとえば、「voice_detection」ノード(サブグラフ)から検出されたコマンドは、目標を生成するコンポーネントに送信されます。
  • 構成–この部分はグラフのノードを構成します

アプリの例:

  {
"name": "voice_control"、
"modules":[
"// apps / ev3 / voice_control: voice_control_goal_generator "、
" @ com_nvidia_isaac // packages / navigation "、
" @com_nvidia_isaac // packages / planner "
]、
" config_files ":[
" apps / ev3 / voice_control / model / isaac_vcd_model.metadata.json "
]、
" config ":{
" 2d_ev3.ev3_hardware.ev3 ":{
" isaac.Ev3Driver ":{
"アドレス ":" ev3dev.local "、
"ポート ":9000
}
}、
" navigation.imu_odometry.odometry ":{
"DifferentialBaseWheelImuOdometry":{
"use_imu":false
}
}、
"commander.robot_remote":{
"isaac.navigation.RobotRemoteControl ":{
" angle_speed_max ":0.6、
" linear_speed_max ":0.3
}
}、
" websight ":{
" WebsightServer ": {
"webroot": "external / com_nvidia_isaac / packages / sight / webroot "、
" ui_config ":{
" windows ":{
"音声コマンドの検出 ":{
" renderer ":" plot "、
"dims":{
"width":400、
"height":200
}、
"channels":[
{
" name ":" voice_control / voice_detection.voice_command_detector / isaac.audio.VoiceCommandConstruction / voice_command_id "、
" active ":true
}
]
}
}
}
}
}、
"navigation.shared_robot_model":{
"SphericalRobotShapeComponent":{
"circles":[
{"center ":[0.0、0.0]、" radius ":0.075}、
{" center ":[0.02、0.03464]、" radius ":0.055}、
{" center ":[0.02、- 0.03464]、 "radius":0.055}、
{"center":[-0.04、0.0]、 "radius":0.055}、
{"center":[0.0525、0.09093]、 "radius":0.035}、
{"center":[0.0525、-0.09093]、 "radius":0.035}、
{"center": [-0.105、0.0]、 "radius":0.035}
]
}
}、
"navigation.control.lqr":{
"isaac.planner .DifferentialBaseLqrPlanner ":{
" manual_mode_channel ":" commander.robot_remote / isaac.navigation.RobotRemoteControl / manual_mode "
}
}、
" navigation.control.control ":{
"isaac.planner.DifferentialBaseControl":{
"manual_mode_channel": "commander.robot_remote / isaac.navigation.RobotRemoteControl / manual_mode"
}
}
}、
"graph":{
"nodes":[
{
"name": "voice_control_components"、
"components":[
{
"name": "message_ledger"、
"type": "isaac ::alice ::MessageLedger"
}、
{
"name": "goal _generator "、
" type ":" isaac ::VoiceControlGoalGenerator "
}
]
}、
{
" name ":" voice_detection "、
"subgraph": "apps / ev3 / voice_control / voice_command_detection.subgraph.json"
}、
{
"name": "2d_ev3"、
"subgraph ":" apps / ev3 / 2d_ev3.subgraph.json "
}、

{
" name ":" Navigation "、
" subgraph ":" @ com_nvidia_isaac // packages / Navigation / apps /differential_base_navigation.subgraph.json "
}、
{
" name ":" commander "、
" subgraph ":" @ com_nvidia_isaac / /packages/navigation/apps/differential_base_commander.subgraph.json "
}
]、
" edges ":[
{
" source ":" voice_detection.subgraph / interface / detected_command "、
" target ":" voice_control_components / goal_generator / detected_command "
}、
{
" source ":" voice_control_components / goal_generator / goal "、
" target ":" navigation.subgraph / interface / goal "
}、
{
" source ":" 2d_ev3.subgraph / interface / base_state "、
" target ":" navigation.subgraph / interface / state "
}、
{
" source ":" navigation.subgraph / interface / command "、
"target": "commander.subgraph / interface / control"
}、
{
"source": "commander.subgraph / interface / command"、
" target ":" 2d_ev3.subgraph / interface / base_command "
}、
{
" source ":" 2d_ev3.subgraph / interface / flatscan "、
" target ":" Navigation.subgraph / interface / flatscan_for_localization "
}、
{
" source ":" 2d_ev3.subgraph / interface / flatscan "、
" target ":" Navigation.subgraph / interface / flatscan_for_obstacles "
}
]
}
}

サブグラフの例:

  {
"modules":[
"@ com_nvidia_isaac // packages / audio"、
"@ com_nvidia_isaac // packages / ml:tensorflow "
]、
"グラフ ":{
"ノード ":[
{
"名前 ":"サブグラフ "、
"コンポーネント ":[
{
" name ":" message_ledger "、
" type ":" isaac ::alice ::MessageLedger "
}、
{
"name": "interface"、
"type": "isaac ::alice ::Subgraph"
}
]
}、
{
"name": "audio_capture"、
"components":[
{
"name": "ml"、
"type": "isaac ::alice ::MessageLedger "
}、
{
" name ":" isaac.audio.AudioCapture "、
" type ":" isaac ::audio ::AudioCapture "
}
]
}、
{
"name": "voice_command_detector"、
"components":[
{
"name": "ml"、
"type": "isaac ::alice ::MessageLedger"
}、
{
"name": "isaac.audio.VoiceCommandFeatureExtraction"、
"type": "isaac ::audio ::VoiceCommandFeatureExtraction"
}、
{
"name ":" isaac.ml.TensorflowInference "、
" type ":" isaac ::ml ::TensorflowInference "
}、
{
" name ":" isaac.audio .VoiceCommandConstruction "、
" type ":" isaac ::audio ::VoiceCommandConstruction "
}
]
}
]、
" edges ": [
{
"source": "audio_capture / isaac.audio.AudioCapture / audio_capture"、
"target": "voice_command_detector / isaac.audio.VoiceCommandFeatureExtraction / audio_packets"
} 、
{
"source": "voice_command_detector / isaac.audio.VoiceCommandFeatureExtrac 、
"target": "voice_command_detector / isaac.ml.TensorflowInference / input_tensors"
}、
{
"source": "voice_command_detector /isaac.ml。 TensorflowInference / output_tensors "、
" target ":" voice_command_detector / isaac.audio.VoiceCommandConstruction / keyword_probabilities "
}、
{
" source ":" voice_command_detector /isaac.audio。 VoiceCommandConstruction / detected_command "、
" target ":" subgraph / interface / detected_command "
}
]
}、
" config ":{
" audio_capture ":{
" isaac.audio.AudioCapture ":{
" sample_rate ":16000、
" num_channels ":1、
" audio_frame_in_milliseconds ":100、
"ticks_per_frame":5
}
}、
"voice_command_detector":{
"isaac.audio.VoiceCommandFeatureExtraction":{
"audio_channel_index":0、
"minimum_time_between_in ferences ":0.1
}、
" isaac.ml.TensorflowInference ":{
" model_file_path ":" apps / ev3 / voice_control / model / isaac_vcd_model.pb "、
" config_file_path ":" apps / ev3 / voice_control / model / isaac_vcd_config.pb "
}、
" isaac.audio.VoiceCommandConstruction ":{
" command_list ":[
" jetson "、
" jetson left "、
" jetson right "
]、
" command_ids ":[0、1、2]、
" max_frames_allowed_after_keyword_detected ":14
}
}
}
}

サブグラフは多くのアプリで再利用できます。実際、isaacのナビゲーションスタックはサブグラフとして使用されます。

パート4:EV3でのIsaacアプリの実行

ドライバー(jetson-ev3 / packages / ev3 / BUILD)は、SegwayRMPベースドライバーと同じコマンドに応答します。つまり、KayaまたはCarterで動作する多くのアプリで動作するため、3番目のオプションであり、はるかに安価です。

CarterボットとKayaボットを紹介するために作成されたいくつかのアプリを適応させました:

  • ジョイスティックアプリ–これはジョイスティックでDifferentialBaseロボットを制御します。ローカルマップを生成するためのLiDARがあります
  • gmapping Distributed:ev3とKayaロボットからのホスト–これにより、EV3ロボットとYDLIDARX4を使用してGMapを作成できます。
  • フルナビゲーション– EV3ロボットのハードウェアと2Dナビゲーションのサブグラフを追加して、CarterまたはKayaを使用するのと同じくらい簡単に他のアプリで使用できるようにしました。

パート5:オドメトリ

自律モードで実行するには、良好なオドメトリを使用することが重要です。これは、時間の経過に伴うロボットの位置を推定するために使用されます。 ev3アプリを使用して調整しましょう:

  [email protected]:〜/ ml / jetson-ev3 $ ./engine/build/deploy.sh --remote_user andrei -p // apps / ev3:ev3 -pkg -d jetpack43 -h 192.168.0.173 

[メール保護]:〜$ブリックラン./ev3_control_server ev3dev.local:9000

[メール保護]:〜/ deploy / andrei / ev3-pkg $ ./apps/ev3/ev3 --graph ./apps/assets/maps/map.graph.json --config ./apps/assets/maps/map.config.json

2つのことを見積もる必要があります:

  • 線形速度
  • 角速度

線形速度と角速度の式は次のとおりです。

角速度を見つけるのは簡単です。これは、左右のモーターの差をベースの長さで割ったものです。

線形速度を見つけることはもう少し複雑です。 3つのケースがあります:

  • 両方のモーター速度が等しい場合–線形速度は右速度(および左速度)と等しい
  • 左のモーター速度が右のモーター速度と反対の場合、線速度は0で、タンクは所定の位置で回転します
  • 左モーター速度が0の場合(右の場合)。線形速度は適切な速度の半分です(ロボットの中心は小さな弧を描いて移動します)。

角速度実験:

手動制御を使用して、ロボットを所定の位置で360度回転させます。これは、左右のモーターを反対の速度で動かすことによって行われます。両方のモーターの速度がわかれば、角速度を計算できます。

試してみましょう:

角速度と線形速度の実験:

私はタンクを運転し、最後に開始位置に戻そうとします。速度を正しく計算している場合、オドメトリデータは最後に可能な限り0に近づける必要があります。

パート6:すべてをまとめる

さて、これまでのところ、高価なRC戦車を持っているだけですか?いいえ、Isaacのさまざまなパーツをすべて使用できるようになりました。たとえば、音声コマンドを発行して、ロボットを自律的に動かします。この例については、voice_controlを確認してください。

Isaacのオーディオと機械学習の宝石を使用しています。宝石とは何ですか?マニュアルに記載されているように、「GEM:計画から知覚までのロボットアルゴリズムのコレクションであり、そのほとんどはGPUで高速化されています。」

このチュートリアルで説明されている手順に従って、独自のRNNをトレーニングしました。特に不明なキーワード/無音/ランダムノイズの場合は、大量のデータがあることを確認してください。

「jetson」、「left」、「right」の3つの単語を認識するように訓練しました。保存したモデルはここにあります。これらの3つの単語を使用して、「jetsonleft」と「jetsonright」の2つのコマンドを作成できます。

検出部分は、ここで独自のサブグラフで説明されており、すぐに使用および再利用できます。

基本的にはマイクを聞くことであり、コマンドの1つを選択すると、voice_command_idが出力されます。そのために、以前にトレーニングされたRNNを使用します。

そのdetected_commandを取得して、独自のコードレットに渡すことができます:

  {
"source": "voice_detection.subgraph / interface / detected_command"、
"target": "voice_control_components / goal_generator / detected_command"
}

コードレットから、目標を生成して公開できます:

  auto proto =rx_detected_command()。getProto(); 
int id =proto.getCommandId();
autogoal_proto =tx_goal()。 initProto();
goal_proto.setStopRobot(true);
goal_proto.setTolerance(0.1);
goal_proto.setGoalFrame( "robot");
ToProto(Pose2d ::Rotation( 90)、goal_proto.initGoal());
tx_goal()。publish();

これにより、ロボットを左に90度回転させるという目標が設定されます。さまざまなフレームでさまざまな目標を設定できます。キッチンの座標のように、「世界」のフレームの座標に行くこともできたでしょう。ロボットのフレームにPose2 ::Translate(1.0、0)を設定して、ロボットを1メートル前進させた可能性があります。

そしてそこから、目標をグローバルプランナーに渡します。

  {
"source": "voice_control_components / goal_generator / goal"、
"target": "navigation.subgraph / interface / goal"
}

すべての魔法が起こる場所:

残念ながら、5 Wではなく、10 Wモードでしか動作しません。これは、私のバッテリーには少し多すぎます。 5Wモードでは、推論に時間がかかりすぎます:

小さいRNNを試して、使用可能な2つのCPUコア(nvpmodel -m 1)から3つに増やしましたが、あまり役に立ちませんでした。推論にかかる時間が30ミリ秒に短縮されましたが、正確な結果を得るにはまだ長すぎます。

パート7:マッピング

マップを作成するには、JetsonでIsaacのインスタンスを1つ実行し、ホストコンピューターでIsaacのインスタンスを1つ実行する必要があります。マッピングには、JetsonNanoが処理できる以上の多くのリソースが必要です。

  [email protected]:〜/ ml / jetson-ev3 $ ./engine/build/deploy.sh --remote_user andrei -p // apps / ev3:gmapping_distributed_ev3 -pkg -d jetpack43 -h 192.168.0.218 

[メール保護]:〜/ deploy / andrei / gmapping_distributed_ev3-pkg $ ./apps/ev3/gmapping_distributed_ev3

[email保護]:〜/ ml / jetson-ev3 $ bazel run apps / ev3:gmapping_distributed_host

ファイルapps / ev3 /gmapping_distributed_host.app.jsonをJetsonIPで変更することを忘れないでください:

  "tcp_subscriber":{
"isaac.alice.TcpSubscriber":{
"port":5000、
"host" : "192.168.0.218"
}
}

出典:自律型タンク


製造プロセス

  1. ロバの車のガベージコレクターのための自動運転AI
  2. 戦車23日目:射程と方位
  3. JQR Quadruped Autonomous Robot
  4. 自律的な未来への準備
  5. CNC機械加工の戦車モデル
  6. 自律型ロボットが扉を開く
  7. 自律アセンブラアセンブル
  8. 予備タンクとは?
  9. 燃料タンク溶接の安全上のヒント
  10. 車のガス漏れを修理するにはどうすればよいですか?
  11. 自動運転車の技術