twitter icon   twitter icon   rss icon

Linux.com Japan

Home Linux Jp チュートリアル BeagleBone とタブレットで 3 車輪ロボットを制御する

BeagleBone とタブレットで 3 車輪ロボットを制御する

原文はこちらです (訳注: ここで紹介するロボット キットは、日本国内では販売されていません。しかし、似たようなキットが、タミヤ模型等から販売されています)。

terrytee pantilt

BeagleBone Black に車輪をつけ、タブレットから無線ですべてを操作できるようにしたロボットを製作しましょう。

 3 車輪ロボット キットには、ロボットのベースを作るために必要なすべての部品が含まれています。追加する部品は、モーター 2 個、電池、そして制御するための機構です。用途に応じたトルク、回転数を持つモーターを選択できます。

 本文献では、BeagleBone Black 上で Web サーバーを動かし、タブレットから簡単にロボットを制御するための Bonescript を動かします。アプリケーションを使う必要はありません。Bonescript は、BeagleBone Black で動く nodejs 環境です。

 左図に、3 車輪ロボット ベース キット、パン・チルト機構のための部品を示します。黒線より上の部品と電池、電子部品、ケーブルおよび 2 つのモーターが追加部品です。BeagleBone Black を使ってロボットの制御ができるようになったら、他の部品を追加しましょう。

 ここでは、45rpm プリシジョン モーターを使用します。車輪は直径 6 インチですから、ロボットは最大分速 86 フィート (分速 26 メートル) を出せます。このモーターは、6-12V で動作し、最大 1A を消費します。なにかが邪魔してモーターが回転できないときに、最大電力を消費します。たとえば、ロボットが壁にぶつかり、タイヤがスリップしないでいるときなどです。そのような状況を検出して電源をオフにすることは、無駄な電池の消費を防ぐとともに、モーターのオーバー ヒートやダメージを防止します。

 Linux.com に掲載している BeagleBone Black の一連の文献で、SPI からのチップ アクセス方法割り込みの受信方法を学びました。これらを使って、ピン上の電圧変化や、サーボ モーターの制御を行うことができます。

3 車輪ロボットを製作する

3 wheel robot kit parts

上図に、3 車輪ロボット キットと追加したモーターを示します。自分が好きなように組み立てることができます。追加モーターに応じた部品を使い、2 つの前輪をマウントします。ハブ スペーサーを使って、2 つのチャネルを接続します。継手 (Swivel) を使い、ロボットの後ろにある小さめのチャネルを接続します。ここでは、2 車輪側を前と表現しています。著者は、ハブ アダプター、スクリュー ハブ、2 つのモーター マウント用部品を使い、2 車輪側を先に製作しました。これらの部品を使うと、残りの部品がわかりやすくなります。

電力を入れる

terry in construction

以前に書いた文献で、BeagleBone Black は、2.5 から 3W 必要とすることを紹介しました。BeagleBone Black への電力供給には、さまざまな方法があります。著者は、3.7V のリチウム電池 (18650) と 5V への昇圧ボードを用いました。BeagleBone Black は、5V 入力を必要とします。CPU が高負荷のときは 3.5W 必要ですから、バッテリと昇圧ボードは 5V/700mA を供給できなければなりません。バッテリ容量は 3AHr ですから、1 回の充電で BeagleBone Black を数時間動かすことができます。

 モーターは、6 から 12V を必要とするので、モーター用に別のバッテリを用意しました。これで、BeagleBone Black の動作を邪魔することはありません。モーター用として、単 3 型の NiMH (ニッケル水素) バッテリを 8 個使用したブロック タイプを利用しました。この出力電圧は 9.5V 程度なので、モーターは最大出力を出すことはできませんが、出費を抑えられます。過剰な電流を流さないように、テストでは、モーターが過負荷にならないようにしました。モーターの過負荷防止とバッテリ保護を行うか、高価な高出力のバッテリを用意するかのどちらかです。たとえば、電流監視装置を使い、電流を遮断する方法もあります。

モーターへの電力は、H ブリッジ回路 (訳注: トランジスタ等で、モーターの正逆回転を制御する回路。たとえばここを参照。) 経由で供給されます。H ブリッジ回路の接地点を BeagleBone Black との共通の接地点にすると便利でしょう。

