日本ソフトウェア科学会第 37 回大会 (2020 年度) 講演論文集

WSAN 向けマクロプログラミング言語の提案
後藤 司

森口 草介

渡部 卓雄

無線センサーアクターネットワーク (WSAN) は，物理環境に配備された複数個の計算機が相互に通信することで，物理環境の観測や環境への働きかけを行う分散システムである．その実現には，センサーノードに加えて環境への働
きかけなどを行うアクターノードを含む複雑なノード間協調が必要である．ノード間協調が不十分な場合，センサーやアクターへのメッセージの到達順序が入れ替わり，実行順序が意図しないものになるハザードと呼ばれる問題が発生することがある．アクターノードを含まない無線センサーネットワーク (WSN) については，マクロプログラミン
グと呼ばれる，WSN 全体を 1 つの計算システムとみなしてその動作を記述する手法がある．マクロプログラミング
では処理に用いるノード間協調を全体の動作から導出する．本研究では，ハザード回避を行う協調動作を導出する機構を取り入れた WSAN 向けのマクロプログラミング言語を提案する．

Wireless Sensor and Actor Networks (WSANs) are distributed systems composed of multiple computersthat observe and act on physical environments. Since WSANs contain actor nodes that control actuators or
perform other local operations, complex inter-node coordination operations involving them are necessary.
The lack of such coordination may result in the incorrect arrival order of messages between actor and sensor
nodes. The problems are called hazards. For wireless sensor networks (WSNs), which do not have actor
nodes, there is a method called macro-programming, which describes the behavior of the entire WSN as asingle computing system. In macro-programming, inter-node cooperation for processing is derived from theoverall behavior. In this study, we propose a macro-programming language for WSAN that incorporates amechanism to derive cooperative actions to avoid hazards.

Network, WSAN) である [1]．アクターノードは

1 はじめに

環境に何らかの影響を及ぼすアクチュエーター（ヒー

無 線 セ ン サ ー ネット ワ ー ク (Wireless Sensor

ター，ファン，モーター等）の制御や，近傍にあるセNetwork, WSN) は，センサーと無線通信機構を

ンサーノードからのデータの集約，近傍にあるセン備えた複数個の計算機を用いて多地点の計測情報を

サーノードの制御等を行う．

収集・活用するための分散システムであり，農業，工WSAN では，センサによる計測とアクチュエータ

業，建築，土木，交通，医療などの分野で用いられの制御を適切に行うためのノード間協調が必要になている．WSN を構成する計算機（ノード）は，センる．ノード間協調における問題の 1 つとして，シンサーによる計測とパケットのルーティングを行う複

クから各ノードへの命令の実行順序が入れ替わってし数個のセンサーノードと情報の集約を行う単一のシ

まうハザード [6] と呼ばれる現象がある．以下，火災

ンクノードに分類される．WSN にアクターノードとを検知してスプリンクラーを制御する WSAN アプリ

呼ばれる計算機を追加したものが無線センサーアク

ケーションを例として説明する．このアプリケーショ

