[Pepper] Pepperアプリケーション開発 ~ソケット通信してみよう~

前回は、Pepperの胸部分にあるタブレットを使用するアプリケーションについて紹介しました。
今回は、以前の記事「Pepperアプリケーション開発 ~通信してみよう~」を少し改良して、PepperとPC間で通信を行います。

具体的には、以下の様な動作を作ります。
1)Pepperに名前を伝えます
2)その人物が来社したことを、私のPCに通知してもらいます(今回の記事)
3)その名前に応じたURLに接続してもらい、テキストデータを取得してもらいます
4)テキストデータの内容に応じて、Pepperに「在席中です」「外出中です」「帰宅しました」と答えてもらいます

以前の記事「Pepperアプリケーション開発 ~通信してみよう~」では、Pepperはhttp通信を用いて、その人物が現在どこにいるのかを判断して答えて貰いました。
このPepperを、さらに活用できるように、誰かが来たことをPCに通知してもらう機能を追加します。

■前準備 WindowsPCで動作するTCPサーバ準備
Pepperにメッセージを送ってもらうために、WindowsPCで動作するTCPサーバを作成します。
今回はVB.netを使って、以下のような簡単な画面を作りました。



図1 TCPサーバ(WindowsPCで動作します)

VB.net で画面を作成する方法については割愛します。

作成した画面上に一つだけある、「通信開始」ボタンを押下すると、バックグラウンドで、ポート番号「1234」で受信待ち状態に入ります。メッセージを受信した場合は、作成した画面上に一つだけあるテキストボックスに、通信内容を出力します。

実際に書いたプログラムは、以下の通りです。

Public Class Main
    'TCPリスナ
    Private objTcpListener As System.Net.Sockets.TcpListener

    'スレッド
    Private objThread As System.Threading.Thread

    'Delegate定義                                                       '
    'スレッドからForm部品を操作するために使用する                       '
    Delegate Sub analyzeMessageFrm(ByVal strMessage As String)

    '画面ロード時処理
    Private Sub Main_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        'TCPリスナの初期化
        'ポート番号を未使用の1234とする
        objTcpListener = New System.Net.Sockets.TcpListener(System.Net.IPAddress.Any, "1234")
    End Sub

    '通信開始処理
    Private Sub BtnConnect_Click(sender As Object, e As EventArgs) Handles BtnConnect.Click
        '受信スレッド開始
        objThread = New System.Threading.Thread(New System.Threading.ThreadStart(AddressOf receiveMessage))
        objThread.IsBackground = True
        objThread.Start()
    End Sub

    'メッセージ受信処理
    Private Sub receiveMessage()
        Dim objClient As System.Net.Sockets.TcpClient           '受信用オブジェクト
        Dim objStream As System.Net.Sockets.NetworkStream       '受信用ストリーム
        Dim objStreamReader As System.IO.StreamReader           '受信用reader
        Dim strMessage As String                                '受信メッセージ

        Do While True
            Try
                'TCP受信開始
                objTcpListener.Start()

                'データを受信する(受信完了まで待機)
                objClient = objTcpListener.AcceptTcpClient()

                'stream型で受信
                objStream = objClient.GetStream()
                objStreamReader = New System.IO.StreamReader(objStream, System.Text.Encoding.UTF8)

                '受信する 受信メッセージは必ず1行
                strMessage = objStreamReader.ReadLine()

                '受信したらクローズする
                objStreamReader.Close()
                objStream.Close()
                objClient.Close()
                objTcpListener.Stop()

                'メッセージ解析処理に処理を移譲する
                analyzeMessage(strMessage)

            Catch ex As Exception
                objTcpListener.Stop()
            End Try
        Loop
    End Sub

    'メッセージを解析する
    Private Sub analyzeMessage(ByVal strMessage As String)
        If ReceiveText.InvokeRequired Then
            'バックグラウンドから呼ばれた場合はメインスレッドに切り替え
            Dim uSocket As New analyzeMessageFrm(AddressOf analyzeMessage)
            Invoke(uSocket, New Object() {strMessage})
        Else
            '受信したメッセージをテキストにはりつける
            Me.ReceiveText.Text = strMessage
        End If
    End Sub
End Class

■PepperからTCP通信を行う
以前の記事「Pepperアプリケーション開発 ~外部ライブラリの読み込み~」で、自分の好きなプログラムをかける部品の作り方を紹介しています。
今回も同じ要領で、通信を行う部品「SendMessage」を追加しています。
※他の部品は、以前の記事「Pepperアプリケーション開発 ~通信してみよう~」と同じです



図2 受付するPepper

「SendMessage」は、Pepperが聞いた名前を入力として受け取ると、私のPCに向けて「<名前>宛にお客様が来ております」と伝えてくれます。
そして、その後の処理を継続するために、聞いた名前をそのまま出力しています。

実際に書いたプログラムは、以下の通りです。

class MyClass(GeneratedClass):
    def __init__(self):
        GeneratedClass.__init__(self)

    def onLoad(self):
        #put initialization code here
        pass

    def onUnload(self):
        #put clean-up code here
        pass

    def onInput_onStart(self):
        #self.onStopped() #activate the output of the box
        pass

    def onInput_onStop(self):
        self.onUnload() #it is recommended to reuse the clean-up as the box is stopped
        self.onStopped() #activate the output of the box

    def onInput_inputName(self, p):
        host = "<私のPCのIPアドレス>"
        port = 1234
        bufsize = 4096

        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.connect((host, port))
        sock.send(p + "宛にお客様が来ております")
        sock.close()
        self.outputName(p)
        self.onStopped()
        pass

Pepperが名前を聞いた後、onInput_inputName メソッドが実行されます。
その中で、TCP通信を確立して、その情報を私のPCに送信しています。
WindowsPCで動作しているのがVB.netのプログラムで、Pepperで動作しているのがPythonですが、TCPのソケット通信では文字列の受け渡ししかしておりませんので、問題なく動作します。
※今回は日本語を利用しておりますので、もし文字化けするようでしたら、文字コードを適切に設定してください

■実行
このシーケンスを実行すると、名前の受付に入ります
ここでは、試しに「tanaka」と入力しました(図3)



図3 Pepperが名前を受け付ける

すると、私のPCに対して通信処理が行われて「tanaka宛にお客様が来ております」という文字が、WindowsPC上に表示されました(図4)



図4 WindowsPCに通知する

■まとめ
以上で、PepperとPC間で通信を行う紹介は終了です。
今回実施した内容を発展させると、TCP通信は双方向でのデータのやり取りができますので、たとえばPCでメッセージを受け取った後、私のWindowsPCから逆に、Pepperにメッセージを送って、その情報に従ってPepperに受け答えしてもらう、ということも出来るかなと思います。
最後までご覧頂き、ありがとうございました。

次回も引き続き、Pepperアプリケーションに触れて行く予定です。


弊社では全国各地の請負い(ご自宅)で作業協力頂ける、フリーランスエンジニアの方を常時探しております。
ご興味ある方は、お気軽にお問い合わせ下さい。


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*