このページではゲームエンジンLÖVE上で動作する上で動作するRTCを作成して、以下のようにPython版サンプルコンポーネントのジョイスティックコンポーネントと接続して物体を操作するシステムの作成を行います。
以下からLÖVEを入手してください。
※LÖVEの新しいバージョンで色が描画されない不具合があります。問題が発生した場合はLÖVEの0.10.2を入手してください。
LÖVEを展開したフォルダにOpenRTM Lua版の各ファイルをコピーします。
以下からOpenRTM Lua版ファイル一式(OpenRTM Lua x.y.z Lua5.1 64bit(もしくは32bit))をダウンロードしてください。 32bit版のLÖVEを使用する場合は32bit版、64bit版のLÖVEを使用する場合は64bit版を使用します。
OpenRTM Lua版からLÖVEにファイルをコピーします。
openrtm-lua-x.y.z-x64-lua5.1\lua
フォルダをlove-11.1.0-win64\
以下にコピーしてください。
次にopenrtm-lua-x.y.z-x64-lua5.1\clibs\
以下のファイルを全てlove-11.1.0-win64\
以下にコピーしてください。
RTC BuilderによるRTCの基本的な作成手順は以下のページを参考にしてください。
上のページの作成手順に従って、以下の仕様のRTCを作成してください。
モジュール名 | LOVESample |
onExecute
を有効にしてください。
ポート名 | in |
データ型 | TimedFloatSeq |
LOVESample.lua
に物理オブジェクトを設定するためのsetObject関数を追加します。
LOVESample.new = function(manager)
local obj = {}
(省略)
function obj:setObject(objects)
self._objects = objects
end
LOVESample.lua
のonExecute関数を編集します。
function obj:onExecute(ec_id)
if self._inIn:isNew() then
local data = self._inIn:read()
self._objects.ball.body:applyForce(data.data[1], 0)
if data.data[2] > 100 then
self._objects.ball.body:setPosition(650/2, 650/2)
self._objects.ball.body:setLinearVelocity(0, 0)
end
end
return self._ReturnCode_t.RTC_OK
end
InPortのデータを読み込んで、左右の操作でボールに力を加える。 上に動かした場合はボールの位置、速度を初期化する。
編集したLOVESample.lua
をlove-11.1.0-win64\lua\
以下にコピーしてください。
適当な場所にフォルダ(今回はLOVESampleGameフォルダ)を新規作成してください。
その中にmain.lua
を作成してください。
今回はPhysicsのチュートリアルのソースコードを変更したものを作成します。
まず、初期化時に一度だけ呼び出されるlove.load()
関数を編集します。
LÖVEは内部でLuaSocketをロードするため、全て無効化します。
function love.load()
package.preload["mime.core"] = nil
package.preload["socket.ftp"] = nil
package.preload["socket.headers"] = nil
package.preload["socket.url"] = nil
package.preload["socket.smtp"] = nil
package.preload["socket.http"] = nil
package.preload["socket.core"] = nil
package.preload["socket.tp"] = nil
package.preload["mime"] = nil
package.preload["socket"] = nil
local openrtm = require "openrtm"
local mgr = openrtm.Manager
mgr:init({"-o","exec_cxt.periodic.type:OpenHRPExecutionContext","-o","manager.components.precreate:LOVESample","-o","manager.components.preconnect:LOVESample0.in?port=rtcname://localhost/TkJoyStick0.pos","-o","manager.components.preactivation:LOVESample0,rtcname://localhost/TkJoyStick0","-o","corba.step.count:4"})
mgr:activateManager()
mgr:runManager(true)
-- チュートリアルのコード
love.physics.setMeter(64) --the height of a meter our worlds will be 64px
(省略)
love.window.setMode(650, 650) --set the window dimensions to 650 by 650
-------------------------------------------------------------------------
local comp = mgr:getComponent("LOVESample0")
comp:setObject(objects)
end
基本は上記のコードのLOVESample
の部分を変更すると、他のRTCにも適用できるようになります。
mgr:init
関数の引数について説明します。
-o
オプションの後にパラメータを指定します。
"-o","exec_cxt.periodic.type:OpenHRPExecutionContext"
実行コンテキストの指定をしています。
LÖVE上ではRTCをステップ実行したいのでOpenHRPExecutionContext
という実行コンテキストを指定します。
"-o","manager.components.precreate:LOVESample"
起動時に生成するRTC名を指定します。
"-o","manager.components.preconnect:LOVESample0.in?port=rtcname://localhost/TkJoyStick0.pos"
起動時に接続するポートを指定します。
この場合はLOVESample0
というRTCのin
というデータポートを、TkJoyStick0
というRTCのpos
というポートに接続します。
ただし、TkJoyStick0
は別プロセスで起動しているため、rtcname形式
による指定が必要になります。
rtcname形式
はネームサーバーからRTCを取得する方法です。rtcname://アドレス/RTC名.ポート名
で指定します。
"-o","manager.components.preactivation:LOVESample0,rtcname://localhost/TkJoyStick0"
起動時にアクティブ化するRTCを指定します。
"-o","corba.step.count:4"
ORBをステップ実行するときのみ有効なオプションです。 指定回数だけORBをステップ実行します。ORBから処理要求がない場合は、要求があるまで待ちます。 preconnect等で外部のRTCと接続する場合に必要です。
love.update
関数は以下のように編集します。
function love.update(dt)
world:update(dt)
local openrtm = require "openrtm"
local mgr = openrtm.Manager
mgr:step()
local comp = mgr:getComponent("LOVESample0")
local ec = comp:get_owned_contexts()[1]
ec:tick()
end
love.draw
関数はチュートリアルのコードと同じです。
事前にネームサーバーの起動が必要です。
※OpenRTM-aist 1.2以降ではRT System Editorにネームサーバー起動ボタンがあるため、手順が簡単になっています。
TkJoyStickコンポーネントを入手して、TkJoyStickComp.exe
を実行してください。
LOVESampleGame
フォルダをlove.exe
にドラッグアンドドロップするとゲームを開始します。
起動時にポートの接続、アクティブ化をオプションで設定しているため、RT System Editorでの操作は不要ですが、念のためRT System Editorによる操作手順も説明します。
まずRTCの起動に成功している場合は、以下のようにネームサービスビューにRTCが表示されます。
Open New System Editor
ボタンを押してシステムダイアグラムを表示してください。
ネームサービスビューからシステムダイアグラムにRTCをドラックアンドドロップしてください。
TkJoyStick0
のpos
のOutPortを、LOVESample0
のin
のInPortにドラックアンドドロップしてください。
これで通信ができるようになります。
※ステップ実行をしている側のRTC(今回はLOVESample0
)のconnect
関数を呼び出すと接続に失敗します。必ず、今回の場合はTkJoyStick0
のpos
を選択してドラックアンドドロップしてください。
All Activate
ボタンを押すとTkJoyStick0
からデータが送信されるため操作ができるようになります。
今回はInPortのみを使用しましたが、OutPortを使用する場合についてはデータ転送の際に以下のようにoil.main
関数で実行する必要があります。
また、サービスポートのプロバイダ側についても同じです。
oil.main
関数で実行する必要があるのは、今回のようにORBをステップ実行した時のみです。
oil.main(function()
self._outOut:write()
end)