ロボット、千葉ロッテマリーンズについていいかげんなことを書きます。
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
どうも一部のソフトウェアでOilのCORBA通信が上手くいかないことがあるらしい。
ネームサーバーへの登録などクライアント側で動作する分には問題ないのですが、サーバー側で動作しているときにクライアントから操作しようとした瞬間に落ちます。
調べてみた結果、Oilの使用しているLOOPライブラリのCoSocket.luaの以下の部分で落ちていることが分かりました。
function select(self, recvt, sendt, timeout)
・・・・・
local readok, writeok, errmsg = scheduler.select(recvt, sendt, 0)
・・・・
readok[#readok+1] = wrapper
どうやら、scheduler.select関数でLuaSocketライブラリのselect関数が呼ばれているらしく、このselect関数で取得したテーブルに上みたいに要素を追加しようとすると途端に落ちます。
落ちるコードの簡単な例は以下の通りなので、今後Oil、というかLOOPを使う予定のある人は試してみてください。
local socket = require( "socket" )
local server = socket.bind("localhost", 2810)
local servers = {server}
local readok = socket.select(servers, nil, 0)
readok[1] = 100
ちなみに、以下のような感じでテーブルをコピーしてから処理すると何も問題は起こらないので、場合によってはLOOPライブラリの修正が必要です。
local readok, writeok, errmsg = scheduler.select(recvt, sendt, 0)
OilもLOOPも2008年ごろから開発が止まっているみたいなので、不具合があったら自分で何とかするしかありません。
正直これの原因究明はかなりきつかったと思います。
エラーが出るならともかく、突然落ちる理由が見当もつかず、調べるのに1週間近くかかりました。
おそらくですが、この修正をする事で20以上のソフトウェア上にOilを使用したLuaスクリプトを組み込むことができるようなります。
つまりLua版RTミドルウェアも動作できます。
まあ問題はLua版RTミドルウェアの中身が全く実装できていない事ですけど、気が向いたら作業はするかもしれないですし、飽きたらやめるかもしれません。
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・
ネームサーバーへの登録などクライアント側で動作する分には問題ないのですが、サーバー側で動作しているときにクライアントから操作しようとした瞬間に落ちます。
調べてみた結果、Oilの使用しているLOOPライブラリのCoSocket.luaの以下の部分で落ちていることが分かりました。
function select(self, recvt, sendt, timeout)
・・・・・
local readok, writeok, errmsg = scheduler.select(recvt, sendt, 0)
・・・・
readok[#readok+1] = wrapper
どうやら、scheduler.select関数でLuaSocketライブラリのselect関数が呼ばれているらしく、このselect関数で取得したテーブルに上みたいに要素を追加しようとすると途端に落ちます。
落ちるコードの簡単な例は以下の通りなので、今後Oil、というかLOOPを使う予定のある人は試してみてください。
local socket = require( "socket" )
local server = socket.bind("localhost", 2810)
local servers = {server}
local readok = socket.select(servers, nil, 0)
readok[1] = 100
ちなみに、以下のような感じでテーブルをコピーしてから処理すると何も問題は起こらないので、場合によってはLOOPライブラリの修正が必要です。
local readok, writeok, errmsg = scheduler.select(recvt, sendt, 0)
readok = {unpack(readok)}
writeok = {unpack(writeok)}
OilもLOOPも2008年ごろから開発が止まっているみたいなので、不具合があったら自分で何とかするしかありません。
正直これの原因究明はかなりきつかったと思います。
エラーが出るならともかく、突然落ちる理由が見当もつかず、調べるのに1週間近くかかりました。
おそらくですが、この修正をする事で20以上のソフトウェア上にOilを使用したLuaスクリプトを組み込むことができるようなります。
つまりLua版RTミドルウェアも動作できます。
まあ問題はLua版RTミドルウェアの中身が全く実装できていない事ですけど、気が向いたら作業はするかもしれないですし、飽きたらやめるかもしれません。
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・
PR
LuaはC/C++等の他の言語に組み込むのが主な用途なので、既存のLuaが使えるソフトウェアに適用できるかを考えてみます。
考えた結果が以下の通りです。
○V-rep
△Snes9x-ReRecording
×AviUtl、RigidChips
V-repは問題なく使えます。
ただ、simSetThreadAutomaticSwitch関数により自動的にスレッドを切り替える機能を無効にすることと、実行コンテキストでsimSwitchThread関数を呼び出してLua側でスレッドを切り替える必要があるので、やや工夫が必要です。
Snes9x-ReRecordingのようなEmuLuaには一つ重大な問題があります。
Luaスクリプト内でフレームを進めるように命令するためにはframeadvance関数を使う必要がありますが、これがコルーチンからは呼び出せません。なので、Loopライブラリを改変してframeadvance関数を呼び出してやります。
thread/Scheduler.luaのrun関数を改変します。
local snes9x = require "snes9x"
・・・・・
こういうソフトウェアを出すと炎上する可能性があるのですが、別にエミュレータ自体は違法ではないので叩くのはやめてください。
ただ、Luaライブラリのバージョンが違うとクラッシュするという情報もあるので、動作できるかは不明です。
AviUtlのスクリプトはフレームごとに実行して画像を動かしたりするようなので不可能です。
RigidChipsもシミュレーションのステップごとにスクリプトを実行するようなので無理です。
調べてみた感じですが、多少の需要はありそうな感じです。
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・
考えた結果が以下の通りです。
○V-rep
△Snes9x-ReRecording
×AviUtl、RigidChips
V-repは問題なく使えます。
ただ、simSetThreadAutomaticSwitch関数により自動的にスレッドを切り替える機能を無効にすることと、実行コンテキストでsimSwitchThread関数を呼び出してLua側でスレッドを切り替える必要があるので、やや工夫が必要です。
Snes9x-ReRecordingのようなEmuLuaには一つ重大な問題があります。
Luaスクリプト内でフレームを進めるように命令するためにはframeadvance関数を使う必要がありますが、これがコルーチンからは呼び出せません。なので、Loopライブラリを改変してframeadvance関数を呼び出してやります。
thread/Scheduler.luaのrun関数を改変します。
local snes9x = require "snes9x"
・・・・・
function run(self, ...)
・・・・・
・・・・・
snes9x.frameadvance()
return self:run()
こういうソフトウェアを出すと炎上する可能性があるのですが、別にエミュレータ自体は違法ではないので叩くのはやめてください。
ただ、Luaライブラリのバージョンが違うとクラッシュするという情報もあるので、動作できるかは不明です。
AviUtlのスクリプトはフレームごとに実行して画像を動かしたりするようなので不可能です。
RigidChipsもシミュレーションのステップごとにスクリプトを実行するようなので無理です。
調べてみた感じですが、多少の需要はありそうな感じです。
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・
RTミドルウェアを実装する上で重要の要素として実行コンテキストがあるわけですが、LuaのC APIはマルチスレッドで動作させることができません。
上のリンクのサイトではC側のプログラムで並列処理ができるようにしていますが、Luaだけでやろうと思うとこのようなコルーチンによる疑似マルチスレッドを使うことになります。
yieldで処理を中断して、他の処理に移るということなので、見かけ上は並列にしているように見えます。
つまりyieldで中断しなければ永久に他の処理は実行されません。
oilの中身もこんな感じの処理をしているので、同じようにyieldで中断すれば実行コンテキストも実装できます。
あと、V-rep等でoil実行の際に必要なファイルについてメモしておきます。
luaフォルダからは以下のファイル、フォルダをコピーします。
さらにclibsフォルダからCモジュールをコピーする必要があります。
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・
上のリンクのサイトではC側のプログラムで並列処理ができるようにしていますが、Luaだけでやろうと思うとこのようなコルーチンによる疑似マルチスレッドを使うことになります。
yieldで処理を中断して、他の処理に移るということなので、見かけ上は並列にしているように見えます。
つまりyieldで中断しなければ永久に他の処理は実行されません。
oilの中身もこんな感じの処理をしているので、同じようにyieldで中断すれば実行コンテキストも実装できます。
local coroutine = require "coroutine"
ExecutionContext = {}
ExecutionContext.new = function()
local obj = {}
obj.run = function()
while true do
print("run")
coroutine.yield(1)
end
end
return obj
end
oil.main(function()
・・・・・
・・・・・
ec = ExecutionContext.new()
oil.newthread(ec.run)
あと、V-rep等でoil実行の際に必要なファイルについてメモしておきます。
luaフォルダからは以下のファイル、フォルダをコピーします。
- oil.lua
- luaidl.lua
- socket.lua※
- oil
- luaidl
- loop
- socket※
さらにclibsフォルダからCモジュールをコピーする必要があります。
- oil/bit.dll
- socket/core.dll※
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・
Lua for WindowsのインストーラーでLuaをインストールするとOilというライブラリが付いてきます。
これはLuaのCORBA実装なので、C++、PythonのomniORB等の他のCORBA実装とも通信できます。
このOilを使う事で、RTミドルウェアのLua実装を開発する事もできます。
これはネームサーバー、RTシステムエディタと通信してRTCを活性化したときにアクティブ状態に遷移して、非活性化したときに非アクティブ状態に遷移するだけの実装なので、中身はほとんど実装できていません。
一応ソースコードはここにあります。
Oilの使い方に関する資料が極めて少なく調べるのに苦労したので、今後のためにいくつかメモを書いておきます。
ORBの初期化の引数なのですが、以下のようにludoを入れるとLuDOという謎機能で通信をするようなので入れないようにしてください。
orb = oil.init{ flavor = "ludo;cooperative;base", port = 2810 }
とりあえず、以下のように初期化します。
local orb = oil.init{ flavor = "intercepted;corba;typed;cooperative;base", port=2810 }
次にIDLファイルを読み込みます。
orb:loadidlfile("CosNaming.idl")
このとき読み込むIDLファイルですが、IDL読み込みの機能が完全ではないらしく原因不明のエラーが発生することがあるので、Oilのexampleに入っているものを使用してください。
次にネームサーバーに接続します。
インターフェースの名称には注意してください。
ns = orb:newproxy("corbaloc:iiop:localhost:2809/NameService","IDL:omg.org/CosNaming/NamingContext:1.0")
最後にオブジェクトをネームサーバーにバインドします。
obj = orb:newservant(Hello, nil, "IDL:Hello:1.0")
ns:rebind({{id="testComp",kind="rtc"}},testComp)
次にRTCプロファイルのような複数のデータを含む構造体を返すオペレーションを実行した際に、どのようにその構造体を表現するかについてメモします。
これは実は簡単で、テーブルに同じ名前の変数を追加して、そのテーブルを返すだけです。
さっきも言ったのですが、IDLの読み込み機能が不完全らしく、特にSDOPackage.idlの読み込みには苦労しました。読み込めるように改変したものは、先ほどのソースコードと一緒に置いてあります。
何故かconst修飾子が全く使えないらしく、CosNotification.idlからconst定数は全て削除しました。それ以外にもエラーが多数発生したので大幅に変更してあります。
多分これの開発は滞る、というか先が長すぎてあまりやる気がでないので、しばらく放置します。
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・
これはLuaのCORBA実装なので、C++、PythonのomniORB等の他のCORBA実装とも通信できます。
このOilを使う事で、RTミドルウェアのLua実装を開発する事もできます。
これはネームサーバー、RTシステムエディタと通信してRTCを活性化したときにアクティブ状態に遷移して、非活性化したときに非アクティブ状態に遷移するだけの実装なので、中身はほとんど実装できていません。
一応ソースコードはここにあります。
Oilの使い方に関する資料が極めて少なく調べるのに苦労したので、今後のためにいくつかメモを書いておきます。
ORBの初期化の引数なのですが、以下のようにludoを入れるとLuDOという謎機能で通信をするようなので入れないようにしてください。
orb = oil.init{ flavor = "ludo;cooperative;base", port = 2810 }
とりあえず、以下のように初期化します。
local orb = oil.init{ flavor = "intercepted;corba;typed;cooperative;base", port=2810 }
次にIDLファイルを読み込みます。
orb:loadidlfile("CosNaming.idl")
このとき読み込むIDLファイルですが、IDL読み込みの機能が完全ではないらしく原因不明のエラーが発生することがあるので、Oilのexampleに入っているものを使用してください。
次にネームサーバーに接続します。
インターフェースの名称には注意してください。
ns = orb:newproxy("corbaloc:iiop:localhost:2809/NameService","IDL:omg.org/CosNaming/NamingContext:1.0")
最後にオブジェクトをネームサーバーにバインドします。
obj = orb:newservant(Hello, nil, "IDL:Hello:1.0")
ns:rebind({{id="testComp",kind="rtc"}},testComp)
次にRTCプロファイルのような複数のデータを含む構造体を返すオペレーションを実行した際に、どのようにその構造体を表現するかについてメモします。
これは実は簡単で、テーブルに同じ名前の変数を追加して、そのテーブルを返すだけです。
local testComp = {}
function testComp:get_component_profile()
print("get_component_profile")
return {instance_name="testComp",type_name="testComp",
description="description",version="0", vendor="sample",
category="test",port_profiles={},
parent=testComp,properties={
{name="implementation_id",value="testComp"}, {name="type_name",value="testComp"},
{name="description",value="description"},{name="version",value="0"},
{name="vendor",value="sample"},{name="category",value="test"},
{name="activity_type",value="STATIC"},{name="max_instance",value="1"},
{name="language",value="Lua"},{name="lang_type",value="SCRIPT"},
{name="instance_name",value="testComp0"}
}
}
end
さっきも言ったのですが、IDLの読み込み機能が不完全らしく、特にSDOPackage.idlの読み込みには苦労しました。読み込めるように改変したものは、先ほどのソースコードと一緒に置いてあります。
何故かconst修飾子が全く使えないらしく、CosNotification.idlからconst定数は全て削除しました。それ以外にもエラーが多数発生したので大幅に変更してあります。
多分これの開発は滞る、というか先が長すぎてあまりやる気がでないので、しばらく放置します。
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・
メーリングリストで問題になっている「ポートプロファイルから出力データを取得する機能」ですが、あそこで機能の内容を説明するのは適当ではないので一応解説します。
この機能があるのはC++版のみで、PythonとJavaには最新のソースコードにも実装はありません。※Javaには実装がありました。間違えてごめんなさい。
まず、この機能を知っていた人はほとんどいないと思います。
僕もこの機能についてはソースコードを読んだ以上の知識はないので、分からないことがあったら自分で調べてください。
機能の説明の前に、RTシステムエディタで何故RTCの情報、保持しているポート等が確認できるかというと、RTCを起動しているプロセスとCORBA通信をすることでコンポーネントプロファイル(ComponentProfile)を取得しているからです。
このコンポーネントプロファイルは保持しているデータポート、サービスポートのプロファイル(PortProfile)を持っているので、RTシステムエディタではここからポートの情報を取得してシステムダイアグラム上にRTCを表示できているということです。
さて「ポートプロファイルから出力データを取得する機能」ですが、これはアウトポートから出力したデータをポートプロファイルから取得できる機能です。
取得できるデータはアウトポートからデータを出力すると上書きされるので、直前に出力したデータしか取得できません。
あの問題ですが、RTシステムエディタでプロファイル取得中に、同時に出力データのポートプロファイルへの格納を行った場合にアクセス違反で落ちます。
これは画像データなど大容量のデータを通信すると問題が起きやすいというだけで、小さいデータを通信するRTCでも運が悪ければ発生します。
ちなみにですが、omniORBのデフォルトの設定では2MBがデータサイズの上限なので、640×480の画像データを送信するアウトポートが3つ以上あると、RTシステムエディタではコンポーネントプロファイルが取得できなくなるのでRTCの表示がバグります。
ただでさえRTシステムエディタとRTCの通信量が増えるので、動きが悪くなるかもしれません。
この機能の内容、利点・欠点はこんな感じです。
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・
この機能があるのはC++版のみで、PythonとJavaには最新のソースコードにも実装はありません。※Javaには実装がありました。間違えてごめんなさい。
まず、この機能を知っていた人はほとんどいないと思います。
僕もこの機能についてはソースコードを読んだ以上の知識はないので、分からないことがあったら自分で調べてください。
機能の説明の前に、RTシステムエディタで何故RTCの情報、保持しているポート等が確認できるかというと、RTCを起動しているプロセスとCORBA通信をすることでコンポーネントプロファイル(ComponentProfile)を取得しているからです。
このコンポーネントプロファイルは保持しているデータポート、サービスポートのプロファイル(PortProfile)を持っているので、RTシステムエディタではここからポートの情報を取得してシステムダイアグラム上にRTCを表示できているということです。
さて「ポートプロファイルから出力データを取得する機能」ですが、これはアウトポートから出力したデータをポートプロファイルから取得できる機能です。
取得できるデータはアウトポートからデータを出力すると上書きされるので、直前に出力したデータしか取得できません。
あの問題ですが、RTシステムエディタでプロファイル取得中に、同時に出力データのポートプロファイルへの格納を行った場合にアクセス違反で落ちます。
これは画像データなど大容量のデータを通信すると問題が起きやすいというだけで、小さいデータを通信するRTCでも運が悪ければ発生します。
ちなみにですが、omniORBのデフォルトの設定では2MBがデータサイズの上限なので、640×480の画像データを送信するアウトポートが3つ以上あると、RTシステムエディタではコンポーネントプロファイルが取得できなくなるのでRTCの表示がバグります。
ただでさえRTシステムエディタとRTCの通信量が増えるので、動きが悪くなるかもしれません。
この機能の内容、利点・欠点はこんな感じです。
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・