ProjectSRのアイコン画像
ProjectSR 2021年02月24日作成 (2021年02月28日更新)
製作品 製作品 閲覧数 1757
ProjectSR 2021年02月24日作成 (2021年02月28日更新) 製作品 製作品 閲覧数 1757

MATLAB映像表示機能付き無線遠隔通信システム

MATLAB映像表示機能付き無線遠隔通信システム

MATLABを使って,映像表示機能+遠隔操作機能付きロボットの
システム構成を紹介します.

🔳知れる事

◇MATLAB GUI製作

◇ラズベリーパイとMATLABのワイヤレス接続
 Wi-Fiを使う

◇無線で映像の受信と表示

◇ジョイスティックでロボットを無線遠隔操縦

🔳概要・基本構成

①MATLABでGUIの製作を行います.

②MATLABにジョイスティック,ウェブカメラ,ラズベリーパイの設定を行います.

③ラズベリーパイからMATLABへ映像の情報を送り,MATLABのGUIで表示します.

④MATLABからラズベリーパイへジョイスティックの操作量の情報を送ります.

⑤ラズベリーパイは,ジョイスティック操作量を受け取り,Arduinoへ転送します.

⑥Arduinoは操作量を受け取り,モータードライバーへ信号を送り,モータを駆動します.

🔳解説

基本構成は,

①送信側のMATLABでジョイスティックの操作量を計算し,ラズベリーパイへ送信

加えて,ラズベリーパイからの映像の情報をGUIに表示

②ラズベリーパイは,映像の情報をMATLABへ送信

加えてMATLABからの操作量を受け取り,Arduinoへ送信

③Arduinoがモータを制御

解説動画

ユーチューブ ニコニコ動画 にて 解説もしています.
ロボットがどのような動作をされるか見たい方は,ご参照ください.

ここに動画が表示されます

ニコニコ動画

MATLAB映像表示機能付き無線遠隔通信システム

構成

基本構成は,

①送信側のMATLABでジョイスティックの操作量を計算し,ラズベリーパイへ送信
 加えて,ラズベリーパイからの映像の情報をGUIに表示

②ラズベリーパイは,映像の情報をMATLABへ送信
 加えてMATLABからの操作量を受け取り,Arduinoへ送信

③Arduinoがモータを制御

キャプションを入力できます

ポイント

●Wi-Fi環境下なので,通信距離が伸びる事,
映像表示が可能になること
●遠隔操作と映像表示が1つのソフトでできる事
●GUIをカスタマイズできること
です.

現在,下記の課題があります.
①動作遅延が発生
②MATLAB2018a以降では映像が表示できない.

今回はMATLABのguideというGUI作成ツールを使って
ロボットの遠隔操縦を行います.

このguideは,GUIのボタンや座標軸等を
ドラッグ&ドロップで自分の好みに作成できます.
作成ができ,ファイルを保存するだけで,
GUIを表示するプログラムが自動的にできるので,
あとは表示機能に関するプログラムコードを
追加して記入して,今回のシステムを構築できます.

キャプションを入力できます

0⃣前準備

ただし,パソコンにMATLAB2017aまたは2017bをインストールしていない人は,MathWork社から
購入する必要があります.
MATLABは企業用や教育用他のeditionがありますが,個人で使う場合であれば,Home Licenseが利用できます.
インストール時は,1日時間がかかるので,時間に余裕をもって行うとよいでしょう.
キャプションを入力できます

MATLABをインストールしたら,ラズベリーパイとの接続,ウェブカメラ情報のやり取りを行うために
ツールボックス,サポートパッケージが必要です.
数年前にインストールしたので,ちょっと定かではありませんが,現在の私のMATLAB2017には
下記がインストールされています.
他に必要である場合は,MATLABがエラーメッセージを表示してくれるはずなので,適宜追加してください.
(過剰だったらすみません.)
キャプションを入力できます
今回使用するラズベリーパイ3Bの設定は,動画に掲載しましております.

1⃣ウェブカメラ映像表示

