前回はロボットの車体部分を作成しました。それでは、Raspberry PiのGPIOを使い、モータードライバを制御することでロボットのモータを回転してみましょう。まずはOSインストールからです。
Raspberry pi 2 にUbuntu 14.04をインストールする
Ubuntuのサイトhttps://wiki.ubuntu.com/ARM/RaspberryPi
より、Download 2015-04-06-ubuntu-trusty.zip をダウンロード、展開します。
展開したdmgファイルをSDカードに書き込みします。次はMacでの手順例です。
まずは、書き込み対象のSDカードを判定します。もし、間違えて指定した場合、間違えた先のデータが綺麗に消えてしまいます。慎重にいきましょう。
SD挿入前に次のコマンドを実行します。
$ df -h
そしてSD挿入後に再度実行します。
$ df -h
SDカードの挿入前、挿入後で増えているのがSDカードのデバイスファイルです。例えば/dev/disk2s1とか/dev/disk3s1とかになります。
書き込み対象となるSDのパーティーションをアンマウントします。
sudo diskutil unmount /dev/disk3s1他には、ディスクユーティリティを開いてSDカードのそのパーティーションをアンマウントする方法もあります。
SDカードはそのままです。抜かないでください。
たとえばdisk3s1ならばs1を除いたdisk3がデバイスネームです。
次のコマンドで書き込みます。デバイスネームの前にrを書き込むのがポイントです。
例えば、/dev/disk3s1 は /dev/rdisk3 となります。
sudo dd bs=1m if=2015-04-06-ubuntu-trusty.img of=/dev/rdisk3
書き込みには結構時間がかかります。
ルートリサイズ
SDカードの全容量が利用可能となるように設定します。$ sudo fdisk /dev/mmcblk0
2番目のパーティションを削除します (d, 2), それから再作成します。(n, p, 2, enter, enter), そして (w)を押して保存して終了します。
再起動してから次のコマンドを実行します。
$ sudo resize2fs /dev/mmcblk0p2
SWAPの作成
初期状態ではSWAPパーテーションがありません。SWAPファイルを準備しておきましょう。$ sudo apt-get install dphys-swapfile
WIFIファームウェア
WIFIを使用する場合、linux-firmwareのインストールが必要です。$ sudo apt-get update $ sudo apt-get install linux-firmware $ sudo reboot
SSHサーバー
他のPCからSSHで接続してメンテナンスできるようにsshのインストールをしておきます。$ sudo apt-get install openssh-server
GPIOでソフトウェアPWM制御を行う
PWM制御とは、半導体を使った電力制御方式で、オンとオフの繰り返しスイッチングを行い、出力される電力を制御します。Raspberry Piもハードウェア制御のPWMが行えるGPIOを持っていますが、数が限られています。そこでソフトウェア制御によるPWMを利用します。ハードウェア制御のPWMには精度は劣りますが、モータの回転制御に使用する分には十分です。
WiringPiのインストール
WiringPiはRaspberry PiのGPIOを制御するためのC言語ライブラリです。ソフトウェアPWM制御を行うことも可能です。またラッパーによりPythonから使用することが可能です。sudo apt-get install libi2c-dev sudo apt-get install git sudo apt-get install git-core sudo apt-get install build-essential cd /opt sudo git clone git://git.drogon.net/wiringPi cd wiringPi sudo ./build cd /opt sudo git clone https://github.com/WiringPi/WiringPi-Python.git cd WiringPi-Python sudo git submodule update --init
モーターの動作テスト
それではWiringPiを使い、モーターが正しく回るかテストしてみましょう。// Include header file #include <wiringPi.h> // Define GPIO #define GPIO_00 17 #define GPIO_02 27 #define GPIO_03 22 #define GPIO_01 18 #define GPIO_04 23 #define GPIO_05 24 #define GPIO_23 13 #define GPIO_24 19 #define GPIO_25 26 #define GPIO_27 16 #define GPIO_28 20 #define GPIO_29 21 int vref[] = {GPIO_00, GPIO_01, GPIO_27, GPIO_23}; int in1[] = {GPIO_02, GPIO_04, GPIO_28, GPIO_24}; int in2[] = {GPIO_03, GPIO_05, GPIO_29, GPIO_25}; /** * motor 0-3 * rotate 0 or 1 */ void run_motor(int motor, int rotate) { int vin1 = rotate == 0 ? 1 : 0; int vin2 = rotate == 0 ? 0 : 1; digitalWrite(in1[motor], vin1); digitalWrite(in2[motor], vin2); digitalWrite(vref[motor], 1); } void break_motor(int motor) { //digitalWrite(vref[motor], 0); digitalWrite(in1[motor], 1); digitalWrite(in2[motor], 1); } void stop_motor(int motor) { digitalWrite(vref[motor],0); digitalWrite(in1[motor], 0); digitalWrite(in2[motor], 0); } void foward() { stop_motor(1); stop_motor(3); run_motor(0, 0); run_motor(2, 1); } void back() { stop_motor(1); stop_motor(3); run_motor(0,1); run_motor(2,0); } void right() { stop_motor(0); stop_motor(2); run_motor(1,0); run_motor(3,1); } void left() { stop_motor(0); stop_motor(2); run_motor(1,1); run_motor(3,0); } void break_all() { break_motor(0); break_motor(1); break_motor(2); break_motor(3); delay(200); stop_motor(0); stop_motor(1); stop_motor(2); stop_motor(3); } int main(void) { // Initialize WiringPi if(wiringPiSetupGpio() == -1) return 1; // Set GPIO pin to output mode for(int i = 0; i < 4; i++) { pinMode(vref[i], OUTPUT); pinMode(in1[i], OUTPUT); pinMode(in2[i], OUTPUT); } // Spin motor foward(); delay(3000); break_all(); back(); delay(3000); break_all(); right(); delay(3000); break_all(); left(); delay(3000); break_all(); return 0; }
まず、wiringPi.hをインクルードしてWiringPiの基本機能が使えるようにします。
#include <wiringPi.h>
次に、wiringPiSetupGpio()関数を呼び出し、GPIOを事前にセットアップしておきます。
// Initialize WiringPi if(wiringPiSetupGpio() == -1) return 1;
使用するピンを出力用に設定します。4つのモーターを使用するためピン番号は事前に配列に入れてあるため、forループですべてのピンを出力に設定しています。
for(int i = 0; i < 4; i++) { pinMode(vref[i], OUTPUT); pinMode(in1[i], OUTPUT); pinMode(in2[i], OUTPUT); }
また、ピン番号は「gpio readall」コマンドにて確認できます。
digitalWrite()関数により、目的のGPIOを0(LOW)または1(HIGH)に設定することが可能です。
このプログラムでは、IN1またはIN2を1(HIGH)に設定しています。
また、モータードライバのVrefは1(HIGH)にします。
これにより、モーターへの供給電圧は最大に設定されます。
digitalWrite(in1[motor], vin1); digitalWrite(in2[motor], vin2); digitalWrite(vref[motor], 1);
コンパイルと実行
それではコンパイル及び実行をしてみましょう¥。cc -std=c99 -pthread -o gpiotest gpiotest.c -lwiringPi sudo ./gpiotest
実行すると、各モーターが回転したあと、プログラムが終了すると思います。
次にモーターのGPIOに渡す値を変えて試してみましょう。例えば次の画像はすべてのモーターを同じ方向に回した時の例です。
これでラズパイにおけるGPIOの制御が可能となりました。次回はこのロボットを制御するROSプログラミングについて解説していきます。
ROSで始めるロボティクス(6) ー ROSでデプスカメラPMD CamBoard pico flexxを使う
ROSで始めるロボティクス(7) ー ロボットのための二次元mapを作る
ROSで始めるロボティクス(8) ー ロボットのナビゲーションを行う
ROSで始めるロボティクス(9) ー ROSを使ったステレオカメラキャリブレーションROSで始めるロボティクス(7) ー ロボットのための二次元mapを作る
ROSで始めるロボティクス(8) ー ロボットのナビゲーションを行う
ROSで始めるロボティクス(10) ー オムニホイールで全方向移動可能ロボットを作る 1
ROSで始めるロボティクス(11) ー オムニホイールで全方向移動可能ロボットを作る 2
参考文献:
詳解 OpenCV
詳解 OpenCV
記載されている会社名、および商品名等は、各社の商標または登録商標です。
0 コメント:
コメントを投稿