ターネットワーク (Wireless Sensor and Actor

ンでは，温度センサーの値を取得するクエリと，温度

A Macroprogramming Language for Wireless SensorActor Networks
Tsukasa Gotoh, Sosuke Moriguchi, Takuo Watanabe,
東京工業大学 情報理工学院, School of Computing,Tokyo Institute of Technology.

センサーの値が閾値より高い場合に火事と判断してスプリンクラーを起動するコマンドの 2 種類の命令
をシンクが送信する．火事が消える瞬間にシンクが送信したクエリとコマンドの到達順序が入れ替わってしまうと，シンクはまだ火災が発生していると判断して章で結論と今後の課題について述べる．

余計にスプリンクラーを起動して必要以上に水を散布してしまう．このような協調に対する問題があるこ

2 無線センサーアクターネットワークとから WSAN の開発は WSN より複雑になる．

2. 1 WSAN の概要

ハザードを回避する手法として，火災などのイベ

無線センサーネットワーク (Wireless Sensor Net-

ントが発生している領域内にあるセンサーノード，ア

work, WSN) はセンサーや無線通信機能を備えた計

クターノード同士で命令実行順序を同期するための算機を複数個物理環境に配備することで，環境の観測

Vector Neighborhood Clock (VNC) による手データを収集するための分散システムである．WSN

法 [6] が提案されている．VNC ではクエリやコマン

において計算機はノードと呼ばれ，センサーで物理環

ドの実行を制御するために近くのノード間で通信を境を計測するためのノードをセンサーノード，情報の行う．この通信は本来のクエリやコマンドと並行して収集を行うノードをシンクノードと呼ぶ．通常 WSN行われるため，それぞれのノード用プログラムではク

は多数のセンサーノードと 1 つのシンクノードから

エリ・コマンド用のコードと VNC のためのコードが構成され，センサーノードにより計測されたデータ

混在してしまう．そのため，プログラム間の整合性を

を無線通信によりセンサーノードを経由してシンク保つことが難しく，また機能に対する再利用性が悪化

ノードへ送信する．シンクノードに集約されたデータ

する．

は記憶領域に保存されたり，ネットワーク経由で参照

WSN のためのソフトウェアを効果的に開発する技

されたりする．

術としてマクロプログラミング [5] と呼ばれる手法が無線センサーアクターネットワーク (Wireless Sen-ある．これは，個々のノード単位ではなくグローバル

sor and Actor Network, WSAN) は，WSN にアクな単位でネットワークをプログラミングするようなターノードと呼ばれるノードを追加したものである．

プログラミングパラダイムであり， コンパイラはグアクターノードはセンサーノードによって集めた物

ローバルな単位のプログラムをノード単位のプログ

理環境の情報を元に適切に物理装置を動作させるこ

ラムに変換する．

とで，物理環境に働きかけることを目的としている．

本研究では，WSAN 開発のためのマクロプログラ

センサーノードは消費電力が小さく，センサーの観測

ミング言語 Brigade を提案する．Brigade では各ノー範囲や計算資源，通信機能が制限されていることに対ドの状態を時変値とし，ノードの種類ごとにまとめして，アクターノードの持つ物理装置はセンサーノー

た時変値のストリームを処理してプログラミングをドの観測範囲よりも広い影響範囲を持ち，計算能力と行う． 1 つの Brigade プログラムからセンサーノー

通信能力も高くなる．このため，センサーノードより

ド，アクターノード，シンクノードの 3 種類の異なるもアクターノードのほうが高価になり，配備される数

ノードに対するプログラムが生成される．このストは少なくなる．

リームによる抽象化によって WSAN アプリケーショ
ンのプログラムを簡潔に記述することができる．さら2. 2 ハザードに各プログラムの生成を行う過程で VNC による協調

ハザード [6] はセンサー，アクター，シンク間の協動作が組み込まれ，ノード間協調の問題の 1 つであ

調動作の不足によって，物理環境に望ましくない変更

るハザードをプログラマが意識することなく回避すを与えてしまうような命令の実行順序の入れ替わりることが可能となる．

の事である．シンクが正しい順序で命令を送信して本論文ではまず第 2 章で WSAN について説明し，いても，到達パスの長さや，レイテンシの違いによっ

第 3 章で VNC について述べる．第 4 章で Brigadeて実行順序が入れ替わる．以下ではシンクがアクター

言語について説明し，第 5 章では Brigade の実装手に送信する命令をコマンド，センサーに送信する命令法を説明する．第 6 章で関連研究の紹介を行い，第 7をクエリと呼ぶ．

火災が発生している領域のように，何らかの事象が発生している領域のことをイベント領域と呼ぶ．イベは Q1 と Q2 が正しい順序でイベント領域まで到達し，レスポンス R1 , R2 が入れ替わる際に発生する．

ント領域の情報をセンサーで読み取ったり，イベント領域に対してアクターを用いて働きかけるといった操

2. 3 マクロプログラミング

作が複数回必要となる WSAN アプリケーションを考マクロプログラミングは，WSN をグローバルな単

える．

位でプログラミングをするようなプログラミングパラ

図 1 は WSAN におけるノードの配置とイベント

ダイムである．マクロプログラミング言語で記述され領域を表した図である．大きな円はイベント領域を，たグローバル単位のプログラムは，コンパイラによっ

小さな円，三角形，四角形はそれぞれセンサー，アクてノード単位のプログラムに変換される [5]．ノード

ター，シンクを表す．C1 , C2 はアクターへのコマン

単位のプログラミングをする上で意識する必要のあドであり，Q1 , Q2 はセンサーへのクエリである．R1 ,る，ハードウェアに近い低レベルな部分や通信のプロ

R2 はクエリ Q1 , Q2 に対するレスポンスとなっていグラムを自動で生成することによって，開発効率を高る．C1 と Q1 は C2 と Q2 よりも先に送信され，長いめる事ができる．

パスを通ることで C2 と Q2 よりもイベント領域までの到達に時間がかかるものとしている．

Regiment [5] は関数型リアクティブプログラミングに基づく WSN 向けのマクロプログラミング言語で[6] では 2 つの命令の種類とその前後関係に応じてある．ネットワークを空間的に分散した時変値の集合

ハザードを CAC, QAC, CAQ, QAQ の 4 種類に分とみなす．時変値は各センサーノードの状態や，物理類している．例えば QAC は Query-after-Command的な近傍の情報を集約した情報などである．これらの頭字語であり，C1 , Q2 の順序でコマンド C1 とク

時変値やその集合を操作できるプリミティブ関数を

エリ Q2 を送信したときに，C1 の実行終了時刻より用いてプログラミングを行い，専用の中間言語であも先に Q2 の実行が開始されるハザードである．シンる Token Machine Language (TML) [4] へとコンパ

クが消火コマンド C1 を発行し消火を行った後に火災イルを行う．

を検知するクエリ Q2 を発行する際に，消火が終了す

このような WSN マクロプログラミング言語をる前に火災検知が行われてしまうと，火災が鎮火し

WSAN に適用する際の問題点として，アクターノー

たとしてもシンクは火災が発生していると判断してドを追加することで現れるノード間協調動作への対

余計に消火コマンドを発行してしまう．他にも，C1 ,処となる．本研究では特にハザードに注目し，ハザー

C2 が入れ替わるのが CAC ハザード，Q1 と C2 が入ド回避を自動で行う機構を持つ WSAN 向けマクロプ

れ替わるのが CAQ ハザードである．QAQ ハザード

ログラミング言語を提供する．

3 Vector Neighborhood Clock3. 1 Neighborhood Clockハ ザ ー ド を 回 避 す る 手 法 と し て Neighborhood

Clock (NC) が提案されている．NC は特定の範囲

R1：イベント領域

R2内に限定された仮想クロックによる同期手法である．
あるノード x の近くのノードを包含し，そのノー

：センサー

C2
Q2
Q1

：アクター
C1

：シンク

ドと x 間で命令が順序どおりに実行される必要のあ
る領域を依存領域という．観測範囲が重なっているセンサーや影響範囲が重なっているアクター，観測範囲

図1

WSAN

と影響範囲が重なっているセンサーとアクターは互いの依存領域内に存在している．ここではセンサー

命令は同期させるため依存関係リストは 1 つとなる．

の依存領域の半径はセンサーの観測半径とアクター

そのため本研究で扱う VNC は k 次元となる．各次元の影響範囲の半径の和で，アクターの依存領域の半に対して NC の手法を用いることでイベント毎の同径はアクターの影響範囲の半径の 2 倍で定義される．

期が可能となる．また同じイベントが離れた位置で依存領域に対する 2 つの命令 Ii , Ij に対し，依存領発生していても区別せず，同じイベント ID を割り当域内のあるノードが Ij を実行する前に依存領域内のてる．

全てのノードが Ii を実行する必要があるとき，Ij はIi に依存していると言い，Ii → Ij と書く．

例として 2 種類のイベント A, B と，イベント

A の命令 A1 , A2 及びイベント B の命令 B1 , B2 ,シンクが送信する命令 Ii , Ii+1 に対して Ii → Ii+1

B3 を考え，それぞれ A1 → A2 , B1 → B2 → B3

であるとする．全てのセンサーとアクターは NC とと い う 依 存 関 係 を 持 つ と す る ．シ ン ク は RC 値

いうスカラー値を持つ．シンクは命令の依存の進行を {N CA : 0, N CB : 0} で初期化してイベント領具合を示す参照クロック RC を生成し，その初期値域に送信し，各センサーとアクターの VNC 値はNC0 をイベント領域全体に送信する．イベント領域{N CA : 0, N CB : 0} になる．シンクが A1 を送信す

内のセンサーとアクターは自身の NC 値を NC0 でるとき，シンクの保持する RC の値 NCA をインクリ初期化する．シンクが送信する命令 Ii に RCi 値を乗メントして 1 にし，それをイベント A 領域のノード

せ，命令を送信するたびに RC 値をインクリメントに送信する．イベント A 領域内のノードは，依存領する．センサー及びアクターは命令 Ii の実行が完了

域内のノードの NCA 値が 0 であるため，A1 を実行

したら依存領域内の全ノードに自身の NC 値を送信できる．実行が完了したら自身の NCA 値を依存領域する．センサーに対するコマンドのように，対象が自内の全ノードに送信する．B1 を送信するときも同様

身でない命令に関しては届いたらすぐ実行完了通知に，NCB をインクリメントして 1 にして送信し，イを送信する．各ノードは依存領域内のノードの NC

ベント B 領域内のノードが B1 を実行する．A2 が送値を保持しており，全てのノードの NC 値が NCi に信されるとき，依存領域内のノードが NCA 値をインなった時に初めて Ii+1 を実行できるようになる．

クリメントして 2 にして送信する．イベント A 領域

これにより Ii の実行が完了する前に Ii+1 が実行さ内のノードは，依存領域内のノードの NCA 値が全てれなくなり，CAC，QAC，CAQ ハザードが回避で2 であれば A2 を実行し，そうでなければ他ノードかきる．また QAQ ハザードはクエリのレスポンスの到ら N CA 値が送信されるのを待ってから実行する．同達時刻が入れ替わった際に発生するハザードである

様にして表 1 のように実行が行われる．

が，レスポンスに RC 値を乗せることでシンクがレ

表1

スポンスの順序を判別することができるため，QAQ

VNC 実行例

命令

RC

A1

{N CA : 1, N CB : 0}

B1

{N CA : 1, N CB : 1}

複数種類のイベントが発生していた場合は，イベ

A2{N CA : 2, N CB : 1}

ント毎に命令の依存関係を定義し，関係のないイベ

B2{N CA : 2, N CB : 2}

ントの命令の実行は待たないようにしたい．Vector

B3{N CA : 2, N CB : 3}

ハザードも回避できる．

3. 2 Vector Neighborhood Clock

Neighborhood Clock (VNC) はイベントごとの命令の依存関係に基づき NC を持つようにしたものである．イベントが k 種類定義され，イベント毎の依存関係リストが最大 j 個ある場合，VNC は k × j 次元となる．ただし，Brigade 言語では各イベント毎の全

4 Brigade 言語
4. 1 言語の概要
Brigade は本研究で提案する WSAN 向けの関数型
マクロプログラミング言語である．各ノードの状態を時間によって変化する値（時変値）として抽象化し，

map(fn(c) -> c * 9 / 5 + 32, celsiusStream)
filter関数はストリームの各値に述語を適用し，条件を満たした値のみで構成されるストリームを返す．
以下のプログラムは温度のストリームの各値のうち，60 度以上の値のみを含むストリームに変換している．

時変値の集合をストリームとする．例えば，センサー

filter(fn(t) -> t >= 60, temperatureStream)が観測した値やその値を変換した情報などの集合がセンサーやアクターの ID は Sensor型と Actor型のストリームとなる．時変値は概念的には時刻から値へ

値によって表される．sensorsは Stream(Sensor)型のの関数であるが，Brigade ではサンプリングされた現ストリームであり，一定時間間隔ごとに全センサー

時刻における値に対して処理を行う．ストリームに関の ID をストリームに流す．Brigade プログラム中数を適用することで値の変換を行い，あるノードのの全てのストリームの起点は sensorsであり，このストリームを他ノードが参照することでノード間の

sensorsに対して関数を適用することによってプログ

ストリームデータの送信が行われる．センサーからラムを構成する．

シンク，シンクからアクターへとストリームを参照す

各センサーが計測した物理環境の情報の取得やアクることで WSAN アプリケーションを構成する．1 つターが保持する物理装置の動作の制御は，sense関数，の Brigade プログラムをコンパイルすることでセン及び actuate関数によって行われる．sense関数はセンサー，アクター，シンクそれぞれのプログラムが生成

サーの ID とセンサーの種類を指定し，対応するセンされる．

サーノードによって計測された値を返す．actuate関

また Brigade によって生成されたプログラムは数はアクターの ID と物理装置の種類，及び物理装置

VNC によるハザード回避を自動で行う．シンクが参を制御するための値によって，対応するアクターの物

照するセンサーのストリームの領域をイベント領域

理装置を動作させる．sense関数と actuate関数の実として認識し，VNC による同期の対象とする．同領

装は Brigade 外部で行われ，Brigade ではそれを呼び域が対象となるストリームは全て VNC によって同期出す形式になっている．

される．ストリーム毎に同期が取られるため，プログ

actuate関数の呼び出しは iter関数内で行われる．

ラマは送信された命令がイベント領域単位では同時

iter関数はストリームの各値に対して引数に与えられに実行されないことを意識してプログラムを書く必

た関数を適用する．mapや filterと異なり，iterは副要がある．

作用を期待するもので，ストリームを返さない．以下は各アクターのファンに対して値を渡し，ファンを制

4. 2 ストリーム
ストリームは時変値の集合である．Brigade ではス
トリームは Stream(t)型の値として扱われる．tには御している．
iter(fn((actorId, switch)) -> actuate(
actorId, "fan", switch), switchStream)

センサー ID を表す Sensor型や整数型などが入り，特定の関数によってストリーム内の各時刻における t型の値を処理し，新たなストリームを生成することで変4. 3 ブロック換が行われる．

センサー，アクター及びシンクのプログラムはそ

map関数はストリーム内の各 t型の値に関数を適用

れぞれ Sensor, Actor及び Sinkブロック内に記述されし，その結果で新しいストリームを構成して返す．以る．例えば Sensorブロック内に記述されたストリー

下のプログラムは摂氏温度のストリームを華氏温度

ムの処理は，コンパイル後はセンサーのプログラム内のストリームに変換している．

に含まれる．ブロックは次のように記述される．
Sensor -> { ... }サーの観測範囲全体をイベント領域とみなし，そのストリームを変換して構成されたストリームも同イベントとして扱う．

ブロック内で定義された変数のスコープはブロック内に限られるが，ストリーム変数はブロック間での受け渡しが行われる．ブロック間におけるストリーム変数の受け渡しが行われると，対応するノード間で通信が行われる．変数の受け渡しは Sensor・Sinkブロッ
ク間，及び Actor・Sinkブロック間で行うことができ，
Sensor・Actor間での受け渡しは行うことができない．

Brigade 内部では sensorsストリームは Sinkブロック上で定義されたストリームであり，Sensorブロックでsensorsを利用するときは Sinkブロック上の変数を参照することになる．
sensorsストリームは全センサー ID のストリームであり，各要素は対応するセンサーに紐付けられているため，そのままストリームを Actorブロックに渡すこ

例えば Sensorブロック上の温度の高いセンサー IDのストリームを Sinkブロック上で参照し，スプリンク
ラーを起動するアクターの ID を同ストリームを変換して構成し，Actorブロック上でそのストリームを参照するとする．最初に Sensorブロックが Sinkブロック上で定義された sensorsストリームを参照しているため，シンクからセンサーへセンサー ID が送信される．この送信を命令とみなして I1 とし，シンクからアクターへのアクター ID の送信を I2 とすると，この 2 つの命令は I1 → I2 という依存関係を持つ．さらにアクターにアクター ID を送信した後に再度セン
サー ID を送信するときには I2 → I1 という依存関係を持つことになる．ただし再度センサーに ID を送信するときに VNC による同期が取られるイベント領域とはできない．getActors関数は，Stream(Sensor)かは，全センサーではなく前回センサーからシンクへ送ら Actorブロックが受け取れる Stream(Actor)型への信されたときと同じ領域になり，再度センサーからシ関数である．この関数は Sinkブロック内でのみ使うことができ，シンクが保持しているセンサーとアクターの位置情報を用いて，ストリーム内のセンサーの依存領域内にある全てのアクターノードの ID をストリームにして返す．
まとめると各関数や値の型は以下の通りとなる．

ンクへ温度の高いセンサー ID が送信されたときにイベント領域が更新される．

VNC による同期に対してプログラマが追加で記述する必要のあるプログラムは無く，上記の機構によりイベント領域毎のハザード回避は全て自動で行われるようになる．
Sensorブロック上の sensorsストリームから分岐し

map:(a → b)→Stream(a)→Stream(b)filter:(a → bool)→Stream(a)→Stream(a)iter:(a →())→Stream(a)→ ()sensors:Stream(Sensor)

た複数のストリームを Sinkブロックが参照している
場合は，それぞれがイベント領域とみなされ，VNCの要素に対応付けられる．

getActors:Stream(Sensor)→Stream(Actor)
sense:Sensor → string → Int

4. 5 例題

actuate:Actor → string → Int →()プログラム 1 は Brigade で記述された火災消火プ
ログラムである．60 ℃以上の温度を検知したセンサーの ID をシンクが受け取り，同領域の対応するアク
ターのスプリンクラーを起動する．

4. 4 VNC によるノード間協調
Brigade ではシンクから送信されるデータを命令とみなし，VNC による協調の対象とする．プログラム
実行時にセンサーからシンクへストリームのデータが送信されたら，シンクはそのデータを送信したセンプログラムは関数定義と Sensor, Sink, Actorブロッ
クにそれぞれ分かれており，各ブロック内での計算がそれぞれ対応するノード上で行われる．onFire関
数は火事かどうかを判定する関数で，センサー ID の示すセンサーの観測した温度が 60 ℃以上であるかをどうかを bool値で返す．actuateSprinkler関数はスンサーが ID を受け取っても onFire関数は実行されプリンクラーを起動するための関数であり，対応すない．

るアクター ID の持つスプリンクラーを起動している．actuate関数はここでは 1 を渡されたら一定時間

5 実装手法

スプリンクラーを起動し，一定時間が経過したら停Brigade コンパイラのコンパイルの手順は図 2 に止するように実装されているものとする．Sensorブて表される．字句解析，構文解析，型検査が行われロックではまず sensorsストリームのセンサー ID をた後にストリームグラフマップを構成し，ブロック間

onFire関数で火事と判定されたセンサー ID を抽出

参照表を構成して通信を行うストリームを認識する．

したストリームに変換する．それを fireRegionに代

参照情報を元に，ストリームをセンサー，アクター，

入することで Sinkブロック内で参照できるようにし，シンク用のプログラムへと変換していく．

getActors関数を用いて同じ領域内のアクターのスト

リーム actorsを構成する．Actorブロックは actorsを参照し，actors内の全てのアクター内でスプリンク
ラーを起動する．

5. 1 ストリームグラフマップとブロック間参照表
ストリームのブロック間の参照関係を確認したり，センサーやアクターのプログラムの生成を容易にす

VNC に よ る 協 調 が な い 場 合 ，こ の 例 で はるため，各ブロック内のプログラムからストリームの

actuateSprinklerの実行が完了する前に onFireが呼ば処理の流れを表す有向グラフのマップと，ストリーム

れてしまい，QAC ハザードが発生する．この WSAN

変数のブロック間の参照の表を構成する．

では Sinkブロック上の変数 actorsと sensorsを，そストリームグラフでは Stream型の変数や，mapやれぞれ Actorブロックと Sensorブロックが参照しておfilterなどの Streamを引数に取る関数がノードとなり，それぞれのデータのシンクからの送信が依存する

り，関数を適用される側のノードからする側のノード

ため，VNC によってアクターが ID を受け取ってかの向きにエッジがつけられる．Stream型の値が変数へ

ら実行を行う actuateSprinklerが完了するまで，セ代入されていたら，変数名を key としてストリーム
グラフをマップに保存する．このマップを後のブロッfn onFire(sensorId) -> {sense(sensorId, "temperature") >= 60
字句解析，構文解析，型検査}
fn actuateSprinkler(actorId) -> {actuate(actorId, "sprinkler", 1)}

ストリームグラフマップ生成

Sensor -> {fireRegion = filter(onFire, sensors)}
Sink -> {ブロック間参照表生成

actors = getActors(fireRegion)}
Actor -> {iter(actuateSprinkler, actors)

センサー・アクタープログラム
への変換

シンクプログラムへの変換}
プログラム 1

Brigade による火災消火プログラム

図2

コンパイル手順

ク間参照表の構成や，センサーやアクターのプログラ
ムの生成に利用する．

ブロック間参照表を生成したら各ノード向けのプ
ログラムを生成する．センサーとアクターはそれぞStream型の変数をノードにする際，同ブロック内でれが単一の値を 1 台のシンクと送受信するのに対し定義されていた場合にはマップからストリームグラフて，シンクは複数台のノードと値を送受信するため，を取得して置き換える．同ブロック内で定義されていプログラムの生成方式が異なる．

ない場合は他ノードで定義されているものとして変数名がそのままグラフのノードとなる．他のブロック

5. 2 センサー・アクター向けプログラムへの変換のストリームグラフを繋げてしまうとブロックごとのセンサーとアクター向けプログラムは，ブロック間プログラムの変換が行えなくなるため，他のブロック

参照表を見て自身が出力として記録されている変数の変数を参照していてもストリームグラフの置き換が key となるストリームグラフをマップから取得し，えは行わない．

そのストリームグラフをイベント駆動型のプログラ

以下の Brigade プログラムを考える．
X = map(f1, filter(f2, Y))

ムに変換する．有向グラフの各ノードは関数へと変換され，エッジの向きに関数呼び出しを行う．図 3 を変換すると次のようになる．

この時，=の左辺の Xはマップの key となり，右辺の式はストリームグラフへ変換された後にマップの valueとなる．

def receiveFromSink(msg) docase msg.name do"Y" -> __map2(msg.element, msg.rc)
end

key

=

X

end

value

=

Y → filter (f2 ) → map(f1 )def __map2(value, rc) do

図3

ストリームグラフ変換

x = f1(value)__filter1(x, rc)
end

また actuate関数の呼び出しなどの副作用を期待している iter関数は変数への代入をしないため，このdef __filter1(value, rc) do
y = f2(value)
if y do

ままではストリームグラフマップへの保存が行われず
コード変換が行われない．iter関数の呼び出しだけはsendToSink_X(value, rc)
end

変数に代入されているものとして扱い，ストリームグ

end

ラフマップへと保存する．

def sendToSink_X(value, rc) do

上記の形式でセンサー，アクター，シンクの各ブ
ロックのストリームグラフマップを構成したら，ブロック間を跨ぐ Stream型変数の参照をノード間通信に変換するため，ブロック間の変数参照の表を作成して通信が行われる箇所を明らかにする．マップの keyに現れる変数を出力，value のストリームグラフの末端に現れる変数を入力として，対応するブロック名と共に表に記録する．出力と入力片方にしか現れない変数は通信が行われないため表から削除するが，iter関数が代入されている変数だけは出力にならないため，削除を行わない．

send({name: "X", element: value, rc: rc},
sinkId)sendToDependencyRegion()end
receiveFromSink関数でシンクから受け取ったメッセー

ジを名前で振り分ける．mapや filterなどは単純な関数へと変換され，最後に値に名前をつけてシンクに送信する．iterの場合は他ノードに値を送信すること無く関数呼び出しが終わる．

VNC による協調を行うため，各ノードはシンクから最初にメッセージを受信するタイミングで依存領
域内のノードを含む木構造のネットワークを構成す

る．Sinkからメッセージを受信した際は，メッセージ場合のみ receive関数が呼ばれる．

に付随する RC 値と依存領域内の VNC 値を比較して，同期が取れたら receiveFromSinkにメッセージを

6 関連研究送信する．Sinkに値を送信する際は，Sinkから送信さ無線センサーアクチュエータネットワーク向けのマれた rc をそのまま返し，更に依存領域内のノードにクロプログラミング言語には SOSNA [3] が挙げられ自身の保持する VNC 値を送信する．

る．ただしアクチュエータはアクターの別名である．

SOSNA はノードのグループのストリームを操作する
5. 3 シンク向けプログラムへの変換

ことでネットワークの動作を記述するような関数型

シンクプログラム上ではストリームを集合としてマクロプログラミング言語である．Brigade のように扱う．ブロック間参照表を見て他のブロックが参照

センサーの情報をシンクに送信してからアクターにしているストリーム変数をシンクが保持していたら，データを送信するのではなく，アクターが周囲のセン

そのストリーム変数に対応する集合を各ノードに向サーの値を直接集約したり，アクター同士で通信しけて送信する．逆に他のブロックの変数を参照してて協調を行う．ノード間通信を同期することによっていた場合，シンクが送信した命令に対するレスポン

WSAN プログラムの 1 周期の計算にかかる時間を見スとなる．receive関数が常に受け取ったレスポンス

積もることができる．SOSNA は同期的に計算を行うを対応する集合に追加しており，対応する命令を他ため，通信待機時間を長くすることでパケットの損失

ノードに送信した後に receive関数による集合の生成を抑え，ハザードを回避することができるが，結果とを一定時間待つ．1 周期が終わったらループし，再度して周期ごとの計算に時間がかかり，リアルタイム性

sensorsに値を送る．

が損なわれてしまう．

以下はプログラム 1 の Sinkブロックをコンパイルした例である．

また WSAN 向けマクロプログラミングミドルウェアとして PICO-MP [2] が挙げられる．ノードの種類
を Publisher と Subscriber に分け，Publisher は型付

def receive(Message res) docase res.name do"FIRE_REGION" ->put(fireRegion, res.element)
end
end

けされたイベントの通知を PICO-MP 基盤に定期的に送信する．Subscriber は一階述語論理の形式で表される述語によって自身が関心のあるイベントの種類を記述し，PICO-MP 基盤から送信されるイベント
通知が述語を満たすかどうか検査する．述語を満たす
イベントを受け取ったら Subscriber は Publisher に

def mainloop() do
send_1(sensors)
wait()

対してイベントの情報を要求する．ネットワークは木構造で構成され，イベント通知を仲介するノードは子

actors = getActors(fireRegion)

ノードの Subscriber の部分式を用いることでイベン

send_1(actors)

ト通知をフィルタリングし，通信量を削減している．

mainloop()

一方，データ通信の順序に関しては定められていない

endため，依存する命令の到達順序が入れ替わり，結果とsend_1で値を送信する際は，シンクが保持する RC

してハザードが発生する可能性がある．

の 1 番目の要素をインクリメントして，値を送信する際に同時に RC 値も送信する．イベント領域が複7 結論と今後の課題

数ある場合は send_2, send_3といったように対応する

本研究では，WSAN 向けマクロプログラミング言

番号が変わる．レスポンスにおいても，付随している

語 Brigade と，その実装手法を提案した．Brigade 言

RC 値が現在シンクが保持している RC 値と同じ値の語を用いることで WSAN プログラムを簡潔に記述できることを示した．またプログラム中のノード間通信を行う箇所に自動で VNC による協調機構を組み込む

謝辞 本研究は JSPS 科研費 18K11236 の助成を受けている．

ことで，WSAN のノード間協調の問題の 1 つであるハザードをプログラマが意識すること無く回避でき

参 考 文 献るようになった．

[1] Akyildiz, I. F. and Kasimoglu, I. H.: Wireless sensor and actor networks: research challenges, Ad Hoc
Networks, Vol. 2, No. 4(2004), pp. 351–367.
[2] Dulay, N., Micheletti, M., Mostarda, L., andPiermarteri, A.: PICO-MP: De-centralised MacroProgramming for Wireless Sensor and Actuator
Networks, 2018 IEEE 32nd International Conference on Advanced Information Networking and Applications (AINA), 2018, pp. 289–296.
[3] Karpiński, M. and Cahill, V.: Stream-Based
Macro-Programming of Wireless Sensor, Actuator
Network Applications with SOSNA, Proceedings of
the 5th Workshop on Data Management for Sensor
Networks, DMSN ’08, New York, NY, USA, Association for Computing Machinery, 2008, pp. 49–55.
[4] Newton, R., Arvind, and Welsh, M.: Building
up to macroprogramming: an intermediate language for sensor networks, IPSN 2005. Fourth International Symposium on Information Processingin Sensor Networks, 2005., 2005, pp. 37–44.
[5] Newton, R., Morrisett, G., and Welsh, M.: The
Regiment Macroprogramming System, 6th International Conference on Information Processing in
Sensor Networks (IPSN ’07), ACM, Apr. 2007,
pp. 489–498.
[6] Vedantham, R., Zhuang, Z., and Sivakumar,
R.: Hazard avoidance in wireless sensor and actor networks, Computer Communications, Vol. 29,
No. 13(2006), pp. 2578–2598.

Brigade ではストリームの値を filterすることによってシンクに送信するデータ量を減らすことができるが，距離の長さや再送によって伝送が遅延し，デー
タが到達する前にシンクが計算を進めてしまう可能性がある．計算に間に合わなかったデータは捨てられるため，シンクからの距離が遠いノードからのデータが頻繁に捨てられてしまう可能性がある．シンクが全ノードからの実行完了通知を受け取るようにする場
合，シンクに送信するデータ量を減らすことができな
いため，各センサーのデータを一度アクターに集約するなど，全体の通信量を減らすような仕組みを実装すべきである．
また Brigade は getActorsによるアクターへのデー
タを送信方法を提供しているが，センサーが計測した値をアクターに送信する手段がない．1 つのアクターが複数種類のセンサーの観測範囲にある場合，最も近いセンサーの値をアクターに割り当てたり，線形補間するなどしてアクターに送信する値を決定する必要がある．