ラズベリーパイに装着したウェブカメラの映像表示を行います.
guideでGUIを作成し,GUIで映像表示が可能になるように,プログラムコードを追加すれば機能します.
製作から,起動までの流れは動画に掲載しております.

⇓guideで作成した映像表示テスト用のGUIです.
キャプションを入力できます
↑のプッシュボタンを押せば
↓のように映像が表示されます.
キャプションを入力できます

ラズベリーパイはウェブカメラをつなげ,
電源を入れてからMATLABで接続をしてください.

キャプションを入力できます

以下にプログラムコードの解説と,実際に駆動したときのプログラムを表示します.
MATLAB guideで今回作成したGUIには,Opening関数,Callback関数,guidata関数
という3つの関数でGUIを機能させています.

➊Opening関数
 ラズベリーパイ,ウェブカメラの接続に関する変数をここで定義して代入します.
・ラズベリーパイの設定に関する変数handles.raspiに接続したラズベリーパイの情報を格納
・ラズベリーパイに接続されているウェブカメラの情報を取得するwebcamを使い,変数handles.wcam1に
 情報を代入します
・プッシュボタンが押されていない場合はGUIは映像表示を行わないようにします.
 なので,handles.stateという変数を用意して,NOを代入します.
キャプションを入力できます

MATLAB guideでは handlesという構造体を使って変数を設定し,
GUI作動に必要な関数が情報のやり取りを行い,機能します.
Arduinoですと,構造体を使う必要はないのですが,MATLAB guideでは少し違う運用のようです.

ちなみに構造体とは,左の図のようにintやdouble等多様な型式の変数を格納することができる変数の
枠みたいなもので,「変数を格納した変数」という言われ方もしています.
MATLAB guideでは「handles.変数名」で変数を定義することができます.
なので,たとえばラズベリーパイの変数ではhandles.raspiとしていますが,handles.abcとしても
問題ありません.

キャプションを入力できます

❷Callback関数
 プッシュボタンが押された後に映像が表示されるプログラムコードを追記します.
つまり,プッシュボタンが押されたら,endまでの処理が実行されます.
 Opening関数で設定したhandles.state変数は'access'を代入します.
 続くwhile文の条件でhandles.stateがaccessの時に映像表示が機能します.
 snapshotは,Opening関数で用意したhandles.wcam1の情報を呼び出して,ウェブカメラ映像の1フレームを
 取得します.この1フレーム分のデータを変数img1へ代入し,imshowで使用します.
 imshowでは映像に関する情報と,表示範囲を指定するコードで,imshow(映像表示用変数,'Parent',表示範囲)
「表示範囲」は,guideで設定した座標軸axes1の変数handles.axes1をコードに記載しています.

キャプションを入力できます

❸guidata関数
 Opening関数,Callback関数設定した変数では値を代入しましたが,
 代入した内容を変数内に保存されていません.
 例えばOpening関数で設定したhandles.wcam1に代入された内容は,pushbutton1_Callbak関数へそのまま
 移行されません.
 代入内容を移行するには,保存を行う必要があります.それを行うのがguidata関数です.
 guidata関数は,Opening関数やCallback関数の最後のほうに記入して,変数の内容を保存するという
 プログラムの処理が行われます.
キャプションを入力できます

映像表示に関する主要な部分は以上です.
少しややこしったかもしれないので,簡潔に機能だけ説明すると,

⓵Opening関数でラズベリーパイ,ウェブカメラの情報をMATLABのプログラムを使って入手する.
 プログラムはMATLAB guideで作成されたコードに記入する
 記入では「handles.変数名」という書き方で変数を定義し,情報を代入する.
 handles.stateをnoにしておく
 必要な情報を変数で代入したら.guidata関数で保存を行う.

⓶Callback関数では,ボタンが押されたらウェブカメラの映像を表示する.
 handles.stateをaccessにする
 while文の条件分岐でhandles.state=accessにして,映像表示用のコードを実行する.
 Opening関数内のhandles.webcam1を呼び出し,snapshot,imshowを使って1フレーム分の画像表示を行う.
 guidata関数で上記内容を保存する
 ⇒結果.1フレームごとに画像が更新されるため,映像として表示される

