前回はロボットの車体部分を作成しました。それでは、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 コメント:
コメントを投稿