無線で通信する

  BeagleBone Black は WiFi を搭載していません。簡単に無線を実現する方法のひとつは、TP-Link WR-703N (訳注: こちらに情報があります) に openWRT (訳注: wikipedia に情報があります) を書き込み、それをアクセス ポイントとして利用することでしょう。TP-Link WR-703N をロボット ベースに搭載し、BeagleBone Black のイーサネット ポートと接続します。タブレットかラップトップで、ボード上の WR-703N が提供するアクセス ポイントに接続します。

 WR-703N を DHCP サーバーとし、BeagleBone Black に既存の有線 LAN と同じ IP アドレスを割り当てるようにします。このようにすることで、設定変更をすることなく、実験中は有線 LAN に接続し、本番では無線を使うことができます。

BeagleBone Black からモーターを制御する

 以前の文献で紹介したサーボ モーターと異なり、回転角を制御するパルス幅モジュレーション (PWN) 制御線を持ちません。電力線と接地線があるだけです。12V を供給すると、最大速度で回転します。たとえば、最大速度の 70% に遅くするには、供給電圧を 70% にする必要があります。そこで、モーターの電力線を PWM 制御する必要があります。サーボ モーターの制御 PWM と違い、20m 秒のタイム スライスの制約はありません。自由に決めて良いのです。たとえば、0.7 秒供給して、0.3 秒カットするのです。タイム スライスを 1 秒以下にすると回転が滑らかになります。

 H ブリッジ用チップを用いると、BeagleBoard Black の 3.3V ラインを使って、高電圧、大電力をスイッチすることができます。H ブリッジ回路ひとつで、モーター 1 台を制御できます。L298 (訳注: 日本では 秋月電子通商で入手可能です) のようなチップには、H ブリッジ回路が 2 つ入っています。ステップ モーターを複数台制御するのに便利です。ボードには、ヒート シンクと接続端子が付いて、小さいものは 中国のショップで $5.00、電流モニター用の抵抗入りのカナダ産ボードは $30 で売られています。

 L298 は、H ブリッジ制御用のピン 2 本と、イネーブル ピンを備えています。2 本の制御ピンを使って H ブリッジを制御し、モーターへの電流の方向を切り替えます。この制御ピンのどちらをハイにするかで、回転方向 の正逆が決まります。イネーブル ピンをハイにすると、バッテリからモーターへ H ブリッジが決めた方向へ電流が流れます。このイネーブル ピンを利用して、回転速度を制御する PWM を実現します。

 2 本の制御ピンと、イネーブル ピンで、1 つの H ブリッジ回路、つまり 1 つのモーターを制御します。L298 にはもう 1 組のイネーブル ピンと制御ピンがあり、モーターをもう 1 つ制御できます。これらの線のほかに、BeagleBone Black との間で接地線と 3.3V 線をつなぐ必要があります。

 最初、ロボットをまっすぐ走行させようとした時、どうしても左へ曲がってしまいました。何回か実験した後、左のモーターが若干遅いことを発見しました。早い段階で発見できたので、ソフトウェアに回転速度の微調整機能を入れることができました。つまり、100% 出力を指示すると、ソフトウェアは、右モーターを 97% 出力とするのです (もしくは、微調整で指定した値)。

 2 つのモーターを簡単に制御するため、2 つの考え方、スピード (0-100) と方向 (0-100) を用いました。方向 50 がまっすぐを意味します。これは、車と同様に、ハンドルの向き (方向) とアクセル (スピード) を指定すれば、ロボットが考えてくれるのです。

 全ソースコードを github に公開しました。ブランチ linux.com-article が、本文献執筆時のブランチです。マスター ブランチには、いくつか新機能と変更を入れてあります。

サーバー

 このロボット ベースは T 形をしているので、TerryTee と呼びます。モーターの PWM 制御を TerryTee nodejs クラスとして実装するのに、bonescript を用います。

 左右のモーターの PWM 信号用のピン識別子を使い、1.0 (100% 出力)、0.95 (95% 出力) 等の回転数の削減率を制御します。削減率をいじることで、モーターの回転数を制御します。

function TerryTee( leftPWMpin, rightPWMpin, leftReduction, rightReduction )
{
    TerryTee.running = 1;
    TerryTee.leftPWMpin = leftPWMpin;
    TerryTee.rightPWMpin = rightPWMpin;
    TerryTee.leftReduction = leftReduction;
    TerryTee.rightReduction = rightReduction;
    TerryTee.speed = 0;
    TerryTee.heading = 50;
}

下図にある setPWM() メソッドは、TerryTee での最下位のメソッドです。上位メソッドは、本メソッドを使って各モーターの速度を制御します。PWMpin でモーターを指定し、'perc' は、モーターに電力を供給する割合を指定します。perc には、0-100 を指定できるようにして、Web インタフェースですべての値を扱えるようにしました。

 緊急停止の場合、running の値が false のため、setPWM は現在の状態を変更しません。setPWM は、モーターの個体差の微調整も行うため、上位メソッドは微調整のことを意識する必要がありません。analogWrite() Bonescrip が、実際の PWM ハードウェアへの信号の書き込みを行います。ソフトウェアからのリフレッシュは必要としないので、設定しなおすまで、同じ回転率で回転します。

