TRIC Robotic Designerの紹介:逆振り子

問題の概要と説明







女性の胸とおもちゃの鉄道の共通点は何ですか? そうです、これとそれは子供向けであり、父親は彼らと遊ぶ。 数日前、ロボットデザイナーTRICを入手しました。 キットは非常に厳しいものであり、開発者は、ラピッドプロトタイピングおよびトレーニングに適していると主張しています。



ロボットゲームの市場で現在入手可能なものは何ですか? 各プロジェクトの自家製回路基板は考慮していません。 レゴ、飲み物、アルドゥイーノ。 レゴは美しいですが、残念ながら、非常に、非常に限られています。 十字架とアルドゥインは非常にうまく展開しますが、かなり不便であり、すぐにさまざまなカード、ネームプレート、モックアップのパン粉に変わります。 これは、サンクトペテルブルクの人々がTRIKデザイナーと一緒に市場に参入する場所です。



だから、私の仕事は、これが一般の人々(私)にどれだけアクセスしやすいかを理解することです。 理論的なサイバネティックスや経営理論に関する講義に参加したことはありません。 オームの法則は、ソケットを舐める価値がないことを理解するのに十分なだけであり、はんだごては私の友人ではありません。 しかし、普通の(年齢を超えた)子供と同じように、私は遊ぶのが好きなので、このトピックに興味を持つようになりました。







私はこのセットを手に入れました:





一般に、そのセットの価格は約2万から7万ルーブルまでさまざまです。 レゴよりも高価ですか? いや 1か月前、レゴEV3を購入しました。 質問の価格は370ユーロの基本セット+ 100ユーロのバッテリー(それらは完全に素晴らしいですか?!)そして、私はまだ30ユーロの充電器を考慮しませんでした。 さらに、ソナー(+ 35€)もジャイロスコープ(+ 35€)も基本セットに含まれていません。 また、原則として、Legov Linuxへのアクセスの欠如に言及することさえせずに、一般的にマイク付きのカメラを忘れることができます。



私のセット(前の写真でレイアウトされています)には、2 つのコントローラー 、2つのカメラ、2つのマイク、ソナー、2種類の赤外線センサー、ボタン、光エンコーダー付きの6つの電動モーター、3つのサーボ、2つの機械式グリップ、ホロノミックなものを含む多数のホイール、充電電池、ひも、ギア、ラック、たくさんの金属板と角(こんにちは!) 設計者は最初から純粋で、一般に、想像力に十分なコントローラーにほとんど何でも接続できます。 ARM9中央処理装置、ビデオの下の中央処理装置をロードしないように別のプロセッサ。 アセンブラからC#まで何でもプログラムできます。ルートコンソールを提供し、ファームウェアコード全体がオープンソースです。



これは私の奇跡の箱のようです:









最初のプロジェクトとして、私は逆振り子を組み立てることに決めました。そして、それはタイトル絵に提示されます。 これは後ろから見たものです:



セットから、2つのエンジン、2つの車輪、小さな留め具、およびバッテリーを備えたコントローラー自体が必要でした。 私の目標は、TRICトレーニングコースからチュートリアルをコピーすることではなく、自分ですべての問題について歯を磨くことに興味があるため、車輪を再発明します。



そのため、自由度1、自由度、加速度計、ジャイロスコープでは、エンジンのエンコーダーを使用しませんでした。 Qt Scriptに書き込みます。



読み取りセンサー



最初は、1つの加速度計でうまく行きたいと思っていました。 同様に、Z軸への投影の符号を読み取り、正の場合はホイールを一方向に、負の場合は他の方向に回転させます。 理論的には、すべてがうまくいきますが、これを行った後、私は私のカートのワイルドジャークを得ました。 それはあまり長くないことが判明したため、彼はため息をついて文学を勉強するために座った。 だから、私はトロリーの垂直からの角度にのみ興味があります。



ジャイロスコープ