※なお,MATLABのプログラムコードのみ記載しても,GUIの図figファイルがないため,エラーになります.
 動画の通り,guide起動から図を作成して,プログラムを追記すると正常に動作します.
 加えて,figファイルとプログラムが書かれたmファイルは,同じフォルダ内に格納すれば正常に動作します.

下記に映像表示テスト用のプログラム全文を記します.
guideでGUIを作成後,プログラムコード追記の際に参考にしてみてください.

□MATLAB-ラズベリーパイ+webカメラ映像表示用プログラム

function varargout = PSR_WEBCAM_test_1(varargin) % PSR_WEBCAM_TEST_1 MATLAB code for PSR_WEBCAM_test_1.fig % PSR_WEBCAM_TEST_1, by itself, creates a new PSR_WEBCAM_TEST_1 or raises the existing % singleton*. % % H = PSR_WEBCAM_TEST_1 returns the handle to a new PSR_WEBCAM_TEST_1 or the handle to % the existing singleton*. % % PSR_WEBCAM_TEST_1('CALLBACK',hObject,eventData,handles,...) calls the local % function named CALLBACK in PSR_WEBCAM_TEST_1.M with the given input arguments. % % PSR_WEBCAM_TEST_1('Property','Value',...) creates a new PSR_WEBCAM_TEST_1 or raises the % existing singleton*. Starting from the left, property value pairs are % applied to the GUI before PSR_WEBCAM_test_1_OpeningFcn gets called. An % unrecognized property name or invalid value makes property application % stop. All inputs are passed to PSR_WEBCAM_test_1_OpeningFcn via varargin. % % *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one % instance to run (singleton)". % % See also: GUIDE, GUIDATA, GUIHANDLES % Edit the above text to modify the response to help PSR_WEBCAM_test_1 % Last Modified by GUIDE v2.5 17-Sep-2020 05:44:57 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; gui_State = struct('gui_Name', mfilename, ... 'gui_Singleton', gui_Singleton, ... 'gui_OpeningFcn', @PSR_WEBCAM_test_1_OpeningFcn, ... 'gui_OutputFcn', @PSR_WEBCAM_test_1_OutputFcn, ... 'gui_LayoutFcn', [] , ... 'gui_Callback', []); if nargin && ischar(varargin{1}) gui_State.gui_Callback = str2func(varargin{1}); end if nargout [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); else gui_mainfcn(gui_State, varargin{:}); end % End initialization code - DO NOT EDIT % --- Executes just before PSR_WEBCAM_test_1 is made visible. function PSR_WEBCAM_test_1_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to webcamtest_PSR_demo_webcam (see VARARGIN) handles.mypi=raspi; handles.wcam1 = webcam(handles.mypi,'UVC Camera (046d:081b) (usb-3f980000.usb-1.5):'); handles.state='No'; % Choose default command line output for webcamtest_PSR_demo_webcam handles.output = hObject; % Update handles structure guidata(hObject, handles); % UIWAIT makes PSR_WEBCAM_test_1 wait for user response (see UIRESUME) % uiwait(handles.figure1); % --- Outputs from this function are returned to the command line. function varargout = PSR_WEBCAM_test_1_OutputFcn(hObject, eventdata, handles) % varargout cell array for returning output args (see VARARGOUT); % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Get default command line output from handles structure varargout{1} = handles.output; % --- Executes on button press in pushbutton1. function pushbutton1_Callback(hObject, eventdata, handles) % hObject handle to pushbutton1 (see GCBO) handles.state='access'; while(strcmp(handles.state,'access')) img1 = snapshot(handles.wcam1); imshow(img1, 'Parent', handles.axes1); % hObject handle to pushbutton3 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) guidata(hObject, handles); end % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA)

長々と解説を書きましたが,以下にまとめの図を記載しました.

キャプションを入力できます

2⃣ウェブカメラ映像表示+ジョイスティック操作

