このページでは Rednet
API と GPS API について解説する。
参考資料:
執筆時のバージョン:
- ComputerCraft 1.55 for Minecraft 1.6.2
Rednet API
Rednet APIを使うと、離れた場所にあるコンピュータ同士で文字列データを送受信することができる。
assets\computercraft\lua\rom\apis\rednet で定義
通信手段
Rednetには以下のような通信手段があり、どれもRednet APIの関数で扱う事が出来る。
- Wireless Modemを使った無線通信
- Wired Modemを使った有線通信(CC1.51-)
- RedPowerのBundled Cablesを使った有線通信(現在では全く使われていない)
このページでの解説は、Wireless Modemを使った無線通信と、Wired Modemを使った有線通信を前提として進める。
なお、このAPIはMineFactoryReloadedのRedNet Cableとは一切関係なく、RedNet Cableは通信に利用することもできない。
+
|
※RedPowerのBundled Cablesを使った有線通信について |
※RedPowerのBundled Cablesを使った有線通信について
通信速度が遅く(16bits/2ticks)、GPSも使えず、配線コストもかかるなど何かと不便なので現在は使われない。
Redstone信号で利用するときと同じように、コンピュータの側面に直接Bundled Cablesを接続する。そして、ケーブルを接続した方向をrednet.openで通信可能にする。後はRednet APIの各関数を利用して通信する。
ComputerCraftで扱える文字コードはASCIIの7ビット文字である。この7ビット文字を詰めて16ビットずつ送信する。Bundled Cablesの各色ワイヤーが各ビットのデータを伝送する。16ビットのデータ(2と2/7文字分)1個分の送信には2tickかかる(文字列データに1tick、セパレータに1tick)。
|
無線通信の通信可能範囲
通信可能範囲は通信するComputerやTurtleを中心とした半径が最大通信距離の球の内側である。
最大通信距離は64~384m(デフォルト設定)で、ComputerやTurtleのある高度によって変化する。以下の式によって求められる。
if y >= 96 then
range = (y - 96) * (modem_highAltitudeRange - modem_range) / ( WorldHeight - 98 ) + modem_range
else
range = modem_range
end
デフォルト設定なら更に以下のようにも簡略化できる。
range = y >= 96 and (y - 96) * 320 / 158 + 64 or 64
CC1.42では、CC1.41の「最高高度でも
Configで設定した最大通信距離に達しない不具合」が修正された。
デフォルト設定の通信可能距離
高度 |
最大通信距離 |
1 |
64 |
... |
64 |
96 |
64 |
97 |
66.0253... |
... |
高度+1毎に+2.0253... |
254 |
384 |
雷雨時には modem_range の代わりに modem_rangeDuringStorm が、 modem_highAltitudeRange の代わりに modem_highAltitudeRangeDuringStorm が計算に使われることによって、最大通信距離が大幅に縮む。デフォルトの場合、 64m~384m が 16m~64m になる。
実際に到達判定に使われる最大通信距離は、送信側と受信側の最大通信距離のうち長い方である。
このため、例えば地上(低高度)にあるコンピュータと高高度にあるコンピュータは、高高度にあるコンピュータの通信範囲内なら互いに送受信が可能。通信の中継やGPSホストなどは、ワールドの限界高度付近に設置したWirless Turtleで行うとよい。
なお、送信側または受信側がロードされていないチャンク(プレイヤーのいるチャンクを中心とした21*21チャンクの範囲の外。いわゆる凍結チャンク)にある場合は、距離的に通信可能範囲内であっても通信を行うことができない。
チャンネル
【1.5-】
+
|
クリックで詳細を開く。なお、従来通り通信をRednet APIで行う限りにおいては、この仕様変更を気にする必要はない。 |
従来の仕様では、送信時に指定できる送信先は特定のIDを持つコンピュータか、全てのコンピュータのみであった。CC1.5よりWireless Modemの機能が刷新され、コンピュータIDに替わり、通信対象の指定にチャンネルが使われるようになった。通信は、送信時に指定されたチャンネルと同じチャンネルをopenしている全てのコンピュータで受信可能である。また、一つのコンピュータは同時に127個のチャンネルまでopenすることができる。
なお、通信をRednet APIで行う限りにおいては、この仕様変更を気にする必要はない。なぜならば、Rednet APIではチャンネル番号としてコンピュータIDが用いられており、rednet.broadcast関数にも特定のチャンネル番号が用いられている(後述)ためである。受信に関しても、rednet.receive関数およびrednet_messageイベントは従来通りこれら2つのチャンネルからのみ受信が可能である。
チャンネルは番号により識別され、チャンネルに使用できる番号は0~65535の整数である。ただし、65534はGPS用に、65535はrednet.broadcast用に使われている。
gps.CHANNEL_GPS = 65534
rednet.CHANNEL_BROADCAST = 65535
|
open
- rednet.open( side )
- side(文字列)方向を通信可能な状態にする
- 戻り値:nil
side は "left", "right", "top", "bottom", "front", "back" のいずれか(以下同様)。
【1.5-】コンピュータIDと同じ番号のチャンネル及び、rednet.CHANNEL_BROADCASTのチャンネルから受信可能な状態にする。
例:
rednet.open( "left" )
左側を通信可能な状態にする。
close
- rednet.close( side )
- side(文字列)方向を通信不可能な状態にする。
- 戻り値:nil
【1.5-】コンピュータIDと同じ番号のチャンネル及び、rednet.CHANNEL_BROADCASTのチャンネルからの受信を不可能な状態にする。
isOpen
【1.5-】
- rednet.close( side )
- side(文字列)方向が通信可能な状態か調べる。
- 戻り値:ブーリアン型。通信可能状態ならtrue、不可能状態ならfalse。
コンピュータIDと同じ番号のチャンネルとrednet.CHANNEL_BROADCASTのチャンネルの両方から受信可能な状態かを返す。
broadcast
- rednet.broadcast( message )
- すべての通信可能なComputer/Turtleへmessage(文字列)を送信する
- 戻り値:ブーリアン型。送信に成功したらtrue、失敗したらfalse。ただし受信の成否については保証しない
【1.5-】rednet.CHANNEL_BROADCASTのチャンネルにmessageを送信する。rednet.receiveはrednet.CHANNEL_BROADCASTチャンネルからも受信可能なため、結果的に従来のrednet.broadcastと同じ働きをする。
例:
rednet.broadcast("ComputerCraft")
すべての通信可能なComputer/Turtleへ文字列"ComputerCraft"を送信する。
announce
【-1.481】
- rednet.announce()
- すべての通信可能なコンピュータに空のメッセージを送信する。 rednet.broadcast("") と同等
- 戻り値:ブーリアン型。送信に成功したらtrue、失敗したらfalse。ただし受信の成否については保証しない
【1.5-】この関数は削除された。
send
- rednet.send( receiverID , message [ , waitUntilPortOpen] )
- receiverID(数値)のIDを持つComputer/Turtleへmessage(文字列)を送信する。waitUntilPortOpen(ブーリアン)にtrueを指定した場合は、サーバのポートが開くまで待つ(省略可)。
- 戻り値:ブーリアン型。送信に成功したらtrue、失敗したらfalse。ただし受信の成否については保証しない
【1.5-】receiverIDと同じ番号のチャンネルにmessageを送信する。rednet.openではコンピュータIDをチャンネル番号としてopenしているため、結果的に従来通りIDがreceiverIDのコンピュータに送信することになる。
例:
rednet.send(22,"ComputerCraft", true)
IDが22のComputer/Turtleへ文字列"ComputerCraft"を送信する(ポートが利用可能になるまで待つ)。
receive
- rednet.receive( timeout )
- 他のComputer/Turtleからの通信を待ち、通信があれば受信する。timeout(数値)で待つ最大時間を指定できる。
- 戻り値:数値型(senderID), 文字列型(message), 数値型(distance)。通信を受信すると、送信者ID(senderID)とメッセージ(message)、送信者までの距離(distance)が返る。ただしRedPowerの有線通信の場合は距離を取得できない。タイムアウトした場合はnilが返る。
os.pullEvent関数を用いてtimerイベント(
timeout指定時のタイムアウト処理)とrednet_messageイベント(通信の受信)の捕捉を行っている。イベントシステムを使って実装されているため、受信待機中に発生した他のイベントは破棄される。
【1.5-】通信可能なチャンネルからの通信を待ち、通信があれば受信する。rednet.openでは自身のコンピュータIDとrednet.CHANNEL_BROADCASTのチャンネルを通信可能な状態にするため、結果的に従来のrednet.receiveと同じ働きをする。なお、内部的にはrednet_messageイベントで受信しているため、前述の2つのチャンネル以外からはopenに関わらず受信できない。
【1.51-】Wired Modemを用いた有線通信の場合、distanceは送信者までのケーブルの長さが返る。
例:
senderId, message, distance = rednet.receive()
print(message)
メッセージを受信し、それを表示する。
run
- rednet.run()
- Rednet通信をモデムから受信し、rednet.receive関数で受信できるようにする
- 戻り値:nil
BIOSプログラム用の関数。BIOSプログラムによって自動的に実行されるため、プレイヤーが実行する必要はない。既に実行されている状態で呼び出した場合は、"rednet is already running"というエラーメッセージが表示される。
Rednet通信をモデムからのmodem_messageイベントで受信し、モデムがオープンかつ、受信チャンネルがコンピュータIDまたはブロードキャストの場合に、受信した情報を元にしてrednet_messageイベントを発生させる。rednet.receive関数は、この関数が発生させたrednet_messageイベントを取得することによってRednet通信を「受信」する。
GPS API
GPSとは
assets\computercraft\lua\rom\programs\gps で定義
GPSホストに記憶させた座標と、無線通信時に取得できるGPSホストまでの距離を元に、三次元測位の原理で位置を知りたいコンピュータの座標を計算するシステム(現実のGPSとはあまり関係ない)。ゲーム内から直接座標を取得するのではなく、Rednet APIの機能をフル活用して座標を求めている。
GPSホストの設置
最低限必要なもの:
- GPSホストにする「Wireless Modemを接続したComputer」または「Wireless Turtle」を計4つ
(当然ながらWired Modemでは利用できない)
GPSホスト4つをそれぞれが同じ平面上にならない位置(つまり三角錐の各頂点の位置)に設置する。GPSホストは、なるべく広範囲から利用できるように、設置限界高度ギリギリに設置するとよい。そして、gps host <x> <y> <z>コマンドで各GPSホストの座標を指定してGPSホストプログラムを起動する。GPSホストの座標は、GPSホストとするComputer/Turtleを設置した座標である(※Wireless Modemブロックの座標ではないので注意)。
GPSホストのComputer/Turtleがチャンク凍結・リロードで再起動しても自動で復帰できるようにするため、GPSホストプログラムはstartupプログラム内で起動するとよい。
startupの例:
shell.run("gps", "host", "100", "254", "-200")
GPSホストプログラムを座標(100, 254, -200)に設定して起動する。
CC1.4からWireless Turtleでもgps hostコマンドが使えるように修正された。これにより、Wireless Turtleをプログラムによって設置位置まで移動させGPSホストプログラムを起動することが可能となった(ただし、自力で登って設置するならComputerの方が低コスト)。
ホスト設置座標の例
※以下の例の「有効範囲」はWireless Modemの通信距離によるもの。実際には、GPSホストがプレイヤーからxまたはz座標で160mくらい離れた(正確にはプレイヤーのいるチャンクを中心とした21*21チャンクの範囲から出た)時点でGPSホストのあるチャンクが凍結され、利用できなくなってしまう(他のmodで追加されるチャンクローダーで回避可能)。
例1:
CC公式フォーラムで紹介されていたもの。平面上の有効範囲はy1で半径約270m、y64で半径約320mの大体円形。
- (x, 254, z - 9)
- (x + 9, 251, z)
- (x, 254, z + 9)
- (x - 9, 251, z)
ただし上の例では、y240~250付近で通信範囲内であっても座標を特定できないエリアがわずかに存在する(山岳~地下で利用する分には特に問題ない)。
例2:
GPSホストを一辺が約12mの正四面体の各頂点に配置した例。有効範囲は4機目を中心として半径約363mの球形内。平面上の有効範囲はy1で半径約270m、y64で半径約315m、y128で半径約340mの円形。
- (x - 6, 254, z - 4)
- (x + 6, 254, z - 4)
- (x, 254, z + 7)
- (x, 244, z)
4機目の高度を下げているのは、4機目が1~3機目と同じ平面上の位置にならないようにするため。
+
|
... |
ホスト3機で2つに絞れた座標(片方が正しい)を4機目で1つに絞るためには、【《計算で求められた正しい座標と4機目間の距離》と《Rednetによる4機目までの正確な距離》の差の絶対値】と【《計算で求められた正しくない座標と4機目間の距離》と《Rednetによる4機目までの正確な距離》の差の絶対値】の差の絶対値が0.05以上である必要がある。これはGPS APIによる制約で、この値がGPS利用予定範囲内のすべての位置で0.05以上になるように4機目の高度を下げるのだが、高度を下げ過ぎると今度は通信可能範囲が縮小してGPS全体の利用可能範囲が狭くなってしまう。双方のバランスをとった結果、4機目のy座標、そして2~4機目のx, z座標つまりGPSの利用可能範囲が決まることになる。
|
GPSの利用
4つ以上のGPSホストが利用可能な位置にある「Wireless Modemを接続したComputer」や「Wireless系 Turtle」でgps locateコマンドやgps.locate関数を使用する。
GPSの仕組み
※【1.5】からWireless Modemの通信仕様変更により、GPS API及びgpsプログラムは、GPSホスト側の受信にはgps.CHANNEL_GPSのチャンネルを、GPSで座標を求めるコンピュータ側の受信には自身のコンピュータIDのチャンネルを用いるように変更されている。そのため、GPS APIやgpsプログラムを使わずにGPSネットワークを利用する場合は、
Peripheral APIを用いて、直接Wireless Modemのメソッドを呼び出して通信する必要がある。詳しくは assets\computercraft\lua\rom\apis\gps 及び assets\computercraft\lua\rom\programs\gps のLuaスクリプトを参照。なお、
GPS API及びgpsプログラムからのみGPSを利用する限りは、この仕様変更を特に気にする必要はない。
- GPSホストには事前にGPSホストのある座標を記憶させておく(gps hostコマンドを使用。GPSホストはCHANNEL_GPSチャンネル宛ての通信が受信可能になる)
- gps locateコマンドまたはgps.locate関数によって、現在位置を知りたいコンピュータから文字列"PING"がCHANNEL_GPSチャンネルへ送信される
- 文字列"PING"を受信したGPSホストは、1.で設定した自身の座標を"PING"を送信したコンピュータ(2.の位置を知りたいコンピュータ)へ返信する
- 位置を知りたいコンピュータは各GPSホストからGPSホストの座標とGPSホストまでの距離(位置を求める計算に使われる)を得る。
- 位置を知りたいコンピュータ側に、同一平面上にない4つ以上のGPSホストから返信があれば位置を計算できる。
同一直線上にない3つのGPSホストの場合、gps locateコマンドや、デバッグモードを指定したgps.locate関数は2つの座標(片方が正しい)を画面に表示するが、gps.locate関数の戻り値から結果を得ることはできない。
locate
assets\computercraft\lua\rom\apis\gps で定義
- gps.locate( timeout [ , debug ] )
- GPSシステムを利用してコンピュータやタートルの座標を求める。timeout(数値)はGPSホストからの返信を待つ時間(秒)。debug(ブーリアン)にtrueを指定すると画面にデバッグ情報を表示する。
- 戻り値:数値型(x), 数値型(y), 数値型(z)。座標が求められた場合は各座標の数値が返る。求められなかった場合はnilが返る
位置を求めるのに有効なGPSホストが3つしかない場合は、デバッグ情報に2つの候補座標が表示されるが関数の戻り値からは座標を取得することができない(nilが返る)。
内部的には
os.pullEvent関数でmodem_messageイベントとtimerイベントを捕捉している。イベントシステムを使って実装されているため、受信待機中に発生した他のイベントは破棄される。
最終更新:2014年01月01日 12:37