TerryTee.prototype.setPWM = function (PWMpin,perc) 
{
    if( !TerryTee.running )
	return;
    if( PWMpin == TerryTee.leftPWMpin ) {
	perc *= TerryTee.leftReduction;
    } else {
	perc *= TerryTee.rightReduction;
    }
    if( perc >  1 )   
	perc /= 100;
    console.log("awrite PWMpin:" + PWMpin + " perc:" + perc  );
    b.analogWrite( PWMpin, perc, 2000 );
};

SetSpeed() は、現在の方向を考慮して、各車輪の PWM 信号を制御し、指定方向と指定スピードを実現します。

TerryTee.prototype.setSpeed = function ( v ) 
{
    if( !TerryTee.running )
	return;
    if( v < 40 )
    {
	TerryTee.speed = 0;
	this.setPWM( TerryTee.leftPWMpin,  0 );
	this.setPWM( TerryTee.rightPWMpin, 0 );
	return;
    }
    var leftv  = v;
    var rightv = v;
    var heading = TerryTee.heading;
    
    if( heading > 50 )
    {
	if( heading >= 95 )
	    leftv = 0;
	else
	    leftv *= 1 - (heading-50)/50;
    }
    if( heading < 50 )
    {
	if( heading <= 5 )
	    rightv = 0;
	else
	    rightv *= 1 - (50-heading)/50;
    }
    console.log("setSpeed v:" + v + " leftv:" + leftv + " rightv:" + rightv );
    this.setPWM( TerryTee.leftPWMpin,  leftv );
    this.setPWM( TerryTee.rightPWMpin, rightv );
    TerryTee.speed = v;
};

 サーバーは、TerryTee オブジェクトを生成し、Terry を制御するための Web ソケットを提供します。'stop' メッセージは緊急停止を意味し、Terry を停止させ、一定時間入力を無視します。その間に、ロボットをチェックして、問題があれば、電力供給を絶ちます。