彼は角速度センサーであり、良好な滑らかな信号を生成しますが、空間での向きを追跡するには速度を統合する必要があります。 最初は、エラーが発生して速度が発行されますが、統合により多くのエラーが発生し、最終的にジャイロの読み取り値が変動します。 したがって、振り子にはジャイロスコープだけでは十分ではなく、加速度計と組み合わせる必要があります。



これが私のジャイロコードです。(true)はメインプログラムループです。

var gyr_x_angle = 0; var lasttime = Date.now(); while (true) { var G = brick.gyroscope().read(); G[0] = G[0] + 69; // drift correction var curtime = Date.now(); var dt = (curtime - lasttime)/1000.0; lasttime = curtime; gyr_x_rate = G[0] * 0.07; gyr_x_angle = gyr_x_angle + gyr_x_rate * dt; }
      
      







配列Gでセンサー値を読み取り、次の行で関心のある軸を修正します。 完全に静止している私の特定のセンサーは平均69ユニットの速度を示しているので、興味のある速度を得るためにそれらを減算します。

センサーは、コーナーに変換する必要がある整数を提供します。 通常モードでは、2000度/秒(dps)で動作します。 Datashitによれば、これは70mdps /桁の定数に相当します。 したがって、G(桁)* 0.07(dps /桁)は角速度を示します。 dtに測定時間を掛けて積分することは残ります。



加速度計



加速度計から角度を取得することはさらに簡単ですが、問題はそれがうるさすぎることであり、トロリーが前後に動き始めたとき、死体は一般に外れています。 コードは次のようになります。

  [...] while (true) { [...] var A = brick.accelerometer().read(); var a_x_angle = Math.atan(A[2] / A[0]) * 180.0 / pi; }
      
      







ノイズを消します:加速度計とジャイロスコープの読み取り値の組み合わせ



  [...] var CF_x_angle = 0; while (true) { [...] CF_x_angle = 0.98*(CF_x_angle+ gyr_x_rate*dt) + 0.02*a_x_angle; }
      
      





現在の角度の値は、ジャイロスコープによって調整された前の角度の値の98%であり、2%は加速度計からの角度の直接読み取り値であるというだけです。 この組み合わせにより、ジャイロスコープのフローティングを処理できます。ここでは、gyr_x_angle変数をまったく使用していません。



PIDコントローラー



先ほど言ったように、私は制御理論に関する賢明な講義には出席しなかったので、 LQRレギュレーターは妥当な時間(数時間)の間、私にとっては強すぎます。 しかし、 PIDは問題ありません。



コード





前のパラグラフで、トロリーの垂直からの逸脱の角度の適切な(私は)推定を得ました。 カルマンフィルターを使用して改善できますが、これはスズメの大砲からの射撃です。 さあ、車輪を回転させましょう。たわみ角が大きいほど、車輪を高速に回転させる必要があります。



PIDが提供するホイール回転速度は、比例、積分、微分の3つの(重み付けされた)用語で構成されます。 比例は単に垂直からの偏差の角度に等しく、積分はすべての制御誤差の合計であり、微分は垂直からの偏差の変化率に比例します。



怖いですが、実際にはコードは非常にシンプルです:

完全なプログラムコード
  var gyr_x_angle = 0; var lasttime = Date.now(); var CF_x_angle = 0; var iTerm = 0; var CF_x_angle_prev = 0; var KP = 0; var KI = 0; var KD = 0; while (true) { var G = brick.gyroscope().read(); G[0] = G[0] + 69; // drift correction var curtime = Date.now(); var dt = (curtime - lasttime)/1000.0; lasttime = curtime; gyr_x_rate = G[0] * 0.07; var A = brick.accelerometer().read(); var a_x_angle = Math.atan(A[2] / A[0]) * 180.0 / pi; CF_x_angle = 0.98*(CF_x_angle+ gyr_x_rate*dt) + 0.02*a_x_angle; //  ! var pTerm = KP*CF_x_angle; //   iTerm = iTerm + KI*CF_x_angle; //   var dTerm = KD * (CF_x_angle - CF_x_angle_prev); //   CF_x_angle_prev = CF_x_angle; power = pTerm + iTerm + dTerm; brick.motor(M3).setPower(power); brick.motor(M4).setPower(power); }
      
      









定数KP、KI、KDの選択



最も難しい部分は残っています。残念ながら、合計の重み値を見つけるには、これは経験的にしか行えません。



まず、係数KPを見つけます。 KIとKDをゼロに設定し、トロリーが次のような(ほぼ)一定の振動を開始する瞬間まで、KPをゼロから始めて増加させます(KP = 8、KI = 0、KD = 0):





明らかに、これは破壊的であり、カートは比例成分から非常に強い信号を受信するため、約半分に削減し、これを取得します(KP = 5、KI = 0、KD = 0):





トロリーには純粋に比例した信号がないため、積分コンポーネントを追加して速度を上げます。 KIをゼロからスムーズに増加させ、カートを目的の位置の周りで再び振動させる瞬間に到達しようとします(KP = 5、KI = 0.5、KD = 0):





次に、ダンパーの役割を果たし、振動を減衰させる差別化コンポーネントを追加します。これが得られるものです(KP = 5、KI = 0.5、KD = 5)。





おわりに



私はかなり早く(ある晩)自己バランスのトロリーを手に入れました。 私のプログラムが25行になっていることを考えると、今は暇なときにカート、ターン、障害物コースの通過を追加する必要がありますが、これはそれほど難しくないはずです。



私には電気技術もサイバネティックなバックグラウンドもありません。つまり、普通のユーザーにとっては非常にアクセスしやすく、実際、私にとって非常に興味深いものです。 勉強を続けます!



同じレゴフセットと比較すると、もちろん、すべてが少し不器用な中国のセンサー(レゴのような)に見えますが、厚くて高品質のレゴフプラスチックに巻き込まれていません。 あまりなめられていないソフトウェアで、現在開発中です。 このコントローラーでプログラミングする人々のコミュニティははるかに小さくなりますが、プロジェクトが1週間に及ぶことを考えると、最近のarduinoの成功を見ても、それほど怖くはありません。 しかし、私はコントローラーの柔軟性を賞賛します。これは、ピーターが開発を引き受けた途方もない熱意から生まれました。








更新:コントローラーの仕様



多くの人は、トリックコントローラーとArduinoまたはLegovボックスの違いを理解していません。 タブレットは次のとおりです。

中央処理装置(CPU) OMAP-L138 C6-Integra™DSP +ARM®SoC、Texas Instruments
CPUクロック速度 375 MHz
CPUコア ARM926EJ-S™RISC MPU
CPU DSPコア C674x固定/浮動小数点VLIW DSP
RAM 256 MB
フラッシュ-メモリ 16 MB
周辺プロセッサ(PP) MSP430F5510、Texas Instruments
PPクロック周波数 24 MHz
ユーザーインターフェース USB 2.0、WiFi b / g / n、BlueTooth、2 * UART、2 * I2C、Micro-SD、マイク入力(ステレオ)、ライン出力(モノ)
DCモーターのインターフェース 4つのモーターポート6〜12V DC、個別のハードウェア過電流保護(モーターごとに最大2A)
周辺機器インターフェース 3.3-5V電源を備えた19個の汎用信号ポート(6個のシングルチャンネルと13個のデュアルチャンネル)、そのうち6個はアナログ入力モードで動作可能
ビデオセンサーインターフェース 2入力BT.656 VGA 640 * 480、ステレオモードをサポート
内蔵LCDモニター 2.4” TFT、カラー、タッチ、解像度320 * 240ピクセル
内蔵スピーカー 定格電力1W、ピーク3W
LEDインジケータ 2色、プログラム可能
拡張スロット 2 * 26ピン「スロット付き」拡張モジュールコネクタ
追加の機器(コントローラーに含まれる) 3軸加速度計、3軸ジャイロスコープ、オーディオコーデック、アンプ、コンバーター、および電源管理回路、電圧および電流用の入出力過負荷保護回路
電源 6-12V DC、外部ACアダプターまたはLiPoバッテリーRC 3P(11.1V)/ 2P(7.4V)
ケース寸法 125 * 80 * 25 mm



All Articles