9
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

gRPC 使って TOPPERS/箱庭 単体ロボットシミュレータにBluetooth デバイスを追加する(サーバー編)

Last updated at Posted at 2021-02-07

モチベーション

TOPPERS/箱庭 単体ロボットシミュレータに仮想的な Bluetooth デバイスを追加することにしました.そのための実装方法として,より汎用的な技術である gRPC を利用することにしましたので,サーバー側の gRPC を利用したプログラムの作成方法について解説します.

なお,gRPC を利用しようと思った動機は,以下の2点です.

  • 様々な言語でサーバー側とクライアント側を開発できる
  • RPC 実装を作る必要がない(データ型定義するだけで自動生成されちゃう!)

サーバー側のプログラムは,Bluetooth 用のシリアルI/Oライブラリで,EV3RTの Bluetooth APIとの連携を可能にします.ただし,本記事では,EV3RT側の解説は含まれておりません.
※別途,gRPC クライアント側の解説記事を書く予定ですので,その際に併せて説明します~.

本記事を通して学べる gRPC の知識は?

  • gRPC 概要
  • gRPC のデータ定義方法
  • gRPC を使ったサーバー側の設計(RAWデータ管理)
  • gRPC の開発環境(C#)の作成方法
  • gRPC の実装例(C#)

gRPC 概要

以下の記事がとても参考になります.

深く学びたい方は,本家サイトを参照ください.

gRPC のデータ定義方法

まず,論より証拠,今回作成した gRPC の定義は以下になります.

service SerialService {
  rpc PutData (SerialPutData) returns (SerialPutResult) {}
  rpc GetData (SerialGetData) returns (SerialGetResult) {}
}

service キーワードから gRPC の定義が始まります.今回のケースでは,RPCのサービス名がSerialServiceです.

そして,このサービスには,以下の2つのAPI(関数)があります(rpcキーワードで始まる部分です).

  • PutData
  • GetData

それぞれの処理について簡単に説明します.

PutData

本APIは,引数に SerialPutData というデータ型をとり,結果を SerialputResultというデータ型で返します.クライアントがサーバーに Bluetooth 用のシリアルデータを送信する際に利用します.
※クライアントは送信したいデータを SerialPutData に詰めます.

GetData

本APIは,引数に SerialGetData というデータ型をとり,結果を SerialGetResultというデータ型で返します.クライアントがサーバーから Bluetooth 用のシリアルデータを受信する際に利用します.
※クライアントは受信するデータを SerialGetResult で受け取ります.

ここから,各データ型の定義方法について解説します.
まず,gRPC で利用するデータ型は,プロトコルバッファーで定義します.

今回作成したデータ型の定義は以下の通りです.

message SerialPutData {
  int32  channel = 1;
  bytes data = 2;
}

message SerialPutResult {
  int32  channel = 1;
  string ercd = 2;
}

message SerialGetData {
  int32  channel = 1;
}
message SerialGetResult {
  int32  channel = 1;
  string ercd = 2;
  bytes data = 3;
}

message で始まるキーワード部分がプロトコルバッファー定義部分です.
message の中のメンバは,データ型毎にそれぞれ自由に定義できます.

  • channel は,シリアルI/Oをマルチチャネルに対応するためのメンバです(今回は1チャネルのみしかやりませんが).
  • ercdには,サーバー側のエラーメッセージが格納されます.
  • dataには,バイナリデータが格納されます.Bluetoothのシリアルデータが対応します.

たったこれだけの定義をするだけで,クライアント側とサーバー側の RPC 実装コードが様々な言語で生成されちゃうわけですから,実装方法の自由度が大きく広がりますし,実装コストも激減ですよね!!

gRPC を使ったサーバー側の設計(RAWデータ管理)

サーバー側の Bluetooth I/O 設計内容(UML)をお示しします.

なお,本設計では,UMLツールとして,astah* professionalを利用しています.直感的な操作ができるところがとても良いです(ハマります).設計検討中は常にモヤモヤしているので,ストレスなく思いを描けるツールの存在はとても大事です.さらに,設計中は様々な視点での検討が必要となるので,UML図だけでなく,DFDやロバストネス図なども使える点がさらに良いです.

##クラス設計
image.png

##シーケンス設計

起動シーケンス

image.png

PutData シーケンス

image.png

GetData シーケンス

image.png

gRPC の開発環境(C#)の作成方法

さて,ここから実際にプログラミングの話になります.
今回のBluetoothサーバー実装言語は,C#にしました.

理由は,以下の記事にあるロガー機能がC#で実装されており,将来的に,このロガーを実機とシミュレータとで切り替えできるようにしたいという野望があるためです.

C#での gRPC の開発環境ですが,こちらの記事が大変参考になります.

gRPC の実装例(C#)

各クラスの実装は,以下で公開しております.

program.cs がユーザプログラムになります.

static void Main(string[] args)
{
    string ipaddr = "172.25.0.1";
    int portno = 50051;
    int buffer_size = 1024 * 1024; /* 1MB */
    Console.WriteLine("ipaddr=" + ipaddr + " portno=" + portno.ToString());

    VirtualBluetoothSerial serial = new VirtualBluetoothSerial();
    serial.SetServerInfo(ipaddr, portno, buffer_size);
    serial.Open();
    string data = null;
    Console.WriteLine("START BT TEST>>>>");
    for (int i = 1; i <= 10; i++)
    {
        data = "Hello World[ " + i.ToString() + " / 10 ]";
        Console.WriteLine("SEND DATA:  " + data);
        serial.WriteLine(data);
        string rcv_data = serial.ReadLine().Trim();
        Console.WriteLine("RECV DATA:  " + rcv_data);

        if (data.Equals(rcv_data))
        {
            Console.WriteLine("TEST PASSED [ " + i.ToString() + " ]");
        }
        else
        {
            Console.WriteLine("TEST FAILED [ " + i.ToString() + " ]");
        }
    }
    Console.WriteLine("<<<<END BT TEST");
    serial.Close();
}

本プログラムは,シリアルデータをサーバー側からクライアントに送信して,そのデータをクライアントからそのまま送り返してもらって,送信データと受信データが一致しているかどうかをチェックしています(10回繰り返します).

デモ

このプログラムの実行するとこんな感じで動きます.
クライアント側は,EV3RTのBluetooth APIを使ってデータの送受信をするようにしています(別途こちらは解説します).

demo.gif

9
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?