開発ブログ

第9回 ソケット通信でWPFアプリからパペロを制御してみた[前編]

投稿日時:2018年11月14日 16:11

こんにちは。ピャペロンです!
今回はソケット通信でWPFアプリからパペロを制御してみたよ。

あらかじめパペロシミュレーターを動かす環境を整えておこう。第2回 Windowsからパペロシミュレーターを動かしてみた

使用するソフト
・Windows 10
・テキストエディタ(Visual Studio Code
・Google Chrome
・Visual Studio 2017
・Python 3.7.1 ※実機で動かす場合はPython 3.4で開発しないと動作しない可能性があります。

参考
[Tips][TextBox] テキストを取得/設定する | HIRO’s.NET Blog
WPF4.5入門 その22 「Buttonコントロール」 – かずきのBlog@hatena
18.1. socket — 低水準ネットワークインターフェイス — Python 3.6.5 ドキュメント
TcpClient Class (System.Net.Sockets) | Microsoft Docs
17.1. threading — スレッドベースの並列処理 — Python 3.6.5 ドキュメント


第7回 Windowsフォームアプリケーションからパペロを制御してみたではWindowsフォームアプリケーションでpythonのプログラムをボタンをクリックするたびに呼び出していたけど、今度はWPFというフレームワークで作るWPFアプリとPythonプログラムをソケット通信という手法でプロセス間通信をしてパペロを制御してみよう。
前編ではpythonでサーバー側のプログラムを作成するよ。
ソケット通信をマスターすればプログラミング言語が異なるプログラムや異なるコンピュータ間でデータの受け渡しが行えるようになるよ。このようなプロセス間通信をする方法は他にもあるから様々な方法を覚えていこう。

 

papero_server.py

from logging import basicConfig, DEBUG
basicConfig(level=DEBUG)
import sys
import pypapero
import socket # ソケットを扱うモジュール
import threading # スレッドを扱うモジュール

class Server: # サーバークラスを定義
    PORT = 50088 # 通信に使用するポート番号を指定
    HOST = '' # 全てのホストを紐付け
    command_msg = None

    def action_right(self): # 右を向きながら挨拶
        papero.send_move_head([""], ["A90T1000L", "A0T1000L"])
        papero.send_start_speech("こんにちは。パペロです。")
        server.command_msg = None

    def action_left(self): # 左を向きながら挨拶
        papero.send_move_head([""], ["A-90T1000L", "A0T1000L"])
        papero.send_start_speech("おはようございます。パペロです。")
        server.command_msg = None

    def get_msg(self): # メッセージをWPFアプリから取得
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as socket_server: # アドレスファミリーとソケットタイプを指定してソケットの生成
            socket_server.bind((self.HOST, self.PORT)) # ソケットをホストとポートに紐付け
            socket_server.listen(1) # 接続される準備
            conn, addr = socket_server.accept() # 接続の待機をして、接続されたらメッセージを送受信するためのソケットを生成
            with conn:
                print('Connected by', addr)
                while True:
                    bytes_msg = conn.recv(1024) # 受信したメッセージを取り出す
                    if not bytes_msg: break
                    msg = bytes_msg.decode("utf-8") # 受信したメッセージはBytes型なのでstring型に復元する
        return msg

    def set_msg(self):
        while True:
            self.command_msg = self.get_msg()

server = Server() # サーバークラスのインスタンスを生成
simulator_id, robot_name, ws_server_addr = pypapero.get_params_from_commandline(sys.argv)
simulator_id = server.get_msg() # メッセージを受信
papero = pypapero.Papero(simulator_id, robot_name, ws_server_addr)
msg_recv = threading.Thread(target=server.set_msg) # メッセージをWPFアプリから取得するスレッドを立てる
msg_recv.setDaemon(True) # メインスレッドが終了するとデーモンスレッドは終了する
msg_recv.start() # スレッドの開始
if papero.errOccurred == 0:
    while True:
        papero_res = papero.papero_robot_message_recv(1.0)
        if (papero_res is not None) and (papero_res[0]["Name"] == "detectButton"):
            if papero_res[0]["Status"]=="R":
                server.action_left()
            elif papero_res[0]["Status"]=="L":
                server.action_right()
        if server.command_msg == "action_right":
            server.action_right()
        elif server.command_msg == "action_left":
            server.action_left()
        elif server.command_msg == "exit":
            break
papero.papero_cleanup()

 

サーバー側のソケット通信プログラムは基本的に
ソケットの生成→ソケットをホストとポートに紐付け→接続される準備→接続待機→通信→ソケットを切断
というような流れになるよ。
get_msg関数でクライアントが接続してメッセージが送られてくるまでプログラムは待機状態になっていることも覚えておこう。
後編ではC#でクライアント側のWPFアプリケーションを作成してソケット通信でこのようにパペロを制御してみよう。

 

第10回 ソケット通信でWPFアプリからパペロを制御してみた[後編]


0

最新開発ブログ一覧  (一覧で確認
2020年8月19日 14:08
開発ブログ
第30回 パペロで赤外線アレイセンサを動かしてみよう!【中編:顔の表面温度を測ってみよう】
by 管理者
2020年7月22日 16:07
開発ブログ
第29回 パペロで赤外線アレイセンサを動かしてみよう!【前編:簡易サーモグラフィを作ろう】
by 管理者
2019年11月20日 17:11
開発ブログ
第28回 パペロでJulius4.5を実行してみた
by 管理者
2019年11月13日 09:11
開発ブログ
第27回 JuliusをPaPeRoi向けにクロスコンパイルしてみた
by 管理者
2019年9月19日 17:09
開発ブログ
第26回Linaro Toolchainでクロスコンパイルしてみた
by 管理者

コメントは受け付けていません。