プログラム作成手順は,1⃣と変わりません.
1⃣からの変更点として,
・ウェブカメラを2つに増やした
・ジョイスティックを使用して,走行ロボットNUEMK-Ⅰを操作できるようにした.
※下記に⓵モータドライバーTA7291Pのバージョンと②Plolu5019バージョンの回路図とプログラムコードを
 示しますが,MATLAB側のプログラムは⓵,②いずれも同じコードを使用しているので,最後に記載します.

⓵ジョイスティックーモータ操作と2つのウェブカメラ映像表示
テスト目的で,ジョイスティックーモータ操作と2つのウェブカメラ映像表示を行うシステムを構築しました.
まず電子回路ですが,ロボット側はラズベリーパイ - Arduino - モータドライバーで接続されています.
ラズベリーパイには,アナログ出力ピンがないため,ArduinoとI2C接続を行い,モータドライバーへ
アナログ信号を出力しています.

※Arduinoの電源が入っていなかったり,ArduinoとラズベリーパイがI2Cで接続されていない場合は,
 MATLABにエラーが表示されます.
 後程記しますが,MATLABのプログラムでI2Cを探し,認識させるコードを書いているため,
 探しても見つからない場合は,エラーが発生するというものです.
↓はテスト用の回路図です.モータードライバーはTA7291P
キャプションを入力できます

オペレータ(MATLAB)側ですが,PCにジョイスティックをつなぎ,8つの領域にジョイスティックが
操作されると,モータの回転方向が決まり,操作量が大きくなると,モータの回転速度が増すようにしています.

キャプションを入力できます

続いて,プログラムコードを説明します.
まずは,走行ロボット NUEMK-Ⅰに搭載されているArduinoのプログラムです.
制御フローで示すとこんな感じです.
キャプションを入力できます

TA7291Pモータドライバーを使用したときのプログラムを下記に記します.
制御フローの条件分岐はswitch文で行っています.

また,モータへの出力用コードは
digitalWrite(ピン番号,HIGH);
digitalWrite(ピン番号,LOW);
analogWrite(ピン番号,ジョイスティック操作量);
となっています.

Wire.hはArduinoがI2C通信が可能にするヘッダーファイルです.
これでラズベリーパイからのI2Cピンを受信し,
下記コードを書いて,情報を読み取ります.
a = Wire.read();
b = Wire.read();
c = Wire.read();

□TA7291P仕様Arduinoプログラム

#include <Wire.h> int a,b,c,y,z; void setup() { Wire.begin(8);// Slave ID #8 Serial.begin(9600); Wire.onReceive(test); pinMode(3,OUTPUT); pinMode(4,OUTPUT); pinMode(5,OUTPUT); pinMode(8,OUTPUT); pinMode(9,OUTPUT); pinMode(10,OUTPUT); } void loop() { //z = -1; //Serial.println(z); } void test(int numBytes){ y=Wire.available(); Serial.print("0"); Serial.print(numBytes); Serial.println("0"); if(numBytes > 0){ a = Wire.read(); b = Wire.read(); c = Wire.read(); //Serial.print("0"); //Serial.print(a); //Serial.print("0"); //Serial.print(b); //Serial.print("0"); //Serial.print(c); //Serial.println("0"); switch(a){ case 1: digitalWrite(3,HIGH); digitalWrite(4,LOW); analogWrite(5,b); digitalWrite(8,HIGH); digitalWrite(9,LOW); analogWrite(10,c); break; case 2: digitalWrite(3,LOW); digitalWrite(4,HIGH); analogWrite(5,b); digitalWrite(8,HIGH); digitalWrite(9,LOW); analogWrite(10,c); break; case 3: digitalWrite(3,LOW); digitalWrite(4,HIGH); analogWrite(5,b); digitalWrite(8,LOW); digitalWrite(9,HIGH); analogWrite(10,c); break; case 4: digitalWrite(3,LOW); digitalWrite(4,HIGH); analogWrite(5,b); digitalWrite(8,LOW); digitalWrite(9,HIGH); analogWrite(10,c); break; case 5: digitalWrite(3,LOW); digitalWrite(4,HIGH); analogWrite(5,b); digitalWrite(8,LOW); digitalWrite(9,HIGH); analogWrite(10,c); break; case 6: digitalWrite(3,LOW); digitalWrite(4,HIGH); analogWrite(5,b); digitalWrite(8,HIGH); digitalWrite(9,LOW); analogWrite(10,c); break; case 7: digitalWrite(3,HIGH); digitalWrite(4,LOW); analogWrite(5,b); digitalWrite(8,LOW); digitalWrite(9,HIGH); analogWrite(10,c); break; case 8: digitalWrite(3,HIGH); digitalWrite(4,LOW); analogWrite(5,b); digitalWrite(8,HIGH); digitalWrite(9,LOW); analogWrite(10,c); break; } //delay(10); } }

