このページではWEBアプリサーバーOpenResty上で動作するRTCを作成して、以下のようにPython版サンプルコンポーネントのジョイスティックコンポーネントと接続してWEBブラウザ上でジョイスティックの位置を表示するシステムの作成を行います。
従来はWEBブラウザ上でRTCのデータを表示等をする場合は、以下のようにRTCとWEBサーバーで通信を行う必要がありましたが、
WEBサーバー上でRTCを起動することで、以下のように構成が簡単になります。
この構成にする事によって、従来の方法では難しかったWEBブラウザでの操作のタイミングでOutPortからデータを送信する、サービスポートの操作を呼び出すという事が容易に実現できます。
※このような使い方を見たわけではありませんが、OpenRTM-aist Python版+Twisted(もしくはDjango)でも同じ構成は可能かもしれません。
以下からopenresty-1.13.6.1-win32.zipをダウンロードして適当な場所に展開してください。
以下のサイトを参考にしてディレクトリを作成する。
rtc-server | |----conf | |----mime.types | |----nginx.conf | |----logs | |----access.log | |----error.log | |----luahooks | |----image.lua | | |----public | |----images | |----index.html | |----sample.html | |----test.gif
nginx.conf
には以下のように記述してください。
worker_processes 1; events { worker_connections 1024; accept_mutex_delay 100ms; } http { sendfile on; tcp_nopush on; include mime.types; default_type text/html; index index.html; # # log settings # log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log logs/access.log main; # # lua global settings # lua_package_path '$prefix/luahooks/?.lua;;'; lua_check_client_abort on; lua_code_cache on; # # initialize script # #init_by_lua_file luahooks/init.lua; # # public # server { listen 1080; root public/images; # # content handler # location /index.html { default_type text/html; content_by_lua_file luahooks/image.lua; } } }
test.gif
には以下のような画像を用意してください。
sample.html
には以下のように記述してください。
rtc-server
のフォルダにOpenRTM Lua版の各ファイルをコピーします。
以下から32bit用のOpenRTM Lua版ファイル一式(OpenRTM Lua x.y.z LuaJIT 32bit)をダウンロードしてください。
OpenRTM Lua版からOpenRestyにファイルをコピーします。
openrtm-lua-x.y.z-x86-LuaJIT\lua
フォルダを、rtc-server
以下にコピーしてください。
openrtm-lua-x.y.z-x86-LuaJIT\lua\idl
フォルダを、rtc-server
以下にコピーしてください。
openrtm-lua-x.y.z-x86-LuaJIT\clibs
フォルダを、rtc-server
以下にコピーしてください。
lua51.dll
の上書きが必要なため、openrtm-lua-x.y.z-x86-LuaJIT\bin\lua51.dll
をopenresty-1.13.6.1-win32\
以下にコピーしてください。
データはJSON形式で取得しますが、Lua CJSONはこちらでdllを用意していないのでビルドしてください。
以下からソースコードをダウンロードしてCMake、Visual Studioでビルドしてください。
Visual Stduio 2017の場合はビルド時にエラーが出ます。 CMakeLists.txtの以下の部分を削除してからビルドしてください。
add_definitions(-Dsnprintf=_snprintf)
RTC BuilderによるRTCの基本的な作成手順は以下のページを参考にしてください。
上のページの作成手順に従って、以下の仕様のRTCを作成してください。
モジュール名 | OpenRestySample |
onExecute
を有効にしてください。
ポート名 | in |
データ型 | RTC::TimedFloatSeq |
データを格納する変数、取得する関数を定義します。
OpenRestySample.new = function(manager)
local obj = {}
(省略)
obj.input_data = {0,0}
function obj:getData()
return self.input_data
end
OpenRestySample.lua
のonExecute
関数を以下のように編集してください。
function obj:onExecute(ec_id)
if self._inIn:isNew() then
local data = self._inIn:read()
self.input_data[1] = data.data[1]
self.input_data[2] = data.data[2]
end
return self._ReturnCode_t.RTC_OK
end
入力データはgetData
関数で取得できます。
編集したOpenRestySample.lua
をrtc-server\lua
にコピーしてください。
image.lua
の編集image.lua
に以下のように記述してください。
package.path = package.path..";./lua/?.lua"
package.cpath = package.cpath..";./clibs/?.dll"
local oil = require "oil"
local openrtm = require "openrtm"
local OpenRestySample = require "OpenRestySample"
local cjson = require "cjson"
local args = ngx.req.get_uri_args()
local command = tostring( args.command )
if command == "start" then
local f = io.open("public/images/sample.html", "r")
local content = f:read("*all")
f:close()
local MyModuleInit = function(manager)
OpenRestySample.Init(manager)
local comp = manager:createComponent("OpenRestySample")
end
if oil.corba == nil then
oil.corba = {}
oil.corba.idl = {}
end
local manager = openrtm.Manager
manager:init({"-o","logger.enable:NO","-o","exec_cxt.periodic.type:OpenHRPExecutionContext"})
manager:setModuleInitProc(MyModuleInit)
manager:activateManager()
manager:runManager(true)
ngx.say(content)
elseif command == "update" then
local x = 0
local y = 0
local manager = openrtm.Manager
manager:step()
local comp = manager:getComponent("OpenRestySample0")
local ec = comp:get_owned_contexts()[1]
ec:tick()
local data = comp:getData()
x = data[1]
y = data[2]
ngx.say(cjson.encode({x=x,y=y}))
end
クエリパラメータcommand
がstart
の場合はRTCを起動します。
command
がupdate
の場合はRTCのステップ処理を更新して入力データを取得します。
JSON形式によりサーバークライアントでデータのやり取りを行います。
事前にネームサーバーの起動が必要です。
※OpenRTM-aist 1.2以降ではRT System Editorにネームサーバー起動ボタンがあるため、手順が簡単になっています。
TkJoyStickコンポーネントを入手して、TkJoyStickComp.exe
を実行してください。
openresty-1.13.6.1-win32
以下のディレクトリを環境変数PATHに設定してください。
rtc-server
の上のディレクトリで以下のコマンドを実行するとWEBサーバーが起動します。
> nginx.exe -p ./
Google Chrome等のWEBブラウザからhttp://localhost:1080/index.html?command=start
にアクセスするとRTCが起動します。
まずRTCの起動に成功している場合は、以下のようにネームサービスビューにRTCが表示されます。
Open New System Editor
ボタンを押してシステムダイアグラムを表示してください。
ネームサービスビューからシステムダイアグラムにRTCをドラックアンドドロップしてください。
TkJoyStick0
のpos
のOutPortを、OpenRestySample0
のin
のInPortにドラックアンドドロップしてください。
※ステップ実行をしている側のRTC(今回はOpenRestySample0
)のconnect
関数を呼び出すと接続に失敗します。必ず、今回の場合はTkJoyStick0
のpos
を選択してドラックアンドドロップしてください。
これで通信ができるようになります。
All Activate
ボタンを押すとTkJoyStick0
からデータが送信されるためWEBブラウザ上の画像が動くようになります。
imahe.lua
のmanager:init
関数の引数を以下のように変更してください。
manager:init({"-o","logger.enable:NO","-o","exec_cxt.periodic.type:OpenHRPExecutionContext", "-o", "manager.components.preconnect:OpenRestySample0.in?port=rtcname://localhost/TkJoyStick0.pos", "-o", "manager.components.preactivation:OpenRestySample0,rtcname://localhost/TkJoyStick0","-o","corba.step.count:4"})
-o
オプションでパラメータの設定ができます。
"-o", "manager.components.preconnect:OpenRestySample0.in?port=rtcname://localhost/TkJoyStick0.pos"
起動時に接続するポートを指定します。 この場合はOpenRestySample0というRTCのinというデータポートを、TkJoyStick0というRTCのposというポートに接続します。
ただし、TkJoyStick0
は別プロセスで起動しているため、rtcname形式
による指定が必要になります。 rtcname形式
はネームサーバーからRTCを取得する方法です。rtcname://アドレス/RTC名.ポート名
で指定します。
"-o","manager.components.preactivation:OpenRestySample0,rtcname://localhost/TkJoyStick0"
起動時にアクティブ化するRTCを指定します。
"-o","corba.step.count:4"
ORBをステップ実行するときのみ有効なオプションです。 指定回数だけORBをステップ実行します。ORBから処理要求がない場合は、要求があるまで待ちます。 preconnect等で外部のRTCと接続する場合に必要です。
今回はInPortのみを使用しましたが、OutPortを使用する場合についてはデータ転送の際に以下のようにoil.main
関数で実行する必要があります。
また、サービスポートのプロバイダ側についても同じです。
oil.main
関数で実行する必要があるのは、今回のようにORBをステップ実行した時のみです。
oil.main(function()
self._outOut:write()
end)