var terry = new TerryTee('P8_46', 'P8_45', 1.0, 0.97 );
terry.setSpeed( 0 );
terry.setHeading( 50 );
b.pinMode     ('P8_37', b.OUTPUT);
b.pinMode     ('P8_38', b.OUTPUT);
b.pinMode     ('P8_39', b.OUTPUT);
b.pinMode     ('P8_40', b.OUTPUT);
b.digitalWrite('P8_37', b.HIGH);
b.digitalWrite('P8_38', b.HIGH);
b.digitalWrite('P8_39', b.LOW);
b.digitalWrite('P8_40', b.LOW);
io.sockets.on('connection', function (socket) {
  ...
  socket.on('stop', function (v) {
      terry.setSpeed( 0 );
      terry.setHeading( 0 );
      terry.forceStop();
  });
  socket.on('speed', function (v) {
      console.log('set speed to ', v );
      console.log('set speed to ', v.value );
      if( typeof v.value === 'undefined')
	  return;
      terry.setSpeed( v.value );
  });
  ...

 github 上のソース コードは、停止時間を設定可能にして、Terry がタブレットから再起動可能としています。

クライアント (Web ページ)

Web インタフェースを簡単に作成するため、BootstrapjQuery を使いました。もっと複雑なインタフェースが必要ならば、Angularjs を使うのが良いでしょう。スピードと方向制御のためのタッチ インタフェース実装に bootstrap-slider を使いました。

BeagleBone robot web interface
<div class="inner cover">
  <div class="row">
    <div class="col-md-1"><p class="lead">Speed</p></div>
    <div class="col-md-8"><input id="speed" data-slider-id='speedSlider' 
                    type="text" data-slider-min="0" data-slider-max="100" 
                    data-slider-step="1" data-slider-value="0"/></div>
  </div>
  <div class="row">
    <div class="col-md-1"><p class="lead">Heading</p></div>
    <div class="col-md-8"><input id="heading" data-slider-id='headingSlider' 
                    type="text" data-slider-min="0" data-slider-max="100" 
                    data-slider-step="1" data-slider-value="50"/></div>
  </div>
</div>
<div class="inner cover">
    <div class="btn-group">
	<button id="rotateleft" type="button" class="btn btn-default btn-lg" >
	  <span class="glyphicon glyphicon-hand-left"></span>&nbsp;Rot&nbsp;Left</button>
	<button id="straightahead" type="button" class="btn btn-default btn-lg" >
	  <span class="glyphicon glyphicon-arrow-up"></span>&nbsp;Straight&nbsp;ahead</button>
	<button id="rotateright" type="button" class="btn btn-default btn-lg" >
	  <span class="glyphicon glyphicon-hand-right"></span>&nbsp;Rot&nbsp;Right</button>
    </div>
</div>

 これらのユーザー インタフェースのエレメントのフック アップには、io.connect() を使い、'var sock' とコネクトして、BeagleBone Black へ入力を戻しています。以下のコードは、Web ページの UI エレメントに入力されたコマンドを BeagleBone Black に戻すものです。rotateleft コマンドは、一定秒数の間、方向とスピードを設定し、その後、停止することを意味します。

$("#speed").on('slide', function(slideEvt) {
    socket.emit('speed', {
        value: slideEvt.value[0],
        '/end': 'of-message'
    });
});
...
$('#straightahead').on('click', function (e) {
     $('#heading').data('slider').setValue(50);
})
$('#rotateleft').on('click', function (e) {
     $('#heading').data('slider').setValue(0);
     $('#speed').data('slider').setValue(70);
     setTimeout(function() {
        $('#speed').data('slider').setValue(0);
        $('#heading').data('slider').setValue(50);
     }, 2000);
})

 BeagleBone Black は、Web サーバーを /usr/share/bone101 にあるファイルから始めるようにしています。すべてのプロジェクトを /home/xuser/webapps/terry-tee に置き、それらへのソフトリンクを /usr/share/bone101/terry-tee に設定するのが良いとわかりました。こうすることで http://mybeagleip/terry-tee/index.html にアクセスすると、タブレットに Web インタフェースが表示されます。Cloud9 (訳注: 突然出てきますが、著者は Cloud9 を利用しているようです。ここに BeagleBone へのインストール例があります) が /var/lib/cloud9/autorun にある Bonescript を自動的に実行します。この 2 つのリンクを用いて、クライアントの実行と、サーバーの Bonescript の実行を自動的に行えます。

root@beaglebone:/var/lib/cloud9/autorun# ls -l
lrwxrwxrwx 1 root root 39 Apr 23 07:02 terry.js -> /home/xuser/webapps/terry-tee/server.js
root@beaglebone:/var/lib/cloud9/autorun# cd /usr/share/bone101/
root@beaglebone:/usr/share/bone101# ls -l terry-tee
lrwxrwxrwx 1 root root 29 Apr 17 05:48 terry-tee -> /home/xuser/webapps/terry-tee

まとめ

 最初は、GPIO ピンの P8_41 から 44 を使おうとしました。しかしこれらにつないでみると、BeagleBone Black が起動しなかったのです。一旦、線を取り外し、BeagleBone Black を起動後つないでみると、問題なく動作しました。一方、41 から 44 には接続せず、37 から 40 を使ってみると、BeagleBone Black は問題なく起動しました。もし BeagleBone Black が起動しなかった場合は、運悪く起動中に使用しているピンを使ってしまったのだと思います。

 本文献で紹介した構成は、ロボット ベースの移動機能だけを制御しています。しかし、コードを拡張することによって、ロボットの別の機能を制御することが可能です。たとえば、腕を取り付けて、物を移動するといったことが、タブレットから制御できるのです。

 BeagleBone Black を使ってロボットを動かすことにより、ロボット ベースに BeagleBone Black CPU の力和訳はこちら) を付与します。OpenCV (日本語で紹介したページがあります) を利用した物の追跡といった応用が考えられます。常に操作者の正面を見るといった動きができます。ここでは WiFi を用いましたが、3G を使うことにより、場所の制約も外せます。

 BeagleBone Black を利用して、Web で制御するモーター駆動の 3 車輪のロボット ベースを容易に実現できるのです。このようなロボットを一度製作すると、さらに機能を追加したくなるでしょう。

 3 車輪ロボット ベース、モーター、ギア ボックス、そしてサーボを提供してくれた ServoCity に感謝します。

Linux Foundationメンバーシップ

30人のカーネル開発者

人気コンテンツ


Linux Foundationについて

Linux Foundation はLinux の普及,保護,標準化を進めるためにオープンソース コミュニティに資源とサービスを提供しています

 

The Linux Foundation Japan

サイトマップ

問い合わせ先

サイトに関するお問い合わせはこちらまで

Linux Foundation Japan

Linux Foundation

Linux Training

提案、要望

Linux.com JAPANでは広く皆様の提案、要望、投稿を受け付ける予定です。

乞うご期待!