②簡易走行ロボット NUE MK-1のシステム例
タミヤギアドモータを使った走行ロボット,NUEMK-Ⅰに搭載した際の製作例を示します.
まずは回路図です.
変更点ですが
モータドライバーはTA7291PからPololu5019に変更しています.
サーボモータを2台動作できるようにしています.
ラズパイ用バッテリーを設けています(スマホ用モバイルバッテリー)
車体駆動用バッテリーは乾電池から,リチウムイオンバッテリーをしよしています.
(NUEには報道用カメラバッテリー DUO190を2台使用)

キャプションを入力できます

キャプションを入力できます

続いて,Arduinoのプログラムを示します.
⓵からの変更点ですが,
・ヘッダーファイル<DualVNH5019MotorShield.h>を追加
・モータへの出力コードを変更
 md.setM1Speed();
 md.setM2Speed();

例えば,MATLABからのデータを変数b,cに格納した場合,
前進なら
md.setM1Speed(b);
md.setM2Speed(c);
後退なら
md.setM1Speed(-b);
md.setM2Speed(-c);
と記載しています.

□Plolu5019モータードライバー仕様

#include <Wire.h> #include <DualVNH5019MotorShield.h> DualVNH5019MotorShield md; int a,b,c,y,z; int val; void stopIfFault() { if (md.getM1Fault()) { Serial.println("M1 fault"); while(1); } if (md.getM2Fault()) { Serial.println("M2 fault"); while(1); } } void setup() { Wire.begin(8);// Slave ID #8 Serial.begin(9600); Wire.onReceive(test); /* pinMode(3,OUTPUT); pinMode(4,OUTPUT); pinMode(5,OUTPUT); pinMode(8,OUTPUT); pinMode(9,OUTPUT); pinMode(10,OUTPUT);*/ Serial.println("Dual VNH5019 Motor Shield"); md.init(); } void loop() { //z = -1; //Serial.println(z); } void test(int numBytes){ y=Wire.available(); Serial.print("0"); Serial.print(numBytes); Serial.println("0"); if(numBytes > 0){ a = Wire.read(); b = Wire.read()/127; c = Wire.read()/127; /*Serial.print("0"); Serial.print(a); Serial.print("0"); Serial.print(b); Serial.print("0"); Serial.print(c); Serial.println("0"); */ switch(a){ case 1: md.setM1Speed(b); md.setM2Speed(c); //Serial.print(a); break; case 2: md.setM1Speed(b); md.setM2Speed(c); //Serial.print(a); break; case 3: md.setM1Speed(-b); md.setM2Speed(-c); //Serial.print(a); break; case 4: md.setM1Speed(-b); md.setM2Speed(-c); //Serial.print(a); break; case 5: md.setM1Speed(-b); md.setM2Speed(-c); // Serial.print(a); break; case 6: md.setM1Speed(-b); md.setM2Speed(-c); //Serial.print(a); break; case 7: md.setM1Speed(b); md.setM2Speed(c); break; case 8: md.setM1Speed(b); md.setM2Speed(c); //Serial.print(a); break; } //delay(10); } }

NUE用サーボモータ回転プログラム
ジョイスティックのボタンが押され,ラズベリーパイのデジタルピンから,信号を受信して,
サーボモータを駆動するために作成したプログラムです.

□サーボモータ回転プログラム

