今日はいよいよEV3をインターネット経由で完全に動かします。
なお、EV3のロボットのモデルはこの記事と同様にTRACK3Rをこの例では使用します。このモデルに限らず、ラージ・モーターを左右に2個使用するものであれば同じコードが使えます。
また、TRACT3Rではミディアム・モーターを使って球を発射したりする機能もありますので、これを操作する機能も付け加えてみます。ミディアム・モーターは右側の人差し指で押せるボタン(右側前面上部)を利用します。
まずはPublisherであるラズパイ側のコードです。
#!/usr/bin/env python import pygame, sys, time from pygame.locals import * import paho.mqtt.client as mqtt # Initialize a joystick and pygame pygame.init() pygame.joystick.init() joystick = pygame.joystick.Joystick(0) joystick.init() screen = pygame.display.set_mode((400,300)) pygame.display.set_caption('Controll ev3') interval = 0.01 # This is the Publisher loopQuit = False #ループ処理 while loopQuit == False: axis_1 = joystick.get_axis(1) #.get_axis(1)の1がジョイスティックの軸の番号 axis_1 = axis_1 * 100 #ジョイスティックの出力を100倍 str_axis_1 = str(int(axis_1)) #float型をint型に、int型をstr型に。 axis_3 = joystick.get_axis(3) #.get_axis(3)の3がジョイスティックの軸の番号 axis_3 = axis_3 * 100 #ジョイスティックの出力を100倍 str_axis_3 = str(int(axis_3))#float型をint型に、int型をstr型に。 button_5 = str(joystick.get_button(5)*100) #ボタン5の値(0か1)を取得し100倍。 #各値をカンマ区切りの一文として結合。 str_js = str_axis_3 + "," + str_axis_1 + "," + button_5 #MQTTでPublish client = mqtt.Client() client.connect("localhost",1883,60) client.publish("topic/motor-BCA/dt", str_js); client.disconnect(); print (str_js) #Publishした値を画面にも表示。 #終了処理 for event in pygame.event.get(): if event.type == QUIT: loopQuit = True elif event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: #キーボードのkとescのコンビでも終了 loopQuit = True time.sleep(interval) pygame.quit() sys.exit()
カンマで区切って一行のメッセージに3種類の数値を書き込んで送っています。
次に、SubscliberであるEV3側のコードです。
#!/usr/bin/env python import paho.mqtt.client as mqtt from ev3dev.auto import * # This is the Subscriber mb = Motor(OUTPUT_B) #ポートBのラージ・モーターを制御対象とする。 mc = Motor(OUTPUT_C) #ポートCのラージ・モーターを制御対象とする。 ma = MediumMotor(OUTPUT_A) #ポートAのミディアム・モーターを制御対象とする。 #Publisherと接続できたら0を表示し、"topic/motor-BCA/dt"をSubscribeする関数。 def on_connect(client, userdata, flags, rc): print("Connected with result code "+str(rc)) client.subscribe("topic/motor-BCA/dt") #msgの値を表示後分割し、モーターの回転数としてそれぞれに渡す関数。 def on_message(client, userdata, msg): print(msg.payload) msg_array = msg.payload.split(",") mb.duty_cycle_sp = msg_array[0] mc.duty_cycle_sp = msg_array[1] ma.duty_cycle_sp = msg_array[2] #ラズパイに接続。 client = mqtt.Client() client.connect("PublisherであるラズパイのIPアドレス",1883,60) #関数を実行。 client.on_connect = on_connect client.on_message = on_message #各モーターを駆動 mb.run_direct() mb.duty_cycle_sp = 0 mc.run_direct() mc.duty_cycle_sp = 0 ma.run_direct() ma.duty_cycle_sp = 0 #以上をループ処理。 client.loop_forever()
カンマ区切りのメッセージをSplitで分割して配列に変換し、この配列からそれぞれの要素を抜き出してあてがっています。
以上のコードを動作させてみた動画をYouTubeにアップしましたのでご覧ください。
目標を達成することができました!これに以前の記事でも紹介したWebカメラを搭載すれば、本当に地球の裏側からでも遠隔操縦することができると思います。
今日のところはこの辺で。☕️