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

前回は、ソケット通信を用いて、PepperからPCへ文字列を送信しました。
今回は、前回のプログラムを拡張し、PCからPepperへ文字列を送り返し、双方向通信を行います。

■VB.netプログラムの改良
PCからPepperへ送信するメッセージは自由に入力可能なものとします。
TextBoxと送信用のボタンを新たに追加し、ソースコードを次のように変更します。

Public Class Main
    'TCPリスナ
    Private objTcpListener As System.Net.Sockets.TcpListener
    Private objStm As System.Net.Sockets.NetworkStream
    Private objClient As System.Net.Sockets.TcpClient           '受信用オブジェクト
    Private okBtnFlg As Boolean
    Private ngBtnFlg As Boolean
    Private objStream As System.Net.Sockets.NetworkStream       '受信用ストリーム
    Private objStreamReader As System.IO.StreamReader           '受信用reader
    Private strMessage As String                                '受信メッセージ


    'スレッド
    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()
        'TCP受信開始
        objTcpListener.Start()

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

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

        Do While True
            Try
                If Not objStreamReader Is Nothing Then
                    '受信する 受信メッセージは必ず1行
                    strMessage = objStreamReader.Read()

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

                Else

                End If

            Catch ex As Exception
            End Try
        Loop

        objTcpListener.Stop()

    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

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim dat As Byte() = System.Text.Encoding.UTF8.GetBytes(Me.TextBox1.Text)
        objStream.Write(dat, 0, dat.GetLength(0))
        objStreamReader.Close()
        objStream.Close()

    End Sub

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        Dim dat As Byte() = System.Text.Encoding.UTF8.GetBytes("ただいま席を外すことが出来ません。")
        objStream.Write(dat, 0, dat.GetLength(0))
        objStreamReader.Close()
        objStream.Close()

    End Sub
End Class

■Pepperプログラムの改良

以前のプログラムでは、Pepperが聞き取ったメッセージをPC(サーバー)に送信後、すぐにコネクションを切断していましたが
今回はPCからのメッセージを受け取る必要があるため、その部分の処理を追加します。

def onInput_inputName(self, p):
    import socket

    host = "<私のPCのIPアドレス>"
    port = 1234
    bufsize = 4096

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((host, port))

    # 変更ここから 
    resMessage = ""

    while True:
        sock.sendall(p + "宛にお客様が来ております")
        self.log( 'Wait...' )

        resMessage = sock.recv(bufsize)
        break

    sock.close()
    # 変更ここまで 

    self.outputName( resMessage )
    self.onStopped()

socket部品のsendallメソッド実行後、受付待ち状態にする必要があるため
while文の中に送受信の処理を記載します。

メッセージの受け取り処理として追加した箇所は以下の1行です。
resMessage = sock.recv(bufsize)

socket部品は、受け取った文字列を”resMessage”に格納し、前回用意した”outputName”メソッドを使用して次のシーケンスへメッセージを渡します。

受け取ったメッセージをPepperに喋らせるには以前の記事でも紹介した「Say」ボックスを使用します。
ですが、「Say」ボックスはデフォルトの状態では、「Localize Text」ボックスで設定された固定文字列しか喋らせることが出来ません。
今回のプログラムでは、文字列が固定ではない(※自由入力)ため、Sayボックスを少し拡張する必要があります。

■Sayボックスの拡張

ボックスにinputの口を追加します。

追加した口は、それぞれ以下のように設定します。
 Type:文字列
 Nature:onStart 

「Say」ボックスをダブルクリックして編集モードに切り替え
配置されている「LocalizedText」を削除し、inputと「SayText」を直接繋げます。

これで「Say」ボックスの拡張は終了です。
あとは、これまで用意してきたボックスを全て繋ぎ、動作確認となります。

■実行

前回と同じように、PCに用意したTCPサーバープログラムを実行し、「通信開始」ボタンで待機状態にした上で
Pepperプログラムを起動し、適当な文字を入力して、PCへメッセージを送ります。
PC側でメッセージを受取った後は、window下部に用意したTextBoxへ好きな文字を入力し、「送信」ボタンを押してPepperへメッセージを送り返します。

送り返されたメッセージを、正しく喋っていることが確認できました。

おまけで用意した「NG」ボタンでは、このようなメッセージがPepperへ渡されます。

■まとめ

以上で、ソケットを使用した双方向通信の紹介は終了です。
今回は、単純に送り返したメッセージをPepperに喋らせるだけでしたが
場所を示すデータを送り返してPepper内部で解析し、解析結果を元に
Pepper自身が移動しながら、指定された場所まで連れて行ってくれる道案内のようなことや
指定場所までのルートをタブレットに表示させるといったことも可能だと思います。

最後までご覧頂き、ありがとうございます。

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


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


コメントを残す

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

*