#include <Servo.h> Servo myservo; int a,b,c,y,z,val,h,i; void setup() { Serial.begin(9600); pinMode(3,INPUT); pinMode(4,INPUT); pinMode(5,INPUT); pinMode(6,INPUT); pinMode(2,INPUT); //pinMode(11,OUTPUT); pinMode(12,OUTPUT); //pinMode(13,OUTPUT); pinMode(7,OUTPUT); } void loop() { if(digitalRead(6) == HIGH){ /* シリアルポートに'A'を出力 */ val=1; } else if(digitalRead(2) == HIGH){ val=2; } else if(digitalRead(3) == HIGH){ val=3; } else if(digitalRead(4) == HIGH){ val=4; } else { val = 0; } switch(val) // Perform an action depending on the command { case 1://Move Forward h=h+1; myservo.attach(12); myservo.write(h); //Serial.println(1); delay(10); break; case 2://Move Backwards h=h-1; myservo.attach(12); myservo.write(h); //Serial.println(2); delay(10); break; case 3://Turn Left i=i+1; myservo.attach(7); myservo.write(i); //Serial.println(3); delay(10); break; case 4://Turn Right i=i-1; myservo.attach(7); myservo.write(i); //Serial.println(4); delay(10); break; default: Serial.println(0); break; } }

NUE操作用MATLABプログラム
最後に,MATLABのプログラムコードを解説します.
基本的にOpening関数,Callback関数内にコードを追加してゆくのですが,
1⃣の内容から,さらにコンテンツを加えています.

Opening関数での追加内容
・ウェブカメラ

handles.wcam2←ウェブカメラ2台目用の変数
・I2C
scanI2CBus(handles.mypi,'i2c-1')←ラズベリーパイのI2C番号を取得
enableI2C(handles.mypi,10)←バススピードを指定して,I2C出力を可能にする
handles.i2csensor = i2cdev(handles.mypi,'i2c-1','0x08')
↑MATLABとラズベリーパイのI2Cを可能にする

handles.joy = vrjoystick(1)
↑PCに接続されているジョイスティックを認識させる

Callback関数内での追加内容
・ウェブカメラ2台目用の映像表示
 img2 = snapshot(handles.wcam2);
 imshow(img2, 'Parent', handles.axes2);

.ジョイスティック用ボタン
a = button(handles.joy,1)
  ↑ボタンを認識

writeDigitalPin(handles.mypi,4,a)

↑ボタンが押されたら,ラズベリーパイのデジタルピンから信号を出力
  ※一応ボタンはすべて出力できるようにしています.

・ジョイスティックレバー操作
 モータ回転方向と回転速度にかかわる部分です
 長いので一部分だけを使って基本的な構成を紹介します.
基本的な構成
if(joystickの縦・横の値が正or負?)
 if(joystick縦値>joystick横値)
  t=[領域の番号,右モータ値,左モータ値]
   try
   write(handles.i2csensor(i2c-1の事), t(上記値) ,’int8’)
   catch
   warning(‘Problem using I2C interface’)
end
else

以下,ジョイスティックの1~8までの領域に対して,同様のコードが書かれています.

□Matlab_Plollu5019使用ロボットプログラム

