このページではゲームエンジン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)