今回は先日記事にしたRaspberry Piのマルチコア、マルチプロセスによる並列処理で実際にロボットを制御してみたいと思います。言語はPythonになります。
並列処理でやりたいこと
これまで当ブログで、Raspberry Piをコントローラーとして動作するスパイダーロボット、PiCrawlerのサーボモータの制御や画像処理をするアプリケーションを紹介してきました。
今までは機能ごとにアプリケーション単体で動かしていましたが、個々の機能がある程度仕上がってきたため、それらの機能を同時に動かしたいと思っています。
通常の組み込み処理では機能ごとの優先度を決め、高優先の処理が空いている時間に低優先の処理を実行するなどのタスク管理をして複数の機能を動作させます。
しかし、Raspberry PiはCPUコアが4つあり、別々のコアで物理的に並列に処理を実行できますので、そのマルチコアを活かして制御と画像処理を両立させてみたいと思います。
Raspberry Pi(ラズベリーパイ)とは
Raspberry Pi(ラズベリーパイ)はイギリスのラズベリーパイ財団が教育用に開発したボードコンピュータです。
最新のRaspberry Pi 4では、ARMアーキテクチャを採用したBroadcom製の高性能SoC BCM2711を搭載しており、1.5GHzで動作するARM Cortex-A72が4コアとマイコンボードの中では非常に高速な処理能力を持っています。また、ユーザーがアクセス可能な40ピンのGPIOも搭載しており、外部ハードウェアを制御することが可能です。
詳細なスペック等は以下の記事で解説していますので、あわせてご覧ください。
動作環境
ハードウェア:Raspberry Pi 3 ModelB
OS:Raspbian 10.11
OpenCV:4.1.0.25
カメラ:OV5647
使用するロボット
当ブログではおなじみのPiCrawlerです。詳細は以下のページで解説しています。
マルチコア、マルチプロセスによる実装方法
Raspberry Piのマルチコアを利用して実際に並列処理をする方法は、以前の記事で紹介しています。
作成したソースコード
今回作成したPythonのソースコードは以下の通りです。
ロボットをその場で回転させる制御プログラムと、カメラモジュールで撮影した映像を表示する画像処理プログラムを、別々のプロセスで同時に実行します。
from picrawler import Picrawler
from time import sleep
import sys
import tty
import termios
import multiprocessing as mp
import cv2
#カメラ初期化
#VideoCaptureオブジェクト取得
cap = cv2.VideoCapture(-1)
#ロボット初期化
crawler = Picrawler([10,11,12,4,5,6,1,2,3,7,8,9])
#ロボットの動作速度
speed =100
#UI文字列
manual = '''
Press keys on keyboard to control PiSloth!
W: Forward
A: Turn left
S: Backward
D: Turn right
'''
#ロボットサーボ制御
def robot_ctl(q):
print(manual)
while True:
key = "A"
print(key)
if 'w' == key or 'W' == key:
crawler.do_action('forward',1,speed)
elif 's' == key or 'S' == key:
crawler.do_action('backward',1,speed)
elif 'a' == key or 'A' == key:
crawler.do_action('turn left',1,speed)
elif 'd' == key or 'D' == key:
crawler.do_action('turn right',1,speed)
elif chr(27) == key:# 27 for ESC
break
sleep(0.05)
#終了メッセージ
print("End robot_ctl Process")
#カメラ制御
def cam_ctl(q):
while(True):
#フレームを取得
ret, frame = cap.read()
#画面サイズを指定
frame = cv2.resize(frame, (640, 480))
#取得したフレームをウインドウ上に表示する
cv2.imshow("frame", frame)
#キーボード入力処理
key = cv2.waitKey(1)
if key == 13: #enterキーの場合処理を抜ける
break
#カメラデバイスクローズ
cap.release()
#ウィンドウクローズ
cv2.destroyAllWindows()
#終了メッセージ
print("End cam_ctl Process")
if __name__ == "__main__":
#キューの生成
queue = mp.Queue()
#プロセス生成
ps_control = mp.Process(target=robot_ctl, args=(queue,))
ps_cam = mp.Process(target=cam_ctl, args=(queue,))
#プロセスのスタート
ps_control.start()
ps_cam.start()
27行目:
サーボモーターの制御メソッドです。
50行目:
カメラモジュールの制御メソッドです。
81~82行目:
サーボ、カメラそれぞれの制御メソッドのプロセスを生成します。
84~85行目:
プロセスを実行します。
動作確認
作成したプログラムをロボットのRaspberry Piで実行した動画です。
ロボットが回転しながら、カメラモジュールの画像を表示することができました。動画の前半がロボットの動作、後半がロボットのカメラで取り込んだ映像を映している様子です。
\ Pythonを自宅で好きな時に学べる! /
まとめ
マルチプロセスで動作するプログラムを作成することで、ロボットに複数の動作を同時にさせることができるようになりました。今後はこの処理をさらに拡張して、ディープラーニングでリアルタイムに物体認識をさせながら、認識したオブジェクトに向かって移動する、といった動作をさせられるようにする予定です。
また、Pythonのプログラミングについてさらに深く学びたい方にはUdemyの以下の講座がおすすめです。
また、以下の記事で効率的にPythonのプログラミングスキルを学べるプログラミングスクールの選び方について解説しています。最近ではほとんどのスクールがオンラインで授業を受けられるようになり、仕事をしながらでも自宅で自分のペースで学習できるようになりました。
スキルアップや副業にぜひ活用してみてください。
スクールではなく、自分でPythonを習得したい方には、いつでもどこでも学べる動画学習プラットフォームのUdemyがおすすめです。
講座単位で購入できるため、スクールに比べ非常に安価(セール時1200円程度~)に学ぶことができます。私も受講しているおすすめの講座を以下の記事でまとめていますので、ぜひ参考にしてみてください。
それでは、また次の記事でお会いしましょう。
\ Raspberry Piを使ったアプリ開発を学びたい人には自宅で学べるUdemyがおすすめ! /
講座単位で購入できます!
コメント