function varargout = webcamtest3(varargin) % webcamtest3 MATLAB code for webcamtest3.fig % webcamtest3, by itself, creates a new webcamtest3 or raises the existing % singleton*. % % H = webcamtest3 returns the handle to a new webcamtest3 or the handle to % the existing singleton*. % % webcamtest3('CALLBACK',hObject,eventData,handles,...) calls the local % function named CALLBACK in webcamtest3.M with the given input arguments. % % webcamtest3('Property','Value',...) creates a new webcamtest3 or raises the % existing singleton*. Starting from the left, property value pairs are % applied to the GUI before webcamtest3_OpeningFcn gets called. An % unrecognized property name or invalid value makes property application % stop. All inputs are passed to webcamtest3_OpeningFcn via varargin. % % *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one % instance to run (singleton)". % % See also: GUIDE, GUIDATA, GUIHANDLES % Edit the above text to modify the response to help webcamtest3 % Last Modified by GUIDE v2.5 12-Dec-2017 23:04:10 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; gui_State = struct('gui_Name', mfilename, ... 'gui_Singleton', gui_Singleton, ... 'gui_OpeningFcn', @webcamtest3_OpeningFcn, ... 'gui_OutputFcn', @webcamtest3_OutputFcn, ... 'gui_LayoutFcn', [] , ... 'gui_Callback', []); if nargin && ischar(varargin{1}) gui_State.gui_Callback = str2func(varargin{1}); end if nargout [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); else gui_mainfcn(gui_State, varargin{:}); end % End initialization code - DO NOT EDIT % --- Executes just before webcamtest3 is made visible. function webcamtest3_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to webcamtest3 (see VARARGIN) handles.mypi=raspi; handles.wcam1 = webcam(handles.mypi,'UVC Camera (046d:0825) (usb-3f980000.usb-1.4):'); handles.wcam2 = webcam(handles.mypi,'UVC Camera (046d:081b) (usb-3f980000.usb-1.5):'); scanI2CBus(handles.mypi,'i2c-1'); enableI2C(handles.mypi,10); handles.i2csensor = i2cdev(handles.mypi,'i2c-1','0x08'); handles.joy = vrjoystick(1); handles.state='No'; % Choose default command line output for webcamtest3 handles.output = hObject; %wcam1 = webcam(handls.mypi,'USB 2.0 Camera (usb-3f980000.usb-1.4):') %wcam2 = webcam(handls.mypi,'UVC Camera (046d:081b) (usb-3f980000.usb-1.5):') %img1 = snapshot(wcam1); %img2 = snapshot(wcam2); %imshow(img1, 'Parent', handles.axes1); %imshow(img2, 'Parent', handles.axes2); % Update handles structure guidata(hObject, handles); % UIWAIT makes webcamtest3 wait for user response (see UIRESUME) % uiwait(handles.figure1); % --- Outputs from this function are returned to the command line. function varargout = webcamtest3_OutputFcn(hObject, eventdata, handles) % varargout cell array for returning output args (see VARARGOUT); % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Get default command line output from handles structure varargout{1} = handles.output; % --- Executes on button press in pushbutton2. function pushbutton1_Callback(hObject,eventdata, handles) % hObject handle to pushbutton2 (see GCBO) handles.output = hObject; handles.state='access'; while(strcmp(handles.state,'access')) img1 = snapshot(handles.wcam1); img2 = snapshot(handles.wcam2); imshow(img1, 'Parent', handles.axes1); imshow(img2, 'Parent', handles.axes2); %if (handles.joy == vrjoystick(1)) a = button(handles.joy,1); b = button(handles.joy,2); c = button(handles.joy,3); d = button(handles.joy,4); e = button(handles.joy,5); f = button(handles.joy,6); g = button(handles.joy,7); h = button(handles.joy,8); i = button(handles.joy,9); j = button(handles.joy,10); k = button(handles.joy,11); l = button(handles.joy,12); %m = button(handles.joy,13); writeDigitalPin(handles.mypi,4,a); writeDigitalPin(handles.mypi,17,b); writeDigitalPin(handles.mypi,27,c); writeDigitalPin(handles.mypi,22,d); writeDigitalPin(handles.mypi,14,e); writeDigitalPin(handles.mypi,13,f); % writeDigitalPin(handles.mypi,14,g); writeDigitalPin(handles.mypi,5,g); writeDigitalPin(handles.mypi,6,h); writeDigitalPin(handles.mypi,19,i); writeDigitalPin(handles.mypi,26,j); writeDigitalPin(handles.mypi,15,k); writeDigitalPin(handles.mypi,16,l); %writeDigitalPin(handles.mypi,20,m); %A = [a,b,c,d]; %disp(A); w = axis(handles.joy, 1)*127; x = -axis(handles.joy, 2)*127; y = round(w); z = round(x); if(w>=0) && (x>=0) if(abs(w)>abs(x)) t = [2,round(abs(y-z/2)),round(abs(y-z))];%[1,e,f-150,c-127,d]%オフセット量をfとcに施している try write(handles.i2csensor,t,'int8'); catch warning('Problem using I2C interface.'); end else t = [1,round(abs(z-y/2)),round(abs(z-y))];%[2,e,f,c,d] try write(handles.i2csensor,t,'int8'); catch warning('Problem using I2C interface.'); end end elseif(w>=0) && (x<0) if(abs(w)>abs(x)) t = [3,round(abs(y+z/2)),round(abs(z+y))];%[3,e,f,c,d] try write(handles.i2csensor,t,'int8'); catch warning('Problem using I2C interface.'); end else t = [4,round(abs(z+y/2)),round(abs(y+z))];%[4,e,f,c,d] try write(handles.i2csensor,t,'int8'); catch warning('Problem using I2C interface.'); end end elseif(w<0) && (x<0) if(abs(w)>abs(x)) t = [6,round(abs(z-y)),round(abs(z/2-y))];%[6,e,f,c,d] try write(handles.i2csensor,t,'int8'); catch warning('Problem using I2C interface.'); end else t = [5,round(abs(y-z)),round(abs(y/2-z))];%[5,e,f,c,d] try write(handles.i2csensor,t,'int8'); catch warning('Problem using I2C interface.'); end end elseif(w<0) && (x>=0) if(abs(w)>abs(x)) t = [7,round(abs(z+y)),round(abs(z/2+y))];%[7,e,f,c,d] try write(handles.i2csensor,t,'int8'); catch warning('Problem using I2C interface.'); end else t = [8,round(abs(y+z)),round(abs(y/2+z))];%[8,e,f,c,d] try write(handles.i2csensor,t,'int8'); catch warning('Problem using I2C interface.'); end end else end if (i==1)&&(j==1) break end %end % Update handles structure guidata(hObject, handles); end % --- Executes on button press in pushbutton3. function pushbutton3_Callback(hObject, eventdata, handles) handles.state='access'; while(strcmp(handles.state,'access')) img1 = snapshot(handles.wcam1); img2 = snapshot(handles.wcam2); imshow(img1, 'Parent', handles.axes1); imshow(img2, 'Parent', handles.axes2); % hObject handle to pushbutton3 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) guidata(hObject, handles); end

部品表

最後に,本製作例で使用した電子部品を紹介します

1⃣ウェブカメラ映像表示+ジョイスティック操作 タミヤギアボックス編

部品名 購入先
Arduino uno 秋月電子通商orマルツパーツor千石電商
TA7291P amazon(ただし販売終了なので中古)代替品でTB6643KQ
ラズベリーパイ3B 秋月電子通商orマルツパーツ
ラズベリーパイI/Oピン用フラットケーブル マルツパーツ
ウェブカメラ アマゾン
タミヤダブルギヤボックス 秋月電子通商orマルツパーツor千石電商
電線 秋月電子通商orマルツパーツor千石電商or近くのホームセンター
Arduino変換基盤 秋月電子通商orマルツパーツor千石電商
ピンヘッダとピンソケット 秋月電子通商orマルツパーツor千石電商

2⃣ウェブカメラ映像表示+ウェブカメラ映像表示+ジョイスティック操作 
 タミヤギアドモータ仕様走行ロボット編

部品名 購入先
Arduino uno 秋月電子通商orマルツパーツor千石電商
Pololuモータドライバー5019 amazon or スイッチサイエンス or朱雀技研
ラズベリーパイ3B 秋月電子通商orマルツパーツ
ラズベリーパイI/Oピン用フラットケーブル マルツパーツ
ウェブカメラ アマゾン
タミヤギアドモータ540とギアヘッド300 秋月電子通商orマルツパーツor千石電商
電線 秋月電子通商orマルツパーツor千石電商or近くのホームセンター
Arduino変換基盤 秋月電子通商orマルツパーツor千石電商
ジョイスティックレバー アマゾン
ピンヘッダとピンソケット 秋月電子通商orマルツパーツor千石電商
ログインしてコメントを投稿する