Coverage Report

Overview

Source coverage:85%
Total line count:21821
Total valid lines:11875
Total visited lines:10156

Files

lua\openrtm\version.lua
100%
lua\openrtm\Task.lua
100%
lua\openrtm\StateMachine.lua
100%
lua\openrtm\SdoServiceConsumerBase.lua
100%
lua\openrtm\OutPortConnector.lua
100%
lua\openrtm\OpenHRPExecutionContext.lua
100%
lua\openrtm\ManagerActionListener.lua
100%
lua\openrtm\LogstreamBase.lua
100%
lua\openrtm\FactoryInit.lua
100%
lua\openrtm\DefaultConfiguration.lua
100%
lua\openrtm\DataPortStatus.lua
100%
lua\openrtm\ConnectorBase.lua
100%
lua\openrtm\CdrRingBuffer.lua
100%
lua\openrtm\BufferStatus.lua
100%
lua\openrtm\PeriodicExecutionContext.lua
98%
lua\openrtm\InPortProvider.lua
98%
lua\openrtm\PortAdmin.lua
97%
lua\openrtm\NumberingPolicy.lua
97%
lua\openrtm\NamingServiceNumberingPolicy.lua
97%
lua\openrtm\TimeValue.lua
96%
lua\openrtm\ListenerHolder.lua
96%
lua\openrtm\ECFactory.lua
96%
lua\openrtm\CORBA_SeqUtil.lua
96%
lua\openrtm\SystemLogger.lua
95%
lua\openrtm\OutPortPushConnector.lua
95%
lua\openrtm\LogstreamFile.lua
95%
lua\openrtm\InPortConnector.lua
95%
lua\openrtm\ComponentActionListener.lua
95%
lua\openrtm\OutPortPullConnector.lua
94%
lua\openrtm\OutPortProvider.lua
94%
lua\openrtm\OutPortDSProvider.lua
94%
lua\openrtm\GlobalFactory.lua
94%
lua\openrtm\SdoServiceProviderBase.lua
93%
lua\openrtm\OutPort.lua
93%
lua\openrtm\InPortPullConnector.lua
93%
lua\openrtm\InPortDSProvider.lua
93%
lua\openrtm\CORBA_RTCUtil.lua
93%
lua\openrtm\ConnectorListener.lua
93%
lua\openrtm\PortConnectListener.lua
92%
lua\openrtm\InPort.lua
91%
lua\openrtm\Factory.lua
91%
lua\openrtm\CorbaPort.lua
91%
lua\openrtm\SimulatorExecutionContext.lua
90%
lua\openrtm\RingBuffer.lua
90%
lua\openrtm\ModuleManager.lua
90%
lua\openrtm\ExecutionContextProfile.lua
90%
lua\openrtm\StringUtil.lua
88%
lua\openrtm\RTObject.lua
87%
lua\openrtm\Properties.lua
86%
lua\openrtm\ConfigAdmin.lua
86%
lua\openrtm\RTObjectStateMachine.lua
85%
lua\openrtm\CorbaNaming.lua
85%
lua\openrtm\RTCUtil.lua
84%
lua\openrtm\PortBase.lua
84%
lua\openrtm\ObjectManager.lua
84%
lua\openrtm\ExecutionContextWorker.lua
84%
lua\openrtm\CorbaConsumer.lua
84%
lua\openrtm\OutPortBase.lua
83%
lua\openrtm\ManagerConfig.lua
83%
lua\openrtm\ExecutionContextBase.lua
81%
lua\openrtm\NamingManager.lua
80%
lua\openrtm\InPortPushConnector.lua
80%
lua\openrtm\InPortBase.lua
80%
lua\openrtm\PublisherFlush.lua
79%
lua\openrtm\NVUtil.lua
79%
lua\openrtm\InPortDSConsumer.lua
79%
lua\openrtm\PublisherBase.lua
78%
lua\openrtm\Manager.lua
78%
lua\openrtm\CdrBufferBase.lua
78%
lua\openrtm\SdoConfiguration.lua
77%
lua\openrtm\ConfigurationListener.lua
76%
lua\openrtm\OutPortDSConsumer.lua
75%
lua\openrtm\Timer.lua
70%
lua\openrtm\SdoServiceAdmin.lua
70%
lua\openrtm\BufferBase.lua
70%
lua\openrtm\PortCallBack.lua
68%
lua\openrtm\ManagerServant.lua
68%
lua\openrtm\NumberingPolicyBase.lua
62%
lua\openrtm\OutPortConsumer.lua
60%
lua\openrtm\NodeNumberingPolicy.lua
60%
lua\openrtm\InPortConsumer.lua
60%

File lua\openrtm\BufferBase.lua

1 ---------------------------------
2 --! @file BufferBase.lua
3 --! @brief バッファの基底クラス定義
4 --! バッファはBufferBaseテーブルをメタテーブルに設定して作成する
5 ---------------------------------
6
7 --[[
8 Copyright (c) 2017 Nobuhiko Miyamoto
9 ]]
10
11 local BufferBase = {}
12 --_G["openrtm.BufferBase"] = BufferBase
13
14 local BufferStatus = require "openrtm.BufferStatus"
15
16 -- バッファ初期化
17 -- @return バッファオブジェクト
18 BufferBase.new = function()
19     local obj = {}
20     -- 初期化時にプロパティ設定
21     -- @param prop プロパティ
22     function obj:init(prop)
23     end
24     -- バッファ長設定
25     -- @param n バッファ長
26     -- @return バッファステータス(nがnilの場合は長さ)
27     function obj:length(n)
28         if n == nil then
29             return 0
30         end
31         return BufferStatus.BUFFER_OK
32     end
33     -- バッファポインタをリセット
34     function obj:reset()
35     end
36     -- 指定位置まで書き込みポインタを進めた場合のバッファ取得
37     -- @param n ポインタの位置
38     -- @return 現在の位置のバッファ
39     function obj:wptr(n)
40     end
41     -- 書き込みポインタの位置を進める
42     -- @param n ポインタの位置
43     -- @return バッファステータス
44     function obj:advanceWptr(n)
45         return BufferStatus.BUFFER_OK
46     end
47     -- データ書き込み
48     -- @param value データ
49     -- @return バッファステータス
50     function obj:put(data)
51         return BufferStatus.BUFFER_OK
52     end
53     -- データ書き込み
54     -- @param value データ
55     -- @param sec タイムアウト時間[s]
56     -- @param nsec タイムアウト時間[ns]
57     -- @return バッファステータス
58     function obj:write(value, sec, nsec)
59         return BufferStatus.BUFFER_OK
60     end
61     -- 書き込み可能なバッファ残り長さ
62     -- @return 長さ
63     function obj:writable()
64         return 0
65     end
66     -- バッファフルの判定
67     -- @return true:バッファフル
68     function obj:full()
69         return true
70     end
71     
72     -- 指定位置まで読み込みポインタを進めた場合のバッファ取得
73     -- @param n ポインタの位置
74     -- @return 現在の位置のバッファ
75     function obj:rptr(n)
76     end
77     -- 読み込みポインタの位置を進める
78     -- @param n ポインタの位置
79     -- @return バッファステータス
80     -- BUFFER_OK:正常に位置設定、PRECONDITION_NOT_MET:位置が不正
81     function obj:advanceRptr(n)
82         return BufferStatus.BUFFER_OK
83     end
84     -- データ読み込み
85     -- @param value value._dataにデータ格納
86     -- @return バッファステータス(valueがnilの場合はバッファの値を返す)
87     function obj:get(value)
88         return BufferStatus.BUFFER_OK
89     end
90     -- データ読み込み
91     -- @param value value._dataにデータ格納
92     -- @param sec タイムアウト時間[s]、デフォルトは-1
93     -- @param nsec タイムアウト時間[ns]、デフォルトは0
94     -- @return バッファステータス
95     -- BUFFER_OK:正常にデータ読み込み、BUFFER_EMPTY:バッファが空
96     function obj:read(value, sec, nsec)
97         return BufferStatus.BUFFER_OK
98     end
99     -- 読み込み可能なデータ長さ取得
100     -- @return データ長さ
101     function obj:readable()
102         return 0
103     end
104     -- バッファが空かの判定
105     -- @return true:空
106     function obj:empty()
107         return true
108     end
109     return obj
110 end
111
112 BufferBase.NullBuffer = {}
113
114 -- 空のバッファ初期化
115 -- @return バッファオブジェクト
116 BufferBase.NullBuffer.new = function(size)
117     local obj = {}
118     setmetatable(obj, {__index=BufferBase.new()})
119     return obj
120 end
121
122
123
124 return BufferBase

File lua\openrtm\BufferStatus.lua

Full coverage

File lua\openrtm\CdrBufferBase.lua

1 ---------------------------------
2 --! @file CdrBufferBase.lua
3 --! @brief リングバッファ基底クラス定義
4 --! バッファ生成ファクトリはCdrBufferFactoryに登録する
5 ---------------------------------
6
7 --[[
8 Copyright (c) 2017 Nobuhiko Miyamoto
9 ]]
10
11 local CdrBufferBase= {}
12 --_G["openrtm.CdrBufferBase"] = CdrBufferBase
13
14 local GlobalFactory = require "openrtm.GlobalFactory"
15 local Factory = GlobalFactory.Factory
16 local BufferBase = require "openrtm.BufferBase"
17
18
19 -- リングバッファ初期化
20 -- @return バッファオブジェクト
21 CdrBufferBase.new = function()
22     local obj = {}
23     setmetatable(obj, {__index=BufferBase.new()})
24     return obj
25 end
26
27
28 CdrBufferBase.CdrBufferFactory = {}
29 setmetatable(CdrBufferBase.CdrBufferFactory, {__index=Factory.new()})
30
31 function CdrBufferBase.CdrBufferFactory:instance()
32     return self
33 end
34
35
36 return CdrBufferBase

File lua\openrtm\CdrRingBuffer.lua

Full coverage

File lua\openrtm\ComponentActionListener.lua

1 ---------------------------------
2 --! @file ComponentActionListener.lua
3 --! @brief コンポーネントコールバック定義クラス
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local ComponentActionListener= {}
11 --_G["openrtm.ComponentActionListener"] = ComponentActionListener
12
13
14 ComponentActionListener.PreComponentActionListenerType = {
15     PRE_ON_INITIALIZE                 = 1,
16     PRE_ON_FINALIZE                   = 2,
17     PRE_ON_STARTUP                    = 3,
18     PRE_ON_SHUTDOWN                   = 4,
19     PRE_ON_ACTIVATED                  = 5,
20     PRE_ON_DEACTIVATED                = 6,
21     PRE_ON_ABORTING                   = 7,
22     PRE_ON_ERROR                      = 8,
23     PRE_ON_RESET                      = 9,
24     PRE_ON_EXECUTE                    = 10,
25     PRE_ON_STATE_UPDATE               = 11,
26     PRE_ON_RATE_CHANGED               = 12,
27     PRE_COMPONENT_ACTION_LISTENER_NUM = 13
28 }
29
30 ComponentActionListener.PreComponentActionListener = {}
31
32
33
34
35 ComponentActionListener.PreComponentActionListener.toString = function(_type)
36     local typeString = {"PRE_ON_INITIALIZE",
37                         "PRE_ON_FINALIZE",
38                         "PRE_ON_STARTUP",
39                         "PRE_ON_SHUTDOWN",
40                         "PRE_ON_ACTIVATED",
41                         "PRE_ON_DEACTIVATED",
42                         "PRE_ON_ABORTING",
43                         "PRE_ON_ERROR",
44                         "PRE_ON_RESET",
45                         "PRE_ON_EXECUTE",
46                         "PRE_ON_STATE_UPDATE",
47                         "PRE_ON_RATE_CHANGED",
48                         "PRE_COMPONENT_ACTION_LISTENER_NUM"}
49
50     if _type < ComponentActionListener.PreComponentActionListenerType.PRE_COMPONENT_ACTION_LISTENER_NUM then
51         return typeString[_type]
52     end
53     return ""
54 end
55
56
57 ComponentActionListener.PreComponentActionListener.new = function()
58     local obj = {}
59     function obj:call(ec_id)
60         
61     end
62     local call_func = function(self, ec_id)
63         self:call(ec_id)
64     end
65     setmetatable(obj, {__call=call_func})
66     return obj
67 end
68
69
70
71
72
73 ComponentActionListener.PostComponentActionListenerType = {
74     POST_ON_INITIALIZE                 = 1,
75     POST_ON_FINALIZE                   = 2,
76     POST_ON_STARTUP                    = 3,
77     POST_ON_SHUTDOWN                   = 4,
78     POST_ON_ACTIVATED                  = 5,
79     POST_ON_DEACTIVATED                = 6,
80     POST_ON_ABORTING                   = 7,
81     POST_ON_ERROR                      = 8,
82     POST_ON_RESET                      = 9,
83     POST_ON_EXECUTE                    = 10,
84     POST_ON_STATE_UPDATE               = 11,
85     POST_ON_RATE_CHANGED               = 12,
86     POST_COMPONENT_ACTION_LISTENER_NUM = 13
87 }
88
89
90 ComponentActionListener.PostComponentActionListener = {}
91
92
93
94
95 ComponentActionListener.PostComponentActionListener.toString = function(_type)
96     local typeString = {"POST_ON_INITIALIZE",
97                         "POST_ON_FINALIZE",
98                         "POST_ON_STARTUP",
99                         "POST_ON_SHUTDOWN",
100                         "POST_ON_ACTIVATED",
101                         "POST_ON_DEACTIVATED",
102                         "POST_ON_ABORTING",
103                         "POST_ON_ERROR",
104                         "POST_ON_RESET",
105                         "POST_ON_EXECUTE",
106                         "POST_ON_STATE_UPDATE",
107                         "POST_ON_RATE_CHANGED",
108                         "POST_COMPONENT_ACTION_LISTENER_NUM"}
109
110     if _type < ComponentActionListener.PostComponentActionListenerType.POST_COMPONENT_ACTION_LISTENER_NUM then
111         return typeString[_type]
112     end
113     return ""
114 end
115
116
117 ComponentActionListener.PostComponentActionListener.new = function()
118     local obj = {}
119     function obj:call(ec_id, ret)
120         
121     end
122     local call_func = function(self, ec_id, ret)
123         self:call(ec_id, ret)
124     end
125     setmetatable(obj, {__call=call_func})
126     return obj
127 end
128
129
130
131 ComponentActionListener.PortActionListenerType = {
132     ADD_PORT                 = 1,
133     REMOVE_PORT              = 2,
134     PORT_ACTION_LISTENER_NUM = 3
135 }
136
137 ComponentActionListener.PortActionListener = {}
138
139
140
141
142 ComponentActionListener.PortActionListener.toString = function(_type)
143     local typeString = {"ADD_PORT",
144                         "REMOVE_PORT",
145                         "PORT_ACTION_LISTENER_NUM"}
146
147     if _type < ComponentActionListener.PortActionListenerType.PORT_ACTION_LISTENER_NUM then
148         return typeString[_type]
149     end
150     return ""
151 end
152
153
154 ComponentActionListener.PortActionListener.new = function()
155     local obj = {}
156     function obj:call(pprof)
157         
158     end
159     local call_func = function(self, pprof)
160         self:call(pprof)
161     end
162     setmetatable(obj, {__call=call_func})
163     return obj
164 end
165
166
167
168 ComponentActionListener.ExecutionContextActionListenerType = {
169     EC_ATTACHED            = 1,
170     EC_DETACHED            = 2,
171     EC_ACTION_LISTENER_NUM = 3
172 }
173
174 ComponentActionListener.ExecutionContextActionListener = {}
175
176
177
178
179 ComponentActionListener.ExecutionContextActionListener.toString = function(_type)
180     local typeString = {"EC_ATTACHED",
181                         "EC_DETACHED",
182                         "EC_ACTION_LISTENER_NUM"}
183
184     if _type < ComponentActionListener.ExecutionContextActionListenerType.EC_ACTION_LISTENER_NUM then
185         return typeString[_type]
186     end
187     return ""
188 end
189
190
191 ComponentActionListener.ExecutionContextActionListener.new = function()
192     local obj = {}
193     function obj:call(ec_id)
194         
195     end
196     local call_func = function(self, ec_id)
197         self:call(ec_id)
198     end
199     setmetatable(obj, {__call=call_func})
200     return obj
201 end
202
203
204 local Entry = {}
205 Entry.new = function(listener, autoclean)
206     local obj = {}
207     obj.listener  = listener
208     obj.autoclean = autoclean
209     return obj
210 end
211
212 ComponentActionListener.PreComponentActionListenerHolder = {}
213 ComponentActionListener.PreComponentActionListenerHolder.new = function()
214     local obj = {}
215     obj._listeners = {}
216     function obj:addListener(listener, autoclean)
217         table.insert(self._listeners, Entry.new(listener, autoclean))
218     end
219     function obj:removeListener(listener)
220         for i,_listener in ipairs(self._listeners) do
221             if _listener.listener == listener then
222                 if _listener.autoclean then
223                     table.remove(self._listeners, i)
224                 end
225             end
226         end
227     end
228     function obj:notify(ec_id)
229         for i, listener in ipairs(self._listeners) do
230             listener.listener:call(ec_id)
231         end
232     end
233     return obj
234 end
235
236
237 ComponentActionListener.PostComponentActionListenerHolder = {}
238 ComponentActionListener.PostComponentActionListenerHolder.new = function()
239     local obj = {}
240     obj._listeners = {}
241     function obj:addListener(listener, autoclean)
242         table.insert(self._listeners, Entry.new(listener, autoclean))
243     end
244     function obj:removeListener(listener)
245         for i,_listener in ipairs(self._listeners) do
246             if _listener.listener == listener then
247                 if _listener.autoclean then
248                     table.remove(self._listeners, i)
249                 end
250             end
251         end
252     end
253     function obj:notify(ec_id, ret)
254         for i, listener in ipairs(self._listeners) do
255             listener.listener:call(ec_id, ret)
256         end
257     end
258     return obj
259 end
260
261 ComponentActionListener.PortActionListenerHolder = {}
262 ComponentActionListener.PortActionListenerHolder.new = function()
263     local obj = {}
264     obj._listeners = {}
265     function obj:addListener(listener, autoclean)
266         table.insert(self._listeners, Entry.new(listener, autoclean))
267     end
268     function obj:removeListener(listener)
269         for i,_listener in ipairs(self._listeners) do
270             if _listener.listener == listener then
271                 if _listener.autoclean then
272                     table.remove(self._listeners, i)
273                 end
274             end
275         end
276     end
277     function obj:notify(pprofile)
278         for i, listener in ipairs(self._listeners) do
279             listener.listener:call(pprofile)
280         end
281     end
282     return obj
283 end
284
285
286
287 ComponentActionListener.ExecutionContextActionListenerHolder = {}
288 ComponentActionListener.ExecutionContextActionListenerHolder.new = function()
289     local obj = {}
290     obj._listeners = {}
291     function obj:addListener(listener, autoclean)
292         table.insert(self._listeners, Entry.new(listener, autoclean))
293     end
294     function obj:removeListener(listener)
295         for i,_listener in ipairs(self._listeners) do
296             if _listener.listener == listener then
297                 if _listener.autoclean then
298                     table.remove(self._listeners, i)
299                 end
300             end
301         end
302     end
303     function obj:notify(ec_id)
304         for i, listener in ipairs(self._listeners) do
305             listener.listener:call(ec_id)
306         end
307     end
308     return obj
309 end
310
311 ComponentActionListener.ComponentActionListeners = {}
312 ComponentActionListener.ComponentActionListeners.new = function()
313     local obj = {}
314     obj.preaction_num = ComponentActionListener.PreComponentActionListenerType.PRE_COMPONENT_ACTION_LISTENER_NUM
315     obj.preaction_ = {}
316     for i = 1,obj.preaction_num do
317         table.insert(obj.preaction_, ComponentActionListener.PreComponentActionListenerHolder.new())
318     end
319
320     obj.postaction_num = ComponentActionListener.PostComponentActionListenerType.POST_COMPONENT_ACTION_LISTENER_NUM
321     obj.postaction_ = {}
322     for i = 1,obj.postaction_num do
323         table.insert(obj.postaction_, ComponentActionListener.PostComponentActionListenerHolder.new())
324     end
325
326     obj.portaction_num = ComponentActionListener.PortActionListenerType.PORT_ACTION_LISTENER_NUM
327     obj.portaction_ = {}
328     for i = 1,obj.portaction_num do
329         table.insert(obj.portaction_, ComponentActionListener.PortActionListenerHolder.new())
330     end
331
332     obj.ecaction_num = ComponentActionListener.ExecutionContextActionListenerType.EC_ACTION_LISTENER_NUM
333     obj.ecaction_ = {}
334     for i = 1,obj.ecaction_num do
335         table.insert(obj.ecaction_, ComponentActionListener.ExecutionContextActionListenerHolder.new())
336     end
337     
338     return obj
339 end
340
341
342 return ComponentActionListener

File lua\openrtm\ConfigAdmin.lua

1 ---------------------------------
2 --! @file ConfigAdmin.lua
3 --! @brief コンフィギュレーション管理クラス定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local ConfigAdmin= {}
11 --_G["openrtm.ConfigAdmin"] = ConfigAdmin
12
13 local Properties = require "openrtm.Properties"
14 local ConfigurationListener = require "openrtm.ConfigurationListener"
15 local ConfigurationListeners = ConfigurationListener.ConfigurationListeners
16 local StringUtil = require "openrtm.StringUtil"
17
18 local ConfigurationParamListenerType = ConfigurationListener.ConfigurationParamListenerType
19 local ConfigurationSetListenerType = ConfigurationListener.ConfigurationSetListenerType
20 local ConfigurationSetNameListenerType = ConfigurationListener.ConfigurationSetNameListenerType
21
22
23 local Config = {}
24 -- コンフィギュレーションパラメータ管理オブジェクト初期化
25 -- 変換関数には以下の関数を使用する
26 -- ret, value = trans(type, str)
27 -- @param name 名前
28 -- @param var 変数
29 -- @param def_val デフォルト値
30 -- @param trans 変換関数
31 -- @return コンフィギュレーションパラメータ管理オブジェクト
32 Config.new = function(name, var, def_val, trans)
33     local obj = {}
34     obj.name = name
35     obj.default_value = def_val
36     obj.string_value = ""
37     obj.callback = nil
38     obj._var = var
39     if trans ~= nil then
40         obj._trans = trans
41     else
42         obj._trans = StringUtil.stringTo
43     end
44     -- コールバック関数設定
45     -- @param cbf コールバック関数
46     function obj:setCallback(cbf)
47         self.callback = cbf
48     end
49     -- パラメータ更新の通知
50     -- @param key キー
51     -- @param val 値
52     function obj:notifyUpdate(key, val)
53         self.callback(key, val)
54     end
55     -- パラメータの更新
56     -- @param key 値
57     -- @return true:更新成功・更新済み、false:更新失敗
58     -- 変換関数がfalseを返した場合は更新失敗
59     function obj:update(val)
60         if self.string_value == val then
61             return true
62         end
63         
64         self.string_value = val
65
66
67         local ret, value = self._trans(self._var._value, val)
68         if ret then
69             self._var._value = value
70             self:notifyUpdate(self.name, val)
71             return true
72         end
73         local ret, value = self._trans(self._var._value, self.default_value)
74         self._var._value = value
75         self:notifyUpdate(self.name, val)
76         return false
77     end
78
79
80     return obj
81 end
82
83 -- コンフィギュレーション管理オブジェクト初期化
84 -- @return コンフィギュレーション管理オブジェクト
85 ConfigAdmin.new = function(configsets)
86     local obj = {}
87     obj._configsets = configsets
88     obj._activeId   = "default"
89     obj._active     = true
90     obj._changed    = false
91     obj._params     = {}
92     obj._emptyconf  = Properties.new()
93     obj._newConfig  = {}
94     obj._listeners  = ConfigurationListeners.new()
95     obj._changedParam = {}
96
97     -- 変数をコンフィギュレーションパラメータ設定に割り当てる
98     -- @param param_name パラメータ名
99     -- @param var 変数
100     -- @param def_val デフォルト値
101     -- @param trans 変換関数(デフォルトはstringTo関数)
102     -- @return true:バインド成功、false:バインド失敗
103     function obj:bindParameter(param_name, var, def_val, trans)
104         if trans == nil then
105             trans = StringUtil.stringTo
106         end
107
108         if param_name == "" or def_val == "" then
109             return false
110         end
111
112         --print(self:isExist(param_name))
113         if self:isExist(param_name) then
114             return false
115         end
116
117         local ret, value = trans(var._value, def_val)
118         --if type(value) == "table" then
119         -- print(#value)
120         --end
121         var._value = value
122         if not ret then
123             return false
124         end
125         local conf_ = Config.new(param_name, var, def_val, trans)
126         table.insert(self._params, conf_)
127         --print(#self._params)
128         conf_:setCallback(function(config_param, config_value)self:onUpdateParam(config_param, config_value) end)
129         --print(self:getActiveId())
130         self:update(self:getActiveId(), param_name)
131
132         return true
133     end
134
135     -- パラメータ削除
136     -- @param param_name パラメータ名
137     -- @return true:削除成功、false:削除失敗
138     function obj:unbindParameter(param_name)
139         local ret_param = nil
140         local ret_index = -1
141         for find_idx, param in ipairs(self._params) do
142             if param.name == param_name then
143                 ret_param = param
144                 ret_index = find_idx
145             end
146         end
147
148         if ret_index == -1 then
149             return false
150         end
151
152         table.remove(self._params, ret_index)
153
154
155         local leaf = self._configsets:getLeaf()
156         for i, v in ipairs(leaf) do
157             if v:hasKey(param_name) then
158                 v:removeNode(param_name)
159             end
160         end
161
162         return true
163     end
164
165     -- コンフィギュレーションセットの存在確認
166     -- @param config_id コンフィギュレーションセットID
167     -- @return true:存在する、false:存在する
168     function obj:haveConfig(config_id)
169         if self._configsets:hasKey(config_id) == nil then
170             return false
171         else
172             return true
173         end
174     end
175     -- コンフィギュレーションセットのアクティブ化
176     -- "_"から始まるIDは指定できない
177     -- @param config_id コンフィギュレーションセットID
178     -- @return true:アクティブ化成功、false:アクティブ化失敗
179     function obj:activateConfigurationSet(config_id)
180         if config_id == "" then
181             return false
182         end
183         if string.sub(config_id,1,1) == '_' then
184             return false
185         end
186         if not self._configsets:hasKey(config_id) then
187             return false
188         end
189         self._activeId = config_id
190         self._active   = true
191         self._changed  = true
192         self:onActivateSet(config_id)
193         return true
194     end
195     -- コンフィギュレーションセットアクティブ化時のコールバック呼び出し
196     -- @param config_id コンフィギュレーションセットID
197     function obj:onActivateSet(config_id)
198         self._listeners.configsetname_[ConfigurationSetNameListenerType.ON_ACTIVATE_CONFIG_SET]:notify(config_id)
199     end
200     -- コンフィギュレーションパラメータ更新
201     -- ID指定の場合は、指定IDのコンフィギュレーションセットの更新
202     -- パラメータ、ID指定の場合は、指定パラメータの更新
203     -- パラメータ、ID未指定の場合は、現在アクティブなコンフィギュレーションセット更新
204     -- @param config_set コンフィギュレーションセットID
205     -- @param config_param パラメータ名
206     function obj:update(config_set, config_param)
207
208         if config_set ~= nil and config_param == nil then
209             if self._configsets:hasKey(config_set) == false then
210                 return
211             end
212             self._changedParam = {}
213             local prop = self._configsets:getNode(config_set)
214             for i, param in ipairs(self._params) do
215                 if prop:hasKey(param.name) then
216                     --print(type(param.name))
217                     --print(prop:getProperty(param.name))
218                     param:update(prop:getProperty(param.name))
219                 end
220             end
221             self:onUpdate(config_set)
222         end
223
224
225         if config_set ~= nil and config_param ~= nil then
226             self._changedParam = {}
227             local key = config_set
228             key = key.."."..config_param
229             for i, conf in ipairs(self._params) do
230                 --print(conf.name, config_param)
231                 if conf.name == config_param then
232                     --print(self._configsets:getProperty(key))
233                     conf:update(self._configsets:getProperty(key))
234                 end
235             end
236         end
237
238         if config_set == nil and config_param == nil then
239             self._changedParam = {}
240             if self._changed and self._active then
241                 self:update(self._activeId)
242                 self._changed = false
243             end
244         end
245
246     end
247
248     -- パラメータの存在確認
249     -- @param param_name パラメータ名
250     -- @return true:存在する、false:存在しない
251     function obj:isExist(param_name)
252         if #self._params == 0 then
253             return false
254         end
255
256         for i, conf in ipairs(self._params) do
257             if conf.name == param_name then
258                 return true
259             end
260         end
261
262         return false
263     end
264
265     -- コンフィギュレーションパラメータに変更があったかの確認
266     -- @return true:変更あり、false:変更なし
267     function obj:isChanged()
268         return self._changed
269     end
270
271     -- 変更のあったコンフィギュレーションパラメータを取得
272     -- 更新したコンフィギュレーションパラメータは
273     -- @return 変更のあったコンフィギュレーションパラメータ一覧
274     function obj:changedParameters()
275         return self._changedParam
276     end
277
278     -- アクティブなコンフィギュレーションセットID取得
279     -- @return アクティブなコンフィギュレーションセットID
280     function obj:getActiveId()
281         return self._activeId
282     end
283
284
285
286
287     -- コンフィギュレーション管理オブジェクトがアクティブかを確認
288     -- return true:アクティブ、false:非アクティブ
289     function obj:isActive()
290         return self._active
291     end
292
293     -- コンフィギュレーションセット一覧取得
294     -- return コンフィギュレーションセット一覧
295     function obj:getConfigurationSets()
296         return self._configsets:getLeaf()
297     end
298
299     -- コンフィギュレーションセット取得
300     -- @param config_id コンフィギュレーションセットID
301     -- @return コンフィギュレーションセット
302     function obj:getConfigurationSet(config_id)
303
304         local prop = self._configsets:findNode(config_id)
305         if prop == nil then
306             return self._emptyconf
307         end
308         return prop
309     end
310
311     -- コンフィギュレーションセットの設定
312     -- 指定コンフィギュレーションセットがない場合に、新規にノードは生成しない
313     -- @param config_set コンフィギュレーションセット
314     -- @return true:設定成功、false:設定失敗
315     function obj:setConfigurationSetValues(config_set)
316         local node_ = config_set:getName()
317         if node_ == "" or node_ == nil then
318             return false
319         end
320
321         if not self._configsets:hasKey(node_) then
322             return false
323         end
324
325         local p = self._configsets:getNode(node_)
326
327
328         p:mergeProperties(config_set)
329         self._changed = true
330         self._active  = false
331         self:onSetConfigurationSet(config_set)
332         return true
333     end
334
335     -- アクティブなコンフィギュレーションセット取得
336     -- @return アクティブなコンフィギュレーションセット
337     function obj:getActiveConfigurationSet()
338         local p = self._configsets:getNode(self._activeId)
339
340
341         return p
342     end
343
344     -- コンフィギュレーションセット追加
345     -- 指定コンフィギュレーションセットがない場合に、新規にノードを生成する
346     -- @param configset コンフィギュレーションセット
347     -- @return true:追加成功、false:追加失敗
348     function obj:addConfigurationSet(configset)
349         if self._configsets:hasKey(configset:getName()) then
350             return false
351         end
352         local node = configset:getName()
353
354
355         self._configsets:createNode(node)
356
357         local p = self._configsets:getNode(node)
358
359
360         p:mergeProperties(configset)
361         table.insert(self._newConfig, node)
362
363         self._changed = true
364         self._active  = false
365         self:onAddConfigurationSet(configset)
366         return true
367     end
368
369     -- コンフィギュレーションセット削除
370     -- @param config_id コンフィギュレーションセットID
371     -- @return true:削除成功、false:削除失敗
372     function obj:removeConfigurationSet(config_id)
373         if config_id == "default" then
374             return false
375         end
376         if self._activeId == config_id then
377             return false
378         end
379
380         local find_flg = false
381
382         local ret_idx = -1
383         for idx, conf in ipairs(self._newConfig) do
384             if conf == config_id then
385                 ret_idx = idx
386                 break
387             end
388         end
389
390
391         if ret_idx == -1 then
392             return false
393         end
394
395         local p = self._configsets:getNode(config_id)
396         if p ~= nil then
397             p:getRoot():removeNode(config_id)
398         end
399
400         table.remove(self._newConfig, ret_idx)
401
402
403
404         self._changed = true
405         self._active  = false
406         self:onRemoveConfigurationSet(config_id)
407         return true
408     end
409
410
411
412     -- コンフィギュレーション更新時コールバック設定
413     -- @param cb コンフィギュレーションコールバック
414     function obj:setOnUpdate(cb)
415         print("setOnUpdate function is obsolete.")
416         print("Use addConfigurationSetNameListener instead.")
417         self._listeners.configsetname_[ConfigurationSetNameListenerType.ON_UPDATE_CONFIG_SET]:addListener(cb, false)
418     end
419
420     -- コンフィギュレーションパラメータ更新時コールバック設定
421     -- @param cb コンフィギュレーションパラメータコールバック
422     function obj:setOnUpdateParam(cb)
423         print("setOnUpdateParam function is obsolete.")
424         print("Use addConfigurationParamListener instead.")
425         self._listeners.configparam_[ConfigurationParamListenerType.ON_UPDATE_CONFIG_PARAM]:addListener(cb, false)
426     end
427
428     -- コンフィギュレーションセット設定時コールバック設定
429     -- @param cb コンフィギュレーションセット設定時コールバック
430     function obj:setOnSetConfigurationSet(cb)
431         print("setOnSetConfigurationSet function is obsolete.")
432         print("Use addConfigurationSetListener instead.")
433         self._listeners.configset_[ConfigurationSetListenerType.ON_SET_CONFIG_SET]:addListener(cb, false)
434     end
435
436     -- コンフィギュレーションセット追加時コールバック設定
437     -- @param cb コンフィギュレーションセット追加時コールバック
438     function obj:setOnAddConfigurationSet(cb)
439         print("setOnAddConfigurationSet function is obsolete.")
440         print("Use addConfigurationSetListener instead.")
441         self._listeners.configset_[ConfigurationSetListenerType.ON_ADD_CONFIG_SET]:addListener(cb, false)
442     end
443
444     -- コンフィギュレーションセット削除時コールバック設定
445     -- @param cb コンフィギュレーションセット削除時コールバック
446     function obj:setOnRemoveConfigurationSet(cb)
447         print("setOnRemoveConfigurationSet function is obsolete.")
448         print("Use addConfigurationSetNameListener instead.")
449         self._listeners.configsetname_[ConfigurationSetNameListenerType.ON_REMOVE_CONFIG_SET]:addListener(cb, False)
450     end
451
452     -- アクティブなコンフィギュレーションセット設定時コールバック設定
453     -- @param cb アクティブなコンフィギュレーションセット設定時コールバック
454     function obj:setOnActivateSet(cb)
455         print("setOnActivateSet function is obsolete.")
456         print("Use addConfigurationSetNameListener instead.")
457         self._listeners.configsetname_[ConfigurationSetNameListenerType.ON_ACTIVATE_CONFIG_SET]:addListener(cb, false)
458     end
459
460     -- コンフィギュレーションパラメータコールバック設定
461     -- @param _type コールバックの種別
462     -- @param listener コンフィギュレーションパラメータコールバック
463     -- @param autoclean 自動削除フラグ
464     function obj:addConfigurationParamListener(_type, listener, autoclean)
465         if autoclean == nil then
466             autoclean = true
467         end
468         self._listeners.configparam_[_type]:addListener(listener, autoclean)
469     end
470
471     -- コンフィギュレーションパラメータコールバック削除
472     -- @param _type コールバックの種別
473     -- @param listener コンフィギュレーションパラメータコールバック
474     function obj:removeConfigurationParamListener(_type, listener)
475         self._listeners.configparam_[_type]:removeListener(listener)
476     end
477
478     -- コンフィギュレーションセットコールバック設定
479     -- @param _type コールバックの種別
480     -- @param listener コンフィギュレーションセットコールバック
481     -- @param autoclean 自動削除フラグ
482     function obj:addConfigurationSetListener(_type, listener, autoclean)
483         if autoclean == nil then
484             autoclean = true
485         end
486         self._listeners.configset_[_type]:addListener(listener, autoclean)
487     end
488
489     -- コンフィギュレーションセットコールバック削除
490     -- @param _type コールバックの種別
491     -- @param listener コンフィギュレーションセットコールバック
492     function obj:removeConfigurationSetListener(_type, listener)
493         self._listeners.configset_[_type]:removeListener(listener)
494     end
495
496     -- コンフィギュレーションセット名のコールバック設定
497     -- @param _type コールバックの種別
498     -- @param listener コンフィギュレーションセット名のコールバック設定
499     -- @param autoclean 自動削除フラグ
500     function obj:addConfigurationSetNameListener(_type, listener, autoclean)
501         if autoclean == nil then
502             autoclean = true
503         end
504         self._listeners.configsetname_[_type]:addListener(listener, autoclean)
505     end
506
507     -- コンフィギュレーションセット名のコールバック削除
508     -- @param _type コールバックの種別
509     -- @param listener コンフィギュレーションセット名のコールバック
510     function obj:removeConfigurationSetNameListener(_type, listener)
511         self._listeners.configsetname_[_type]:removeListener(listener)
512     end
513
514     -- コンフィギュレーション更新時コールバック呼び出し
515     -- @param config_set コンフィギュレーションセット
516     function obj:onUpdate(config_set)
517         self._listeners.configsetname_[ConfigurationSetNameListenerType.ON_UPDATE_CONFIG_SET]:notify(config_set)
518     end
519
520     -- コンフィギュレーションパラメータ更新時コールバック呼び出し
521     -- @param config_param パラメータ名
522     -- @param config_value 値
523     function obj:onUpdateParam(config_param, config_value)
524         table.insert(self._changedParam, config_param)
525         self._listeners.configparam_[ConfigurationParamListenerType.ON_UPDATE_CONFIG_PARAM]:notify(config_param, config_value)
526     end
527
528     -- コンフィギュレーション設定時コールバック呼び出し
529     -- @param config_set コンフィギュレーションセット
530     function obj:onSetConfigurationSet(config_set)
531         self._listeners.configset_[ConfigurationSetListenerType.ON_SET_CONFIG_SET]:notify(config_set)
532     end
533
534     -- コンフィギュレーション追加時コールバック呼び出し
535     -- @param config_set コンフィギュレーションセット
536     function obj:onAddConfigurationSet(config_set)
537         self._listeners.configset_[ConfigurationSetListenerType.ON_ADD_CONFIG_SET]:notify(config_set)
538     end
539     -- コンフィギュレーション削除時コールバック呼び出し
540     -- @param config_id コンフィギュレーションセットID
541     function obj:onRemoveConfigurationSet(config_id)
542         self._listeners.configsetname_[ConfigurationSetNameListenerType.ON_REMOVE_CONFIG_SET]:notify(config_id)
543     end
544
545     -- コンフィギュレーションアクティブ化時コールバック呼び出し
546     -- @param config_id コンフィギュレーションセットID
547     function obj:onActivateSet(config_id)
548         self._listeners.configsetname_[ConfigurationSetNameListenerType.ON_ACTIVATE_CONFIG_SET]:notify(config_id)
549     end
550
551
552     
553     return obj
554 end
555
556
557 return ConfigAdmin

File lua\openrtm\ConfigurationListener.lua

1 ---------------------------------
2 --! @file ConfigurationListener.lua
3 --! @brief コンフィギュレーションコールバック定義クラス
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local ConfigurationListener= {}
11 --_G["openrtm.ConfigurationListener"] = ConfigurationListener
12
13 ConfigurationListener.ConfigurationParamListenerType = {
14     ON_UPDATE_CONFIG_PARAM      = 1,
15     CONFIG_PARAM_LISTENER_NUM   = 2
16 }
17
18
19 ConfigurationListener.ConfigurationParamListener = {}
20
21
22
23
24 ConfigurationListener.ConfigurationParamListener.toString = function(_type)
25     local typeString = {"ON_UPDATE_CONFIG_PARAM",
26                         "CONFIG_PARAM_LISTENER_NUM"}
27
28     if _type < ConfigurationListener.ConfigurationParamListenerType.CONFIG_PARAM_LISTENER_NUM then
29         return typeString[_type]
30     end
31     return ""
32 end
33
34
35 ConfigurationListener.ConfigurationParamListener.new = function()
36     local obj = {}
37     function obj:call(config_set_name, config_param_name)
38         
39     end
40
41
42     local call_func = function(self, config_set_name, config_param_name)
43         self:call(config_set_name, config_param_name)
44     end
45     setmetatable(obj, {__call=call_func})
46     return obj
47 end
48
49
50
51
52
53 ConfigurationListener.ConfigurationSetListenerType = {
54     ON_SET_CONFIG_SET       = 1,
55     ON_ADD_CONFIG_SET       = 2,
56     CONFIG_SET_LISTENER_NUM = 3
57 }
58
59
60 ConfigurationListener.ConfigurationSetListener = {}
61
62
63
64
65 ConfigurationListener.ConfigurationSetListener.toString = function(_type)
66     local typeString = {"ON_SET_CONFIG_SET",
67                         "ON_ADD_CONFIG_SET",
68                         "CONFIG_SET_LISTENER_NUM"}
69
70     if _type < ConfigurationListener.ConfigurationSetListenerType.CONFIG_SET_LISTENER_NUM then
71         return typeString[_type]
72     end
73     return ""
74 end
75
76
77 ConfigurationListener.ConfigurationSetListener.new = function()
78     local obj = {}
79     function obj:call(config_set)
80         
81     end
82
83
84     local call_func = function(self, config_set)
85         self:call(config_set)
86     end
87     setmetatable(obj, {__call=call_func})
88     return obj
89 end
90
91
92
93
94
95 ConfigurationListener.ConfigurationSetNameListenerType = {
96     ON_UPDATE_CONFIG_SET         = 1,
97     ON_REMOVE_CONFIG_SET         = 2,
98     ON_ACTIVATE_CONFIG_SET       = 3,
99     CONFIG_SET_NAME_LISTENER_NUM = 4
100 }
101
102
103 ConfigurationListener.ConfigurationSetNameListener = {}
104
105
106
107
108 ConfigurationListener.ConfigurationSetNameListener.toString = function(_type)
109     local typeString = {"ON_UPDATE_CONFIG_SET",
110                         "ON_REMOVE_CONFIG_SET",
111                         "ON_ACTIVATE_CONFIG_SET",
112                         "CONFIG_SET_NAME_LISTENER_NUM"}
113
114     if _type < ConfigurationListener.ConfigurationSetNameListenerType.CONFIG_SET_NAME_LISTENER_NUM then
115         return typeString[_type]
116     end
117     return ""
118 end
119
120
121 ConfigurationListener.ConfigurationSetNameListener.new = function()
122     local obj = {}
123     function obj:call(config_set_name)
124         
125     end
126
127
128     local call_func = function(self, config_set_name)
129         self:call(config_set_name)
130     end
131     setmetatable(obj, {__call=call_func})
132     return obj
133 end
134
135
136
137 local Entry = {}
138 Entry.new = function(listener, autoclean)
139     local obj = {}
140     obj.listener  = listener
141     obj.autoclean = autoclean
142     return obj
143 end
144
145
146
147 ConfigurationListener.ConfigurationParamListenerHolder = {}
148 ConfigurationListener.ConfigurationParamListenerHolder.new = function()
149     local obj = {}
150     obj._listeners = {}
151     function obj:addListener(listener, autoclean)
152         table.insert(self._listeners, Entry.new(listener, autoclean))
153     end
154     function obj:removeListener(listener)
155         for i,_listener in ipairs(self._listeners) do
156             if _listener.listener == listener then
157                 if _listener.autoclean then
158                     table.remove(self._listeners, i)
159                 end
160             end
161         end
162     end
163     function obj:notify(config_set_name, config_param_name)
164         for i, listener in ipairs(self._listeners) do
165             listener.listener:call(config_set_name, config_param_name)
166         end
167         
168     end
169     return obj
170 end
171
172
173
174 ConfigurationListener.ConfigurationSetListenerHolder = {}
175 ConfigurationListener.ConfigurationSetListenerHolder.new = function()
176     local obj = {}
177     obj._listeners = {}
178     function obj:addListener(listener, autoclean)
179         table.insert(self._listeners, Entry.new(listener, autoclean))
180     end
181     function obj:removeListener(listener)
182         for i,_listener in ipairs(self._listeners) do
183             if _listener.listener == listener then
184                 if _listener.autoclean then
185                     table.remove(self._listeners, i)
186                 end
187             end
188         end
189     end
190     function obj:notify(config_set)
191         for i, listener in ipairs(self._listeners) do
192             listener.listener:call(config_set)
193         end
194         
195     end
196     
197     return obj
198 end
199
200
201
202
203 ConfigurationListener.ConfigurationSetNameListenerHolder = {}
204 ConfigurationListener.ConfigurationSetNameListenerHolder.new = function()
205     local obj = {}
206     obj._listeners = {}
207     function obj:addListener(listener, autoclean)
208         table.insert(self._listeners, Entry.new(listener, autoclean))
209     end
210     function obj:removeListener(listener)
211         for i,_listener in ipairs(self._listeners) do
212             if _listener.listener == listener then
213                 if _listener.autoclean then
214                     table.remove(self._listeners, i)
215                 end
216             end
217         end
218     end
219     function obj:notify(config_set_name)
220         for i, listener in ipairs(self._listeners) do
221             listener.listener:call(config_set_name)
222         end
223         
224     end
225     
226     return obj
227 end
228
229
230 ConfigurationListener.ConfigurationListeners = {}
231 ConfigurationListener.ConfigurationListeners.new = function()
232     local obj = {}
233     obj.configparam_num = ConfigurationListener.ConfigurationParamListenerType.CONFIG_PARAM_LISTENER_NUM
234     obj.configparam_ = {}
235     for i = 1,obj.configparam_num do
236         table.insert(obj.configparam_, ConfigurationListener.ConfigurationParamListenerHolder.new())
237     end
238     obj.configset_num = ConfigurationListener.ConfigurationSetListenerType.CONFIG_SET_LISTENER_NUM
239     obj.configset_ = {}
240     for i = 1,obj.configset_num do
241         table.insert(obj.configset_, ConfigurationListener.ConfigurationSetListenerHolder.new())
242     end
243     obj.configsetname_num = ConfigurationListener.ConfigurationSetNameListenerType.CONFIG_SET_NAME_LISTENER_NUM
244     obj.configsetname_ = {}
245     for i = 1,obj.configsetname_num do
246         table.insert(obj.configsetname_, ConfigurationListener.ConfigurationSetNameListenerHolder.new())
247     end
248     return obj
249 end
250
251
252 return ConfigurationListener

File lua\openrtm\ConnectorBase.lua

Full coverage

File lua\openrtm\ConnectorListener.lua

1 ---------------------------------
2 --! @file ConnectorListener.lua
3 --! @brief コネクタコールバック定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local ConnectorListener= {}
11 --_G["openrtm.ConnectorListener"] = ConnectorListener
12
13
14 ConnectorListener.ConnectorListenerStatus = {
15  NO_CHANGE                 = 1,
16  INFO_CHANGED              = 2,
17  DATA_CHANGED              = 3,
18  BOTH_CHANGED              = 4
19 }
20
21
22 ConnectorListener.ConnectorDataListenerType = {
23  ON_BUFFER_WRITE              = 1,
24  ON_BUFFER_FULL               = 2,
25  ON_BUFFER_WRITE_TIMEOUT      = 3,
26  ON_BUFFER_OVERWRITE          = 4,
27  ON_BUFFER_READ               = 5,
28  ON_SEND                      = 6,
29  ON_RECEIVED                  = 7,
30  ON_RECEIVER_FULL             = 8,
31  ON_RECEIVER_TIMEOUT          = 9,
32  ON_RECEIVER_ERROR            = 10,
33  CONNECTOR_DATA_LISTENER_NUM  = 11
34 }
35
36
37
38 ConnectorListener.ConnectorDataListener = {}
39
40
41
42
43 ConnectorListener.ConnectorDataListener.toString = function(_type)
44  local typeString = {"ON_BUFFER_WRITE",
45       "ON_BUFFER_FULL",
46       "ON_BUFFER_WRITE_TIMEOUT",
47       "ON_BUFFER_OVERWRITE",
48       "ON_BUFFER_READ", 
49       "ON_SEND", 
50       "ON_RECEIVED",
51       "ON_RECEIVER_FULL", 
52       "ON_RECEIVER_TIMEOUT", 
53       "ON_RECEIVER_ERROR",
54       "CONNECTOR_DATA_LISTENER_NUM"}
55
56  if _type < ConnectorListener.ConnectorDataListenerType.CONNECTOR_DATA_LISTENER_NUM then
57   return typeString[_type]
58  end
59  return ""
60 end
61
62
63 ConnectorListener.ConnectorDataListener.new = function()
64  local obj = {}
65  function obj:call(info, data)
66   
67  end
68
69  function obj:__call__(info, cdrdata, dataType)
70   local Manager = require "openrtm.Manager"
71   local _data = Manager:instance():cdrUnmarshal(cdrdata, dataType)
72   return _data
73  end
74
75  local call_func = function(self, info, data)
76   self:call(info, data)
77  end
78  setmetatable(obj, {__call=call_func})
79  return obj
80 end
81
82 --[[
83 ConnectorListener.ConnectorDataListenerT = {}
84 ConnectorListener.ConnectorDataListenerT.new = function()
85  local obj = {}
86  function obj:__call__(info, cdrdata, dataType)
87   local Manager = require "openrtm.Manager"
88   local _data = Manager:instance():cdrUnmarshal(cdrdata, dataType)
89   return _data 
90  end
91  local call_func = function(self, info, cdrdata, data)
92   self:call(info, cdrdata, data)
93  end
94  setmetatable(obj, {__call=call_func})
95  return obj
96 end
97 ]]
98
99
100
101 ConnectorListener.ConnectorListenerType = {
102     ON_BUFFER_EMPTY        = 1,
103       ON_BUFFER_READ_TIMEOUT = 2,
104       ON_SENDER_EMPTY        = 3,
105       ON_SENDER_TIMEOUT      = 4,
106       ON_SENDER_ERROR        = 5,
107       ON_CONNECT             = 6,
108       ON_DISCONNECT          = 7,
109       CONNECTOR_LISTENER_NUM = 8
110 }
111
112
113
114 ConnectorListener.ConnectorListener = {}
115
116
117
118
119 ConnectorListener.ConnectorListener.toString = function(_type)
120     local typeString = {"ON_BUFFER_EMPTY",
121                         "ON_BUFFER_READ_TIMEOUT",
122                         "ON_SENDER_EMPTY", 
123                         "ON_SENDER_TIMEOUT", 
124                         "ON_SENDER_ERROR", 
125                         "ON_CONNECT",
126                         "ON_DISCONNECT",
127                         "CONNECTOR_LISTENER_NUM"}
128
129     if _type < ConnectorListener.ConnectorListenerType.CONNECTOR_LISTENER_NUM then
130         return typeString[_type]
131     end
132     return ""
133 end
134
135
136 ConnectorListener.ConnectorListener.new = function()
137     local obj = {}
138     function obj:call(info)
139         
140     end
141     local call_func = function(self, info)
142         self:call(info)
143     end
144     setmetatable(obj, {__call=call_func})
145     return obj
146 end
147
148
149 local Entry = {}
150 Entry.new = function(listener, autoclean)
151     local obj = {}
152     obj.listener  = listener
153     obj.autoclean = autoclean
154     return obj
155 end
156
157 ConnectorListener.ConnectorDataListenerHolder = {}
158 ConnectorListener.ConnectorDataListenerHolder.new = function()
159     local obj = {}
160     obj._listeners = {}
161     function obj:addListener(listener, autoclean)
162         table.insert(self._listeners, Entry.new(listener, autoclean))
163     end
164     function obj:removeListener(listener)
165         for i,_listener in ipairs(self._listeners) do
166             if _listener.listener == listener then
167                 if _listener.autoclean then
168                     table.remove(self._listeners, i)
169                 end
170             end
171         end
172     end
173     function obj:notify(info, cdrdata)
174         --print(cdrdata)
175         local ret = ConnectorListener.ConnectorListenerStatus.NO_CHANGE
176         for i, listener in ipairs(self._listeners) do
177             ret = listener.listener:call(info, cdrdata)
178         end
179         return ret
180     end
181     return obj
182 end
183
184
185
186 ConnectorListener.ConnectorListenerHolder = {}
187 ConnectorListener.ConnectorListenerHolder.new = function()
188     local obj = {}
189     obj._listeners = {}
190     function obj:addListener(listener, autoclean)
191         table.insert(self._listeners, Entry.new(listener, autoclean))
192     end
193     function obj:removeListener(listener)
194         for i,_listener in ipairs(self._listeners) do
195             if _listener.listener == listener then
196                 if _listener.autoclean then
197                     table.remove(self._listeners, i)
198                 end
199             end
200         end
201     end
202     function obj:notify(info)
203         local ret = ConnectorListener.ConnectorListenerStatus.NO_CHANGE
204         for i, listener in ipairs(self._listeners) do
205             ret = listener.listener:call(info)
206         end
207         return ret
208     end
209     return obj
210 end
211
212
213 ConnectorListener.ConnectorListeners = {}
214
215 ConnectorListener.ConnectorListeners.new = function()
216     local obj = {}
217     obj.connector_num = ConnectorListener.ConnectorDataListenerType.CONNECTOR_DATA_LISTENER_NUM
218     obj.connectorData_ = {}
219     for i = 1,obj.connector_num do
220         table.insert(obj.connectorData_, ConnectorListener.ConnectorDataListenerHolder.new())
221     end
222     obj.connector_num = ConnectorListener.ConnectorListenerType.CONNECTOR_LISTENER_NUM
223     obj.connector_ = {}
224     for i = 1,obj.connector_num do
225         table.insert(obj.connector_, ConnectorListener.ConnectorListenerHolder.new())
226     end
227     return obj
228 end
229
230
231 return ConnectorListener

File lua\openrtm\CorbaConsumer.lua

1 ---------------------------------
2 --! @file CorbaConsumer.lua
3 --! @brief CORBAコンシューマ定義クラス
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local CorbaConsumer= {}
11 --_G["openrtm.CorbaConsumer"] = CorbaConsumer
12
13
14 local oil = require "oil"
15 local RTCUtil = require "openrtm.RTCUtil"
16
17
18 CorbaConsumer.CorbaConsumerBase = {}
19
20 -- CORBAコンシューマオブジェクト初期化関数
21 -- @param consumer CORBAコンシューマオブジェクト
22 -- @return CORBAコンシューマオブジェクト
23 CorbaConsumer.CorbaConsumerBase.new = function(consumer)
24     local obj = {}
25
26     if consumer ~= nil then
27         obj._objref = consumer._objref
28     else
29         obj._objref = oil.corba.idl.null
30     end
31     
32     -- オブジェクトリファレンス設定
33     -- @param _obj オブジェクトリファレンス
34     -- @return true:設定成功、false:設定失敗
35     function obj:setObject(_obj)
36         return self:_setObject(_obj)
37     end
38     -- オブジェクトリファレンス設定
39     -- @param _obj オブジェクトリファレンス
40     -- @return true:設定成功、false:設定失敗
41     function obj:_setObject(_obj)
42
43         if _obj == nil then
44             return false
45         end
46
47         self._objref = _obj
48         
49         return true
50     end
51
52     -- オブジェクトリファレンス取得
53     -- @return オブジェクトリファレンス
54     function obj:getObject()
55         --print(self._objref)
56         return self._objref
57     end
58
59     -- オブジェクトリファレンスをnullに設定する
60     function obj:releaseObject()
61         self:_releaseObject()
62     end
63     -- オブジェクトリファレンスをnullに設定する
64     function obj:_releaseObject()
65         self._objref = oil.corba.idl.null
66     end
67
68     return obj
69 end
70
71 -- CORBAコンシューマオブジェクト初期化関数
72 -- @param interfaceType インターフェース型
73 -- @param consumer CORBAコンシューマオブジェクト
74 -- @return CORBAコンシューマオブジェクト
75 CorbaConsumer.new = function(interfaceType, consumer)
76     local obj = {}
77     obj._interfaceType = interfaceType
78     setmetatable(obj, {__index=CorbaConsumer.CorbaConsumerBase.new(consumer)})
79     if consumer ~= nil then
80         obj._var = consumer._var
81     end
82     -- オブジェクトリファレンス設定
83     -- @param _obj オブジェクトリファレンス
84     -- @return true:設定成功、false:設定失敗
85     function obj:setObject(_obj)
86
87         if not self:_setObject(_obj) then
88             self:releaseObject()
89             return false
90         end
91
92         self._var = self._objref
93         return true
94     end
95     -- オブジェクトリファレンス取得
96     -- 同一プロセスの場合はサーバント取得
97     -- @param get_ref trueの場合にはサーバント取得可能でもオブジェクトリファレンスを取得
98     -- @return オブジェクトリファレンス、もしくはサーバント
99     function obj:_ptr(get_ref)
100         if get_ref == nil then
101             get_ref = false
102         end
103         return self._var
104     end
105     -- IOR文字列からオブジェクトリファレンスを設定
106     -- 設定したインターフェース型に変換する
107     -- @param ior IOR文字列
108     -- @return true:設定成功、false:設定失敗
109     function obj:setIOR(ior)
110         local ret = true
111         local success, exception = oil.pcall(
112             function()
113                 --print(ior)
114                 --print(self._interfaceType)
115                 local Manager = require "openrtm.Manager"
116                 local orb = Manager:instance():getORB()
117                 local obj_ = RTCUtil.newproxy(orb, ior,self._interfaceType)
118                 if not self:_setObject(obj_) then
119                     self:releaseObject()
120                     ret = false
121                 end
122                 self._var = self._objref
123             end)
124         if not success then
125             print(exception)
126             return false
127         end
128
129
130         return ret
131     end
132
133     -- オブジェクトリファレンスにnullを設定する
134     function obj:releaseObject()
135         self:_releaseObject(self)
136         self._var = oil.corba.idl.null
137         self._sev = nil
138     end
139     return obj
140 end
141
142
143 return CorbaConsumer

File lua\openrtm\CorbaNaming.lua

1 ---------------------------------
2 --! @file CorbaNaming.lua
3 --! @brief ネームサーバーヘルパクラス定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local CorbaNaming= {}
11 --_G["openrtm.CorbaNaming"] = CorbaNaming
12
13 local oil = require "oil"
14 local StringUtil = require "openrtm.StringUtil"
15 local RTCUtil = require "openrtm.RTCUtil"
16
17
18 -- ネームサーバーヘルパオブジェクト初期化
19 -- @param orb ORBオブジェクト
20 -- @param name_server ネームサーバーのアドレス(例:localhost:2809)
21 -- @return ネームサーバヘルパオブジェクト
22 CorbaNaming.new = function(orb, name_server)
23     local obj = {}
24     obj._orb = orb
25     obj._nameServer = ""
26     obj._rootContext = oil.corba.idl.null
27     obj._blLength = 100
28
29     if name_server ~= nil then
30         obj._nameServer = "corbaloc:iiop:"..name_server.."/NameService"
31         --print(obj._nameServer)
32         local success, exception = oil.pcall(
33             function()
34                 obj._rootContext = RTCUtil.newproxy(obj._orb, obj._nameServer,"IDL:omg.org/CosNaming/NamingContext:1.0")
35                 --print(self._rootContext)
36                 --if self._rootContext == nil then
37                 -- print("CorbaNaming: Failed to narrow the root naming context.")
38                 --end
39             end)
40         if not success then
41             print(exception)
42         end
43     end
44     -- ネームサーバーにオブジェクトを登録
45     -- 登録パスは以下のように設定する
46     -- test1.host_cxt/test2.rtc
47     -- @param string_name 登録パス(文字列)
48     -- @param obj オブジェクトリファレンス
49     -- @param force trueの場合には同じパスに登録済みの場合でも強制的に上書きする
50     function obj:rebindByString(string_name, obj, force)
51         if force == nil then
52             force = true
53         end
54         --print(self:toName(string_name))
55         self:rebind(self:toName(string_name), obj, force)
56     end
57     -- ネームサーバーにオブジェクトを登録
58     -- Nameリストは以下のように指定
59     -- {{id="id1",kind="kind1"},...}
60     -- @param name_list 登録パス(Nameリスト)
61     -- @param obj オブジェクトリファレンス
62     -- @param force trueの場合には同じパスに登録済みの場合でも強制的に上書きする
63     function obj:rebind(name_list, obj, force)
64         if force == nil then
65             force = true
66         end
67         local success, exception = oil.pcall(
68             function()
69                 --error("")
70                 self._rootContext:rebind(name_list, obj)
71             end)
72         if not success then
73             --print(exception)
74             if force then
75                 --print("test1")
76                 self:rebindRecursive(self._rootContext, name_list, obj)
77                 --print("test2")
78             else
79                 print(exception)
80                 error(exception)
81             end
82         end
83     end
84     -- ネームサーバーにオブジェクトを登録する
85     -- 指定パスのコンテキストがない場合は生成する
86     -- Nameリストは以下のように指定
87     -- {{id="id1",kind="kind1"},...}
88     -- @param context ルートコンテキスト
89     -- @param name_list 登録パス(Nameリスト)
90     -- @param 登録オブジェクト
91     function obj:rebindRecursive(context, name_list, _obj)
92         local length = #name_list
93         for i =1,length do
94             if i == length then
95                 --print("test1")
96                 context:rebind(self:subName(name_list, i, i), _obj)
97                 --print("test2")
98                 return
99             else
100                 if self:objIsNamingContext(context) then
101                     local success, exception = oil.pcall(
102                         function()
103                             context = context:bind_new_context(self:subName(name_list, i, i))
104                         end)
105                     if not success then
106                         --print(exception)
107                         context = context:resolve(self:subName(name_list, i, i))
108                     end
109                 else
110                     error("CosNaming.NamingContext.CannotProceed")
111                 end
112             end
113         end
114     end
115     -- オブジェクトがコンテキストかを判定
116     -- 未実装
117     -- @return true:オブジェクトはコンテキスト、false:それ以外
118     function obj:objIsNamingContext(obj)
119         return true
120     end
121
122     -- 文字列をNameリストに変換
123     -- 文字列で以下のように設定する
124     -- test1.host_cxt/test2.rtc
125     -- @param 設定パス(文字列)
126     -- @return 設定パス(Nameリスト)
127     -- 戻り値は以下のようになる
128     -- {{id="test1",kind="host_cxt"},{id="test2",kind="rtc"}}
129     function obj:toName(sname)
130         if sname == "" then
131             error("CosNaming.NamingContext.InvalidName")
132         end
133         local string_name = sname
134         local name_comps = {}
135         --print(string_name)
136         name_comps = StringUtil.split(string_name,"/")
137         local name_list = {}
138         for i, comp in ipairs(name_comps) do
139             local s = StringUtil.split(comp,"%.")
140             name_list[i] = {}
141             if #s == 1 then
142                 name_list[i].id = comp
143                 name_list[i].kind = ""
144             else
145                 local n = ""
146                 for i=1,#s-1 do
147                     n = n..s[i]
148                     if i ~= #s-1 then
149                         n = n.."."
150                     end
151                 end
152                 name_list[i].id = n
153                 name_list[i].kind = s[#s]
154             end
155         end
156         return name_list
157     end
158     -- Nameリストから、指定したインデックス間の要素を抽出する
159     -- Nameリストは以下のように指定
160     -- {{id="id1",kind="kind1"},...}
161     -- @param Nameリスト
162     -- @param begin 開始インデックス
163     -- @param _end 終了インデックス
164     -- @return 抽出したリスト
165     function obj:subName(name_list, begin, _end)
166         if _end == nil  or _end < 1 then
167             _end = #name_list
168         end
169         sub_name = {}
170         for i =begin,_end do
171             table.insert(sub_name, name_list[i])
172         end
173         return sub_name
174
175     end
176
177     -- ネームサーバーから指定パスのオブジェクトを削除
178     -- Nameリストは以下のように指定
179     -- {{id="id1",kind="kind1"},...}
180     -- @param name 削除パス(Nameオブジェクト)
181     function obj:unbind(name)
182         local name_ = name
183         if type(name) == "string" then
184             name_ = self:toName(name)
185         end
186
187         local success, exception = oil.pcall(
188             function()
189                 self._rootContext:unbind(name_)
190             end)
191         if not success then
192             print(exception)
193         end
194     end
195
196     -- 名前からオブジェクトを取得
197     -- @param name 名前リスト
198     -- {{id="id1",kind="kind1"},...}
199     -- @return オブジェクト
200     function obj:resolve(name)
201         local name_ = ""
202         if type(name) == "string" then
203             name_ = self:toName(name)
204         else
205             name_ = name
206         end
207         local _obj = oil.corba.idl.null
208         local success, exception = oil.pcall(
209             function()
210             _obj = self._rootContext:resolve(name_)
211         end)
212
213         if not success then
214             print(exception)
215             return oil.corba.idl.null
216         end
217         if _obj ~= nil then
218             return _obj
219         end
220     end
221
222     -- 名前からオブジェクトを取得
223     -- @param string_name 名前
224     -- test1.host_cxt/test2.rtc
225     -- @return オブジェクト
226     function obj:resolveStr(string_name)
227         return self:resolve(self:toName(string_name))
228     end
229
230     -- ルートコンテキスト取得
231     -- @return ルートコンテキスト
232     function obj:getRootContext()
233         return self._rootContext
234     end
235
236     return obj
237 end
238
239
240 return CorbaNaming

File lua\openrtm\CorbaPort.lua

1 ---------------------------------
2 --! @file CorbaPort.lua
3 --! @brief CORBAポートクラス定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local CorbaPort= {}
11 --_G["openrtm.CorbaPort"] = CorbaPort
12
13 local oil = require "oil"
14 local PortBase = require "openrtm.PortBase"
15 local Properties = require "openrtm.Properties"
16 local StringUtil = require "openrtm.StringUtil"
17 local NVUtil = require "openrtm.NVUtil"
18 local CORBA_SeqUtil = require "openrtm.CORBA_SeqUtil"
19
20
21 local CorbaProviderHolder = {}
22
23 -- プロバイダ保持オブジェクト初期化関数
24 -- @param type_name 型名
25 -- @param instance_name インスタンス名
26 -- @param servant サーバント
27 -- @return プロバイダ保持オブジェクト
28 CorbaProviderHolder.new = function(type_name, instance_name, servant)
29     local obj = {}
30
31     -- インスタンス名取得
32     -- @return インスタンス名
33     function obj:instanceName()
34         return self._instanceName
35     end
36
37
38     -- 種別名取得
39     -- @return 種別名
40     function obj:itypeName()
41         return self._typeName
42     end
43
44
45     -- IOR文字列取得
46     -- @return IOR文字列
47     function obj:ior()
48         return self._ior
49     end
50
51
52     -- 記述子取得
53     -- @return 記述子
54     function obj:descriptor()
55         return self._typeName.."."..self._instanceName
56     end
57
58     -- インターフェースのアクティブ化
59     -- RTCのアクティブ化時にインターフェースのアクティブ化を行い使用可能にする
60     function obj:activate()
61     end
62
63     -- インターフェースの非アクティブ化
64     -- RTCの非アクティブ化時にインターフェースの非アクティブ化を行い使用不可にする
65     function obj:deactivate()
66     end
67
68
69     obj._typeName = type_name
70     obj._instanceName = instance_name
71     obj._servant = servant
72     local Manager = require "openrtm.Manager"
73     local _mgr = Manager:instance()
74     --obj.._oid = _mgr:getPOA():tostring(obj.._servant)
75
76     obj._ior = _mgr:getORB():tostring(obj._servant)
77     --obj:deactivate()
78     return obj
79 end
80
81
82 local CorbaConsumerHolder = {}
83
84 -- コンシューマ保持オブジェクト初期化
85 -- @param type_name 種別名
86 -- @param instance_name インスタンス名
87 -- @param consumer コンシューマオブジェクト
88 -- @param owner 親オブジェクト
89 -- @return コンシューマ保持オブジェクト
90 CorbaConsumerHolder.new = function(type_name, instance_name, consumer, owner)
91     local obj = {}
92
93     -- インスタンス名取得
94     -- @return インスタンス名
95     function obj:instanceName()
96         return self._instanceName
97     end
98     -- 型名取得
99     -- @return 型名
100     function obj:typeName()
101         return self._typeName
102     end
103     -- 記述子取得
104     -- @return 記述子(型名.インスタンス名)
105     function obj:descriptor()
106         return self._typeName.."."..self._instanceName
107     end
108
109     -- IOR文字列からオブジェクトリファレンス設定
110     -- @param ior IOR文字列
111     -- @return true:設定成功、false:設定失敗
112     function obj:setObject(ior)
113         self._ior = ior
114
115         return self._consumer:setIOR(ior)
116
117     end
118
119     -- オブジェクトリファレンスをnullに設定する
120     function obj:releaseObject()
121         self._consumer:releaseObject()
122     end
123
124     -- IOR文字列取得
125     -- IOR文字列
126     function obj:getIor()
127         return self._ior
128     end
129
130
131     obj._typeName = type_name
132     obj._instanceName = instance_name
133     obj._consumer = consumer
134     obj._owner = owner
135     obj._ior = ""
136
137     return obj
138 end
139
140
141 -- CORBAポート初期化関数
142 -- @param name ポート名
143 -- @return CORBAポート
144 CorbaPort.new = function(name)
145     local obj = {}
146     setmetatable(obj, {__index=PortBase.new(name)})
147     local Manager = require "openrtm.Manager"
148     obj._PortInterfacePolarity = Manager:instance():getORB().types:lookup("::RTC::PortInterfacePolarity").labelvalue
149     obj._ReturnCode_t = Manager:instance():getORB().types:lookup("::RTC::ReturnCode_t").labelvalue
150
151     -- CORBAポートのプロパティ設定
152     -- @param prop プロパティ
153     function obj:init(prop)
154         self._rtcout:RTC_TRACE("init()")
155         self:createRef()
156
157         self._properties:mergeProperties(prop)
158
159         local num = tonumber(self._properties:getProperty("connection_limit","-1"))
160         if num == nil then
161             self._rtcout:RTC_ERROR("invalid connection_limit value: "..
162                                  self._properties:getProperty("connection_limit"))
163         end
164
165         self:setConnectionLimit(num)
166     end
167
168     -- プロバイダ登録
169     -- @param instance_name インスタンス名
170     -- @param type_name 型名
171     -- @param provider プロバイダオブジェクト
172     -- @param idl_file idlファイルパス(例:"../idl/MyService.idl")
173     -- @param interface_type インターフェース型(例:"IDL:SimpleService/MyService:1.0")
174     -- @return true:登録成功、false:登録失敗
175     function obj:registerProvider(instance_name, type_name, provider, idl_file, interface_type)
176         self._rtcout:RTC_TRACE("registerProvider(instance="..instance_name..", type_name="..type_name..")")
177         if interface_type ~= nil and idl_file ~= nil then
178             local Manager = require "openrtm.Manager"
179             Manager:instance():getORB():loadidlfile(idl_file)
180             provider = Manager:instance():getORB():newservant(provider, nil, interface_type)
181         end
182         local success, exception = oil.pcall(
183             function()
184                 table.insert(self._providers, CorbaProviderHolder.new(type_name,
185                                                           instance_name,
186                                                           provider))
187             end)
188         if not success then
189             self._rtcout:RTC_ERROR("appending provider interface failed")
190             self._rtcout:RTC_ERROR(exception)
191             return false
192         end
193
194
195         if not self:appendInterface(instance_name, type_name, self._PortInterfacePolarity.PROVIDED) then
196             return false
197         end
198
199         return true
200     end
201
202     -- コンシューマ登録
203     -- @param instance_name インスタンス名
204     -- @param type_name 型名
205     -- @param idl_file IDLファイルパス(例:"../idl/MyService.idl")
206     -- @return true:登録成功、false:登録失敗
207     function obj:registerConsumer(instance_name, type_name, consumer, idl_file)
208         self._rtcout:RTC_TRACE("registerConsumer()")
209         if idl_file ~= nil then
210             local Manager = require "openrtm.Manager"
211             Manager:instance():getORB():loadidlfile(idl_file)
212         end
213         if not self:appendInterface(instance_name, type_name, self._PortInterfacePolarity.REQUIRED) then
214             return false
215         end
216
217         table.insert(self._consumers,CorbaConsumerHolder.new(type_name,
218                                                         instance_name,
219                                                         consumer,
220                                                         self))
221         return true
222     end
223
224     -- インターフェースのアクティブ化
225     -- RTCアクティブ化時にインターフェースのアクティブ化を行い使用可能にする
226     function obj:activateInterfaces()
227         self._rtcout:RTC_TRACE("activateInterfaces()")
228         for i, provider in ipairs(self._providers) do
229             provider:activate()
230         end
231     end
232
233     -- インターフェースの非アクティブ化
234     -- RTC非アクティブ化時にインターフェースの非アクティブ化を行い使用不可にする
235     function obj:deactivateInterfaces()
236         self._rtcout:RTC_TRACE("deactivateInterfaces()")
237         for i, provider in ipairs(self._providers) do
238             provider:deactivate()
239         end
240     end
241
242     -- コネクタプロファイルにオブジェクトを設定する
243     -- 以下の要素名にIOR文字列を登録
244     -- RTC名.port.ポート名.型名.インスタンス名
245     -- port.型名.インスタンス名
246     -- @param connector_profile コネクタプロファイル
247     -- @return リターンコード
248     -- RTC_OK:登録成功、RTC_ERROR:コネクタ数上限により登録失敗
249     function obj:publishInterfaces(connector_profile)
250         self._rtcout:RTC_TRACE("publishInterfaces()")
251
252         local returnvalue = self:_publishInterfaces()
253
254         if returnvalue ~= self._ReturnCode_t.RTC_OK then
255             return returnvalue
256         end
257
258         local properties = {}
259
260         for i, provider in ipairs(self._providers) do
261             local newdesc = string.sub(self._profile.name, 1, #self._ownerInstanceName)..
262                 ".port"..string.sub(self._profile.name, #self._ownerInstanceName+1)
263             newdesc = newdesc..".provided."..provider:descriptor()
264
265             table.insert(properties, NVUtil.newNV(newdesc, provider:ior()))
266
267
268             local olddesc = "port."..provider:descriptor()
269             table.insert(properties, NVUtil.newNV(olddesc, provider:ior()))
270
271         end
272
273         CORBA_SeqUtil.push_back_list(connector_profile.properties, properties)
274
275         return self._ReturnCode_t.RTC_OK
276     end
277
278     -- コネクタプロファイルからオブジェクトリファレンスを設定する
279     -- 以下の要素名からIOR文字列を取り出してオブジェクトリファレンスを取得
280     -- RTC名.port.ポート名
281     -- port.型名.インスタンス名
282     -- @param connector_profile コネクタプロファイル
283     -- @return リターンコード
284     -- RTC_OK:設定成功、RTC_ERROR:設定失敗、オブジェクトリファレンスが取得できない
285     -- 「port.connection.strictness」の要素が「strict」に設定されている場合は、
286     -- オブジェクトリファレンスを取得できなかった場合にRTC_ERRORになる
287     function obj:subscribeInterfaces(connector_profile)
288         self._rtcout:RTC_TRACE("subscribeInterfaces()")
289         local nv = connector_profile.properties
290
291         local strict = false
292         local index = NVUtil.find_index(nv, "port.connection.strictness")
293         if index >=  0 then
294             local strictness = NVUtil.any_from_any(nv[index].value)
295             if "best_effort" == strictness then
296                 strict = false
297             elseif "strict" == strictness then
298                 strict = true
299             end
300
301             self._rtcout:RTC_DEBUG("Connetion strictness is: "..strictness)
302         end
303
304         for i, consumer in ipairs(self._consumers) do
305             local ior = {}
306             --print(nv, consumer)
307             --print(self:findProvider(nv, consumer, ior))
308             if self:findProvider(nv, consumer, ior) and #ior > 0 then
309
310                 self:setObject(ior[1], consumer)
311
312             else
313                 ior = {}
314                 --print(self:findProviderOld(nv, consumer, ior), #ior)
315                 if self:findProviderOld(nv, consumer, ior) and #ior > 0 then
316
317                     self:setObject(ior[1], consumer)
318                 else
319
320                     if strict then
321                         self._rtcout:RTC_ERROR("subscribeInterfaces() failed.")
322                         return self._ReturnCode_t.RTC_ERROR
323                     end
324                 end
325             end
326         end
327
328         self._rtcout:RTC_TRACE("subscribeInterfaces() successfully finished.")
329
330         return self._ReturnCode_t.RTC_OK
331     end
332
333     -- コネクタプロファイルのオブジェクトリファレンスの設定を解除
334     -- 以下の要素名からIOR文字列を取り出してオブジェクトリファレンスを取得
335     -- RTC名.port.ポート名
336     -- port.型名.インスタンス名
337     -- @param connector_profile コネクタプロファイル
338      function obj:unsubscribeInterfaces(connector_profile)
339         self._rtcout:RTC_TRACE("unsubscribeInterfaces()")
340         local nv = connector_profile.properties
341
342         for i, consumer in ipairs(self._consumers) do
343             local ior = {}
344             if self:findProvider(nv, consumer, ior) and #ior > 0 then
345                 self._rtcout:RTC_DEBUG("Correspoinding consumer found.")
346                 self:releaseObject(ior[1], consumer)
347             else
348                 ior = {}
349                 if self:findProviderOld(nv, consumer, ior) and #ior > 0 then
350                     self._rtcout:RTC_DEBUG("Correspoinding consumer found.")
351                     self:releaseObject(ior[1], consumer)
352                 end
353             end
354         end
355
356
357     end
358
359     -- コネクタプロファイルのプロパティからIOR文字列を取得
360     -- 以下からオブジェクトリファレンスを保持している要素名を取得する
361     -- RTC名.port.ポート名.required.型名.インスタンス名
362     -- @param nv コネクタプロファイルのプロパティ
363     -- @param cons コンシューマ保持オブジェクト
364     -- @param iorstr IOR文字列リスト
365     -- @return true:取得成功、false:取得失敗
366      function obj:findProvider(nv, cons, iorstr)
367
368         local newdesc = string.sub(self._profile.name,1,#self._ownerInstanceName)..
369             ".port"..string.sub(self._profile.name,#self._ownerInstanceName+1)
370         newdesc = newdesc..".required."..cons:descriptor()
371         --print(newdesc)
372         
373
374
375         local cons_index = NVUtil.find_index(nv, newdesc)
376         --print(cons_index)
377         --print(#nv)
378         --for i,v in ipairs(nv) do
379         -- print(v.name, v.value)
380         --end
381         if cons_index < 0 then
382             return false
383         end
384
385         local provider = NVUtil.any_from_any(nv[cons_index].value)
386         
387         if provider == "" then
388             self._rtcout:RTC_WARN("Cannot extract Provider interface descriptor")
389             return false
390         end
391
392
393         local prov_index = NVUtil.find_index(nv, provider)
394         if prov_index < 0 then
395             return false
396         end
397
398         local ior_ = NVUtil.any_from_any(nv[prov_index].value)
399         if ior_ == "" then
400             self._rtcout:RTC_WARN("Cannot extract Provider IOR string")
401             return false
402         end
403
404         if type(iorstr) == "table" then
405             table.insert(iorstr, ior_)
406         end
407
408         self._rtcout:RTC_ERROR("interface matched with new descriptor: "..newdesc)
409
410         return true
411     end
412
413     -- コネクタプロファイルのプロパティからIOR文字列を取得
414     -- 以下の要素名からオブジェクトリファレンスを取得する
415     -- port.型名.インスタンス名
416     -- @param nv コネクタプロファイルのプロパティ
417     -- @param cons コンシューマ保持オブジェクト
418     -- @param iorstr IOR文字列リスト
419     -- @return true:取得成功、false:取得失敗
420     function obj:findProviderOld(nv, cons, iorstr)
421         local olddesc = "port."..cons:descriptor()
422
423         --print(olddesc)
424
425         --for i,v in ipairs(nv) do
426         -- print(v.name, v.value)
427         --end
428
429         local index = NVUtil.find_index(nv, olddesc)
430
431
432         if index < 0 then
433             return false
434         end
435
436
437
438         local ior_ = NVUtil.any_from_any(nv[index].value)
439         --print(ior_)
440
441         if ior_ == "" then
442             self._rtcout:RTC_WARN("Cannot extract Provider IOR string")
443             return false
444         end
445
446         if type(iorstr) == "table" then
447             table.insert(iorstr, ior_)
448         end
449
450         self._rtcout:RTC_ERROR("interface matched with old descriptor: "..olddesc)
451
452         return true
453     end
454
455     -- コンシューマ保持オブジェクトにオブジェクトリファレンス設定
456     -- @param ior IOR文字列
457     -- @param cons コンシューマ保持オブジェクト
458     -- @return true:設定成功、false:設定失敗
459     function obj:setObject(ior, cons)
460         if "null" == ior then
461             return true
462         end
463
464         if "nil"  == ior then
465             return true
466         end
467
468
469         --if "IOR:" ~= string.sub(ior,1,4) then
470         -- return false
471         --end
472
473
474         if not cons:setObject(ior) then
475             self._rtcout:RTC_ERROR("Cannot narrow reference")
476             return false
477         end
478
479         self._rtcout:RTC_TRACE("setObject() done")
480         return true
481     end
482
483     -- コンシューマ保持オブジェクトからオブジェクトリファレンスを解除
484     -- @param ior IOR文字列
485     -- @param cons コンシューマ保持オブジェクト
486     -- @return true:解除成功、false:解除失敗
487     function obj:releaseObject(ior, cons)
488         if ior == cons:getIor() then
489             cons:releaseObject()
490             self._rtcout:RTC_DEBUG("Consumer "..cons:descriptor().." released.")
491             return true
492         end
493
494         self._rtcout:RTC_WARN("IORs between Consumer and Connector are different.")
495         return false
496     end
497
498
499
500
501
502     obj:addProperty("port.port_type", "CorbaPort")
503     obj._properties = Properties.new()
504     obj._providers = {}
505     obj._consumers = {}
506
507     return obj
508 end
509
510
511 return CorbaPort

File lua\openrtm\CORBA_RTCUtil.lua

1 ---------------------------------
2 --! @file CORBA_RTCUtil.lua
3 --! @brief RTC操作関数定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local CORBA_RTCUtil = {}
11 --_G["openrtm.CORBA_RTCUtil"] = CORBA_RTCUtil
12
13 local oil = require "oil"
14 local RTObject = require "openrtm.RTObject"
15 local NVUtil = require "openrtm.NVUtil"
16 local Properties = require "openrtm.Properties"
17 local StringUtil = require "openrtm.StringUtil"
18
19
20
21
22 -- コンポーネントプロファイル取得
23 -- @param rtc RTC
24 -- @return コンポーネントプロファイル(プロパティ形式)
25 CORBA_RTCUtil.get_component_profile = function(rtc)
26     local prop = Properties.new()
27     if rtc == oil.corba.idl.null then
28         return prop
29     end
30     local prof = rtc:get_component_profile()
31     NVUtil.copyToProperties(prop, prof.properties)
32     return prop
33 end
34
35
36 -- RTCの存在確認
37 -- @param rtc RTC
38 -- @return true:存在する
39 CORBA_RTCUtil.is_existing = function(rtc)
40     local ret = true
41     if NVUtil._non_existent(rtc) then
42         ret = false
43     end
44     return ret
45 end
46
47 -- RTCがデフォルトの実行コンテキストで生存しているかを確認
48 -- @param rtc RTC
49 -- @return true:生存
50 CORBA_RTCUtil.is_alive_in_default_ec = function(rtc)
51     local ec = CORBA_RTCUtil.get_actual_ec(rtc)
52     if ec == oil.corba.idl.null then
53         return false
54     end
55     return rtc:is_alive(ec)
56 end
57
58
59
60
61
62 -- RTCから指定IDの実行コンテキストを取得
63 -- @param rtc RTC
64 -- @param ec_id
65 -- @return 実行コンテキスト
66 CORBA_RTCUtil.get_actual_ec = function(rtc, ec_id)
67     local Manager = require "openrtm.Manager"
68     local ReturnCode_t  = Manager._ReturnCode_t
69     if ec_id == nil then
70         ec_id = 0
71     end
72     if ec_id < 0 then
73         return oil.corba.idl.null
74     end
75
76
77     if rtc == oil.corba.idl.null then
78         return oil.corba.idl.null
79     end
80
81     if ec_id < RTObject.ECOTHER_OFFSET then
82         local eclist = rtc:get_owned_contexts()
83         if ec_id >= #eclist then
84             return oil.corba.idl.null
85         end
86
87         if eclist[ec_id+1] == nil then
88             return oil.corba.idl.null
89         end
90         return eclist[ec_id+1]
91     elseif ec_id >= RTObject.ECOTHER_OFFSET then
92         local pec_id = ec_id - RTObject.ECOTHER_OFFSET
93         local eclist = rtc:get_participating_contexts()
94         --print(pec_id, #eclist)
95         if pec_id >= #eclist then
96             return oil.corba.idl.null
97         end
98         if eclist[pec_id+1] == nil then
99             return oil.corba.idl.null
100         end
101         return eclist[pec_id+1]
102     end
103 end
104
105
106 -- 対象RTCの指定実行コンテキストのIDを取得
107 -- @param rtc RTC
108 -- @param ec 実行コンテキスト
109 -- @return ID
110 -- 存在しない場合は-1
111 CORBA_RTCUtil.get_ec_id = function(rtc, ec)
112     if rtc == oil.corba.idl.null then
113         return -1
114     end
115     if ec == oil.corba.idl.null then
116         return -1
117     end
118
119     local eclist_own = rtc:get_owned_contexts()
120
121     local count = 0
122     for k,e in ipairs(eclist_own) do
123         if e ~= oil.corba.idl.null then
124             if NVUtil._is_equivalent(e, ec, e.getObjRef, ec.getObjRef) then
125                 return count
126             end
127         end
128         count = count+1
129     end
130     local eclist_pec = rtc:get_participating_contexts()
131     count = 0
132     for k, e in pairs(eclist_pec) do
133         if e ~= oil.corba.idl.null then
134             if NVUtil._is_equivalent(e, ec, e.getObjRef, ec.getObjRef) then
135                 return count+RTObject.ECOTHER_OFFSET
136             end
137         end
138         count = count+1
139     end
140     return -1
141 end
142
143
144
145 -- RTCのアクティブ化
146 -- @param rtc RTC
147 -- @param ec_id 実行コンテキストのID
148 -- @return リターンコード
149 -- RTC_OK:アクティブ化成功
150 CORBA_RTCUtil.activate = function(rtc, ec_id)
151     local Manager = require "openrtm.Manager"
152     local ReturnCode_t  = Manager._ReturnCode_t
153     if ec_id == nil then
154         ec_id = 0
155     end
156     if rtc == oil.corba.idl.null then
157         return ReturnCode_t.BAD_PARAMETER
158     end
159     local ec = CORBA_RTCUtil.get_actual_ec(rtc, ec_id)
160     if ec == oil.corba.idl.null then
161         return ReturnCode_t.BAD_PARAMETER
162     end
163     return NVUtil.getReturnCode(ec:activate_component(rtc))
164 end
165
166 -- RTCの非アクティブ化
167 -- @param rtc RTC
168 -- @param ec_id 実行コンテキストのID
169 -- @return リターンコード
170 -- RTC_OK:非アクティブ化成功
171 CORBA_RTCUtil.deactivate = function(rtc, ec_id)
172     local Manager = require "openrtm.Manager"
173     local ReturnCode_t  = Manager._ReturnCode_t
174     if ec_id == nil then
175         ec_id = 0
176     end
177     if rtc == oil.corba.idl.null then
178         return ReturnCode_t.BAD_PARAMETER
179     end
180     local ec = CORBA_RTCUtil.get_actual_ec(rtc, ec_id)
181     if ec == oil.corba.idl.null then
182         return ReturnCode_t.BAD_PARAMETER
183     end
184     return NVUtil.getReturnCode(ec:deactivate_component(rtc))
185 end
186
187
188 -- RTCのリセット
189 -- @param rtc RTC
190 -- @param ec_id 実行コンテキストのID
191 -- @return リターンコード
192 -- RTC_OK:リセット成功
193 CORBA_RTCUtil.reset = function(rtc, ec_id)
194     local Manager = require "openrtm.Manager"
195     local ReturnCode_t  = Manager._ReturnCode_t
196     if ec_id == nil then
197         ec_id = 0
198     end
199     if rtc == oil.corba.idl.null then
200         return ReturnCode_t.BAD_PARAMETER
201     end
202     local ec = CORBA_RTCUtil.get_actual_ec(rtc, ec_id)
203     if ec == oil.corba.idl.null then
204         return ReturnCode_t.BAD_PARAMETER
205     end
206     return NVUtil.getReturnCode(ec:reset_component(rtc))
207 end
208
209
210 -- RTCの状態取得
211 -- @param rtc RTC
212 -- @param ec_id 実行コンテキストのID
213 -- @return ret、state
214 -- ret true:状態取得成功
215 -- state 状態(取得に失敗した場合はCREATED_STATE)
216 CORBA_RTCUtil.get_state = function(rtc, ec_id)
217     local Manager = require "openrtm.Manager"
218     local LifeCycleState = Manager:instance():getORB().types:lookup("::RTC::LifeCycleState").labelvalue
219     if ec_id == nil then
220         ec_id = 0
221     end
222     if rtc == oil.corba.idl.null then
223         return false, LifeCycleState.CREATED_STATE
224     end
225     local ec = CORBA_RTCUtil.get_actual_ec(rtc, ec_id)
226
227     if ec == oil.corba.idl.null then
228         return false, LifeCycleState.CREATED_STATE
229     end
230     local state = ec:get_component_state(rtc)
231
232     return true, NVUtil.getLifeCycleState(state)
233 end
234
235
236 -- RTCが非アクティブ状態かを確認
237 -- @param rtc RTC
238 -- @param ec_id 実行コンテキストのID
239 -- @return true:非アクティブ状態
240 CORBA_RTCUtil.is_in_inactive = function(rtc, ec_id)
241     local Manager = require "openrtm.Manager"
242     local LifeCycleState = Manager:instance():getORB().types:lookup("::RTC::LifeCycleState").labelvalue
243
244     if ec_id == nil then
245         ec_id = 0
246     end
247     local ret, state = CORBA_RTCUtil.get_state(rtc, ec_id)
248     if ret then
249         if state == LifeCycleState.INACTIVE_STATE then
250             return true
251         end
252     end
253
254     return false
255 end
256
257 -- RTCがアクティブ状態かを確認
258 -- @param rtc RTC
259 -- @param ec_id 実行コンテキストのID
260 -- @return true:アクティブ状態
261 CORBA_RTCUtil.is_in_active = function(rtc, ec_id)
262     local Manager = require "openrtm.Manager"
263     local LifeCycleState = Manager:instance():getORB().types:lookup("::RTC::LifeCycleState").labelvalue
264
265     if ec_id == nil then
266         ec_id = 0
267     end
268     local ret, state = CORBA_RTCUtil.get_state(rtc, ec_id)
269     if ret then
270         if state == LifeCycleState.ACTIVE_STATE then
271             return true
272         end
273     end
274
275     return false
276 end
277
278 -- RTCがエラー状態かを確認
279 -- @param rtc RTC
280 -- @param ec_id 実行コンテキストのID
281 -- @return true:エラー状態
282 CORBA_RTCUtil.is_in_error = function(rtc, ec_id)
283     local Manager = require "openrtm.Manager"
284     local LifeCycleState = Manager:instance():getORB().types:lookup("::RTC::LifeCycleState").labelvalue
285
286     if ec_id == nil then
287         ec_id = 0
288     end
289     local ret, state = CORBA_RTCUtil.get_state(rtc, ec_id)
290     if ret then
291         if state == LifeCycleState.ERROR_STATE then
292             return true
293         end
294     end
295
296     return false
297 end
298
299
300 -- 対象RTCのデフォルトの実行コンテキストでの実行周期を取得
301 -- @param rtc RTC
302 -- @return 実行周期
303 CORBA_RTCUtil.get_default_rate = function(rtc)
304     local ec = CORBA_RTCUtil.get_actual_ec(rtc)
305     return ec:get_rate()
306 end
307
308 -- 対象RTCのデフォルトの実行コンテキストでの実行周期を設定
309 -- @param rtc RTC
310 -- @param 実行周期
311 -- @return リターンコード
312 -- RTC_OK:設定成功
313 CORBA_RTCUtil.set_default_rate = function(rtc, rate)
314     local ec = CORBA_RTCUtil.get_actual_ec(rtc)
315     return ec:set_rate(rate)
316 end
317
318 -- 対象RTCのデフォルトの実行コンテキストでの実行周期を取得
319 -- @param rtc RTC
320 -- @param ec_id 実行コンテキストのID
321 -- @return 実行周期
322 CORBA_RTCUtil.get_current_rate = function(rtc, ec_id)
323     local ec = CORBA_RTCUtil.get_actual_ec(rtc, ec_id)
324     return ec:get_rate()
325 end
326
327 -- 対象RTCのデフォルトの実行コンテキストでの実行周期を設定
328 -- @param rtc RTC
329 -- @param ec_id 実行コンテキストのID
330 -- @param 実行周期
331 -- @return リターンコード
332 -- RTC_OK:設定成功
333 CORBA_RTCUtil.set_current_rate = function(rtc, ec_id, rate)
334     local ec = CORBA_RTCUtil.get_actual_ec(rtc, ec_id)
335     return ec:set_rate(rate)
336 end
337
338
339 -- RTC1のデフォルトの実行コンテキストにRTC2を追加
340 -- @param localcomp RTC1
341 -- @param othercomp RTC2
342 -- @return リターンコード
343 CORBA_RTCUtil.add_rtc_to_default_ec = function(localcomp, othercomp)
344     local Manager = require "openrtm.Manager"
345     local ReturnCode_t  = Manager._ReturnCode_t
346     if othercomp == oil.corba.idl.null then
347         return ReturnCode_t.BAD_PARAMETER
348     end
349     local ec = CORBA_RTCUtil.get_actual_ec(localcomp)
350     if ec == oil.corba.idl.null then
351         return ReturnCode_t.BAD_PARAMETER
352     end
353     return NVUtil.getReturnCode(ec:add_component(othercomp))
354 end
355
356
357 -- RTC1のデフォルトの実行コンテキストからRTC2を削除
358 -- @param localcomp RTC1
359 -- @param othercomp RTC2
360 -- @return リターンコード
361 CORBA_RTCUtil.remove_rtc_to_default_ec = function(localcomp, othercomp)
362     local Manager = require "openrtm.Manager"
363     local ReturnCode_t  = Manager._ReturnCode_t
364     if othercomp == oil.corba.idl.null then
365         return ReturnCode_t.BAD_PARAMETER
366     end
367     local ec = CORBA_RTCUtil.get_actual_ec(localcomp)
368     if ec == oil.corba.idl.null then
369         return ReturnCode_t.BAD_PARAMETER
370     end
371     return NVUtil.getReturnCode(ec:remove_component(othercomp))
372 end
373
374
375 -- RTCのデフォルトの実行コンテキストにアタッチしている外部のRTCを取得
376 -- @param rtc RTC
377 -- @return RTC一覧
378 CORBA_RTCUtil.get_participants_rtc = function(rtc)
379     local ec = CORBA_RTCUtil.get_actual_ec(rtc)
380     if ec == oil.corba.idl.null then
381         return {}
382     end
383     local profile = ec:get_profile()
384     return profile.participants
385 end
386
387 -- RTCのポート名一覧を取得
388 -- @param rtc RTC
389 -- @return ポート名一覧
390 CORBA_RTCUtil.get_port_names = function(rtc)
391     local names = {}
392     if rtc == oil.corba.idl.null then
393         return names
394     end
395     local ports = rtc:get_ports()
396     for k,p in ipairs(ports) do
397         local pp = p:get_port_profile()
398         local s = pp.name
399         table.insert(names, s)
400     end
401     return names
402 end
403
404
405 -- RTCのInPort名一覧を取得
406 -- @param rtc RTC
407 -- @return InPort名一覧
408 CORBA_RTCUtil.get_inport_names = function(rtc)
409     local names = {}
410     if rtc == oil.corba.idl.null then
411         return names
412     end
413     local ports = rtc:get_ports()
414     for k,p in ipairs(ports) do
415         local pp = p:get_port_profile()
416         local prop = Properties.new()
417         NVUtil.copyToProperties(prop, pp.properties)
418         if prop:getProperty("port.port_type") == "DataInPort" then
419             local s = pp.name
420             table.insert(names, s)
421         end
422     end
423     return names
424 end
425
426
427 -- RTCのOutPort名一覧を取得
428 -- @param rtc RTC
429 -- @return OutPort名一覧
430 CORBA_RTCUtil.get_outport_names = function(rtc)
431     local names = {}
432     if rtc == oil.corba.idl.null then
433         return names
434     end
435     local ports = rtc:get_ports()
436     for k,p in ipairs(ports) do
437         local pp = p:get_port_profile()
438         local prop = Properties.new()
439         NVUtil.copyToProperties(prop, pp.properties)
440         if prop:getProperty("port.port_type") == "DataOutPort" then
441             local s = pp.name
442             table.insert(names, s)
443         end
444     end
445     return names
446 end
447
448
449 -- RTCのサービスポート名一覧を取得
450 -- @param rtc RTC
451 -- @return サービスポート名一覧
452 CORBA_RTCUtil.get_svcport_names = function(rtc)
453     local names = {}
454     if rtc == oil.corba.idl.null then
455         return names
456     end
457     local ports = rtc:get_ports()
458     for k,p in ipairs(ports) do
459         local pp = p:get_port_profile()
460         local prop = Properties.new()
461         NVUtil.copyToProperties(prop, pp.properties)
462         if prop:getProperty("port.port_type") == "CorbaPort" then
463             local s = pp.name
464             table.insert(names, s)
465         end
466     end
467     return names
468 end
469
470
471
472
473
474
475
476
477
478
479 -- ポート名からポートを取得
480 -- @param rtc RTC
481 -- @param port_name ポート名
482 -- @return ポート
483 CORBA_RTCUtil.get_port_by_name = function(rtc, port_name)
484     if rtc == oil.corba.idl.null then
485         return oil.corba.idl.null
486     end
487     local ports = rtc:get_ports()
488     for k,p in ipairs(ports) do
489         pp = p:get_port_profile()
490         s = pp.name
491
492         if port_name == s then
493             return p
494         end
495     end
496
497     return oil.corba.idl.null
498 end
499
500 -- ポートからコネクタ名一覧を取得
501 -- @param port ポート
502 -- @return コネクタ名一覧
503 CORBA_RTCUtil.get_connector_names_by_portref = function(port)
504     local names = {}
505     if port == oil.corba.idl.null then
506         return names
507     end
508     local conprof = port:get_connector_profiles()
509     for k,c in ipairs(conprof) do
510         table.insert(names, c.name)
511     end
512     return names
513 end
514
515 -- RTCとポート名からコネクタ名一覧を取得
516 -- @param RTC rtc
517 -- @param port_name ポート名
518 -- @return コネクタ名一覧
519 CORBA_RTCUtil.get_connector_names = function(rtc, port_name)
520     local names = {}
521     local port = CORBA_RTCUtil.get_port_by_name(rtc, port_name)
522     if port == oil.corba.idl.null then
523         return names
524     end
525     local conprof = port:get_connector_profiles()
526     for k,c in ipairs(conprof) do
527         table.insert(names, c.name)
528     end
529     return names
530 end
531
532 -- ポートからコネクタID一覧を取得
533 -- @param port ポート
534 -- @return コネクタID一覧
535 CORBA_RTCUtil.get_connector_ids_by_portref = function(port)
536     local ids = {}
537     if port == oil.corba.idl.null then
538         return ids
539     end
540     local conprof = port:get_connector_profiles()
541     for k,c in ipairs(conprof) do
542         table.insert(ids, c.connector_id)
543     end
544     return ids
545 end
546
547 -- RTCとポート名からコネクタID一覧を取得
548 -- @param RTC rtc
549 -- @param port_name ポート名
550 -- @return コネクタID一覧
551 CORBA_RTCUtil.get_connector_ids = function(rtc, port_name)
552     local ids = {}
553     local port = CORBA_RTCUtil.get_port_by_name(rtc, port_name)
554     if port == oil.corba.idl.null then
555         return ids
556     end
557     local conprof = port:get_connector_profiles()
558     for k,c in ipairs(conprof) do
559         table.insert(ids, c.connector_id)
560     end
561     return ids
562 end
563
564
565
566 -- コネクタプロファイルの生成
567 -- @param name コネクタ名
568 -- @param prop_arg 設定
569 -- データフロー型はデフォルトでpush
570 -- インターフェース型はデフォルトでdata_service
571 -- @param port0 ポート0
572 -- @param port1 ポート1
573 -- @return コネクタプロファイル
574 CORBA_RTCUtil.create_connector = function(name, prop_arg, port0, port1)
575     local prop = prop_arg
576     local conn_prof = {name=name, connector_id="", ports={port0, port1}, properties={}}
577
578
579     if tostring(prop:getProperty("dataport.dataflow_type")) == "" then
580         prop:setProperty("dataport.dataflow_type","push")
581     end
582
583
584
585     if tostring(prop:getProperty("dataport.interface_type")) == "" then
586         prop:setProperty("dataport.interface_type","data_service")
587     end
588
589
590     conn_prof.properties = {}
591     NVUtil.copyFromProperties(conn_prof.properties, prop)
592
593     return conn_prof
594 end
595
596 -- 指定ポート同士が接続済みかを確認
597 -- @param localport ポート1
598 -- @param otherport ポート2
599 -- @return true:接続済み
600 CORBA_RTCUtil.already_connected = function(localport, otherport)
601     local conprof = localport:get_connector_profiles()
602     for k,c in ipairs(conprof) do
603         for k,p in ipairs(c.ports) do
604             if NVUtil._is_equivalent(p, otherport, p.getPortRef, otherport.getPortRef) then
605                 return true
606             end
607         end
608     end
609
610     return false
611 end
612
613
614 -- ポートの接続
615 -- @param name コネクタ名
616 -- @param prop 設定
617 -- @param port0 ポート0
618 -- @param port1 ポート1
619 -- @return リターンコード
620 -- RTC_OK:接続成功
621 CORBA_RTCUtil.connect = function(name, prop, port0, port1)
622     local Manager = require "openrtm.Manager"
623     local ReturnCode_t  = Manager._ReturnCode_t
624     if port0 == oil.corba.idl.null then
625         return ReturnCode_t.BAD_PARAMETER
626     end
627     if port1 == oil.corba.idl.null then
628         return ReturnCode_t.BAD_PARAMETER
629     end
630     if NVUtil._is_equivalent(port0, port1, port0.getPortRef, port1.getPortRef) then
631         return ReturnCode_t.BAD_PARAMETER
632     end
633     local cprof = CORBA_RTCUtil.create_connector(name, prop, port0, port1)
634     
635     local ret, prof = port0:connect(cprof)
636     ret = NVUtil.getReturnCode(ret)
637     
638     --print(ret)
639     return ret
640 end
641
642
643 -- 複数のポートを接続
644 -- @param name コネクタ名
645 -- @param prop 設定
646 -- @param port 接続元のポート
647 -- @param target_ports 接続先のポート一覧
648 -- @param リターンコード
649 -- RTC_OK:すべてのコネクタが接続成功
650 -- BAD_PARAMETER:いずれかのコネクタが接続失敗
651 CORBA_RTCUtil.connect_multi = function(name, prop, port, target_ports)
652     local Manager = require "openrtm.Manager"
653     local ReturnCode_t  = Manager._ReturnCode_t
654     local ret = ReturnCode_t.RTC_OK
655     if port == oil.corba.idl.null then
656         return ReturnCode_t.BAD_PARAMETER
657     end
658     for k,p in ipairs(target_ports) do
659         if p == oil.corba.idl.null then
660             ret =  ReturnCode_t.BAD_PARAMETER
661         else
662             if NVUtil._is_equivalent(p, port, p.getPortRef, port.getPortRef) then
663                 ret =  ReturnCode_t.BAD_PARAMETER
664             else
665                 if CORBA_RTCUtil.already_connected(port, p) then
666                     ret =  ReturnCode_t.BAD_PARAMETER
667                 else
668                     if ReturnCode_t.RTC_OK ~= CORBA_RTCUtil.connect(name, prop, port, p) then
669                         ret =  ReturnCode_t.BAD_PARAMETER
670                     end
671                 end
672             end
673         end
674     end
675
676
677     return ret
678 end
679
680 -- ポート検索用関数オブジェクトの初期化
681 -- @param name ポート名
682 -- @return ポート検索用関数オブジェクト
683 CORBA_RTCUtil.find_port = function(name)
684     local obj = {}
685     obj._name = name
686
687
688     -- ポート検索用関数
689     -- @param self 自身のオブジェクト
690     -- @param p 比較対象のポート
691     -- @return true:一致
692     local call_func = function(self, p)
693         local prof = p:get_port_profile()
694         local c = prof.name
695
696         return (self._name == c)
697     end
698     setmetatable(obj, {__call=call_func})
699
700     return obj
701 end
702
703
704 -- ポート名指定でコネクタを接続
705 -- @param name コネクタ名
706 -- @param prop 設定
707 -- @param rtc0 RTC0
708 -- @param port_name0 RTC0の保持するポート名
709 -- @param rtc1 RTC1
710 -- @param port_name1 RTC1の保持するポート名
711 -- @return リターンコード
712 -- RTC_OK:接続成功
713 -- BAD_PARAMETER:ポートが存在しない場合など
714 CORBA_RTCUtil.connect_by_name = function(name, prop, rtc0, port_name0, rtc1, port_name1)
715     local Manager = require "openrtm.Manager"
716     local ReturnCode_t  = Manager._ReturnCode_t
717     if rtc0 == oil.corba.idl.null then
718         return ReturnCode_t.BAD_PARAMETER
719     end
720     if rtc1 == oil.corba.idl.null then
721         return ReturnCode_t.BAD_PARAMETER
722     end
723
724     local port0 = CORBA_RTCUtil.get_port_by_name(rtc0, port_name0)
725     if port0 == oil.corba.idl.null then
726         return ReturnCode_t.BAD_PARAMETER
727     end
728
729     local port1 = CORBA_RTCUtil.get_port_by_name(rtc1, port_name1)
730     if port1 == oil.corba.idl.null then
731         return ReturnCode_t.BAD_PARAMETER
732     end
733     
734     return CORBA_RTCUtil.connect(name, prop, port0, port1)
735 end
736
737 -- コネクタ切断
738 -- @param connector_prof コネクタプロファイル
739 -- @return リターンコード
740 -- RTC_OK:切断成功
741 CORBA_RTCUtil.disconnect = function(connector_prof)
742     local ports = connector_prof.ports
743     return CORBA_RTCUtil.disconnect_by_portref_connector_id(ports[1], connector_prof.connector_id)
744 end
745
746
747 -- コネクタ名指定でコネクタ切断
748 -- @param port_ref ポート
749 -- @param conn_name コネクタ名
750 -- @return リターンコード
751 -- RTC_OK:切断成功
752 -- BAD_PARAMETER:コネクタが存在しない場合など
753 CORBA_RTCUtil.disconnect_by_portref_connector_name = function(port_ref, conn_name)
754     local Manager = require "openrtm.Manager"
755     local ReturnCode_t  = Manager._ReturnCode_t
756     if port_ref == oil.corba.idl.null then
757         return ReturnCode_t.BAD_PARAMETER
758     end
759     local conprof = port_ref:get_connector_profiles()
760     for k,c in ipairs(conprof) do
761         if c.name == conn_name then
762             return CORBA_RTCUtil.disconnect(c)
763         end
764     end
765     return ReturnCode_t.BAD_PARAMETER
766 end
767
768
769 -- ポート名、コネクタ名指定でコネクタ切断
770 -- @param port_name ポート名
771 -- RTCをrtcloc、rtcname形式で指定する
772 -- rtcname://localhost/test.host_cxt/ConsoleIn0.out
773 -- @param conn_name コネクタ名
774 -- @return リターンコード
775 -- RTC_OK:切断成功
776 -- BAD_PARAMETER:コネクタが存在しない場合など
777 CORBA_RTCUtil.disconnect_by_portname_connector_name = function(port_name, conn_name)
778     local Manager = require "openrtm.Manager"
779     local ReturnCode_t  = Manager._ReturnCode_t
780     local port_ref = CORBA_RTCUtil.get_port_by_url(port_name)
781     if port_ref == oil.corba.idl.null then
782         return ReturnCode_t.BAD_PARAMETER
783     end
784
785
786     local conprof = port_ref:get_connector_profiles()
787     for k,c in pairs(conprof) do
788         if c.name == conn_name then
789             return CORBA_RTCUtil.disconnect(c)
790         end
791     end
792
793     return ReturnCode_t.BAD_PARAMETER
794 end
795
796
797 -- コネクタID指定でコネクタ切断
798 -- @param port_ref ポート
799 -- @param conn_name コネクタ名
800 -- @return リターンコード
801 -- RTC_OK:切断成功
802 CORBA_RTCUtil.disconnect_by_portref_connector_id = function(port_ref, conn_id)
803     local Manager = require "openrtm.Manager"
804     local ReturnCode_t  = Manager._ReturnCode_t
805     if port_ref == oil.corba.idl.null then
806         return ReturnCode_t.BAD_PARAMETER
807     end
808     return NVUtil.getReturnCode(port_ref:disconnect(conn_id))
809 end
810
811
812 -- ポート名、コネクタID指定でコネクタ切断
813 -- @param port_name ポート名
814 -- RTCをrtcloc、rtcname形式で指定する
815 -- rtcname://localhost/test.host_cxt/ConsoleIn0.out
816 -- @param conn_name コネクタ名
817 -- @return リターンコード
818 -- RTC_OK:切断成功
819 CORBA_RTCUtil.disconnect_by_portname_connector_id = function(port_name, conn_id)
820     local Manager = require "openrtm.Manager"
821     local ReturnCode_t  = Manager._ReturnCode_t
822     local port_ref = CORBA_RTCUtil.get_port_by_url(port_name)
823     if port_ref == oil.corba.idl.null then
824         return ReturnCode_t.BAD_PARAMETER
825     end
826
827     return NVUtil.getReturnCode(port_ref:disconnect(conn_id))
828 end
829
830 -- 全コネクタ切断
831 -- @param port_ref ポート
832 -- @return リターンコード
833 -- RTC_OK:切断成功
834 CORBA_RTCUtil.disconnect_all_by_ref = function(port_ref)
835     local Manager = require "openrtm.Manager"
836     local ReturnCode_t  = Manager._ReturnCode_t
837     if port_ref == oil.corba.idl.null then
838         return ReturnCode_t.BAD_PARAMETER
839     end
840     return NVUtil.getReturnCode(port_ref:disconnect_all())
841 end
842
843 -- ポート名、全コネクタ切断
844 -- @param port_name ポート名
845 -- RTCをrtcloc、rtcname形式で指定する
846 -- rtcname://localhost/test.host_cxt/ConsoleIn0.out
847 -- @return リターンコード
848 -- RTC_OK:切断成功
849 CORBA_RTCUtil.disconnect_all_by_name = function(port_name)
850     local Manager = require "openrtm.Manager"
851     local ReturnCode_t  = Manager._ReturnCode_t
852     local port_ref = CORBA_RTCUtil.get_port_by_url(port_name)
853     if port_ref == oil.corba.idl.null then
854         return ReturnCode_t.BAD_PARAMETER
855     end
856     return NVUtil.getReturnCode(port_ref:disconnect_all())
857 end
858
859
860 -- rtcloc、rtcname形式でポートを取得する
861 -- @param port_name ポート名
862 -- RTCをrtcloc、rtcname形式で指定する
863 -- rtcname://localhost/test.host_cxt/ConsoleIn0.out
864 -- @return ポート
865 CORBA_RTCUtil.get_port_by_url = function(port_name)
866     local Manager = require "openrtm.Manager"
867     local mgr = Manager:instance()
868     local nm = mgr:getNaming()
869     local p = StringUtil.split(port_name, "%.")
870     if #p < 2 then
871         return oil.corba.idl.null
872     end
873
874     local tmp = StringUtil.split(port_name, "%.")
875     tmp[#tmp] = nil
876
877     --print(StringUtil.flatten(tmp, "%."))
878     local rtcs = nm:string_to_component(StringUtil.flatten(tmp, "%."))
879
880     if #rtcs < 1 then
881         return oil.corba.idl.null
882     end
883     local pn = StringUtil.split(port_name, "/")
884
885     return CORBA_RTCUtil.get_port_by_name(rtcs[1],pn[#pn])
886 end
887
888
889 -- ポート1と接続しているポートとポート2が一致した場合にコネクタを切断
890 -- @param localport ポート1
891 -- @param othername ポート2
892 -- @return リターンコード
893 -- RTC_OK:切断成功
894 -- BAD_PARAMETER:接続していなかった場合など
895 CORBA_RTCUtil.disconnect_by_port_name = function(localport, othername)
896     local Manager = require "openrtm.Manager"
897     local ReturnCode_t  = Manager._ReturnCode_t
898     if localport == oil.corba.idl.null then
899         return ReturnCode_t.BAD_PARAMETER
900     end
901     local prof = localport:get_port_profile()
902     if prof.name == othername then
903         
904         return ReturnCode_t.BAD_PARAMETER
905     end
906
907     local conprof = localport:get_connector_profiles()
908     for k,c in ipairs(conprof) do
909         for k2,p in ipairs(c.ports) do
910             if p ~= oil.corba.idl.null then
911                 local pp = p:get_port_profile()
912                 --print(pp.name,othername)
913                 if pp.name == othername then
914                     return CORBA_RTCUtil.disconnect(c)
915                 end
916             end
917         end
918     end
919     return ReturnCode_t.BAD_PARAMETER
920 end
921
922 -- コンフィギュレーションセットをプロパティ形式で取得
923 -- @param rtc RTC
924 -- @param conf_name コンフィギュレーションセット名
925 -- @return コンフィギュレーションセット(プロパティ形式)
926 CORBA_RTCUtil.get_configuration = function(rtc, conf_name)
927     local conf = rtc:get_configuration()
928
929     local confset = conf:get_configuration_set(conf_name)
930     local confData = confset.configuration_data
931     local prop = Properties.new()
932     NVUtil.copyToProperties(prop, confData)
933     return prop
934 end
935
936 -- コンフィギュレーションパラメータの取得
937 -- @param rtc RTC
938 -- @param confset_name コンフィギュレーションセット名
939 -- @param value_name パラメータ名
940 -- @return パラメータ
941 CORBA_RTCUtil.get_parameter_by_key = function(rtc, confset_name, value_name)
942     local conf = rtc:get_configuration()
943
944
945     local confset = conf:get_configuration_set(confset_name)
946     local confData = confset.configuration_data
947     local prop = Properties.new()
948     NVUtil.copyToProperties(prop, confData)
949     return prop:getProperty(value_name)
950 end
951
952
953 -- アクティブなコンフィギュレーションセット名を取得
954 -- @param rtc RTC
955 -- @return コンフィギュレーションセット名
956 CORBA_RTCUtil.get_active_configuration_name = function(rtc)
957     local conf = rtc:get_configuration()
958     local confset = conf:get_active_configuration_set()
959     return confset.id
960 end
961
962
963 -- アクティブなコンフィギュレーションセットをプロパティ形式で取得
964 -- @param rtc RTC
965 -- @return コンフィギュレーションセット(プロパティ形式)
966 CORBA_RTCUtil.get_active_configuration = function(rtc)
967     local conf = rtc:get_configuration()
968
969     local confset = conf:get_active_configuration_set()
970     local confData = confset.configuration_data
971     local prop = Properties.new()
972     NVUtil.copyToProperties(prop, confData)
973     return prop
974 end
975
976
977 -- コンフィギュレーションパラメータの設定
978 -- @param rtc RTC
979 -- @param confset_name コンフィギュレーションセット名
980 -- @param value_name パラメータ名
981 -- @param value 設定する値
982 -- @return true:設定成功
983 CORBA_RTCUtil.set_configuration = function(rtc, confset_name, value_name, value)
984     local conf = rtc:get_configuration()
985
986     local confset = conf:get_configuration_set(confset_name)
987
988     CORBA_RTCUtil.set_configuration_parameter(conf, confset, value_name, value)
989
990     conf:activate_configuration_set(confset_name)
991     return true
992 end
993
994
995 -- アクティブなコンフィギュレーションセットのパラメータを設定
996 -- @param rtc RTC
997 -- @param value_name パラメータ名
998 -- @param value 設定する値
999 -- @return true:設定成功
1000 CORBA_RTCUtil.set_active_configuration = function(rtc, value_name, value)
1001     local conf = rtc:get_configuration()
1002
1003     local confset = conf:get_active_configuration_set()
1004     CORBA_RTCUtil.set_configuration_parameter(conf, confset, value_name, value)
1005
1006     conf:activate_configuration_set(confset.id)
1007     return true
1008 end
1009
1010
1011 -- コンフィギュレーションパラメータ設定
1012 -- @param conf コンフィギュレーション
1013 -- @param confset コンフィギュレーションセット
1014 -- @param value_name パラメータ名
1015 -- @param value 設定する値
1016 -- @return true:設定成功
1017 CORBA_RTCUtil.set_configuration_parameter = function(conf, confset, value_name, value)
1018     local confData = confset.configuration_data
1019     local prop = Properties.new()
1020     NVUtil.copyToProperties(prop, confData)
1021     prop:setProperty(value_name,value)
1022     NVUtil.copyFromProperties(confData,prop)
1023     confset.configuration_data = confData
1024     conf:set_configuration_set_values(confset)
1025     return true
1026 end
1027
1028
1029 return CORBA_RTCUtil

File lua\openrtm\CORBA_SeqUtil.lua

1 ---------------------------------
2 --! @file CORBA_SeqUtil.lua
3 --! @brief 配列操作ヘルプ関数
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local CORBA_SeqUtil= {}
11 --_G["openrtm.CORBA_SeqUtil"] = CORBA_SeqUtil
12
13 -- 指定関数がtrueになる要素を配列から検索
14 -- 指定関数をすべての要素に実行して判定する
15 -- @param seq 配列
16 -- @param f 関数
17 -- @return 配列の要素インデックス
18 CORBA_SeqUtil.find = function(seq, f)
19     for i, s in ipairs(seq) do
20         --print(f(s))
21         if f(s) then
22             return i
23         end
24     end
25     return -1
26 end
27
28 -- オブジェクトリファレンスをIOR文字列に変換
29 -- 未実装
30 -- @param objlist オブジェクトリファレンスのリスト
31 -- @return IRO文字列のリスト
32 CORBA_SeqUtil.refToVstring = function(objlist)
33     local iorlist = {}
34     local Manager = require "openrtm.Manager"
35     --local orb = Manager:instance():getORB()
36     for i, obj in ipairs(objlist) do
37         table.insert(iorlist, obj)
38     end
39     return iorlist
40 end
41
42 -- 指定関数がtrueになる場合に配列から要素を削除する
43 -- @param seq 配列
44 -- @param f 関数
45 CORBA_SeqUtil.erase_if = function(seq, f)
46     local index = CORBA_SeqUtil.find(seq, f)
47     if index < 0 then
48         return
49     end
50     table.remove(seq ,index)
51 end
52
53 -- 配列を連結する
54 -- @param seq1 連結先の配列
55 -- @param seq2 後ろに連結する配列
56 CORBA_SeqUtil.push_back_list = function(seq1, seq2)
57     for i, elem in ipairs(seq2) do
58         table.insert(seq1, elem)
59     end
60 end
61
62 -- 指定関数を配列の要素全てに実行する
63 -- @param seq 配列
64 -- @param f 関数
65 CORBA_SeqUtil.for_each = function(seq, f)
66     for i, s in ipairs(seq) do
67         f(s)
68     end
69 end
70
71
72
73
74
75 return CORBA_SeqUtil

File lua\openrtm\DataPortStatus.lua

Full coverage

File lua\openrtm\DefaultConfiguration.lua

Full coverage

File lua\openrtm\ECFactory.lua

1 ---------------------------------
2 --! @file ECFactory.lua
3 --! @brief 実行コンテキスト生成用ファクトリ定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local ECFactory= {}
11 --_G["openrtm.ECFactory"] = ECFactory
12
13 -- 実行コンテキスト削除関数
14 -- @param ec 実行コンテキスト
15 ECFactory.ECDelete = function(ec)
16 end
17
18
19 ECFactory.ECFactoryBase = {}
20
21 -- 実行コンテキスト生成ファクトリ基底オブジェクトの初期化関数
22 -- @return 実行コンテキスト生成ファクトリ
23 ECFactory.ECFactoryBase.new = function()
24     local obj = {}
25     -- 実行コンテキスト名取得
26     -- @return 実行コンテキスト名
27     function obj:name()
28         return ""
29     end
30     -- 実行コンテキスト生成
31     -- @return 実行コンテキスト
32     function obj:create()
33     end
34     -- 実行コンテキスト削除
35     -- @param ec 実行コンテキスト
36     function obj:destroy(ec)
37     end
38     return obj
39 end
40
41 ECFactory.ECFactoryLua = {}
42
43 -- 実行コンテキスト生成ファクトリの初期化関数
44 -- @param name 実行コンテキスト名
45 -- @param new_func 実行コンテキスト初期化関数
46 -- 実行コンテキストを返す関数を指定する
47 -- @param delete_func 実行コンテキスト削除関数
48 -- 実行コンテキストを引数とする関数を指定
49 -- @return 実行コンテキスト生成ファクトリ
50 ECFactory.ECFactoryLua.new = function(name, new_func, delete_func)
51     local obj = {}
52     setmetatable(obj, {__index=ECFactory.ECFactoryBase.new()})
53     obj._name   = name
54     obj._New    = new_func
55     obj._Delete = delete_func
56        -- 実行コンテキスト名取得
57     -- @return 実行コンテキスト名
58     function obj:name()
59         return self._name
60     end
61     -- 実行コンテキスト生成
62     -- @return 実行コンテキスト
63     function obj:create()
64         return self._New()
65     end
66     -- 実行コンテキスト削除
67     -- @param ec 実行コンテキスト
68     function obj:destroy(ec)
69         self._Delete(ec)
70     end
71     return obj
72 end
73
74
75 return ECFactory

File lua\openrtm\ExecutionContextBase.lua

1 ---------------------------------
2 --! @file ExecutionContextBase.lua
3 --! @brief 実行コンテキスト基底クラス定義
4 --! 実行コンテキストを作成する場合はExecutionContextBaseをメタテーブルに設定する
5 ---------------------------------
6
7 --[[
8 Copyright (c) 2017 Nobuhiko Miyamoto
9 ]]
10
11 local ExecutionContextBase= {}
12 --_G["openrtm.ExecutionContextBase"] = ExecutionContextBase
13
14
15 local TimeValue = require "openrtm.TimeValue"
16 local ExecutionContextWorker = require "openrtm.ExecutionContextWorker"
17 local ExecutionContextProfile = require "openrtm.ExecutionContextProfile"
18 local GlobalFactory = require "openrtm.GlobalFactory"
19 local NVUtil = require "openrtm.NVUtil"
20 local Properties = require "openrtm.Properties"
21
22
23 local DEFAULT_EXECUTION_RATE = 1000
24
25 -- 実行コンテキスト基底オブジェクト初期化関数
26 -- @param name 名前
27 -- @return 実行コンテキスト
28 ExecutionContextBase.new = function(name)
29     local obj = {}
30     local Manager = require "openrtm.Manager"
31     obj._ReturnCode_t = Manager:instance():getORB().types:lookup("::RTC::ReturnCode_t").labelvalue
32     obj._LifeCycleState = Manager:instance():getORB().types:lookup("::RTC::LifeCycleState").labelvalue
33
34     obj._rtcout = Manager:instance():getLogbuf("ec_base")
35     obj._activationTimeout   = TimeValue.new(0.5)
36     obj._degetConfigvationTimeout = TimeValue.new(0.5)
37     obj._resetTimeout        = TimeValue.new(0.5)
38     obj._syncActivation   = true
39     obj._syncDeactivation = true
40     obj._syncReset        = true
41     obj._worker  = ExecutionContextWorker.new()
42     obj._profile = ExecutionContextProfile.new()
43
44     -- 初期化時に実行コンテキストにプロパティを設定する
45     -- @param props プロパティ
46     function obj:init(props)
47         self._rtcout:RTC_TRACE("init()")
48         self._rtcout:RTC_DEBUG(props)
49         --print(props)
50         self:setExecutionRate(props)
51         self:setProperties(props)
52
53         self._syncActivation   = false
54         self._syncDeactivation = false
55         self._syncReset        = false
56     end
57     -- 実行コンテキストを終了する
58     function obj:exit()
59         self._rtcout:RTC_TRACE("exit()")
60         self._profile:exit()
61         self._worker:exit()
62     end
63     -- 実行周期を設定する
64     -- 「rate」の要素名から実行周期を取得する
65     -- @param props プロパティ
66     -- @return true:設定成功、false:設定失敗
67     -- 実行周期を数値に変換できなかった場合はfalse
68     function obj:setExecutionRate(props)
69         if props:findNode("rate") then
70             local rate_ = tonumber(props:getProperty("rate"))
71             if rate_ ~= nil then
72                 self:setRate(rate_)
73                 return true
74             end
75         end
76         return false
77     end
78
79     -- 実行周期設定
80     -- @param rate 実行周期
81     -- @return リターンコード
82     -- RTC_OK:onSettingRate、onSetRateがRTC_OKを返す
83     -- BAD_PARAMETER:不正な周期を指定
84     function obj:setRate(rate)
85         self._rtcout:RTC_TRACE("setRate("..rate..")")
86         local ret_ = self._profile:setRate(self:onSettingRate(rate))
87         if ret_ ~= self._ReturnCode_t.RTC_OK then
88             self._rtcout:RTC_ERROR("Setting execution rate failed. "..rate)
89             return ret_
90         end
91
92         ret_ = self._worker:rateChanged()
93         if ret_ ~= self._ReturnCode_t.RTC_OK then
94             self._rtcout:RTC_ERROR("Invoking on_rate_changed() for each RTC failed.")
95             return ret_
96         end
97
98         ret_ = self:onSetRate(rate)
99         if ret_ ~= self._ReturnCode_t.RTC_OK then
100             self._rtcout:RTC_ERROR("onSetRate("..rate..") failed.")
101             return ret_
102         end
103         self._rtcout:RTC_INFO("setRate("..rate..") done")
104         return ret_
105     end
106
107
108
109
110     -- プロパティの設定
111     -- @param props プロパティ
112     function obj:setProperties(props)
113         self._profile:setProperties(props)
114     end
115
116     -- オブジェクトリファレンス設定
117     -- @param ec_ptr オブジェクトリファレンス
118     function obj:setObjRef(ec_ptr)
119         self._worker:setECRef(ec_ptr)
120         self._profile:setObjRef(ec_ptr)
121     end
122
123     -- 実行コンテキストの種類設定
124     -- @param 実行コンテキストの種類
125     -- @return リターンコード
126     -- RTC_OK:正常に設定
127     -- BAD_PARAMETER:RTC::ExecutionKindに定義のない値
128     function obj:setKind(kind)
129         return self._profile:setKind(kind)
130     end
131
132     -- 実行コンテキストにRTCを関連付ける
133     -- @param rtc RTC
134     -- @return リターンコード
135     -- RTC_OK:正常にバインド
136     -- BAD_PARAMETER:RTCが不正
137     -- RTC_ERROR:実行コンテキストが不正
138     function obj:bindComponent(rtc)
139         return self._worker:bindComponent(rtc)
140     end
141
142     -- オブジェクトリファレンス取得
143     -- @return オブジェクトリファレンス
144     function obj:getObjRef()
145         return self._profile:getObjRef()
146     end
147
148     -- 実行コンテキストを開始する
149     -- @return リターンコード
150     -- RTC_OK:onStarting、onStartedがRTC_OKを返す
151     -- PRECONDITION_NOT_MET:既に実行状態
152     function obj:start()
153         self._rtcout:RTC_TRACE("start()")
154         local ret_ = self:onStarting()
155         if ret_ ~= self._ReturnCode_t.RTC_OK then
156             self._rtcout:RTC_ERROR("onStarting() failed. Starting EC aborted.")
157             return ret_
158         end
159
160         ret_ = self._worker:start()
161         if ret_ ~= self._ReturnCode_t.RTC_OK then
162             self._rtcout:RTC_ERROR("Invoking on_startup() for each RTC failed.")
163             return ret_
164         end
165
166         ret_ = self:onStarted()
167         if ret_ ~= self._ReturnCode_t.RTC_OK then
168             self._rtcout:RTC_ERROR("onStartted() failed. Started EC aborted..")
169             self._worker:stop()
170             self._rtcout:RTC_ERROR("on_shutdown() was invoked, because of onStarted")
171             return ret_
172         end
173
174         return ret_
175     end
176
177     -- 実行状態が変化時のコールバック
178     -- @param running 実行状態
179     -- @return 実行状態
180     function obj:onIsRunning(running)
181         return running
182     end
183     -- 実行コンテキスト開始時のコールバック
184     -- @return リターンコード
185     function obj:onStarting()
186         return self._ReturnCode_t.RTC_OK
187     end
188     -- 実行コンテキスト開始後のコールバック
189     -- @return リターンコード
190     function obj:onStarted()
191         return self._ReturnCode_t.RTC_OK
192     end
193     -- 実行コンテキスト停止時のコールバック
194     -- @return リターンコード
195     function obj:onStopping()
196         return self._ReturnCode_t.RTC_OK
197     end
198     -- 実行コンテキスト停止後のコールバック
199     -- @return リターンコード
200     function obj:onStopped()
201         return self._ReturnCode_t.RTC_OK
202     end
203     -- 実行周期取得時のコールバック
204     -- @param rate 実行周期
205     -- @return 実行周期
206     function obj:onGetRate(rate)
207         return rate
208     end
209     -- 実行周期設定時のコールバック
210     -- @param rate 実行周期
211     -- @return 実行周期
212     function obj:onSettingRate(rate)
213         --print(rate)
214         return rate
215     end
216
217     -- 実行周期設定後のコールバック
218     -- @param rate 実行周期
219     -- @return リターンコード
220     function obj:onSetRate(rate)
221         return self._ReturnCode_t.RTC_OK
222     end
223     -- RTC追加時のコールバック
224     -- @param rtobj RTC
225     -- @return リターンコード
226     function obj:onAddingComponent(rtobj)
227         return self._ReturnCode_t.RTC_OK
228     end
229     -- RTC追加後のコールバック
230     -- @param rtobj RTC
231     -- @return リターンコード
232     function obj:onAddedComponent(rtobj)
233         return self._ReturnCode_t.RTC_OK
234     end
235     -- RTC削除時のコールバック
236     -- @param rtobj RTC
237     -- @return リターンコード
238     function obj:onRemovingComponent(rtobj)
239         return self._ReturnCode_t.RTC_OK
240     end
241     -- RTC削除後のコールバック
242     -- @param rtobj RTC
243     -- @return リターンコード
244     function obj:onRemovedComponent(rtobj)
245         return self._ReturnCode_t.RTC_OK
246     end
247     -- アクティブ時のコールバック
248     -- @param comp RTC
249     -- @return リターンコード
250     function obj:onActivating(comp)
251         return self._ReturnCode_t.RTC_OK
252     end
253     -- アクティブ状態遷移待機後のコールバック
254     -- @param comp RTC
255     -- @param count 待機回数
256     -- @return リターンコード
257     function obj:onWaitingActivated(comp, count)
258         return self._ReturnCode_t.RTC_OK
259     end
260     -- アクティブ状態遷移後のコールバック
261     -- @param comp RTC
262     -- @param count 待機回数
263     -- @return リターンコード
264     function obj:onActivated(comp, count)
265         return self._ReturnCode_t.RTC_OK
266     end
267     -- アクティブ状態遷移開始時のコールバック
268     -- @param comp RTC
269     -- @return リターンコード
270     function obj:onActivating(comp)
271         return self._ReturnCode_t.RTC_OK
272     end
273     -- 非アクティブ状態遷移開始時のコールバック
274     -- @param comp RTC
275     -- @return リターンコード
276     function obj:onDeactivating(comp)
277         return self._ReturnCode_t.RTC_OK
278     end
279     -- 非アクティブ状態遷移後のコールバック
280     -- @param comp RTC
281     -- @param count 待機回数
282     -- @return リターンコード
283     function obj:onWaitingDeactivated(comp, count)
284         return self._ReturnCode_t.RTC_OK
285     end
286     -- 非アクティブ状態遷移後のコールバック
287     -- @param comp RTC
288     -- @param count 待機回数
289     -- @return リターンコード
290     function obj:onDeactivated(comp, count)
291         return self._ReturnCode_t.RTC_OK
292     end
293     -- リセット実行開始時のコールバック
294     -- @param comp RTC
295     -- @return リターンコード
296     function obj:onResetting(comp)
297         return self._ReturnCode_t.RTC_OK
298     end
299     -- リセット待機時のコールバック
300     -- @param comp RTC
301     -- @param count 待機回数
302     -- @return リターンコード
303     function obj:onWaitingReset(comp, count)
304         return self._ReturnCode_t.RTC_OK
305     end
306     -- リセット実行時のコールバック
307     -- @param comp RTC
308     -- @param count 待機回数
309     -- @return リターンコード
310     function obj:onReset(comp, count)
311         return self._ReturnCode_t.RTC_OK
312     end
313     -- RTC状態取得時のコールバック
314     -- @param state 状態
315     -- @return 状態
316     function obj:onGetComponentState(state)
317         return state
318     end
319     -- 実行コンテキスト種別取得時のコールバック
320     -- @param kind 種別
321     -- @return 種別
322     function obj:onGetKind(kind)
323         return kind
324     end
325     -- プロファイル得時のコールバック
326     -- @param profile プロファイル
327     -- @return プロファイル
328     function obj:onGetProfile(profile)
329         return profile
330     end
331     -- RTC実行前に呼び出す処理
332     -- onActivated、onAborting、onDeactivated、onResetが実行される
333     function obj:invokeWorkerPreDo()
334         self._worker:invokeWorkerPreDo()
335     end
336     -- RTC実行時に呼び出す処理
337     -- onExecute、onErrorが実行される
338     function obj:invokeWorkerDo()
339         self._worker:invokeWorkerDo()
340     end
341     -- RTC実行後に呼び出す処理
342     -- onStateUpdateが実行される
343     function obj:invokeWorkerPostDo()
344         self._worker:invokeWorkerPostDo()
345     end
346     -- 実行周期取得
347     -- @return 実行周期(秒)
348     function obj:getPeriod()
349         return self._profile:getPeriod()
350     end
351     -- 実行周期取得
352     -- @return 実行周期(Hz)
353     function obj:getRate()
354         local rate_ = self._profile:getRate()
355         return self:onGetRate(rate_)
356     end
357     -- RTCのアクティブ化
358     -- @param comp RTC
359     -- @return リターンコード
360     -- RTC_OK:onActivating、onActivatedがRTC_OKを返す
361     -- BAD_PARAMETER:指定RTCがバインドされていない
362     -- PRECONDITION_NOT_MET:非アクティブ状態以外の状態
363     function obj:activateComponent(comp)
364         self._rtcout:RTC_TRACE("activateComponent()")
365         local ret_ = self:onActivating(comp)
366         if ret_ ~= self._ReturnCode_t.RTC_OK then
367             self._rtcout:RTC_ERROR("onActivating() failed.")
368             return ret_
369         end
370
371         local rtobj_ = {object=nil}
372         ret_ = self._worker:activateComponent(comp, rtobj_)
373         if ret_ ~= self._ReturnCode_t.RTC_OK then
374             return ret_
375         end
376
377         if not self._syncActivation then
378             ret_ = self:onActivated(rtobj_.object, -1)
379             if ret_ ~= self._ReturnCode_t.RTC_OK then
380
381                 self._rtcout:RTC_ERROR("onActivated() failed.")
382             end
383             --print(ret_)
384             return ret_
385         end
386
387
388         self._rtcout:RTC_DEBUG("Synchronous activation mode. ")
389         self._rtcout:RTC_DEBUG("Waiting for the RTC to be ACTIVE state. ")
390         return self:waitForActivated(rtobj_.object)
391     end
392     -- RTCのアクティブ状態遷移まで待機する
393     -- @param rtobj RTC
394     -- @return リターンコード
395     function obj:waitForActivated(rtobj)
396         return self._ReturnCode_t.RTC_OK
397     end
398     -- RTCの非アクティブ化
399     -- @param comp RTC
400     -- @return リターンコード
401     -- RTC_OK:onDeactivating、onDeactivated
402     -- BAD_PARAMETER:指定RTCがバインドされていない
403     -- PRECONDITION_NOT_MET:アクティブ状態以外の状態
404     function obj:deactivateComponent(comp)
405         self._rtcout:RTC_TRACE("deactivateComponent()")
406         local ret_ = self:onDeactivating(comp)
407         if ret_ ~= self._ReturnCode_t.RTC_OK then
408             self._rtcout:RTC_ERROR("onDeactivating() failed.")
409             return ret_
410         end
411
412         local rtobj_ = {object=nil}
413         ret_ = self._worker:deactivateComponent(comp, rtobj_)
414         if ret_ ~= self._ReturnCode_t.RTC_OK then
415             return ret_
416         end
417
418         if not self._syncDeactivation then
419             ret_ = self:onDeactivated(rtobj_[0], -1)
420             if ret_ ~= self._ReturnCode_t.RTC_OK then
421                 self._rtcout:RTC_ERROR("onActivated() failed.")
422             end
423             return ret_
424         end
425
426         self._rtcout:RTC_DEBUG("Synchronous deactivation mode. ")
427         self._rtcout:RTC_DEBUG("Waiting for the RTC to be INACTIVE state. ")
428         return self:waitForDeactivated(rtobj_.object)
429
430     end
431     -- RTCの非アクティブ状態遷移まで待機する
432     -- @param rtobj RTC
433     -- @return リターンコード
434     function obj:waitForDeactivated(rtobj)
435         return self._ReturnCode_t.RTC_OK
436     end
437     -- RTCのリセット
438     -- @param comp RTC
439     -- @return リターンコード
440     -- RTC_OK:onResetting、onReset
441     -- BAD_PARAMETER:指定RTCがバインドされていない
442     -- PRECONDITION_NOT_MET:エラー状態以外の状態
443     function obj:resetComponent(comp)
444         self._rtcout:RTC_TRACE("resetComponent()")
445         local ret_ = self:onResetting(comp)
446         if ret_ ~= self._ReturnCode_t.RTC_OK then
447             self._rtcout:RTC_ERROR("onResetting() failed.")
448             return ret_
449         end
450
451         local rtobj_ = {object=nil}
452         ret_ = self._worker:resetComponent(comp, rtobj_)
453         if ret_ ~= self._ReturnCode_t.RTC_OK then
454             return ret_
455         end
456
457         if not self._syncReset then
458             ret_ = self:onReset(rtobj_[0], -1)
459             if ret_ ~= self._ReturnCode_t.RTC_OK then
460                 self._rtcout:RTC_ERROR("onReset() failed.")
461             end
462             return ret_
463         end
464
465         self._rtcout:RTC_DEBUG("Synchronous deactivation mode. ")
466         self._rtcout:RTC_DEBUG("Waiting for the RTC to be INACTIVE state. ")
467         return self:waitForReset(rtobj_.object)
468
469     end
470     -- RTCのリセット完了まで待機する
471     -- @param rtobj RTC
472     -- @return リターンコード
473     function obj:waitForReset(rtobj)
474         return self._ReturnCode_t.RTC_OK
475     end
476
477     -- 実行状態を取得
478     -- @return 実行状態
479     function obj:isRunning()
480         self._rtcout:RTC_TRACE("isRunning()")
481         return self._worker:isRunning()
482     end
483
484
485
486     -- 実行状態を取得
487     -- @return 実行状態
488     function obj:is_running()
489         self._rtcout:RTC_TRACE("is_running()")
490         return self:isRunning()
491     end
492
493     -- 実行周期を取得
494     -- @return 実行周期
495     function obj:get_rate()
496         return self:getRate()
497     end
498     -- 実行周期を設定
499     -- @param rate 実行周期
500     -- @return リターンコード
501     function obj:set_rate(rate)
502         return self:setRate(rate)
503     end
504     -- RTCのアクティブ化
505     -- @param comp RTC
506     -- @return リターンコード
507     function obj:activate_component(comp)
508         --print("activate_component")
509         return self:activateComponent(comp)
510     end
511     -- RTCの非アクティブ化
512     -- @param comp RTC
513     -- @return リターンコード
514     function obj:deactivate_component(comp)
515         return self:deactivateComponent(comp)
516     end
517     -- RTCのリセット
518     -- @param comp RTC
519     -- @return リターンコード
520     function obj:reset_component(comp)
521         return self:resetComponent(comp)
522     end
523     -- RTCの状態取得
524     -- @param comp RTC
525     -- @return 状態
526     function obj:get_component_state(comp)
527         return self:getComponentState(comp)
528     end
529     -- 実行コンテキストの種別取得
530     -- @return 種別
531     function obj:get_kind()
532         return self:getKind()
533     end
534     function obj:getKind()
535         local kind_ = self._profile:getKind()
536         self._rtcout:RTC_TRACE("getKind() = %s", self:getKindString(kind_))
537         kind_ = self:onGetKind(kind_)
538         self._rtcout:RTC_DEBUG("onGetKind() returns %s", self:getKindString(kind_))
539         return kind_
540     end
541     -- RTCの追加
542     -- @param comp RTC
543     -- @return リターンコード
544     function obj:addComponent(comp)
545         self._rtcout:RTC_TRACE("addComponent()")
546         local ret_ = self:onAddingComponent(comp)
547         if ret_ ~= self._ReturnCode_t.RTC_OK then
548             self._rtcout:RTC_ERROR("Error: onAddingComponent(). RTC is not attached.")
549             return ret_
550         end
551         
552         ret_ = self._worker:addComponent(comp)
553         if ret_ ~= self._ReturnCode_t.RTC_OK then
554               self._rtcout:RTC_ERROR("Error: ECWorker addComponent() faild.")
555             return ret_
556         end
557         
558         ret_ = self._profile:addComponent(comp)
559         if ret_ ~= self._ReturnCode_t.RTC_OK then
560             self._rtcout:RTC_ERROR("Error: ECProfile addComponent() faild.")
561             return ret_
562         end
563         
564         ret_ = self:onAddedComponent(comp)
565         if ret_ ~= self._ReturnCode_t.RTC_OK then
566             self._rtcout:RTC_ERROR("Error: onAddedComponent() faild.")
567             self._rtcout:RTC_INFO("Removing attached RTC.")
568             self._worker:removeComponent(comp)
569             self._profile:removeComponent(comp)
570             return ret_
571         end
572     
573         self._rtcout:RTC_INFO("Component has been added to this EC.")
574         return self._ReturnCode_t.RTC_OK
575     end
576     -- RTCの追加
577     -- @param comp RTC
578     -- @return リターンコード
579     function obj:add_component(comp)
580         return self:addComponent(comp)
581     end
582     -- RTCの削除
583     -- @param comp RTC
584     -- @return リターンコード
585     function obj:removeComponent(comp)
586         self._rtcout:RTC_TRACE("removeComponent()")
587         local ret_ = self:onRemovingComponent(comp)
588         if ret_ ~= self._ReturnCode_t.RTC_OK then
589             self._rtcout:RTC_ERROR("Error: onRemovingComponent(). RTC will not not attached.")
590             return ret_
591         end
592     
593         ret_ = self._worker:removeComponent(comp)
594         if ret_ ~= self._ReturnCode_t.RTC_OK then
595             self._rtcout:RTC_ERROR("Error: ECWorker removeComponent() faild.")
596             return ret_
597         end
598     
599         ret_ = self._profile:removeComponent(comp)
600         if ret_ ~= self._ReturnCode_t.RTC_OK then
601             self._rtcout:RTC_ERROR("Error: ECProfile removeComponent() faild.")
602             return ret_
603         end
604     
605         ret_ = self:onRemovedComponent(comp)
606         if ret_ ~= self._ReturnCode_t.RTC_OK then
607             self._rtcout:RTC_ERROR("Error: onRemovedComponent() faild.")
608             self._rtcout:RTC_INFO("Removing attached RTC.")
609             self._worker:removeComponent(comp)
610             self._profile:removeComponent(comp)
611             return ret_
612         end
613     
614         self._rtcout:RTC_INFO("Component has been removeed to this EC.")
615         return self._ReturnCode_t.RTC_OK
616     end
617     -- RTCの削除
618     -- @param comp RTC
619     -- @return リターンコード
620     function obj:remove_component(comp)
621         return self:removeComponent(comp)
622     end
623     -- プロファイル取得
624     -- @return プロファイル
625     function obj:get_profile()
626         return self:getProfile()
627     end
628     -- プロファイル取得
629     -- @return プロファイル
630     function obj:getProfile()
631         self._rtcout:RTC_TRACE("getProfile()")
632         local prof_ = self._profile:getProfile()
633         self._rtcout:RTC_DEBUG("kind: "..self:getKindString(prof_.kind))
634         self._rtcout:RTC_DEBUG("rate: "..prof_.rate)
635         self._rtcout:RTC_DEBUG("properties:")
636         local props_ = Properties.new()
637         NVUtil.copyToProperties(props_, prof_.properties)
638         self._rtcout:RTC_DEBUG(props_)
639         return self:onGetProfile(prof_)
640     end
641     -- 実行コンテキストの種別取得
642     -- @return 種別
643     function obj:getKindString(kind)
644         return self._profile:getKindString(kind)
645     end
646
647     -- RTCの状態取得
648     -- @param comp RTC
649     -- @return 状態
650     function obj:getComponentState(comp)
651         local state_ = self._worker:getComponentState(comp)
652         self._rtcout:RTC_TRACE("getComponentState() = "..self:getStateString(state_))
653         if state_ == self._LifeCycleState.CREATED_STATE then
654             self._rtcout:RTC_ERROR("CREATED state: not initialized "..
655                                  "RTC or unknwon RTC specified.")
656         end
657
658         return self:onGetComponentState(state_)
659     end
660     -- RTCの状態を文字列に変換
661     -- @param state 状態
662     -- @return 文字列化した状態
663     function obj:getStateString(state)
664         return self._worker:getStateString(state)
665     end
666
667     -- 実行コンテキストの停止
668     -- @return リターンコード
669     -- RTC_OK:onStopping、onStoppedがRTC_OKを返す
670     -- PRECONDITION_NOT_MET:既に停止状態
671     function obj:stop()
672         self._rtcout:RTC_TRACE("stop()")
673         local ret_ = self:onStopping()
674         if ret_ ~= self._ReturnCode_t.RTC_OK then
675             self._rtcout:RTC_ERROR("onStopping() failed. Stopping EC aborted.")
676             return ret_
677         end
678
679         ret_ = self._worker:stop()
680         if ret_ ~= self._ReturnCode_t.RTC_OK then
681             self._rtcout:RTC_ERROR("Invoking on_shutdown() for each RTC failed.")
682             return ret_
683         end
684
685         ret_ = self:onStopped()
686         if ret_ ~= self._ReturnCode_t.RTC_OK then
687             self._rtcout:RTC_ERROR("onStopped() failed. Stopped EC aborted.")
688             return ret_
689         end
690
691         return ret_
692     end
693
694
695
696     return obj
697 end
698
699
700 ExecutionContextBase.ExecutionContextFactory = {}
701 setmetatable(ExecutionContextBase.ExecutionContextFactory, {__index=GlobalFactory.Factory.new()})
702
703 function ExecutionContextBase.ExecutionContextFactory:instance()
704     return self
705 end
706
707 return ExecutionContextBase

File lua\openrtm\ExecutionContextProfile.lua

1 ---------------------------------
2 --! @file ExecutionContextProfile.lua
3 --! @brief 実行コンテキストのプロファイル保持クラス定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local ExecutionContextProfile= {}
11 --_G["openrtm.ExecutionContextProfile"] = ExecutionContextProfile
12
13 local oil = require "oil"
14
15 local TimeValue = require "openrtm.TimeValue"
16 local NVUtil = require "openrtm.NVUtil"
17 local CORBA_SeqUtil = require "openrtm.CORBA_SeqUtil"
18
19 local DEFAULT_PERIOD = 0.000001
20
21
22 local find_participant = function(comp)
23  local obj = {}
24  obj._comp = comp
25
26  local call_func = function(self, comp)
27   return NVUtil._is_equivalent(comp, self._comp, comp.getObjRef, self._comp.getObjRef)
28  end
29  setmetatable(obj, {__call=call_func})
30  return obj
31 end
32
33 -- 実行コンテキストのプロファイル保持オブジェクト初期化関数
34 -- @param kind 種別
35 -- @return 実行コンテキストのプロファイル保持オブジェクト
36 ExecutionContextProfile.new = function(kind)
37  local obj = {}
38  local Manager = require "openrtm.Manager"
39  obj._ExecutionKind = Manager:instance():getORB().types:lookup("::RTC::ExecutionKind").labelvalue
40  obj._ReturnCode_t = Manager:instance():getORB().types:lookup("::RTC::ReturnCode_t").labelvalue
41
42  if kind == nil then
43   kind = obj._ExecutionKind.PERIODIC
44  end
45  obj._rtcout = Manager:instance():getLogbuf("periodic_ecprofile")
46  obj._period = TimeValue.new(DEFAULT_PERIOD)
47     obj._rtcout:RTC_TRACE("ExecutionContextProfile.__init__()")
48     obj._rtcout:RTC_DEBUG("Actual rate: "..obj._period:sec().." [sec], "..obj._period:usec().." [usec]")
49     obj._ref = oil.corba.idl.null
50     obj._profile = {kind=obj._ExecutionKind.PERIODIC,
51      rate=1.0/obj._period:toDouble(),
52      owner=oil.corba.idl.null, participants={},
53      properties={}}
54
55  -- 実行コンテキスト終了
56  function obj:exit()
57   self._rtcout:RTC_TRACE("exit")
58   self._profile.owner = oil.corba.idl.null
59   self._profile.participants = {}
60   self._profile.properties = {}
61   self._ref = oil.corba.idl.null
62  end
63  -- 実行周期設定
64  -- @param rate 実行周期
65  -- @return リターンコード
66  -- RTC_OK:onSettingRate、onSetRateがRTC_OKを返す
67  -- BAD_PARAMETER:不正な周期を指定
68  function obj:setRate(rate)
69   self._rtcout:RTC_TRACE("setRate("..rate..")")
70   if rate <= 0.0 then
71    return self._ReturnCode_t.BAD_PARAMETER
72   end
73   self._profile.rate = rate
74   self._period = TimeValue.new(1.0 / rate)
75   return self._ReturnCode_t.RTC_OK
76  end
77  -- プロパティ設定
78  -- @param props プロパティ
79  function obj:setProperties(props)
80   self._rtcout:RTC_TRACE("setProperties()")
81   self._rtcout:RTC_DEBUG(props)
82   NVUtil.copyFromProperties(self._profile.properties, props)
83  end
84  -- オブジェクトリファレンス設定
85  -- @param ec_ptr オブジェクトリファレンス
86  function obj:setObjRef(ec_ptr)
87   self._rtcout:RTC_TRACE("setObjRef()")
88   self._ref = ec_ptr
89  end
90  -- オブジェクトリファレンス取得
91  -- @return オブジェクトリファレンス
92  function obj:getObjRef()
93   self._rtcout:RTC_TRACE("getObjRef()")
94   return self._ref
95  end
96  -- 種別設定
97  -- @param kind 種別
98  -- @return リターンコード
99  -- RTC_OK:正常に設定
100     -- BAD_PARAMETER:RTC::ExecutionKindに定義のない値
101  function obj:setKind(kind)
102   if kind < self._ExecutionKind.PERIODIC or kind > self._ExecutionKind.OTHER then
103    self._rtcout:RTC_ERROR("Invalid kind is given. "..kind)
104    return self._ReturnCode_t.BAD_PARAMETER
105   end
106
107   self._rtcout:RTC_TRACE("setKind("..self:getKindString(kind)..")")
108   --print(self:getKindString(kind))
109   self._profile.kind = kind
110   return self._ReturnCode_t.RTC_OK
111  end
112  function obj:getKind()
113   self._rtcout:RTC_TRACE("%s = getKind()", self:getKindString(self._profile.kind))
114      return self._profile.kind
115  end
116  -- 実行コンテキストの種別を文字列に変換
117  -- @param kind 種別
118  -- @return 文字列に変換した種別
119  function obj:getKindString(kind)
120   local kinds_ = {"PERIODIC", "EVENT_DRIVEN", "OTHER"}
121   local kind_ = kind
122   if kind_ == nil then
123    kind_ = self._profile.kind
124   else
125    kind_ = kind
126   end
127
128   if kind_ < self._ExecutionKind.PERIODIC or kind_ > self._ExecutionKind.OTHER then
129    return ""
130   end
131
132   return kinds_[kind_+1]
133  end
134  -- 実行周期取得
135  -- @return 実行周期(Hz)
136  function obj:getRate()
137   return self._profile.rate
138  end
139  -- 実行周期取得
140  -- @return 実行周期(秒)
141  function obj:getPeriod()
142   return self._period
143  end
144  -- プロファイル取得
145  -- @return プロファイル
146  function obj:getProfile()
147   self._rtcout:RTC_TRACE("getProfile()")
148   return self._profile
149  end
150
151  function obj:addComponent(comp)
152   self._rtcout:RTC_TRACE("addComponent()")
153   if comp == oil.corba.idl.null then
154    self._rtcout:RTC_ERROR("A nil reference was given.")
155       return self._ReturnCode_t.BAD_PARAMETER
156   end
157      local rtobj_ = comp
158      --[[
159   if rtobj_ == oil.corba.idl.null then
160         self._rtcout:RTC_ERROR("Narrowing was failed.")
161       return self._ReturnCode_t.RTC_ERROR
162   end
163   --]]
164   table.insert(self._profile.participants, rtobj_)
165         
166      return self._ReturnCode_t.RTC_OK
167  end
168
169
170  function obj:removeComponent(comp)
171   self._rtcout:RTC_TRACE("removeComponent()")
172   if comp == oil.corba.idl.null then
173    self._rtcout:RTC_ERROR("A nil reference was given.")
174    return self._ReturnCode_t.BAD_PARAMETER
175   end
176
177   local rtobj_ = comp
178   --[[
179   if rtobj_== oil.corba.idl.null then
180    self._rtcout:RTC_ERROR("Narrowing was failed.")
181    return self._ReturnCode_t.RTC_ERROR
182   end
183   --]]
184
185         
186         local index_ = CORBA_SeqUtil.find(self._profile.participants,
187                                         find_participant(rtobj_))
188         if index_ < 0 then
189             self._rtcout:RTC_ERROR("The given RTObject does not exist in the EC.")
190             return self._ReturnCode_t.BAD_PARAMETER
191         end
192         table.remove(self._profile.participants, index_)
193         return self._ReturnCode_t.RTC_OK
194     end
195
196     return obj
197 end
198
199
200 return ExecutionContextProfile

File lua\openrtm\ExecutionContextWorker.lua

1 ---------------------------------
2 --! @file ExecutionContextWorker.lua
3 --! @brief 実行コンテキスト状態遷移マシン駆動クラス
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local ExecutionContextWorker= {}
11 --_G["openrtm.ExecutionContextWorker"] = ExecutionContextWorker
12
13
14 local oil = require "oil"
15 local RTObjectStateMachine = require "openrtm.RTObjectStateMachine"
16 local StringUtil = require "openrtm.StringUtil"
17
18
19
20 -- 実行コンテキスト状態遷移マシン駆動オブジェクト初期化
21 -- @return 実行コンテキスト状態遷移マシン駆動オブジェクト
22 ExecutionContextWorker.new = function()
23     local obj = {}
24     local RTObject = require "openrtm.RTObject"
25     local ECOTHER_OFFSET = RTObject.ECOTHER_OFFSET
26     local Manager = require "openrtm.Manager"
27     obj._ReturnCode_t = Manager:instance():getORB().types:lookup("::RTC::ReturnCode_t").labelvalue
28     obj._LifeCycleState = Manager:instance():getORB().types:lookup("::RTC::LifeCycleState").labelvalue
29
30     obj._rtcout = Manager:instance():getLogbuf("ec_worker")
31     obj._running = false
32     obj._rtcout:RTC_TRACE("ExecutionContextWorker.__init__")
33     obj._ref = nil
34     obj._comps = {}
35     obj._addedComps = {}
36     obj._removedComps = {}
37     -- 実行コンテキスト終了
38     function obj:exit()
39         self._rtcout:RTC_TRACE("exit")
40     end
41     -- 実行周期変更後に実行する関数
42     -- @return リターンコード
43     -- RTC_OK:全てのRTCのonRateChangedコールバックがRTC_OKを返す
44     function obj:rateChanged()
45         self._rtcout:RTC_TRACE("rateChanged()")
46         local ret = self._ReturnCode_t.RTC_OK
47         for i,comp in ipairs(self._comps) do
48             tmp = comp:onRateChanged()
49             if tmp ~= self._ReturnCode_t.RTC_OK then
50                 ret = tmp
51             end
52         end
53         return ret
54     end
55     -- オブジェクトリファレンス設定
56     -- @param ref オブジェクトリファレンス
57     function obj:setECRef(ref)
58         self._ref = ref
59     end
60     -- RTCを関連付ける
61     -- @param rtc RTC
62     -- @return リターンコード
63     -- RTC_OK:正常にバインド
64     -- BAD_PARAMETER:RTCが不正
65     -- RTC_ERROR:実行コンテキストが不正
66     function obj:bindComponent(rtc)
67         self._rtcout:RTC_TRACE("bindComponent()")
68         if rtc == nil then
69             self._rtcout:RTC_ERROR("NULL pointer is given.")
70             return self._ReturnCode_t.BAD_PARAMETER
71         end
72         local ec_ = self:getECRef()
73         --print(ec_)
74         local id_ = rtc:bindContext(ec_)
75         if id_ < 0 or id_ > ECOTHER_OFFSET then
76             self._rtcout:RTC_ERROR("bindContext returns invalid id: "..id_)
77             return self._ReturnCode_t.RTC_ERROR
78         end
79
80         self._rtcout:RTC_DEBUG("bindContext returns id = "..id_)
81
82         --local comp_ = rtc:getObjRef()
83         local comp_ = rtc
84         table.insert(self._comps, RTObjectStateMachine.new(id_, comp_))
85         self._rtcout:RTC_DEBUG("bindComponent() succeeded.")
86         return self._ReturnCode_t.RTC_OK
87     end
88     -- オブジェクトリファレンス取得
89     -- @return オブジェクトリファレンス
90     function obj:getECRef()
91         return self._ref
92     end
93     -- 実行コンテキスト開始
94     -- @return リターンコード
95     -- RTC_OK:正常終了
96     -- PRECONDITION_NOT_MET:既に実行状態
97     function obj:start()
98         self._rtcout:RTC_TRACE("start()")
99         if self._running then
100             self._rtcout:RTC_WARN("ExecutionContext is already running.")
101             return self._ReturnCode_t.PRECONDITION_NOT_MET
102         end
103         --print(#self._comps)
104
105         for i, comp in ipairs(self._comps) do
106             comp:onStartup()
107         end
108
109         self._rtcout:RTC_DEBUG(#self._comps.." components started.")
110         self._running = true
111         return self._ReturnCode_t.RTC_OK
112     end
113     -- 実行コンテキスト開始
114     -- @return リターンコード
115     -- RTC_OK:正常終了
116     -- PRECONDITION_NOT_MET:既に停止状態
117     function obj:stop()
118         self._rtcout:RTC_TRACE("stop()")
119
120         if not self._running then
121           self._rtcout:RTC_WARN("ExecutionContext is already stopped.")
122           return self._ReturnCode_t.PRECONDITION_NOT_MET
123         end
124
125         self._running = false
126
127         for i, comp in ipairs(self._comps) do
128           comp:onShutdown()
129         end
130
131
132         return self._ReturnCode_t.RTC_OK
133     end
134     -- RTC実行前に実行する処理
135     -- onActivated、onAborting、onDeactivated、onResetが実行される
136     function obj:invokeWorkerPreDo()
137         self._rtcout:RTC_PARANOID("invokeWorkerPreDo()")
138         for i, comp in ipairs(self._comps) do
139             comp:workerPreDo()
140         end
141     end
142     -- RTC実行
143     -- onExecute、onErrorが実行される
144     function obj:invokeWorkerDo()
145         self._rtcout:RTC_PARANOID("invokeWorkerDo()")
146         for i, comp in ipairs(self._comps) do
147             comp:workerDo()
148         end
149     end
150     -- RTC実行後に実行する処理
151     -- onStateUpdateが実行される
152     function obj:invokeWorkerPostDo()
153         self._rtcout:RTC_PARANOID("invokeWorkerPostDo()")
154         for i, comp in ipairs(self._comps) do
155             comp:workerPostDo()
156         end
157         self:updateComponentList()
158     end
159     -- RTCのアクティブ化
160     -- @param comp RTCのオブジェクトリファレンス
161     -- @param rtobj 状態遷移マシンを格納する変数
162     -- @return リターンコード
163     -- RTC_OK:正常終了
164     -- BAD_PARAMETER:指定RTCがバインドされていない
165     -- PRECONDITION_NOT_MET:非アクティブ状態以外の状態
166     function obj:activateComponent(comp, rtobj)
167         self._rtcout:RTC_TRACE("activateComponent()")
168         local obj_ = self:findComponent(comp)
169         if obj_ == nil then
170             self._rtcout:RTC_ERROR("Given RTC is not participant of this EC.")
171             return self._ReturnCode_t.BAD_PARAMETER
172         end
173
174         self._rtcout:RTC_DEBUG("Component found in the EC.")
175         --print(obj_:isCurrentState(self._LifeCycleState.INACTIVE_STATE))
176         --print(self._ReturnCode_t.INACTIVE_STATE)
177         if not obj_:isCurrentState(self._LifeCycleState.INACTIVE_STATE) then
178             self._rtcout:RTC_ERROR("State of the RTC is not INACTIVE_STATE.")
179             return self._ReturnCode_t.PRECONDITION_NOT_MET
180         end
181
182         self._rtcout:RTC_DEBUG("Component is in INACTIVE state. Going to ACTIVE state.")
183         --print("aaaaaa")
184         obj_:goTo(self._LifeCycleState.ACTIVE_STATE)
185         rtobj.object = obj_
186
187         self._rtcout:RTC_DEBUG("activateComponent() done.")
188         return self._ReturnCode_t.RTC_OK
189     end
190     -- RTCの非アクティブ化
191     -- @param comp 状態遷移マシン
192     -- @param rtobj オブジェクトリファレンスを格納する変数
193     -- @return リターンコード
194     -- RTC_OK:正常終了
195     -- BAD_PARAMETER:指定RTCがバインドされていない
196     -- PRECONDITION_NOT_MET:アクティブ状態以外の状態
197     function obj:deactivateComponent(comp, rtobj)
198         self._rtcout:RTC_TRACE("deactivateComponent()")
199         local obj_ = self:findComponent(comp)
200         if obj_ == nil then
201             self._rtcout:RTC_ERROR("Given RTC is not participant of this EC.")
202             return self._ReturnCode_t.BAD_PARAMETER
203         end
204
205         self._rtcout:RTC_DEBUG("Component found in the EC.")
206
207         if not obj_:isCurrentState(self._LifeCycleState.ACTIVE_STATE) then
208             self._rtcout:RTC_ERROR("State of the RTC is not ACTIVE_STATE.")
209             return self._ReturnCode_t.PRECONDITION_NOT_MET
210         end
211
212
213
214         obj_:goTo(self._LifeCycleState.INACTIVE_STATE)
215         rtobj.object = obj_
216
217
218         return self._ReturnCode_t.RTC_OK
219     end
220     -- RTCのリセット
221     -- @param comp 状態遷移マシン
222     -- @param rtobj オブジェクトリファレンスを格納する変数
223     -- @return リターンコード
224     -- RTC_OK:正常終了
225     -- BAD_PARAMETER:指定RTCがバインドされていない
226     -- PRECONDITION_NOT_MET:エラー状態以外の状態
227     function obj:resetComponent(comp, rtobj)
228         self._rtcout:RTC_TRACE("resetComponent()")
229         local obj_ = self:findComponent(comp)
230         if obj_ == nil then
231             self._rtcout:RTC_ERROR("Given RTC is not participant of this EC.")
232             return self._ReturnCode_t.BAD_PARAMETER
233         end
234
235         self._rtcout:RTC_DEBUG("Component found in the EC.")
236
237         if not obj_:isCurrentState(self._LifeCycleState.ERROR_STATE) then
238             self._rtcout:RTC_ERROR("State of the RTC is not ERROR_STATE.")
239             return self._ReturnCode_t.PRECONDITION_NOT_MET
240         end
241
242
243
244         obj_:goTo(self._LifeCycleState.INACTIVE_STATE)
245         rtobj.object = obj_
246
247
248         return self._ReturnCode_t.RTC_OK
249     end
250     -- 指定のRTCのオブジェクトリファレンスから状態遷移マシンを検索
251     -- @param comp RTCのオブジェクトリファレンス
252     -- @return 状態遷移マシン
253     function obj:findComponent(comp)
254         for i, comp_ in ipairs(self._comps) do
255             --print(comp_:isEquivalent(comp))
256             if comp_:isEquivalent(comp) then
257                 return comp_
258             end
259         end
260         return nil
261     end
262
263     -- RTCのリスト更新
264     function obj:updateComponentList()
265         for k,comp in ipairs(self._addedComps) do
266             table.insert(self._comps, comp)
267             self._rtcout:RTC_TRACE("Component added.")
268         end
269
270         self._addedComps = {}
271         
272     
273         
274         for k, comp in ipairs(self._removedComps) do
275             local lwrtobj_ = comp:getRTObject()
276             lwrtobj_:detach_context(comp:getExecutionContextHandle())
277
278             local idx_ = StringUtil.table_index(self._comps, comp)
279     
280             if idx_ > 0 then
281                 table.remove(self._comps, idx_)
282                 self._rtcout:RTC_TRACE("Component deleted.")
283             end
284         end
285     
286         self._removedComps = {}
287     end
288
289     -- 指定のRTCのオブジェクトリファレンスから状態を取得
290     -- @param comp RTCのオブジェクトリファレンス
291     -- @return 状態
292     function obj:getComponentState(comp)
293         self._rtcout:RTC_TRACE("getComponentState()")
294
295         local rtobj_ = self:findComponent(comp)
296         if rtobj_ == nil then
297             self._rtcout:RTC_WARN("Given RTC is not participant of this EC.")
298             return self._LifeCycleState.CREATED_STATE
299         end
300
301         local state_ = rtobj_:getState()
302
303         self._rtcout:RTC_DEBUG("getComponentState() = "..self:getStateString(state_).." done")
304         return state_
305     end
306
307     -- 状態を文字列に変換
308     -- @param state 状態
309     -- @return 文字列に変換した状態
310     function obj:getStateString(state)
311         local st = {"CREATED_STATE",
312               "INACTIVE_STATE",
313               "ACTIVE_STATE",
314               "ERROR_STATE"}
315
316         if st[state+1] == nil then
317             return ""
318         else
319             return st[state+1]
320         end
321     end
322
323     -- 実行状態を取得
324     -- @return 実行状態
325     function obj:isRunning()
326         self._rtcout:RTC_TRACE("isRunning()")
327         return self._running
328     end
329
330
331     function obj:addComponent(comp)
332         self._rtcout:RTC_TRACE("addComponent()")
333         if comp == oil.corba.idl.null then
334             self._rtcout:RTC_ERROR("nil reference is given.")
335             return self._ReturnCode_t.BAD_PARAMETER
336         end
337         local success, exception = oil.pcall(
338         function()
339             local ec_ = self:getECRef()
340             local id_ = comp:attach_context(ec_)
341             
342             table.insert(self._addedComps, RTObjectStateMachine.new(id_, comp))
343         end)
344         if not success then
345             self._rtcout:RTC_ERROR("addComponent() failed.")
346             return self._ReturnCode_t.RTC_ERROR
347         end
348     
349
350         self._rtcout:RTC_DEBUG("addComponent() succeeded.")
351         --if self._running == false then
352         -- self.updateComponentList()
353         --end
354         self:updateComponentList()
355         return self._ReturnCode_t.RTC_OK
356     end
357
358     function obj:removeComponent(comp)
359         self._rtcout:RTC_TRACE("removeComponent()")
360         if comp == oil.corba.idl.null then
361             self._rtcout:RTC_ERROR("nil reference is given.")
362             return self._ReturnCode_t.BAD_PARAMETER
363         end
364
365         local rtobj_ = self:findComponent(comp)
366
367            if rtobj_ == nil then
368             self._rtcout:RTC_ERROR("no RTC found in this context.")
369             return self._ReturnCode_t.BAD_PARAMETER
370         end
371
372         table.insert(self._removedComps, rtobj_)
373
374         --if self._running == false then
375         -- self:updateComponentList()
376         --end
377         self:updateComponentList()
378         return self._ReturnCode_t.RTC_OK
379     end
380
381
382
383     return obj
384 end
385
386
387 return ExecutionContextWorker

File lua\openrtm\Factory.lua

1 ---------------------------------
2 --! @file Factory.lua
3 --! @brief RTC生成ファクトリ定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local Factory= {}
11 --_G["openrtm.Factory"] = Factory
12
13 local oil = require "oil"
14
15
16 -- RTC削除関数
17 -- @param rtc RTC
18 Factory.Delete = function(rtc)
19 end
20
21 Factory.FactoryBase = {}
22
23 -- RTC生成ファクトリ基底オブジェクト初期化
24 -- @param profile RTCのプロファイル
25 -- @return RTC生成ファクトリ
26 Factory.FactoryBase.new = function(profile)
27     local obj = {}
28     -- 初期化に呼ばれる関数
29     function obj:init()
30         self._Profile = profile
31         self._Number = -1
32     end
33     -- RTCの生成
34     -- @param mgr マネージャ
35     -- @return RTC
36     function obj:create(mgr)
37     end
38     -- RTCの削除
39     -- @param mgr マネージャ
40     function obj:destroy(mgr)
41     end
42     -- プロファイル取得
43     -- @return プロファイル
44     function obj:profile()
45         return self._Profile
46     end
47     -- RTCの数取得
48     -- RTC数
49     function obj:number()
50         return self._Number
51     end
52
53
54     obj:init()
55     return obj
56 end
57
58
59
60 Factory.FactoryLua = {}
61
62 -- RTC生成ファクトリ初期化
63 -- @param profile RTCのプロファイル
64 -- @param new_func 生成関数
65 -- @param delete_func 削除関数
66 -- @param policy 番号付けポリシー
67 -- @return RTC生成ファクトリ
68 Factory.FactoryLua.new = function(profile, new_func, delete_func, policy)
69     local obj = {}
70     setmetatable(obj, {__index=Factory.FactoryBase.new(profile)})
71     -- 初期化時に呼び出される関数
72     function obj:init()
73         if policy == nil then
74             local NumberingPolicy = require "openrtm.NumberingPolicy"
75             self._policy = NumberingPolicy.ProcessUniquePolicy.new()
76         else
77             self._policy = policy
78         end
79         self._New = new_func
80         self._Delete = delete_func
81     end
82     -- RTC生成
83     -- 生成するたびにカウントアップする
84     -- RTCを削除した場合は、削除済みの番号に割り当てる
85     -- @param mgr マネージャ
86     -- @return RTC
87     function obj:create(mgr)
88         local ret = nil
89         local success, exception = oil.pcall(
90             function()
91                 --print(mgr)
92                 local rtobj = self._New(mgr)
93                 if rtobj == nil then
94                     return nil
95                 end
96                 self._Number = self._Number + 1
97                 rtobj:setProperties(self:profile())
98                 local instance_name = rtobj:getTypeName()
99                 local instance_name = instance_name..self._policy:onCreate(rtobj)
100                 rtobj:setInstanceName(instance_name)
101                 ret = rtobj
102             end)
103         if not success then
104             print(exception)
105         end
106         return ret
107     end
108     -- RTC削除
109     -- @param mgr マネージャ
110     function obj:destroy(comp)
111         self._Number = self._Number - 1
112         self._policy:onDelete(comp)
113         self._Delete(comp)
114     end
115
116
117
118     obj:init()
119     return obj
120 end
121
122
123
124 return Factory

File lua\openrtm\FactoryInit.lua

Full coverage

File lua\openrtm\GlobalFactory.lua

1 ---------------------------------
2 --! @file GlobalFactory.lua
3 --! @brief オブジェクト生成ファクトリ定義
4 --! FACTORY_OK:正常
5 --! FACTORY_ERROR:エラー
6 --! ALREADY_EXISTS:既に指定ファクトリが存在
7 --! NOT_FOUND:指定ファクトリがない
8 --! INVALID_ARG:不正な引数
9 --! UNKNOWN_ERROR:それ以外のエラー
10 ---------------------------------
11
12 --[[
13 Copyright (c) 2017 Nobuhiko Miyamoto
14 ]]
15
16 local GlobalFactory= {}
17 --_G["openrtm.GlobalFactory"] = GlobalFactory
18
19 GlobalFactory.Factory = {}
20
21 GlobalFactory.Factory.FACTORY_OK = 0
22 GlobalFactory.Factory.FACTORY_ERROR = 1
23 GlobalFactory.Factory.ALREADY_EXISTS = 2
24 GlobalFactory.Factory.NOT_FOUND = 3
25 GlobalFactory.Factory.INVALID_ARG = 4
26 GlobalFactory.Factory.UNKNOWN_ERROR = 5
27
28 local FactoryEntry = {}
29
30 -- オブジェクト生成ファクトリ関数初期化
31 -- @param id 識別子
32 -- @param creator 生成関数
33 -- @param destructor 削除関数
34 -- @return 生成オブジェクト
35 function FactoryEntry.new(id, creator, destructor)
36     local obj = {}
37     obj.id_ = id
38     obj.creator_ = creator
39     obj.destructor_ = destructor
40     return obj
41 end
42
43 -- ファクトリ登録オブジェクト初期化
44 -- @return ファクトリ登録オブジェクト
45 GlobalFactory.Factory.new = function()
46     local obj = {}
47     obj._creators = {}
48     obj._objects = {}
49     -- 指定IDのファクトリが存在するかの確認
50     -- @param id 識別子
51     -- @return true:存在する、false:存在しない
52     function obj:hasFactory(id)
53         if self._creators[id] == nil then
54             return false
55         else
56             return true
57         end
58     end
59     
60     -- 登録ファクトリのID一覧を取得
61     -- @return ID一覧
62     function obj:getIdentifiers()
63         local idlist = {}
64         for i, ver in pairs(self._creators) do
65             table.insert(idlist, i)
66         end
67         return idlist
68     end
69
70     -- ファクトリ追加
71     -- @param id 識別子
72     -- @param creator 生成関数
73     -- @param destructor 削除関数
74     -- @return リターンコード
75     -- FACTORY_OK:正常に追加
76     -- ALREADY_EXISTS:既に指定IDで追加済み
77     -- INVALID_ARG:不正な引数
78     function obj:addFactory(id, creator, destructor)
79         --print("test",creator,destructor)
80         if creator == nil or destructor == nil then
81             return GlobalFactory.Factory.INVALID_ARG
82         end
83
84         if self._creators[id] ~= nil then
85             return GlobalFactory.Factory.ALREADY_EXISTS
86         end
87
88         self._creators[id] = FactoryEntry.new(id, creator, destructor)
89         return GlobalFactory.Factory.FACTORY_OK
90     end
91
92
93     -- ファクトリ削除
94     -- @param id 識別子
95     -- @return リターンコード
96     -- FACTORY_OK:正常に削除
97     -- NOT_FOUND:ファクトリがない
98     function obj:removeFactory(id)
99
100         if self._creators[id] == nil then
101             return GlobalFactory.Factory.NOT_FOUND
102         end
103
104         self._creators[id] = nil
105         return GlobalFactory.Factory.FACTORY_OK
106     end
107
108     -- 指定オブジェクトを生成
109     -- @param id 識別子
110     -- @return オブジェクト
111     function obj:createObject(id)
112
113         if self._creators[id] == nil then
114             print("Factory.createObject return nil id: "..id)
115             return nil
116         end
117
118         local obj_ = self._creators[id].creator_()
119         self._objects[obj_] = self._creators[id]
120         --for k,v in pairs(self._objects) do
121         -- print(k,v)
122         --end
123         return obj_
124     end
125
126     -- 指定オブジェクトを削除
127     -- @param obj オブジェクト
128     -- @param id 識別子
129     -- @return リターンコード
130     -- FACTORY_OK:正常に削除
131     -- NOT_FOUND:オブジェクトがない
132     function obj:deleteObject(obj, id)
133
134         if id ~= nil then
135             if self._creators[id] == nil then
136                 self._creators[id].destructor_(obj)
137                 self._creators[id] = nil
138                 return GlobalFactory.Factory.FACTORY_OK
139             end
140         end
141
142         if self._objects[obj] == nil then
143             return GlobalFactory.Factory.NOT_FOUND
144         end
145
146         tmp = obj
147         self._objects[obj].destructor_(obj)
148         --print(#self._objects)
149
150         --for k,v in pairs(self._objects) do
151         -- print(k,v)
152         --end
153         self._objects[obj] = nil
154         --print(#self._objects)
155         return GlobalFactory.Factory.FACTORY_OK
156     end
157
158     -- 作成済みオブジェクト一覧を取得
159     -- @return 作成済みオブジェクト一覧
160     function obj:createdObjects()
161
162         objects_ = {}
163         for i, ver in pairs(self._objects) do
164             table.insert(objects_, ver)
165         end
166         return objects_
167     end
168
169
170     -- 指定オブジェクトの存在確認
171     -- true:存在する、false:存在しない
172     function obj:isProducerOf(obj)
173
174         if self._objects[obj] ~= nil then
175             return true
176         else
177             return false
178         end
179
180     end
181
182     -- 指定オブジェクトのID取得
183     -- @param obj オブジェクト
184     -- @return ID、リターンコード
185     function obj:objectToIdentifier(obj)
186
187         if self._objects[obj] == nil then
188             return -1, GlobalFactory.Factory.NOT_FOUND
189         end
190         local id = self._objects[obj].id_
191         return id, GlobalFactory.Factory.FACTORY_OK
192     end
193
194     -- 指定オブジェクトの生成関数を取得
195     -- @param obj オブジェクト
196     -- @return 生成関数
197     function obj:objectToCreator(obj)
198         if not self:isProducerOf(obj) then
199             return nil
200         end
201         return self._objects[obj].creator_
202     end
203
204     -- 指定オブジェクトの削除関数を取得
205     -- @param obj オブジェクト
206     -- @return 削除関数
207     function obj:objectToDestructor(obj)
208         if not self:isProducerOf(obj) then
209             return nil
210         end
211         return self._objects[obj].destructor_
212     end
213     return obj
214 end
215
216
217 GlobalFactory.GlobalFactory = {}
218 setmetatable(GlobalFactory.GlobalFactory, {__index=GlobalFactory.Factory.new()})
219
220
221
222 function GlobalFactory.GlobalFactory:instance()
223     return self
224 end
225
226
227 return GlobalFactory

File lua\openrtm\InPort.lua

1 ---------------------------------
2 --! @file InPort.lua
3 --! @brief インポートオブジェクト定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local InPort= {}
11 --_G["openrtm.InPort"] = InPort
12
13
14 local InPortBase = require "openrtm.InPortBase"
15 local DataPortStatus = require "openrtm.DataPortStatus"
16
17
18 -- InPort初期化
19 -- @param name ポート名
20 -- @param value データ変数
21 -- @param data_type データ型
22 -- @param buffer バッファ
23 -- @param read_block 読み込み時ブロックの設定
24 -- @param write_block 書き込み時時ブロックの設定
25 -- @param read_timeout 読み込み時のタイムアウト
26 -- @param write_timeout 書き込み時のタイムアウト
27 -- @return InPort
28 InPort.new = function(name, value, data_type, buffer, read_block, write_block, read_timeout, write_timeout)
29     if read_block == nil then
30         read_block = false
31     end
32     if write_block == nil then
33         write_block = false
34     end
35     if read_timeout == nil then
36         read_timeout = 0
37     end
38     if write_timeout == nil then
39         write_timeout = 0
40     end
41     
42     local obj = {}
43     
44     --print(data_type)
45     setmetatable(obj, {__index=InPortBase.new(name, data_type)})
46     obj._name           = name
47     obj._value          = value
48     obj._OnRead         = nil
49     obj._OnReadConvert  = nil
50
51     
52
53     -- ポート名取得
54     -- ※プロファイルのポート名ではない
55     -- @return ポート名
56     function obj:name()
57         return self._name
58     end
59
60     -- 新規データの存在確認
61     -- true;存在する、false:存在しない
62     function obj:isNew()
63         self._rtcout:RTC_TRACE("isNew()")
64
65
66
67         if #self._connectors == 0 then
68             self._rtcout:RTC_DEBUG("no connectors")
69             return false
70         end
71
72         local r = self._connectors[1]:getBuffer():readable()
73         if r > 0 then
74             self._rtcout:RTC_DEBUG("isNew() = True, readable data: "..r)
75             return true
76         end
77
78         self._rtcout:RTC_DEBUG("isNew() = False, no readable data")
79         return false
80     end
81
82     -- 新規データがないことを確認
83     -- @return true:存在しない、false:存在する
84     function obj:isEmpty()
85         self._rtcout:RTC_TRACE("isEmpty()")
86         if #self._connectors == 0 then
87             self._rtcout:RTC_DEBUG("no connectors")
88             return true
89         end
90
91         local r = self._connectors[1]:getBuffer():readable()
92         if r == 0 then
93             self._rtcout:RTC_DEBUG("isEmpty() = true, buffer is empty")
94             return true
95         end
96
97         self._rtcout:RTC_DEBUG("isEmpty() = false, data exists in the buffer")
98         return false
99     end
100
101     -- データ読み込み
102     -- 変換関数を設定している場合は、変換後のデータを返す
103     -- コネクタ数が0、もしくはデータ読み込みに失敗した場合は、保持している変数をそのまま返す
104     -- @return データ
105     function obj:read()
106         self._rtcout:RTC_TRACE("DataType read()")
107
108         if self._OnRead ~= nil then
109             self._OnRead:call()
110             self._rtcout:RTC_TRACE("OnRead called")
111         end
112
113
114
115
116         
117
118         if #self._connectors == 0 then
119             self._rtcout:RTC_DEBUG("no connectors")
120             return self._value
121         end
122
123
124         local cdr = {_data=self._value}
125         local ret = self._connectors[1]:read(cdr)
126
127
128         if ret == DataPortStatus.PORT_OK then
129             self._rtcout:RTC_DEBUG("data read succeeded")
130             self._value = cdr._data
131
132             if self._OnReadConvert ~= nil then
133                 self._value = self._OnReadConvert:call(self._value)
134                 self._rtcout:RTC_DEBUG("OnReadConvert called")
135                 return self._value
136             end
137             return self._value
138
139
140         elseif ret == DataPortStatus.BUFFER_EMPTY then
141             self._rtcout:RTC_WARN("buffer empty")
142             return self._value
143
144         elseif ret == DataPortStatus.BUFFER_TIMEOUT then
145             self._rtcout:RTC_WARN("buffer read timeout")
146             return self._value
147         end
148
149         self._rtcout:RTC_ERROR("unknown retern value from buffer.read()")
150         return self._value
151     end
152     -- 変数に最新値格納
153     function obj:update()
154         self:read()
155     end
156     -- データ読み込み時コールバックの設定
157     -- @param on_read データ読み込み時コールバック
158     function obj:setOnRead(on_read)
159         self._OnRead = on_read
160     end
161     -- データ変換関数設定
162     -- @param on_rconvert データ変換関数
163     -- out_value = on_rconvert(in_value)という関数を指定
164     function obj:setOnReadConvert(on_rconvert)
165         self._OnReadConvert = on_rconvert
166     end
167
168
169
170     return obj
171 end
172
173
174 return InPort

File lua\openrtm\InPortBase.lua

1 ---------------------------------
2 --! @file InPortBase.lua
3 --! @brief InPort基底クラス定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local InPortBase= {}
11 --_G["openrtm.InPortBase"] = InPortBase
12
13 local oil = require "oil"
14
15 local CORBA_SeqUtil = require "openrtm.CORBA_SeqUtil"
16 local Properties = require "openrtm.Properties"
17 local ConnectorListener = require "openrtm.ConnectorListener"
18 local ConnectorListeners = ConnectorListener.ConnectorListeners
19 local PublisherBase = require "openrtm.PublisherBase"
20 local PublisherFactory = PublisherBase.PublisherFactory
21 local PortBase = require "openrtm.PortBase"
22 local StringUtil = require "openrtm.StringUtil"
23 local CdrBufferBase = require "openrtm.CdrBufferBase"
24 local CdrBufferFactory = CdrBufferBase.CdrBufferFactory
25
26
27 local ConnectorDataListenerType = ConnectorListener.ConnectorDataListenerType
28 local ConnectorListenerType = ConnectorListener.ConnectorListenerType
29 local ConnectorDataListener = ConnectorListener.ConnectorDataListener
30 local ConnectorListener = ConnectorListener.ConnectorListener
31
32 local OutPortConsumer = require "openrtm.OutPortConsumer"
33 local OutPortConsumerFactory = OutPortConsumer.OutPortConsumerFactory
34 local InPortProvider = require "openrtm.InPortProvider"
35 local InPortProviderFactory = InPortProvider.InPortProviderFactory
36
37 local NVUtil = require "openrtm.NVUtil"
38
39
40 local ConnectorBase = require "openrtm.ConnectorBase"
41 local ConnectorInfo = ConnectorBase.ConnectorInfo
42
43 local InPortPushConnector = require "openrtm.InPortPushConnector"
44 local InPortPullConnector = require "openrtm.InPortPullConnector"
45
46
47 -- InPort基底オブジェクト初期化
48 -- @param name ポート名
49 -- @param data_type データ型(例:::RTC::TimedLong)
50 -- @return InPort
51 InPortBase.new = function(name, data_type)
52  local obj = {}
53  setmetatable(obj, {__index=PortBase.new(name)})
54  local Manager = require "openrtm.Manager"
55  obj._ReturnCode_t = Manager:instance():getORB().types:lookup("::RTC::ReturnCode_t").labelvalue
56
57  obj._rtcout = Manager:instance():getLogbuf(name)
58  obj._rtcout:RTC_DEBUG("Port name: "..name)
59
60  --local svr = Manager:instance():getORB():newservant(obj, nil, "IDL:omg.org/RTC/PortService:1.0")
61  --local str = Manager:instance():getORB():tostring(svr)
62  --obj._objref = Manager:instance():getORB():newproxy(str,"IDL:omg.org/RTC/PortService:1.0")
63  --obj._profile.port_ref = obj._objref
64
65
66     obj._singlebuffer  = true
67     obj._thebuffer     = nil
68     obj._properties    = Properties.new()
69     obj._providerTypes = ""
70     obj._consumerTypes = ""
71     obj._connectors    = {}
72
73     obj._rtcout:RTC_DEBUG("setting port.port_type: DataInPort")
74     obj:addProperty("port.port_type", "DataInPort")
75
76     obj._rtcout:RTC_DEBUG("setting port.data_type: "..tostring(data_type))
77  local _data_type = string.sub(data_type, 3)
78  _data_type = string.gsub(_data_type, "::", "/")
79  _data_type = "IDL:".._data_type..":1.0"
80     obj:addProperty("dataport.data_type", _data_type)
81
82     obj:addProperty("dataport.subscription_type", "Any")
83     obj._value = nil
84     obj._listeners = ConnectorListeners.new()
85  obj._data_type = data_type
86  --print(data_type)
87
88  -- 初期化時のプロパティ設定
89  -- @param prop プロパティ
90  function obj:init(prop)
91   self._rtcout:RTC_TRACE("init()")
92   self:createRef()
93
94   self._properties:mergeProperties(prop)
95   if self._singlebuffer then
96    self._rtcout:RTC_DEBUG("single buffer mode.")
97    self._thebuffer = CdrBufferFactory:instance():createObject("ring_buffer")
98    --print(self._thebuffer, self._thebuffer.write)
99    if self._thebuffer == nil then
100     self._rtcout:RTC_ERROR("default buffer creation failed")
101    end
102   else
103    self._rtcout:RTC_DEBUG("multi buffer mode.")
104   end
105
106
107
108   self:initProviders()
109   self:initConsumers()
110
111   local num = tonumber(self._properties:getProperty("connection_limit","-1"))
112   if num == nil then
113    self._rtcout:RTC_ERROR("invalid connection_limit value: "..self._properties:getProperty("connection_limit"))
114   end
115   self:setConnectionLimit(num)
116     end
117     -- 利用可能なサービスコンシューマ一覧初期化
118     -- OutPortConsumerFactoryからサービスコンシューマ一覧を取得する
119     -- 「consumer_types」のプロパティが「all」の場合は、
120     -- 利用可能なサービスコンシューマを全て利用可能にする
121  function obj:initConsumers()
122   self._rtcout:RTC_TRACE("initConsumers()")
123
124
125   local factory = OutPortConsumerFactory:instance()
126   local consumer_types = factory:getIdentifiers()
127
128   self._rtcout:RTC_PARANOID("available InPortConsumer: "..StringUtil.flatten(consumer_types))
129   local tmp_str = StringUtil.normalize(self._properties:getProperty("consumer_types"))
130   
131   if self._properties:hasKey("consumer_types") ~= nil and tmp_str  ~= "all" then
132    self._rtcout:RTC_DEBUG("allowed consumers: "..self._properties:getProperty("consumer_types"))
133
134    local temp_types = consumer_types
135    consumer_types = {}
136    local active_types = StringUtil.split(self._properties:getProperty("consumer_types"), ",")
137
138    table.sort(temp_types)
139    table.sort(active_types)
140
141    consumer_types = temp_types
142
143    for i, v in ipairs(active_types) do
144     consumer_types[#consumer_types+1] = v
145    end
146   end
147
148
149
150   if #consumer_types > 0 then
151    self._rtcout:RTC_PARANOID("dataflow_type pull is supported")
152    self:appendProperty("dataport.dataflow_type", "pull")
153    for i, consumer_type in ipairs(consumer_types) do
154     self:appendProperty("dataport.interface_type",consumer_type)
155    end
156   end
157
158   self._consumerTypes = consumer_types
159  end
160  -- 利用可能なサービスプロバイダ一覧初期化
161  -- InPortProviderFactoryからサービスプロバイダ一覧を取得する
162     -- 「provider_types」のプロパティが「all」の場合は、
163     -- 利用可能なサービスプロバイダを全て利用可能にする
164  function obj:initProviders()
165   self._rtcout:RTC_TRACE("initProviders()")
166
167
168   local factory = InPortProviderFactory:instance()
169   local provider_types  = factory:getIdentifiers()
170   self._rtcout:RTC_PARANOID("available InPortProviders: "..StringUtil.flatten(provider_types))
171   local tmp_str = StringUtil.normalize(self._properties:getProperty("provider_types"))
172   if self._properties:hasKey("provider_types") and tmp_str  ~= "all" then
173    self._rtcout:RTC_DEBUG("allowed providers: "..self._properties:getProperty("allowed"))
174
175    local temp_types = provider_types
176    provider_types = {}
177    local active_types = StringUtil.split(self._properties:getProperty("provider_types"), ",")
178
179    table.sort(temp_types)
180    table.sort(active_types)
181
182    provider_types = temp_types
183
184    for i, v in ipairs(active_types) do
185     provider_types[#provider_types+1] = v
186    end
187   end
188
189
190
191   if #provider_types > 0 then
192    self._rtcout:RTC_PARANOID("dataflow_type push is supported")
193    self:appendProperty("dataport.dataflow_type", "push")
194    for i, provider_type in ipairs(provider_types) do
195     self:appendProperty("dataport.interface_type",provider_type)
196    end
197   end
198
199   self._providerTypes = provider_types
200  end
201  
202  -- プロバイダの初期化してインターフェースをコネクタプロファイルに登録
203  -- push型の場合はプロバイダを生成して、コネクタを生成する
204  -- @param cprof コネクタプロファイル
205  -- コネクタプロファイルの以下のノードからプロパティを取得
206  -- dataport
207  -- dataport.inport
208  -- @return リターンコード
209  -- RTC_OK:正常終了
210  -- BAD_PARAMETER:プロバイダの初期化失敗、不正なデータフロー型
211  -- RTC_ERROR:コネクタ生成失敗
212  function obj:publishInterfaces(cprof)
213
214   self._rtcout:RTC_TRACE("publishInterfaces()")
215
216
217   local retval = self:_publishInterfaces()
218   if retval ~= self._ReturnCode_t.RTC_OK then
219    return retval
220   end
221
222
223   local prop = Properties.new(self._properties)
224
225   local conn_prop = Properties.new()
226   NVUtil.copyToProperties(conn_prop, cprof.properties)
227   prop:mergeProperties(conn_prop:getNode("dataport"))
228
229
230   prop:mergeProperties(conn_prop:getNode("dataport.inport"))
231
232
233   local dflow_type = prop:getProperty("dataflow_type")
234   dflow_type = StringUtil.normalize(dflow_type)
235
236   if dflow_type == "push" then
237    self._rtcout:RTC_DEBUG("dataflow_type = push .... create PushConnector")
238
239    
240    local provider = self:createProvider(cprof, prop)
241
242    if provider == nil then
243     self._rtcout:RTC_ERROR("InPort provider creation failed.")
244     return self._ReturnCode_t.BAD_PARAMETER
245    end
246
247
248    local connector = self:createConnector(cprof, prop, {provider_ = provider})
249
250    if connector == nil then
251     self._rtcout:RTC_ERROR("PushConnector creation failed.")
252     return self._ReturnCode_t.RTC_ERROR
253    end
254    --print(self._data_type)
255    connector:setDataType(self._data_type)
256    provider:setConnector(connector)
257
258    self._rtcout:RTC_DEBUG("publishInterfaces() successfully finished.")
259    return self._ReturnCode_t.RTC_OK
260
261   elseif dflow_type == "pull" then
262    self._rtcout:RTC_DEBUG("dataflow_type = pull .... do nothing")
263    return self._ReturnCode_t.RTC_OK
264   end
265
266   self._rtcout:RTC_ERROR("unsupported dataflow_type")
267   return self._ReturnCode_t.BAD_PARAMETER
268  end
269
270
271  -- コネクタプロファイルからインターフェース取得
272  -- pull型の場合はコンシューマ生成して、コネクタを生成する
273  -- @param cprof コネクタプロファイル
274  -- コネクタプロファイルの以下のノードからプロパティを取得
275  -- dataport
276  -- dataport.inport
277  -- @return リターンコード
278  -- RTC_OK:正常終了
279  -- BAD_PARAMETER:コンシューマ生成失敗、不正なデータフロー型
280  -- RTC_ERROR:コネクタ生成失敗
281  function obj:subscribeInterfaces(cprof)
282   self._rtcout:RTC_TRACE("subscribeInterfaces()")
283
284
285
286
287   local prop = Properties.new(self._properties)
288
289   local conn_prop = Properties.new()
290
291   NVUtil.copyToProperties(conn_prop, cprof.properties)
292   --print(cprof.properties[1].value)
293
294
295   prop:mergeProperties(conn_prop:getNode("dataport"))
296
297   prop:mergeProperties(conn_prop:getNode("dataport.inport"))
298
299
300
301   local dflow_type = StringUtil.normalize(prop:getProperty("dataflow_type"))
302   local profile = ConnectorInfo.new(cprof.name,
303           cprof.connector_id,
304           CORBA_SeqUtil.refToVstring(cprof.ports),
305           prop)
306   --print(dflow_type)
307   if dflow_type == "push" then
308
309    local conn = self:getConnectorById(cprof.connector_id)
310    if conn == nil then
311     self._rtcout:RTC_ERROR("specified connector not found: "..cprof.connector_id)
312     return self._ReturnCode_t.RTC_ERROR
313    end
314
315    local ret = conn:setConnectorInfo(profile)
316
317    if ret == self._ReturnCode_t.RTC_OK then
318     self._rtcout:RTC_DEBUG("subscribeInterfaces() successfully finished.")
319    end
320    
321
322    self._rtcout:RTC_PARANOID("dataflow_type = push .... create PushConnector")
323
324    return ret
325   elseif dflow_type == "pull" then
326
327    consumer = self:createConsumer(cprof, prop)
328    --print(consumer)
329    if consumer == nil then
330     return self._ReturnCode_t.BAD_PARAMETER
331    end
332
333
334    local connector = self:createConnector(cprof, prop, {consumer_ = consumer})
335    --print(connector)
336
337
338    if connector == nil then
339     return self._ReturnCode_t.RTC_ERROR
340    end
341    connector:setDataType(self._data_type)
342
343    local ret = connector:setConnectorInfo(profile)
344    if ret == self._ReturnCode_t.RTC_OK then
345     self._rtcout:RTC_DEBUG("subscribeInterfaces() successfully finished.")
346    end
347
348
349    return self._ReturnCode_t.RTC_OK
350   end
351
352   self._rtcout:RTC_ERROR("unsupported dataflow_type")
353
354   return self._ReturnCode_t.BAD_PARAMETER
355  end
356
357  -- コネクタ生成
358  -- @param cprof コネクタプロファイル
359  -- @param prop プロパティ
360  -- @param args args.provider_:プロバイダ、args.consumer_:コンシューマ
361  -- @return コネクタオブジェクト
362  function obj:createConnector(cprof, prop, args)
363   local provider_ = args.provider_
364   local consumer_ = args.consumer_
365   local profile = ConnectorInfo.new(cprof.name,
366          cprof.connector_id,
367          CORBA_SeqUtil.refToVstring(cprof.ports),
368          prop)
369   local connector = nil
370
371   local ret = nil
372   local success, exception = oil.pcall(
373    function()
374     if provider_ ~= nil then
375      if self._singlebuffer then
376       --print(self._thebuffer)
377       connector = InPortPushConnector.new(profile, provider_,
378                    self._listeners,
379                    self._thebuffer)
380      else
381       connector = InPortPushConnector.new(profile, provider_,
382                    self._listeners)
383      end
384
385     elseif consumer_ ~= nil then
386      if self._singlebuffer then
387       connector = InPortPullConnector.new(profile, consumer_,
388                    self._listeners,
389                    self._thebuffer)
390      else
391       connector = InPortPullConnector.new(profile, consumer_,
392                    self._listeners)
393      end
394
395     else
396      self._rtcout:RTC_ERROR("provider or consumer is not passed. returned 0;")
397      ret = nil
398      return
399     end
400
401
402
403
404     if provider_ ~= nil then
405      self._rtcout:RTC_TRACE("InPortPushConnector created")
406     elseif consumer_ ~= nil then
407      self._rtcout:RTC_TRACE("InPortPullConnector created")
408     end
409
410
411     table.insert(self._connectors, connector)
412     self._rtcout:RTC_PARANOID("connector push backed: "..#self._connectors)
413     ret = connector
414     return
415    end)
416   if not success then
417    self._rtcout:RTC_ERROR("InPortPushConnector creation failed")
418    self._rtcout:RTC_ERROR(exception)
419    return nil
420   end
421   return ret
422  end
423
424
425
426
427  -- サービスプロバイダ作成
428  -- 「interface_type」の要素にインターフェース型を指定
429  -- 「provider」のノードにプロバイダのプロパティを指定
430  -- @param cprof コネクタプロファイル
431  -- @param prop プロパティ
432  -- @return プロバイダ
433  function obj:createProvider(cprof, prop)
434   if prop:getProperty("interface_type") == "" or
435    not StringUtil.includes(self._providerTypes, prop:getProperty("interface_type")) then
436    self._rtcout:RTC_ERROR("no provider found")
437    self._rtcout:RTC_DEBUG("interface_type:  "..prop:getProperty("interface_type"))
438    self._rtcout:RTC_DEBUG("interface_types: "..StringUtil.flatten(self._providerTypes))
439    return nil
440   end
441
442
443   self._rtcout:RTC_DEBUG("interface_type: "..prop:getProperty("interface_type"))
444   local provider = InPortProviderFactory:instance():createObject(prop:getProperty("interface_type"))
445
446
447   if provider ~= nil then
448    self._rtcout:RTC_DEBUG("provider created")
449    provider:init(prop:getNode("provider"))
450
451    if not provider:publishInterface(cprof.properties) then
452     self._rtcout:RTC_ERROR("publishing interface information error")
453     InPortProviderFactory:instance():deleteObject(provider)
454     return nil
455    end
456    --[[for i,v in ipairs(cprof.properties) do
457     print(v.name,v.value)
458     v.value = NVUtil.any_from_any(v.value)
459    end]]
460             return provider
461         end
462
463         self._rtcout:RTC_ERROR("provider creation failed")
464         return nil
465     end
466
467     -- サービスコンシューマ作成
468     -- @param cprof コネクタプロファイル
469     -- 「interface_type」の要素にインターフェース型を指定
470     -- 「consumer」のノードにコンシューマのプロパティを指定
471     -- @param prop プロパティ
472     -- @return コンシューマ
473     function obj:createConsumer(cprof, prop)
474         if prop:getProperty("interface_type") == "" or
475               not StringUtil.includes(self._consumerTypes, prop:getProperty("interface_type")) then
476             self._rtcout:RTC_ERROR("no consumer found")
477             self._rtcout:RTC_DEBUG("interface_type: "..prop:getProperty("interface_type"))
478             self._rtcout:RTC_DEBUG("interface_types: "..
479                                  StringUtil.flatten(self._consumerTypes))
480             return nil
481         end
482
483         self._rtcout:RTC_DEBUG("interface_type: "..prop:getProperty("interface_type"))
484         local consumer = OutPortConsumerFactory:instance():createObject(prop:getProperty("interface_type"))
485
486         if consumer ~= nil then
487             self._rtcout:RTC_DEBUG("consumer created")
488             consumer:init(prop:getNode("consumer"))
489
490             if not consumer:subscribeInterface(cprof.properties) then
491                 self._rtcout:RTC_ERROR("interface subscription failed.")
492                 OutPortConsumerFactory:instance():deleteObject(consumer)
493                 return nil
494             end
495             return consumer
496         end
497
498         self._rtcout:RTC_ERROR("consumer creation failed")
499         return nil
500     end
501
502     -- IDからコネクタを取得
503     -- @param id 識別子
504     -- @return コネクタ
505     function obj:getConnectorById(id)
506         self._rtcout:RTC_TRACE("getConnectorById(id = "..id..")")
507
508         for i, con in pairs(self._connectors) do
509             if id == con:id() then
510                 return con
511             end
512         end
513
514         self._rtcout:RTC_WARN("ConnectorProfile with the id("..id..") not found.")
515         return nil
516     end
517
518     -- 指定コネクタプロファイルのコネクタを削除
519     -- @param connector_profile コネクタプロファイル
520     function obj:unsubscribeInterfaces(connector_profile)
521         self._rtcout:RTC_TRACE("unsubscribeInterfaces()")
522
523         local id = connector_profile.connector_id
524         self._rtcout:RTC_PARANOID("connector_id: "..id)
525
526         for i, con in pairs(self._connectors) do
527             if id == con:id() then
528                 con:deactivate()
529                 con:disconnect()
530                 self._connectors[i] = nil
531                 self._rtcout:RTC_TRACE("delete connector: "..id)
532                 return
533             end
534         end
535
536
537         self._rtcout:RTC_ERROR("specified connector not found: "..id)
538     end
539
540     -- インターフェースのアクティブ化
541     function obj:activateInterfaces()
542         self._rtcout:RTC_TRACE("activateInterfaces()")
543         for i, con in ipairs(self._connectors) do
544             con:activate()
545             self._rtcout:RTC_DEBUG("activate connector: "..
546                                 con:name().." "..con:id())
547         end
548     end
549
550     -- インターフェースの非アクティブ化
551     function obj:deactivateInterfaces()
552         self._rtcout:RTC_TRACE("deactivateInterfaces()")
553         for i, con in pairs(self._connectors) do
554             con:deactivate()
555             self._rtcout:RTC_DEBUG("deactivate connector: "..
556                                 con:name().." "..con:id())
557         end
558     end
559
560     function obj:addConnectorDataListener(listener_type, listener, autoclean)
561         if autoclean == nil then
562             autoclean = true
563         end
564         self._rtcout:RTC_TRACE("addConnectorDataListener()")
565
566            if listener_type < ConnectorDataListenerType.CONNECTOR_DATA_LISTENER_NUM then
567               self._listeners.connectorData_[listener_type]:addListener(listener, autoclean)
568             return
569         end
570
571         self._rtcout:RTC_ERROR("addConnectorDataListener(): Invalid listener type.")
572
573     end
574
575     function obj:removeConnectorDataListener(listener_type, listener)
576         self._rtcout:RTC_TRACE("removeConnectorDataListener()")
577
578         if listener_type < ConnectorDataListenerType.CONNECTOR_DATA_LISTENER_NUM then
579             self._listeners.connectorData_[listener_type]:removeListener(listener)
580             return
581         end
582
583         self._rtcout:RTC_ERROR("removeConnectorDataListener(): Invalid listener type.")
584     end
585     
586
587     function obj:addConnectorListener(listener_type, listener, autoclean)
588         if autoclean == nil then
589             autoclean = true
590         end
591         self._rtcout:RTC_TRACE("addConnectorListener()")
592
593            if listener_type < ConnectorListenerType.CONNECTOR_LISTENER_NUM then
594               self._listeners.connector_[listener_type]:addListener(listener, autoclean)
595             return
596         end
597
598         self._rtcout:RTC_ERROR("addConnectorListener(): Invalid listener type.")
599
600     end
601
602     function obj:removeConnectorListener(listener_type, listener)
603         self._rtcout:RTC_TRACE("removeConnectorListener()")
604
605         if listener_type < ConnectorListenerType.CONNECTOR_LISTENER_NUM then
606             self._listeners.connector_[listener_type]:removeListener(listener)
607             return
608         end
609
610         self._rtcout:RTC_ERROR("removeConnectorListener(): Invalid listener type.")
611     end
612
613     return obj
614 end
615
616
617
618
619
620 return InPortBase

File lua\openrtm\InPortConnector.lua

1 ---------------------------------
2 --! @file InPortConnectorBase.lua
3 --! @brief InPortコネクタ基底クラス定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local InPortConnector= {}
11 --_G["openrtm.InPortConnectorBase"] = InPortConnector
12
13 local ConnectorBase = require "openrtm.ConnectorBase"
14
15 InPortConnector = {}
16
17 -- InPortコネクタ基底オブジェクト初期化
18 -- @param info プロファイル
19 -- @param buffer バッファ
20 -- @return InPortコネクタ
21 InPortConnector.new = function(info, buffer)
22     local obj = {}
23     setmetatable(obj, {__index=ConnectorBase.new()})
24     local Manager = require "openrtm.Manager"
25     obj._rtcout = Manager:instance():getLogbuf("InPortConnector")
26     obj._ReturnCode_t = Manager:instance():getORB().types:lookup("::RTC::ReturnCode_t").labelvalue
27     obj._profile = info
28     obj._buffer = buffer
29     obj._dataType = nil
30     obj._endian = true
31     -- プロファイル取得
32     -- @return プロファイル
33     function obj:profile()
34         self._rtcout:RTC_TRACE("profile()")
35         return self._profile
36     end
37     -- コネクタID取得
38     -- @return コネクタID
39     function obj:id()
40         self._rtcout:RTC_TRACE("id() = "..self:profile().id)
41         return self:profile().id
42     end
43     -- コネクタ名取得
44     -- @return コネクタ名
45     function obj:name()
46         self._rtcout:RTC_TRACE("name() = "..self:profile().name)
47         return self:profile().name
48     end
49     -- コネクタ切断
50     -- @return リターンコード
51     function obj:disconnect()
52         return DataPortStatus.PORT_OK
53     end
54     -- バッファ取得
55     -- @return バッファ
56     function obj:getBuffer()
57         return self._buffer
58     end
59     -- データ読み込み
60     -- @param data data._data:データ格納オブジェクト
61     -- @return リターンコード
62     function obj:read(data)
63         return DataPortStatus.PORT_ERROR
64     end
65     -- プロファイル設定
66     -- @param profile プロファイル
67     -- @return リターンコード
68     function obj:setConnectorInfo(profile)
69         self._profile = profile
70         return self._ReturnCode_t.RTC_OK
71     end
72     -- データ型設定
73     -- @param data データ型
74     function obj:setDataType(data)
75         self._dataType = data
76         --print(self._dataType)
77     end
78     return obj
79 end
80
81
82 return InPortConnector

File lua\openrtm\InPortConsumer.lua

1 ---------------------------------
2 --! @file InPortConsumer.lua
3 --! @brief InPortコンシューマと生成ファクトリ定義
4 --! Push型通信の独自インターフェース型を実装する場合は、
5 --! InPortConsumerをメタテーブルに設定したコンシューマオブジェクトを生成する
6 ---------------------------------
7
8 --[[
9 Copyright (c) 2017 Nobuhiko Miyamoto
10 ]]
11
12 local InPortConsumer= {}
13 --_G["openrtm.InPortConsumer"] = InPortConsumer
14
15 local GlobalFactory = require "openrtm.GlobalFactory"
16 local Factory = GlobalFactory.Factory
17
18 -- InPortコンシューマオブジェクト初期化
19 -- @return InPortコンシューマオブジェクト
20 InPortConsumer.new = function()
21     local obj = {}
22     obj.subscribe = {}
23     -- コンシューマのインターフェース追加関数オブジェクト初期化
24     -- @param prop プロパティ
25     -- return インターフェース追加関数オブジェクト
26     obj.subscribe.new = function(prop)
27         local obj = {}
28         obj._prop = prop
29         -- インターフェース追加関数
30         -- @param self 自身のオブジェクト
31         -- @param consumer コンシューマ
32         local call_func = function(self, consumer)
33             consumer:subscribeInterface(self._prop)
34         end
35         setmetatable(obj, {__call=call_func})
36         return obj
37     end
38     obj.unsubscribe = {}
39     -- コンシューマのインターフェース削除関数オブジェクト初期化
40     -- @param prop プロパティ
41     -- return インターフェース削除オブジェクト
42     obj.unsubscribe.new = function(prop)
43         local obj = {}
44         obj._prop = prop
45         -- インターフェース削除関数
46         -- @param self 自身のオブジェクト
47         -- @param consumer コンシューマ
48         local call_func = function(self, consumer)
49             consumer:unsubscribeInterface(self._prop)
50         end
51         setmetatable(obj, {__call=call_func})
52         return obj
53     end
54     return obj
55 end
56
57
58 InPortConsumer.InPortConsumerFactory = {}
59 setmetatable(InPortConsumer.InPortConsumerFactory, {__index=Factory.new()})
60
61 function InPortConsumer.InPortConsumerFactory:instance()
62     return self
63 end
64
65
66 return InPortConsumer

File lua\openrtm\InPortDSConsumer.lua

1 ---------------------------------
2 --! @file InPortDSConsumer.lua
3 --! @brief CorbaCdrインターフェースで通信するInPortConsumer定義
4 --! 「data_service」のインターフェース型で利用可能
5 --! RTC.idlのPortServiceインターフェース
6 ---------------------------------
7
8 --[[
9 Copyright (c) 2017 Nobuhiko Miyamoto
10 ]]
11
12 local InPortDSConsumer= {}
13 --_G["openrtm.InPortDSConsumer"] = InPortDSConsumer
14
15
16 local oil = require "oil"
17 local InPortConsumer = require "openrtm.InPortConsumer"
18 local CorbaConsumer = require "openrtm.CorbaConsumer"
19 local DataPortStatus = require "openrtm.DataPortStatus"
20 local NVUtil = require "openrtm.NVUtil"
21
22 local Factory = require "openrtm.Factory"
23 local InPortConsumerFactory = InPortConsumer.InPortConsumerFactory
24 local RTCUtil = require "openrtm.RTCUtil"
25
26
27
28 -- CorbaCdrインターフェースのInPortConsumerオブジェクト初期化
29 -- @return CorbaCdrインターフェースのInPortConsumerオブジェクト
30 InPortDSConsumer.new = function()
31     local obj = {}
32     setmetatable(obj, {__index=InPortConsumer.new()})
33     setmetatable(obj, {__index=CorbaConsumer.new()})
34     local Manager = require "openrtm.Manager"
35     obj._rtcout = Manager:instance():getLogbuf("InPortDSConsumer")
36     obj._properties = nil
37     obj._PortStatus = Manager:instance():getORB().types:lookup("::RTC::PortStatus").labelvalue
38
39     -- 初期化時にプロパティ設定
40     -- @param prop プロパティ
41     function obj:init(prop)
42         self._rtcout:RTC_TRACE("init()")
43         self._properties = prop
44     end
45
46     -- データ送信
47     -- @param data 送信データ
48     -- @return リターンコード
49     -- RTC_OK:putオペレーションが正常終了
50     -- CONNECTION_LOST:通信失敗
51     function obj:put(data)
52         self._rtcout:RTC_PARANOID("put()")
53         local ret = DataPortStatus.PORT_OK
54         local success, exception = oil.pcall(
55             function()
56                 local inportcdr = self:getObject()
57                 if inportcdr ~= oil.corba.idl.null then
58                     ret = NVUtil.getPortStatus_RTC(inportcdr:push(data))
59                     ret = self:convertReturnCode(ret)
60                     return
61                 end
62                 ret = DataPortStatus.CONNECTION_LOST
63                 return
64             end)
65         if not success then
66             self._rtcout:RTC_ERROR(exception)
67             return DataPortStatus.CONNECTION_LOST
68         end
69         return ret
70     end
71
72     -- プロパティにインターフェース情報追加
73     -- @param properties プロパティ
74     function obj:publishInterfaceProfile(properties)
75     end
76     -- プロパティからインターフェース情報取得
77     -- オブジェクトリファレンスの設定
78             -- dataport.corba_cdr.inport_ior
79     -- dataport.corba_cdr.inport_ref
80     -- @param properties プロパティ
81     -- @return true:設定成功、false:設定失敗
82     function obj:subscribeInterface(properties)
83         self._rtcout:RTC_TRACE("subscribeInterface()")
84         if self:subscribeFromIor(properties) then
85             return true
86         end
87         if self:subscribeFromRef(properties) then
88             return true
89         end
90         return false
91     end
92     -- プロパティからインターフェース設定解除
93     -- IOR文字列、もしくはリファレンスを取得
94     -- dataport.corba_cdr.inport_ior
95     -- dataport.corba_cdr.inport_ref
96     -- @param properties プロパティ
97     function obj:unsubscribeInterface(properties)
98         self._rtcout:RTC_TRACE("unsubscribeInterface()")
99
100         if self:unsubscribeFromIor(properties) then
101             return
102         end
103
104         self:unsubscribeFromRef(properties)
105     end
106
107     -- IOR文字列からオブジェクトリファレンス設定
108     -- @param properties プロパティ
109     -- 以下からIOR文字列取得
110     -- dataport.corba_cdr.inport_ior
111     -- @return true:設定成功、false:設定失敗
112     function obj:subscribeFromIor(properties)
113         self._rtcout:RTC_TRACE("subscribeFromIor()")
114
115         local index = NVUtil.find_index(properties,
116                                            "dataport.data_service.inport_ior")
117         --print(index)
118         if index < 0 then
119             self._rtcout:RTC_ERROR("inport_ior not found")
120             return false
121         end
122
123         local ior = ""
124         if properties[index] ~= nil then
125             ior = NVUtil.any_from_any(properties[index].value)
126         end
127
128         if ior == "" then
129             self._rtcout:RTC_ERROR("inport_ior has no string")
130             return false
131         end
132
133         local Manager = require "openrtm.Manager"
134         local orb = Manager:instance():getORB()
135         
136         local _obj = RTCUtil.newproxy(orb, ior,"IDL:omg.org/RTC/DataPushService:1.0")
137
138
139         if _obj == nil then
140             self._rtcout:RTC_ERROR("invalid IOR string has been passed")
141             return false
142         end
143         
144         if not self:setObject(_obj) then
145             self._rtcout:RTC_WARN("Setting object to consumer failed.")
146             return false
147         end
148
149         return true
150     end
151
152
153
154     -- オブジェクトからオブジェクトリファレンス設定
155     -- @param properties プロパティ
156     -- 以下からリファレンスを取得
157     -- dataport.corba_cdr.inport_ref
158     -- @return true:設定成功、false:設定失敗
159     function obj:subscribeFromRef(properties)
160         self._rtcout:RTC_TRACE("subscribeFromRef()")
161         local index = NVUtil.find_index(properties,
162                                         "dataport.data_service.inport_ref")
163         if index < 0 then
164             self._rtcout:RTC_ERROR("inport_ref not found")
165             return false
166         end
167
168         local _obj = NVUtil.any_from_any(properties[index].value)
169
170         local Manager = require "openrtm.Manager"
171         local orb = Manager:instance():getORB()
172
173         _obj = orb:narrow(_obj, "IDL:omg.org/RTC/DataPushService:1.0")
174
175
176         if _obj == nil then
177             self._rtcout:RTC_ERROR("prop[inport_ref] is not objref")
178             return false
179         end
180
181
182         if not self:setObject(obj) then
183             self._rtcout:RTC_ERROR("Setting object to consumer failed.")
184             return false
185         end
186
187         return true
188     end
189
190
191     -- IOR文字列からオブジェクトリファレンス設定解除
192     -- @param properties プロパティ
193     -- 以下からIOR文字列取得
194     -- dataport.corba_cdr.inport_ior
195     -- @return true:設定解除成功、false:設定解除失敗
196     function obj:unsubscribeFromIor(properties)
197         self._rtcout:RTC_TRACE("unsubscribeFromIor()")
198         local index = NVUtil.find_index(properties,
199                                         "dataport.data_service.inport_ior")
200         if index < 0 then
201             self._rtcout:RTC_ERROR("inport_ior not found")
202             return false
203         end
204
205
206         ior = NVUtil.any_from_any(properties[index].value)
207
208
209         if ior == "" then
210             self._rtcout:RTC_ERROR("prop[inport_ior] is not string")
211             return false
212         end
213
214         local Manager = require "openrtm.Manager"
215         local orb = Manager:instance():getORB()
216         local var = RTCUtil.newproxy(orb, ior,"IDL:omg.org/RTC/DataPushService:1.0")
217         if not NVUtil._is_equivalent(self:_ptr(true), var, self:_ptr(true).getObjRef, var.getObjRef) then
218             self._rtcout:RTC_ERROR("connector property inconsistency")
219             return false
220         end
221
222         self:releaseObject()
223         return true
224     end
225
226     -- オブジェクトからオブジェクトリファレンス設定解除
227     -- @param properties プロパティ
228     -- 以下からリファレンスを取得
229     -- dataport.corba_cdr.inport_ref
230     -- @return true:設定解除成功、false:設定解除失敗
231     function obj:unsubscribeFromRef(properties)
232         self._rtcout:RTC_TRACE("unsubscribeFromRef()")
233         local index = NVUtil.find_index(properties,
234                                         "dataport.data_service.inport_ref")
235
236         if index < 0 then
237             return false
238         end
239
240
241         local _obj = NVUtil.any_from_any(properties[index].value)
242
243
244         if obj == nil then
245             return false
246         end
247
248         local obj_ptr = self:_ptr(true)
249
250         if obj_ptr == nil or not NVUtil._is_equivalent(obj_ptr, obj, obj_ptr.getObjRef, obj.getObjRef) then
251             return false
252         end
253
254         self:releaseObject()
255         return true
256     end
257
258     -- RTC::PortStatusをデータポートステータスに変換
259     function obj:convertReturnCode(ret)
260         
261         if ret == self._PortStatus.PORT_OK then
262             return DataPortStatus.PORT_OK
263
264         elseif ret == self._PortStatus.PORT_ERROR then
265             return DataPortStatus.PORT_ERROR
266
267         elseif ret == self._PortStatus.BUFFER_FULL then
268             return DataPortStatus.SEND_FULL
269
270         elseif ret == self._PortStatus.BUFFER_TIMEOUT then
271             return DataPortStatus.SEND_TIMEOUT
272
273         elseif ret == self._PortStatus.UNKNOWN_ERROR then
274             return DataPortStatus.UNKNOWN_ERROR
275
276         else
277             return DataPortStatus.UNKNOWN_ERROR
278         end
279     end
280
281     return obj
282 end
283
284 -- InPortDSConsumer生成ファクトリ登録関数
285 InPortDSConsumer.Init = function()
286     InPortConsumerFactory:instance():addFactory("data_service",
287         InPortDSConsumer.new,
288         Factory.Delete)
289 end
290
291 return InPortDSConsumer

File lua\openrtm\InPortDSProvider.lua

1 ---------------------------------
2 --! @file InPortDSProvider.lua
3 --! @brief CorbaCdrインターフェースで通信するInPortProvider定義
4 --! 「data_service」のインターフェース型で利用可能
5 --! RTC.idlのPortServiceインターフェース
6 ---------------------------------
7
8 --[[
9 Copyright (c) 2017 Nobuhiko Miyamoto
10 ]]
11
12 local InPortDSProvider= {}
13 --_G["openrtm.InPortDSProvider"] = InPortDSProvider
14
15
16
17 local oil = require "oil"
18 local InPortProvider = require "openrtm.InPortProvider"
19 local NVUtil = require "openrtm.NVUtil"
20 local BufferStatus = require "openrtm.BufferStatus"
21
22 local Factory = require "openrtm.Factory"
23 local InPortProviderFactory = InPortProvider.InPortProviderFactory
24 local RTCUtil = require "openrtm.RTCUtil"
25
26 local ConnectorListener = require "openrtm.ConnectorListener"
27 local ConnectorDataListenerType = ConnectorListener.ConnectorDataListenerType
28
29
30 -- CorbaCdrインターフェースのInPortProviderオブジェクト初期化
31 -- @return CorbaCdrインターフェースのInPortProviderオブジェクト
32 InPortDSProvider.new = function()
33  local obj = {}
34  --print(InPortProvider.new)
35  setmetatable(obj, {__index=InPortProvider.new()})
36  local Manager = require "openrtm.Manager"
37  obj._PortStatus = Manager:instance():getORB().types:lookup("::RTC::PortStatus").labelvalue
38     obj:setInterfaceType("data_service")
39
40  local orb = Manager:instance():getORB()
41  obj._svr = orb:newservant(obj, nil, "IDL:omg.org/RTC/DataPushService:1.0")
42  local str = orb:tostring(obj._svr)
43  obj._objref = RTCUtil.getReference(orb, obj._svr, "IDL:omg.org/RTC/DataPushService:1.0")
44
45
46
47     obj._buffer = nil
48
49     obj._profile = nil
50     obj._listeners = nil
51
52
53
54     table.insert(obj._properties, NVUtil.newNV("dataport.data_service.inport_ior",
55              str))
56     --table.insert(obj._properties, NVUtil.newNV("dataport.data_service.inport_ref",
57  --            obj._objref))
58  --print(obj._properties)
59  --for i,v in ipairs(obj._properties) do
60  -- print(i,v)
61  --end
62
63  -- 終了処理
64  function obj:exit()
65   Manager:instance():getORB():deactivate(self._svr)
66  end
67  -- 初期化時にプロパティ設定
68  -- @param prop プロパティ
69  function obj:init(prop)
70     end
71     -- バッファ設定
72     -- @param buffer バッファ
73  function obj:setBuffer(buffer)
74   self._buffer = buffer
75  end
76  -- コールバック関数設定
77  -- @param info プロファイル
78  -- @param listeners コールバック関数
79  function obj:setListener(info, listeners)
80   self._profile = info
81   self._listeners = listeners
82     end
83     -- データ書き込み
84     -- @param data データ
85     -- @return リターンコード
86     -- PORT_OK:正常終了
87     -- PORT_ERROR:バッファがない
88     -- UNKNOWN_ERROR:復号化失敗など、その他のエラー
89     -- その他、バッファフル、タイムアウト等の戻り値
90  function obj:push(data)
91   --print("put")
92   local status = self._PortStatus.PORT_OK
93   local success, exception = oil.pcall(
94    function()
95     self._rtcout:RTC_PARANOID("InPortDSProvider.put()")
96
97     --[[
98     if self._buffer == nil then
99      self:onReceiverError(data)
100      return self._PortStatus.PORT_ERROR
101     end
102     --]]
103
104                 self._rtcout:RTC_PARANOID("received data size: "..#data)
105
106                 self:onReceived(data)
107                 --print(self._connector)
108                 if self._connector == nil then
109                     status = self._PortStatus.PORT_ERROR
110                     return
111                 end
112                 --print("test,",data)
113                 local ret = self._connector:write(data)
114
115                 status = self:convertReturn(ret, data)
116             end)
117
118         if not success then
119             self._rtcout:RTC_TRACE(exception)
120             return self._PortStatus.UNKNOWN_ERROR
121         end
122         return status
123     end
124     -- バッファステータスをOpenRTM::PortStatusに変換
125     --コールバック呼び出し
126     -- @param status バッファステータス
127     -- @param data データ
128     -- @param ポートステータス
129     function obj:convertReturn(status, data)
130         if status == BufferStatus.BUFFER_OK then
131             self:onBufferWrite(data)
132             return self._PortStatus.PORT_OK
133
134         elseif status == BufferStatus.BUFFER_ERROR then
135             self:onReceiverError(data)
136             return self._PortStatus.PORT_ERROR
137
138         elseif status == BufferStatus.BUFFER_FULL then
139             self:onBufferFull(data)
140             self:onReceiverFull(data)
141             return self._PortStatus.BUFFER_FULL
142
143         elseif status == BufferStatus.BUFFER_EMPTY then
144             return self._PortStatus.BUFFER_EMPTY
145
146         elseif status == BufferStatus.PRECONDITION_NOT_MET then
147             self:onReceiverError(data)
148             return self._PortStatus.PORT_ERROR
149
150         elseif status == BufferStatus.TIMEOUT then
151             self:onBufferWriteTimeout(data)
152             self:onReceiverTimeout(data)
153             return self._PortStatus.BUFFER_TIMEOUT
154
155         else
156             self:onReceiverError(data)
157             return self._PortStatus.UNKNOWN_ERROR
158         end
159     end
160     -- バッファ書き込み時コールバック
161     -- @param data データ
162     function obj:onBufferWrite(data)
163         if self._listeners ~= nil and self._profile ~= nil then
164             self._listeners.connectorData_[ConnectorDataListenerType.ON_BUFFER_WRITE]:notify(self._profile, data)
165         end
166     end
167     -- バッファフル時コールバック
168     -- @param data データ
169     function obj:onBufferFull(data)
170         if self._listeners ~= nil and self._profile ~= nil then
171             self._listeners.connectorData_[ConnectorDataListenerType.ON_BUFFER_FULL]:notify(self._profile, data)
172         end
173     end
174     -- バッファ書き込みタイムアウト時コールバック
175     -- @param data データ
176     function obj:onBufferWriteTimeout(data)
177         if self._listeners ~= nil and self._profile ~= nil then
178             self._listeners.connectorData_[ConnectorDataListenerType.ON_BUFFER_WRITE_TIMEOUT]:notify(self._profile, data)
179         end
180     end
181     -- バッファ上書き時コールバック
182     -- @param data データ
183     function obj:onBufferWriteOverwrite(data)
184         if self._listeners ~= nil and self._profile ~= nil then
185             self._listeners.connectorData_[ConnectorDataListenerType.ON_BUFFER_OVERWRITE]:notify(self._profile, data)
186         end
187     end
188     -- 受信時コールバック
189     -- @param data データ
190     function obj:onReceived(data)
191         if self._listeners ~= nil and self._profile ~= nil then
192             self._listeners.connectorData_[ConnectorDataListenerType.ON_RECEIVED]:notify(self._profile, data)
193         end
194     end
195     -- 受信バッファフル時コールバック
196     -- @param data データ
197     function obj:onReceiverFull(data)
198         if self._listeners ~= nil and self._profile ~= nil then
199             self._listeners.connectorData_[ConnectorDataListenerType.ON_RECEIVER_FULL]:notify(self._profile, data)
200         end
201     end
202     -- 受信タイムアウト時コールバック
203     -- @param data データ
204     function obj:onReceiverTimeout(data)
205         if self._listeners ~= nil and self._profile ~= nil then
206             self._listeners.connectorData_[ConnectorDataListenerType.ON_RECEIVER_TIMEOUT]:notify(self._profile, data)
207         end
208     end
209     -- 受信エラー時コールバック
210     -- @param data データ
211     function obj:onReceiverError(data)
212         if self._listeners ~= nil and self._profile ~= nil then
213             self._listeners.connectorData_[ConnectorDataListenerType.ON_RECEIVER_ERROR]:notify(self._profile, data)
214         end
215     end
216     function obj:getObjRef()
217         return self._objref
218     end
219     return obj
220 end
221
222 -- InPortDSProvider生成ファクトリ登録関数
223 InPortDSProvider.Init = function()
224     InPortProviderFactory:instance():addFactory("data_service",
225         InPortDSProvider.new,
226         Factory.Delete)
227 end
228
229
230 return InPortDSProvider

File lua\openrtm\InPortProvider.lua

1 ---------------------------------
2 --! @file InPortProvider.lua
3 --! @brief InPortプロバイダと生成ファクトリ定義
4 --! Push型通信の独自インターフェース型を実装する場合は、
5 --! InPortProviderをメタテーブルに設定したプロバイダオブジェクトを生成する
6 ---------------------------------
7
8 --[[
9 Copyright (c) 2017 Nobuhiko Miyamoto
10 ]]
11
12 local InPortProvider= {}
13 --_G["openrtm.InPortProvider"] = InPortProvider
14
15
16
17
18 local GlobalFactory = require "openrtm.GlobalFactory"
19 local Factory = GlobalFactory.Factory
20 local NVUtil = require "openrtm.NVUtil"
21
22 -- InPortプロバイダ初期化
23 -- @return InPortProvider
24 InPortProvider.new = function()
25     local obj = {}
26     local Manager = require "openrtm.Manager"
27     obj._properties = {}
28     obj._interfaceType = ""
29     obj._dataflowType = ""
30     obj._subscriptionType = ""
31     obj._rtcout = Manager:instance():getLogbuf("InPortProvider")
32     obj._connector = nil
33     -- 終了関数
34     function obj:exit()
35     end
36     -- コネクタプロファイルにインターフェース型を設定
37     -- @param prop プロパティ
38     function obj:publishInterfaceProfile(prop)
39         self._rtcout:RTC_TRACE("publishInterfaceProfile()")
40         NVUtil.appendStringValue(prop, "dataport.interface_type",
41                                           self._interfaceType)
42         NVUtil.append(prop, self._properties)
43     end
44     -- コネクタプロファイルに各種設定を行う
45     -- @param prop プロパティ
46     -- @return true:設定成功、false:設定失敗
47     function obj:publishInterface(prop)
48         self._rtcout:RTC_TRACE("publishInterface()")
49         if not NVUtil.isStringValue(prop,
50                                     "dataport.interface_type",
51                                     self._interfaceType) then
52             return false
53         end
54         --for i,v in ipairs(self._properties) do
55         -- print(i,v)
56         --end
57
58         NVUtil.append(prop, self._properties)
59         return true
60     end
61     -- インターフェース型の設定
62     -- @param interface_type インターフェース型
63     function obj:setInterfaceType(interface_type)
64         self._rtcout:RTC_TRACE("setInterfaceType("..interface_type..")")
65         self._interfaceType = interface_type
66     end
67     -- データフロー型の設定
68     -- @param dataflow_type データフロー型
69     function obj:setDataFlowType(dataflow_type)
70         self._rtcout:RTC_TRACE("setDataFlowType("..dataflow_type..")")
71         self._dataflowType = dataflow_type
72     end
73     -- サブスクリプション型の設定
74     -- @param subs_type サブスクリプション型
75     function obj:setSubscriptionType(subs_type)
76         self._rtcout:RTC_TRACE("setSubscriptionType("..subs_type..")")
77         self._subscriptionType = subs_type
78     end
79     -- コネクタ設定
80     -- @param connector コネクタ
81     function obj:setConnector(connector)
82         self._connector = connector
83     end
84
85     return obj
86 end
87
88 InPortProvider.InPortProviderFactory = {}
89 setmetatable(InPortProvider.InPortProviderFactory, {__index=Factory.new()})
90
91 function InPortProvider.InPortProviderFactory:instance()
92     return self
93 end
94
95
96 return InPortProvider

File lua\openrtm\InPortPullConnector.lua

1 ---------------------------------
2 --! @file InPortPullConnector.lua
3 --! @brief Pull型通信InPortConnector定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local InPortPullConnector= {}
11 --_G["openrtm.InPortPullConnector"] = InPortPullConnector
12
13 local InPortConnector = require "openrtm.InPortConnector"
14 local DataPortStatus = require "openrtm.DataPortStatus"
15
16 local CdrBufferBase = require "openrtm.CdrBufferBase"
17 local CdrBufferFactory = CdrBufferBase.CdrBufferFactory
18 local OutPortConsumer = require "openrtm.OutPortConsumer"
19 local OutPortConsumerFactory = OutPortConsumer.OutPortConsumerFactory
20
21 local ConnectorListener = require "openrtm.ConnectorListener"
22 local ConnectorListenerType = ConnectorListener.ConnectorListenerType
23
24 -- Pull型通信InPortConnectorの初期化
25 -- @param info プロファイル
26 -- 「buffer」という要素名にバッファの設定を格納
27 -- @param consumer コンシューマ
28 -- @param listeners コールバック
29 -- @param buffer バッファ
30 -- 指定しない場合はリングバッファを生成する
31 -- @return Pull型通信InPortConnector
32 InPortPullConnector.new = function(info, consumer, listeners, buffer)
33     local obj = {}
34     setmetatable(obj, {__index=InPortConnector.new(info, buffer)})
35
36     -- データ読み込み
37     -- @param data data._dataにデータを格納
38     -- @return リターンコード
39     -- PORT_OK:get関数がPORT_OKを返す
40     -- PORT_ERROR:コンシューマがnil、データ型が不明
41     function obj:read(data)
42         self._rtcout:RTC_TRACE("InPortPullConnector.read()")
43         if self._consumer == nil then
44             return DataPortStatus.PORT_ERROR
45         end
46
47         --print(self._dataType)
48         if self._dataType == nil then
49             return DataPortStatus.PORT_ERROR
50         end
51
52
53
54         local cdr_data = {_data=""}
55         local ret = self._consumer:get(cdr_data)
56
57         if ret == DataPortStatus.PORT_OK then
58             local Manager = require "openrtm.Manager"
59             data._data = Manager:instance():cdrUnmarshal(cdr_data._data, self._dataType)
60         end
61
62
63         return ret
64     end
65
66     -- コネクタ切断
67     -- @return リターンコード
68     function obj:disconnect()
69         self._rtcout:RTC_TRACE("disconnect()")
70         self:onDisconnect()
71         if self._consumer ~= nil then
72             OutPortConsumerFactory:instance():deleteObject(self._consumer)
73         end
74         self._consumer = nil
75
76         return DataPortStatus.PORT_OK
77     end
78
79     -- アクティブ化
80     function obj:activate()
81     end
82
83     -- 非アクティブ化
84     function obj:deactivate()
85     end
86
87     -- バッファ作成
88     -- リングバッファを生成する
89     -- @param profile コネクタプロファイル
90     -- @return バッファ
91     function obj:createBuffer(profile)
92         local buf_type = profile.properties:getProperty("buffer_type","ring_buffer")
93         return CdrBufferFactory:instance():createObject(buf_type)
94     end
95
96     -- コネクタ接続時のコールバック呼び出し
97     function obj:onConnect()
98         if self._listeners ~= nil and self._profile ~= nil then
99             self._listeners.connector_[ConnectorListenerType.ON_CONNECT]:notify(self._profile)
100         end
101     end
102
103     -- コネクタ切断時のコールバック呼び出し
104     function obj:onDisconnect()
105         if self._listeners ~= nil and self._profile ~= nil then
106             self._listeners.connector_[ConnectorListenerType.ON_DISCONNECT]:notify(self._profile)
107         end
108     end
109
110     obj._consumer = consumer
111     obj._listeners = listeners
112
113
114     if buffer == nil then
115         obj._buffer = obj:createBuffer(obj._profile)
116     end
117
118     if obj._buffer == nil or obj._consumer == nil then
119         error("")
120     end
121
122     obj._buffer:init(info.properties:getNode("buffer"))
123     obj._consumer:init(info.properties)
124     obj._consumer:setBuffer(obj._buffer)
125     obj._consumer:setListener(info, obj._listeners)
126     obj:onConnect()
127     return obj
128 end
129
130
131 return InPortPullConnector

File lua\openrtm\InPortPushConnector.lua

1 ---------------------------------
2 --! @file InPortPushConnector.lua
3 --! @brief Push型通信InPortConnector定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local InPortPushConnector= {}
11 --_G["openrtm.InPortPushConnector"] = InPortPushConnector
12
13 local InPortConnector = require "openrtm.InPortConnector"
14 local DataPortStatus = require "openrtm.DataPortStatus"
15 local BufferStatus = require "openrtm.BufferStatus"
16 local InPortProvider = require "openrtm.InPortProvider"
17 local InPortProviderFactory = InPortProvider.InPortProviderFactory
18 local CdrBufferBase = require "openrtm.CdrBufferBase"
19 local CdrBufferFactory = CdrBufferBase.CdrBufferFactory
20
21
22 local ConnectorListener = require "openrtm.ConnectorListener"
23 local ConnectorListenerType = ConnectorListener.ConnectorListenerType
24 local ConnectorDataListenerType = ConnectorListener.ConnectorDataListenerType
25
26 -- Push型通信InPortConnectorの初期化
27 -- @param info プロファイル
28 -- 「buffer」という要素名にバッファの設定を格納
29 -- @param provider プロバイダ
30 -- @param listeners コールバック
31 -- @param buffer バッファ
32 -- 指定しない場合はリングバッファを生成する
33 -- @return Push型通信InPortConnector
34 InPortPushConnector.new = function(info, provider, listeners, buffer)
35     local obj = {}
36     --print(buffer)
37     setmetatable(obj, {__index=InPortConnector.new(info, buffer)})
38
39
40     -- データ読み込み
41     -- @param data data._dataにデータを格納
42     -- @return リターンコード
43     -- バッファの読み込み結果によって、PORT_OK、BUFFER_EMPTY、BUFFER_TIMEOUT
44     -- PRECONDITION_NOT_MET、PORT_ERRORを返す
45     function obj:read(data)
46         self._rtcout:RTC_TRACE("read()")
47
48         local ret = BufferStatus.BUFFER_OK
49         if self._buffer == nil then
50             return DataPortStatus.PRECONDITION_NOT_MET
51         end
52         local cdr = {_data=""}
53         ret = self._buffer:read(cdr)
54         
55         if self._dataType == nil then
56             return BufferStatus.PRECONDITION_NOT_MET
57         end
58
59         if ret == BufferStatus.BUFFER_OK then
60             local Manager = require "openrtm.Manager"
61             data._data = Manager:instance():cdrUnmarshal(cdr._data, self._dataType)
62         end
63
64         if ret == BufferStatus.BUFFER_OK then
65             self:onBufferRead(cdr._data)
66             return DataPortStatus.PORT_OK
67
68         elseif ret == BufferStatus.BUFFER_EMPTY then
69             self:onBufferEmpty()
70             return DataPortStatus.BUFFER_EMPTY
71
72         elseif ret == BufferStatus.TIMEOUT then
73             self:onBufferReadTimeout()
74             return DataPortStatus.BUFFER_TIMEOUT
75
76         elseif ret == BufferStatus.PRECONDITION_NOT_MET then
77             return DataPortStatus.PRECONDITION_NOT_MET
78         end
79
80         return DataPortStatus.PORT_ERROR
81     end
82     -- コネクタ切断
83     -- @return リターンコード
84     function obj:disconnect()
85         self._rtcout:RTC_TRACE("disconnect()")
86         self:onDisconnect()
87
88         if self._provider ~= nil then
89             local cfactory = InPortProviderFactory:instance()
90             cfactory:deleteObject(self._provider)
91
92             self._provider:exit()
93         end
94
95         self._provider = nil
96
97
98         if self._buffer ~= nil and self._deleteBuffer == true then
99             local bfactory = CdrBufferFactory:instance()
100             bfactory:deleteObject(self._buffer)
101         end
102
103         self._buffer = nil
104
105         return DataPortStatus.PORT_OK
106     end
107     -- アクティブ化
108     function obj:activate()
109     end
110     -- 非アクティブ化
111     function obj:deactivate()
112     end
113     -- バッファ作成
114     -- リングバッファを生成する
115     -- @param profile コネクタプロファイル
116     -- @return バッファ
117     function obj:createBuffer(profile)
118         buf_type = profile.properties:getProperty("buffer_type","ring_buffer")
119         return CdrBufferFactory:instance():createObject(buf_type)
120     end
121     -- データ書き込み
122     -- @param data データ(CDR)
123     -- @return リターンコード(バッファの書き込み結果による)
124     function obj:write(data)
125         --print(self._dataType)
126         --print("write")
127
128
129         --print(_data.data)
130         return self._buffer:write(data)
131     end
132
133     -- コネクタ接続時のコールバック呼び出し
134     function obj:onConnect()
135         --print("onConnect")
136         if self._listeners ~= nil and self._profile ~= nil then
137             self._listeners.connector_[ConnectorListenerType.ON_CONNECT]:notify(self._profile)
138         end
139     end
140
141     -- コネクタ切断時のコールバック呼び出し
142     function obj:onDisconnect()
143         if self._listeners and self._profile then
144             self._listeners.connector_[ConnectorListenerType.ON_DISCONNECT]:notify(self._profile)
145         end
146     end
147     
148     function obj:onBufferRead(data)
149         
150         if self._listeners and self._profile then
151             self._listeners.connectorData_[ConnectorDataListenerType.ON_BUFFER_READ]:notify(self._profile, data)
152         end
153     end
154     
155     function obj:onBufferEmpty()
156         if self._listeners and self._profile then
157             self._listeners.connector_[ConnectorListenerType.ON_BUFFER_EMPTY]:notify(self._profile)
158         end
159     end
160     
161     function obj:onBufferReadTimeout()
162         if self._listeners and self._profile then
163             self._listeners.connector_[ConnectorListenerType.ON_BUFFER_READ_TIMEOUT]:notify(self._profile)
164         end
165     end
166
167     obj._provider = provider
168     obj._listeners = listeners
169
170     --print(buffer)
171     if buffer ~= nil then
172         obj._deleteBuffer = true
173     else
174         obj._deleteBuffer = false
175     end
176
177
178     if obj._buffer == nil then
179         obj._buffer = obj:createBuffer(info)
180     end
181
182
183     if obj._buffer == nil or obj._provider == nil then
184         error("")
185     end
186     
187     obj._buffer:init(info.properties:getNode("buffer"))
188     obj._provider:init(info.properties)
189     obj._provider:setBuffer(obj._buffer)
190     obj._provider:setListener(info, obj._listeners)
191
192     obj:onConnect()
193     return obj
194 end
195
196
197 return InPortPushConnector

File lua\openrtm\ListenerHolder.lua

1 ---------------------------------
2 --! @file ListenerHolder.lua
3 --! @brief リスナ保持クラス定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local ListenerHolder= {}
11 --_G["openrtm.ListenerHolder"] = ListenerHolder
12
13 local Entry = {}
14 Entry.new = function(listener, autoclean)
15     local obj = {}
16     obj.listener  = listener
17     obj.autoclean = autoclean
18     return obj
19 end
20
21
22 ListenerHolder.new = function()
23     local obj = {}
24     obj._listeners = {}
25     function obj:addListener(listener, autoclean)
26         table.insert(self._listeners, Entry.new(listener, autoclean))
27     end
28     function obj:removeListener(listener)
29         for i,_listener in ipairs(self._listeners) do
30             if _listener.listener == listener then
31                 if _listener.autoclean then
32                     table.remove(self._listeners, i)
33                 end
34             end
35         end
36     end
37     function obj:notify(func, ...)
38         for i, listener in ipairs(self._listeners) do
39             listener.listener[func](listener.listener, ...)
40         end
41         
42     end
43     return obj
44 end
45
46
47 return ListenerHolder

File lua\openrtm\LogstreamBase.lua

Full coverage

File lua\openrtm\LogstreamFile.lua

1 ---------------------------------
2 --! @file LogstreamFile.lua
3 --! @brief ファイル出力ロガーストリーム定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local LogstreamBase = require "openrtm.LogstreamBase"
11 local LogstreamFactory = LogstreamBase.LogstreamFactory
12 local Factory = require "openrtm.Factory"
13 local StringUtil = require "openrtm.StringUtil"
14 local Logger = require "openrtm.SystemLogger"
15
16
17
18 local LogstreamFile= {}
19 -- LogstreamFile.s_logger = nil
20 --_G["openrtm.LogstreamFile"] = LogstreamFile
21
22 -- ファイル出力ロガーストリームオブジェクト初期化
23 -- @return
24 LogstreamFile.new = function()
25     local obj = {}
26     setmetatable(obj, {__index=LogstreamBase.new()})
27     obj.handlers = {}
28     
29     -- 初期化時にプロパティを設定
30     -- @param prop プロパティ
31     -- 「file_name」の要素にファイル名
32     -- 「,」で区切る
33     -- 「stdout」に設定した場合は標準出力
34     -- @return true:設定成功、false:設定失敗
35     -- 登録したロガーの数が0の場合はfalse
36     function obj:init(prop)
37         --self.logger = require"logging.console"
38         --if LogstreamFile.s_logger == nil then
39         -- LogstreamFile.s_logger = self
40         --end
41         
42         
43         local files = StringUtil.split(prop:getProperty("file_name"), ",")
44         for k,v in pairs(files) do
45             self:addHandler(StringUtil.eraseBothEndsBlank(v))
46         end
47         
48         
49         if StringUtil.getKeyCount(self.handlers) == 0 then
50             return false
51         end
52         
53         return true
54     end
55     
56     -- ロガーの登録
57     -- @param f ファイル名
58     -- 「stdout」の場合は標準出力
59     -- @return true:登録成功、false:登録失敗
60     -- 既に登録済みの場合はfalse
61     -- 空文字列の場合はfalse
62     function obj:addHandler(f)
63         f = StringUtil.eraseBothEndsBlank(f)
64         for k,v in pairs(self.handlers) do
65             if k == f then
66                 return false
67             end
68         end
69         local fname = StringUtil.normalize(f)
70         if fname == "" then
71             return false
72         end
73         
74         if fname == "stdout" then
75             require "logging.console"
76             self.handlers[fname] = logging.console()
77             return true
78         else
79             require "logging.file"
80             self.handlers[fname] = logging.file(fname)
81             return true
82         end
83     end
84     -- ログ出力
85     -- @param msg 出力文字列
86     -- @param level ログレベル
87     -- @param name ロガー名
88     -- @return true:出力成功、false:出力失敗
89     -- 設定できないログレベルの場合はfalse
90     function obj:log(msg, level, name)
91         if level == Logger.FATAL then
92             for k,v in pairs(self.handlers) do
93                 v:fatal(name..msg)
94             end
95         elseif level == Logger.ERROR then
96             for k,v in pairs(self.handlers) do
97                 v:error(name.." "..msg)
98             end
99         elseif level == Logger.WARN then
100             for k,v in pairs(self.handlers) do
101                 v:warn(name.." "..msg)
102             end
103         elseif level == Logger.INFO then
104             for k,v in pairs(self.handlers) do
105                 v:info(name.." "..msg)
106             end
107         elseif level == Logger.DEBUG then
108             for k,v in pairs(self.handlers) do
109                 v:debug(name.." "..msg)
110             end
111         elseif level == Logger.TRACE then
112             for k,v in pairs(self.handlers) do
113                 v:debug(name.." "..msg)
114             end
115         elseif level == Logger.VERBOSE then
116             for k,v in pairs(self.handlers) do
117                 v:debug(name.." "..msg)
118             end
119         elseif level == Logger.PARANOID then
120             for k,v in pairs(self.handlers) do
121                 v:debug(name.." "..msg)
122             end
123         else
124             return false
125         end
126         return true
127     end
128     
129     -- ログレベル設定
130     -- @param level ログレベル
131     function obj:setLogLevel(level)
132         if level == Logger.INFO then
133             for k,v in pairs(self.handlers) do
134                 v:setLevel(logging.INFO)
135             end
136         elseif level == Logger.FATAL then
137             for k,v in pairs(self.handlers) do
138                 v:setLevel(logging.FATAL)
139             end
140         elseif level == Logger.ERROR then
141             for k,v in pairs(self.handlers) do
142                 v:setLevel(logging.ERROR)
143             end
144         elseif level == Logger.WARN then
145             for k,v in pairs(self.handlers) do
146                 v:setLevel(logging.WARN)
147             end
148         elseif level == Logger.DEBUG then
149             for k,v in pairs(self.handlers) do
150                 v:setLevel(logging.DEBUG)
151             end
152         elseif level == Logger.SILENT then
153             for k,v in pairs(self.handlers) do
154                 v:setLevel(logging.DEBUG)
155             end
156         elseif level == Logger.TRACE then
157             for k,v in pairs(self.handlers) do
158                 v:setLevel(logging.DEBUG)
159             end
160         elseif level == Logger.VERBOSE then
161             for k,v in pairs(self.handlers) do
162                 v:setLevel(logging.DEBUG)
163             end
164         elseif level == Logger.PARANOID then
165             for k,v in pairs(self.handlers) do
166                 v:setLevel(logging.DEBUG)
167             end
168         else
169             for k,v in pairs(self.handlers) do
170                 v:setLevel(logging.INFO)
171             end
172         end
173     end
174     
175     -- ロガー終了
176     -- @return true;成功、false:失敗
177     function obj:shutdown()
178         self.handlers = {}
179         return true
180     end
181     
182     --function obj:getLogger(name)
183     -- if name ~= nil then
184     -- logging.getLogger("file."+name)
185     -- else
186     -- logging.getLogger("file."+name)
187     -- end
188     --end
189     
190     
191     return obj
192 end
193
194
195 -- ファイル出力ロガー生成ファクトリ登録
196 LogstreamFile.Init = function()
197     LogstreamFactory:instance():addFactory("file",
198         LogstreamFile.new,
199         Factory.Delete)
200 end
201
202
203
204 return LogstreamFile

File lua\openrtm\Manager.lua

1 ---------------------------------
2 --! @file Manager.lua
3 --! @brief RTC管理マネージャ定義
4 --! ORB初期化、RTCの生成、モジュールのロード、ロガー初期化、ファクトリ初期化等を実行
5 ---------------------------------
6
7 --[[
8 Copyright (c) 2017 Nobuhiko Miyamoto
9 ]]
10
11
12
13 local Manager= {}
14 --_G["openrtm.Manager"] = Manager
15
16 local oil = require "oil"
17 local ObjectManager = require "openrtm.ObjectManager"
18 local Properties = require "openrtm.Properties"
19 local StringUtil = require "openrtm.StringUtil"
20 local ManagerConfig = require "openrtm.ManagerConfig"
21 local SystemLogger = require "openrtm.SystemLogger"
22 local LogStream = SystemLogger.LogStream
23 local NumberingPolicyBase = require "openrtm.NumberingPolicyBase"
24 local NumberingPolicyFactory = NumberingPolicyBase.NumberingPolicyFactory
25 local ManagerActionListener = require "openrtm.ManagerActionListener"
26 local ManagerActionListeners = ManagerActionListener.ManagerActionListeners
27 local ManagerServant = require "openrtm.ManagerServant"
28 local CompParam = ManagerServant.CompParam
29 local NamingManager = require "openrtm.NamingManager"
30 local FactoryInit = require "openrtm.FactoryInit"
31 local PeriodicExecutionContext = require "openrtm.PeriodicExecutionContext"
32 local Factory = require "openrtm.Factory"
33 local FactoryLua = Factory.FactoryLua
34 local OpenHRPExecutionContext = require "openrtm.OpenHRPExecutionContext"
35 local SimulatorExecutionContext = require "openrtm.SimulatorExecutionContext"
36 local LogstreamBase = require "openrtm.LogstreamBase"
37 local LogstreamFactory = LogstreamBase.LogstreamFactory
38 local ModuleManager = require "openrtm.ModuleManager"
39 local Task = require "openrtm.Task"
40 local CORBA_RTCUtil = require "openrtm.CORBA_RTCUtil"
41 local SdoServiceConsumerBase = require "openrtm.SdoServiceConsumerBase"
42 local SdoServiceConsumerFactory = SdoServiceConsumerBase.SdoServiceConsumerFactory
43
44 local Timer = require "openrtm.Timer"
45
46 -- ORB_Dummy_ENABLEをtrueに設定した場合、
47 -- oil関連の処理はすべてダミー関数に置き換えられる
48 if ORB_Dummy_ENABLE == nil then
49  ORB_Dummy_ENABLE = false
50 end
51
52 if ORB_Dummy_ENABLE then
53
54  oil.corba = {}
55  oil.corba.idl = {}
56
57  oil.newthread = function(obj)
58  --obj()
59  end
60  function oil.tasks:suspend(t)
61
62  end
63
64  ORB_Dummy = {}
65
66  ORB_Dummy.types = {}
67
68  --oil = {}
69  oil.main = function(func)
70   func()
71  end
72  
73  function ORB_Dummy:loadidlfile(name)
74  end
75
76  function ORB_Dummy.types:lookup(name)
77   local ret = {}
78   ret.labelvalue = {}
79   if name == "::RTC::ReturnCode_t" then
80    ret.labelvalue.RTC_OK = 0
81    ret.labelvalue.RTC_ERROR = 1
82    ret.labelvalue.BAD_PARAMETER = 2
83    ret.labelvalue.UNSUPPORTED = 3
84    ret.labelvalue.OUT_OF_RESOURCES = 4
85    ret.labelvalue.PRECONDITION_NOT_MET = 5
86   elseif name == "::RTC::ExecutionKind" then
87    ret.labelvalue.PERIODIC = 0
88    ret.labelvalue.EVENT_DRIVEN = 1
89    ret.labelvalue.OTHER = 2
90   elseif name == "::RTC::LifeCycleState" then
91    ret.labelvalue.CREATED_STATE = 0
92    ret.labelvalue.INACTIVE_STATE = 1
93    ret.labelvalue.ACTIVE_STATE = 2
94    ret.labelvalue.ERROR_STATE = 3
95   elseif name == "::OpenRTM::PortStatus" then
96    ret.labelvalue.PORT_OK = 0
97    ret.labelvalue.PORT_ERROR = 1
98    ret.labelvalue.BUFFER_FULL = 2
99    ret.labelvalue.BUFFER_EMPTY = 3
100    ret.labelvalue.BUFFER_TIMEOUT = 4
101    ret.labelvalue.UNKNOWN_ERROR = 5
102   elseif name == "::RTC::PortStatus" then
103    ret.labelvalue.PORT_OK = 0
104    ret.labelvalue.PORT_ERROR = 1
105    ret.labelvalue.BUFFER_FULL = 2
106    ret.labelvalue.BUFFER_EMPTY = 3
107    ret.labelvalue.BUFFER_TIMEOUT = 4
108    ret.labelvalue.UNKNOWN_ERROR = 5
109   elseif name == "::RTC::PortInterfacePolarity" then
110    ret.labelvalue.PROVIDED = 0
111    ret.labelvalue.REQUIRED = 1
112   end
113   return ret
114  end
115
116  function ORB_Dummy:newservant(obj, name, idl)
117   return obj
118  end
119
120  function ORB_Dummy:tostring(ref)
121   return ref
122  end
123
124  function ORB_Dummy:newencoder()
125   local encoder = {}
126   encoder.data = 0
127   function encoder:put(data, data_type)
128    self.data = data
129   end
130   function encoder:getdata()
131
132    return self.data
133   end
134
135
136   return encoder
137  end
138
139  function ORB_Dummy:newdecoder(cdr)
140   local decoder = {}
141   decoder.cdr = cdr
142
143   function decoder:get(data_type)
144    return self.cdr
145   end
146
147   return decoder
148  end
149
150
151  function ORB_Dummy:deactivate(object)
152
153  end
154
155  Dummy_NameServer = {}
156
157  Dummy_NameServer.new = function()
158   local obj = {}
159   function obj:rebind(name_list, obj)
160    print("rebind:")
161    for i, name in ipairs(name_list) do
162     print(name.id, name.kind)
163    end
164   end
165
166   function obj:unbind(name_list)
167    print("unbind:")
168    for i, name in ipairs(name_list) do
169     print(name.id, name.kind)
170    end
171   end
172   function obj:bind_new_context(name_list)
173    for i, name in ipairs(name_list) do
174     print(name.id, name.kind)
175    end
176    return Dummy_NameServer.new()
177   end
178   function obj:resolve(name_list)
179    for i, name in ipairs(name_list) do
180     print(name.id, name.kind)
181    end
182    return Dummy_NameServer.new()
183   end
184   return obj
185  end
186
187  NameServer_dummy = Dummy_NameServer.new()
188
189  Manager.Dummy_InPortCDR = {}
190  Dummy_InPortCDR = Manager.Dummy_InPortCDR
191  Dummy_InPortCDR.new = function()
192   local obj = {}
193   function obj:put(data)
194    return ORB_Dummy.types:lookup("::OpenRTM::PortStatus").PORT_OK
195   end
196   function obj:push(data)
197    return ORB_Dummy.types:lookup("::RTC::PortStatus").PORT_OK
198   end
199   function obj:getObjRef()
200    return self
201   end
202   return obj
203  end
204
205  Manager.Dummy_OutPortCDR = {}
206  Dummy_OutPortCDR = Manager.Dummy_OutPortCDR
207  Dummy_OutPortCDR.new = function()
208   local obj = {}
209   function obj:get()
210    return ORB_Dummy.types:lookup("::OpenRTM::PortStatus").PORT_OK, ""
211   end
212   function obj:pull()
213    return ORB_Dummy.types:lookup("::RTC::PortStatus").PORT_OK, ""
214   end
215   function obj:getObjRef()
216    return self
217   end
218   return obj
219  end
220
221
222
223  function ORB_Dummy:newproxy(ref, proxy,idl)
224   local ret = ref
225   if oil.VERSION == "OiL 0.4 beta" then
226    idl = proxy
227   end
228
229   if idl == "IDL:omg.org/CosNaming/NamingContext:1.0" then
230    ret = NameServer_dummy
231   elseif idl == "IDL:openrtm.aist.go.jp/OpenRTM/InPortCdr:1.0" and ref == "IOR:Dummy" then
232    ret = Dummy_InPortCDR.new()
233   elseif idl == "IDL:omg.org/RTC/DataPushService:1.0" and ref == "IOR:Dummy" then
234    ret = Dummy_InPortCDR.new()
235   elseif idl == "IDL:openrtm.aist.go.jp/OpenRTM/OutPortCdr:1.0" and ref == "IOR:Dummy" then
236    ret = Dummy_OutPortCDR.new()
237   elseif idl == "IDL:omg.org/RTC/DataPullService:1.0" and ref == "IOR:Dummy" then
238    ret = Dummy_OutPortCDR.new()
239   else
240   end
241   ret._non_existent = function(self)
242    return false
243   end
244   ret._is_equivalent = function(self, other)
245    --print(self, other)
246    if self._profile ~= nil then
247     if self._profile.name ~= nil then
248      if self._profile.name == other._profile.name then
249       return true
250      end
251     end
252    end
253    return (self == other)
254   end
255   --print("test2:",ret,ref)
256   return ret
257  end
258
259 end
260
261
262 -- インスタンス名一致判定関数オブジェクト初期化
263 -- @param argv argv.prop:プロパティ、argv._name:インスタンス名
264 -- @return インスタンス名一致判定関数オブジェクト
265 local InstanceName = function(argv)
266  local obj = {}
267  if argv.prop then
268   obj._name = argv.prop:getProperty("instance_name")
269  elseif argv.factory then
270   obj._name = argv.factory:getInstanceName()
271  elseif argv.name then
272   obj._name = argv.name
273  end
274  -- インスタンス名一致判定
275  -- @param comp RTC
276  -- @return true:一致、false:不一致
277  local call_func = function(self, comp)
278   return (self._name == comp:getInstanceName())
279  end
280  setmetatable(obj, {__call=call_func})
281  return obj
282 end
283
284 -- RTC生成ファクトリ一致判定関数オブジェクトの初期化
285 -- @param argv argv.name:型名、argv.prop:プロパティ、factory:ファクトリ
286 local FactoryPredicate = function(argv)
287  local obj = {}
288  if argv.name then
289   obj._vendor = ""
290   obj._category = ""
291   obj._impleid = argv.name
292   obj._version = ""
293  elseif argv.prop then
294   obj._vendor = argv.prop:getProperty("vendor")
295   obj._category = argv.prop:getProperty("category")
296   obj._impleid = argv.prop:getProperty("implementation_id")
297   --print(obj._impleid)
298   obj._version = argv.prop:getProperty("version")
299  elseif argv.factory then
300   obj._vendor = argv.factory:profile():getProperty("vendor")
301   obj._category = argv.factory:profile():getProperty("category")
302   obj._impleid = argv.factory:profile():getProperty("implementation_id")
303   obj._version = argv.factory:profile():getProperty("version")
304  end
305
306  -- RTC生成ファクトリ一致判定関数
307  -- @param self 自身のオブジェクト
308  -- @param factory ファクトリ
309  -- @return true:一致、false:不一致
310  local call_func = function(self, factory)
311   if self._impleid == "" then
312    return false
313   end
314   local _prop = Properties.new({prop=factory:profile()})
315   --print(factory:profile())
316   --print(_prop:)
317   --print(self._impleid,_prop:getProperty("implementation_id"))
318   --print(self._impleid, self._vendor, self._category, self._version)
319   --print(_prop:getProperty("implementation_id"), _prop:getProperty("vendor"), _prop:getProperty("category"), _prop:getProperty("implementation_id"))
320   if self._impleid ~= _prop:getProperty("implementation_id") then
321    return false
322   end
323   if self._vendor ~= "" and self._vendor ~= _prop:getProperty("vendor") then
324    return false
325   end
326   if self._category  ~= "" and self._category  ~= _prop:getProperty("category") then
327    return false
328   end
329   if self._version  ~= "" and self._version  ~= _prop:getProperty("version") then
330    return false
331   end
332
333   return true
334  end
335  setmetatable(obj, {__call=call_func})
336  return obj
337 end
338
339 -- EC生成ファクトリ一致判定関数オブジェクトの初期化
340 -- @param argv argv.name:型名、argv.factory:ファクトリ
341 -- @return EC生成ファクトリ一致判定関数オブジェクト
342 local ECFactoryPredicate = function(argv)
343  local obj = {}
344  if argv.name then
345   obj._name  = argv.name
346  elseif argv.factory then
347   obj._name = argv.factory:name()
348  end
349  -- EC生成ファクトリ一致判定関数
350  -- @param self 自身のオブジェクト
351  -- @param factory ファクトリ
352  -- @return true:一致、false:不一致
353  local call_func = function(self, factory)
354   return (self._name == factory:name())
355  end
356  setmetatable(obj, {__call=call_func})
357  return obj
358 end
359
360
361 -- モジュール一致判定関数オブジェクト初期化
362 -- @param prop プロパティ
363 -- @return モジュール一致判定関数オブジェクト
364 local ModulePredicate = function(prop)
365  local obj = {}
366  obj._prop  = prop
367  -- モジュール一致判定関数
368  -- @param self 自身のオブジェクト
369  -- @param prop プロパティ
370  -- @return true:一致、false:不一致
371  local call_func = function(self, prop)
372   if self._prop:getProperty("implementation_id") ~= prop:getProperty("implementation_id") then
373    return false
374   end
375   if self._prop:getProperty("vendor") ~= "" and self._prop:getProperty("vendor") ~= prop:getProperty("vendor") then
376    return false
377   end
378   if self._prop:getProperty("category") ~= "" and self._prop:getProperty("category") ~= prop:getProperty("category") then
379    return false
380   end
381   if self._prop:getProperty("version") ~= "" and self._prop:getProperty("version") ~= prop:getProperty("version") then
382    return false
383   end
384   return true
385  end
386  setmetatable(obj, {__call=call_func})
387  return obj
388 end
389
390 local Finalized = {}
391
392 -- 終了したRTCを登録するオブジェクト初期化
393 -- @return 終了したRTCを登録するオブジェクト
394 Finalized.new = function()
395  local obj = {}
396  obj.comps = {}
397  return obj
398 end
399
400 -- マネージャ初期化
401 -- 以下の処理を実行
402 -- オブジェクトマネージャ(RTC、EC)初期化
403 -- ファクトリ初期化
404 -- ロガー初期化
405 -- 実行コンテキスト生成ファクトリ初期化
406 -- 複合コンポーネント生成ファクトリ初期化
407 -- マネージャアクションコールバック関数オブジェクト初期化
408 -- @param argv コマンドライン引数
409 -- "-a":マネージャサーバント無効
410 -- "-f":設定ファイル指定
411 -- "-l":ロードするモジュール指定
412 -- "-o":追加のオプション指定
413 -- "-a":アドレス、ポート番号指定
414 -- "-d":マスターマネージャに設定
415 function Manager:init(argv)
416  if argv == nil then
417   argv = {}
418  end
419  self._initProc = nil
420  self._ecs = {}
421  if self._orb ~= nil then
422   self:createShutdownThread(1)
423  end
424  self._orb = nil
425  self._compManager = ObjectManager.new(InstanceName)
426  self._factory = ObjectManager.new(FactoryPredicate)
427  self._ecfactory = ObjectManager.new(ECFactoryPredicate)
428  self:initManager(argv)
429  self:initFactories()
430  self:initLogger()
431  self:initExecContext()
432  self:initComposite()
433  self:initTimer()
434  self._finalized = Finalized.new()
435     self._listeners = ManagerActionListeners.new()
436  self._initThread = nil
437 end
438
439
440
441
442 -- マネージャ終了処理開始
443 function Manager:terminate()
444
445 end
446
447 -- マネージャ終了
448 -- RTC全削除
449 -- ネーミングマネージャ終了
450 -- ORB終了
451 -- ロガー終了
452 function Manager:shutdown()
453  if not self.shutdown_start then
454   self.shutdown_start = true
455   self._listeners.manager_:preShutdown()
456   self:shutdownComponents()
457   self:shutdownManagerServant()
458   self:shutdownNaming()
459   self:shutdownORB()
460   self:shutdownManager()
461   self._listeners.manager_:postShutdown()
462   self:shutdownLogger()
463  end
464 end
465
466
467
468 function Manager:instance()
469  return self
470 end
471
472 -- マネージャ終了まで待機
473 function Manager:join()
474
475 end
476
477 -- 初期化時実行関数の設定
478 -- 指定関数はrunManager関数で実行される
479 -- @param proc 関数
480 -- proc(manager):マネージャを引数とする関数を定義
481 function Manager:setModuleInitProc(proc)
482  self._initProc = proc
483 end
484
485 -- マネージャアクティブ化
486 function Manager:activateManager()
487  local mods = StringUtil.strip(StringUtil.split(self._config:getProperty("manager.modules.preload"), ","))
488  
489  for k,mod in ipairs(mods) do
490   if mod == nil or mod == "" then
491   else
492    --local basename = StringUtil.split(StringUtil.basename(mod),"%.")[1]
493    --basename = basename.."Init"
494    
495    local success, exception = oil.pcall(
496     function()
497      --print(mod, "Init")
498      self._module:load(mod, "Init")
499     end)
500    if not success then
501     self._rtcout:RTC_ERROR(exception)
502    end
503   end
504  end
505  local sdofactory_ = SdoServiceConsumerFactory:instance()
506     self._config:setProperty("sdo.service.consumer.available_services",
507         StringUtil.flatten(sdofactory_:getIdentifiers()))
508  return true
509 end
510
511 -- マネージャ実行
512 -- 以下の処理を実行する
513 -- ORBの初期化
514 -- setModuleInitProc関数で指定した関数実行
515 -- マネージャサーバント初期化
516 -- ネーミングマネージャ初期化
517 -- @param no_block true:ノンブロッキングモードで実行、false:この関数でブロックする
518 -- ブロックモードで実行する場合は、step関数を適宜実行する必要がある
519 -- また、周期実行コンテキストなどコルーチンで実行する実行コンテキストは使用できない
520 function Manager:runManager(no_block)
521  self.shutdown_start = false
522  if no_block == nil then
523   no_block = false
524  end
525  self.no_block = no_block
526  oil.main(function()
527
528   self:initORB()
529
530   if no_block then
531    --oil.newthread(self._orb.step, self._orb)
532    local count = tonumber(self._config:getProperty("corba.step.count"))
533    if count ~= nil then
534     self:run_step(count)
535    end
536   else
537    oil.newthread(self._orb.run, self._orb)
538   end
539
540   self:initManagerServant()
541
542   self:initNaming()
543   --print(self._orb, self._orb.run)
544
545   if self._initProc ~= nil then
546    self._initProc(self)
547   end
548   if self._initThread ~= nil then
549    oil.newthread(self._initThread, self)
550   end
551
552
553
554   self:initPreCreation()
555   self:initPreConnection()
556   self:initPreActivation()
557
558   --self:unload("ConsoleIn")
559
560
561
562   --cout = self:getComponent("ConsoleOut0")
563   --cin = self:getComponent("ConsoleIn0")
564   --config = self:getComponent("ConfigSample0")
565
566   --print(CORBA_RTCUtil.get_component_profile(cin))
567   --print(CORBA_RTCUtil.is_existing(cin))
568   --print(CORBA_RTCUtil.is_alive_in_default_ec(cin))
569   --ec_cin = CORBA_RTCUtil.get_actual_ec(cin)
570   --print(CORBA_RTCUtil.get_ec_id(cin,ec_cin))
571
572   --CORBA_RTCUtil.activate(cout)
573   --CORBA_RTCUtil.activate(cin)
574   --oil.tasks:suspend(10)
575   --CORBA_RTCUtil.deactivate(cout)
576   --CORBA_RTCUtil.reset(cin)
577
578   --print(CORBA_RTCUtil.get_state(cin))
579
580   --rtc = self._namingManager:string_to_component("rtcname://localhost/*/TkJoyStick0")
581   --rtc = self._namingManager:string_to_component("rtcname://localhost/openrtm.host_cxt/TkJoyStick0")
582   --print(#rtc)
583   --rtc = self._namingManager:string_to_component("rtcloc://localhost:2810/TkJoyStick0")
584
585
586   --print(CORBA_RTCUtil.get_state(rtc[1]))
587   --print(CORBA_RTCUtil.is_in_inactive(cin))
588   --print(CORBA_RTCUtil.is_in_inactive(rtc[1]))
589   --print(CORBA_RTCUtil.is_in_active(cin))
590   --print(CORBA_RTCUtil.is_in_active(rtc[1]))
591   --print(CORBA_RTCUtil.is_in_error(cin))
592   --print(CORBA_RTCUtil.is_in_error(rtc[1]))
593   --CORBA_RTCUtil.set_default_rate(cin, 100)
594   --CORBA_RTCUtil.set_default_rate(rtc[1], 800)
595   --print(CORBA_RTCUtil.get_default_rate(cin))
596   --print(CORBA_RTCUtil.get_default_rate(rtc[1]))
597   --CORBA_RTCUtil.set_current_rate(cin, 0, 200)
598   --CORBA_RTCUtil.set_current_rate(rtc[1], 0, 600)
599   --print(CORBA_RTCUtil.get_current_rate(cin, 0))
600   --print(CORBA_RTCUtil.get_current_rate(rtc[1], 0))
601   --print(#CORBA_RTCUtil.get_participants_rtc(cin))
602   --StringUtil.print_table(CORBA_RTCUtil.get_port_names(cin))
603   --StringUtil.print_table(CORBA_RTCUtil.get_inport_names(cout))
604   --StringUtil.print_table(CORBA_RTCUtil.get_outport_names(cin))
605   --StringUtil.print_table(CORBA_RTCUtil.get_svcport_names(cin))
606   --pin = CORBA_RTCUtil.get_port_by_name(cout,"ConsoleOut0.in")
607   --pout = CORBA_RTCUtil.get_port_by_name(cin,"ConsoleIn0.out")
608   --print(pin)
609   --print(#CORBA_RTCUtil.get_connector_names_by_portref(pin))
610   --local prop = Properties.new()
611   --CORBA_RTCUtil.connect("test_connector",prop,pin,pout)
612   --CORBA_RTCUtil.connect_multi("test_connector",prop,pin,{pout})
613   --print(#CORBA_RTCUtil.get_connector_names_by_portref(pin))
614   --StringUtil.print_table(CORBA_RTCUtil.get_connector_names(cout, "ConsoleOut0.in"))
615   --StringUtil.print_table(CORBA_RTCUtil.get_connector_ids_by_portref(pin))
616   --StringUtil.print_table(CORBA_RTCUtil.get_connector_ids(cout, "ConsoleOut0.in"))
617   --print(CORBA_RTCUtil.already_connected(pout,pin))
618   --CORBA_RTCUtil.connect_by_name("test_connector",prop,cout,"ConsoleOut0.in",cin,"ConsoleIn0.out")
619   --CORBA_RTCUtil.disconnect_by_portref_connector_name(pin, "test_connector")
620   --print(CORBA_RTCUtil.get_port_by_url("rtcname://localhost/ConsoleIn0.out"))
621   --CORBA_RTCUtil.disconnect_by_portname_connector_name("rtcname://localhost/ConsoleIn0.out", "test_connector")]
622   --ids = CORBA_RTCUtil.get_connector_ids_by_portref(pin)
623   --print(CORBA_RTCUtil.get_configuration(config, "default"))
624   --print(CORBA_RTCUtil.get_parameter_by_key(config, "default", "double_param0"))
625   --print(CORBA_RTCUtil.get_active_configuration_name(config))
626   --print(CORBA_RTCUtil.get_active_configuration(config))
627   --CORBA_RTCUtil.set_configuration(config, "default", "double_param0", "1.5")
628   --CORBA_RTCUtil.set_active_configuration(config, "double_param0", "10.5")
629   --CORBA_RTCUtil.disconnect_by_port_name(pout, "ConsoleOut0.in")
630   --CORBA_RTCUtil.disconnect_all_by_ref(pout)
631   --CORBA_RTCUtil.disconnect_all_by_name("rtcname://localhost/ConsoleIn0.out")
632   --CORBA_RTCUtil.disconnect_by_portname_connector_id("rtcname://localhost/ConsoleIn0.out", ids[1])
633   --CORBA_RTCUtil.disconnect_by_portref_connector_id(pout, ids[1])
634   --print(#rtc)
635   --print(self:getManagerServant():get_components_by_name("mesure_lua0"))
636   --CORBA_RTCUtil.activate(rtc[1])
637   --self:createComponent("ConfigSample")
638   --local mgrs = self:getManagerServant()
639   --mgrs:create_component("mesure_lua")
640   --local module_name = {"rtc?manager=test"}
641   --local ret = mgrs:getParameterByModulename("manager",module_name)
642   --print(ret, module_name[1])
643   --self._orb:run()
644  end)
645 end
646
647 -- CORBAの処理を1ステップ進める
648 -- ノンブロックモードの場合のみ有効
649 function Manager:step()
650  if self.no_block then
651   oil.main(function()
652    oil.newthread(self._orb.step, self._orb)
653   end)
654  end
655 end
656
657
658 -- CORBAの処理を1ステップ進める
659 -- ノンブロックモードの場合のみ有効
660 function Manager:run_step(count)
661  if count == nil then
662   count = 1
663  end
664  if self.no_block then
665   local stepfunc = function(orb)
666    for i=1,count do
667     orb:step()
668    end
669   end
670   oil.newthread(stepfunc, self._orb)
671  end
672 end
673
674
675
676 -- すべてのモジュールをアンロード
677 function Manager:unloadAll()
678  self._rtcout:RTC_TRACE("Manager.unloadAll()")
679  self._module:unloadAll()
680 end
681
682 -- ロード済みモジュール一覧取得
683 -- @return ロード済みモジュール一覧
684 function Manager:getLoadedModules()
685  self._rtcout:RTC_TRACE("Manager.getLoadedModules()")
686  return self._module:getLoadedModules()
687 end
688
689 -- ロード可能モジュール一覧取得
690 -- @return ロード可能モジュール一覧
691 function Manager:getLoadableModules()
692  local ret = {}
693  return ret
694 end
695
696 -- RTC生成ファクトリの登録
697 -- @param profile プロファイル
698 -- 「manager.components.naming_policy」の要素で名前付けポリシーを指定
699 -- @param new_func 初期化関数
700 -- @param delete_func 削除関数
701 -- @return ファクトリ
702 function Manager:registerFactory(profile, new_func, delete_func)
703  --print(profile:getProperty("type_name"))
704  self._rtcout:RTC_TRACE("Manager.registerFactory("..profile:getProperty("type_name")..")")
705  local policy_name = self._config:getProperty("manager.components.naming_policy","process_unique")
706  local policy = NumberingPolicyFactory:instance():createObject(policy_name)
707  local factory = FactoryLua.new(profile, new_func, delete_func, policy)
708  --print(self._factory.registerObject)
709  return self._factory:registerObject(factory)
710 end
711
712
713 -- RTC生成ファクトリの削除
714 -- @param id プロファイルのID
715 -- @return 削除したファクトリ
716 function Manager:unregisterFactory(id)
717  self._rtcout:RTC_TRACE("Manager.unregisterFactory("..id..")")
718  return self._factory:unregisterObject(id)
719 end
720
721
722
723 -- RTC生成ファクトリプロファイル一覧取得
724 -- return RTC生成ファクトリプロファイル一覧
725 function Manager:getFactoryProfiles()
726  local factories = self._factory:getObjects()
727
728  if #factories == 0 then
729   return {}
730  end
731
732  local props = {}
733  for k,factory in ipairs(factories) do
734   table.insert(props, factory:profile())
735  end
736
737  return props
738 end
739
740 -- EC生成ファクトリ登録
741 -- @param profile プロファイル
742 -- @param new_func 初期化関数
743 -- @param delete_func 削除関数
744 -- @return ファクトリ
745 function Manager:registerECFactory(name, new_func, delete_func)
746 end
747
748 -- RTC生成ファクトリ一覧取得
749 -- @return RTC生成ファクトリ一覧
750 function Manager:getModulesFactories()
751  local ret = {}
752  return ret
753 end
754
755 -- RTC生成
756 -- @param comp_args RTC名とオプション(RTC?param1=xxx&param2=yyy)
757 -- RTC名は「RTC:ベンダ名:カテゴリ名:実装ID:言語名:バージョン」で指定
758 -- オプションで「instance_name」を指定した場合は、指定インスタンス名のRTCを返す
759 -- @return RTC
760 -- 以下の場合はnilを返す
761 -- comp_argsが不正
762 -- 指定IDのファクトリがない
763 -- RTCの生成失敗
764 -- initialize関数がRTC_OK以外を返す
765 function Manager:createComponent(comp_args)
766  self._rtcout:RTC_TRACE("Manager.createComponent("..comp_args..")")
767  local comp_prop = Properties.new()
768     local comp_id   = Properties.new()
769  if not self:procComponentArgs(comp_args, comp_id, comp_prop) then
770   return nil
771  end
772  if comp_prop:getProperty("instance_name") ~= nil then
773   comp = self:getComponent(comp_prop:getProperty("instance_name"))
774   if comp ~= nil then
775    return comp
776   end
777  end
778  self._listeners.rtclifecycle_:preCreate(comp_args)
779  if comp_prop:findNode("exported_ports") then
780  end
781  --print(comp_id)
782  local factory = self._factory:find(comp_id)
783  --print(comp_id, factory)
784  --print(factory)
785  if factory == nil then
786   self._rtcout:RTC_ERROR("createComponent: Factory not found: "..
787    comp_id:getProperty("implementation_id"))
788   if not StringUtil.toBool(self._config:getProperty("manager.modules.search_auto"), "YES", "NO", true) then
789    return nil
790   end
791   --[[
792   local mp = self._module:getLoadableModules()
793   self._rtcout:RTC_INFO(#mp.." loadable modules found")
794   local found_obj = nil
795   local predicate = ModulePredicate(comp_id)
796   for k, _obj in pairs(mp) do
797    if predicate(_obj) then
798     found_obj = _obj
799     break
800    end
801   end
802   if found_obj == nil then
803    self._rtcout:RTC_ERROR("No module for "..comp_id:getProperty("implementation_id").." in loadable modules list")
804    return nil
805   end
806   if found_obj:findNode("module_file_name") == nil then
807    self._rtcout:RTC_ERROR("Hmm...module_file_name key not found.")
808    return nil
809   end
810   self._rtcout:RTC_INFO("Loading module: "..found_obj:getProperty("module_file_name"))
811   self:load(found_obj:getProperty("module_file_name"), "")
812   --]]
813         self:load(comp_id:getProperty("implementation_id"), "")
814
815         factory = self._factory:find(comp_id)
816         if factory == nil then
817             self._rtcout:RTC_ERROR("Factory not found for loaded module: "..comp_id:getProperty("implementation_id"))
818             return nil
819         end
820     end
821     local prop = factory:profile()
822     local inherit_prop = {"config.version",
823                     "openrtm.name",
824                     "openrtm.version",
825                     "os.name",
826                     "os.release",
827                     "os.version",
828                     "os.arch",
829                     "os.hostname",
830                     "corba.endpoints",
831                     "corba.endpoints_ipv4",
832                     "corba.endpoints_ipv6",
833                     "corba.id",
834                     "exec_cxt.periodic.type",
835                     "exec_cxt.periodic.rate",
836                     "exec_cxt.event_driven.type",
837                     "exec_cxt.sync_transition",
838                     "exec_cxt.sync_activation",
839                     "exec_cxt.sync_deactivation",
840                     "exec_cxt.sync_reset",
841                     "exec_cxt.transition_timeout",
842                     "exec_cxt.activation_timeout",
843                     "exec_cxt.deactivation_timeout",
844                     "exec_cxt.reset_timeout",
845                     "exec_cxt.cpu_affinity",
846                     "logger.enable",
847                     "logger.log_level",
848                     "naming.enable",
849                     "naming.type",
850                     "naming.formats",
851                     "sdo.service.provider.available_services",
852                     "sdo.service.consumer.available_services",
853                     "sdo.service.provider.enabled_services",
854                     "sdo.service.consumer.enabled_services",
855                     "manager.instance_name"}
856     local prop_ = prop:getNode("port")
857     prop_:mergeProperties(self._config:getNode("port"))
858     local comp = factory:create(self)
859     --print(comp)
860     --print(comp:getTypeName())
861     --print(comp)
862
863     if comp == nil then
864         self._rtcout:RTC_ERROR("createComponent: RTC creation failed: "..
865                             comp_id:getProperty("implementation_id"))
866         return nil
867     end
868
869     if self._config:getProperty("corba.endpoints_ipv4") == "" then
870         self:setEndpointProperty(comp:getObjRef())
871     end
872     for i, v in pairs(inherit_prop) do
873         if self._config:findNode(v) then
874             --print(v, self._config:getProperty(v))
875             prop:setProperty(v,self._config:getProperty(v))
876         end
877     end
878
879     self._rtcout:RTC_TRACE("RTC Created: "..comp_id:getProperty("implementation_id"))
880     self._listeners.rtclifecycle_:postCreate(comp)
881     prop:mergeProperties(comp_prop)
882     self._listeners.rtclifecycle_:preConfigure(prop)
883     self:configureComponent(comp,prop)
884     self._listeners.rtclifecycle_:postConfigure(prop)
885     self._listeners.rtclifecycle_:preInitialize()
886     if comp:initialize() ~= self._ReturnCode_t.RTC_OK then
887         self._rtcout:RTC_TRACE("RTC initialization failed: "..
888                              comp_id:getProperty("implementation_id"))
889         self._rtcout:RTC_TRACE(comp_id:getProperty("implementation_id").." was finalized")
890         if comp:exit() ~= self._ReturnCode_t.RTC_OK then
891             self._rtcout:RTC_DEBUG(comp_id:getProperty("implementation_id").." finalization was failed.")
892         end
893         return nil
894     end
895     self._rtcout:RTC_TRACE("RTC initialization succeeded: "..
896                            comp_id:getProperty("implementation_id"))
897     self._listeners.rtclifecycle_:postInitialize()
898     self:registerComponent(comp)
899     return comp
900 end
901
902 -- RTCの登録
903 -- オブジェクトマネージャへの登録
904 -- ネーミングマネージャへの登録
905 -- @param comp RTC
906 -- @return true:登録成功、false:登録失敗
907 function Manager:registerComponent(comp)
908     self._rtcout:RTC_TRACE("Manager.registerComponent("..comp:getInstanceName()..")")
909
910     --print(comp:getInstanceName())
911     self._compManager:registerObject(comp)
912     local names = comp:getNamingNames()
913
914     self._listeners.naming_:preBind(comp, names)
915
916     for i, name in ipairs(names) do
917         --print(name)
918         self._rtcout:RTC_TRACE("Bind name: "..name)
919         self._namingManager:bindObject(name, comp)
920     end
921     self._listeners.naming_:postBind(comp, names)
922
923     self:publishPorts(comp)
924     self:subscribePorts(comp)
925
926     return true
927 end
928
929 -- RTCの登録解除
930 -- オブジェクトマネージャから登録解除
931 -- ネーミングマネージャから登録解除
932 -- @param comp RTC
933 function Manager:unregisterComponent(comp)
934     self._rtcout:RTC_TRACE("Manager.unregisterComponent("..comp:getInstanceName()..")")
935     self._compManager:unregisterObject(comp:getInstanceName())
936     local names = comp:getNamingNames()
937
938     self._listeners.naming_:preUnbind(comp, names)
939     for i,name in ipairs(names) do
940         self._rtcout:RTC_TRACE("Unbind name: "..name)
941         self._namingManager:unbindObject(name)
942     end
943     self._listeners.naming_:postUnbind(comp, names)
944 end
945
946 -- 実行コンテキスト生成
947 -- @param ec_args EC名とオプション(EC&param1=xxx&param2=yyy)
948 -- @return 実行コンテキスト
949 function Manager:createContext(ec_args)
950
951 end
952
953 -- RTCの削除
954 -- @param argv argv.instance_name:インスタンス名、argv.comp:RTC
955 -- インスタンス名指定の場合はRTCを検索する
956 function Manager:deleteComponent(argv)
957     if argv.instance_name ~= nil then
958         local instance_name = argv.instance_name
959         self._rtcout.RTC_TRACE("Manager.deleteComponent("..instance_name..")")
960         local _comp = self._compManager:find(instance_name)
961         if _comp ~= nil then
962             self._rtcout:RTC_WARN("RTC "..instance_name.." was not found in manager.")
963             return
964         end
965         self:deleteComponent({comp=_comp})
966     elseif argv.comp ~= nil then
967         local comp = argv.comp
968         self._rtcout:RTC_TRACE("Manager.deleteComponent(RTObject_impl)")
969
970         self:unregisterComponent(comp)
971
972         local comp_id = comp:getProperties()
973         local factory = self._factory:find(comp_id)
974         --print(comp_id)
975
976         if factory == nil then
977             self._rtcout:RTC_DEBUG("Factory not found: "..
978                                comp_id:getProperty("implementation_id"))
979             return
980         else
981             self._rtcout:RTC_DEBUG("Factory found: "..
982                                comp_id:getProperty("implementation_id"))
983             factory:destroy(comp)
984         end
985         if StringUtil.toBool(self._config:getProperty("manager.shutdown_on_nortcs"), "YES", "NO", true) then
986             local comps = self:getComponents()
987             --print(#comps)
988             if #comps == 0 then
989                 self:createShutdownThread(1)
990             end
991         end
992     end
993 end
994
995 -- インスタンス名からRTC取得
996 -- @param instance_name インスタンス名
997 -- @return RTC
998 function Manager:getComponent(instance_name)
999     self._rtcout:RTC_TRACE("Manager.getComponent("..instance_name..")")
1000     return self._compManager:find(instance_name)
1001 end
1002
1003 -- マネージャアクションコールバックの登録
1004 -- @param listener コールバック関数オブジェクト
1005 -- @param autoclean 自動削除フラグ
1006 function Manager:addManagerActionListener(listener,autoclean)
1007     if autoclean == nil then
1008         autoclean = true
1009     end
1010     self._listeners.manager_:addListener(listener, autoclean)
1011 end
1012
1013 -- ネージャアクションコールバックの登録解除
1014 -- @param listener コールバック関数オブジェクト
1015 function Manager:removeManagerActionListener(listener)
1016     self._listeners.manager_:removeListener(listener)
1017 end
1018
1019 -- モジュールアクションコールバックの登録
1020 -- @param listener コールバック関数オブジェクト
1021 -- @param autoclean 自動削除フラグ
1022 function Manager:addModuleActionListener(listener, autoclean)
1023     if autoclean == nil then
1024         autoclean = true
1025     end
1026     self._listeners.module_:addListener(listener, autoclean)
1027 end
1028
1029 -- モジュールアクションコールバックの登録解除
1030 -- @param listener コールバック関数オブジェクト
1031 function Manager:removeModuleActionListener(listener)
1032     self._listeners.module_:removeListener(listener)
1033 end
1034
1035 -- RTC状態遷移アクションコールバックの登録
1036 -- @param listener コールバック関数オブジェクト
1037 -- @param autoclean 自動削除フラグ
1038 function Manager:addRtcLifecycleActionListener(listener, autoclean)
1039     if autoclean == nil then
1040         autoclean = true
1041     end
1042     self._listeners.rtclifecycle_:addListener(listener, autoclean)
1043 end
1044
1045 -- RTC状態遷移アクションコールバックの登録解除
1046 -- @param listener コールバック関数オブジェクト
1047 function Manager:removeRtcLifecycleActionListener(listener)
1048     self._listeners.rtclifecycle_:removeListener(listener)
1049 end
1050
1051 -- ネームサーバーアクションコールバックの登録
1052 -- @param listener コールバック関数オブジェクト
1053 -- @param autoclean 自動削除フラグ
1054 function Manager:addNamingActionListener(listener, autoclean)
1055     if autoclean == nil then
1056         autoclean = true
1057     end
1058     self._listeners.naming_:addListener(listener, autoclean)
1059 end
1060
1061 -- ネームサーバーアクションコールバックの登録解除
1062 -- @param listener コールバック関数オブジェクト
1063 function Manager:removeNamingActionListener(listener)
1064     self._listeners.naming_:removeListener(listener)
1065 end
1066
1067 -- ローカルサービスアクションコールバックの登録
1068 -- @param listener コールバック関数オブジェクト
1069 -- @param autoclean 自動削除フラグ
1070 function Manager:addLocalServiceActionListener(listener, autoclean)
1071     if autoclean == nil then
1072         autoclean = true
1073     end
1074     self._listeners.localservice_:addListener(listener, autoclean)
1075 end
1076
1077 -- ローカルサービスアクションコールバックの登録解除
1078 -- @param listener コールバック関数オブジェクト
1079 function Manager:removeLocalServiceActionListener(listener)
1080     self._listeners.localservice_:removeListener(listener)
1081 end
1082
1083 -- ORB取得
1084 -- @return ORB
1085 function Manager:getORB()
1086     --print(self._rtcout)
1087     --print(self)
1088     self._rtcout:RTC_TRACE("Manager.getORB()")
1089     --print(self._orb)
1090     return self._orb
1091 end
1092
1093 -- マネージャ初期化
1094 -- @param argv コマンドライン引数
1095 function Manager:initManager(argv)
1096     local config = ManagerConfig.new(argv)
1097     self._config = Properties.new()
1098     config:configure(self._config)
1099     self._config:setProperty("logger.file_name",self:formatString(self._config:getProperty("logger.file_name"),
1100                                                     self._config))
1101     self._module = ModuleManager.new(self._config)
1102
1103     --self._module:load("testModule.lua","init")
1104 end
1105
1106 function Manager:shutdownManagerServant()
1107     if self._mgrservant ~= nil then
1108         self._mgrservant:exit()
1109         self._mgrservant = nil
1110     end
1111 end
1112
1113 -- マネージャ終了
1114 function Manager:shutdownManager()
1115
1116 end
1117
1118 -- ロガーストリーム初期化
1119 -- ファイル出力ロガーを初期化する
1120 -- 「logger」の要素にプロパティを設定
1121 -- logger.file_name:ファイル名
1122 function Manager:initLogstreamFile()
1123     local logprop = self._config:getNode("logger")
1124     local logstream = LogstreamFactory:instance():createObject("file")
1125     if logstream == nil then
1126         return
1127     end
1128     if not logstream:init(logprop) then
1129         logstream = LogstreamFactory:instance():deleteObject(logstream)
1130     end
1131     self._rtcout:addLogger(logstream)
1132 end
1133
1134 -- ロガープラグイン初期化
1135 function Manager:initLogstreamPlugins()
1136
1137 end
1138
1139 -- 外部ロガーモジュール初期化
1140 function Manager:initLogstreamOthers()
1141     local factory = LogstreamFactory:instance()
1142     local pp = self._config:getNode("logger.logstream")
1143
1144     local leaf0 = pp:getLeaf()
1145
1146     for k,l in pairs(leaf0) do
1147         local lstype = l:getName()
1148         local logstream = factory:createObject(lstype)
1149         if logstream == nil then
1150             self._rtcout:RTC_WARN("Logstream "..lstype.." creation failed.")
1151         else
1152             self._rtcout:RTC_INFO("Logstream "..lstype.." created.")
1153             if not logstream:init(l) then
1154                 self._rtcout:RTC_WARN("Logstream "..lstype.." init failed.")
1155                 factory:deleteObject(logstream)
1156                 self._rtcout:RTC_WARN("Logstream "..lstype.." deleted.")
1157             else
1158                 self._rtcout:RTC_INFO("Logstream "..lstype.." added.")
1159                 self._rtcout:addLogger(logstream)
1160             end
1161         end
1162     end
1163 end
1164
1165 -- ロガー初期化
1166 -- @param true:設定成功
1167 function Manager:initLogger()
1168     self._rtcout = self:getLogbuf()
1169     --print(self._config:getProperty("logger.enable"), StringUtil.toBool(self._config:getProperty("logger.enable"), "YES", "NO", true))
1170     if not StringUtil.toBool(self._config:getProperty("logger.enable"), "YES", "NO", true) then
1171         return true
1172     end
1173
1174     self:initLogstreamFile()
1175     self:initLogstreamPlugins()
1176     self:initLogstreamOthers()
1177
1178     self._rtcout:setLogLevel(self._config:getProperty("logger.log_level"))
1179     self._rtcout:setLogLock(StringUtil.toBool(self._config:getProperty("logger.stream_lock"),
1180                                                 "enable", "disable", false))
1181     self._rtcout:RTC_INFO(self._config:getProperty("openrtm.version"))
1182     self._rtcout:RTC_INFO("Copyright (C) 2018")
1183     self._rtcout:RTC_INFO(" Nobuhiko Miyamoto")
1184     self._rtcout:RTC_INFO(" Tokyo Metropolitan University")
1185     self._rtcout:RTC_INFO("Manager starting.")
1186     self._rtcout:RTC_INFO("Starting local logging.")
1187
1188     return true
1189 end
1190
1191 -- ロガー終了
1192 function Manager:shutdownLogger()
1193
1194 end
1195
1196 -- ORB初期化
1197 function Manager:initORB()
1198
1199     if ORB_Dummy_ENABLE then
1200         self._orb = ORB_Dummy
1201     else
1202         if oil.VERSION == "OiL 0.6" then
1203             self._orb = oil.init{ flavor = "cooperative;corba;" }
1204         else
1205             self._orb = oil.init{ flavor = "cooperative;corba;intercepted;typed;base;" }
1206         end
1207
1208         if oil.VERSION == "OiL 0.5" then
1209             oil.corba.idl.null = nil
1210         elseif oil.VERSION == "OiL 0.6" then
1211             oil.corba = {}
1212             oil.corba.idl = {}
1213             oil.corba.idl.null = nil
1214
1215             oil.pcall = pcall
1216             self._orb.tostring = function(self, str)
1217                     return tostring(str)
1218                     end
1219         end
1220
1221         self._orb:loadidlfile(Manager:findIdLFile("CosNaming.idl"))
1222         self._orb:loadidlfile(Manager:findIdLFile("RTC.idl"))
1223         self._orb:loadidlfile(Manager:findIdLFile("OpenRTM.idl"))
1224         self._orb:loadidlfile(Manager:findIdLFile("DataPort.idl"))
1225         self._orb:loadidlfile(Manager:findIdLFile("Manager.idl"))
1226         self._orb:loadidlfile(Manager:findIdLFile("InterfaceDataTypes.idl"))
1227     end
1228     self._ReturnCode_t = self._orb.types:lookup("::RTC::ReturnCode_t").labelvalue
1229
1230 end
1231
1232
1233 function Manager:loadIdLFile(name)
1234     self._orb:loadidlfile(name)
1235 end
1236
1237 -- IDLファイルパス取得
1238 -- @param name IDLファイル名
1239 -- IDLファイルは、Manager.luaの存在するディレクトリの2階層上のディレクトリを検索する
1240 -- @return IDLファイルパス
1241 function Manager:findIdLFile(name)
1242     local fpath = StringUtil.dirname(string.sub(debug.getinfo(1)["source"],2))
1243     --local fpath = StringUtil.dirname(string.gsub(debug.getinfo(1)["source"],"@",""))
1244     --print(fpath)
1245     local _str = string.gsub(fpath,"\\","/").."../idl/"..name
1246     --print(_str)
1247     return _str
1248 end
1249
1250 -- ORBのオプション生成
1251 -- @return オプション
1252 function Manager:createORBOptions()
1253
1254 end
1255
1256 -- プロパティからエンドポイント一覧を取得
1257 -- @param endpoints エンドポイント一覧を格納する変数
1258 function Manager:createORBEndpoints(endpoints)
1259
1260 end
1261
1262 -- エンドポイントのオプション生成
1263 -- @param opt オプションの文字列を格納する変数
1264 -- @param endpoints エンドポイント一覧
1265 function Manager:createORBEndpointOption(opt, endpoints)
1266
1267 end
1268
1269 -- ORB終了
1270 function Manager:shutdownORB()
1271     self._orb:shutdown()
1272     self._orb = nil
1273 end
1274
1275 -- ネームサーバー接続初期化
1276 -- 「naming.enable」のプロパティがYESの時に有効
1277 -- 「naming.type」のプロパティでメソッドを指定
1278 -- 「メソッド名.nameservers」で利用するアドレスを指定
1279 -- @return true:初期化成功、false:初期化失敗
1280 function Manager:initNaming()
1281     self._rtcout:RTC_TRACE("Manager.initNaming()")
1282     self._namingManager = NamingManager.new(self)
1283     --print(StringUtil.toBool(self._config:getProperty("naming.enable"), "YES", "NO", true))
1284     if not StringUtil.toBool(self._config:getProperty("naming.enable"), "YES", "NO", true) then
1285         return true
1286     end
1287     local meths = StringUtil.split(self._config:getProperty("naming.type"),",")
1288     meths = StringUtil.strip(meths)
1289     --print(self._config:getProperty("naming.type"))
1290
1291     for i, meth in ipairs(meths) do
1292         --print(meth)
1293         local names = StringUtil.split(self._config:getProperty(meth..".nameservers"), ",")
1294         for j, name in ipairs(names) do
1295             --print(name)
1296             self._rtcout:RTC_TRACE("Register Naming Server: "..meth.."/"..name)
1297             self._namingManager:registerNameServer(meth,name)
1298         end
1299     end
1300     if StringUtil.toBool(self._config:getProperty("naming.update.enable"), "YES", "NO", true) then
1301     end
1302     return true
1303 end
1304
1305 -- ネームサーバー接続終了
1306 function Manager:shutdownNaming()
1307
1308 end
1309
1310 -- 実行コンテキスト生成ファクトリ初期化
1311 -- @return true:初期化成功、false:初期化失敗
1312 function Manager:initExecContext()
1313     self._rtcout:RTC_TRACE("Manager.initExecContext()")
1314     PeriodicExecutionContext.Init(self)
1315     OpenHRPExecutionContext.Init(self)
1316     SimulatorExecutionContext.Init(self)
1317     
1318     return true
1319 end
1320
1321 -- 複合コンポーネント生成ファクトリ初期化
1322 -- @return true:登録成功、false:登録失敗
1323 function Manager:initComposite()
1324     return true
1325 end
1326
1327 -- ファクトリ初期化
1328 -- @return true:登録成功、false:登録失敗
1329 function Manager:initFactories()
1330     FactoryInit()
1331     return true
1332 end
1333
1334 -- タイマ初期化
1335 -- @return true:登録成功、false:登録失敗
1336 function Manager:initTimer()
1337     return true
1338 end
1339 function Manager:endpointPropertySwitch()
1340
1341 end
1342
1343 -- iPv4、iPv6のエンドポイント一覧取得
1344 -- @return エンドポイント一覧
1345 function Manager:setEndpointProperty()
1346     local ret = {}
1347     return ret
1348 end
1349
1350 -- マネージャサーバント初期化
1351 -- 「manager.corba_servant」のプロパティがYESの時に有効
1352 -- 「manager.is_master」のプロパティがYESの時にはマスターマネージャで起動
1353 -- @return true:初期化成功、false:初期化失敗
1354 function Manager:initManagerServant()
1355     self._rtcout:RTC_TRACE("Manager.initManagerServant()")
1356     if not StringUtil.toBool(
1357         self._config:getProperty("manager.corba_servant"), "YES","NO",true) then
1358         return true
1359     end
1360
1361     self._mgrservant = ManagerServant.new()
1362
1363     if self._config:getProperty("corba.endpoints_ipv4") == "" then
1364         self:setEndpointProperty(self._mgrservant:getObjRef())
1365     end
1366     local prop = self._config:getNode("manager")
1367     local names = StringUtil.split(prop:getProperty("naming_formats"),",")
1368
1369     if StringUtil.toBool(prop:getProperty("is_master"),
1370                            "YES","NO",true) then
1371         --for i, name in ipairs(names) do
1372         -- local mgr_name = self:formatString(name, prop)
1373         -- self._namingManager:bindManagerObject(mgr_name, self._mgrservant)
1374         --end
1375     end
1376     if StringUtil.toBool(self._config:getProperty("corba.update_master_manager.enable"),
1377                            "YES", "NO", true) and
1378                            not StringUtil.toBool(self._config:getProperty("manager.is_master"),
1379                                                    "YES", "NO", false) then
1380     end
1381
1382     local otherref = nil
1383
1384     local success, exception = oil.pcall(
1385         function()
1386         end)
1387     if not success then
1388     end
1389
1390     return true
1391 end
1392
1393 -- ローカルサービス初期化
1394 -- @return true:初期化成功、false:初期化失敗
1395 function Manager:initLocalService()
1396     return true
1397 end
1398
1399 -- 全RTC終了処理
1400 function Manager:shutdownComponents()
1401     self._rtcout:RTC_TRACE("Manager.shutdownComponents()")
1402     local comps = self._namingManager:getObjects()
1403     for k,comp in ipairs(comps) do
1404         local success, exception = oil.pcall(
1405             function()
1406                 comp:exit()
1407                 local p = Properties.new({key=comp:getInstanceName()})
1408                 p:mergeProperties(comp:getProperties())
1409         end)
1410         if not success then
1411
1412             self._rtcout:RTC_TRACE(exception)
1413         end
1414     end
1415
1416
1417     for k,ec in ipairs(self._ecs) do
1418         local success, exception = oil.pcall(
1419             function()
1420                 self._orb:deactivate(ec._svr)
1421         end)
1422         if not success then
1423             self._rtcout:RTC_TRACE(exception)
1424         end
1425     end
1426 end
1427
1428 -- RTC登録解除
1429 -- @param comp RTC
1430 function Manager:cleanupComponent(comp)
1431
1432 end
1433
1434 -- 全RTC登録解除
1435 -- 一旦、削除リストに格納したRTCを削除する
1436 function Manager:cleanupComponents()
1437     self._rtcout:RTC_VERBOSE("Manager.cleanupComponents()")
1438
1439     self._rtcout:RTC_VERBOSE(#self._finalized.comps.." components are marked as finalized.")
1440     for i, _comp in ipairs(self._finalized.comps) do
1441         self:deleteComponent({comp=_comp})
1442     end
1443
1444     self._finalized.comps = {}
1445 end
1446
1447 -- RTCを削除リストに追加する
1448 -- @param _comp RTC
1449 function Manager:notifyFinalized(_comp)
1450     self._rtcout:RTC_TRACE("Manager.notifyFinalized()")
1451
1452     --table.insert(self._finalized.comps, _comp)
1453     self:deleteComponent({comp=_comp})
1454 end
1455
1456 -- RTC名、オプションを文字列から取得
1457 -- @param comp_arg RTC名、オプション(RTC?param1=xxx&param2=yyy)
1458 -- RTC名は「RTC:ベンダ名:カテゴリ名:実装ID:言語名:バージョン」で指定
1459 -- @param comp_id RTC型名
1460 -- 以下の要素を格納する
1461 -- vendor:ベンダ名
1462 -- category:カテゴリ名
1463 -- implementation_id:実装ID
1464 -- language:言語名
1465 -- version:バージョン
1466 -- @param comp_conf オプション
1467 -- @return true:取得成功、false:取得失敗
1468 function Manager:procComponentArgs(comp_arg, comp_id, comp_conf)
1469     local id_and_conf_str = StringUtil.split(comp_arg, "?")
1470     local id_and_conf = {}
1471     for k, v in pairs(id_and_conf_str) do
1472         v = StringUtil.eraseHeadBlank(v)
1473         v = StringUtil.eraseTailBlank(v)
1474         table.insert(id_and_conf, v)
1475     end
1476     --StringUtil.print_table(id_and_conf)
1477     if #id_and_conf ~= 1 and #id_and_conf ~= 2 then
1478         self._rtcout:RTC_ERROR("Invalid arguments. Two or more '?'")
1479         return false
1480     end
1481     local prof = CompParam.prof_list
1482     local param_num = #prof
1483     --print(prof[1],id_and_conf[1])
1484     if id_and_conf[1]:find(":") == nil then
1485         id_and_conf[1] = prof[1]..":::"..id_and_conf[1].."::"
1486     end
1487
1488
1489     local id_str = StringUtil.split(id_and_conf[1], ":")
1490     local id = {}
1491     --print(id_and_conf[1],#id_str)
1492     for k, v in pairs(id_str) do
1493         v = StringUtil.eraseHeadBlank(v)
1494         v = StringUtil.eraseTailBlank(v)
1495         table.insert(id, v)
1496     end
1497     if #id ~= param_num then
1498         self._rtcout:RTC_ERROR("Invalid RTC id format.")
1499         return false
1500     end
1501
1502     if id[1] ~= prof[1] then
1503         self._rtcout:RTC_ERROR("Invalid id type.")
1504         return false
1505     end
1506
1507     for i = 2,param_num do
1508         --print(prof[i], id[i])
1509         comp_id:setProperty(prof[i], id[i])
1510         --print(prof[i])
1511         self._rtcout:RTC_TRACE("RTC basic profile "..prof[i]..": "..id[i])
1512     end
1513
1514     if #id_and_conf == 2 then
1515         local conf_str = StringUtil.split(id_and_conf[2], "&")
1516         local conf = {}
1517         for k, v in pairs(conf_str) do
1518             v = StringUtil.eraseHeadBlank(v)
1519             v = StringUtil.eraseTailBlank(v)
1520             table.insert(conf, v)
1521         end
1522         for i = 1,#conf do
1523             local keyval_str = StringUtil.split(conf[i], "=")
1524             local keyval = {}
1525             for k, v in pairs(keyval_str) do
1526                 v = StringUtil.eraseHeadBlank(v)
1527                 v = StringUtil.eraseTailBlank(v)
1528                 table.insert(keyval, v)
1529             end
1530             if #keyval > 1 then
1531                 comp_conf:setProperty(keyval[1],keyval[2])
1532                 self._rtcout:RTC_TRACE("RTC property "..keyval[1]..": "..keyval[2])
1533             end
1534         end
1535     end
1536
1537
1538     return true
1539 end
1540
1541 -- EC名、オプションを文字列から取得
1542 -- @param ec_args EC名、オプションの文字列
1543 -- @param ec_id EC名
1544 -- @param ec_conf オプション
1545 -- @return true:取得成功、false:取得失敗
1546 function Manager:procContextArgs(ec_args, ec_id, ec_conf)
1547     return true
1548 end
1549
1550 -- RTCのコンフィギュレーション設定
1551 -- 以下の名前でコンフィグレーションファイルを指定
1552 -- カテゴリ名.型名.config_file
1553 -- カテゴリ名.インスタンス名.config_file
1554 -- @param comp RTC
1555 -- @param prop プロパティ
1556 function Manager:configureComponent(comp, prop)
1557     local category  = comp:getCategory()
1558     local type_name = comp:getTypeName()
1559     local inst_name = comp:getInstanceName()
1560     local type_conf = category.."."..type_name..".config_file"
1561     local name_conf = category.."."..inst_name..".config_file"
1562     local type_prop = Properties.new()
1563     local name_prop = Properties.new()
1564     local config_fname = {}
1565     if self._config:getProperty(name_conf) ~= "" then
1566     end
1567     if self._config:findNode(category.."."..inst_name) then
1568         local temp_ = Properties.new({prop=self._config:getNode(category.."."..inst_name)})
1569         local keys_ = temp_:propertyNames()
1570         if not (#keys_ == 1 and keys_[#keys_] == "config_file") then
1571             name_prop:mergeProperties(self._config:getNode(category.."."..inst_name))
1572             self._rtcout:RTC_INFO("Component name conf exists in rtc.conf. Merged.")
1573             self._rtcout:RTC_INFO(name_prop)
1574             if self._config:findNode("config_file") then
1575                 table.insert(config_fname, self._config:getProperty("config_file"))
1576             end
1577         end
1578
1579     end
1580     if self._config:getProperty(type_conf) ~= "" then
1581     end
1582     if self._config:findNode(category.."."..type_name) then
1583         local temp_ = Properties.new({prop=self._config:getNode(category.."."..type_name)})
1584         local keys_ = temp_:propertyNames()
1585         if not (#keys_ == 1 and keys_[#keys_] == "config_file") then
1586             type_prop:mergeProperties(self._config:getNode(category.."."..type_name))
1587             self._rtcout:RTC_INFO("Component name conf exists in rtc.conf. Merged.")
1588             self._rtcout:RTC_INFO(type_prop)
1589             if self._config:findNode("config_file") then
1590                 table.insert(config_fname, self._config:getProperty("config_file"))
1591             end
1592         end
1593     end
1594     comp:setProperties(prop)
1595     type_prop:mergeProperties(name_prop)
1596     type_prop:setProperty("config_file",StringUtil.flatten(StringUtil.unique_sv(config_fname)))
1597     comp:setProperties(type_prop)
1598     local comp_prop = Properties.new({prop=comp:getProperties()})
1599     local naming_formats = self._config:getProperty("naming.formats")
1600     if comp_prop:findNode("naming.formats") then
1601         naming_formats = comp_prop:getProperty("naming.formats")
1602     end
1603     naming_formats = StringUtil.flatten(StringUtil.unique_sv(StringUtil.split(naming_formats, ",")))
1604     --print(naming_formats)
1605     local naming_names = self:formatString(naming_formats, comp:getProperties())
1606     --print(naming_names)
1607     comp:getProperties():setProperty("naming.formats",naming_formats)
1608     comp:getProperties():setProperty("naming.names",naming_names)
1609     --print(comp:getProperties())
1610 end
1611
1612 -- ファイルからプロパティを追加する
1613 -- @param prop プロパティ
1614 -- @param file_name ファイルパス
1615 -- @return true:追加成功、false:追加失敗
1616 function Manager:mergeProperty(prop, file_name)
1617     return true
1618 end
1619
1620 -- フォーマットに従ってRTC名変換
1621 -- 以下の置き換えを行う
1622 -- %n:インスタンス名
1623 -- %t:型名
1624 -- %m:型名
1625 -- %v:バージョン
1626 -- %V:ベンダ名
1627 -- %c:カテゴリ名
1628 -- %h:ホスト名
1629 -- %M:マネージャ名
1630 -- %p:プロセスID
1631 -- @param naming_format フォーマット
1632 -- @param prop プロパティ
1633 -- @return 変換後文字列
1634 function Manager:formatString(naming_format, prop)
1635     local name_ = naming_format
1636     local str_  = ""
1637     local count = 0
1638     local len_  = #name_
1639     local num = 0
1640     --local ok, ret = xpcall(
1641     -- function()
1642     local flag = true
1643     while(flag) do
1644         num = num + 1
1645         local n = string.sub(name_,num,num)
1646         --print(n)
1647         if n == "" then
1648             break
1649         end
1650         --print(n,name_)
1651         if n == '%' then
1652             count = count + 1
1653             if count % 2 == 0 then
1654                 str_ = str_..n
1655             end
1656         elseif n == '$' then
1657             count = 0
1658             num = num + 1
1659             n = string.sub(name_,num,num)
1660             if n == "" then
1661                 break
1662             end
1663             if n == '{' or n == '(' then
1664                 num = num + 1
1665                 n = string.sub(name_,num,num)
1666                 local env = ""
1667                 local start = num+1
1668                 while(true) do
1669                     if n == '}' or n == ')' then
1670                         break
1671                     elseif n == "" then
1672                         break
1673                     end
1674                     env = env..n
1675                     num = num + 1
1676                     n = string.sub(name_,num,num)
1677                 end
1678                 --envval = os.getenv(env)
1679                 --if envval then
1680                 -- str_ = str_..envval
1681                 --end
1682             end
1683         else
1684             if  count > 0 and count % 2 == 1 then
1685                 count = 0
1686                 if   n == "n" then str_ = str_..prop:getProperty("instance_name")
1687                 elseif n == "t" then str_ = str_..prop:getProperty("type_name")
1688                 elseif n == "m" then str_ = str_..prop:getProperty("type_name")
1689                 elseif n == "v" then str_ = str_..prop:getProperty("version")
1690                 elseif n == "V" then str_ = str_..prop:getProperty("vendor")
1691                 elseif n == "c" then str_ = str_..prop:getProperty("category")
1692                 elseif n == "h" then str_ = str_..self._config:getProperty("os.hostname")
1693                 elseif n == "M" then str_ = str_..self._config:getProperty("manager.name")
1694                 elseif n == "p" then str_ = str_..self._config:getProperty("manager.pid")
1695                 else str_ = str_..n end
1696             else
1697                 count = 0
1698                 str_ = str_..n
1699             end
1700         end
1701     end
1702     return str_
1703     -- end)
1704
1705 end
1706
1707 -- ロガー取得
1708 -- @param name ロガー名
1709 -- @return ロガー
1710 function Manager:getLogbuf(name)
1711     if name == nil then
1712         name = "Manager"
1713     end
1714     if not StringUtil.toBool(self._config:getProperty("logger.enable"), "YES", "NO", true) then
1715         --print(LogStream.new())
1716         return LogStream.new():getLogger(name)
1717     end
1718     if self._rtcout == nil then
1719         self._rtcout = LogStream.new(name)
1720         --print(self._config:getProperty("logger.log_level"))
1721         self._rtcout:setLogLevel(self._config:getProperty("logger.log_level"))
1722         return self._rtcout:getLogger(name)
1723     else
1724         return self._rtcout:getLogger(name)
1725     end
1726 end
1727
1728 -- プロパティ取得
1729 -- @return プロパティ
1730 function Manager:getConfig()
1731     return self._config
1732 end
1733
1734 -- モジュールを直接ロードする
1735 -- @param file_name ファイルパス
1736 function Manager:try_direct_load(file_name)
1737
1738 end
1739
1740 -- ネームサーバーにポートを登録する
1741 -- @param comp RTC
1742 function Manager:publishPorts(comp)
1743
1744 end
1745
1746 -- ネームサーバーからポートを取得して接続する
1747 -- @param comp RTC
1748 function Manager:subscribePorts(comp)
1749
1750 end
1751
1752 -- ネームサーバーからポート一覧を取得
1753 -- @param nsname パス
1754 -- @param kind kind
1755 -- @return ポート一覧
1756 function Manager:getPortsOnNameServers(nsname, kind)
1757     local ret = {}
1758     return ret
1759 end
1760
1761 -- データポートを接続する
1762 -- @param port ポート
1763 -- @param target_ports 接続先のポート一覧
1764 function Manager:connectDataPorts(port, target_ports)
1765
1766 end
1767
1768 -- サービスポートを接続する
1769 -- @param port ポート
1770 -- @param target_ports 接続先のポート一覧
1771 function Manager:connectServicePorts(port, target_ports)
1772
1773 end
1774
1775 -- 起動時にポートを自動接続する関数
1776 -- rtc.confに以下のように記述
1777 -- manager.components.preconnect: ConsoleIn0.out?port=ConsoleOut0.in&dataflow_type=pull
1778 function Manager:initPreConnection()
1779     self._rtcout:RTC_TRACE("Connection pre-creation: "..tostring(self._config:getProperty("manager.components.preconnect")))
1780     local connectors = StringUtil.split(tostring(self._config:getProperty("manager.components.preconnect")), ",")
1781
1782     for k,c in ipairs(connectors) do
1783         c = StringUtil.eraseBothEndsBlank(c)
1784
1785         if c == "" then
1786         else
1787             local port0_str = StringUtil.split(c,"?")[1]
1788             local param = StringUtil.urlparam2map(c)
1789             --print(port0_str)
1790             --for k,v in pairs(param) do
1791             -- print(k,v)
1792             --end
1793
1794             local ports = {}
1795             local configs = {}
1796             for k,p in pairs(param) do
1797                 if k == "port" then
1798                     table.insert(ports,p)
1799                 else
1800                     local tmp = string.gsub(k,"port","")
1801
1802                     local ret, v = StringUtil.stringTo(0, tmp)
1803                     if ret then
1804                         ports.append(v)
1805                     else
1806                         configs[k] = p
1807                     end
1808                 end
1809             end
1810
1811             if #ports == 0 then
1812                 self._rtcout:RTC_ERROR("Invalid format for pre-connection.")
1813                 self._rtcout:RTC_ERROR("Format must be Comp0.port0?port=Comp1.port1")
1814             else
1815
1816                 if configs["dataflow_type"] == nil then
1817                     configs["dataflow_type"] = "push"
1818                 end
1819                 if configs["interface_type"] == nil then
1820                     configs["interface_type"] = "data_service"
1821                 end
1822                 local tmp = StringUtil.split(port0_str,"%.")
1823                 tmp[#tmp] = nil
1824
1825                 local comp0_name = StringUtil.flatten(tmp,"%.")
1826
1827                 local port0_name = port0_str
1828                 local comp0_ref = nil
1829
1830                 if string.find(comp0_name, "://") == nil then
1831                     --print(comp0_name)
1832                     local comp0 = self:getComponent(comp0_name)
1833                     --print(comp0)
1834                     if comp0 == nil then
1835                         self._rtcout:RTC_ERROR(comp0_name.." not found.")
1836                     else
1837                         comp0_ref = comp0:getObjRef()
1838                     end
1839                 else
1840                     local rtcs = self._namingManager:string_to_component(comp0_name)
1841
1842                     if #rtcs == 0 then
1843                         self._rtcout:RTC_ERROR(comp0_name.." not found.")
1844                     else
1845                         comp0_ref = rtcs[1]
1846                         port0_name = StringUtil.split(port0_str, "/")
1847                         port0_name = port0_name[#port0_name]
1848                     end
1849                 end
1850
1851                 local port0_var = CORBA_RTCUtil.get_port_by_name(comp0_ref, port0_name)
1852
1853
1854                 if port0_var == oil.corba.idl.null then
1855                     self._rtcout:RTC_DEBUG("port "..port0_str.." found: ")
1856                 else
1857                     for k,port_str in ipairs(ports) do
1858
1859                         local tmp = StringUtil.split(port_str, "%.")
1860                         tmp[#tmp] = nil
1861                         local comp_name = StringUtil.flatten(tmp,"%.")
1862                         local port_name = port_str
1863
1864                         local comp_ref = nil
1865
1866                         if string.find(comp_name, "://") == nil then
1867                             --print(comp_name)
1868                             local comp = self:getComponent(comp_name)
1869                             if comp == nil then
1870                                 self._rtcout:RTC_ERROR(comp_name.." not found.")
1871                             else
1872                                 comp_ref = comp:getObjRef()
1873                             end
1874                         else
1875                             local rtcs = self._namingManager:string_to_component(comp_name)
1876
1877                             if #rtcs == 0 then
1878                                 self._rtcout:RTC_ERROR(comp_name.." not found.")
1879                             else
1880                                 comp_ref = rtcs[1]
1881                                 port_name = StringUtil.split(port_str, "/")
1882                                 port_name = port_name[#port_name]
1883                             end
1884                         end
1885
1886                         if comp_ref ~= nil then
1887                             port_var = CORBA_RTCUtil.get_port_by_name(comp_ref, port_name)
1888
1889
1890                             if port_var == oil.corba.idl.null then
1891                                 self._rtcout:RTC_DEBUG("port "..port_str.." found: ")
1892                             else
1893                                 local prop = Properties.new()
1894
1895                                 for k,v in pairs(configs) do
1896                                     k = StringUtil.eraseBothEndsBlank(k)
1897                                     v = StringUtil.eraseBothEndsBlank(v)
1898                                     prop:setProperty("dataport."..k,v)
1899                                 end
1900                                 --print(c)
1901                                 --print(prop)
1902                                 --print(port0_var)
1903                                 --print(port_var)
1904
1905                                 if self._ReturnCode_t.RTC_OK ~= CORBA_RTCUtil.connect(c, prop, port0_var, port_var) then
1906                                     self._rtcout.RTC_ERROR("Connection error: "..c)
1907                                 end
1908                             end
1909                         end
1910                     end
1911                 end
1912             end
1913         end
1914     end
1915 end
1916
1917 -- 起動時にRTCを自動アクティブ化する関数
1918 -- rtc.confに以下のように記述
1919 -- manager.components.preactivation: ConsoleIn0, ConsoleOut0
1920 function Manager:initPreActivation()
1921     self._rtcout:RTC_TRACE("Components pre-activation: "..tostring(self._config:getProperty("manager.components.preactivation")))
1922     local comps = StringUtil.split(tostring(self._config:getProperty("manager.components.preactivation")), ",")
1923     for k,c in pairs(comps) do
1924         local c = StringUtil.eraseBothEndsBlank(c)
1925
1926         if c ~= "" then
1927             local comp_ref = nil
1928             if string.find(c, "://") == nil then
1929                 local comp = self:getComponent(c)
1930                 if comp == nil then
1931                     self._rtcout:RTC_ERROR(c.." not found.")
1932                 else
1933                     comp_ref = comp:getObjRef()
1934                 end
1935             else
1936                 local rtcs = self._namingManager:string_to_component(c)
1937                 if #rtcs == 0 then
1938                     self._rtcout:RTC_ERROR(c.." not found.")
1939                 else
1940                     comp_ref = rtcs[1]
1941                 end
1942             end
1943             if comp_ref ~= nil then
1944                 local ret = CORBA_RTCUtil.activate(comp_ref)
1945                 if ret ~= self._ReturnCode_t.RTC_OK then
1946                     self._rtcout:RTC_ERROR(c.." activation failed.")
1947                 else
1948                     self._rtcout:RTC_INFO(c.." activated.")
1949                 end
1950             end
1951         end
1952     end
1953 end
1954
1955 -- 起動時にRTCを自動生成する関数
1956 -- rtc.confに以下のように記述
1957 -- manager.components.precreate: ConsoleIn, ConsoleOut
1958 function Manager:initPreCreation()
1959     local comps = StringUtil.strip(StringUtil.split(self._config:getProperty("manager.components.precreate"), ","))
1960     for k,comp in ipairs(comps) do
1961         if comp == nil or comp == "" then
1962         else
1963             self:createComponent(comp)
1964         end
1965     end
1966 end
1967
1968 -- マネージャサーバント取得
1969 -- @return マネージャサーバント
1970 function Manager:getManagerServant()
1971     self._rtcout:RTC_TRACE("Manager.getManagerServant()")
1972     return self._mgrservant
1973 end
1974
1975 -- RTC一覧取得
1976 -- @return RTC一覧
1977 function Manager:getComponents()
1978     self._rtcout:RTC_TRACE("Manager.getComponents()")
1979     return self._compManager:getObjects()
1980 end
1981
1982 -- ネーミングマネージャを取得
1983 -- @return ネーミングマネージャ
1984 function Manager:getNaming()
1985     self._rtcout:RTC_TRACE("Manager.getNaming()")
1986     return self._namingManager
1987 end
1988
1989 -- モジュールのロード
1990 -- @param fname ファイルパス
1991 -- @param initfunc ファクトリ登録関数名
1992 -- @return リターンコード
1993 function Manager:load(fname, initfunc)
1994     self._rtcout:RTC_TRACE("Manager.load(fname = "..fname..", initfunc = "..initfunc..")")
1995     fname = string.gsub(fname, "\\", "./")
1996     self._listeners.module_:preLoad(fname, initfunc)
1997     local success, exception = oil.pcall(
1998         function()
1999             if initfunc == "" then
2000                 initfunc = "Init"
2001             end
2002             --print(fname, initfunc)
2003             local path = self._module:load(fname, initfunc)
2004             self._rtcout:RTC_DEBUG("module path: "..path)
2005             self._listeners.module_:postLoad(path, initfunc)
2006     end)
2007     if not success then
2008         --print(exception.type)
2009         --print(exception.name)
2010         
2011         if exception.type == "NotAllowedOperation" then
2012             self._rtcout:RTC_ERROR("Operation not allowed: "..exception.reason)
2013             return self._ReturnCode_t.PRECONDITION_NOT_MET
2014         elseif exception.type == "NotFound" then
2015             self._rtcout:RTC_ERROR("Not found: "..fname)
2016             return self._ReturnCode_t.RTC_ERROR
2017         elseif exception.type == "FileNotFound" then
2018             self._rtcout:RTC_ERROR("Not found: "..fname)
2019             return self._ReturnCode_t.RTC_ERROR
2020         elseif exception.type == "InvalidArguments" then
2021             self._rtcout:RTC_ERROR("Invalid argument: "..exception.reason)
2022             return self._ReturnCode_t.BAD_PARAMETER
2023         else
2024             self._rtcout:RTC_ERROR("Unknown error.")
2025             return self._ReturnCode_t.RTC_ERROR
2026         end
2027     end
2028     return self._ReturnCode_t.RTC_OK
2029     --return self._ReturnCode_t.PRECONDITION_NOT_MET
2030 end
2031
2032 -- モジュールのアンロード
2033 -- @param fname ファイルパス
2034 function Manager:unload(fname)
2035     self._rtcout:RTC_TRACE("Manager.unload()")
2036     self._listeners.module_:preUnload(fname)
2037     self._module:unload(fname)
2038     self._listeners.module_:postUnload(fname)
2039 end
2040
2041
2042
2043
2044
2045
2046
2047
2048 -- 未使用
2049 function Manager:setinitThread(thread)
2050     self._initThread = thread
2051 end
2052
2053
2054
2055 local function alignment(self, size)
2056     local extra = (self.cursor-2)%size
2057     if extra > 0 then return size-extra end
2058     return 0
2059 end
2060
2061
2062 local align = function(self, size)
2063     local shift = alignment(self, size)
2064     --print(self.cursor, shift, size)
2065     if shift > 0 then self:jump(shift) end
2066 end
2067
2068 -- CDR符号化
2069 -- @param data 変換前のデータ
2070 -- @param dataType データ型
2071 -- @return CDRバイナリデータ
2072 function Manager:cdrMarshal(data, dataType)
2073
2074     local encoder = self._orb:newencoder()
2075     --encoder.emptychar = ""
2076     --encoder.align = function(...)return 0 end
2077     encoder.align = align
2078     --encoder.cursor = encoder.cursor-1
2079     encoder:put(data, self._orb.types:lookup(dataType))
2080
2081     local cdr = encoder:getdata()
2082     --for i=1,#cdr do
2083     -- print(i,string.byte(string.sub(cdr,i,i)))
2084     --end
2085     if #cdr == 0 then
2086     else
2087         cdr = string.sub(cdr,2)
2088     --elseif #cdr == 2 then
2089     -- cdr = string.sub(cdr,2)
2090     --elseif #cdr == 4 then
2091     -- cdr = string.sub(cdr,3)
2092     --else
2093     -- cdr = string.sub(cdr,5)
2094     end
2095     --for i=1,#cdr do
2096     -- print(i,string.byte(string.sub(cdr,i,i)))
2097     --end
2098     return cdr
2099 end
2100
2101 -- CDR復号化
2102 -- @param cdr CDRバイナリデータ
2103 -- @param dataType データ型
2104 -- @return 変換後のデータ
2105 function Manager:cdrUnmarshal(cdr, dataType)
2106     --print(cdr, dataType)
2107     --if #cdr == 0 then
2108     --elseif #cdr == 1 then
2109     -- cdr = string.char(1)..cdr
2110     --elseif #cdr == 2 then
2111     -- cdr = string.char(1)..string.char(255)..cdr
2112     --else
2113     -- cdr = string.char(1)..string.char(255)..string.char(255)..string.char(255)..cdr
2114     --end
2115     --local Codec = require "oil.corba.giop.Codec"
2116     --Codec.Encoder.emptychar = ""
2117     --print(#cdr)
2118
2119
2120     cdr = string.char(1)..cdr
2121     local decoder = self._orb:newdecoder(cdr)
2122     --decoder.cursor = decoder.cursor-1
2123     decoder.align = align
2124     --decoder.align = Codec.Encoder.align
2125     --decoder.align = function(...)return 0 end
2126     local _data = decoder:get(self._orb.types:lookup(dataType))
2127     return _data
2128 end
2129
2130 -- スタンドアロンコンポーネントかの判定
2131 -- @return true:スタンドアロンコンポーネント、false:rtcdでの実行
2132 Manager.is_main = function()
2133     return (debug.getinfo(4 + (offset or 0)) == nil)
2134 end
2135
2136
2137 local terminate_Task = {}
2138 -- マネージャ終了コルーチンの初期化
2139 -- @param mgr マネージャ
2140 -- @param sleep_time 終了までの待機時間
2141 -- マネージャ終了コルーチン
2142 terminate_Task.new = function(mgr, sleep_time)
2143     local obj = {}
2144     obj._mgr = mgr
2145     obj._sleep_time = sleep_time
2146
2147     function obj:svc()
2148         --oil.tasks:suspend(self._sleep_time)
2149         Timer.sleep(self._sleep_time)
2150         self._mgr:shutdown()
2151     end
2152     return obj
2153 end
2154
2155 -- マネージャ終了コルーチンの生成
2156 function Manager:createShutdownThread(sleep_time)
2157     if not self.shutdown_start then
2158         if sleep_time == nil then
2159             sleep_time = 0
2160         end
2161         if not self.no_block then
2162             Task.start(terminate_Task.new(self, sleep_time))
2163         else
2164             oil.main(function()
2165                 oil.newthread(self._orb.run, self._orb)
2166                 Task.start(terminate_Task.new(self, sleep_time))
2167             end)
2168         end
2169     end
2170 end
2171
2172
2173
2174 return Manager
2175
2176

File lua\openrtm\ManagerActionListener.lua

Full coverage

File lua\openrtm\ManagerConfig.lua

1 ---------------------------------
2 --! @file ManagerConfig.lua
3 --! @brief マネージャのコンフィギュレーション管理クラス定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local ManagerConfig= {}
11 --_G["openrtm.ManagerConfig"] = ManagerConfig
12
13 local Properties = require "openrtm.Properties"
14 local default_config = require "openrtm.DefaultConfiguration"
15 local StringUtil = require "openrtm.StringUtil"
16
17
18 local config_file_path = {"./rtc.conf"}
19
20 -- マネージャのコンフィギュレーション管理オブジェクト初期化
21 -- @param argv コマンドライン引数
22 -- "-a":マネージャサーバント無効
23 -- "-f":設定ファイル指定
24 -- "-l":ロードするモジュール指定
25 -- "-o":追加のオプション指定
26 -- "-a":アドレス、ポート番号指定
27 -- "-d":マスターマネージャに設定
28 -- @return マネージャのコンフィギュレーション管理オブジェクト
29 ManagerConfig.new = function(argv)
30     local obj = {}
31     obj._configFile = ""
32     obj._argprop = Properties.new()
33     obj._isMaster = false
34
35     -- コマンドライン引数により初期化
36     -- @param _argv コマンドライン引数
37     function obj:init(_argv)
38         self:parseArgs(_argv)
39     end
40     -- 指定プロパティを設定
41     -- @param prop プロパティ
42     -- @param プロパティ
43     function obj:configure(prop)
44         prop:setDefaults(default_config)
45         if self:findConfigFile() then
46             local fd = io.open(self._configFile, "r")
47             --print(fs)
48             prop:load(fd)
49             --print(prop)
50             --print(prop)
51             fd:close()
52         end
53
54         self:setSystemInformation(prop)
55         if self._isMaster then
56             prop:setProperty("manager.is_master","YES")
57         end
58
59         prop:mergeProperties(self._argprop)
60         prop:setProperty("config_file", self._configFile)
61         return prop
62     end
63     -- コマンドライン引数からオプション一覧取得して設定
64     -- @param _argv コマンドライン引数
65     function obj:parseArgs(_argv)
66         local opts = StringUtil.getopt(_argv, "adlf:o:p:")
67         --print(_argv)
68
69         for i, opt in ipairs(opts) do
70             --print(opt)
71             --print(opt.id, opt.optarg)
72             if opt.id == "a" then
73                 self._argprop:setProperty("manager.corba_servant", "NO")
74             elseif opt.id == "f" then
75                 if opt.optarg ~= nil then
76                     self._configFile = opt.optarg
77                 end
78             elseif opt.id == "l" then
79                 if opt.optarg ~= nil then
80                     self._configFile = opt.optarg
81                 end
82             elseif opt.id == "o" then
83                 if opt.optarg ~= nil then
84                     local pos = string.find(opt.optarg, ":")
85                     if pos ~= nil then
86                         local idx = string.sub(opt.optarg,1,pos-1)
87                         local value = string.sub(opt.optarg,pos+1)
88                         idx = StringUtil.unescape(idx)
89                         idx = StringUtil.eraseHeadBlank(idx)
90                         idx = StringUtil.eraseTailBlank(idx)
91                         
92                         value = StringUtil.unescape(value)
93                         value = StringUtil.eraseHeadBlank(value)
94                         value = StringUtil.eraseTailBlank(value)
95                         --print(idx, value)
96                         self._argprop:setProperty(idx, value)
97                     end
98                 end
99             elseif opt.id == "p" then
100                 if opt.optarg ~= nil then
101                     local arg_ = ":"..tostring(opt.optarg)
102                     self._argprop:setProperty("corba.endpoints", arg_)
103                 end
104             elseif opt.id == "d" then
105                 self._isMaster = true
106             end
107         end
108
109     end
110     -- 設定ファイルの存在確認、設定
111     -- @retuen true:存在しない、false:存在する
112     function obj:findConfigFile()
113         if self._configFile ~= "" then
114             if not self:fileExist(self._configFile) then
115                 return false
116             end
117             return true
118         end
119         for i,filename in ipairs(config_file_path) do
120             if self:fileExist(filename) then
121                 self._configFile = filename
122                 return true
123             end
124         end
125         return false
126     end
127     -- システム情報を設定する
128     -- @param prop プロパティ
129     function obj:setSystemInformation(prop)
130     end
131     -- ファイルの存在確認
132     -- @retuen true:存在しない、false:存在する
133     function obj:fileExist(filename)
134         local fd = io.open(filename, "r")
135
136         if fd == nil then
137             return false
138         else
139             fd:close()
140             return true
141         end
142     end
143     if argv ~= nil then
144         obj:init(argv)
145     end
146     return obj
147 end
148
149
150 return ManagerConfig

File lua\openrtm\ManagerServant.lua

1 ---------------------------------
2 --! @file ManagerServant.lua
3 --! @brief マネージャサーバント定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local ManagerServant= {}
11 --_G["openrtm.ManagerServant"] = ManagerServant
12
13 local StringUtil = require "openrtm.StringUtil"
14 local NVUtil = require "openrtm.NVUtil"
15 local oil = require "oil"
16 local RTCUtil = require "openrtm.RTCUtil"
17 local Properties = require "openrtm.Properties"
18 local CORBA_SeqUtil = require "openrtm.CORBA_SeqUtil"
19 local Timer = require "openrtm.Timer"
20
21
22
23 ManagerServant.CompParam = {}
24 ManagerServant.CompParam.prof_list = {
25                 "RTC",
26                 "vendor",
27                 "category",
28                 "implementation_id",
29                 "language",
30                 "version"
31                 }
32
33
34
35 -- マネージャのCORBAオブジェクトの一致を判定する関数オブジェクト初期化
36 -- @param mgr マネージャ
37 -- @return 関数オブジェクト
38 local is_equiv = function(mgr)
39     local obj = {}
40     obj._mgr = mgr
41     -- マネージャのCORBAオブジェクトの一致を判定する関数
42     -- @param self 自身のオブジェクト
43     -- @param mgr 比較対象のマネージャ
44     -- @return true:一致
45     local call_func = function(self, mgr)
46         return NVUtil._is_equivalent(self._mgr, mgr, self._mgr.getObjRef, mgr.getObjRef)
47     end
48     setmetatable(obj, {__call=call_func})
49     return obj
50 end
51
52
53
54
55 -- RTCのパラメータ格納オブジェクト初期化
56 -- @param module_name RTC名、オプション
57 -- @return RTCのパラメータ格納オブジェクト
58 ManagerServant.CompParam.new = function(module_name)
59     local obj = {}
60     module_name = StringUtil.split(module_name, "?")[1]
61     local param_list = StringUtil.split(module_name, ":")
62     if #param_list < #ManagerServant.CompParam.prof_list then
63         obj._type = "RTC"
64         obj._vendor = ""
65         obj._category = ""
66         obj._impl_id = module_name
67         obj._language = "Lua"
68         obj._version = ""
69     else
70         obj._type = param_list[1]
71         obj._vendor = param_list[2]
72         obj._category = param_list[3]
73         obj._impl_id = param_list[4]
74         if param_list[5] ~= "" then
75             obj._language = param_list[5]
76         else
77             obj._language = "Lua"
78         end
79         obj._version = param_list[6]
80     end
81     function obj:vendor()
82         return self._vendor
83     end
84     function obj:category()
85         return self._category
86     end
87     function obj:impl_id()
88         return self._impl_id
89     end
90     function obj:language()
91         return self._language
92     end
93     function obj:version()
94         return self._version
95     end
96
97     return obj
98 end
99
100 -- マネージャサーバント初期化
101 -- @return マネージャサーバント
102 ManagerServant.new = function()
103     local obj = {}
104
105     -- オブジェクトリファレンス初期化
106     -- INSマネージャへの登録
107     -- @return true:登録成功、false:登録失敗
108     function obj:createINSManager()
109         local success, exception = oil.pcall(
110             function()
111                 --print(self._mgr:getConfig())
112                 local id = self._mgr:getConfig():getProperty("manager.name")
113                 self._svr = self._mgr:getORB():newservant(self, id, "IDL:RTM/Manager:1.0")
114                 self._objref = RTCUtil.getReference(self._mgr:getORB(), self._svr, "IDL:RTM/Manager:1.0")
115                 --print(str)
116                 --print(self._objref:_non_existent())
117             end)
118         if not success then
119             self._rtcout:RTC_DEBUG(exception)
120             return false
121         end
122         return true
123     end
124     
125     function obj:getObjRef()
126         return self._objref
127     end
128
129     function obj:exit()
130         --print(#self._masters)
131         for k,master in ipairs(self._masters) do
132             master:remove_slave_manager(self._objref)
133         end
134         self._masters = {}
135         for k,slave in ipairs(self._slaves) do
136             slave:remove_master_manager(self._objref)
137         end
138         self._slaves = {}
139
140         self._mgr:getORB():deactivate(self._svr)
141
142     end
143
144     -- アドレスからマネージャを検索
145     -- @param host_port アドレス、ポート番号
146     -- @return マネージャ
147     function obj:findManager(host_port)
148         self._rtcout:RTC_TRACE("findManager(host_port = "..host_port..")")
149         local mgr = oil.corba.idl.null
150         local success, exception = oil.pcall(
151             function()
152                 local config = self._mgr:getConfig()
153                 local mgrloc = "corbaloc:iiop:"
154                 mgrloc = mgrloc..host_port
155                 mgrloc = mgrloc.."/"..config:getProperty("manager.name")
156
157                 self._rtcout:RTC_DEBUG("corbaloc: "..mgrloc)
158
159
160                 mgr = RTCUtil.newproxy(self._mgr:getORB(), mgrloc,"IDL:RTM/Manager:1.0")
161                 if NVUtil._non_existent(mgr) then
162                     mgr = oil.corba.idl.null
163                 end
164                 --print(mgr)
165
166         end)
167         if not success then
168             mgr = oil.corba.idl.null
169             self._rtcout:RTC_DEBUG(exception)
170         end
171
172         return mgr
173     end
174
175     -- 指定名のRTCを取得
176     -- @param name RTC名
177     -- カテゴリ名とRTCインスタンス名を指定
178     -- Category/ConsoleIn0
179     -- カテゴリ名は省略可能
180     -- @return 一致したRTC一覧
181     function obj:get_components_by_name(name)
182         self._rtcout:RTC_TRACE("get_components_by_name()")
183         local rtcs = self._mgr:getComponents()
184         local crtcs = {}
185         local name = StringUtil.eraseHeadBlank(name)
186
187         local rtc_name = StringUtil.split(name, "/")
188         for k,rtc in ipairs(rtcs) do
189             if #rtc_name == 1 then
190                 --print(rtc:getInstanceName(), rtc_name[1])
191                 if rtc:getInstanceName() == rtc_name[1] then
192                     table.insert(crtcs, rtc:getObjRef())
193                 end
194
195             else
196                 if rtc_name[1] == "*" then
197                     if rtc:getInstanceName() == rtc_name[2] then
198                         table.insert(crtcs, rtc:getObjRef())
199                     end
200                 else
201                     if rtc:getCategory() == rtc_name[1] then
202                         if rtc:getInstanceName() == rtc_name[2] then
203                             table.insert(crtcs, rtc:getObjRef())
204                         end
205                     end
206                 end
207             end
208         end
209         return crtcs
210     end
211
212     -- マスターマネージャを追加する
213     -- @param mgr マネージャ
214     -- @return リターンコード
215     function obj:add_master_manager(mgr)
216         self._rtcout:RTC_TRACE("add_master_manager(), "..#self._masters.." masters")
217         local index = CORBA_SeqUtil.find(self._masters, is_equiv(mgr))
218         --print(index)
219         if not (index < 1) then
220             self._rtcout:RTC_ERROR("Already exists.")
221             return self._ReturnCode_t.BAD_PARAMETER
222         end
223
224         table.insert(self._masters, mgr)
225         self._rtcout.RTC_TRACE("add_master_manager() done, "..#self._masters.." masters")
226         return self._ReturnCode_t.RTC_OK
227     end
228     -- スレーブマネージャを追加する
229     -- @param mgr マネージャ
230     -- @return リターンコード
231     function obj:add_slave_manager(mgr)
232         self._rtcout:RTC_TRACE("add_slave_manager(), "..#self._slaves.." slaves")
233         local index = CORBA_SeqUtil.find(self._slaves, is_equiv(mgr))
234
235         if not (index < 1) then
236             self._rtcout:RTC_ERROR("Already exists.")
237             return self._ReturnCode_t.BAD_PARAMETER
238         end
239
240         table.insert(self._slaves, mgr)
241         self._rtcout.RTC_TRACE("add_slave_manager() done, "..#self._slaves.." slaves")
242         return self._ReturnCode_t.RTC_OK
243     end
244
245     -- オブジェクトリファレンス取得
246     -- @return オブジェクトリファレンス
247     function obj:getObjRef()
248         return self._objref
249     end
250
251     -- モジュールのロード
252     -- @param pathname ファイルパス
253     -- @param initfunc ファクトリ登録関数
254     -- @return リターンコード
255     function obj:load_module(pathname, initfunc)
256         self._rtcout:RTC_TRACE("ManagerServant::load_module("..pathname..", "..initfunc..")")
257         self._mgr:load(pathname, initfunc)
258         return self._ReturnCode_t.RTC_OK
259     end
260
261     -- モジュールのアンロード
262     -- @param pathname ファイルパス
263     -- @return リターンコード
264     function obj:unload_module(pathname)
265         self._rtcout:RTC_TRACE("ManagerServant::unload_module("..pathname..")")
266         self._mgr:unload(pathname)
267         return self._ReturnCode_t.RTC_OK
268     end
269
270     -- ロード可能モジュール一覧取得
271     -- @return ロード可能モジュール一覧
272     function obj:get_loadable_modules()
273         return {}
274     end
275
276     -- ロード済みモジュール一覧取得
277     -- @return ロード可能モジュール一覧
278     function obj:get_loaded_modules()
279         self._rtcout:RTC_TRACE("get_loaded_modules()")
280         local prof = self._mgr:getLoadedModules()
281         local cprof = {}
282         for k,p in ipairs(prof) do
283             local module_profile = {properties={}}
284             NVUtil.copyFromProperties(module_profile.properties, p)
285             table.insert(cprof, p)
286                         
287         end
288
289
290         if self._isMaster then
291             for k,slave in ipairs(self._slaves) do
292                 local success, exception = oil.pcall(
293                     function()
294                         local profs = slave:get_loaded_modules()
295                         CORBA_SeqUtil.push_back_list(cprof, profs)
296                     end
297                 )
298                 if not success then
299                     self._rtcout:RTC_ERROR("Unknown exception cought.")
300                       self._rtcout:RTC_DEBUG(exception)
301                       self._slaves.remove(slave)
302                 end
303             end
304         end
305
306         return cprof
307     end
308
309     -- ファクトリプロファイル一覧取得
310     -- @return ファクトリプロファイル一覧
311     function obj:get_factory_profiles()
312         self._rtcout:RTC_TRACE("get_factory_profiles()")
313         local prof = self._mgr:getFactoryProfiles()
314         local cprof = {}
315         for k,p in ipairs(prof) do
316             local module_profile = {properties={}}
317             NVUtil.copyFromProperties(module_profile.properties, p)
318             table.insert(cprof, p)
319                         
320         end
321
322
323         if self._isMaster then
324             for k,slave in ipairs(self._slaves) do
325                 local success, exception = oil.pcall(
326                     function()
327                         local profs = slave:get_factory_profiles()
328                         CORBA_SeqUtil.push_back_list(cprof, profs)
329                     end
330                 )
331                 if not success then
332                     self._rtcout:RTC_ERROR("Unknown exception cought.")
333                       self._rtcout:RTC_DEBUG(exception)
334                       self._slaves.remove(slave)
335                 end
336             end
337         end
338
339         return cprof
340     end
341
342     function obj:findManagerByName(manager_name)
343         return oil.corba.idl.null
344     end
345
346
347
348
349     function obj:getParameterByModulename(param_name, module_name)
350         local arg = module_name[1]
351         local pos0, c = string.find(arg, "&"..param_name.."=")
352         local pos1, c = string.find(arg, "?"..param_name.."=")
353
354         if pos0 == nil and pos1 == nil then
355             return ""
356         end
357         local pos = 0
358         if pos1 == nil then
359             pos = pos0
360         else
361             pos = pos1
362         end
363
364
365         local paramstr = ""
366         local endpos, c = string.find(string.sub(arg,pos+1), '&')
367         if endpos == nil then
368             endpos = string.find(string.sub(arg,pos+1), '?')
369             if endpos == nil then
370                 paramstr = string.sub(arg, pos + 1)
371             else
372                 paramstr = string.sub(arg, pos + 1, pos - 1 + endpos)
373             end
374         else
375             paramstr = string.sub(arg, pos + 1, pos - 1 + endpos)
376             --print(arg,paramstr,endpos)
377         end
378         self._rtcout:RTC_VERBOSE(param_name.." arg: "..paramstr)
379
380         local eqpos, c = string.find(paramstr, "=")
381         if eqpos == nil then
382             eqpos = 0
383         end
384
385         paramstr = string.sub(paramstr, eqpos + 1)
386
387         self._rtcout:RTC_DEBUG(param_name.." is "..paramstr)
388         if endpos == nil then
389             arg = string.sub(arg, 1, pos-1)
390         else
391             arg = string.sub(arg,1,pos-1)..string.sub(arg, endpos)
392         end
393
394         module_name[1] = arg
395
396         return paramstr
397     end
398
399     function obj:createComponentByManagerName(module_name)
400         local arg = module_name
401         local tmp = {arg}
402         local mgrstr = self:getParameterByModulename("manager_name",tmp)
403         local arg = tmp[1]
404         if mgrstr == "" then
405             return oil.corba.idl.null
406         end
407
408         local mgrobj = oil.corba.idl.null
409         if mgrstr ~= "manager_%p" then
410             mgrobj = self:findManagerByName(mgrstr)
411         end
412
413
414         local comp_param = ManagerServant.CompParam.new(arg)
415         if mgrobj == oil.corba.idl.null then
416             local config = self._mgr:getConfig()
417             local rtcd_cmd = config:getProperty("manager.modules."..comp_param:language()..".manager_cmd")
418             if rtcd_cmd == "" then
419                 rtcd_cmd = "rtcd_lua"
420             end
421             local load_path = config:getProperty("manager.modules.load_path")
422             local load_path_language = config:getProperty("manager.modules."..comp_param:language()..".load_path")
423             load_path = load_path..","..load_path_language
424             local cmd = rtcd_cmd
425             load_path = string.gsub(load_path, "\\","\\\\")
426
427             cmd = cmd.." -o ".."manager.is_master:NO"
428             cmd = cmd.." -o ".."manager.corba_servant:YES"
429             cmd = cmd.." -o ".."corba.master_manager:"..config:getProperty("corba.master_manager")
430             cmd = cmd.." -o ".."manager.name:"..config:getProperty("manager.name")
431             cmd = cmd.." -o ".."manager.instance_name:"..mgrstr
432             cmd = cmd.." -o ".."\"manager.modules.load_path:"..load_path.."\""
433             cmd = cmd.." -o ".."manager.supported_languages:"..comp_param:language()
434             cmd = cmd.." -o ".."manager.shutdown_auto:NO"
435
436             self._rtcout:RTC_DEBUG("Invoking command: "..cmd..".")
437
438             local slaves_names = {}
439             local regex = 'manager_%d.*'
440             if mgrstr == "manager_%p" then
441                 for k, slave in pairs(self._slaves) do
442                     local success, exception = oil.pcall(
443                         function()
444                             local prof = slave:get_configuration()
445                             local prop = Properties.new()
446                             NVUtil.copyToProperties(prop, prof)
447                             local name = prop:getProperty("manager.instance_name")
448                             if string.match(name, regex) ~= nil then
449                                 table.insert(slaves_names, name)
450                             end
451                     end)
452                     if not success then
453                         self._rtcout:RTC_ERROR("Unknown exception cought.")
454                         self._rtcout:RTC_DEBUG(exception)
455                         self._slaves:remove(slave)
456                     end
457                 end
458             end
459
460             local ret = os.execute(cmd)
461
462             --oil.tasks:suspend(0.01)
463             Timer.sleep(0.01)
464             local count = 0
465             local t0_ = os.clock()
466             while mgrobj == oil.corba.idl.null do
467                 if mgrstr == "manager_%p" then
468                     mgrobj = self:findManager(mgrstr)
469                     for k, slave in pairs(self._slaves) do
470                         local success, exception = oil.pcall(
471                             function()
472                                 local prof = slave.get_configuration()
473                                 local prop = OpenRTM_aist.Properties()
474                                 NVUtil.copyToProperties(prop, prof)
475                                 local name = prop.getProperty("manager.instance_name")
476
477                                 if string.match(name, regex) ~= nil and not StringUtil.includes(slaves_names, name) then
478                                     mgrobj = slave
479                                 end
480                         end)
481                         if not success then
482                             self._rtcout:RTC_ERROR("Unknown exception cought.")
483                             self._rtcout:RTC_DEBUG(exception)
484                             self._slaves:remove(slave)
485                         end
486                     end
487                 else
488                     mgrobj = self:findManagerByName(mgrstr)
489                 end
490
491                 count = count+1
492                 if count > 1000 then
493                     break
494                 end
495                 local t1_ = os.clock()
496                 if (t1_ - t0_) > 10.0 and count > 10 then
497                     break
498                 end
499                 --oil.tasks:suspend(0.01)
500                 Timer.sleep(0.01)
501
502             end
503
504         end
505         if mgrobj == oil.corba.idl.null then
506             self._rtcout:RTC_WARN("Manager cannot be found.")
507             return oil.corba.idl.null
508         end
509         self._rtcout:RTC_DEBUG("Creating component on "..mgrstr)
510         self._rtcout:RTC_DEBUG("arg: "..arg)
511         local rtobj = oil.corba.idl.null
512         local success, exception = oil.pcall(
513             function()
514                 rtobj = mgrobj.create_component(arg)
515                 self._rtcout.RTC_DEBUG("Component created "..arg)
516             end)
517         if not success then
518             self._rtcout.RTC_DEBUG("Exception was caught while creating component.")
519             self._rtcout.RTC_ERROR(exception)
520             return oil.corba.idl.null
521         end
522         return rtobj
523     end
524
525     function obj:createComponentByAddress(module_name)
526         local arg = module_name
527         local tmp = {arg}
528         local mgrstr = self:getParameterByModulename("manager_address",tmp)
529         local arg = tmp[1]
530         if mgrstr == "" then
531             return oil.corba.idl.null
532         end
533
534         local mgrvstr = StringUtil.split(mgrstr, ":")
535         if #mgrvstr ~= 2 then
536             self._rtcout:RTC_WARN("Invalid manager address: "..mgrstr)
537             return oil.corba.idl.null
538         end
539         local mgrobj = self:findManager(mgrstr)
540         local comp_param = ManagerServant.CompParam.new(arg)
541         if mgrobj == oil.corba.idl.null then
542             local config = self._mgr:getConfig()
543             local rtcd_cmd = config:getProperty("manager.modules."..comp_param:language()..".manager_cmd")
544             if rtcd_cmd == "" then
545                 rtcd_cmd = "rtcd_lua"
546             end
547             local load_path = config:getProperty("manager.modules.load_path")
548             local load_path_language = config:getProperty("manager.modules."..comp_param:language()..".load_path")
549             load_path = load_path..","..load_path_language
550             local cmd = rtcd_cmd
551             load_path = string.gsub(load_path, "\\","\\\\")
552             cmd = cmd.." -o corba.master_manager:"
553             cmd = cmd..mgrstr
554             cmd = cmd.." -o \"manager.modules.load_path:"
555             cmd = cmd..load_path + "\""
556             cmd = cmd.." -d "
557
558             self._rtcout:RTC_DEBUG("Invoking command: "..cmd..".")
559             local ret = os.execute(cmd)
560             --oil.tasks:suspend(0.01)
561             Timer.sleep(0.01)
562             local count = 0
563             local t0_ = os.clock()
564             while mgrobj == oil.corba.idl.null do
565                 mgrobj = self:findManager(mgrstr)
566                 count = count+1
567                 if count > 1000 then
568                     break
569                 end
570                 local t1_ = os.clock()
571                 if (t1_ - t0_) > 10.0 and count > 10 then
572                     break
573                 end
574                 --oil.tasks:suspend(0.01)
575                 Timer.sleep(0.01)
576
577             end
578
579         end
580         if mgrobj == oil.corba.idl.null then
581             self._rtcout:RTC_WARN("Manager cannot be found.")
582             return oil.corba.idl.null
583         end
584         self._rtcout:RTC_DEBUG("Creating component on "..mgrstr)
585         self._rtcout:RTC_DEBUG("arg: "..arg)
586         local rtobj = oil.corba.idl.null
587         local success, exception = oil.pcall(
588             function()
589                 rtobj = mgrobj.create_component(arg)
590                 self._rtcout.RTC_DEBUG("Component created "..arg)
591             end)
592         if not success then
593             self._rtcout.RTC_DEBUG("Exception was caught while creating component.")
594             self._rtcout.RTC_ERROR(exception)
595             return oil.corba.idl.null
596         end
597         return rtobj
598     end
599
600     -- RTC生成
601     -- @param module_name RTC名、オプション(RTC?param1=xxx&param2=yyy)
602     -- @return RTC
603     function obj:create_component(module_name)
604         self._rtcout:RTC_TRACE("create_component("..module_name..")")
605         local rtc = self:createComponentByAddress(module_name)
606         if rtc ~= oil.corba.idl.null then
607             return rtc
608         end
609         rtc = self:createComponentByManagerName(module_name)
610         if rtc ~= oil.corba.idl.null then
611             return rtc
612         end
613         local tmp = {module_name}
614         self:getParameterByModulename("manager_address",tmp)
615         module_name = tmp[1]
616
617         local comp_param = ManagerServant.CompParam.new(module_name)
618
619         if self._isMaster then
620
621             for k, slave in ipairs(self._slaves) do
622                 local success, exception = oil.pcall(
623                     function()
624                         local prof = slave:get_configuration()
625                         local prop = Properties.new()
626                         NVUtil.copyToProperties(prop, prof)
627                         local slave_lang = prop:getProperty("manager.language")
628                         
629                         if slave_lang == comp_param:language() then
630                             rtc = slave:create_component(module_name)
631                         end
632                 end)
633                 if not success then
634                     self._rtcout:RTC_ERROR("Unknown exception cought.")
635                     self._rtcout:RTC_DEBUG(exception)
636                     table.remove(self._slaves, k)
637                 end
638                 if rtc ~= oil.corba.idl.null then
639                     return rtc
640                 end
641             end
642
643             if manager_name == "" then
644                 module_name = module_name + "&manager_name=manager_%p"
645                 rtc = self:createComponentByManagerName(module_name)
646                 return rtc
647             end
648         else
649             --print(module_name)
650             rtc = self._mgr:createComponent(module_name)
651             if rtc ~= nil then
652                 return rtc:getObjRef()
653             end
654         end
655
656         return oil.corba.idl.null
657     end
658
659     -- RTC削除
660     -- @param instance_name インスタンス名
661     -- @return リターンコード
662     function obj:delete_component(instance_name)
663         self._rtcout:RTC_TRACE("delete_component("..instance_name..")")
664         local comp_ = self._mgr:getComponent(instance_name)
665         if comp_ == nil then
666             self._rtcout:RTC_WARN("No such component exists: "..instance_name)
667             return self._ReturnCode_t.BAD_PARAMETER
668         end
669
670         local success, exception = oil.pcall(
671             function()
672                 comp_:exit()
673             end)
674         if not success then
675             self._rtcout:RTC_ERROR("Unknown exception was raised, when RTC was finalized.")
676             return self._ReturnCode_t.RTC_ERROR
677         end
678
679         return self._ReturnCode_t.RTC_OK
680     end
681
682     -- RTC一覧取得
683     -- @return RTC一覧
684     function obj:get_components()
685         self._rtcout:RTC_TRACE("get_components()")
686
687
688         local rtcs = self._mgr:getComponents()
689         local crtcs = {}
690
691
692         for i, rtc in ipairs(rtcs) do
693             table.insert(crtcs, rtc:getObjRef())
694         end
695
696         return crtcs
697     end
698
699     -- RTCのプロファイル一覧取得
700     -- @return RTCのプロファイル一覧
701     function obj:get_component_profiles()
702         local rtcs = self._mgr:getComponents()
703         local cprofs = {}
704
705         for i, rtc in ipairs(rtcs) do
706             table.insert(cprofs, rtc:get_component_profile())
707         end
708         return cprofs
709
710     end
711
712     -- マネージャのプロファイル取得
713     -- @return プロファイル
714     function obj:get_profile()
715         self._rtcout:RTC_TRACE("get_profile()")
716         local prof = {properties={}}
717         NVUtil.copyFromProperties(prof.properties, self._mgr:getConfig():getNode("manager"))
718
719         return prof
720     end
721
722     -- マネージャのコンフィギュレーション取得
723     -- @return コンフィギュレーション
724     function obj:get_configuration()
725         self._rtcout:RTC_TRACE("get_configuration()")
726         local nvlist = {}
727         NVUtil.copyFromProperties(nvlist, self._mgr:getConfig())
728         return nvlist
729     end
730
731     -- マネージャのコンフィギュレーション設定
732     -- @param name キー
733     -- @param value 値
734     -- @return リターンコード
735     function obj:set_configuration(name, value)
736         self._rtcout:RTC_TRACE("set_configuration(name = "..name..", value = "..value..")")
737         self._mgr:getConfig():setProperty(name, value)
738         return self._ReturnCode_t.RTC_OK
739     end
740
741     -- マスターマネージャかスレーブマネージャかの確認
742     -- @return true:マスターマネージャ、false:スレーブマネージャ
743     function obj:is_master()
744         local ret = ""
745         if self._isMaster then
746             ret = "YES"
747         else
748             ret = "NO"
749         end
750         self._rtcout:RTC_TRACE("is_master(): "..ret)
751         return self._isMaster
752     end
753
754     -- マスターマネージャ一覧取得
755     -- @return マスターマネージャ一覧
756     function obj:get_master_managers()
757         self._rtcout:RTC_TRACE("get_master_managers()")
758         return self._masters
759     end
760
761
762     -- マスターマネージャ削除
763     -- @param mgr マネージャ
764     -- @return リターンコード
765     function obj:remove_master_manager(mgr)
766         self._rtcout:RTC_TRACE("remove_master_manager(), "..#self._masters.." masters")
767         local index = CORBA_SeqUtil.find(self._masters, is_equiv(mgr))
768
769         if index < 1 then
770             self._rtcout:RTC_ERROR("Not found.")
771             return self._ReturnCode_t.BAD_PARAMETER
772         end
773
774
775         self._masters[index] = nil
776         self._rtcout.RTC_TRACE("remove_master_manager() done, "..#self._masters.." masters")
777         return self._ReturnCode_t.RTC_OK
778     end
779
780     -- スレーブマネージャ一覧取得
781     -- @return スレーブマネージャ一覧
782     function obj:get_slave_managers()
783         self._rtcout:RTC_TRACE("get_slave_managers(), "..#self._slaves.." slaves")
784         return self._slaves
785     end
786
787
788     -- スレーブマネージャ削除
789     -- @param mgr マネージャ
790     -- @return リターンコード
791     function obj:remove_slave_manager(mgr)
792         self._rtcout:RTC_TRACE("remove_slave_manager(), "..#self._slaves.." slaves")
793         local index = CORBA_SeqUtil.find(self._slaves, is_equiv(mgr))
794
795         if index < 1 then
796             self._rtcout:RTC_ERROR("Not found.")
797             return self._ReturnCode_t.BAD_PARAMETER
798         end
799
800
801         self._slaves[index] = nil
802         self._rtcout.RTC_TRACE("remove_slave_manager() done, "..#self._slaves.." slaves")
803         return self._ReturnCode_t.RTC_OK
804     end
805
806     -- マネージャのコピー作成
807     -- @return リターンコード
808     function obj:fork()
809         return self._ReturnCode_t.PRECONDITION_NOT_MET
810     end
811
812     -- マネージャ終了
813     -- @return リターンコード
814     function obj:shutdown()
815         self._mgr:createShutdownThread(1)
816         return self._ReturnCode_t.RTC_OK
817     end
818
819     -- マネージャ再起動
820     -- @return リターンコード
821     function obj:restart()
822         return self._ReturnCode_t.PRECONDITION_NOT_MET
823     end
824
825     -- RTCのオブジェクトリファレンス取得
826     -- 未実装
827     -- @param name
828     -- @return
829     function obj:get_service(name)
830         return oil.corba.idl.null
831     end
832
833     local Manager = require "openrtm.Manager"
834     obj._mgr    = Manager:instance()
835     obj._ReturnCode_t = obj._mgr:getORB().types:lookup("::RTC::ReturnCode_t").labelvalue
836
837     obj._owner  = oil.corba.idl.null
838     obj._rtcout = obj._mgr:getLogbuf("ManagerServant")
839     obj._isMaster = false
840     obj._masters = {}
841     obj._slaves = {}
842
843     local config = obj._mgr:getConfig()
844
845     obj._objref = oil.corba.idl.null
846
847
848     if not obj:createINSManager() then
849         obj._rtcout:RTC_WARN("Manager CORBA servant creation failed.")
850         return obj
851     end
852
853
854
855     obj._rtcout:RTC_TRACE("Manager CORBA servant was successfully created.")
856
857     if StringUtil.toBool(config:getProperty("manager.is_master"), "YES", "NO", true) then
858         obj._rtcout:RTC_TRACE("This manager is master.")
859         obj._isMaster = true
860         return obj
861     else
862         obj._rtcout:RTC_TRACE("This manager is slave.")
863         local success, exception = oil.pcall(
864             function()
865                 local owner = obj:findManager(config:getProperty("corba.master_manager"))
866                 --print(owner)
867                 --print(owner)
868                 if owner == oil.corba.idl.null then
869                     obj._rtcout:RTC_INFO("Master manager not found")
870                     return obj
871                 end
872
873                 obj:add_master_manager(owner)
874                 owner:add_slave_manager(obj._objref)
875         end)
876         if not success then
877             obj._rtcout:RTC_ERROR("Unknown exception cought.")
878             obj._rtcout:RTC_ERROR(exception)
879         end
880     end
881
882     return obj
883 end
884
885 return ManagerServant

File lua\openrtm\ModuleManager.lua

1 ---------------------------------
2 --! @file ModuleManager.lua
3 --! @brief モジュール管理マネージャ定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local StringUtil = require "openrtm.StringUtil"
11 local ObjectManager = require "openrtm.ObjectManager"
12 local Properties = require "openrtm.Properties"
13
14
15
16 local ModuleManager= {}
17 --_G["openrtm.ModuleManager"] = ModuleManager
18
19
20 local CONFIG_EXT    = "manager.modules.config_ext"
21 local CONFIG_PATH   = "manager.modules.config_path"
22 local DETECT_MOD    = "manager.modules.detect_loadable"
23 local MOD_LOADPTH   = "manager.modules.load_path"
24 local INITFUNC_SFX  = "manager.modules.init_func_suffix"
25 local INITFUNC_PFX  = "manager.modules.init_func_prefix"
26 local ALLOW_ABSPATH = "manager.modules.abs_path_allowed"
27 local ALLOW_URL     = "manager.modules.download_allowed"
28 local MOD_DWNDIR    = "manager.modules.download_dir"
29 local MOD_DELMOD    = "manager.modules.download_cleanup"
30 local MOD_PRELOAD   = "manager.modules.preload"
31
32
33 local DLL = {}
34
35 DLL.new = function(dll)
36     local obj = {}
37     obj.dll = dll
38     return obj
39 end
40
41 -- モジュール保持オブジェクト初期化
42 -- @param dll モジュール
43 -- @param prop 設定情報
44 -- 「file_path」の要素にはファイルパスを格納する
45 -- 「import_name」の要素にはモジュール名を格納する
46 -- @return モジュール保持オブジェクト
47 local DLLEntity = {}
48 DLLEntity.new = function(dll,prop)
49     local obj = {}
50     obj.dll = dll
51     obj.properties = prop
52     return obj
53 end
54
55 -- モジュール比較関数オブジェクトの初期化
56 -- @param argv argv.name:ファイルパス
57 -- @return モジュール比較関数オブジェクト
58 local DLLPred = function(argv)
59     local obj = {}
60     if argv.name ~= nil then
61         obj._import_name = argv.name
62     end
63     if argv.factory ~= nil then
64         obj._import_name = argv.factory
65     end
66     -- モジュールの比較
67     -- @param self 自身のオブジェクト
68     -- @param dll 比較対象のモジュール
69     -- ファイルパスの一致で確認
70     -- @return true:一致
71     local call_func = function(self, dll)
72         --print(self._filepath, dll.properties:getProperty("file_path"))
73         --print(self._import_name, dll.properties:getProperty("import_name"))
74         return (self._import_name == dll.properties:getProperty("import_name"))
75     end
76     setmetatable(obj, {__call=call_func})
77     return obj
78 end
79
80
81 ModuleManager.Error = {}
82 -- エラー例外オブジェクトの初期化
83 -- @param reason_ エラー内容
84 -- @return エラー例外オブジェクト
85 ModuleManager.Error.new = function(reason_)
86     local obj = {}
87     obj.reason = reason_
88     obj.type = "Error"
89     local str_func = function(self)
90         local str = "ModuleManager."..self.type..":"..self.reason
91         return str
92     end
93     setmetatable(obj, {__tostring =str_func})
94     return obj
95 end
96
97
98 ModuleManager.NotFound = {}
99 -- オブジェクトが存在しない例外オブジェクトの初期化
100 -- @param name_ エラー内容
101 -- @return 例外オブジェクト
102 ModuleManager.NotFound.new = function(name_)
103     local obj = {}
104     obj.name = name_
105     obj.type = "NotFound"
106     local str_func = function(self)
107         local str = "ModuleManager."..self.type..":"..self.name
108         return str
109     end
110     setmetatable(obj, {__tostring =str_func})
111     return obj
112 end
113
114
115 ModuleManager.FileNotFound = {}
116 -- ファイルが存在しない例外オブジェクトの初期化
117 -- @param name_ エラー内容
118 -- @return 例外オブジェクト
119 ModuleManager.FileNotFound.new = function(name_)
120     local obj = {}
121     obj.type = "FileNotFound"
122     local str_func = function(self)
123         local str = "ModuleManager."..self.type..":"..self.name
124         return str
125     end
126     setmetatable(obj, {__tostring =str_func, __index=ModuleManager.NotFound.new(name_)})
127     return obj
128 end
129
130 ModuleManager.ModuleNotFound = {}
131 -- モジュールが存在しない例外オブジェクトの初期化
132 -- @param name_ エラー内容
133 -- @return 例外オブジェクト
134 ModuleManager.ModuleNotFound.new = function(name_)
135     local obj = {}
136     obj.type = "ModuleNotFound"
137     local str_func = function(self)
138         local str = "ModuleManager."..self.type..":"..self.name
139         return str
140     end
141     setmetatable(obj, {__tostring =str_func, __index=ModuleManager.NotFound.new(name_)})
142     return obj
143 end
144
145 ModuleManager.SymbolNotFound = {}
146 -- シンボルが存在しない例外オブジェクトの初期化
147 -- @param name_ エラー内容
148 -- @return 例外オブジェクト
149 ModuleManager.SymbolNotFound.new = function(name_)
150     local obj = {}
151     obj.type = "SymbolNotFound"
152     local str_func = function(self)
153         local str = "ModuleManager."..self.type..":"..self.name
154         return str
155     end
156     setmetatable(obj, {__tostring =str_func, __index=ModuleManager.NotFound.new(name_)})
157     return obj
158 end
159
160
161 ModuleManager.NotAllowedOperation = {}
162 -- 指定した操作ができない場合の例外オブジェクトの初期化
163 -- @param reason_ エラー内容
164 -- @return 例外オブジェクト
165 ModuleManager.NotAllowedOperation.new = function(reason_)
166     local obj = {}
167     obj.type = "NotAllowedOperation"
168     local str_func = function(self)
169         local str = "ModuleManager."..self.type..":"..self.reason
170         return str
171     end
172     setmetatable(obj, {__tostring =str_func, __index=ModuleManager.Error.new(reason_)})
173     return obj
174 end
175
176
177 ModuleManager.InvalidArguments = {}
178 -- 不正な引数指定の例外オブジェクトの初期化
179 -- @param reason_ エラー内容
180 -- @return 例外オブジェクト
181 ModuleManager.InvalidArguments.new = function(reason_)
182     local obj = {}
183     obj.type = "InvalidArguments"
184     local str_func = function(self)
185         local str = "ModuleManager."..self.type..":"..self.reason
186         return str
187     end
188     setmetatable(obj, {__tostring =str_func, __index=ModuleManager.Error.new(reason_)})
189     return obj
190 end
191
192
193 ModuleManager.InvalidOperation = {}
194 -- 不正な操作の例外オブジェクトの初期化
195 -- @param reason_ エラー内容
196 -- @return 例外オブジェクト
197 ModuleManager.InvalidOperation.new = function(reason_)
198     local obj = {}
199     obj.type = "InvalidOperation"
200     local str_func = function(self)
201         local str = "ModuleManager."..self.type..":"..self.reason
202         return str
203     end
204     setmetatable(obj, {__tostring =str_func, __index=ModuleManager.Error.new(reason_)})
205     return obj
206 end
207
208
209
210
211
212
213 -- モジュール管理オブジェクトの初期化
214 -- @param prop プロパティ
215 -- 「manager.modules.abs_path_allowed」がYESの時、絶対パスでファイルを指定できる
216 -- 「manager.modules.download_allowed」がYESの時、URLでファイルを指定できる
217 -- @return モジュール管理オブジェクト
218 ModuleManager.new = function(prop)
219     local obj = {}
220
221     -- 終了関数
222     function obj:exit()
223         self:unloadAll()
224     end
225
226     -- モジュールのロード
227     -- @param file_name ファイルパス
228     -- ファイル名のみの指定の場合は「manager.modules.load_path」で設定したパスを探査する
229     -- @param init_func 初期化関数
230     -- @return ファイルパス
231     function obj:load(file_name, init_func)
232         file_name = string.gsub(file_name, "\\", "/")
233         self._rtcout:RTC_TRACE("load(fname = "..file_name..")")
234         if file_name == "" then
235             error(ModuleManager.InvalidArguments.new("Invalid file name."))
236         end
237         if StringUtil.isURL(file_name) then
238             if not self._downloadAllowed then
239                 error(ModuleManager.NotAllowedOperation.new("Downloading module is not allowed."))
240             else
241                 error(ModuleManager.NotFound.new("Not implemented."))
242             end
243         end
244         local import_name = StringUtil.basename(file_name)
245         local pathChanged=false
246         local file_path = nil
247         local save_path = ""
248
249
250         if StringUtil.isAbsolutePath(file_name) then
251             if not self._absoluteAllowed then
252                 error(ModuleManager.NotAllowedOperation.new("Absolute path is not allowed"))
253             else
254                 save_path = package.path
255                 package.path = package.path..";"..StringUtil.dirname(file_name).."?.lua"
256
257                 pathChanged = true
258                 import_name = StringUtil.basename(file_name)
259                 file_path = file_name
260             end
261
262         else
263             file_path = self:findFile(file_name, self._loadPath)
264             if file_path == nil then
265                 error(ModuleManager.FileNotFound.new(file_name))
266             end
267         end
268
269
270         
271         if not self:fileExist(file_path) then
272
273             error(ModuleManager.FileNotFound.new(file_name))
274         end
275
276
277
278         local f = io.open(file_path, "r")
279         if init_func ~= nil then
280             if string.find(f:read("*a"), init_func) == nil then
281
282                 error(ModuleManager.FileNotFound.new(file_name))
283             end
284         end
285         f:close()
286
287
288
289         if not pathChanged then
290             package.path = package.path..";"..StringUtil.dirname(file_path).."?.lua"
291         end
292
293         local ext_pos = string.find(import_name, ".lua")
294         if ext_pos ~= nil then
295             import_name = string.sub(import_name,1,ext_pos-1)
296         end
297
298         --print(import_name)
299         --print("testModule", tostring(import_name))
300         local mo = require(tostring(import_name))
301         --local mo = require "testModule"
302         --print(mo)
303         --print(package.path)
304
305         if pathChanged then
306             package.path = save_path
307         end
308
309
310         file_path = string.gsub(file_path, "\\", "/")
311         file_path = string.gsub(file_path, "//", "/")
312
313         --print(mo,type(mo))
314         --print(file_path)
315         local dll = DLLEntity.new(mo,Properties.new())
316
317         dll.properties:setProperty("file_path",file_path)
318         dll.properties:setProperty("import_name",import_name)
319         self._modules:registerObject(dll)
320
321
322         if init_func == nil then
323             return file_name
324         end
325
326         self:symbol(import_name,init_func)(self._mgr)
327
328         return file_name
329     end
330
331     -- 指定パス一覧にファイルが存在するかを確認
332     -- @param fname ファイル名
333     -- @param load_path ディレクトリパスのリスト
334     -- @return ファイルが存在した場合はファイルのパスを返す
335     -- 存在しない場合は空文字列を返す
336     function obj:findFile(fname, load_path)
337         file_name = fname
338
339         for k, path in ipairs(load_path) do
340             local f = nil
341             local suffix = self._properties:getProperty("manager.modules.Lua.suffixes")
342             if string.find(fname, "."..suffix) == nil then
343                 f = tostring(path).."/"..tostring(file_name).."."..suffix
344             else
345                 f = tostring(path).."/"..tostring(file_name)
346             end
347             
348             
349             --print(self:fileExist(f))
350             if self:fileExist(f) then
351                 f = string.gsub(f,"\\","/")
352                 f = string.gsub(f,"//","/")
353                 return f
354             end
355             --local filelist = {}
356             --StringUtil.findFile(path,file_name,filelist)
357
358             --if len(filelist) > 0 then
359             -- return filelist[1]
360             --end
361         end
362         return ""
363     end
364
365     -- ファイルの存在確認
366     -- @param filename ファイル名
367     -- @return true:存在する
368     function obj:fileExist(filename)
369         local fname = filename
370         local suffix = self._properties:getProperty("manager.modules.Lua.suffixes")
371         if string.find(fname, "."..suffix) == nil then
372             fname = tostring(filename).."."..suffix
373         end
374         --print(fname)
375
376         --if os.path.isfile(fname)
377         -- return True
378         --end
379         --print(fname)
380
381         local f = io.open(fname, "r")
382         if f ~= nil then
383             return true
384         end
385         return false
386
387         --return false
388     end
389
390     -- モジュールから指定関数を取得
391     -- @param import_name モジュール名
392     -- 既にモジュール名のモジュールが登録済みである必要がある
393     -- @param func_name 関数名
394     -- @return 関数オブジェクト
395     function obj:symbol(import_name, func_name)
396         local dll = self._modules:find(import_name)
397         --print(dll, file_name)
398         if dll == nil then
399             error(ModuleManager.ModuleNotFound.new(import_name))
400         end
401
402         local func = dll.dll[func_name]
403
404         if func == nil then
405             error(ModuleManager.SymbolNotFound.new(import_name))
406         end
407
408         return func
409     end
410
411     -- モジュールのアンロード
412     -- @param file_name ファイルパス
413     function obj:unload(file_name)
414         file_name = string.gsub(file_name, "\\", "/")
415         file_name = string.gsub(file_name, "//", "/")
416         local dll = self._modules:find(file_name)
417         if dll == nil then
418             error(ModuleManager.NotFound.new(file_name))
419         end
420         local dll_name = dll.properties:getProperty("import_name")
421         --print(package.loaded[dll_name])
422         package.loaded[dll_name] = nil
423         self._modules:unregisterObject(file_name)
424
425     end
426
427     -- 全モジュールのアンロード
428     function obj:unloadAll()
429         local dlls = self._modules:getObjects()
430         for k,dll in ipairs(dlls) do
431             local ident = dll.properties:getProperty("import_name")
432             --print(ident)
433             self._modules:unregisterObject(ident)
434         end
435     end
436
437     -- ロード済みのモジュール全てのプロファイルを取得
438     -- @return 全モジュールのプロファイル
439     function obj:getLoadedModules()
440         local dlls = self._modules:getObjects()
441         local modules = {}
442         for k,dll in ipairs(dlls) do
443             table.insert(modules, dll.properties)
444         end
445         return modules
446     end
447
448     obj._properties = prop
449     obj._configPath = StringUtil.split(prop:getProperty(CONFIG_PATH), ",")
450
451     for k, v in pairs(obj._configPath) do
452         obj._configPath[k] = StringUtil.eraseHeadBlank(v)
453     end
454     obj._loadPath = StringUtil.split(prop:getProperty(MOD_LOADPTH,"./"), ",")
455     local system_path = StringUtil.split(package.path,";")
456
457     for k, v in pairs(obj._loadPath) do
458         obj._loadPath[k] = StringUtil.eraseHeadBlank(v)
459     end
460
461     for k, v in pairs(system_path) do
462         local path = StringUtil.eraseHeadBlank(v)
463         if path ~= "" then
464             path = StringUtil.dirname(path)
465             table.insert(obj._loadPath, path)
466         end
467         
468     end
469
470     obj._absoluteAllowed = StringUtil.toBool(prop:getProperty(ALLOW_ABSPATH),
471                             "yes", "no", false)
472
473     obj._downloadAllowed = StringUtil.toBool(prop:getProperty(ALLOW_URL),
474                             "yes", "no", false)
475
476     obj._initFuncSuffix = prop:getProperty(INITFUNC_SFX)
477     obj._initFuncPrefix = prop:getProperty(INITFUNC_PFX)
478     obj._modules = ObjectManager.new(DLLPred)
479     obj._rtcout = nil
480     local Manager = require "openrtm.Manager"
481     obj._mgr = Manager:instance()
482     if obj._rtcout == nil then
483         obj._rtcout = obj._mgr:getLogbuf("ModuleManager")
484     end
485
486     obj._modprofs = {}
487     return obj
488 end
489
490
491 return ModuleManager

File lua\openrtm\NamingManager.lua

1 ---------------------------------
2 --! @file NamingManager.lua
3 --! @brief ネーミングマネージャ、名前管理基底クラスの定義
4 ---------------------------------
5
6
7 --[[
8 Copyright (c) 2017 Nobuhiko Miyamoto
9 ]]
10
11 local NamingManager= {}
12 --_G["openrtm.NamingManager"] = NamingManager
13
14 local oil = require "oil"
15 local CorbaNaming = require "openrtm.CorbaNaming"
16 local StringUtil = require "openrtm.StringUtil"
17 local RTCUtil = require "openrtm.RTCUtil"
18 local NVUtil = require "openrtm.NVUtil"
19 local CorbaConsumer = require "openrtm.CorbaConsumer"
20
21
22 NamingManager.NamingBase = {}
23
24 -- 名前管理基底オブジェクト初期化
25 -- @return 名前管理オブジェクト
26 NamingManager.NamingBase.new = function()
27     local obj = {}
28     -- RTCをネームサーバーに登録
29     -- @param name 登録名
30     -- @param rtobj RTC
31     function obj:bindObject(name, rtobj)
32     end
33     -- ポートをネームサーバーに登録
34     -- @param name 登録名
35     -- @param port ポート
36     function obj:bindPortObject(name, port)
37     end
38     -- オブジェクトをネームサーバーから登録解除
39     -- @param name 登録名
40     function obj:unbindObject(name)
41     end
42     -- ネームサーバー生存確認
43     -- @return true:生存、false:終了済み
44     function obj:isAlive()
45         return true
46     end
47     -- 文字列からオブジェクトを取得
48     -- @param name オブジェクト名
49     -- @return オブジェクト一覧
50     function obj:string_to_component(name)
51         return {}
52     end
53
54
55     return obj
56 end
57
58 NamingManager.NamingOnCorba = {}
59
60 -- CORBAネームサーバー管理オブジェクト初期化
61 -- @param orb ORB
62 -- @param names アドレス
63 -- @return CORBAネームサーバー管理オブジェクト
64 NamingManager.NamingOnCorba.new = function(orb, names)
65     local obj = {}
66     setmetatable(obj, {__index=NamingManager.NamingBase.new()})
67     local Manager = require "openrtm.Manager"
68     obj._rtcout = Manager:instance():getLogbuf("manager.namingoncorba")
69     obj._cosnaming = CorbaNaming.new(orb,names)
70     obj._endpoint = ""
71     obj._replaceEndpoint = false
72
73     -- RTCをネームサーバーに登録
74     -- @param name 登録名
75     -- @param rtobj RTC
76     function obj:bindObject(name, rtobj)
77
78         self._rtcout:RTC_TRACE("bindObject(name = "..name..", rtobj or mgr)")
79         local success, exception = oil.pcall(
80             function()
81
82                 self._cosnaming:rebindByString(name, rtobj:getObjRef(), true)
83
84             end)
85         if not success then
86             --print(exception)
87             self._rtcout:RTC_ERROR(exception)
88         end
89
90     end
91
92     -- オブジェクトをネームサーバーから登録解除
93     -- @param name 登録名
94     function obj:unbindObject(name)
95         self._rtcout:RTC_TRACE("unbindObject(name = "..name..")")
96         local success, exception = oil.pcall(
97             function()
98                 self._cosnaming:unbind(name)
99             end)
100         if not success then
101             --print(exception)
102             self._rtcout.RTC_ERROR(exception)
103         end
104
105     end
106
107
108     -- ネームサーバーから指定名のRTCを検索
109     -- @param context ネーミングコンテキスト
110     -- @param name RTCの登録名
111     -- @param rtcs 一致したRTC一覧
112     function obj:getComponentByName(context, name, rtcs)
113
114         local orb = Manager:instance():getORB()
115         local BindingType = orb.types:lookup("::CosNaming::BindingType").labelvalue
116
117         local length = 500
118
119         local bl,bi = context:list(length)
120
121
122
123         for k,i in ipairs(bl) do
124             --print(i.binding_type, BindingType.ncontext)
125             --print(NVUtil.getBindingType(i.binding_type), BindingType.ncontext)
126             --print(i.binding_name)
127             if NVUtil.getBindingType(i.binding_type) == BindingType.ncontext then
128                 local next_context = RTCUtil.newproxy(orb, context:resolve(i.binding_name),"IDL:omg.org/CosNaming/NamingContext:1.0")
129                 --print(next_context)
130                 self:getComponentByName(next_context, name, rtcs)
131             elseif NVUtil.getBindingType(i.binding_type) == BindingType.nobject then
132                 if i.binding_name[1].id == name and i.binding_name[1].kind == "rtc" then
133                     --print(i.binding_name[1].id, i.binding_name[1].kind)
134                     local success, exception = oil.pcall(
135                         function()
136                             local cc = CorbaConsumer.new()
137                             cc:setObject(context:resolve(i.binding_name))
138                             local _obj = RTCUtil.newproxy(orb, cc:getObject(),"IDL:openrtm.aist.go.jp/OpenRTM/DataFlowComponent:1.0")
139
140                             if not NVUtil._non_existent(_obj) then
141                                 table.insert(rtcs, _obj)
142                             end
143                     end)
144                     if not success then
145                         self._rtcout:RTC_ERROR(exception)
146                     end
147                 end
148             end
149         end
150     end
151
152
153     -- rtcname形式の文字列からRTCを取得
154     -- @param name RTC名(rtcname形式)
155     -- rtcname://localhost/test.host_cxt/ConsoleIn0
156     -- @return 一致したRTC一覧
157     function obj:string_to_component(name)
158
159         local rtc_list = {}
160         local tmp = StringUtil.split(name, "://")
161         if #tmp > 1 then
162             --print(tmp[1])
163             if tmp[1] == "rtcname" then
164                 local url = tmp[2]
165                 local r = StringUtil.split(url, "/")
166
167                 if #r > 1 then
168                     local host = r[1]
169                     local rtc_name = string.sub(url, #host+2)
170                     --print(rtc_name)
171
172
173                     local success, exception = oil.pcall(
174                         function()
175
176                             local cns = nil
177                             if host == "*" then
178                                 cns = self._cosnaming
179                             else
180                                 local orb = Manager:instance():getORB()
181                                 cns = CorbaNaming.new(orb,host)
182
183                             end
184
185                             local names = StringUtil.split(rtc_name, "/")
186
187
188                             if #names == 2 and names[1] == "*" then
189
190                                 local root_cxt = cns:getRootContext()
191
192                                 self:getComponentByName(root_cxt, names[2], rtc_list)
193                                 return rtc_list
194                             else
195                                 rtc_name = rtc_name..".rtc"
196
197                                 local _obj = cns:resolveStr(rtc_name)
198
199                                 if _obj == oil.corba.idl.null then
200                                     return {}
201                                 end
202                                 if NVUtil._non_existent(_obj) then
203                                     return {}
204                                 end
205
206                                 _obj = RTCUtil.newproxy(orb, _obj,"IDL:openrtm.aist.go.jp/OpenRTM/DataFlowComponent:1.0")
207
208
209                                 table.insert(rtc_list, _obj)
210                                 return rtc_list
211                             end
212                     end)
213                     if not success then
214                         return {}
215                     end
216                 end
217             end
218         end
219
220         return rtc_list
221     end
222
223
224     return obj
225 end
226
227
228
229 NamingManager.NamingOnManager = {}
230
231 -- Manager名前管理オブジェクト初期化
232 -- @param orb ORB
233 -- @param mgr マネージャ
234 -- @return Manager名前管理オブジェクト
235 NamingManager.NamingOnManager.new = function(orb, mgr)
236     local obj = {}
237     setmetatable(obj, {__index=NamingManager.NamingBase.new()})
238     local Manager = require "openrtm.Manager"
239     obj._rtcout = Manager:instance():getLogbuf("manager.namingonmanager")
240     obj._cosnaming = nil
241     obj._orb = orb
242     obj._mgr = mgr
243
244
245     -- 指定ホスト名のマネージャを取得
246     -- @param name ホスト名(例:localhost:2810)
247     -- @return マネージャ
248     function obj:getManager(name)
249         if name == "*" then
250             local mgr_sev = self._mgr:getManagerServant()
251             local mgr = nil
252             if mgr_sev:is_master() then
253                 mgr = mgr_sev:getObjRef()
254             else
255                 local masters = mgr_sev:get_master_managers()
256                 if #masters > 0 then
257                     mgr = masters[1]
258                 else
259                     mgr = mgr_sev:getObjRef()
260                 end
261             end
262             return mgr
263         end
264         local success, exception = oil.pcall(
265             function()
266                 local mgrloc = "corbaloc:iiop:"
267                 local prop = self._mgr:getConfig()
268                 local manager_name = prop:getProperty("manager.name")
269                 mgrloc = mgrloc..name
270                 mgrloc = mgrloc.."/"..manager_name
271
272
273
274
275                 mgr = RTCUtil.newproxy(self._orb, mgrloc,"IDL:RTM/Manager:1.0")
276                 --mgr = RTCUtil.newproxy(self._orb, mgrloc,"IDL:openrtm.aist.go.jp/OpenRTM/DataFlowComponent:1.0")
277
278                 --print(mgrloc)
279
280
281                 self._rtcout:RTC_DEBUG("corbaloc: "..mgrloc)
282                 --print(mgr)
283
284         end)
285         if not success then
286             self._rtcout:RTC_DEBUG(exception)
287         else
288             return mgr
289         end
290         return oil.corba.idl.null
291     end
292
293
294
295     -- rtcloc形式の文字列からRTCを取得
296     -- @param name RTC名(rtcloc形式)
297     -- rtcloc://localhost:2010/Category/ConsoleIn0
298     -- @return 一致したRTC一覧
299     function obj:string_to_component(name)
300         --print(name)
301         local rtc_list = {}
302         local tmp = StringUtil.split(name, "://")
303         --print(#tmp)
304
305         if #tmp > 1 then
306
307             if tmp[1] == "rtcloc" then
308
309                 local url = tmp[2]
310                 local r = StringUtil.split(url, "/")
311                 if #r > 1 then
312                     local host = r[1]
313                     local rtc_name = string.sub(url, #host+2)
314
315
316                     local mgr = self:getManager(host)
317
318                     if mgr ~= oil.corba.idl.null then
319                         --print("test1")
320                         --print(mgr:get_master_managers())
321                         rtc_list = mgr:get_components_by_name(rtc_name)
322                         --print("test2")
323
324                         local slaves = mgr:get_slave_managers()
325
326                         for k,slave in ipairs(slaves) do
327                             local success, exception = oil.pcall(
328                                 function()
329                                     rtc_list.extend(slave:get_components_by_name(rtc_name))
330                             end)
331                             if not success then
332                                 self._rtcout:RTC_DEBUG(exception)
333                                 mgr:remove_slave_manager(slave)
334                             end
335                         end
336                     end
337                 end
338                 return rtc_list
339             end
340         end
341         return rtc_list
342     end
343
344     return obj
345 end
346
347 -- 名前管理オブジェクト格納オブジェクト初期化
348 -- @param meth メソッド名
349 -- @param name オブジェクト名
350 -- @param naming 名前管理オブジェクト
351 -- @return 名前管理オブジェクト格納オブジェクト
352 NamingManager.NameServer = {}
353 NamingManager.NameServer.new = function(meth, name, naming)
354     local obj = {}
355     obj.method = meth
356     obj.nsname = name
357     obj.ns     = naming
358     return obj
359 end
360
361
362 NamingManager.Comps = {}
363 -- RTC格納オブジェクト初期化
364 -- @param n 名前
365 -- @param _obj RTC
366 -- @return RTC格納オブジェクト
367 NamingManager.Comps.new = function(n, _obj)
368     local obj = {}
369     obj.name = n
370     obj.rtobj = _obj
371     return obj
372 end
373
374
375 NamingManager.Mgr = {}
376 NamingManager.Mgr.new = function(n, _obj)
377     local obj = {}
378     obj.name = n
379     obj.mgr = _obj
380     return obj
381 end
382
383 NamingManager.Port = {}
384 NamingManager.Port.new = function(n, _obj)
385     local obj = {}
386     obj.name = n
387     obj.port = _obj
388     return obj
389 end
390
391 -- ネーミングマネージャ初期化
392 -- @param manager マネージャ
393 -- @return ネーミングマネージャ
394 NamingManager.new = function(manager)
395     local obj = {}
396     obj._manager = manager
397     obj._rtcout = manager:getLogbuf('manager.namingmanager')
398     obj._names = {}
399     obj._compNames = {}
400     obj._mgrNames  = {}
401     obj._portNames = {}
402     -- 名前管理オブジェクト登録
403     -- @param method メソッド名
404     -- @param name_server アドレス
405     function obj:registerNameServer(method, name_server)
406         --print(self._rtcout)
407         self._rtcout:RTC_TRACE("NamingManager::registerNameServer("..method..", "..name_server..")")
408         local name = self:createNamingObj(method, name_server)
409         --print(name)
410         table.insert(self._names, NamingManager.NameServer.new(method, name_server, name))
411     end
412     -- 名前管理オブジェクト生成
413     -- @param method メソッド名
414     -- @param name_server アドレス
415     -- @return 名前管理オブジェクト
416     function obj:createNamingObj(method, name_server)
417         --print(method)
418         self._rtcout:RTC_TRACE("createNamingObj(method = "..method..", nameserver = "..name_server..")")
419
420         local mth = method
421
422
423         if mth == "corba" then
424             local ret = nil
425             local success, exception = oil.pcall(
426                 function()
427                     local name = NamingManager.NamingOnCorba.new(self._manager:getORB(),name_server)
428
429                     self._rtcout:RTC_INFO("NameServer connection succeeded: "..method.."/"..name_server)
430                     ret = name
431                 end)
432             if not success then
433                 print(exception)
434                 self._rtcout:RTC_INFO("NameServer connection failed: "..method.."/"..name_server)
435             end
436             return ret
437         elseif mth == "manager" then
438
439             local name = NamingManager.NamingOnManager.new(self._manager:getORB(), self._manager)
440             --print(name)
441             return name
442         end
443         return nil
444     end
445     -- RTCをネームサーバーに登録
446     -- @param name 登録名
447     -- @param rtobj RTC
448     function obj:bindObject(name, rtobj)
449         self._rtcout:RTC_TRACE("NamingManager::bindObject("..name..")")
450         for i, n in ipairs(self._names) do
451             if n.ns ~= nil then
452                 local success, exception = oil.pcall(
453                     function()
454                         n.ns:bindObject(name, rtobj)
455                     end)
456                 if not success then
457                     n.ns = nil
458                 end
459             end
460         end
461
462         self:registerCompName(name, rtobj)
463     end
464     function obj:bindManagerObject(name,  mgr)
465         self._rtcout:RTC_TRACE("NamingManager::bindManagerObject("..name..")")
466         for i, n in ipairs(self._names) do
467             if n.ns ~= nil then
468                 local success, exception = oil.pcall(
469                     function()
470                         n.ns:bindObject(name, mgr)
471                     end)
472                 if not success then
473                     n.ns = nil
474                 end
475             end
476         end
477
478         self:registerMgrName(name, mgr)
479     end
480     function obj:bindPortObject(name, port)
481         self._rtcout:RTC_TRACE("NamingManager::bindPortObject("..name..")")
482         for i, n in ipairs(self._names) do
483             if n.ns ~= nil then
484                 local success, exception = oil.pcall(
485                     function()
486                         n.ns:bindObject(name, port)
487                     end)
488                 if not success then
489                     n.ns = nil
490                 end
491             end
492         end
493
494         self:registerPortName(name, port)
495     end
496     -- RTCの登録
497     -- @param name 登録名
498     -- @param rtobj RTC
499     function obj:registerCompName(name, rtobj)
500         for i, compName in ipairs(self._compNames) do
501             if compName.name == name then
502                 compName.rtobj = rtobj
503                 return
504             end
505         end
506         table.insert(self._compNames, NamingManager.Comps.new(name, rtobj))
507     end
508
509     function obj:registerMgrName(name, mgr)
510         for i, mgrName in ipairs(self._mgrNames) do
511             if mgrName.name == name then
512                 mgrName.mgr = mgr
513                 return
514             end
515         end
516         table.insert(self._mgrNames, NamingManager.Mgr.new(name, rtobj))
517     end
518
519     function obj:registerPortName(name, port)
520         for i, portName in ipairs(self._portNames) do
521             if portName.name == name then
522                 portName.port = port
523                 return
524             end
525         end
526         table.insert(self._portNames, NamingManager.Port.new(name, port))
527     end
528
529     -- RTCをネームサーバーから登録解除
530     -- @param name 登録名
531     function obj:unbindObject(name)
532         self._rtcout:RTC_TRACE("NamingManager::unbindObject("..name..")")
533         for i,n in ipairs(self._names) do
534             if n.ns ~= nil then
535                 n.ns:unbindObject(name)
536             end
537         end
538         self:unregisterCompName(name)
539         self:unregisterMgrName(name)
540         self:unregisterPortName(name)
541     end
542
543     function obj:unbindAll()
544         self._rtcout:RTC_TRACE("NamingManager::unbindAll(): %d names.", #self._compNames)
545         for i, compName in ipairs(self._compNames) do
546             self:unbindObject(compName.name)
547         end
548         for i, mgrName in ipairs(self._mgrNames) do
549             self:unbindObject(mgrName.name)
550         end
551         for i, portName in ipairs(self._portNames) do
552             self:unbindObject(portName.name)
553         end
554     end
555
556     -- RTCの登録解除
557     -- @param name 登録名
558     function obj:unregisterCompName(name)
559         for i, compName in ipairs(self._compNames) do
560             if compName.name == name then
561                 table.remove(self._compNames, i)
562                 return
563             end
564         end
565     end
566     -- マネージャの登録解除
567     -- @param name 登録名
568     function obj:unregisterMgrName(name)
569         for i, mgrName in ipairs(self._mgrNames) do
570             if mgrName.name == name then
571                 table.remove(self._mgrNames, i)
572                 return
573             end
574         end
575     end
576     -- ポートの登録解除
577     -- @param name 登録名
578     function obj:unregisterPortName(name)
579         for i, portName in ipairs(self._portNames) do
580             if portName.name == name then
581                 table.remove(self._portNames, i)
582                 return
583             end
584         end
585     end
586
587     -- rtcloc、rtcname形式の文字列からRTCを取得
588     -- @param name RTC名
589     -- @return 一致したRTC一覧
590     function obj:string_to_component(name)
591         for k,n in ipairs(self._names) do
592             if n.ns ~= nil then
593                 local comps = n.ns:string_to_component(name)
594                 if #comps > 0 then
595                     return comps
596                 end
597             end
598         end
599         return {}
600     end
601
602     function obj:getObjects()
603         local comps = {}
604         for k,comp in ipairs(self._compNames) do
605             table.insert(comps, comp.rtobj)
606         end
607         return comps
608     end
609
610     return obj
611 end
612
613
614
615 return NamingManager

File lua\openrtm\NamingServiceNumberingPolicy.lua

1 ---------------------------------
2 --! @file NamingServiceNumberingPolicy.lua
3 --! @brief ネームサーバーによる名前付けポリシー定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local NamingServiceNumberingPolicy= {}
11 --_G["openrtm.NamingServiceNumberingPolicy"] = NamingServiceNumberingPolicy
12
13 local Factory = require "openrtm.Factory"
14 local NumberingPolicy = require "openrtm.NumberingPolicy"
15 local NumberingPolicyBase = require "openrtm.NumberingPolicyBase"
16 local NumberingPolicyFactory = NumberingPolicyBase.NumberingPolicyFactory
17 local StringUtil = require "openrtm.StringUtil"
18
19 NamingServiceNumberingPolicy.new = function()
20     local obj = {}
21     setmetatable(obj, {__index=NumberingPolicy.new()})
22     obj._objects = {}
23     local Manager = require "openrtm.Manager"
24     obj._mgr = Manager:instance()
25     function obj:onCreate(_obj)
26         local num = 0
27            while true do
28               local num_str = tostring(num)
29       
30             local name = _obj:getTypeName()..num_str
31             
32               if not self:find(name) then
33                 return num_str
34               else
35                 num = num+1
36             end
37         end
38         return tostring(num)
39     end
40     function obj:onDelete(_obj)
41     end
42
43     function obj:find(name)
44         local rtcs = {}
45         local rtc_name = "rtcname://*/*/"
46         rtc_name = rtc_name..name
47            local rtcs = self._mgr:getNaming():string_to_component(rtc_name)
48     
49         if #rtcs > 0 then
50             return true
51         else
52             return false
53         end
54     end
55     
56     return obj
57 end
58
59
60 NamingServiceNumberingPolicy.Init = function()
61     NumberingPolicyFactory:instance():addFactory("ns_unique",
62         NamingServiceNumberingPolicy.new,
63         Factory.Delete)
64 end
65
66
67 return NamingServiceNumberingPolicy

File lua\openrtm\NodeNumberingPolicy.lua

1 ---------------------------------
2 --! @file NodeNumberingPolicy.lua
3 --! @brief マネージャノード内の名前付けポリシー
4 ---------------------------------
5
6
7 --[[
8 Copyright (c) 2017 Nobuhiko Miyamoto
9 ]]
10
11 local NodeNumberingPolicy= {}
12 --_G["openrtm.NodeNumberingPolicy"] = NodeNumberingPolicy
13
14 local Factory = require "openrtm.Factory"
15 local NumberingPolicy = require "openrtm.NumberingPolicy"
16 local NumberingPolicyBase = require "openrtm.NumberingPolicyBase"
17 local NumberingPolicyFactory = NumberingPolicyBase.NumberingPolicyFactory
18 local StringUtil = require "openrtm.StringUtil"
19
20
21 NodeNumberingPolicy.new = function()
22     local obj = {}
23     setmetatable(obj, {__index=NumberingPolicy.new()})
24     local Manager = require "openrtm.Manager"
25     obj._mgr = Manager:instance()
26
27     function obj:onCreate(_obj)
28         local num = 0
29         while true do
30             local num_str = tostring(num)
31    
32             local name = _obj:getTypeName()..num_str
33          
34             if not self:find(name) then
35                 return num_str
36             else
37                 num = num+1
38             end
39         end
40         return tostring(num)
41     end
42     function obj:onDelete(_obj)
43     end
44     function obj:find(name)
45         local rtcs = {}
46         local rtc_name = "rtcloc://*/*/"
47         rtc_name = rtc_name..name
48            local rtcs = self._mgr:getNaming():string_to_component(rtc_name)
49     
50         if #rtcs > 0 then
51             return true
52         else
53             return false
54         end
55     end
56     return obj
57 end
58
59
60 NodeNumberingPolicy.Init = function()
61     NumberingPolicyFactory:instance():addFactory("node_unique",
62         NodeNumberingPolicy.new,
63         Factory.Delete)
64 end
65
66
67 return NodeNumberingPolicy

File lua\openrtm\NumberingPolicy.lua

1 ---------------------------------
2 --! @file NumberingPolicy.lua
3 --! @brief 名前付けポリシー基底クラス、プロセス内の名前付けポリシー定義
4 ---------------------------------
5
6
7 --[[
8 Copyright (c) 2017 Nobuhiko Miyamoto
9 ]]
10
11 local NumberingPolicy= {}
12 --_G["openrtm.NumberingPolicy"] = NumberingPolicy
13
14 local Factory = require "openrtm.Factory"
15 local NumberingPolicyBase = require "openrtm.NumberingPolicyBase"
16 local NumberingPolicyFactory = NumberingPolicyBase.NumberingPolicyFactory
17 local StringUtil = require "openrtm.StringUtil"
18
19
20 NumberingPolicy = {}
21 -- 名前付けポリシー基底オブジェクト初期化
22 -- @return 名前付けポリシーオブジェクト
23 NumberingPolicy.new = function()
24     local obj = {}
25     function obj:onCreate(obj)
26     end
27     function obj:onDelete(obj)
28     end
29     return obj
30 end
31
32
33 NumberingPolicy.ProcessUniquePolicy = {}
34
35 -- プロセス内名前付けポリシー定義オブジェクト初期化
36 -- @return 名前付けポリシーオブジェクト
37 NumberingPolicy.ProcessUniquePolicy.new = function()
38     local obj = {}
39     obj._num = 0
40     obj._objects = {}
41     setmetatable(obj, {__index=NumberingPolicy.new()})
42     -- RTCへの名前付け
43     -- @param obj RTC
44     -- @return 名前
45     function obj:onCreate(_obj)
46         self._num = self._num + 1
47         local pos = self:find(nil)
48         if pos < 0 then
49             pos = 1
50         end
51         self._objects[pos] = _obj
52         return StringUtil.otos(pos-1)
53     end
54     -- RTCの登録解除
55     -- @param obj RTC
56     function obj:onDelete(_obj)
57         local pos = self:find(_obj)
58         if pos >= 0 then
59             self._objects[pos] = nil
60             self._num = self._num - 1
61         end
62     end
63     -- RTCの番号取得
64     -- @param obj RTC
65     -- @return 番号
66     function obj:find(_obj)
67         for i = 1, #self._objects + 1 do
68             local obj_ = self._objects[i]
69             if obj_ == _obj then
70                 return i
71             end
72         end
73         return -1
74     end
75     return obj
76 end
77
78 -- プロセス内名前付けポリシー生成ファクトリ登録
79 NumberingPolicy.ProcessUniquePolicy.Init = function()
80     NumberingPolicyFactory:instance():addFactory("process_unique",
81         NumberingPolicy.ProcessUniquePolicy.new,
82         Factory.Delete)
83 end
84
85
86 return NumberingPolicy

File lua\openrtm\NumberingPolicyBase.lua

1 ---------------------------------
2 --! @file NumberingPolicyBase.lua
3 --! @brief 名前付けポリシー生成ファクトリの定義
4 ---------------------------------
5
6
7 --[[
8 Copyright (c) 2017 Nobuhiko Miyamoto
9 ]]
10
11 local NumberingPolicyBase= {}
12 --_G["openrtm.NumberingPolicyBase"] = NumberingPolicyBase
13
14 local GlobalFactory = require "openrtm.GlobalFactory"
15 local Factory = GlobalFactory.Factory
16
17 NumberingPolicyBase.new = function()
18     local obj = {}
19     function obj:onCreate(object)
20     end
21     function obj:onDelete(object)
22     end
23     return obj
24 end
25
26
27 NumberingPolicyBase.NumberingPolicyFactory = {}
28 setmetatable(NumberingPolicyBase.NumberingPolicyFactory, {__index=Factory.new()})
29
30 function NumberingPolicyBase.NumberingPolicyFactory:instance()
31     return self
32 end
33
34 return NumberingPolicyBase

File lua\openrtm\NVUtil.lua

1 ---------------------------------
2 --! @file NVUtil.lua
3 --! @brief NameValeヘルパ関数
4 ---------------------------------
5
6
7 --[[
8 Copyright (c) 2017 Nobuhiko Miyamoto
9 ]]
10
11 local NVUtil= {}
12 --_G["openrtm.NVUtil"] = NVUtil
13
14 local oil = require "oil"
15 local CORBA_SeqUtil = require "openrtm.CORBA_SeqUtil"
16 local StringUtil = require "openrtm.StringUtil"
17
18 -- NameValue生成
19 -- @param name キー
20 -- @param value 値
21 -- @return NameValue
22 NVUtil.newNV = function(name, value)
23     return {name=name, value=value}
24 end
25
26 -- プロパティからNameValueをコピーする
27 -- @param nv NameValue
28 -- @param prop プロパティ
29 NVUtil.copyFromProperties = function(nv, prop)
30     local keys = prop:propertyNames()
31     local keys_len = #keys
32     local nv_len = #nv
33     if nv_len > 0 then
34         for i = 1,nv_len do
35             nv[i] = nil
36         end
37     end
38
39     for i = 1, keys_len do
40         table.insert(nv, NVUtil.newNV(keys[i], prop:getProperty(keys[i])))
41     end
42 end
43
44 -- 文字列をRTC::ReturnCode_tに変換
45 -- @param ret_code リターンコード(文字列)
46 -- @return リターンコード
47 NVUtil.getReturnCode = function(ret_code)
48     --print(ret_code)
49     if type(ret_code) == "string" then
50         local Manager = require "openrtm.Manager"
51         local _ReturnCode_t = Manager:instance():getORB().types:lookup("::RTC::ReturnCode_t").labelvalue
52         if ret_code == "RTC_OK" then
53             return _ReturnCode_t.RTC_OK
54         elseif ret_code == "RTC_ERROR" then
55             return _ReturnCode_t.RTC_ERROR
56         elseif ret_code == "BAD_PARAMETER" then
57             return _ReturnCode_t.BAD_PARAMETER
58         elseif ret_code == "UNSUPPORTED" then
59             return _ReturnCode_t.UNSUPPORTED
60         elseif ret_code == "OUT_OF_RESOURCES" then
61             return _ReturnCode_t.OUT_OF_RESOURCES
62         elseif ret_code == "PRECONDITION_NOT_MET" then
63             return _ReturnCode_t.PRECONDITION_NOT_MET
64         end
65     end
66     return ret_code
67 end
68
69 -- 文字列をOpenRTM::PortStatusに変換
70 -- @param ret_code ポートステータス(文字列)
71 -- @return ポートステータス
72 NVUtil.getPortStatus = function(ret_code)
73     --print(ret_code)
74     if type(ret_code) == "string" then
75         local Manager = require "openrtm.Manager"
76         local _PortStatus = Manager:instance():getORB().types:lookup("::OpenRTM::PortStatus").labelvalue
77
78         if ret_code == "PORT_OK" then
79             return _PortStatus.PORT_OK
80         elseif ret_code == "PORT_ERROR" then
81             return _PortStatus.PORT_ERROR
82         elseif ret_code == "BUFFER_FULL" then
83             return _PortStatus.BUFFER_FULL
84         elseif ret_code == "BUFFER_EMPTY" then
85             return _PortStatus.BUFFER_EMPTY
86         elseif ret_code == "BUFFER_TIMEOUT" then
87             return _PortStatus.BUFFER_TIMEOUT
88         elseif ret_code == "UNKNOWN_ERROR" then
89             return _PortStatus.UNKNOWN_ERROR
90         end
91     end
92     return ret_code
93 end
94
95 -- 文字列をRTC::PortStatusに変換
96 -- @param ret_code ポートステータス(文字列)
97 -- @return ポートステータス
98 NVUtil.getPortStatus_RTC = function(ret_code)
99     --print(ret_code)
100     if type(ret_code) == "string" then
101         local Manager = require "openrtm.Manager"
102         local _PortStatus = Manager:instance():getORB().types:lookup("::RTC::PortStatus").labelvalue
103
104         if ret_code == "PORT_OK" then
105             return _PortStatus.PORT_OK
106         elseif ret_code == "PORT_ERROR" then
107             return _PortStatus.PORT_ERROR
108         elseif ret_code == "BUFFER_FULL" then
109             return _PortStatus.BUFFER_FULL
110         elseif ret_code == "BUFFER_EMPTY" then
111             return _PortStatus.BUFFER_EMPTY
112         elseif ret_code == "BUFFER_TIMEOUT" then
113             return _PortStatus.BUFFER_TIMEOUT
114         elseif ret_code == "UNKNOWN_ERROR" then
115             return _PortStatus.UNKNOWN_ERROR
116         end
117     end
118     return ret_code
119 end
120
121
122 -- NameValueからプロパティにコピーする
123 -- @param prop プロパティ
124 -- @param nvlist NameValue
125 NVUtil.copyToProperties = function(prop, nvlist)
126     for i, nv in ipairs(nvlist) do
127         --print(i,nv.value)
128         local val = NVUtil.any_from_any(nv.value)
129         --print(val)
130         prop:setProperty(nv.name,val)
131     end
132 end
133
134 local nv_find = {}
135
136 -- NaveValueを検索するための関数オブジェクト初期化
137 -- return NaveValueを検索するための関数オブジェクト
138 nv_find.new = function(name)
139     local obj = {}
140     obj._name  = name
141     -- NameValueが指定名と一致するかを判定
142     -- @param self 自身のオブジェクト
143     -- @param nv NameValue
144     -- @return true:一致、false:不一致
145     local call_func = function(self, nv)
146         --print(self._name, nv.name)
147         return (self._name == nv.name)
148     end
149     setmetatable(obj, {__call=call_func})
150     return obj
151 end
152
153 -- 名前からNameValueを取得
154 -- @param nv NameValueのリスト
155 -- @param name 要素名
156 -- @return 一致したNamValueの配列番号
157 NVUtil.find_index = function(nv, name)
158     return CORBA_SeqUtil.find(nv, nv_find.new(name))
159 end
160
161 -- NameValueのリストに指定名、値を追加
162 -- 既に指定名のNameValueが存在する場合は上書き
163 -- ","で区切る値の場合は後ろに追加
164 -- @param nv NameValueのリスト
165 -- @param _name 要素名
166 -- @param _value 値
167 NVUtil.appendStringValue = function(nv, _name, _value)
168     local index = NVUtil.find_index(nv, _name)
169     local tmp_nv = nv[index]
170     if tmp_nv ~= nil then
171         local tmp_str = NVUtil.any_from_any(tmp_nv.value)
172         local values = StringUtil.split(tmp_str,",")
173         local find_flag = false
174         for i, val in ipairs(values) do
175             if val == _value then
176                 find_flag = true
177             end
178         end
179         if not find_flag then
180             tmp_str = tmp_str..", "
181             tmp_str = tmp_str.._value
182             tmp_nv.value = tmp_str
183         end
184     else
185         table.insert(nv,{name=_name,value=_value})
186     end
187 end
188
189 -- NameValueのリストを連結する
190 -- @param dest 連結先のNameValueのリスト
191 -- @param src 連結元のNameValueのリスト
192 NVUtil.append = function(dest, src)
193     for i, val in ipairs(src) do
194         table.insert(dest, val)
195     end
196 end
197
198
199 -- NameValueリストの指定名の値が指定文字列と一致するかを判定
200 -- @param nv NameValueリスト
201 -- @param name 要素名
202 -- @param value 値(文字列)
203 -- @return true:一致、false:不一致、指定要素がない
204 NVUtil.isStringValue = function(nv, name, value)
205     --print(NVUtil.toString(nv, name))
206     if NVUtil.isString(nv, name) then
207         if NVUtil.toString(nv, name) == value then
208             return true
209         end
210     end
211     return false
212 end
213
214 -- NameValueリストから指定要素の値を取得
215 -- @param nv NameValueリスト
216 -- @param name 要素名
217 -- @return 指定要素
218 NVUtil.find = function(nv, name)
219     local index = CORBA_SeqUtil.find(nv, nv_find.new(name))
220     if nv[index] ~= nil then
221         return nv[index].value
222     else
223         return nil
224     end
225 end
226
227 -- オブジェクトリファレンスの一致を判定
228 -- @param obj1 オブジェクト1
229 -- @param obj2 オブジェクト2
230 -- @param obj1_ref オブジェクト1のリファレンス
231 -- @param obj2_ref オブジェクト2のリファレンス
232 -- @return true:一致、false:不一致
233 NVUtil._is_equivalent = function(obj1, obj2, obj1_ref, obj2_ref)
234     if oil.VERSION == "OiL 0.4 beta" then
235         if obj1._is_equivalent == nil then
236             if obj2._is_equivalent == nil then
237                 return obj1_ref(obj1):_is_equivalent(obj2_ref(obj2))
238             else
239                 return obj1_ref(obj1):_is_equivalent(obj2)
240             end
241         else
242             if obj2._is_equivalent == nil then
243
244                 return obj1:_is_equivalent(obj2_ref(obj2))
245             else
246                 return obj1:_is_equivalent(obj2)
247             end
248         end
249     elseif oil.VERSION == "OiL 0.5" then
250         if obj1._is_equivalent == nil then
251
252             obj1 = obj1_ref(obj1)
253         end
254         if obj2._is_equivalent == nil then
255             obj2 = obj2_ref(obj2)
256         end
257         --print(obj1,obj2,(obj1 == obj2))
258         if obj1._is_equivalent == nil or obj2._is_equivalent == nil then
259             return (obj1 == obj2)
260         else
261             return obj1:_is_equivalent(obj2)
262         end
263     elseif oil.VERSION == "OiL 0.6" then
264         if obj1._is_equivalent == nil then
265
266             obj1 = obj1_ref(obj1)
267         end
268         if obj2._is_equivalent == nil then
269             obj2 = obj2_ref(obj2)
270         end
271         if obj1._is_equivalent == nil and obj2._is_equivalent == nil then
272             return (obj1 == obj2)
273         else
274             if obj1._is_equivalent ~= nil then
275                 return obj1:_is_equivalent(obj2)
276             else
277                 return obj2:_is_equivalent(obj1)
278             end
279         end
280     end
281 end
282
283 -- 指定変数がanyの場合に値を取り出す
284 -- @param value 変数
285 -- @return 取り出した値
286 NVUtil.any_from_any = function(value)
287     if type(value) == "table" then
288         if value._anyval ~= nil then
289             return value._anyval
290         end
291     end
292     return value
293 end
294
295 -- NameValueリストを表示用文字列に変換
296 -- @param nv NameValueリスト
297 -- @return 文字列
298 NVUtil.dump_to_stream = function(nv)
299     local out = ""
300     for i, n in ipairs(nv) do
301         local val = NVUtil.any_from_any(nv[i].value)
302         if type(val) == "string" then
303             out = out..n.name..": "..val.."\n"
304         else
305             out = out..n.name..": not a string value \n"
306         end
307     end
308     return out
309 end
310
311 -- NameValueリストの指定要素を文字列に変換
312 -- @param nv NameValueリスト
313 -- @param name 要素名
314 -- @return 文字列
315 NVUtil.toString = function(nv, name)
316     if name == nil then
317         return NVUtil.dump_to_stream(nv)
318     end
319
320     local str_value = ""
321     local ret_value = NVUtil.find(nv, name)
322     if ret_value ~= nil then
323         local val = NVUtil.any_from_any(ret_value)
324         if type(val) == "string" then
325             str_value = val
326         end
327     end
328     return str_value
329 end
330
331 -- NameValueの指定要素が文字列かを判定
332 -- @param nv NameValueリスト
333 -- @param name 要素名
334 -- @return true:文字列、false:文字列以外
335 NVUtil.isString = function(nv, name)
336     local value = NVUtil.find(nv, name)
337     if value ~= nil then
338         local val = NVUtil.any_from_any(value)
339         return (type(val) == "string")
340     else
341         return false
342     end
343 end
344
345
346 -- 文字列をCosNamingのBindingTypeに変換
347 -- @param binding_type バインディング型(文字列)
348 -- @return バインディング型
349 NVUtil.getBindingType = function(binding_type)
350     if type(binding_type) == "string" then
351         local Manager = require "openrtm.Manager"
352         local _BindingType = Manager:instance():getORB().types:lookup("::CosNaming::BindingType").labelvalue
353
354         if binding_type == "ncontext" then
355             return _BindingType.ncontext
356         elseif binding_type == "nobject" then
357             return _BindingType.nobject
358         end
359     end
360     return binding_type
361 end
362
363
364 -- 文字列をRTCの状態に変換
365 -- @param state RTCの状態(文字列)
366 -- @return RTCの状態
367 NVUtil.getLifeCycleState = function(state)
368     --print(state)
369     if type(state) == "string" then
370         local Manager = require "openrtm.Manager"
371         local _LifeCycleState = Manager:instance():getORB().types:lookup("::RTC::LifeCycleState").labelvalue
372         if state == "CREATED_STATE" then
373             return _LifeCycleState.CREATED_STATE
374         elseif state == "INACTIVE_STATE" then
375             return _LifeCycleState.INACTIVE_STATE
376         elseif state == "ACTIVE_STATE" then
377             return _LifeCycleState.ACTIVE_STATE
378         elseif state == "ERROR_STATE" then
379             return _LifeCycleState.ERROR_STATE
380         end
381     end
382     return state
383 end
384
385 -- CORBAオブジェクトの生存確認
386 -- @param _obj CORBAオブジェクト
387 -- @return false:生存
388 NVUtil._non_existent = function(_obj)
389     --print(_obj._non_existent)
390     if _obj._non_existent == nil then
391         return false
392     else
393         local ret = true
394         local success, exception = oil.pcall(
395             function()
396                 ret = _obj:_non_existent()
397         end)
398         return ret
399     end
400 end
401
402
403 return NVUtil

File lua\openrtm\ObjectManager.lua

1 ---------------------------------
2 --! @file ObjectManager.lua
3 --! @brief オブジェクトマネージャ定義
4 ---------------------------------
5
6
7 --[[
8 Copyright (c) 2017 Nobuhiko Miyamoto
9 ]]
10
11 local ObjectManager= {}
12 --_G["openrtm.ObjectManager"] = ObjectManager
13
14
15 -- オブジェクトマネージャ初期化
16 -- @param predicate 一致判定関数オブジェクト
17 -- @return オブジェクトマネージャ
18 ObjectManager.new = function(predicate)
19     local obj = {}
20     obj._objects = {} --self.Objects()
21     obj._predicate = predicate
22     -- オブジェクト登録
23     -- @param object オブジェクト
24     -- @return true:登録成功、false:登録失敗
25     function obj:registerObject(object)
26         local predi = self._predicate({factory=object})
27         for i, _obj in ipairs(self._objects) do
28             if predi(_obj) == true then
29                 return false
30             end
31         end
32         --print(#self._objects)
33         table.insert(self._objects, object)
34         --print(#self._objects)
35         return true
36     end
37     -- オブジェクト登録解除
38     -- @param id ID
39     -- @return 登録解除したオブジェクト
40     function obj:unregisterObject(id)
41         local predi = self._predicate({name=id})
42         for i, _obj in ipairs(self._objects) do
43             if predi(_obj) == true then
44                 local ret = _obj
45                 table.remove(self._objects, i)
46                 return ret
47             end
48         end
49         return nil
50     end
51     -- 指定関数を登録オブジェクト全てに実行
52     -- @param p 関数オブジェクト初期化関数
53     -- @return 関数オブジェクト
54     function obj:for_each(p)
55         local predi = p()
56         for i, _obj in ipairs(self._objects) do
57             predi(_obj)
58         end
59         return predi
60     end
61     -- idからオブジェクト検索
62     -- @param id ID
63     -- @return オブジェクト
64     function obj:find(id)
65         --print(id)
66         local predi = nil
67         if type(id) == "string" then
68             predi = self._predicate({name=id})
69         else
70             predi = self._predicate({prop=id})
71         end
72         for i, _obj in ipairs(self._objects) do
73             if predi(_obj) then
74                 return _obj
75             end
76         end
77         return nil
78     end
79     -- 登録オブジェクト一覧取得
80     -- @return 登録オブジェクト一覧
81     function obj:getObjects()
82         return self._objects
83     end
84
85     return obj
86 end
87
88
89 return ObjectManager

File lua\openrtm\OpenHRPExecutionContext.lua

Full coverage

File lua\openrtm\OutPort.lua

1 ---------------------------------
2 --! @file OutPort.lua
3 --! @brief アウトポート定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local OutPort= {}
11 --_G["openrtm.OutPort"] = OutPort
12
13
14 local TimeValue = require "openrtm.TimeValue"
15 local OutPortBase = require "openrtm.OutPortBase"
16 local DataPortStatus = require "openrtm.DataPortStatus"
17
18 -- データ変数に時刻を設定する
19 -- @param data データ変数
20 OutPort.setTimestamp = function(data)
21     local tm = TimeValue.new(os.time())
22     data.tm.sec  = tm:sec()
23     data.tm.nsec = tm:usec() * 1000
24 end
25
26 -- アウトポート初期化
27 -- @param name ポート名
28 -- @param value データ変数
29 -- @param data_type データ型
30 -- @param buffer バッファ
31 -- アウトポート
32 OutPort.new = function(name, value, data_type, buffer)
33     local obj = {}
34
35     setmetatable(obj, {__index=OutPortBase.new(name, data_type)})
36
37     obj._value          = value
38     obj._OnWrite        = nil
39     obj._OnWriteConvert = nil
40     
41     function obj:name()
42         return self._name
43     end
44     
45     -- データ書き込み
46     -- @param value 送信データ
47     -- @return true:送信成功、false:送信失敗
48     function obj:write(value)
49         if value == nil then
50             value = self._value
51         end
52         --print(self._value.data)
53
54
55         if self._OnWrite ~= nil then
56             self._OnWrite:call(value)
57         end
58
59         local conn_size = #self._connectors
60         if conn_size == 0 then
61             return false
62         end
63
64
65
66         if self._OnWriteConvert ~= nil then
67             value = self._OnWriteConvert:call(value)
68         end
69
70         local result = true
71
72         for i, con in ipairs(self._connectors) do
73             local ret = con:write({_data=value, _type=self._data_type})
74             if ret ~= DataPortStatus.PORT_OK then
75                 result = false
76                 if ret == DataPortStatus.CONNECTION_LOST then
77                     self:disconnect(con:id())
78                 end
79             end
80         end
81
82         return result
83     end
84     -- データ書き込み時コールバック関数の設定
85     -- @param on_write コールバック関数
86     function obj:setOnWrite(on_write)
87         self._OnWrite = on_write
88     end
89     -- データ変換関数の設定
90     -- @param on_wconvert データ変換関数
91     function obj:setOnWriteConvert(on_wconvert)
92         self._OnWriteConvert = on_wconvert
93     end
94     -- データ型取得
95     -- @return データ型
96     function obj:getPortDataType()
97         return self._data_type
98     end
99
100
101     return obj
102 end
103
104
105 return OutPort

File lua\openrtm\OutPortBase.lua

1 ---------------------------------
2 --! @file OutPortBase.lua
3 --! @brief アウトポート基底クラス定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local OutPortBase= {}
11 --_G["openrtm.OutPortBase"] = OutPortBase
12
13 local oil = require "oil"
14
15 local CORBA_SeqUtil = require "openrtm.CORBA_SeqUtil"
16 local Properties = require "openrtm.Properties"
17 local ConnectorListener = require "openrtm.ConnectorListener"
18 local ConnectorListeners = ConnectorListener.ConnectorListeners
19 local PublisherBase = require "openrtm.PublisherBase"
20 local PublisherFactory = PublisherBase.PublisherFactory
21 local PortBase = require "openrtm.PortBase"
22 local StringUtil = require "openrtm.StringUtil"
23
24
25 local ConnectorDataListenerType = ConnectorListener.ConnectorDataListenerType
26 local ConnectorListenerType = ConnectorListener.ConnectorListenerType
27 local ConnectorDataListener = ConnectorListener.ConnectorDataListener
28 local ConnectorListener = ConnectorListener.ConnectorListener
29
30
31 local InPortConsumer = require "openrtm.InPortConsumer"
32 local InPortConsumerFactory = InPortConsumer.InPortConsumerFactory
33 local OutPortProvider = require "openrtm.OutPortProvider"
34 local OutPortProviderFactory = OutPortProvider.OutPortProviderFactory
35
36 local NVUtil = require "openrtm.NVUtil"
37
38 local ConnectorBase = require "openrtm.ConnectorBase"
39 local ConnectorInfo = ConnectorBase.ConnectorInfo
40
41 local OutPortPushConnector = require "openrtm.OutPortPushConnector"
42 local OutPortPullConnector = require "openrtm.OutPortPullConnector"
43
44 -- アウトポート基底オブジェクト初期化
45 -- @param name ポート名
46 -- @param data_type データ型
47 -- @return アウトポート
48 OutPortBase.new = function(name, data_type)
49  local obj = {}
50  setmetatable(obj, {__index=PortBase.new(name)})
51  local Manager = require "openrtm.Manager"
52  obj._ReturnCode_t = Manager:instance():getORB().types:lookup("::RTC::ReturnCode_t").labelvalue
53
54  obj._rtcout = Manager:instance():getLogbuf(name)
55  obj._rtcout:RTC_DEBUG("Port name: "..name)
56
57  --local svr = Manager:instance():getORB():newservant(obj, nil, "IDL:omg.org/RTC/PortService:1.0")
58  --local str = Manager:instance():getORB():tostring(svr)
59  --obj._objref = Manager:instance():getORB():newproxy(str,"IDL:omg.org/RTC/PortService:1.0")
60  --obj._profile.port_ref = obj._objref
61
62
63
64     obj._rtcout:RTC_DEBUG("setting port.port_type: DataOutPort")
65     obj:addProperty("port.port_type", "DataOutPort")
66
67  local _data_type = string.sub(data_type, 3)
68  _data_type = string.gsub(_data_type, "::", "/")
69  _data_type = "IDL:".._data_type..":1.0"
70     obj._rtcout:RTC_DEBUG("setting dataport.data_type: "..tostring(data_type))
71     obj:addProperty("dataport.data_type", _data_type)
72
73
74     local factory = PublisherFactory:instance()
75     local pubs = StringUtil.flatten(factory:getIdentifiers())
76  pubs = StringUtil.eraseHeadBlank(pubs)
77
78
79
80     obj._rtcout:RTC_DEBUG("available subscription_type: "..pubs)
81     obj:addProperty("dataport.subscription_type", pubs)
82     obj:addProperty("dataport.io_mode", pubs)
83
84     obj._properties    = Properties.new()
85     obj._name          = name
86     obj._connectors    = {}
87     obj._consumers     = {}
88     obj._providerTypes = ""
89     obj._consumerTypes = ""
90  obj._data_type = data_type
91
92
93     obj._listeners = ConnectorListeners.new()
94
95  -- 初期化時にプロパティを設定する
96  -- @param prop プロパティ
97  function obj:init(prop)
98   self._rtcout:RTC_TRACE("init()")
99   self:createRef()
100
101   self._properties:mergeProperties(prop)
102
103
104   self:configure()
105
106
107   self:initConsumers()
108   self:initProviders()
109
110
111   local num = tonumber(self._properties:getProperty("connection_limit","-1"))
112   if num == nil then
113    self._rtcout:RTC_ERROR("invalid connection_limit value: "..self._properties:getProperty("connection_limit"))
114   end
115   self:setConnectionLimit(num)
116
117     end
118     -- 未実装
119  function obj:configure()
120  end
121     -- 利用可能なサービスコンシューマ一覧初期化
122     -- InPortConsumerFactoryからサービスコンシューマ一覧を取得する
123     -- 「consumer_types」のプロパティが「all」の場合は、
124     -- 利用可能なサービスコンシューマを全て利用可能にする
125  function obj:initConsumers()
126   self._rtcout:RTC_TRACE("initConsumers()")
127
128
129   local factory = InPortConsumerFactory:instance()
130   local consumer_types = factory:getIdentifiers()
131   --print(StringUtil.flatten(consumer_types))
132   self._rtcout:RTC_PARANOID("available InPortConsumer: "..StringUtil.flatten(consumer_types))
133   local tmp_str = StringUtil.normalize(self._properties:getProperty("consumer_types"))
134   --print(self._properties:getProperty("consumer_types"))
135
136   if self._properties:hasKey("consumer_types") and tmp_str  ~= "all" then
137    self._rtcout:RTC_DEBUG("allowed consumers: "..self._properties:getProperty("consumer_types"))
138
139    local temp_types = consumer_types
140    consumer_types = {}
141    local active_types = StringUtil.split(self._properties:getProperty("consumer_types"), ",")
142
143    table.sort(temp_types)
144    table.sort(active_types)
145
146    consumer_types = temp_types
147
148    for i, v in ipairs(active_types) do
149     consumer_types[#consumer_types+1] = v
150    end
151
152   end
153
154
155
156
157   if #consumer_types > 0 then
158    self._rtcout:RTC_PARANOID("dataflow_type push is supported")
159    self:appendProperty("dataport.dataflow_type", "push")
160    for i, consumer_type in ipairs(consumer_types) do
161     self:appendProperty("dataport.interface_type",consumer_type)
162    end
163   end
164
165
166
167   self._consumerTypes = consumer_types
168  end
169  -- 利用可能なサービスプロバイダ一覧初期化
170  -- OutPortProviderFactoryからサービスプロバイダ一覧を取得する
171     -- 「provider_types」のプロパティが「all」の場合は、
172     -- 利用可能なサービスプロバイダを全て利用可能にする
173  function obj:initProviders()
174   self._rtcout:RTC_TRACE("initProviders()")
175
176
177   local factory = OutPortProviderFactory:instance()
178   local provider_types  = factory:getIdentifiers()
179   self._rtcout:RTC_PARANOID("available OutPortProviders: "..StringUtil.flatten(provider_types))
180   local tmp_str = StringUtil.normalize(self._properties:getProperty("provider_types"))
181   if self._properties:hasKey("provider_types") and tmp_str  ~= "all" then
182    self._rtcout:RTC_DEBUG("allowed providers: "..self._properties:getProperty("allowed"))
183
184    local temp_types = provider_types
185    provider_types = {}
186    local active_types = StringUtil.split(self._properties:getProperty("provider_types"), ",")
187
188    table.sort(temp_types)
189    table.sort(active_types)
190
191    provider_types = temp_types
192
193    for i, v in ipairs(active_types) do
194     provider_types[#provider_types+1] = v
195    end
196   end
197
198
199
200   if #provider_types > 0 then
201    self._rtcout:RTC_PARANOID("dataflow_type pull is supported")
202    self:appendProperty("dataport.dataflow_type", "pull")
203    for i, provider_type in ipairs(provider_types) do
204     self:appendProperty("dataport.interface_type",provider_type)
205    end
206   end
207
208   self._providerTypes = provider_types
209  end
210
211  -- コネクタプロファイルからインターフェース取得
212  -- push型の場合はコンシューマ生成して、コネクタを生成する
213  -- @param cprof コネクタプロファイル
214  -- コネクタプロファイルの以下のノードからプロパティを取得
215  -- dataport
216  -- dataport.outport
217  -- @return リターンコード
218  -- RTC_OK:正常終了
219  -- BAD_PARAMETER:コンシューマ生成失敗、不正なデータフロー型
220  -- RTC_ERROR:コネクタ生成失敗
221  function obj:subscribeInterfaces(cprof)
222   self._rtcout:RTC_TRACE("subscribeInterfaces()")
223
224
225
226   --print(self._properties)
227
228   local prop = Properties.new(self._properties)
229
230
231   local conn_prop = Properties.new()
232
233   NVUtil.copyToProperties(conn_prop, cprof.properties)
234   --print(cprof.properties[1].value)
235
236
237   prop:mergeProperties(conn_prop:getNode("dataport"))
238
239
240   prop:mergeProperties(conn_prop:getNode("dataport.outport"))
241
242
243   local dflow_type = StringUtil.normalize(prop:getProperty("dataflow_type"))
244   local profile = ConnectorInfo.new(cprof.name,
245           cprof.connector_id,
246           CORBA_SeqUtil.refToVstring(cprof.ports),
247           prop)
248
249   --[[local success, exception = oil.pcall(
250    function()
251     print(prop)
252    end)
253   print(exception)]]
254         --print(dflow_type)
255         --print(prop)
256         --print(dflow_type)
257         --print(prop)
258         if dflow_type == "push" then
259             self._rtcout:RTC_PARANOID("dataflow_type = push .... create PushConnector")
260
261             consumer = self:createConsumer(cprof, prop)
262
263             --print(consumer)
264             if consumer == nil then
265                 return self._ReturnCode_t.BAD_PARAMETER
266             end
267
268
269             local connector = self:createConnector(cprof, prop, {consumer_ = consumer})
270             --print(connector)
271
272
273
274             if connector == nil then
275                 return self._ReturnCode_t.RTC_ERROR
276             end
277
278             local ret = connector:setConnectorInfo(profile)
279             if ret == self._ReturnCode_t.RTC_OK then
280                 self._rtcout:RTC_DEBUG("subscribeInterfaces() successfully finished.")
281             end
282
283
284             return self._ReturnCode_t.RTC_OK
285         elseif dflow_type == "pull" then
286             local conn = self:getConnectorById(cprof.connector_id)
287             if conn == nil then
288                 self._rtcout:RTC_ERROR("specified connector not found: "..cprof.connector_id)
289                 return self._ReturnCode_t.RTC_ERROR
290             end
291
292             local ret = conn:setConnectorInfo(profile)
293
294             if ret == self._ReturnCode_t.RTC_OK then
295                 self._rtcout:RTC_DEBUG("subscribeInterfaces() successfully finished.")
296             end
297
298             return ret
299         end
300
301         self._rtcout:RTC_ERROR("unsupported dataflow_type")
302
303         return self._ReturnCode_t.BAD_PARAMETER
304     end
305
306     -- プロバイダの初期化してインターフェースをコネクタプロファイルに登録
307     -- pull型の場合はプロバイダを生成して、コネクタを生成する
308     -- @param cprof コネクタプロファイル
309     -- コネクタプロファイルの以下のノードからプロパティを取得
310     -- dataport
311     -- dataport.outport
312     -- @return リターンコード
313     -- RTC_OK:正常終了
314     -- BAD_PARAMETER:プロバイダの初期化失敗、不正なデータフロー型
315     -- RTC_ERROR:コネクタ生成失敗
316     function obj:publishInterfaces(cprof)
317         self._rtcout:RTC_TRACE("publishInterfaces()")
318
319
320         local retval = self:_publishInterfaces()
321         if retval ~= self._ReturnCode_t.RTC_OK then
322             return retval
323         end
324
325
326         local prop = Properties.new(self._properties)
327
328         local conn_prop = Properties.new()
329
330         NVUtil.copyToProperties(conn_prop, cprof.properties)
331         prop:mergeProperties(conn_prop:getNode("dataport"))
332
333         prop:mergeProperties(conn_prop:getNode("dataport.outport"))
334
335
336
337         local dflow_type = StringUtil.normalize(prop:getProperty("dataflow_type"))
338
339         if dflow_type == "push" then
340             self._rtcout:RTC_PARANOID("dataflow_type = push .... do nothing")
341             return self._ReturnCode_t.RTC_OK
342
343         elseif dflow_type == "pull" then
344             self._rtcout:RTC_PARANOID("dataflow_type = pull .... create PullConnector")
345
346             provider = self:createProvider(cprof, prop)
347             if provider == nil then
348                 return self._ReturnCode_t.BAD_PARAMETER
349             end
350
351
352             local connector = self:createConnector(cprof, prop, {provider_ = provider})
353             if connector == nil then
354                 return self._ReturnCode_t.RTC_ERROR
355             end
356
357
358             provider:setConnector(connector)
359
360             self._rtcout:RTC_DEBUG("publishInterface() successfully finished.")
361             return self._ReturnCode_t.RTC_OK
362         end
363
364         self._rtcout:RTC_ERROR("unsupported dataflow_type")
365
366         return self._ReturnCode_t.BAD_PARAMETER
367     end
368
369     -- コネクタ生成
370     -- @param cprof コネクタプロファイル
371     -- @param prop プロパティ
372     -- @param args args.provider_:プロバイダ、args.consumer_:コンシューマ
373     -- @return コネクタオブジェクト
374     function obj:createConnector(cprof, prop, args)
375         local provider_ = args.provider_
376         local consumer_ = args.consumer_
377         local profile = ConnectorInfo.new(cprof.name,
378                                     cprof.connector_id,
379                                     CORBA_SeqUtil.refToVstring(cprof.ports),
380                                     prop)
381         local connector = nil
382
383         local ret = nil
384         local success, exception = oil.pcall(
385             function()
386                 if consumer_ ~= nil then
387                     connector = OutPortPushConnector.new(profile, consumer_,
388                                                         self._listeners)
389
390                 elseif provider_  ~= nil then
391                     connector = OutPortPullConnector.new(profile, provider_,
392                                                         self._listeners)
393
394                 else
395                     self._rtcout:RTC_ERROR("provider or consumer is not passed. returned 0;")
396                     ret = nil
397                     return
398                 end
399
400
401
402
403                 if consumer_ ~= nil then
404                     self._rtcout:RTC_TRACE("OutPortPushConnector created")
405                 elseif provider_ ~= nil then
406                     self._rtcout:RTC_TRACE("OutPortPullConnector created")
407                 end
408
409
410                 table.insert(self._connectors, connector)
411                 self._rtcout:RTC_PARANOID("connector push backed: "..#self._connectors)
412                 ret = connector
413                 return
414             end)
415         if not success then
416             --print(exception)
417             self._rtcout:RTC_ERROR("OutPortPushConnector creation failed")
418             self._rtcout:RTC_ERROR(exception)
419             return nil
420         end
421         return ret
422     end
423
424     -- サービスプロバイダ作成
425     -- 「interface_type」の要素にインターフェース型を指定
426     -- 「provider」のノードにプロバイダのプロパティを指定
427     -- @param cprof コネクタプロファイル
428     -- @param prop プロパティ
429     -- @return プロバイダ
430     function obj:createProvider(cprof, prop)
431
432         if prop:getProperty("interface_type") == "" or
433               not StringUtil.includes(self._providerTypes, prop:getProperty("interface_type")) then
434             self._rtcout:RTC_ERROR("no provider found")
435             self._rtcout:RTC_DEBUG("interface_type: "..prop:getProperty("interface_type"))
436             self._rtcout:RTC_DEBUG("interface_types: "..
437                                  StringUtil.flatten(self._providerTypes))
438             return nil
439         end
440
441         self._rtcout:RTC_DEBUG("interface_type: "..prop:getProperty("interface_type"))
442         local provider = OutPortProviderFactory:instance():createObject(prop:getProperty("interface_type"))
443
444         if provider ~= nil then
445             self._rtcout:RTC_DEBUG("provider created")
446             provider:init(prop:getNode("provider"))
447
448             if not provider:publishInterface(cprof.properties) then
449                 self._rtcout:RTC_ERROR("publishing interface information error")
450                 OutPortProviderFactory:instance():deleteObject(provider)
451                 return nil
452             end
453
454             return provider
455         end
456
457         self._rtcout:RTC_ERROR("provider creation failed")
458         return nil
459     end
460     
461     -- サービスコンシューマ作成
462     -- 「interface_type」の要素にインターフェース型を指定
463     -- 「consumer」のノードにコンシューマのプロパティを指定
464     -- @param cprof コネクタプロファイル
465     -- @param prop プロパティ
466     -- @return コンシューマ
467     function obj:createConsumer(cprof, prop)
468         --print(prop:getProperty("interface_type"))
469         --print(StringUtil.includes(self._consumerTypes, prop:getProperty("interface_type")))
470         if prop:getProperty("interface_type") == "" or
471             not StringUtil.includes(self._consumerTypes, prop:getProperty("interface_type")) then
472             self._rtcout:RTC_ERROR("no consumer found")
473             self._rtcout:RTC_DEBUG("interface_type: "..prop:getProperty("interface_type"))
474             self._rtcout:RTC_DEBUG("interface_types: "..StringUtil.flatten(self._consumerTypes))
475             return nil
476         end
477
478
479         self._rtcout:RTC_DEBUG("interface_type: "..prop:getProperty("interface_type"))
480         local consumer = InPortConsumerFactory:instance():createObject(prop:getProperty("interface_type"))
481
482
483         if consumer ~= nil then
484             self._rtcout:RTC_DEBUG("consumer created")
485             consumer:init(prop:getNode("consumer"))
486
487             if not consumer:subscribeInterface(cprof.properties) then
488                 self._rtcout:RTC_ERROR("interface subscription failed.")
489                 InPortConsumerFactory:instance():deleteObject(provider)
490                 return nil
491             end
492             return consumer
493         end
494
495         self._rtcout:RTC_ERROR("provider creation failed")
496         return nil
497     end
498
499     -- IDからコネクタを取得
500     -- @param id 識別子
501     -- @return コネクタ
502     function obj:getConnectorById(id)
503         self._rtcout:RTC_TRACE("getConnectorById(id = "..id..")")
504
505         for i, con in pairs(self._connectors) do
506             if id == con:id() then
507                 return con
508             end
509         end
510
511         self._rtcout:RTC_WARN("ConnectorProfile with the id("..id..") not found.")
512         return nil
513     end
514
515     -- 指定コネクタプロファイルのコネクタを削除
516     -- @param connector_profile コネクタプロファイル
517     function obj:unsubscribeInterfaces(connector_profile)
518         self._rtcout:RTC_TRACE("unsubscribeInterfaces()")
519
520         local id = connector_profile.connector_id
521         self._rtcout:RTC_PARANOID("connector_id: "..id)
522
523         for i, con in pairs(self._connectors) do
524             if id == con:id() then
525                 con:deactivate()
526                 con:disconnect()
527                 self._connectors[i] = nil
528                 self._rtcout:RTC_TRACE("delete connector: "..id)
529                 return
530             end
531         end
532
533
534         self._rtcout:RTC_ERROR("specified connector not found: "..id)
535     end
536
537     -- インターフェースのアクティブ化
538     function obj:activateInterfaces()
539         self._rtcout:RTC_TRACE("activateInterfaces()")
540         for i, con in pairs(self._connectors) do
541             con:activate()
542             self._rtcout:RTC_DEBUG("activate connector: "..
543                                 con:name().." "..con:id())
544         end
545     end
546
547     -- インターフェースの非アクティブ化
548     function obj:deactivateInterfaces()
549         self._rtcout:RTC_TRACE("deactivateInterfaces()")
550         for i, con in pairs(self._connectors) do
551             con:deactivate()
552             self._rtcout:RTC_DEBUG("deactivate connector: "..
553                                 con:name().." "..con:id())
554         end
555     end
556
557
558     function obj:addConnectorDataListener(listener_type, listener, autoclean)
559         if autoclean == nil then
560             autoclean = true
561         end
562         self._rtcout:RTC_TRACE("addConnectorDataListener()")
563
564            if listener_type < ConnectorDataListenerType.CONNECTOR_DATA_LISTENER_NUM then
565             self._rtcout:RTC_TRACE("addConnectorDataListener(%s)", ConnectorDataListener.toString(listener_type))
566               self._listeners.connectorData_[listener_type]:addListener(listener, autoclean)
567             return
568         end
569
570         self._rtcout:RTC_ERROR("addConnectorDataListener(): Unknown Listener Type")
571
572     end
573
574     function obj:removeConnectorDataListener(listener_type, listener)
575         self._rtcout:RTC_TRACE("removeConnectorDataListener()")
576
577         if listener_type < ConnectorDataListenerType.CONNECTOR_DATA_LISTENER_NUM then
578             self._rtcout:RTC_TRACE("removeConnectorDataListener(%s)", ConnectorDataListener.toString(listener_type))
579             self._listeners.connectorData_[listener_type]:removeListener(listener)
580             return
581         end
582
583         self._rtcout:RTC_ERROR("removeConnectorDataListener(): Unknown Listener Type")
584     end
585     
586
587     function obj:addConnectorListener(listener_type, listener, autoclean)
588         if autoclean == nil then
589             autoclean = true
590         end
591         self._rtcout:RTC_TRACE("addConnectorListener()")
592
593            if listener_type < ConnectorListenerType.CONNECTOR_LISTENER_NUM then
594             self._rtcout:RTC_TRACE("addConnectorListener(%s)", ConnectorListener.toString(listener_type))
595               self._listeners.connector_[listener_type]:addListener(listener, autoclean)
596             return
597         end
598
599         self._rtcout:RTC_ERROR("addConnectorListener(): Unknown Listener Type")
600
601     end
602
603     function obj:removeConnectorListener(listener_type, listener)
604         self._rtcout:RTC_TRACE("removeConnectorListener()")
605
606         if listener_type < ConnectorListenerType.CONNECTOR_LISTENER_NUM then
607             self._rtcout:RTC_TRACE("removeConnectorListener(%s)", ConnectorListener.toString(listener_type))
608             self._listeners.connector_[listener_type]:removeListener(listener)
609             return
610         end
611
612         self._rtcout:RTC_ERROR("removeConnectorListener(): Unknown Listener Type")
613     end
614     
615
616     return obj
617 end
618
619
620 return OutPortBase

File lua\openrtm\OutPortConnector.lua

Full coverage

File lua\openrtm\OutPortConsumer.lua

1 ---------------------------------
2 --! @file OutPortConsumer.lua
3 --! @brief OutPortコンシューマと生成ファクトリ定義
4 --! Pull型通信の独自インターフェース型を実装する場合は、
5 --! OutPortConsumerをメタテーブルに設定したコンシューマオブジェクトを生成する
6 ---------------------------------
7
8 --[[
9 Copyright (c) 2017 Nobuhiko Miyamoto
10 ]]
11
12 local OutPortConsumer= {}
13 --_G["openrtm.OutPortConsumer"] = OutPortConsumer
14
15 local GlobalFactory = require "openrtm.GlobalFactory"
16 local Factory = GlobalFactory.Factory
17
18 -- OutPortコンシューマオブジェクト初期化
19 -- @return OutPortコンシューマオブジェクト
20 OutPortConsumer.new = function()
21     local obj = {}
22     obj.subscribe = {}
23     -- コンシューマのインターフェース追加関数オブジェクト初期化
24     -- @param prop プロパティ
25     -- return インターフェース追加関数オブジェクト
26     obj.subscribe.new = function(prop)
27         local obj = {}
28         obj._prop = prop
29         -- インターフェース追加関数
30         -- @param self 自身のオブジェクト
31         -- @param consumer コンシューマ
32         local call_func = function(self, consumer)
33             consumer:subscribeInterface(self._prop)
34         end
35         setmetatable(obj, {__call=call_func})
36         return obj
37     end
38     obj.unsubscribe = {}
39     -- コンシューマのインターフェース削除関数オブジェクト初期化
40     -- @param prop プロパティ
41     -- return インターフェース削除オブジェクト
42     obj.unsubscribe.new = function(prop)
43         local obj = {}
44         obj._prop = prop
45         -- インターフェース削除関数
46         -- @param self 自身のオブジェクト
47         -- @param consumer コンシューマ
48         local call_func = function(self, consumer)
49             consumer:unsubscribeInterface(self._prop)
50         end
51         setmetatable(obj, {__call=call_func})
52         return obj
53     end
54     return obj
55 end
56
57
58 OutPortConsumer.OutPortConsumerFactory = {}
59 setmetatable(OutPortConsumer.OutPortConsumerFactory, {__index=Factory.new()})
60
61 function OutPortConsumer.OutPortConsumerFactory:instance()
62     return self
63 end
64
65
66 return OutPortConsumer

File lua\openrtm\OutPortDSConsumer.lua

1 ---------------------------------
2 --! @file OutPortDSConsumer.lua
3 --! @brief CorbaCdrインターフェースで通信するOutPortConsumer定義
4 --! 「data_service」のインターフェース型で利用可能
5 --! RTC.idlのPortServiceインターフェース
6 ---------------------------------
7
8 --[[
9 Copyright (c) 2017 Nobuhiko Miyamoto
10 ]]
11
12 local OutPortDSConsumer= {}
13 --_G["openrtm.OutPortDSConsumer"] = OutPortDSConsumer
14
15 local oil = require "oil"
16 local OutPortConsumer = require "openrtm.OutPortConsumer"
17 local NVUtil = require "openrtm.NVUtil"
18 local BufferStatus = require "openrtm.BufferStatus"
19 local DataPortStatus = require "openrtm.DataPortStatus"
20 local CorbaConsumer = require "openrtm.CorbaConsumer"
21
22 local Factory = require "openrtm.Factory"
23 local OutPortConsumerFactory = OutPortConsumer.OutPortConsumerFactory
24
25 local RTCUtil = require "openrtm.RTCUtil"
26
27 local ConnectorListener = require "openrtm.ConnectorListener"
28 local ConnectorListenerType = ConnectorListener.ConnectorListenerType
29 local ConnectorDataListenerType = ConnectorListener.ConnectorDataListenerType
30
31 -- CorbaCdrインターフェースのOutPortConsumerオブジェクト初期化
32 -- @return CorbaCdrインターフェースのOutPortConsumerオブジェクト
33 OutPortDSConsumer.new = function()
34     local obj = {}
35     setmetatable(obj, {__index=OutPortConsumer.new()})
36     setmetatable(obj, {__index=CorbaConsumer.new()})
37     local Manager = require "openrtm.Manager"
38     obj._PortStatus = Manager:instance():getORB().types:lookup("::RTC::PortStatus").labelvalue
39
40     obj._rtcout = Manager:instance():getLogbuf("OutPortDSConsumer")
41     obj._buffer = nil
42     obj._profile = nil
43     obj._listeners = nil
44
45     -- 初期化時にプロパティ設定
46     -- @param prop プロパティ
47     function obj:init(prop)
48         self._rtcout:RTC_TRACE("init()")
49     end
50     
51     -- バッファの設定
52     -- @param buffer バッファ
53     function obj:setBuffer(buffer)
54         self._rtcout:RTC_TRACE("setBuffer()")
55         self._buffer = buffer
56     end
57     
58     -- コールバック関数設定
59     -- @param info プロファイル
60     -- @param listeners コールバック関数
61     function obj:setListener(info, listeners)
62         self._rtcout:RTC_TRACE("setListener()")
63         self._listeners = listeners
64         self._profile = info
65     end
66
67     -- データ取得
68     -- @param data data._dataにデータを格納する
69     -- @return リターンコード
70     -- RTC_OK:getオペレーションが正常終了
71     -- CONNECTION_LOST:通信失敗
72     function obj:get(data)
73         self._rtcout:RTC_PARANOID("get()")
74
75         local ret = self._PortStatus.PORT_OK
76         local cdr_data = ""
77         local success, exception = oil.pcall(
78             function()
79                 local outportcdr = self:getObject()
80                 --print(outportcdr)
81
82                 if outportcdr ~= oil.corba.idl.null then
83                     ret,cdr_data = outportcdr:pull()
84                     ret = NVUtil.getPortStatus_RTC(ret)
85                     return
86                 end
87                     ret = DataPortStatus.CONNECTION_LOST
88                     return
89                 end)
90         if not success then
91             self._rtcout:RTC_WARN("Exception caught from OutPort.pull().")
92             self._rtcout:RTC_ERROR(exception)
93             return DataPortStatus.CONNECTION_LOST
94         end
95         --print(ret, DataPortStatus.CONNECTION_LOST)
96         if ret == self._PortStatus.PORT_OK then
97             self._rtcout:RTC_DEBUG("get() successful")
98             data._data = cdr_data
99             self:onReceived(data._data)
100             self:onBufferWrite(data._data)
101
102             if self._buffer:full() then
103                 self._rtcout:RTC_INFO("InPort buffer is full.")
104                 self:onBufferFull(data._data)
105                 self:onReceiverFull(data._data)
106             end
107
108             self._buffer:put(data._data)
109             self._buffer:advanceWptr()
110             self._buffer:advanceRptr()
111             return DataPortStatus.PORT_OK
112         end
113         return self:convertReturn(ret,data._data)
114     end
115     -- プロパティからインターフェース情報取得
116     -- オブジェクトリファレンスの設定
117     -- IOR文字列、もしくはリファレンスを取得
118     -- dataport.corba_cdr.outport_ior
119     -- dataport.corba_cdr.outport_ref
120     -- @param properties プロパティ
121     -- @return true:設定成功、false:設定失敗
122     function obj:subscribeInterface(properties)
123         self._rtcout:RTC_TRACE("subscribeInterface()")
124         if self:subscribeFromIor(properties) then
125             return true
126         end
127         if self:subscribeFromRef(properties) then
128             return true
129         end
130         return false
131     end
132     -- プロパティからインターフェース設定解除-- IOR文字列、もしくはリファレンスを取得
133     -- dataport.corba_cdr.outport_ior
134     -- dataport.corba_cdr.outport_ref
135     -- @param properties プロパティ
136     function obj:unsubscribeInterface(properties)
137         self._rtcout:RTC_TRACE("unsubscribeInterface()")
138
139         if self:unsubscribeFromIor(properties) then
140             return
141         end
142
143         self:unsubscribeFromRef(properties)
144     end
145
146     -- IOR文字列からオブジェクトリファレンス設定
147     -- @param properties プロパティ
148     -- 以下からIOR文字列取得
149     -- dataport.corba_cdr.outport_ior
150     -- @return true:設定成功、false:設定失敗
151     function obj:subscribeFromIor(properties)
152         self._rtcout:RTC_TRACE("subscribeFromIor()")
153
154         local index = NVUtil.find_index(properties,
155                                            "dataport.data_service.outport_ior")
156         --print(index)
157         if index < 0 then
158             self._rtcout:RTC_ERROR("outport_ior not found")
159             return false
160         end
161
162         local ior = ""
163         if properties[index] ~= nil then
164             ior = NVUtil.any_from_any(properties[index].value)
165         end
166
167         if ior == "" then
168             self._rtcout:RTC_ERROR("dataport.data_service.outport_ior")
169             return false
170         end
171
172         local Manager = require "openrtm.Manager"
173         local orb = Manager:instance():getORB()
174         local _obj = RTCUtil.newproxy(orb, ior,"IDL:omg.org/RTC/DataPullService:1.0")
175
176
177
178         if _obj == nil then
179             self._rtcout:RTC_ERROR("invalid IOR string has been passed")
180             return false
181         end
182
183         if not self:setObject(_obj) then
184             self._rtcout:RTC_WARN("Setting object to consumer failed.")
185             return false
186         end
187
188         return true
189     end
190
191
192
193     -- オブジェクトからオブジェクトリファレンス設定
194     -- @param properties プロパティ
195     -- 以下からリファレンスを取得
196     -- dataport.corba_cdr.outport_ref
197     -- @return true:設定成功、false:設定失敗
198     function obj:subscribeFromRef(properties)
199         self._rtcout:RTC_TRACE("subscribeFromRef()")
200         local index = NVUtil.find_index(properties,
201                                         "dataport.data_service.outport_ref")
202         if index < 0 then
203             self._rtcout:RTC_ERROR("outport_ref not found")
204             return false
205         end
206
207         local _obj = NVUtil.any_from_any(properties[index].value)
208
209         local Manager = require "openrtm.Manager"
210         local orb = Manager:instance():getORB()
211
212         _obj = orb:narrow(_obj, "IDL:omg.org/RTC/DataPullService:1.0")
213
214
215         if _obj == nil then
216             self._rtcout:RTC_ERROR("prop[outport_ref] is not objref")
217             return false
218         end
219
220
221         if not self:setObject(obj) then
222             self._rtcout:RTC_ERROR("Setting object to consumer failed.")
223             return false
224         end
225
226         return true
227     end
228
229
230
231     -- IOR文字列からオブジェクトリファレンス設定解除
232     -- @param properties プロパティ
233     -- 以下からIOR文字列取得
234     -- dataport.corba_cdr.outport_ior
235     -- @return true:設定解除成功、false:設定解除失敗
236     function obj:unsubscribeFromIor(properties)
237         self._rtcout:RTC_TRACE("unsubscribeFromIor()")
238         local index = NVUtil.find_index(properties,
239                                         "dataport.data_service.outport_ior")
240         if index < 0 then
241             self._rtcout:RTC_ERROR("outport_ior not found")
242             return false
243         end
244
245
246         ior = NVUtil.any_from_any(properties[index].value)
247
248
249         if ior == "" then
250             self._rtcout:RTC_ERROR("prop[outport_ior] is not string")
251             return false
252         end
253
254         local Manager = require "openrtm.Manager"
255         local orb = Manager:instance():getORB()
256         local var = RTCUtil.newproxy(orb, ior,"IDL:omg.org/RTC/DataPullService:1.0")
257
258         if not NVUtil._is_equivalent(self:_ptr(true), var, self:_ptr(true).getObjRef, var.getObjRef) then
259             self._rtcout:RTC_ERROR("connector property inconsistency")
260             return false
261         end
262
263         self:releaseObject()
264         return true
265     end
266
267     -- オブジェクトからオブジェクトリファレンス設定解除
268     -- @param properties プロパティ
269     -- 以下からリファレンスを取得
270     -- dataport.corba_cdr.outport_ref
271     -- @return true:設定解除成功、false:設定解除失敗
272     function obj:unsubscribeFromRef(properties)
273         self._rtcout:RTC_TRACE("unsubscribeFromRef()")
274         local index = NVUtil.find_index(properties,
275                                         "dataport.data_service.outport_ref")
276
277         if index < 0 then
278             return false
279         end
280
281
282         local _obj = NVUtil.any_from_any(properties[index].value)
283
284
285         if obj == nil then
286             return false
287         end
288
289         local obj_ptr = self:_ptr(true)
290
291         if obj_ptr == nil or not NVUtil._is_equivalent(obj_ptr, obj, obj_ptr.getObjRef, obj.getObjRef) then
292             return false
293         end
294
295         self:releaseObject()
296         return true
297     end
298
299     -- RTC::PortStatusをデータポートステータスに変換
300     function obj:convertReturn(status, data)
301         if status == self._PortStatus.PORT_OK then
302
303           return DataPortStatus.PORT_OK
304
305         elseif status == self._PortStatus.PORT_ERROR then
306             self:onSenderError()
307             return DataPortStatus.PORT_ERROR
308
309         elseif status == self._PortStatus.BUFFER_FULL then
310
311             return DataPortStatus.BUFFER_FULL
312
313         elseif status == self._PortStatus.BUFFER_EMPTY then
314             self:onSenderEmpty()
315             return DataPortStatus.BUFFER_EMPTY
316
317         elseif status == self._PortStatus.BUFFER_TIMEOUT then
318             self:onSenderTimeout()
319             return DataPortStatus.BUFFER_TIMEOUT
320
321         elseif status == self._PortStatus.UNKNOWN_ERROR then
322             self:onSenderError()
323             return DataPortStatus.UNKNOWN_ERROR
324
325         else
326             self:onSenderError()
327             return DataPortStatus.UNKNOWN_ERROR
328         end
329     end
330
331     -- バッファ書き込み時のコールバック実行
332     -- @param data データ
333     function obj:onBufferWrite(data)
334         if self._listeners ~= nil and self._profile ~= nil then
335             self._listeners.connectorData_[ConnectorDataListenerType.ON_BUFFER_WRITE]:notify(self._profile, data)
336         end
337     end
338     -- バッファフル時のコールバック実行
339     -- @param data データ
340     function obj:onBufferFull(data)
341         if self._listeners ~= nil and self._profile ~= nil then
342             self._listeners.connectorData_[ConnectorDataListenerType.ON_BUFFER_FULL]:notify(self._profile, data)
343         end
344     end
345     -- データ受信時のコールバック実行
346     -- @param data データ
347     function obj:onReceived(data)
348         if self._listeners ~= nil and self._profile ~= nil then
349             self._listeners.connectorData_[ConnectorDataListenerType.ON_RECEIVED]:notify(self._profile, data)
350         end
351     end
352     -- 受信データフルのコールバック実行
353     -- @param data データ
354     function obj:onReceiverFull(data)
355         if self._listeners ~= nil and self._profile ~= nil then
356             self._listeners.connectorData_[ConnectorDataListenerType.ON_RECEIVER_FULL]:notify(self._profile, data)
357         end
358     end
359     -- 送信データエンプティのコールバック実行
360     -- @param data データ
361     function obj:onSenderEmpty(data)
362         if self._listeners ~= nil and self._profile ~= nil then
363             self._listeners.connector_[ConnectorListenerType.ON_SENDER_EMPTY]:notify(self._profile)
364         end
365     end
366     -- 送信データ時間切れ時のコールバック実行
367     -- @param data データ
368     function obj:onSenderTimeout(data)
369         if self._listeners ~= nil and self._profile ~= nil then
370             self._listeners.connector_[ConnectorListenerType.ON_SENDER_TIMEOUT]:notify(self._profile)
371         end
372     end
373     -- 送信エラー時のコールバック実行
374     -- @param data データ
375     function obj:onSenderError(data)
376         if self._listeners ~= nil and self._profile ~= nil then
377             self._listeners.connector_[ConnectorListenerType.ON_SENDER_ERROR]:notify(self._profile)
378         end
379     end
380
381     return obj
382 end
383
384 -- OutPortDSConsumer生成ファクトリ登録関数
385 OutPortDSConsumer.Init = function()
386     OutPortConsumerFactory:instance():addFactory("data_service",
387         OutPortDSConsumer.new,
388         Factory.Delete)
389 end
390
391
392 return OutPortDSConsumer

File lua\openrtm\OutPortDSProvider.lua

1 ---------------------------------
2 --! @file OutPortDSProvider.lua
3 --! @brief CorbaCdrインターフェースで通信するOutPortProvider定義
4 --! 「data_service」のインターフェース型で利用可能
5 --! RTC.idlのPortServiceインターフェース
6 ---------------------------------
7
8 --[[
9 Copyright (c) 2017 Nobuhiko Miyamoto
10 ]]
11
12 local OutPortDSProvider= {}
13 --_G["openrtm.OutPortDSProvider"] = OutPortDSProvider
14
15 local OutPortProvider = require "openrtm.OutPortProvider"
16 local BufferStatus = require "openrtm.BufferStatus"
17
18 local Factory = require "openrtm.Factory"
19 local OutPortProviderFactory = OutPortProvider.OutPortProviderFactory
20
21 local RTCUtil = require "openrtm.RTCUtil"
22
23 local NVUtil = require "openrtm.NVUtil"
24
25 local ConnectorListener = require "openrtm.ConnectorListener"
26 local ConnectorListenerType = ConnectorListener.ConnectorListenerType
27 local ConnectorDataListenerType = ConnectorListener.ConnectorDataListenerType
28
29
30 -- CorbaCdrインターフェースのOutPortProviderオブジェクト初期化
31 -- @return CorbaCdrインターフェースのOutPortProviderオブジェクト
32 OutPortDSProvider.new = function()
33     local obj = {}
34     setmetatable(obj, {__index=OutPortProvider.new()})
35     local Manager = require "openrtm.Manager"
36     obj._PortStatus = Manager:instance():getORB().types:lookup("::RTC::PortStatus").labelvalue
37
38
39     obj:setInterfaceType("data_service")
40     obj._buffer = nil
41
42     local orb = Manager:instance():getORB()
43     obj._svr = orb:newservant(obj, nil, "IDL:omg.org/RTC/DataPullService:1.0")
44     local str = orb:tostring(obj._svr)
45     obj._objref = RTCUtil.getReference(orb, obj._svr, "IDL:omg.org/RTC/DataPullService:1.0")
46
47     table.insert(obj._properties, NVUtil.newNV("dataport.data_service.outport_ior",
48                                                     str))
49     --table.insert(obj._properties, NVUtil.newNV("dataport.data_service.outport_ref",
50     -- obj._objref))
51
52     obj._listeners = nil
53     obj._connector = nil
54     obj._profile   = nil
55
56     -- 終了処理
57     function obj:exit()
58         Manager:instance():getORB():deactivate(self._svr)
59     end
60
61     -- 初期化時にプロパティ設定
62     -- @param prop プロパティ
63     function obj:init(prop)
64     end
65
66     -- バッファ設定
67     -- @param buffer バッファ
68     function obj:setBuffer(buffer)
69         self._buffer = buffer
70     end
71
72     -- コールバック関数設定
73     -- @param info プロファイル
74     -- @param listeners コールバック関数
75     function obj:setListener(info, listeners)
76         self._profile = info
77         self._listeners = listeners
78     end
79
80     -- コネクタ設定
81     -- @param connector コネクタ
82     function obj:setConnector(connector)
83         self._connector = connector
84     end
85
86     -- データ読み込み
87     -- @return リターンコード、データ
88     -- PORT_OK:正常終了
89     -- PORT_ERROR:バッファがない
90     -- BUFFER_EMPTY:バッファが空
91     -- その他、バッファフル、タイムアウト等の戻り値
92     function obj:pull()
93         self._rtcout:RTC_PARANOID("OutPortDSProvider.get()")
94         if self._buffer == nil then
95             self:onSenderError()
96             return self._PortStatus.UNKNOWN_ERROR, ""
97         end
98
99
100         if self._buffer:empty() then
101             self._rtcout:RTC_ERROR("buffer is empty.")
102             return self._PortStatus.BUFFER_EMPTY, ""
103         end
104
105         local cdr = {_data=""}
106         local ret = self._buffer:read(cdr)
107
108         if ret == BufferStatus.BUFFER_OK then
109             if cdr._data == "" then
110                 self._rtcout:RTC_ERROR("buffer is empty.")
111                 return self._PortStatus.BUFFER_EMPTY, ""
112             end
113         end
114         return self:convertReturn(ret, cdr._data)
115     end
116
117     -- バッファ書き込み時コールバック
118     -- @param data データ
119     function obj:onBufferRead(data)
120         if self._listeners ~= nil and self._profile ~= nil then
121             self._listeners.connectorData_[ConnectorDataListenerType.ON_BUFFER_READ]:notify(self._profile, data)
122         end
123     end
124
125     -- データ送信時コールバック
126     -- @param data データ
127     function obj:onSend(data)
128         if self._listeners ~= nil and self._profile ~= nil then
129             self._listeners.connectorData_[ConnectorDataListenerType.ON_SEND]:notify(self._profile, data)
130         end
131     end
132
133     -- バッファ空時コールバック
134     function obj:onBufferEmpty()
135         if self._listeners ~= nil and self._profile ~= nil then
136             self._listeners.connector_[ConnectorListenerType.ON_BUFFER_EMPTY]:notify(self._profile)
137         end
138     end
139     -- バッファ読み込みタイムアウト時コールバック
140     function obj:onBufferReadTimeout()
141         if self._listeners ~= nil and self._profile ~= nil then
142             self._listeners.connector_[ConnectorListenerType.ON_BUFFER_READ_TIMEOUT]:notify(self._profile)
143         end
144     end
145     -- 送信データ空時コールバック
146     function obj:onSenderEmpty()
147         if self._listeners ~= nil and self._profile ~= nil then
148             self._listeners.connector_[ConnectorListenerType.ON_SENDER_EMPTY]:notify(self._profile)
149         end
150     end
151     -- データ送信タイムアウト時コールバック
152     function obj:onSenderTimeout()
153         if self._listeners ~= nil and self._profile ~= nil then
154             self._listeners.connector_[ConnectorListenerType.ON_SENDER_TIMEOUT]:notify(self._profile)
155         end
156     end
157     -- データ送信エラー時コールバック
158     function obj:onSenderError()
159         if self._listeners ~= nil and self._profile ~= nil then
160             self._listeners.connector_[ConnectorListenerType.ON_SENDER_ERROR]:notify(self._profile)
161         end
162     end
163     -- バッファステータスをRTC::PortStatusに変換
164     --コールバック呼び出し
165     -- @param status バッファステータス
166     -- @param data データ
167     -- @param ポートステータス、データ
168     function obj:convertReturn(status, data)
169         if status == BufferStatus.BUFFER_OK then
170             self:onBufferRead(data)
171             self:onSend(data)
172             return self._PortStatus.PORT_OK, data
173         elseif status == BufferStatus.BUFFER_ERROR then
174             self:onSenderError()
175             return self._PortStatus.PORT_ERROR, data
176         elseif status == BufferStatus.BUFFER_FULL then
177           return self._PortStatus.BUFFER_FULL, data
178         elseif status == BufferStatus.BUFFER_EMPTY then
179             self:onBufferEmpty()
180             self:onSenderEmpty()
181             return self._PortStatus.BUFFER_EMPTY, data
182         elseif status == BufferStatus.PRECONDITION_NOT_MET then
183             self:onSenderError()
184             return self._PortStatus.PORT_ERROR, data
185         elseif status == BufferStatus.TIMEOUT then
186             self:onBufferReadTimeout()
187             self:onSenderTimeout()
188             return self._PortStatus.BUFFER_TIMEOUT, data
189         else
190             return self._PortStatus.UNKNOWN_ERROR, data
191         end
192     end
193     function obj:getObjRef()
194         return self._objref
195     end
196
197
198
199
200     return obj
201 end
202
203 -- OutPortDSProvider生成ファクトリ登録関数
204 OutPortDSProvider.Init = function()
205     OutPortProviderFactory:instance():addFactory("data_service",
206         OutPortDSProvider.new,
207         Factory.Delete)
208 end
209
210
211 return OutPortDSProvider

File lua\openrtm\OutPortProvider.lua

1 ---------------------------------
2 --! @file OutPortProvider.lua
3 --! @brief OutPortプロバイダと生成ファクトリ定義
4 --! Pull型通信の独自インターフェース型を実装する場合は、
5 --! OutPortProviderをメタテーブルに設定したプロバイダオブジェクトを生成する
6 ---------------------------------
7
8 --[[
9 Copyright (c) 2017 Nobuhiko Miyamoto
10 ]]
11
12 local OutPortProvider= {}
13 --_G["openrtm.OutPortProvider"] = OutPortProvider
14
15 local GlobalFactory = require "openrtm.GlobalFactory"
16 local Factory = GlobalFactory.Factory
17 local NVUtil = require "openrtm.NVUtil"
18
19 -- OutPortプロバイダオブジェクト初期化
20 -- @return OutPortプロバイダオブジェクト
21 OutPortProvider.new = function()
22     local obj = {}
23     local Manager = require "openrtm.Manager"
24     obj._properties = {}
25     obj._portType         = ""
26     obj._dataType         = ""
27     obj._interfaceType    = ""
28     obj._dataflowType     = ""
29     obj._subscriptionType = ""
30     obj._rtcout = Manager:instance():getLogbuf("OutPortProvider")
31
32     -- コネクタプロファイルにインターフェース型を設定
33     -- @param prop プロパティ
34     function obj:publishInterfaceProfile(prop)
35         self._rtcout:RTC_TRACE("publishInterfaceProfile()")
36         NVUtil.appendStringValue(prop, "dataport.interface_type",
37                                           self._interfaceType)
38         NVUtil.append(prop, self._properties)
39     end
40
41     -- コネクタプロファイルに各種設定を行う
42     -- @param prop プロパティ
43     -- @return true:設定成功、false:設定失敗
44     function obj:publishInterface(prop)
45         self._rtcout:RTC_TRACE("publishInterface()")
46         if not NVUtil.isStringValue(prop,
47                                     "dataport.interface_type",
48                                     self._interfaceType) then
49             return false
50         end
51
52         NVUtil.append(prop, self._properties)
53         return true
54     end
55     -- ポート型の設定
56     -- @param port_type ポート型
57     function obj:setPortType(port_type)
58         self._portType = port_type
59     end
60     -- データ型の設定
61     -- @param port_type データ型
62     function obj:setDataType(data_type)
63         self._dataType = data_type
64     end
65     -- インターフェース型の設定
66     -- @param interface_type インターフェース型
67     function obj:setInterfaceType(interface_type)
68         self._interfaceType = interface_type
69     end
70     -- データフロー型の設定
71     -- @param dataflow_type データフロー型
72     function obj:setDataFlowType(dataflow_type)
73         self._dataflowType = dataflow_type
74     end
75     -- サブスクリプション型の設定
76     -- @param subs_type サブスクリプション型
77     function obj:setSubscriptionType(subs_type)
78         self._subscriptionType = subs_type
79     end
80     return obj
81 end
82
83 OutPortProvider.OutPortProviderFactory = {}
84 setmetatable(OutPortProvider.OutPortProviderFactory, {__index=Factory.new()})
85
86 function OutPortProvider.OutPortProviderFactory:instance()
87     return self
88 end
89
90
91 return OutPortProvider

File lua\openrtm\OutPortPullConnector.lua

1 ---------------------------------
2 --! @file OutPortPullConnector.lua
3 --! @brief Pull型通信OutPortConnector定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local OutPortPullConnector= {}
11 --_G["openrtm.OutPortPullConnector"] = OutPortPullConnector
12
13 local OutPortConnector = require "openrtm.OutPortConnector"
14 local DataPortStatus = require "openrtm.DataPortStatus"
15 local CdrBufferBase = require "openrtm.CdrBufferBase"
16 local CdrBufferFactory = CdrBufferBase.CdrBufferFactory
17 local OutPortProvider = require "openrtm.OutPortProvider"
18 local OutPortProviderFactory = OutPortProvider.OutPortProviderFactory
19
20 local ConnectorListener = require "openrtm.ConnectorListener"
21 local ConnectorListenerType = ConnectorListener.ConnectorListenerType
22
23
24 -- Pull型通信OutPortConnectorの初期化
25 -- @param info プロファイル
26 -- 「buffer」という要素名にバッファの設定を格納
27 -- @param provider プロバイダ
28 -- @param listeners コールバック
29 -- @param buffer バッファ
30 -- 指定しない場合はリングバッファを生成する
31 -- @return Pull型通信OutPortConnector
32 OutPortPullConnector.new = function(info, provider, listeners, buffer)
33     local obj = {}
34     setmetatable(obj, {__index=OutPortConnector.new(info)})
35     
36     -- データ書き込み
37     -- @param data data._dataを書き込み
38     -- @return リターンコード(バッファの書き込み結果による)
39     function obj:write(data)
40         local Manager = require "openrtm.Manager"
41
42         local cdr_data = Manager:instance():cdrMarshal(data._data, data._type)
43         --print(cdr_data)
44
45
46         if self._buffer ~= nil then
47             self._buffer:write(cdr_data)
48         else
49             return DataPortStatus.UNKNOWN_ERROR
50         end
51         return DataPortStatus.PORT_OK
52     end
53
54     -- コネクタ切断
55     -- @return リターンコード
56     function obj:disconnect()
57         self._rtcout:RTC_TRACE("disconnect()")
58         self:onDisconnect()
59
60         if self._provider ~= nil then
61             OutPortProviderFactory:instance():deleteObject(self._provider)
62             self._provider:exit()
63         end
64         self._provider = nil
65
66
67         if self._buffer ~= nil then
68             CdrBufferFactory:instance():deleteObject(self._buffer)
69         end
70         self._buffer = nil
71
72
73         return DataPortStatus.PORT_OK
74     end
75
76     -- バッファ取得
77     -- @return バッファ
78     function obj:getBuffer()
79         return self._buffer
80     end
81
82     -- アクティブ化
83     function obj:activate()
84     end
85     -- 非アクティブ化
86     function obj:deactivate()
87     end
88     -- バッファ作成
89     -- リングバッファを生成する
90     -- @param profile コネクタプロファイル
91     -- @return バッファ
92     function obj:createBuffer(info)
93         local buf_type = info.properties:getProperty("buffer_type","ring_buffer")
94         return CdrBufferFactory:instance():createObject(buf_type)
95     end
96     -- コネクタ接続時のコールバック呼び出し
97     function obj:onConnect()
98         if self._listeners ~= nil and self._profile ~= nil then
99             self._listeners.connector_[ConnectorListenerType.ON_CONNECT]:notify(self._profile)
100         end
101     end
102
103     -- コネクタ切断時のコールバック呼び出し
104     function obj:onDisconnect()
105         if self._listeners ~= nil and self._profile ~= nil then
106             self._listeners.connector_[ConnectorListenerType.ON_DISCONNECT]:notify(self._profile)
107         end
108     end
109
110
111
112
113
114
115     obj._provider = provider
116     obj._listeners = listeners
117     obj._buffer = buffer
118
119
120     obj._inPortListeners = nil
121
122
123
124     obj._value = nil
125
126     if obj._buffer == nil then
127         obj._buffer = obj:createBuffer(info)
128     end
129
130     if obj._provider == nil or obj._buffer == nil then
131         obj._rtcout:RTC_ERROR("Exeption: in OutPortPullConnector.__init__().")
132         error("")
133     end
134
135     obj._buffer:init(info.properties:getNode("buffer"))
136     obj._provider:init(info.properties)
137     obj._provider:setBuffer(obj._buffer)
138     obj._provider:setConnector(obj)
139     obj._provider:setListener(info, obj._listeners)
140     obj:onConnect()
141     return obj
142 end
143
144
145 return OutPortPullConnector

File lua\openrtm\OutPortPushConnector.lua

1 ---------------------------------
2 --! @file OutPortPushConnector.lua
3 --! @brief Push型通信OutPortConnector定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local OutPortPushConnector= {}
11 --_G["openrtm.OutPortPushConnector"] = OutPortPushConnector
12
13 --local oil = require "oil"
14 local OutPortConnector = require "openrtm.OutPortConnector"
15 local DataPortStatus = require "openrtm.DataPortStatus"
16 local BufferStatus = require "openrtm.BufferStatus"
17 local OutPortProvider = require "openrtm.OutPortProvider"
18 local OutPortProviderFactory = OutPortProvider.OutPortProviderFactory
19 local CdrBufferBase = require "openrtm.CdrBufferBase"
20 local CdrBufferFactory = CdrBufferBase.CdrBufferFactory
21 local InPortConsumer = require "openrtm.InPortConsumer"
22 local InPortConsumerFactory = InPortConsumer.InPortConsumerFactory
23 local PublisherBase = require "openrtm.PublisherBase"
24 local PublisherFactory = PublisherBase.PublisherFactory
25 local StringUtil = require "openrtm.StringUtil"
26
27 local ConnectorListener = require "openrtm.ConnectorListener"
28 local ConnectorListenerType = ConnectorListener.ConnectorListenerType
29
30
31 -- Push型通信OutPortConnectorの初期化
32 -- @param info プロファイル
33 -- 「buffer」という要素名にバッファの設定を格納
34 -- @param consumer コンシューマ
35 -- @param listeners コールバック
36 -- @param buffer バッファ
37 -- 指定しない場合はリングバッファを生成する
38 -- @return Push型通信OutPortConnector
39 OutPortPushConnector.new = function(info, consumer, listeners, buffer)
40     --print(consumer, listeners, buffer)
41     local obj = {}
42     setmetatable(obj, {__index=OutPortConnector.new(info)})
43
44     -- データ書き込み
45     -- @param data data._dataを書き込み
46     -- @return リターンコード(パブリッシャのデータ書き込み結果による)
47     function obj:write(data)
48         self._rtcout:RTC_TRACE("write()")
49
50         local Manager = require "openrtm.Manager"
51
52         local cdr_data = Manager:instance():cdrMarshal(data._data, data._type)
53         --print(#cdr_data)
54
55         return self._publisher:write(cdr_data, 0, 0)
56     end
57
58     -- コネクタ切断
59     -- @return リターンコード
60     function obj:disconnect()
61         self._rtcout:RTC_TRACE("disconnect()")
62         self:onDisconnect()
63
64         if self._publisher ~= nil then
65             self._rtcout:RTC_DEBUG("delete publisher")
66             local pfactory = PublisherFactory:instance()
67             pfactory:deleteObject(self._publisher)
68         end
69
70         self._publisher = nil
71
72
73         if self._consumer ~= nil then
74             self._rtcout:RTC_DEBUG("delete consumer")
75             local cfactory = InPortConsumerFactory:instance()
76             cfactory:deleteObject(self._consumer)
77         end
78
79         self._consumer = nil
80
81
82         if self._buffer ~= nil then
83             self._rtcout:RTC_DEBUG("delete buffer")
84             local bfactory = CdrBufferFactory:instance()
85             bfactory:deleteObject(self._buffer)
86         end
87
88         self._buffer = nil
89         self._rtcout:RTC_TRACE("disconnect() done")
90
91         return DataPortStatus.PORT_OK
92     end
93     -- アクティブ化
94     function obj:activate()
95         self._publisher:activate()
96     end
97     -- 非アクティブ化
98     function obj:deactivate()
99         self._publisher:activate()
100     end
101     -- バッファ取得
102     -- @return バッファ
103     function obj:getBuffer()
104         return self._buffer
105     end
106
107     -- パブリッシャー生成
108     -- @param profile コネクタプロファイル
109     -- @return パブリッシャー
110     function obj:createPublisher(info)
111         local pub_type = info.properties:getProperty("subscription_type","flush")
112         pub_type = StringUtil.normalize(pub_type)
113         return PublisherFactory:instance():createObject(pub_type)
114     end
115
116     -- バッファ作成
117     -- @param profile コネクタプロファイル
118     -- @return バッファ
119     function obj:createBuffer(info)
120         local buf_type = info.properties:getProperty("buffer_type",
121                                                "ring_buffer")
122
123         return CdrBufferFactory:instance():createObject(buf_type)
124     end
125     -- コネクタ接続時のコールバック呼び出し
126     function obj:onConnect()
127         if self._listeners ~= nil and self._profile ~= nil then
128             self._listeners.connector_[ConnectorListenerType.ON_CONNECT]:notify(self._profile)
129         end
130     end
131     
132     -- コネクタ切断時のコールバック呼び出し
133     function obj:onDisconnect()
134         if self._listeners ~= nil and self._profile ~= nil then
135             self._listeners.connector_[ConnectorListenerType.ON_DISCONNECT]:notify(self._profile)
136         end
137     end
138     
139     -- InPortサーバントオブジェクト設定
140     -- @param directInPort InPortサーバントオブジェクト
141     -- @return true:設定成功、false:設定失敗
142     function obj:setInPort(directInPort)
143         return false
144     end
145
146     obj._buffer = buffer
147     obj._consumer = consumer
148     obj._listeners = listeners
149
150     obj._directInPort = nil
151     obj._inPortListeners = nil
152
153     obj._publisher = obj:createPublisher(info)
154     if obj._buffer == nil then
155         obj._buffer = obj:createBuffer(info)
156     end
157
158
159     if obj._publisher == nil or obj._buffer == nil or obj._consumer == nil then
160         error("")
161     end
162
163     if obj._publisher:init(info.properties) ~= DataPortStatus.PORT_OK then
164         error("")
165     end
166
167
168
169     obj._buffer:init(info.properties:getNode("buffer"))
170     obj._consumer:init(info.properties)
171     obj._publisher:setConsumer(obj._consumer)
172     obj._publisher:setBuffer(obj._buffer)
173     obj._publisher:setListener(obj._profile, obj._listeners)
174
175     obj:onConnect()
176
177     return obj
178 end
179
180
181 return OutPortPushConnector

File lua\openrtm\PeriodicExecutionContext.lua

1 ---------------------------------
2 --! @file PeriodicExecutionContext.lua
3 --! @brief 周期実行コンテキスト定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local PeriodicExecutionContext= {}
11 --_G["openrtm.PeriodicExecutionContext"] = PeriodicExecutionContext
12
13 local DEFAULT_PERIOD = 0.000001
14
15
16 local ExecutionContextBase = require "openrtm.ExecutionContextBase"
17
18 local ExecutionContextBase = require "openrtm.ExecutionContextBase"
19 local ExecutionContextFactory = ExecutionContextBase.ExecutionContextFactory
20 local ECFactory = require "openrtm.ECFactory"
21 local Task = require "openrtm.Task"
22 local oil = require "oil"
23
24 local RTCUtil = require "openrtm.RTCUtil"
25 local Timer = require "openrtm.Timer"
26
27
28
29
30 -- 周期実行コンテキスト初期化
31 -- @return 周期実行コンテキスト
32 PeriodicExecutionContext.new = function()
33     local obj = {}
34     setmetatable(obj, {__index=ExecutionContextBase.new("periodic_ec")})
35     local Manager = require "openrtm.Manager"
36     obj._ReturnCode_t = Manager:instance():getORB().types:lookup("::RTC::ReturnCode_t").labelvalue
37     obj._ExecutionKind = Manager:instance():getORB().types:lookup("::RTC::ExecutionKind").labelvalue
38     obj._rtcout = Manager:instance():getLogbuf("rtobject.periodic_ec")
39     obj._rtcout:RTC_TRACE("PeriodicExecutionContext.__init__()")
40     obj._svc = false
41     obj._nowait = false
42
43     --ref = Manager:instance():getORB():tostring(obj)
44     obj._svr = Manager:instance():getORB():newservant(obj, nil, "IDL:omg.org/RTC/ExecutionContextService:1.0")
45     local ref = RTCUtil.getReference(Manager:instance():getORB(), obj._svr, "IDL:omg.org/RTC/ExecutionContextService:1.0")
46     --print(ref:_non_existent())
47     --print(ref:start())
48     --print(svr)
49     obj:setObjRef(ref)
50     obj:setKind(obj._ExecutionKind.PERIODIC)
51     obj:setRate(1.0 / DEFAULT_PERIOD)
52     obj._rtcout:RTC_DEBUG("Actual rate: "..obj._profile:getPeriod():sec().." [sec], "..obj._profile:getPeriod():usec().." [usec]")
53
54     obj._cpu = {}
55
56     -- コルーチンで周期実行処理
57     -- @return 0:正常
58     function obj:svc()
59         self._rtcout:RTC_TRACE("svc()")
60         local count_ = 0
61
62
63
64         while(self:threadRunning()) do
65             self:invokeWorkerPreDo()
66             local t0_ = os.clock()
67             self:invokeWorkerDo()
68             self:invokeWorkerPostDo()
69             local t1_ = os.clock()
70             local period_ = self:getPeriod()
71             if count_ > 1000 then
72                 local exctm_ = t1_ - t0_
73                 local slptm_ = period_:toDouble() - exctm_
74                 self._rtcout:RTC_PARANOID("Period: "..period_:toDouble().." [s]")
75                 self._rtcout:RTC_PARANOID("Execution: "..exctm_.." [s]")
76                 self._rtcout:RTC_PARANOID("Sleep: "..slptm_.." [s]")
77             end
78
79
80             local t2_ = os.clock()
81
82             if not self._nowait and period_:toDouble() > (t1_ - t0_) then
83                 if count_ > 1000 then
84                     self._rtcout:RTC_PARANOID("sleeping...")
85                 end
86                 --print(period_:toDouble())
87                 local slptm_ = period_:toDouble() - (t1_ - t0_)
88                 --print(slptm_)
89                 --oil.tasks:suspend(slptm_)
90                 Timer.sleep(slptm_)
91             else
92                 if oil.VERSION == "OiL 0.6" then
93                     Timer.sleep(0)
94                 else
95                     coroutine.yield(1)
96                 end
97             end
98
99             --oil.tasks:suspend(1)
100
101
102             if count_ > 1000 then
103                 local t3_ = os.clock()
104                 self._rtcout:RTC_PARANOID("Slept: "..(t3_ - t2_).." [s]")
105                 count_ = 0
106             end
107             count_ = count_ + 1
108
109         end
110
111         self._rtcout:RTC_DEBUG("Thread terminated.")
112         return 0
113     end
114
115     -- コルーチンの処理開始
116     -- @return 0:正常
117     function obj:open()
118         self._rtcout:RTC_TRACE("open()")
119         Task.start(self)
120         return 0
121     end
122     -- 開始時実行関数
123     -- @return リターンコード
124     function obj:onStarted()
125         if not self._svc then
126             self._svc = true
127             self:open()
128         end
129         return self._ReturnCode_t.RTC_OK
130     end
131     -- 終了時実行関数
132     -- @return リターンコード
133     function obj:onStopped()
134         if self._svc then
135             self._svc = false
136             --self:wait(0)
137         end
138         return self._ReturnCode_t.RTC_OK
139     end
140     -- コルーチンが動作しているかの確認
141     -- @return true:動作中、false:停止済み
142     function obj:threadRunning()
143         return self._svc
144     end
145     return obj
146 end
147
148 -- 周期実行コンテキスト生成ファクトリ登録
149 PeriodicExecutionContext.Init = function(manager)
150     ExecutionContextFactory:instance():addFactory("PeriodicExecutionContext",
151         PeriodicExecutionContext.new,
152         ECFactory.ECDelete)
153 end
154
155 return PeriodicExecutionContext

File lua\openrtm\PortAdmin.lua

1 ---------------------------------
2 --! @file PortAdmin.lua
3 --! @brief ポート管理クラス定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local PortAdmin= {}
11 --_G["openrtm.PortAdmin"] = PortAdmin
12
13
14 local oil = require "oil"
15 local ObjectManager = require "openrtm.ObjectManager"
16 local CORBA_SeqUtil = require "openrtm.CORBA_SeqUtil"
17
18
19 -- ポートの名前が一致しているか判定する関数オブジェクト初期化
20 -- @param argv argv.name:型名、argv.factory:ファクトリ
21 -- @return 関数オブジェクト
22 local comp_op = function(argv)
23     local obj = {}
24     if argv.name ~= nil then
25         obj._name = argv.name
26     elseif argv.factory ~= nil then
27         obj._name = argv.factory:getProfile().name
28     end
29     -- ポートの名前が一致しているか判定する
30     -- @param self 自身のオブジェクト
31     -- @param obj RTC
32     -- @return true:一致、false:不一致
33     local call_func = function(self, obj)
34         name_ = obj:getProfile().name
35         return (self._name == name_)
36     end
37     setmetatable(obj, {__call=call_func})
38     return obj
39 end
40
41
42 local find_port_name = {}
43 -- ポート名が一致しているか判定する関数オブジェクト初期化
44 -- @param name ポート名
45 -- @return 関数オブジェクト
46 find_port_name.new = function(name)
47     local obj = {}
48     obj._name = name
49     --ポート名が一致しているか判定する
50     -- @param self 自身のオブジェクト
51     -- @param p ポート
52     -- @return true:一致、false:不一致
53     local call_func = function(self, p)
54         local prof = p:get_port_profile()
55         local name_ = prof.name
56         --print(self._name, name_)
57         return (self._name == name_)
58     end
59     setmetatable(obj, {__call=call_func})
60     return obj
61 end
62
63 -- ポート管理オブジェクト初期化
64 -- @param orb ORB
65 -- @return ポート管理オブジェクト
66 PortAdmin.new = function(orb)
67     local obj = {}
68     obj._orb = orb
69     obj._portRefs = {}
70     obj._portServants = ObjectManager.new(comp_op)
71     local Manager = require "openrtm.Manager"
72     obj._rtcout = Manager:instance():getLogbuf("PortAdmin")
73
74     -- ポートのインターフェースのアクティブ化
75     function obj:activatePorts()
76         --print("activatePorts1")
77         local ports = self._portServants:getObjects()
78         for i, port in pairs(ports) do
79             port:activateInterfaces()
80         end
81         --print("activatePorts2")
82     end
83     -- ポートのインターフェースの非アクティブ化
84     function obj:deactivatePorts()
85         ports = self._portServants:getObjects()
86         for i, port in pairs(ports) do
87             port:deactivateInterfaces()
88         end
89     end
90     -- ポートのプロファイル一覧取得
91     -- @return プロファイル一覧
92     function obj:getPortProfileList()
93         local ret = {}
94         for i, p in ipairs(self._portRefs) do
95             table.insert(ret, p:get_port_profile())
96         end
97         return ret
98     end
99
100     -- ポート追加
101     -- @param port ポート
102     -- @return true:登録成功、false:登録失敗
103     function obj:addPort(port)
104         local index = CORBA_SeqUtil.find(self._portRefs,
105                                     find_port_name.new(port:getName()))
106         if index >= 0 then
107             return false
108         end
109         --print(port:getPortRef())
110         table.insert(self._portRefs, port:getPortRef())
111         return self._portServants:registerObject(port)
112     end
113
114     -- ポート削除
115     -- @param port ポート
116     -- @return true:削除成功、false:削除失敗
117     function obj:removePort(port)
118         local ret = false
119         local success, exception = oil.pcall(
120             function()
121
122             port:disconnect_all()
123             tmp = port:getProfile().name
124             --print(#self._portRefs)
125             CORBA_SeqUtil.erase_if(self._portRefs, find_port_name.new(tmp))
126             --print(#self._portRefs)
127             port:deactivate()
128
129
130             port:setPortRef(oil.corba.idl.null)
131
132             if not self._portServants:unregisterObject(tmp) then
133                 ret = false
134                 return
135             end
136             ret = true
137             end)
138         if not success then
139             --print(exception)
140             self._rtcout:RTC_ERROR(exception)
141             return false
142         end
143         return ret
144     end
145
146     -- ポートのオブジェクトリファレンス一覧取得
147     -- @return ポートのオブジェクトリファレンス一覧
148     function obj:getPortServiceList()
149         return self._portRefs
150     end
151
152     -- 全ポート削除
153     function obj:finalizePorts()
154         self:deactivatePorts()
155         local ports = self._portServants:getObjects()
156         for i, port in ipairs(ports) do
157             self:removePort(port)
158         end
159     end
160
161     return obj
162 end
163
164
165 return PortAdmin

File lua\openrtm\PortBase.lua

1 ---------------------------------
2 --! @file PortBase.lua
3 --! @brief ポート基底クラス定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local PortBase= {}
11 --_G["openrtm.PortBase"] = PortBase
12
13 local oil = require "oil"
14 local CORBA_SeqUtil = require "openrtm.CORBA_SeqUtil"
15 local Properties = require "openrtm.Properties"
16 local NVUtil = require "openrtm.NVUtil"
17 local StringUtil = require "openrtm.StringUtil"
18 local PortConnectListener = require "openrtm.PortConnectListener"
19 local PortConnectListenerType = PortConnectListener.PortConnectListenerType
20 local PortConnectRetListenerType = PortConnectListener.PortConnectRetListenerType
21
22 local uuid = require "uuid"
23
24 local RTCUtil = require "openrtm.RTCUtil"
25
26
27
28 local find_conn_id = {}
29 -- コネクタIDが一致しているか判定する関数オブジェクト初期化
30 -- @param id_ コネクタID
31 -- @return 関数オブジェクト
32 find_conn_id.new = function(id_)
33  local obj = {}
34  obj._id = id_
35  -- コネクタIDが一致しているか判定する
36  -- @param self 自身のオブジェクト
37  -- @param cprof コネクタプロファイル
38  -- @return true:一致、false:不一致
39  local call_func = function(self, cprof)
40   return (self._id == cprof.connector_id)
41  end
42  setmetatable(obj, {__call=call_func})
43  return obj
44 end
45
46
47
48 local find_port_ref = {}
49 -- ポートのオブジェクトリファレンスが一致するかを判定する関数オブジェクト
50 -- @param port_ref ポート
51 -- @return 関数オブジェクト
52 find_port_ref.new = function(port_ref)
53  local obj = {}
54  obj._port_ref = port_ref
55  -- ポートのオブジェクトリファレンスが一致するかを判定する
56  -- @param self 自身のオブジェクト
57  -- @param port_ref ポート
58  -- @return true:一致、false:不一致
59  local call_func = function(self, port_ref)
60   --print(self._port_ref, port_ref, self._port_ref._is_equivalent, port_ref._is_equivalent)
61   return NVUtil._is_equivalent(self._port_ref, port_ref, self._port_ref.getPortRef, port_ref.getPortRef)
62   --[[local ret = false
63   local success, exception = oil.pcall(
64    function()
65    ret = (self._port_ref:get_port_profile().name == port_ref:get_port_profile().name)
66    end)
67   return ret]]
68   --return self._port_ref:_is_equivalent(port_ref)
69  end
70  setmetatable(obj, {__call=call_func})
71  return obj
72 end
73
74
75 local find_interface = {}
76
77 -- インターフェースが一致しているか判定する関数オブジェクト
78 -- @param name インターフェース名
79 -- @param pol インターフェースの方向(PROVIDED、REQUIRED)
80 -- @return 関数オブジェクト
81 find_interface.new = function(name, pol)
82  local obj = {}
83  obj._name = name
84  obj._pol = pol
85  -- インターフェースが一致しているか判定する
86  -- @param self 自身のオブジェクト
87  -- @param prof インターフェースのプロファイル
88  -- @return true:一致、false:不一致
89  local call_func = function(self, prof)
90   local name = prof.instance_name
91   return ((self._name == name) and (self._pol == prof.polarity))
92  end
93  setmetatable(obj, {__call=call_func})
94  return obj
95
96 end
97
98
99 -- ポート基底オブジェクト初期化
100 -- @param name ポート名
101 -- @return ポート
102 PortBase.new = function(name)
103  local obj = {}
104
105  local Manager = require "openrtm.Manager"
106  obj._ReturnCode_t = Manager:instance():getORB().types:lookup("::RTC::ReturnCode_t").labelvalue
107
108  obj._ownerInstanceName = "unknown"
109  --print("test3:",obj, obj._objref)
110
111
112     obj._profile = {name="", interfaces={}, port_ref=oil.corba.idl.null, connector_profiles={}, owner=oil.corba.idl.null, properties={}}
113
114
115     if name == nil then
116   obj._profile.name = "unknown.unknown"
117     else
118   obj._profile.name = obj._ownerInstanceName.."."..name
119  end
120
121
122     obj._profile.owner = oil.corba.idl.null
123
124
125     obj._rtcout = Manager:instance():getLogbuf(name)
126     obj._onPublishInterfaces = nil
127     obj._onSubscribeInterfaces = nil
128     obj._onConnected = nil
129     obj._onUnsubscribeInterfaces = nil
130     obj._onDisconnected = nil
131     obj._onConnectionLost = nil
132     obj._connectionLimit   = -1
133     obj._portconnListeners = nil
134  obj._properties = Properties.new()
135  obj._svr = nil
136  obj._connectors = {}
137
138  -- ポートプロファイル取得
139  -- @return プロファイル
140  function obj:get_port_profile()
141   self._rtcout:RTC_TRACE("get_port_profile()")
142
143   self:updateConnectors()
144   local connectors = {}
145   for i,con in ipairs(self._profile.connector_profiles) do
146    local conn_prof = {name=con.name,
147        connector_id=con.connector_id,
148        ports=con.ports,
149        properties={}}
150    for j,conf in ipairs(con.properties) do
151     con.properties[j] = {name=conf.name, value=NVUtil.any_from_any(conf.value)}
152    end
153    table.insert(connectors, conn_prof)
154   end
155
156
157   local prof = {name=self._profile.name,
158     interfaces=self._profile.interfaces,
159     port_ref=self._profile.port_ref,
160     --port_ref="test",
161     connector_profiles=connectors,
162     owner=self._profile.owner,
163     properties=self._profile.properties}
164   return prof
165  end
166
167  -- ポートプロファイル取得
168  -- @return プロファイル
169  function obj:getPortProfile()
170   self._rtcout:RTC_TRACE("getPortProfile()")
171   return self._profile
172  end
173
174  -- コネクタプロファイル一覧取得
175  -- @return プロファイル一覧
176  function obj:get_connector_profiles()
177   self._rtcout:RTC_TRACE("get_connector_profiles()")
178
179   self:updateConnectors()
180
181   return self._profile.connector_profiles
182  end
183
184  -- コネクタプロファイル取得
185  -- @param connector_id コネクタID
186  -- @return プロファイル
187  function obj:get_connector_profile(connector_id)
188   self._rtcout:RTC_TRACE("get_connector_profile("..connector_id..")")
189
190   self:updateConnectors()
191
192   local index = CORBA_SeqUtil.find(self._profile.connector_profiles,
193             find_conn_id.new(connector_id))
194   if index < 0 then
195     local conn_prof = {name="", connector_id="", ports={}, properties={}}
196     return conn_prof
197   end
198
199   local conn_prof = {name=self._profile.connector_profiles[index].name,
200      connector_id=self._profile.connector_profiles[index].connector_id,
201      ports=self._profile.connector_profiles[index].ports,
202      properties=self._profile.connector_profiles[index].properties}
203   return conn_prof
204  end
205
206  -- コネクタ接続
207  -- @param connector_profile コネクタプロファイル
208  -- @return リターンコード、コネクタプロファイル
209  function obj:connect(connector_profile)
210   self._rtcout:RTC_TRACE("connect()")
211   if self:isEmptyId(connector_profile) then
212    self:setUUID(connector_profile)
213   else
214    --print(self:isExistingConnId(connector_profile.connector_id))
215    if self:isExistingConnId(connector_profile.connector_id) then
216     self._rtcout:RTC_ERROR("Connection already exists.")
217     return self._ReturnCode_t.PRECONDITION_NOT_MET, connector_profile
218    end
219   end
220
221
222   local retval = self._ReturnCode_t.BAD_PARAMETER
223   local success, exception = oil.pcall(
224    function()
225     --print(#connector_profile.ports)
226     retval,connector_profile = connector_profile.ports[1]:notify_connect(connector_profile)
227     --print(retval)
228     retval = NVUtil.getReturnCode(retval)
229     if retval ~= self._ReturnCode_t.RTC_OK then
230      self._rtcout:RTC_ERROR("Connection failed. cleanup.")
231      self:disconnect(connector_profile.connector_id)
232     end
233    end)
234   if not success then
235    --print(exception)
236    self._rtcout:RTC_ERROR(exception)
237    return self._ReturnCode_t.BAD_PARAMETER, connector_profile
238   end
239   --print(retval)
240   --local conn_prof = {name="",
241   --     connector_id="",
242   --     ports={},
243   --     properties={}}
244   return retval, connector_profile
245  end
246
247  -- コネクタ切断
248  -- @param connector_id コネクタID
249  -- @return リターンコード
250  function obj:disconnect(connector_id)
251   self._rtcout:RTC_TRACE("disconnect("..connector_id..")")
252
253   local index = self:findConnProfileIndex(connector_id)
254
255   if index < 0 then
256    self._rtcout:RTC_ERROR("Invalid connector id: "..connector_id)
257    return self._ReturnCode_t.BAD_PARAMETER
258   end
259
260   local prof = self._profile.connector_profiles[index]
261
262
263
264   if #prof.ports < 1 then
265    self._rtcout:RTC_FATAL("ConnectorProfile has empty port list.")
266    return self._ReturnCode_t.PRECONDITION_NOT_MET
267   end
268   local ret = self._ReturnCode_t.RTC_ERROR
269   local success, exception = oil.pcall(
270    function()
271     ret = prof.ports[1]:notify_disconnect(connector_id)
272    end)
273   if not success then
274    self._rtcout:RTC_WARN(exception)
275   end
276
277
278   if ret ~= self._ReturnCode_t.RTC_OK then
279    self._rtcout:RTC_ERROR("notify_disconnect() for all ports failed.")
280    return self._ReturnCode_t.RTC_ERROR
281   else
282    return ret
283   end
284  end
285
286  -- コネクタ切断実行関数
287  -- @param connector_id コネクタID
288  -- @return リターンコード
289  function obj:notify_disconnect(connector_id)
290   self._rtcout:RTC_TRACE("notify_disconnect("..connector_id..")")
291
292   local index = self:findConnProfileIndex(connector_id)
293
294   if index < 0 then
295    self._rtcout:RTC_ERROR("Invalid connector id: "..connector_id)
296    return self._rtcout.BAD_PARAMETER
297   end
298
299   local prof = {name = self._profile.connector_profiles[index].name,
300     connector_id = self._profile.connector_profiles[index].connector_id,
301     ports = self._profile.connector_profiles[index].ports,
302     properties = self._profile.connector_profiles[index].properties}
303
304   self:onNotifyDisconnect(self:getName(), prof)
305
306   local retval = self:disconnectNext(prof)
307   self:onDisconnectNextport(self:getName(), prof, retval)
308
309   if self._onUnsubscribeInterfaces ~= nil then
310    self._onUnsubscribeInterfaces(prof)
311   end
312   self:onUnsubscribeInterfaces(self:getName(), prof)
313   self:unsubscribeInterfaces(prof)
314
315   if self._onDisconnected ~= nil then
316    self._onDisconnected(prof)
317   end
318
319   table.remove(self._profile.connector_profiles, index)
320
321   self:onDisconnected(self:getName(), prof, retval)
322   return retval
323  end
324
325  -- コネクタ接続実行関数
326  -- @param connector_profile コネクタプロファイル
327  -- @return リターンコード、コネクタプロファイル
328  function obj:notify_connect(connector_profile)
329
330   self._rtcout:RTC_TRACE("notify_connect()")
331
332
333
334   local prop = Properties.new()
335   NVUtil.copyToProperties(prop, connector_profile.properties)
336
337
338   local default_value = StringUtil.toBool(self._properties:getProperty("allow_dup_connection"), "YES","NO",false)
339
340   if not StringUtil.toBool(prop:getProperty("dataport.allow_dup_connection"), "YES","NO",default_value) then
341   end
342
343
344   local retval = {}
345
346   self:onNotifyConnect(self:getName(),connector_profile)
347
348
349   retval[1] = self:publishInterfaces(connector_profile)
350   --for i, v in ipairs(connector_profile.properties) do
351   -- print(v.name, v.value)
352   --end
353
354   if retval[1] ~= self._ReturnCode_t.RTC_OK then
355    self._rtcout:RTC_ERROR("publishInterfaces() in notify_connect() failed.")
356   end
357
358   self:onPublishInterfaces(self:getName(), connector_profile, retval[1])
359   if self._onPublishInterfaces ~= nil then
360    self._onPublishInterfaces(connector_profile)
361   end
362
363
364   retval[2], connector_profile = self:connectNext(connector_profile)
365   retval[2] = NVUtil.getReturnCode(retval[2])
366   --print("test2", retval[2])
367   if retval[2] ~= self._ReturnCode_t.RTC_OK then
368    self._rtcout:RTC_ERROR("connectNext() in notify_connect() failed.")
369   end
370
371
372   self:onConnectNextport(self:getName(), connector_profile, retval[2])
373
374   if self._onSubscribeInterfaces ~= nil then
375    self._onSubscribeInterfaces(connector_profile)
376   end
377
378   retval[3] = self:subscribeInterfaces(connector_profile)
379   if retval[3] ~= self._ReturnCode_t.RTC_OK then
380    self._rtcout:RTC_ERROR("subscribeInterfaces() in notify_connect() failed.")
381   end
382
383
384   self:onSubscribeInterfaces(self:getName(), connector_profile, retval[3])
385
386   self._rtcout:RTC_PARANOID(#self._profile.connector_profiles.." connectors are existing")
387
388
389   local index = self:findConnProfileIndex(connector_profile.connector_id)
390
391   --print(index)
392   if index < 0 then
393    table.insert(self._profile.connector_profiles, connector_profile)
394    --print(#self._profile.connector_profiles)
395    self._rtcout:RTC_PARANOID("New connector_id. Push backed.")
396
397   else
398    self._profile.connector_profiles[index] = connector_profile
399    self._rtcout:RTC_PARANOID("Existing connector_id. Updated.")
400   end
401
402
403
404   for i, ret in ipairs(retval) do
405    --print(i,ret)
406    if ret ~= self._ReturnCode_t.RTC_OK then
407     self:onConnected(self:getName(), connector_profile, ret)
408     return ret, connector_profile
409    end
410   end
411
412
413
414   if self._onConnected ~= nil then
415    self._onConnected(connector_profile)
416   end
417   self:onConnected(self:getName(), connector_profile, self._ReturnCode_t.RTC_OK)
418
419   local conn_prof = {name=connector_profile.name,
420        connector_id=connector_profile.connector_id,
421        ports=connector_profile.ports,
422        properties={}}
423
424   for i,v in ipairs(connector_profile.properties) do
425    conn_prof.properties[i] = {name=v.name, value=NVUtil.any_from_any(v.value)}
426    --print(v.name, v.value)
427    --print(conn_prof.properties[i].name, conn_prof.properties[i].value)
428   end
429
430
431   return self._ReturnCode_t.RTC_OK, conn_prof
432  end
433
434  -- コネクタ一覧更新
435  function obj:updateConnectors()
436
437   local connector_ids = {}
438   local clist = self._profile.connector_profiles
439
440   for i, cprof in ipairs(clist) do
441    if not self:checkPorts(cprof.ports) then
442     table.insert(connector_ids, cprof.connector_id)
443     self._rtcout:RTC_WARN("Dead connection: "..cprof.connector_id)
444    end
445   end
446
447   for i, cid in ipairs(connector_ids) do
448    self:disconnect(cid)
449   end
450
451     end
452
453  -- コネクタ一覧取得
454  -- @return コネクタ一覧
455  function obj:connectors()
456   self._rtcout:RTC_TRACE("connectors(): size = "..#self._connectors)
457   return self._connectors
458  end
459
460  -- ポートが生存しているかを確認
461  -- @param ports ポート
462  -- @return true:生存、false:消滅済み
463   function obj:checkPorts(ports)
464   local ret = true
465   for i, port in ipairs(ports) do
466    --print(NVUtil._non_existent(port))
467    if NVUtil._non_existent(port) then
468     self._rtcout:RTC_WARN("Dead Port reference detected.")
469     ret = false
470    end
471   end
472
473   return ret
474  end
475
476  -- IDが空かを判定
477  -- @param コネクタプロファイル
478  -- @return true:空
479   function obj:isEmptyId(connector_profile)
480   return (connector_profile.connector_id == "")
481  end
482
483  -- コネクタIDがすでに登録済みかを確認
484  -- @param id_ コネクタID
485  -- @return true:登録済み、false:未登録
486   function obj:isExistingConnId(id_)
487   return (CORBA_SeqUtil.find(self._profile.connector_profiles,
488                                            find_conn_id.new(id_)) >= 0)
489  end
490
491  -- コネクタ接続実行時のコールバック実行
492  -- @param portname ポート名
493  -- @param profile ポートプロファイル
494  function obj:onNotifyConnect(portname, profile)
495   if self._portconnListeners ~= nil then
496    local _type = PortConnectListenerType.ON_NOTIFY_CONNECT
497    self._portconnListeners.portconnect_[_type]:notify(portname, profile)
498   end
499     end
500     -- コネクタ切断実行時のコールバック実行
501  -- @param portname ポート名
502  -- @param profile ポートプロファイル
503  function obj:onNotifyDisconnect(portname, profile)
504   if self._portconnListeners ~= nil then
505    local _type = PortConnectListenerType.ON_NOTIFY_DISCONNECT
506    self._portconnListeners.portconnect_[_type]:notify(portname, profile)
507   end
508     end
509     -- インターフェス解放時のコールバック実行
510  -- @param portname ポート名
511  -- @param profile ポートプロファイル
512  function obj:onUnsubscribeInterfaces(portname, profile)
513   if self._portconnListeners ~= nil then
514    local _type = PortConnectListenerType.ON_UNSUBSCRIBE_INTERFACES
515    self._portconnListeners.portconnect_[_type]:notify(portname, profile)
516   end
517     end
518     -- インターフェス登録時のコールバック実行
519  -- @param portname ポート名
520  -- @param profile ポートプロファイル
521  -- @param ret リターンコード
522  function obj:onPublishInterfaces(portname, profile, ret)
523   if self._portconnListeners ~= nil then
524    local _type = PortConnectRetListenerType.ON_PUBLISH_INTERFACES
525    self._portconnListeners.portconnret_[_type]:notify(portname, profile, ret)
526   end
527     end
528     -- 次のポート接続時のコールバック実行
529  -- @param portname ポート名
530  -- @param profile ポートプロファイル
531  -- @param ret リターンコード
532  function obj:onConnectNextport(portname, profile, ret)
533   if self._portconnListeners ~= nil then
534    local _type = PortConnectRetListenerType.ON_CONNECT_NEXTPORT
535    self._portconnListeners.portconnret_[_type]:notify(portname, profile, ret)
536   end
537     end
538     -- インターフェ-ス取得時のコールバック実行
539  -- @param portname ポート名
540  -- @param profile ポートプロファイル
541  -- @param ret リターンコード
542  function obj:onSubscribeInterfaces(portname, profile, ret)
543   if self._portconnListeners ~= nil then
544    local _type = PortConnectRetListenerType.ON_SUBSCRIBE_INTERFACES
545    self._portconnListeners.portconnret_[_type]:notify(portname, profile, ret)
546   end
547     end
548     -- コネクタ接続後のコールバック実行
549  -- @param portname ポート名
550  -- @param profile ポートプロファイル
551  -- @param ret リターンコード
552  function obj:onConnected(portname, profile, ret)
553   if self._portconnListeners ~= nil then
554    local _type = PortConnectRetListenerType.ON_CONNECTED
555    self._portconnListeners.portconnret_[_type]:notify(portname, profile, ret)
556   end
557     end
558     -- 次のポート切断時のコールバック実行
559  -- @param portname ポート名
560  -- @param profile ポートプロファイル
561  -- @param ret リターンコード
562  function obj:onDisconnectNextport(portname, profile, ret)
563   if self._portconnListeners ~= nil then
564    local _type = PortConnectRetListenerType.ON_DISCONNECT_NEXT
565    self._portconnListeners.portconnret_[_type]:notify(portname, profile, ret)
566   end
567     end
568     -- コネクタ接断後のコールバック実行
569  -- @param portname ポート名
570  -- @param profile ポートプロファイル
571  -- @param ret リターンコード
572  function obj:onDisconnected(portname, profile, ret)
573   if self._portconnListeners ~= nil then
574    local _type = PortConnectRetListenerType.ON_DISCONNECTED
575    self._portconnListeners.portconnret_[_type]:notify(portname, profile, ret)
576   end
577     end
578
579  -- ポート名取得
580  -- @return ポート名
581  function obj:getName()
582   self._rtcout:RTC_TRACE("getName() = "..self._profile.name)
583   return self._profile.name
584  end
585
586  -- インターフェースをコネクタプロファイルに登録
587  -- @param connector_profile コネクタプロファイル
588  -- @return リターンコード
589  function obj:publishInterfaces(connector_profile)
590   --print("publishInterfaces")
591   return self._ReturnCode_t.BAD_PARAMETER
592  end
593
594  -- コネクタ接続可能かの判定
595  -- @return リターンコード
596  function obj:_publishInterfaces()
597   if not (self._connectionLimit < 0) then
598    if self._connectionLimit <= #self._profile.connector_profiles then
599     self._rtcout:RTC_PARANOID("Connected number has reached the limitation.")
600     self._rtcout:RTC_PARANOID("Can connect the port up to "..self._connectionLimit.." ports.")
601     self._rtcout:RTC_PARANOID(#self._profile.connector_profiles.." connectors are existing")
602     return self._ReturnCode_t.RTC_ERROR
603    end
604   end
605
606   return self._ReturnCode_t.RTC_OK
607  end
608
609  -- 次のポートを接続
610  -- @param connector_profile コネクタプロファイル
611  -- @return リターンコード、コネクタプロファイル
612  function obj:connectNext(connector_profile)
613   --print("test:",self,self._profile.port_ref)
614   --print(connector_profile.ports[1]:get_port_profile().name)
615   local index = CORBA_SeqUtil.find(connector_profile.ports,
616            find_port_ref.new(self._profile.port_ref))
617   --print(index)
618
619
620
621   if index < 0 then
622    return self._ReturnCode_t.BAD_PARAMETER, connector_profile
623   end
624
625   index = index + 1
626   --print(index)
627   local p = connector_profile.ports[index]
628   --print(p)
629   if p ~= nil then
630    --[[for i,v in ipairs(connector_profile.properties) do
631     print(v.name,v.value)
632    end]]
633             local prop = {}
634             for i, v in ipairs(connector_profile.properties) do
635                 prop[i] = {name=v.name, value=NVUtil.any_from_any(v.value)}
636             end
637             connector_profile.properties = prop
638             return p:notify_connect(connector_profile)
639         end
640
641         return self._ReturnCode_t.RTC_OK, connector_profile
642     end
643     -- 次のポートを切断
644     -- @param connector_profile コネクタプロファイル
645     -- @return リターンコード
646     function obj:disconnectNext(connector_profile)
647
648         local index = CORBA_SeqUtil.find(connector_profile.ports,
649                                                 find_port_ref.new(self._profile.port_ref))
650         if index < 0 then
651             return self._ReturnCode_t.BAD_PARAMETER
652         end
653
654         if index == #connector_profile.ports then
655             return self._ReturnCode_t.RTC_OK
656         end
657
658         index = index + 1
659
660
661
662         local p = connector_profile.ports[index]
663         --print(p,index)
664         local ret = self._ReturnCode_t.RTC_ERROR
665         while p ~= nil do
666             local success, exception = oil.pcall(
667                 function()
668                     index = index + 1
669                     ret = p:notify_disconnect(connector_profile.connector_id)
670                 end)
671
672             if not success then
673                 self._rtcout:RTC_WARN(exception)
674             end
675             p = connector_profile.ports[index]
676
677         end
678
679
680         return ret
681     end
682
683     -- IDからコネクタプロファイル取得
684     -- @param id_ コネクタID
685     -- @return 配列の番号
686     function obj:findConnProfileIndex(id_)
687         return CORBA_SeqUtil.find(self._profile.connector_profiles,
688                                            find_conn_id.new(id_))
689     end
690     -- コネクタプロファイルにUUIDを設定
691     -- @param connector_profile コネクタプロファイル
692     function obj:setUUID(connector_profile)
693         connector_profile.connector_id = self:getUUID()
694         --print(connector_profile.connector_id)
695     end
696     -- UUID生成
697     -- @return UUID
698     function obj:getUUID()
699         return uuid()
700     end
701     -- コネクタプロファイルからインターフェース取得
702     -- @param cprof コネクタプロファイル
703     -- @return リターンコード
704     function obj:subscribeInterfaces(connector_profile)
705         return self._ReturnCode_t.BAD_PARAMETER
706     end
707     -- プロファイルの設定
708     -- @param _key キー
709     -- @param _value 値
710     function obj:addProperty(_key, _value)
711         table.insert(self._profile.properties, {name=_key, value=_value})
712     end
713     -- プロファイルの設定追加
714     -- @param _key キー
715     -- @param _value 値
716     function obj:appendProperty(key, value)
717         --print(key, value)
718         NVUtil.appendStringValue(self._profile.properties, key, value)
719         --print(self._profile.properties)
720     end
721     -- コネクタプロファイルのインターフェース設定解除
722     -- @return リターンコード
723     function obj:unsubscribeInterfaces(connector_profile)
724         return self._ReturnCode_t.BAD_PARAMETER
725     end
726     -- コネクタ最大数設定
727     -- @param limit_value コネクタ最大数
728     function obj:setConnectionLimit(limit_value)
729         self._connectionLimit = limit_value
730     end
731
732     -- インターフェース追加
733     -- @param _instance_name インスタンス名
734     -- @param _type_name 型名
735     -- @param pol 方向
736     -- @return true:追加成功、false:追加失敗
737     function obj:appendInterface(_instance_name, _type_name, pol)
738         local index = CORBA_SeqUtil.find(self._profile.interfaces,
739                                     find_interface.new(_instance_name, pol))
740
741         if index >= 0 then
742             return false
743         end
744
745
746         local prof = {instance_name=_instance_name, type_name=_type_name, polarity=pol}
747         table.insert(self._profile.interfaces, prof)
748
749         return true
750     end
751
752     -- オーナーのRTC設定
753     -- @param owner RTC
754     function obj:setOwner(owner)
755         local prof = owner:get_component_profile()
756         self._ownerInstanceName = prof.instance_name
757         self._rtcout:RTC_TRACE("setOwner("..self._ownerInstanceName..")")
758
759
760         local plist = StringUtil.split(self._profile.name, "%.")
761         if self._ownerInstanceName == "" then
762             self._rtcout:RTC_ERROR("Owner is not set.")
763             self._rtcout:RTC_ERROR("addXXXPort() should be called in onInitialize().")
764         end
765         local portname = self._ownerInstanceName.."."..plist[#plist]
766
767         if owner.getObjRef == nil then
768             self._profile.owner = owner
769         else
770             self._profile.owner = owner:getObjRef()
771         end
772         self._profile.name = portname
773     end
774
775     -- ポートコネクタコールバックの設定
776     -- @param portconnListeners ポートコネクタコールバック関数
777     function obj:setPortConnectListenerHolder(portconnListeners)
778         self._portconnListeners = portconnListeners
779     end
780
781     -- オブジェクトリファレンス取得
782     -- @return オブジェクトリファレンス
783     function obj:getPortRef()
784         self._rtcout:RTC_TRACE("getPortRef()")
785         return self._profile.port_ref
786     end
787     function obj:getObjRef()
788         return self._objref
789     end
790
791     -- プロファイル取得
792     -- @return プロファイル
793     function obj:getProfile()
794         self._rtcout:RTC_TRACE("getProfile()")
795         return self._profile
796     end
797
798     -- 全コネクタ切断
799     -- @return リターンコード
800     function obj:disconnect_all()
801         self._rtcout:RTC_TRACE("disconnect_all()")
802
803         local plist = self._profile.connector_profiles
804
805
806         local retcode = self._ReturnCode_t.RTC_OK
807         local len_ = #plist
808         self._rtcout:RTC_DEBUG("disconnecting "..len_.." connections.")
809
810
811
812         for i, con in ipairs(plist) do
813             tmpret = self:disconnect(con.connector_id)
814             if tmpret ~= self._ReturnCode_t.RTC_OK then
815                 retcode = tmpret
816             end
817         end
818
819
820         return retcode
821     end
822
823     -- オブジェクトリファレンス設定
824     -- @param port_ref オブジェクトリファレンス
825     function obj:setPortRef(port_ref)
826         self._rtcout:RTC_TRACE("setPortRef()")
827         self._profile.port_ref = port_ref
828     end
829
830     -- オブジェクトリファレンス生成
831     function obj:createRef()
832         --print("createRef")
833         local Manager = require "openrtm.Manager"
834         self._svr = Manager:instance():getORB():newservant(self, nil, "IDL:omg.org/RTC/PortService:1.0")
835         self._objref = RTCUtil.getReference(Manager:instance():getORB(), self._svr, "IDL:omg.org/RTC/PortService:1.0")
836         self._profile.port_ref = self._objref
837     end
838
839     -- インターフェースの非アクティブ化
840     function obj:deactivate()
841         local Manager = require "openrtm.Manager"
842         if self._svr ~= nil then
843             Manager:instance():getORB():deactivate(self._svr)
844         end
845     end
846
847     return obj
848 end
849
850
851 return PortBase

File lua\openrtm\PortCallBack.lua

1 ---------------------------------
2 --! @file PortCallBack.lua
3 --! @brief ポート関連のコールバック定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local PortCallBack= {}
11 --_G["openrtm.PortCallBack"] = PortCallBack
12
13 PortCallBack.ConnectionCallback = {}
14 PortCallBack.ConnectionCallback.new = function()
15     local obj = {}
16     function obj:call(profile)
17         
18     end
19     local call_func = function(self, profile)
20         self:call(profile)
21     end
22     setmetatable(obj, {__call=call_func})
23     return obj
24 end
25
26
27 PortCallBack.DisconnectCallback = {}
28 PortCallBack.DisconnectCallback.new = function()
29     local obj = {}
30     function obj:call(connector_id)
31         
32     end
33     local call_func = function(self, connector_id)
34         self:call(connector_id)
35     end
36     setmetatable(obj, {__call=call_func})
37     return obj
38 end
39
40 PortCallBack.OnWrite = {}
41 PortCallBack.OnWrite.new = function()
42     local obj = {}
43     function obj:call(value)
44         
45     end
46     local call_func = function(self, value)
47         self:call(value)
48     end
49     setmetatable(obj, {__call=call_func})
50     return obj
51 end
52
53 PortCallBack.OnWriteConvert = {}
54 PortCallBack.OnWriteConvert.new = function()
55     local obj = {}
56     function obj:call(value)
57         return value
58     end
59     local call_func = function(self, value)
60         self:call(value)
61     end
62     setmetatable(obj, {__call=call_func})
63     return obj
64 end
65
66
67 PortCallBack.OnRead = {}
68 PortCallBack.OnRead.new = function()
69     local obj = {}
70     function obj:call()
71         
72     end
73     local call_func = function(self)
74         self:call()
75     end
76     setmetatable(obj, {__call=call_func})
77     return obj
78 end
79
80 PortCallBack.OnReadConvert = {}
81 PortCallBack.OnReadConvert.new = function()
82     local obj = {}
83     function obj:call(value)
84         return value
85     end
86     local call_func = function(self, value)
87         self:call(value)
88     end
89     setmetatable(obj, {__call=call_func})
90     return obj
91 end
92
93
94
95 return PortCallBack

File lua\openrtm\PortConnectListener.lua

1 ---------------------------------
2 --! @file PortConnectListener.lua
3 --! @brief コネクタ関連のコールバック定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local PortConnectListener= {}
11 --_G["openrtm.PortConnectListener"] = PortConnectListener
12
13 PortConnectListener.PortConnectListenerType = {
14                                                 ON_NOTIFY_CONNECT = 1,
15                                                 ON_NOTIFY_DISCONNECT = 2,
16                                                 ON_UNSUBSCRIBE_INTERFACES = 3,
17                                                 PORT_CONNECT_LISTENER_NUM = 4
18                                                 }
19
20
21
22 PortConnectListener.PortConnectListener = {}
23
24
25
26
27 PortConnectListener.PortConnectListener.toString = function(_type)
28     local typeString = {"ON_NOTIFY_CONNECT",
29                         "ON_NOTIFY_DISCONNECT",
30                         "ON_UNSUBSCRIBE_INTERFACES",
31                         "PORT_CONNECT_LISTENER_NUM"}
32
33     if _type < PortConnectListener.PortConnectListenerType.PORT_CONNECT_LISTENER_NUM then
34         return typeString[_type]
35     end
36     return ""
37 end
38
39 PortConnectListener.PortConnectListener.new = function()
40     local obj = {}
41     function obj:call(portname, profile)
42         
43     end
44
45
46
47     local call_func = function(self, portname, profile)
48         self:call(info, data)
49     end
50     setmetatable(obj, {__call=call_func})
51     return obj
52 end
53
54
55
56 PortConnectListener.PortConnectRetListenerType = {
57                                                 ON_PUBLISH_INTERFACES = 1,
58                                                 ON_CONNECT_NEXTPORT = 2,
59                                                 ON_SUBSCRIBE_INTERFACES = 3,
60                                                 ON_CONNECTED = 4,
61                                                 ON_DISCONNECT_NEXT = 5,
62                                                 ON_DISCONNECTED = 6,
63                                                 PORT_CONNECT_RET_LISTENER_NUM = 7
64                                                 }
65
66
67
68
69
70
71 PortConnectListener.PortConnectRetListener = {}
72
73
74
75
76 PortConnectListener.PortConnectRetListener.toString = function(_type)
77     local typeString = {"ON_PUBLISH_INTERFACES",
78                         "ON_CONNECT_NEXTPORT",
79                         "ON_SUBSCRIBE_INTERFACES",
80                         "ON_CONNECTED",
81                         "ON_DISCONNECT_NEXT",
82                         "ON_DISCONNECTED"}
83
84     if _type < PortConnectListener.PortConnectRetListenerType.PORT_CONNECT_RET_LISTENER_NUM then
85         return typeString[_type]
86     end
87     return ""
88 end
89
90 PortConnectListener.PortConnectRetListener.new = function()
91     local obj = {}
92     function obj:call(portname, profile, ret)
93         
94     end
95
96
97
98     local call_func = function(self, portname, profile, ret)
99         self:call(portname, profile, ret)
100     end
101     setmetatable(obj, {__call=call_func})
102     return obj
103 end
104
105
106
107
108 local Entry = {}
109 Entry.new = function(listener, autoclean)
110     local obj = {}
111     obj.listener  = listener
112     obj.autoclean = autoclean
113     return obj
114 end
115
116
117
118
119 PortConnectListener.PortConnectListenerHolder = {}
120 PortConnectListener.PortConnectListenerHolder.new = function()
121     local obj = {}
122     obj._listeners = {}
123     function obj:addListener(listener, autoclean)
124         table.insert(self._listeners, Entry.new(listener, autoclean))
125     end
126     function obj:removeListener(listener)
127         for i,_listener in ipairs(self._listeners) do
128             if _listener.listener == listener then
129                 if _listener.autoclean then
130                     table.remove(self._listeners, i)
131                 end
132             end
133         end
134     end
135     function obj:notify(portname, profile)
136         for i, listener in ipairs(self._listeners) do
137             listener.listener:call(portname, profile)
138         end
139     end
140     return obj
141 end
142
143
144
145
146
147 PortConnectListener.PortConnectRetListenerHolder = {}
148 PortConnectListener.PortConnectRetListenerHolder.new = function()
149     local obj = {}
150     obj._listeners = {}
151     function obj:addListener(listener, autoclean)
152         table.insert(self._listeners, Entry.new(listener, autoclean))
153     end
154     function obj:removeListener(listener)
155         for i,_listener in ipairs(self._listeners) do
156             if _listener.listener == listener then
157                 if _listener.autoclean then
158                     table.remove(self._listeners, i)
159                 end
160             end
161         end
162     end
163     function obj:notify(portname, profile, ret)
164         for i, listener in ipairs(self._listeners) do
165             local ret = listener.listener:call(portname, profile, ret)
166         end
167     end
168     return obj
169 end
170
171
172
173 PortConnectListener.PortConnectListeners = {}
174
175 PortConnectListener.PortConnectListeners.new = function()
176     local obj = {}
177
178     obj.portconnect_num = PortConnectListener.PortConnectListenerType.PORT_CONNECT_LISTENER_NUM
179     obj.portconnect_ = {}
180     for i = 1,obj.portconnect_num do
181         table.insert(obj.portconnect_, PortConnectListener.PortConnectListenerHolder.new())
182     end
183
184     obj.portconnret_num = PortConnectListener.PortConnectRetListenerType.PORT_CONNECT_RET_LISTENER_NUM
185     obj.portconnret_ = {}
186     for i = 1,obj.portconnret_num do
187         table.insert(obj.portconnret_, PortConnectListener.PortConnectRetListenerHolder.new())
188     end
189
190
191     return obj
192 end
193
194
195
196
197 return PortConnectListener

File lua\openrtm\Properties.lua

1 ---------------------------------
2 --! @file Properties.lua
3 --! @brief プロパティ操作関数定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local Properties= {}
11 --_G["openrtm.Properties"] = Properties
12
13 local StringUtil = require "openrtm.StringUtil"
14 --string = require string
15
16 -- プロパティ初期化
17 -- @param argv argv.prop:コピー元のプロパティ、argv.key・argv.value:キーと値、argv.defaults_map:テーブル
18 Properties.new = function(argv)
19  local obj = {}
20  function obj:init()
21   self.default_value = ""
22   self.root = nil
23   self.empty = ""
24   self.leaf = {}
25   self.name  = ""
26   self.value = ""
27   if argv == nil then
28    argv = {}
29   end
30   if argv.prop ~= nil then
31    --print(argv.prop:str())
32    self.name = argv.prop.name
33    self.value = argv.prop.value
34    self.default_value = argv.prop.default_value
35    local keys = argv.prop:propertyNames()
36    --print(#keys)
37    for i, _key in ipairs(keys) do
38     --print(i, _key)
39     local node = argv.prop:getNode(_key)
40     --print(node)
41     if node ~= nil then
42      --print(_key, node.default_value)
43      self:setDefault(_key, node.default_value)
44      self:setProperty(_key, node.value)
45     end
46    end
47   end
48   if argv.key ~= nil then
49    self.name = argv.key
50    if argv.value == nil then
51     self.value = ""
52    else
53     self.value = argv.value
54    end
55   end
56   if argv.defaults_map ~= nil then
57    for _key, _value in pairs(argv.defaults_map) do
58     _key = StringUtil.eraseBothEndsBlank(_key)
59     _value = StringUtil.eraseBothEndsBlank(_value)
60     self:setDefault(_key, _value)
61    end
62   end
63   --[[
64   if argv.defaults_str ~= nil then
65    local _num = argv.num
66    if argv.num == nil then
67     _num = 100000
68    end
69    self:setDefaults(argv.defaults_str, _num)
70   end
71   ]]
72  end
73  -- キー取得
74  -- @return キー
75  function obj:getName()
76   return self.name
77  end
78  -- 値取得
79  -- @return 値
80  function obj:getValue()
81   return self.value
82  end
83  -- デフォルト値取得
84  -- @param key キー
85  -- @param default デフォルト値
86  -- @return 値
87  function obj:getDefaultValue(key, default)
88   return self.default_value
89  end
90  -- ルート要素の取得
91  -- @return ルート要素
92  function obj:getRoot()
93   return self.root
94  end
95  -- プロパティ値取得
96  -- @param key キー
97  -- @param default デフォルト値
98  -- @return プロパティ
99  function obj:getProperty(key, default)
100   --print(key)
101   if default == nil then
102    local keys = StringUtil.split(key, "%.")
103    local node = self:_getNode(keys, 1, self)
104    if node then
105     if node.value ~= "" then
106      return node.value
107     else
108      return node.default_value
109     end
110    end
111    return self.empty
112   else
113    local value = self:getProperty(key)
114    if value ~= "" then
115     return value
116    else
117     return default
118    end
119   end
120  end
121  -- デフォルト値取得
122  -- @param key キー
123  -- @return デフォルト値
124  function obj:getDefault(key)
125   local keys = StringUtil.split(key, "%.")
126   local node = self:_getNode(keys, 1, self)
127   if node ~= nil then
128    return node.default_value
129   end
130   return self.empty
131  end
132  -- プロパティ設定
133  -- @param key キー
134  -- @param value 値
135  -- @return プロパティ
136  function obj:setProperty(key, value)
137   --print(self.leaf)
138   if value ~= nil then
139    local keys = StringUtil.split(key, "%.")
140    --print(key,#keys)
141    local curr = self
142    for _i, _key in ipairs(keys) do
143     --print(curr)
144     local _next = curr:hasKey(_key)
145     if _next == nil then
146      _next = Properties.new({key=_key})
147      _next.root = curr
148      table.insert(curr.leaf,_next)
149     end
150     curr = _next
151    end
152
153    curr.value = value
154    return retval
155   else
156    --print(self:getProperty(key))
157    self:setProperty(key, self:getProperty(key))
158    local prop = self:getNode(key)
159    return prop.value
160   end
161   return self.root
162  end
163  -- デフォルト値設定
164  -- @param key キー
165  -- @param value デフォルト値
166  -- @return 値
167  function obj:setDefault(key, value)
168   local keys = StringUtil.split(key, "%.")
169   local curr = self
170   --print(self.leaf)
171   --StringUtil.print_table(keys)
172   for _i, _key in ipairs(keys) do
173    local _next = curr:hasKey(_key)
174    if _next == nil then
175     _next = Properties.new({key=_key})
176     _next.root = curr
177     --print(curr.leaf, _next)
178     --print(#curr.leaf)
179     table.insert(curr.leaf, _next)
180    end
181    curr= _next
182   end
183   if value ~= "" and string.sub(value, -1) ~= "\n" then
184    value = string.sub(value, 0, -1)
185   end
186   curr.default_value = value
187   return value
188  end
189  --デフォルト値をテーブルから設定
190  -- @param defaults デフォルト値のテーブル
191  -- @param num 最大数
192  -- @return プロパティ
193  function obj:setDefaults(defaults, num)
194   if num == nil then
195    num = 10000
196   end
197
198   --[[for i = 1, #defaults/2 do
199    if i > num then
200     break
201    end
202    local _key = defaults[i*2-1]
203    local _value = defaults[i*2]
204    --print(_key, _value)
205    _key = StringUtil.eraseHeadBlank(_key)
206    _key = StringUtil.eraseTailBlank(_key)
207    _value = StringUtil.eraseHeadBlank(_value)
208    _value = StringUtil.eraseTailBlank(_value)
209    self:setDefault(_key, _value)
210   end
211   ]]
212         local count = 1
213         for _key,_value in pairs(defaults) do
214             if num < count then
215                 break
216             end
217             _key = StringUtil.eraseBothEndsBlank(_key)
218             _value = StringUtil.eraseBothEndsBlank(_value)
219             self:setDefault(_key, _value)
220             count = count+1
221         end
222         return self.leaf
223     end
224     -- 指定ストリームにプロパティを出力
225     -- @param out アウトストリーム
226     function obj:list(out)
227         self:_store(out, "", self)
228         return
229     end
230     -- 指定ストリームからプロパティを入力
231     -- @param inStream インストリーム
232     -- @return プロパティ
233     function obj:loadStream(inStream)
234         pline = ""
235         for i, readStr in ipairs(inStream) do
236             if readStr ~= "" then
237                 local _str = readStr
238                 _str = StringUtil.eraseHeadBlank(_str)
239                 local s = string.sub(_str,0,1)
240                 if s == "#" or s == "!" or s == "\n" then
241                 else
242                     --_str = _str.rstrip('\r\n')
243                     if string.sub(_str,-1) == "\\" and not StringUtil.isEscaped(_str, #_str-1) then
244                         local tmp = string.sub(_str,0,-1)
245                         tmp = StringUtil.eraseTailBlank(tmp)
246                         pline = pline..tmp
247                     else
248                         pline = pline.._str
249                         local key, value = self:splitKeyValue(pline)
250                         key = StringUtil.unescape(key)
251                         key = StringUtil.eraseHeadBlank(key)
252                         key = StringUtil.eraseHeadBlank(key)
253                         value = StringUtil.unescape(value)
254                         value = StringUtil.eraseHeadBlank(value)
255                         value = StringUtil.eraseHeadBlank(value)
256                         self:setProperty(key, value)
257                         pline = ""
258                     end
259                 end
260             end
261         end
262         return self.leaf
263     end
264     -- 指定ストリームにヘッダを記述したプロパティを出力
265     -- @param out アウトストリーム
266     -- @param header ヘッダ
267     function obj:store(out, header)
268         out.write("#"..header.."\n")
269         self:_store(out, "", self)
270     end
271     -- プロパティのキー一覧を取得
272     -- @return キー一覧
273     function obj:propertyNames()
274         local names = {}
275         for i, leaf in ipairs(self.leaf) do
276             self:_propertyNames(names, leaf.name, leaf)
277         end
278         return names
279     end
280     -- プロパティのキーの数取得
281     -- @return キーの数
282     function obj:size()
283         return #self:propertyNames()
284     end
285     -- 指定キーのノードを検索
286     -- @param key キー
287     -- @return ノード
288     function obj:findNode(key)
289         if key == nil then
290             return nil
291         end
292         --keys = {}
293         --self:split(key, '%.', keys)
294         local keys = StringUtil.split(key, "%.")
295         --print(keys[0])
296         --print(self:_getNode(keys, 1, self))
297         return self:_getNode(keys, 1, self)
298     end
299     -- 指定キーのノードを取得
300     -- @param key キー
301     -- @return ノード
302     function obj:getNode(key)
303         if key == nil then
304             return self
305         end
306         local leaf = self:findNode(key)
307         --print(leaf, type(leaf))
308
309         if leaf ~= nil then
310             return leaf
311         end
312         self:createNode(key)
313         --print(self:findNode(key), type(self:findNode(key)))
314         return self:findNode(key)
315     end
316     -- 指定キーのノードを生成
317     -- @param key キー
318     -- @return true:生成成功、false:生成失敗
319     function obj:createNode(key)
320         if key == "" then
321             return false
322         end
323         if self:findNode(key) ~= nil then
324             return false
325         end
326         self:setProperty(key,"")
327         return true
328     end
329     -- ノード削除
330     -- @param leaf_name キー
331     -- @return プロパティ
332     function obj:removeNode(leaf_name)
333         for i, leaf in ipairs(self.leaf) do
334             if leaf.name == leaf_name then
335                 local prop = leaf
336                 table.remove(self.leaf, i)
337                 return prop
338             end
339         end
340         return nil
341
342     end
343     -- キーの存在確認
344     -- @param key キー
345     -- @return プロパティ
346     function obj:hasKey(key)
347         --print(self.leaf)
348         for i, leaf in ipairs(self.leaf) do
349             if leaf.name == key then
350                 return leaf
351             end
352         end
353         return nil
354     end
355     -- プロパティ全削除
356     function obj:clear()
357         self.leaf = {}
358     end
359     -- プロパティの追加
360     -- @param prop 追加元のプロパティ
361     -- @return 追加先のプロパティ
362     function obj:mergeProperties(prop)
363         local keys = prop:propertyNames()
364         for i = 1, prop:size() do
365             self:setProperty(keys[i], prop:getProperty(keys[i]))
366         end
367         return self
368     end
369     -- 文字列からキーと値を取り出し
370     -- @param _str 文字列(key:value)
371     -- @param key キー一覧
372     -- @param value 値一覧
373     -- @return プロパティ
374     function obj:splitKeyValue(_str)
375
376         local key = ""
377         local value = ""
378         local length = #_str
379         for i = 1, length do
380             local s = string.sub(_str,i,i)
381             if (s == ":" or s == "=") and not StringUtil.isEscaped(_str, i) then
382                 key = string.sub(_str,1,i-1)
383                 value = string.sub(_str,i+1)
384                 return key, value
385             end
386         end
387         for i = 1, length do
388             if s == " " and not StringUtil.isEscaped(_str, i) then
389                 key = string.sub(_str,1,i-1)
390                 value = string.sub(_str,i+1)            
391                 return key, value
392             end
393         end
394         key = _str
395         value = ""
396         return key, value
397     end
398     -- 文字列を分割する
399     -- @param _str 文字列
400     -- @param delim 分割文字
401     -- @param value 値一覧
402     -- @return true;分割成功、false:分割失敗
403     function obj:split( _str, delim, value)
404         if _str == "" then
405             return false
406         end
407         local begin_it = 0
408         local length = #_str
409         for end_it = 1,length do
410             if string.sub(_str,end_it,end_it) == delim and not StringUtil.isEscaped(_str, end_it) then
411                 table.insert(value,string.sub(_str,begin_it, end_it))
412                 begin_it = end_it+1
413             end
414         end
415         return true
416     end
417     -- ノード取得
418     -- @param keys キー一覧
419     -- @param index キー一覧のインデックス
420     -- @param curr 現在のノード
421     -- @return 次のノード
422     function obj:_getNode(keys, index, curr)
423         --print(keys[index])
424         local _next = curr:hasKey(keys[index])
425         --print(_next)
426         if _next == nil then
427             return nil
428         end
429         if index < #keys then
430             index = index + 1
431             return _next:_getNode(keys, index, _next)
432         else
433             return _next
434         end
435     end
436     -- ノードのキー一覧取得
437     -- @param names キー一覧
438     -- @param curr_name 現在探索しているキー
439     -- @param curr 現在のノード
440     function obj:_propertyNames(names, curr_name, curr)
441         if #curr.leaf > 0 then
442             for i = 1, #curr.leaf do
443                 local next_name = curr_name.."."..curr.leaf[i].name
444                 self:_propertyNames(names, next_name, curr.leaf[i])
445             end
446         else
447             table.insert(names,curr_name)
448         end
449     end
450     -- 指定ストリームにプロパティを出力
451     -- @param out アウトストリーム
452     -- @param curr_name 現在のキー
453     -- @param curr 現在のノード
454     function obj:_store(out, curr_name, curr)
455         if #curr.leaf > 0 then
456             for i = 1, #curr.leaf do
457                 local next_name = ""
458                 if curr_name == "" then
459                     next_name = curr.leaf[i].name
460                 else
461                     next_name = curr_name+"."+curr.leaf[i].name
462                 end
463                 self:_store(out, next_name, curr.leaf[i])
464             end
465         else
466             local val = curr.value
467             if val == "" then
468                 val = curr.default_value
469                 out.write(curr_name..": "..val.."\n")
470             end
471         end
472     end
473     -- インデント生成
474     -- @param index 現在のインデント数
475     -- @return インデント
476     function obj:indent(index)
477         --print("indent")
478         local space = ""
479         for i = 1, index-1 do
480             space = space.." "
481         end
482         return space
483     end
484     -- プロパティを出力用に文字列に変換
485     -- @param out 出力文字列
486     -- @param curr 現在のノード
487     -- @param index インデント数
488     -- @return 文字列
489     function obj:_dump(out, curr, index)
490         if index ~= 0 then
491             out[1] = out[1]..self:indent(index).."- "..curr.name
492         end
493         if #curr.leaf == 0 then
494             --print("test",curr.default_value, curr.value)
495             if curr.value == "" then
496                 out[1] = out[1]..": "..tostring(curr.default_value).."\n"
497             else
498                 out[1] = out[1]..": "..tostring(curr.value).."\n"
499             end
500             return out[1]
501         end
502         if index ~= 0 then
503             out[1] = out[1].."\n"
504         end
505         for i = 1, #curr.leaf do
506             self:_dump(out, curr.leaf[i], index + 1)
507         end
508         return out[1]
509     end
510     -- プロパティ取得
511     -- @return プロパティ
512     function obj:getLeaf()
513         return self.leaf
514     end
515
516     -- ファイルストリームからプロパティを設定
517     -- @param inStream ファイルストリーム
518     function obj:load(inStream)
519         local pline = ""
520         for readStr in inStream:lines() do
521             
522             local _str = StringUtil.eraseHeadBlank(readStr)
523
524
525             if string.sub(_str,1,1) == "#" or string.sub(_str,1,1) == "!" or string.sub(_str,1,1) == "\n" then
526             else
527
528                 _str = StringUtil.eraseHeadBlank(_str)
529
530                 if string.sub(_str, #_str, #_str) == "\\" and not StringUtil.isEscaped(_str, #_str) then
531
532                     local tmp = string.sub(_str,1,#_str-1)
533                     tmp = StringUtil.eraseTailBlank(tmp)
534
535                     pline = pline..tmp
536                 else
537                     pline = pline.._str
538
539                     
540                     --print(key)
541                     local key, value = self:splitKeyValue(pline)
542                     key = StringUtil.unescape(key)
543                     key = StringUtil.eraseHeadBlank(key)
544                     key = StringUtil.eraseTailBlank(key)
545
546                     value = StringUtil.unescape(value)
547                     value = StringUtil.eraseHeadBlank(value)
548                     value = StringUtil.eraseTailBlank(value)
549                     --print(value)
550                     --print(key, value)
551                     self:setProperty(key, value)
552                     pline = ""
553                 end
554             end
555         end
556     end
557     -- 文字列変換関数
558     -- @param self 自身のオブジェクト
559     -- @return 変換後の文字列
560     local str_func = function(self)
561         local str = {}
562         table.insert(str,"")
563         --print(self._dump)
564         return self:_dump(str, self, 0)
565     end
566     obj:init()
567
568     setmetatable(obj, {__tostring =str_func})
569     return obj
570 end
571
572
573 return Properties

File lua\openrtm\PublisherBase.lua

1 ---------------------------------
2 --! @file PublisherBase.lua
3 --! @brief パブリッシャー基底クラス定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local PublisherBase= {}
11 --_G["openrtm.PublisherBase"] = PublisherBase
12
13
14 local GlobalFactory = require "openrtm.GlobalFactory"
15 local Factory = GlobalFactory.Factory
16 local DataPortStatus = require "openrtm.DataPortStatus"
17
18 -- パブリッシャー基底オブジェクト初期化
19 -- @return パブリッシャー
20 PublisherBase.new = function()
21     local obj = {}
22     -- 初期化時にプロパティを設定
23     -- @param prop プロパティ
24     -- @return リターンコード
25     function obj:init(prop)
26         return DataPortStatus.PORT_OK
27     end
28     -- サービスコンシューマ設定
29     -- @param consumer コンシューマオブジェクト
30     -- @return リターンコード
31     function obj:setConsumer(consumer)
32         return DataPortStatus.PORT_OK
33     end
34     -- バッファ設定
35     -- @param buffer バッファ
36     -- @return リターンコード
37     function obj:setBuffer(buffer)
38         return DataPortStatus.PORT_OK
39     end
40     -- コールバック設定
41     -- @param info プロファイル
42     -- @param listeners コールバック関数
43     -- @return リターンコード
44     function obj:setListener(info, listeners)
45         return DataPortStatus.PORT_OK
46     end
47     -- データ書き込み
48     -- @param data データ
49     -- @param sec タイムアウト時間[s]
50     -- @param usec タイムアウト時間[us]
51     -- @return リターンコード
52     function obj:write(data, sec, usec)
53         return DataPortStatus.PORT_OK
54     end
55     -- アクティブ状態化の確認
56     -- @return true:アクティブ状態、false:非アクティブ状態
57     function obj:isActive()
58         return false
59     end
60     -- アクティブ化
61     -- @return リターンコード
62     function obj:activate()
63         return DataPortStatus.PORT_OK
64     end
65     -- 非アクティブ化
66     -- @return リターンコード
67     function obj:deactivate()
68         return DataPortStatus.PORT_OK
69     end
70     return obj
71 end
72
73
74 PublisherBase.PublisherFactory = {}
75 setmetatable(PublisherBase.PublisherFactory, {__index=Factory.new()})
76
77 function PublisherBase.PublisherFactory:instance()
78     return self
79 end
80
81 return PublisherBase

File lua\openrtm\PublisherFlush.lua

1 ---------------------------------
2 --! @file PublisherFlush.lua
3 --! @brief 即座にデータ書き込みを実行するパブリッシャー定義
4 ---------------------------------
5
6
7 --[[
8 Copyright (c) 2017 Nobuhiko Miyamoto
9 ]]
10
11 local PublisherFlush= {}
12 --_G["openrtm.PublisherFlush"] = PublisherFlush
13
14 local DataPortStatus = require "openrtm.DataPortStatus"
15 local PublisherBase = require "openrtm.PublisherBase"
16 local PublisherFactory = PublisherBase.PublisherFactory
17 local Factory = require "openrtm.Factory"
18
19 local ConnectorListener = require "openrtm.ConnectorListener"
20 local ConnectorDataListenerType = ConnectorListener.ConnectorDataListenerType
21
22
23 -- PublisherFlush初期化
24 -- @return PublisherFlush
25 PublisherFlush.new = function()
26     local obj = {}
27     setmetatable(obj, {__index=PublisherBase.new(info, provider)})
28     local Manager = require "openrtm.Manager"
29     obj._rtcout = Manager:instance():getLogbuf("PublisherFlush")
30     obj._consumer  = nil
31     obj._active    = false
32     obj._profile   = nil
33     obj._listeners = nil
34     obj._retcode   = DataPortStatus.PORT_OK
35     
36     -- 初期化時にプロパティを設定
37     -- @param prop プロパティ
38     -- @return リターンコード
39     function obj:init(prop)
40         self._rtcout:RTC_TRACE("init()")
41         return DataPortStatus.PORT_OK
42     end
43     -- サービスコンシューマ設定
44     -- @param consumer コンシューマオブジェクト
45     -- @return リターンコード
46     function obj:setConsumer(consumer)
47         self._rtcout:RTC_TRACE("setConsumer()")
48         if consumer == nil then
49             return DataPortStatus.INVALID_ARGS
50         end
51
52         self._consumer = consumer
53
54         return DataPortStatus.PORT_OK
55     end
56     -- バッファ設定
57     -- @param buffer バッファ
58     -- @return リターンコード
59     function obj:setBuffer(buffer)
60         self._rtcout:RTC_TRACE("setBuffer()")
61         return DataPortStatus.PORT_OK
62     end
63     -- コールバック設定
64     -- @param info プロファイル
65     -- @param listeners コールバック関数
66     -- @return リターンコード
67     function obj:setListener(info, listeners)
68         self._rtcout:RTC_TRACE("setListeners()")
69
70         if listeners == nil then
71             self._rtcout:RTC_ERROR("setListeners(listeners == 0): invalid argument")
72             return DataPortStatus.INVALID_ARGS
73         end
74
75         self._profile = info
76         self._listeners = listeners
77
78         return DataPortStatus.PORT_OK
79     end
80     -- データ書き込み
81     -- @param data データ
82     -- @param sec タイムアウト時間[s]
83     -- @param usec タイムアウト時間[us]
84     -- @return リターンコード
85     function obj:write(data, sec, usec)
86         self._rtcout:RTC_PARANOID("write()")
87         if self._consumer == nil or self._listeners == nil then
88             return DataPortStatus.PRECONDITION_NOT_MET
89         end
90
91         if self._retcode == DataPortStatus.CONNECTION_LOST then
92             self._rtcout:RTC_DEBUG("write(): connection lost.")
93             return self._retcode
94         end
95
96         self:onSend(data)
97
98         self._retcode = self._consumer:put(data)
99
100         if self._retcode == DataPortStatus.PORT_OK then
101             self:onReceived(data)
102             return self._retcode
103         elseif self._retcode == DataPortStatus.PORT_ERROR then
104             self:onReceiverError(data)
105             return self._retcode
106         elseif self._retcode == DataPortStatus.SEND_FULL then
107             self:onReceiverFull(data)
108             return self._retcode
109         elseif self._retcode == DataPortStatus.SEND_TIMEOUT then
110             self:onReceiverTimeout(data)
111             return self._retcode
112         elseif self._retcode == DataPortStatus.CONNECTION_LOST then
113             self:onReceiverTimeout(data)
114             return self._retcode
115         elseif self._retcode == DataPortStatus.UNKNOWN_ERROR then
116             self:onReceiverError(data)
117             return self._retcode
118         else
119             self:onReceiverError(data)
120             return self._retcode
121         end
122     end
123     -- アクティブ状態化の確認
124     -- @return true:アクティブ状態、false:非アクティブ状態
125     function obj:isActive()
126         return self._active
127     end
128     -- アクティブ化
129     -- @return リターンコード
130     function obj:activate()
131         if self._active then
132             return DataPortStatus.PRECONDITION_NOT_MET
133         end
134
135         self._active = true
136
137         return DataPortStatus.PORT_OK
138     end
139     -- 非アクティブ化
140     -- @return リターンコード
141     function obj:deactivate()
142         if not self._active then
143             return DataPortStatus.PRECONDITION_NOT_MET
144         end
145
146         self._active = false
147
148         return DataPortStatus.PORT_OK
149     end
150
151     -- データ送信後のコールバック実行
152     -- @param data データ
153     function obj:onSend(data)
154         if self._listeners ~= nil and self._profile ~= nil then
155             self._listeners.connectorData_[ConnectorDataListenerType.ON_SEND]:notify(self._profile, data)
156         end
157     end
158
159     -- データ受信後のコールバック実行
160     -- @param data データ
161     function obj:onReceived(data)
162         if self._listeners ~= nil and self._profile ~= nil then
163             self._listeners.connectorData_[ConnectorDataListenerType.ON_RECEIVED]:notify(self._profile, data)
164         end
165     end
166     -- データ受信フル時のコールバック実行
167     -- @param data データ
168     function obj:onReceiverFull(data)
169         if self._listeners ~= nil and self._profile ~= nil then
170             self._listeners.connectorData_[ConnectorDataListenerType.ON_RECEIVER_FULL]:notify(self._profile, data)
171         end
172     end
173     -- データ受信タイムアウト時のコールバック実行
174     -- @param data データ
175     function obj:onReceiverTimeout(data)
176         if self._listeners ~= nil and self._profile ~= nil then
177             self._listeners.connectorData_[ConnectorDataListenerType.ON_RECEIVER_TIMEOUT]:notify(self._profile, data)
178         end
179     end
180     -- データ受信エラー時のコールバック実行
181     -- @param data データ
182     function obj:onReceiverError(data)
183         if self._listeners ~= nil and self._profile ~= nil then
184             self._listeners.connectorData_[ConnectorDataListenerType.ON_RECEIVER_ERROR]:notify(self._profile, data)
185         end
186     end
187
188     return obj
189 end
190
191 -- PublisherFlush生成ファクトリ登録
192 PublisherFlush.Init = function()
193     PublisherFactory:instance():addFactory("flush",
194         PublisherFlush.new,
195         Factory.Delete)
196 end
197
198
199 return PublisherFlush

File lua\openrtm\RingBuffer.lua

1 ---------------------------------
2 --! @file RingBuffer.lua
3 --! @brief リングバッファ定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local RingBuffer= {}
11 --_G["openrtm.RingBuffer"] = RingBuffer
12
13
14 local BufferBase = require "openrtm.BufferBase"
15 local TimeValue = require "openrtm.TimeValue"
16 local BufferStatus = require "openrtm.BufferStatus"
17 local StringUtil = require "openrtm.StringUtil"
18
19
20 RingBuffer.RINGBUFFER_DEFAULT_LENGTH = 8
21
22 -- リングバッファ初期化
23 -- @param length バッファ長
24 -- @return リングバッファ
25 RingBuffer.new = function(length)
26     local obj = {}
27     setmetatable(obj, {__index=BufferBase.new()})
28     if length == nil then
29         length = RingBuffer.RINGBUFFER_DEFAULT_LENGTH
30     end
31     obj._overwrite = true
32     obj._readback = true
33     obj._timedwrite = false
34     obj._timedread  = false
35     obj._wtimeout = TimeValue.new(1,0)
36     obj._rtimeout = TimeValue.new(1,0)
37     obj._length   = length
38     obj._wpos = 0
39     obj._rpos = 0
40     obj._fillcount = 0
41     obj._wcount = 0
42     obj._buffer = {}
43
44     -- 初期化時にプロパティを設定
45     -- @param prop プロパティ
46     function obj:init(prop)
47         self:__initLength(prop)
48         self:__initWritePolicy(prop)
49         self:__initReadPolicy(prop)
50     end
51
52     -- バッファ長設定、取得
53     -- @param n バッファ長
54     -- @return バッファステータス(nがnilの場合は長さ)
55     -- BUFFER_OK:正常に設定完了、NOT_SUPPORTED:長さが不正
56     function obj:length(n)
57         if n == nil then
58             return self._length
59         end
60
61         if n < 1 then
62             return BufferStatus.NOT_SUPPORTED
63         end
64
65         self._buffer = {}
66         self._length = n
67         self:reset()
68         return BufferStatus.BUFFER_OK
69     end
70
71     -- バッファポインタをリセット
72     function obj:reset()
73         self._fillcount = 0
74         self._wcount = 0
75         self._wpos = 0
76         self._rpos = 0
77     end
78
79     -- 指定位置まで書き込みポインタを進めた場合のバッファ取得
80     -- @param n ポインタの位置
81     -- @return 現在の位置のバッファ
82     function obj:wptr(n)
83         if n == nil then
84             n = 0
85         end
86         return self._buffer[(self._wpos + n + self._length) % self._length + 1]
87     end
88
89     -- 書き込みポインタの位置を進める
90     -- @param n ポインタの位置
91     -- @return バッファステータス
92     -- BUFFER_OK:正常に位置設定完了、PRECONDITION_NOT_MET:移動不可
93     function obj:advanceWptr(n)
94         if n == nil then
95             n = 1
96         end
97
98         if (n > 0 and n > (self._length - self._fillcount)) or
99               (n < 0 and n < (-self._fillcount)) then
100             return BufferStatus.PRECONDITION_NOT_MET
101         end
102
103         self._wpos = (self._wpos + n + self._length) % self._length
104         self._fillcount = self._fillcount + n
105         self._wcount = self._wcount + n
106         return BufferStatus.BUFFER_OK
107     end
108
109     -- データ書き込み
110     -- @param value データ
111     -- @return バッファステータス
112     function obj:put(value)
113         self._buffer[self._wpos+1] = value
114         return BufferStatus.BUFFER_OK
115     end
116
117     -- データ書き込み
118     -- @param value データ
119     -- @param sec タイムアウト時間[s]
120     -- @param nsec タイムアウト時間[ns]
121     -- @return バッファステータス
122     function obj:write(value, sec, nsec)
123         if sec == nil then
124             sec = -1
125         end
126         if nsec == nil then
127             nsec = 0
128         end
129         if self:full() then
130             local timedwrite = self._timedwrite
131             local overwrite  = self._overwrite
132             if overwrite then
133                 self:advanceRptr()
134             else
135                 return BufferStatus.BUFFER_FULL
136             end
137             
138         end
139
140         self:put(value)
141         self:advanceWptr(1)
142         return BufferStatus.BUFFER_OK
143     end
144
145     -- 書き込み可能なバッファ残り長さ
146     -- @return 長さ
147     function obj:writable()
148         return self._length - self._fillcount
149     end
150
151     -- バッファフルの判定
152     -- @return true:バッファフル
153     function obj:full()
154         return (self._length == self._fillcount)
155     end
156
157     -- 指定位置まで読み込みポインタを進めた場合のバッファ取得
158     -- @param n ポインタの位置
159     -- @return 現在の位置のバッファ
160     function obj:rptr(n)
161         if n == nil then
162             n = 0
163         end
164         return self._buffer[(self._rpos + n + self._length) % self._length + 1]
165     end
166
167     -- 読み込みポインタの位置を進める
168     -- @param n ポインタの位置
169     -- @return バッファステータス
170     -- BUFFER_OK:正常に位置設定、PRECONDITION_NOT_MET:位置が不正
171     function obj:advanceRptr(n)
172         if n == nil then
173             n = 1
174         end
175
176         if (n > 0 and n > self._fillcount) or
177               (n < 0 and n < (self._fillcount - self._length)) then
178           return BufferStatus.PRECONDITION_NOT_MET
179         end
180
181         self._rpos = (self._rpos + n + self._length) % self._length
182         self._fillcount = self._fillcount - n
183         return BufferStatus.BUFFER_OK
184     end
185
186     -- データ読み込み
187     -- @param value value._dataにデータ格納
188     -- @return バッファステータス(valueがnilの場合はバッファの値を返す)
189     function obj:get(value)
190         if value == nil then
191             return self._buffer[self._rpos+1]
192         end
193
194         value._data = self._buffer[self._rpos+1]
195         return BufferStatus.BUFFER_OK
196     end
197
198     -- データ読み込み
199     -- @param value value._dataにデータ格納
200     -- @param sec タイムアウト時間[s]、デフォルトは-1
201     -- @param nsec タイムアウト時間[ns]、デフォルトは0
202     -- @return バッファステータス
203     -- BUFFER_OK:正常にデータ読み込み、BUFFER_EMPTY:バッファが空
204     function obj:read(value, sec, nsec)
205         if sec == nil then
206             sec = -1
207         end
208         if nsec == nil then
209             nsec = 0
210         end
211         if self:empty() then
212             local timedread = self._timedread
213             local readback  = self._readback
214             if readback then
215                 if not (self._wcount > 0) then
216                     return BufferStatus.BUFFER_EMPTY
217                 end
218                 self:advanceRptr(-1)
219             else
220                 return BufferStatus.BUFFER_EMPTY
221             end
222         end
223         self:get(value)
224         self:advanceRptr()
225         return BufferStatus.BUFFER_OK
226     end
227
228     -- 読み込み可能なデータ長さ取得
229     -- @return データ長さ
230     function obj:readable()
231         return self._fillcount
232     end
233     -- バッファが空かの判定
234     -- @return true:空
235     function obj:empty()
236         return (self._fillcount == 0)
237     end
238     -- 初期化時にバッファ長さ設定
239     -- @param prop プロパティ
240     function obj:__initLength(prop)
241         local n = tonumber(prop:getProperty("length"))
242         if n ~= nil then
243             self:length(n)
244         end
245     end
246     -- バッファ書き込み時のポリシー設定
247     -- @param prop プロパティ
248     function obj:__initWritePolicy(prop)
249         local policy = StringUtil.normalize(prop:getProperty("write.full_policy"))
250         if policy == "overwrite" then
251             self._overwrite  = true
252               self._timedwrite = false
253         elseif policy == "do_nothing" then
254             self._overwrite  = false
255               self._timedwrite = false
256         end
257
258     end
259     -- バッファ読み込み時のポリシー設定
260     -- @param prop プロパティ
261     function obj:__initReadPolicy(prop)
262         local policy = StringUtil.normalize(prop:getProperty("read.empty_policy"))
263         if policy == "readback" then
264             self._readback  = true
265               self._timedread = false
266         elseif policy == "do_nothing" then
267             self._readback  = false
268               self._timedread = false
269         end
270     end
271     obj:reset()
272
273
274     return obj
275 end
276
277
278 return RingBuffer

File lua\openrtm\RTCUtil.lua

1 ---------------------------------
2 --! @file RTCUtil.lua
3 --! @brief RTCヘルパ関数
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local RTCUtil= {}
11 --_G["openrtm.RTCUtil"] = RTCUtil
12
13
14 local oil = require "oil"
15
16 -- オブジェクトのプロキシサーバント生成
17 -- @param orb ORB
18 -- @param ior IOR文字列
19 -- @param idl IDLファイル
20 -- @return サーバント
21 RTCUtil.newproxy = function(orb, ior, idl)
22  if type(ior) == "table" then
23   if ior.getObjRef ~= nil then
24    return ior:getObjRef()
25   end
26  end
27  if oil.VERSION == "OiL 0.4 beta" then
28   if type(ior) == "table" then
29    ior = orb:tostring(ior)
30   end
31   return orb:newproxy(ior,idl)
32  elseif oil.VERSION == "OiL 0.5" or oil.VERSION == "OiL 0.6" then
33   return orb:newproxy(ior,nil,idl)
34  end
35  return nil
36 end
37
38 -- オブジェクトリファレンス取得
39 -- @param orb ORB
40 -- @param servant サーバント
41 -- @param idl IDLファイル
42 -- @return オブジェクトリファレンス
43 RTCUtil.getReference = function(orb, servant, idl)
44  if oil.VERSION == "OiL 0.4 beta" then
45   local ior = orb:tostring(servant)
46   return RTCUtil.newproxy(orb, ior, idl)
47  elseif oil.VERSION == "OiL 0.5" or oil.VERSION == "OiL 0.6" then
48   return servant
49  end
50  return nil
51 end
52
53 -- データのインスタンスをデータ型から取得
54 -- @param data_type データ型(文字列)
55 -- @return データのインスタンス
56 RTCUtil.instantiateDataType = function(data_type)
57  local Manager = require "openrtm.Manager"
58  local orb = Manager:getORB()
59  local data = orb.types:lookup(data_type)
60  local ret = {}
61  for k,v in pairs(data.fields) do
62   RTCUtil.getDataType(v, ret)
63  end
64  return ret
65  --return {tm={sec=0,nsec=0},data={}}
66 end
67
68 -- データの要素を抽出する
69 -- @param data データ
70 -- @param ret データのインスタンス
71 RTCUtil.getDataType = function(data, ret)
72  if data.type_def ~= nil then
73   --print(data.type_def._type)
74   if data.type_def._type == "struct" then
75    ret[data.name] = {}
76   elseif data.type_def._type == "ulong" then
77    ret[data.name] = 0
78    return
79   elseif data.type_def._type == "long" then
80    ret[data.name] = 0
81    return
82   elseif data.type_def._type == "short" then
83    ret[data.name] = 0
84    return
85   elseif data.type_def._type == "ushort" then
86    ret[data.name] = 0
87    return
88   elseif data.type_def._type == "octet" then
89    ret[data.name] = 0x00
90    return
91   elseif data.type_def._type == "string" then
92    ret[data.name] = ""
93    return
94   elseif data.type_def._type == "float" then
95    ret[data.name] = 0
96    return
97   elseif data.type_def._type == "double" then
98    ret[data.name] = 0
99    return
100   --[[
101   elseif data.type_def._type == "ufloat" then
102    ret[data.name] = 0
103    return
104   elseif data.type_def._type == "udouble" then
105    ret[data.name] = 0
106    return
107   --]]
108         elseif data.type_def._type == "char" then
109             ret[data.name] = ""
110             return
111         elseif data.type_def._type == "boolean" then
112             ret[data.name] = true
113             return
114         elseif data.type_def._type == "sequence" then
115             ret[data.name] = {}
116             return
117         else
118             ret[data.name] = 0
119             return
120         end
121         for k,v in pairs(data.type_def.fields) do
122             RTCUtil.getDataType(v, ret[data.name])
123         end
124     end
125 end
126
127
128 return RTCUtil

File lua\openrtm\RTObject.lua

1 ---------------------------------
2 --! @file RTObject.lua
3 --! @brief RTC基底クラス定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local RTObject= {}
11 --_G["openrtm.RTObject"] = RTObject
12
13 local oil = require "oil"
14 local PortAdmin = require "openrtm.PortAdmin"
15 local Properties = require "openrtm.Properties"
16 local ConfigAdmin = require "openrtm.ConfigAdmin"
17 local SdoServiceAdmin = require "openrtm.SdoServiceAdmin"
18 local SdoConfiguration = require "openrtm.SdoConfiguration"
19 local Configuration_impl = SdoConfiguration.Configuration_impl
20 local ComponentActionListener = require "openrtm.ComponentActionListener"
21 local ComponentActionListeners = ComponentActionListener.ComponentActionListeners
22 local PortConnectListener = require "openrtm.PortConnectListener"
23 local PortConnectListeners = PortConnectListener.PortConnectListeners
24 local ManagerConfig = require "openrtm.ManagerConfig"
25 local ExecutionContextBase = require "openrtm.ExecutionContextBase"
26 local ExecutionContextFactory = ExecutionContextBase.ExecutionContextFactory
27 local StringUtil = require "openrtm.StringUtil"
28 local NVUtil = require "openrtm.NVUtil"
29 local CORBA_SeqUtil = require "openrtm.CORBA_SeqUtil"
30 local RTCUtil = require "openrtm.RTCUtil"
31 local PreComponentActionListenerType = ComponentActionListener.PreComponentActionListenerType
32 local PostComponentActionListenerType = ComponentActionListener.PostComponentActionListenerType
33 local PortActionListenerType = ComponentActionListener.PortActionListenerType
34 local ExecutionContextActionListenerType = ComponentActionListener.ExecutionContextActionListenerType
35 local PreComponentActionListener = ComponentActionListener.PreComponentActionListener
36 local PostComponentActionListener = ComponentActionListener.PostComponentActionListener
37 local PortActionListener = ComponentActionListener.PortActionListener
38 local ExecutionContextActionListener = ComponentActionListener.ExecutionContextActionListener
39 local ComponentActionListeners = ComponentActionListener.ComponentActionListeners
40
41 local uuid = require "uuid"
42
43
44 RTObject.ECOTHER_OFFSET = 1000
45
46
47 local default_conf = {
48   ["implementation_id"]="",
49   ["type_name"]="",
50   ["description"]="",
51   ["version"]="",
52   ["vendor"]="",
53   ["category"]="",
54   ["activity_type"]="",
55   ["max_instance"]="",
56   ["language"]="",
57   ["lang_type"]="",
58   ["conf"]=""}
59
60
61
62 local ec_copy = {}
63
64 -- 実行コンテキストのリストを連結する関数オブジェクト初期化
65 -- @param eclist 連結先のリスト
66 -- @return 実行コンテキストのリストを連結する関数オブジェクト
67 ec_copy.new = function(eclist)
68     local obj = {}
69     obj._eclist = eclist
70     -- 実行コンテキストのリストを連結する
71     -- @param self 自身のオブジェクト
72     -- @param ecs 連結元のリスト
73     local call_func = function(self, ecs)
74         if ecs ~= nil then
75             table.insert(self._eclist, ecs)
76         end
77     end
78     setmetatable(obj, {__call=call_func})
79     return obj
80 end
81
82
83
84 local ec_find = {}
85
86 -- 実行コンテキストのオブジェクトリファレンスが一致するかを確認する関数オブジェクト初期化
87 -- @param _ec 実行コンテキスト
88 -- @return 関数オブジェクト
89 ec_find.new = function(_ec)
90     local obj = {}
91     obj._ec = _ec
92
93
94     -- 実行コンテキストのオブジェクトリファレンスが一致するかを確認する
95     -- @param self 自身のオブジェクト
96     -- @param ecs 実行コンテキスト
97     -- @return true:一致、false:不一致
98     local call_func = function(self, ecs)
99         local ret = false
100         local success, exception = oil.pcall(
101             function()
102                 if ecs ~= nil then
103
104                     --print(#self._ec, #ecs)
105                     --for k, v in pairs(self._ec) do
106                     -- print( k, v )
107                     --end
108                     --print(self._ec:get_profile())
109                     --print(self._ec, ecs)
110                     ret = NVUtil._is_equivalent(self._ec, ecs, self._ec.getObjRef, ecs.getObjRef)
111                     --local Manager = require "openrtm.Manager"
112                     --local orb = Manager:instance():getORB()
113                     --ret = (orb:tostring(self._ec) == orb:tostring(ec))
114                     return
115                 end
116             end)
117         if not success then
118             print(exception)
119             return false
120         end
121
122         return ret
123     end
124     setmetatable(obj, {__call=call_func})
125     return obj
126 end
127
128
129 local svc_name = function(_id)
130     local obj = {}
131     obj._id = _id
132
133     local call_func = function(self, prof)
134         return (self._id == prof.id)
135     end
136     setmetatable(obj, {__call=call_func})
137     return obj
138 end
139
140 -- RTC基底オブジェクト初期化
141 -- @param manager マネージャ
142 -- @return RTC
143 RTObject.new = function(manager)
144
145     local obj = {}
146
147     --print(manager)
148     obj._manager = manager
149     obj._orb = obj._manager:getORB()
150     --print(obj._orb)
151     obj._portAdmin = PortAdmin.new(obj._manager:getORB())
152     obj._rtcout = obj._manager:getLogbuf("rtobject")
153     obj._created = true
154     obj._properties = Properties.new({defaults_map=default_conf})
155     --print(obj._properties:getNode("conf"),type(obj._properties:getNode("conf")))
156     obj._configsets = ConfigAdmin.new(obj._properties:getNode("conf"))
157     obj._profile = {instance_name="",type_name="",
158                   description="description",version="0", vendor="",
159                   category="",port_profiles={},
160                   parent=oil.corba.idl.null,properties={
161                   {name="implementation_id",value=""}, {name="type_name",value=""},
162                   {name="description",value=""},{name="version",value=""},
163                   {name="vendor",value=""},{name="category",value=""},
164                   {name="activity_type",value=""},{name="max_instance",value=""},
165                   {name="language",value=""},{name="lang_type",value=""},
166                   {name="instance_name",value=""}
167                   }
168                   }
169     obj._sdoservice = SdoServiceAdmin.new(obj)
170     obj._SdoConfigImpl = Configuration_impl.new(obj._configsets,obj._sdoservice)
171     obj._SdoConfig = obj._SdoConfigImpl:getObjRef()
172     obj._execContexts = {}
173
174     obj._sdoOwnedOrganizations = {}
175     obj._sdoSvcProfiles = {}
176     obj._sdoOrganization = {}
177     obj._sdoStatus = {}
178     obj._ecMine  = {}
179     obj._ecOther = {}
180     obj._eclist  = {}
181     obj._exiting = false
182     obj._readAll = false
183     obj._writeAll = false
184     obj._readAllCompletion = false
185     obj._writeAllCompletion = false
186     obj._inports = {}
187     obj._outports = {}
188     obj._actionListeners = ComponentActionListeners.new()
189     obj._portconnListeners = PortConnectListeners.new()
190     obj._svr = nil
191
192     obj._ReturnCode_t = obj._orb.types:lookup("::RTC::ReturnCode_t").labelvalue
193
194     -- 初期化時のコールバック関数
195     -- @return リターンコード
196     function obj:onInitialize()
197         self._rtcout:RTC_TRACE("onInitialize()")
198         return self._ReturnCode_t.RTC_OK
199     end
200     -- 終了時のコールバック関数
201     -- @return リターンコード
202     function obj:onFinalize()
203         self._rtcout:RTC_TRACE("onFinalize()")
204         return self._ReturnCode_t.RTC_OK
205     end
206     -- 実行コンテキスト開始時のコールバック関数
207     -- @param ec_id 実行コンテキストのID
208     -- @return リターンコード
209     function obj:onStartup(ec_id)
210         self._rtcout:RTC_TRACE("onStartup("..ec_id..")")
211         return self._ReturnCode_t.RTC_OK
212     end
213     -- 実行コンテキスト停止時のコールバック関数
214     -- @param ec_id 実行コンテキストのID
215     -- @return リターンコード
216     function obj:onShutdown(ec_id)
217         self._rtcout:RTC_TRACE("onShutdown("..ec_id..")")
218         return self._ReturnCode_t.RTC_OK
219     end
220     -- アクティブ状態遷移後のコールバック関数
221     -- @param ec_id 実行コンテキストのID
222     -- @return リターンコード
223     function obj:onActivated(ec_id)
224         self._rtcout:RTC_TRACE("onActivated("..ec_id..")")
225         return self._ReturnCode_t.RTC_OK
226     end
227     -- 非アクティブ状態遷移後のコールバック関数
228     -- @param ec_id 実行コンテキストのID
229     -- @return リターンコード
230     function obj:onDeactivated(ec_id)
231         self._rtcout:RTC_TRACE("onDeactivated("..ec_id..")")
232         return self._ReturnCode_t.RTC_OK
233     end
234     -- アクティブ状態で実行コンテキストにより駆動されるコールバック関数
235     -- @param ec_id 実行コンテキストのID
236     -- @return リターンコード
237     function obj:onExecute(ec_id)
238         self._rtcout:RTC_TRACE("onExecute("..ec_id..")")
239         return self._ReturnCode_t.RTC_OK
240     end
241     -- エラー状態遷移時のコールバック関数
242     -- @param ec_id 実行コンテキストのID
243     -- @return リターンコード
244     function obj:onAborting(ec_id)
245         self._rtcout:RTC_TRACE("onAborting("..ec_id..")")
246         return self._ReturnCode_t.RTC_OK
247     end
248     -- エラー状態で実行コンテキストにより駆動されるコールバック関数
249     -- @param ec_id 実行コンテキストのID
250     -- @return リターンコード
251     function obj:onError(ec_id)
252         self._rtcout:RTC_TRACE("onError("..ec_id..")")
253         return self._ReturnCode_t.RTC_OK
254     end
255     -- リセット実行時のコールバック関数
256     -- @param ec_id 実行コンテキストのID
257     -- @return リターンコード
258     function obj:onReset(ec_id)
259         self._rtcout:RTC_TRACE("onReset("..ec_id..")")
260         return self._ReturnCode_t.RTC_OK
261     end
262     -- 状態更新時のコールバック関数
263     -- @param ec_id 実行コンテキストのID
264     -- @return リターンコード
265     function obj:onStateUpdate(ec_id)
266         self._rtcout:RTC_TRACE("onStateUpdate("..ec_id..")")
267         return self._ReturnCode_t.RTC_OK
268     end
269     -- 実行周期変更後のコールバック関数
270     -- @param ec_id 実行コンテキストのID
271     -- @return リターンコード
272     function obj:onRateChanged(ec_id)
273         self._rtcout:RTC_TRACE("onRateChanged("..ec_id..")")
274         return self._ReturnCode_t.RTC_OK
275     end
276     -- 初期化
277     -- @return リターンコード
278     function obj:initialize()
279         self._rtcout:RTC_TRACE("initialize()")
280         self:createRef()
281         local ec_args_ = {}
282         if self:getContextOptions(ec_args_) ~= self._ReturnCode_t.RTC_OK then
283             self._rtcout:RTC_ERROR("Valid EC options are not available. Aborting")
284             return self._ReturnCode_t.BAD_PARAMETER
285         end
286         if self:createContexts(ec_args_) ~= self._ReturnCode_t.RTC_OK then
287             self._rtcout:RTC_ERROR("EC creation failed. Maybe out of resources. Aborting.")
288             return self._ReturnCode_t.BAD_PARAMETER
289         end
290         --self._rtcout:RTC_INFO(#self._ecMine.." execution context"..toSTR_(self._ecMine).." created.")
291         local ret_ = self:on_initialize()
292         self._created = false
293         if ret_ ~= self._ReturnCode_t.RTC_OK then
294             self._rtcout:RTC_ERROR("on_initialize() failed.")
295             return ret_
296         end
297         self._rtcout:RTC_DEBUG("on_initialize() was properly done.")
298         for idx_, ec_ in ipairs(self._ecMine) do
299             self._rtcout:RTC_DEBUG("EC"..idx_.." starting.")
300             ec_:start()
301         end
302         self._sdoservice:init(self)
303         return self._ReturnCode_t.RTC_OK
304     end
305     -- 終了
306     -- @return リターンコード
307     function obj:finalize()
308         self._rtcout:RTC_TRACE("finalize()")
309         if self._created or not self._exiting then
310             return self._ReturnCode_t.PRECONDITION_NOT_MET
311         end
312         if #self._ecOther ~= 0 then
313             self._ecOther = {}
314         end
315         local ret = self:on_finalize()
316         self:shutdown()
317         return ret
318     end
319     -- プロパティ取得
320     -- @return プロパティ
321     function obj:getProperties()
322         self._rtcout:RTC_TRACE("getProperties()")
323         return self._properties
324     end
325     -- インスタンス名取得
326     -- @return インスタンス名
327     function obj:getInstanceName()
328         self._rtcout:RTC_TRACE("getInstanceName()")
329         return self._profile.instance_name
330     end
331     -- インスタンス名設定
332     -- @param instance_name インスタンス名
333     function obj:setInstanceName(instance_name)
334         self._rtcout:RTC_TRACE("setInstanceName("..instance_name..")")
335         self._properties:setProperty("instance_name",instance_name)
336         self._profile.instance_name = self._properties:getProperty("instance_name")
337     end
338     -- 型名取得
339     -- @return 型名
340     function obj:getTypeName()
341         self._rtcout:RTC_TRACE("getTypeName()")
342         return self._profile.type_name
343     end
344     -- カテゴリ名取得
345     -- @return カテゴリ名
346     function obj:getCategory()
347         self._rtcout:RTC_TRACE("getCategory()")
348         return self._profile.category
349     end
350     -- プロパティ設定
351     -- @param prop プロパティ
352     function obj:setProperties(prop)
353         self._rtcout:RTC_TRACE("setProperties()")
354         self._properties:mergeProperties(prop)
355         self._profile.instance_name = self._properties:getProperty("instance_name")
356         self._profile.type_name = self._properties:getProperty("type_name")
357         self._profile.description = self._properties:getProperty("description")
358         self._profile.version = self._properties:getProperty("version")
359          self._profile.vendor = self._properties:getProperty("vendor")
360         self._profile.category = self._properties:getProperty("category")
361     end
362
363     -- オブジェクトリファレンス取得
364     -- @return オブジェクトリファレンス
365     function obj:getObjRef()
366         self._rtcout:RTC_TRACE("getObjRef()")
367         return self._objref
368     end
369
370     -- Manager全体で設定したグローバルな実行コンテキストの設定取得
371     -- @param global_ec_props 実行コンテキストの設定
372     -- @return リターンコード
373     function obj:getGlobalContextOptions(global_ec_props)
374         self._rtcout:RTC_TRACE("getGlobalContextOptions()")
375
376         local prop_ = self._properties:findNode("exec_cxt.periodic")
377         if prop_ == nil then
378           self._rtcout:RTC_WARN("No global EC options found.")
379           return self._ReturnCode_t.RTC_ERROR
380         end
381         --print(prop_)
382
383         self._rtcout:RTC_DEBUG("Global EC options are specified.")
384         self._rtcout:RTC_DEBUG(prop_)
385         self:getInheritedECOptions(global_ec_props)
386         global_ec_props:mergeProperties(prop_)
387         return self._ReturnCode_t.RTC_OK
388     end
389     -- RTC固有の実行コンテキストの設定取得
390     -- @param ec_args 実行コンテキストの設定
391     -- @return リターンコード
392     function obj:getPrivateContextOptions(ec_args)
393         self._rtcout:RTC_TRACE("getPrivateContextOptions()")
394         if not self._properties.findNode("execution_contexts") then
395             self._rtcout:RTC_DEBUG("No component specific EC specified.")
396             return self._ReturnCode_t.RTC_ERROR
397         end
398         return self._ReturnCode_t.RTC_OK
399     end
400     -- 引数に実行コンテキストのオプションを追加する
401     -- @param default_opts オプション
402     -- @return リターンコード
403     function obj:getInheritedECOptions(default_opts)
404         self._rtcout:RTC_TRACE("getPrivateContextOptions()")
405         return self._ReturnCode_t.RTC_OK
406     end
407
408     -- 実行コンテキストのオプション取得
409     -- @param ec_args 実行コンテキストのオプション
410     -- @return リターンコード
411     function obj:getContextOptions(ec_args)
412         self._rtcout:RTC_DEBUG("getContextOptions()")
413         local global_props_ = Properties.new()
414         local ret_global_  = self:getGlobalContextOptions(global_props_)
415         local ret_private_ = self:getPrivateContextOptions(ec_args)
416         if ret_global_ ~= self._ReturnCode_t.RTC_OK and ret_private_ ~= self._ReturnCode_t.RTC_OK then
417             return self._ReturnCode_t.RTC_ERROR
418         end
419         --print(ret_global_, ret_private_)
420         if ret_global_ == self._ReturnCode_t.RTC_OK and ret_private_ ~= self._ReturnCode_t.RTC_OK then
421             table.insert(ec_args,global_props_)
422         end
423         return self._ReturnCode_t.RTC_OK
424     end
425     -- 実行コンテキスト生成
426     -- @param ec_args オプション
427     -- @return リターンコード
428     function obj:createContexts(ec_args)
429
430
431         local ret_ = self._ReturnCode_t.RTC_OK
432         local avail_ec_ = ExecutionContextFactory:instance():getIdentifiers()
433
434         --print(#ec_args)
435         for i,ec_arg_ in ipairs(ec_args) do
436             local ec_type_ = ec_arg_:getProperty("type")
437             local ec_name_ = ec_arg_:getProperty("name")
438             --print(ec_arg_)
439             local ret_aec = false
440             for i,aec in ipairs(avail_ec_) do
441                 --print(aec)
442                 if ec_type_ == aec then
443                     ret_aec = true
444
445                     break
446                 end
447             end
448             if not ret_aec then
449                 self._rtcout:RTC_WARN("EC "..ec_type_.." is not available.")
450                 self._rtcout:RTC_DEBUG("Available ECs: "..
451                                     StringUtil.flatten(avail_ec_))
452             else
453                 local ec_ = ExecutionContextFactory:instance():createObject(ec_type_)
454                 ec_:init(ec_arg_)
455                 table.insert(self._eclist, ec_)
456                 ec_:bindComponent(self)
457             end
458         end
459
460         if #self._eclist == 0 then
461             default_opts = Properties.new()
462             ec_type_ = "PeriodicExecutionContext"
463             local ec_ = ExecutionContextFactory:instance():createObject(ec_type_)
464             ec_:init(default_opts)
465             table.insert(self._eclist, ec_)
466             ec_:bindComponent(self)
467         end
468         return ret_
469     end
470     -- 初期化時コールバック関数実行
471     -- @return リターンコード
472     function obj:on_initialize()
473         self._rtcout:RTC_TRACE("on_initialize()")
474         local ret = self._ReturnCode_t.RTC_ERROR
475         local success, exception = oil.pcall(
476             function()
477                 self:preOnInitialize(0)
478                 self._rtcout:RTC_DEBUG("Calling onInitialize().")
479                 ret = self:onInitialize()
480                 if ret ~= self._ReturnCode_t.RTC_OK then
481                     self._rtcout:RTC_ERROR("onInitialize() returns an ERROR ("..ret..")")
482                 else
483                     self._rtcout:RTC_DEBUG("onInitialize() succeeded.")
484                 end
485             end)
486         if not success then
487             self._rtcout:RTC_ERROR(exception)
488             ret = self._ReturnCode_t.RTC_ERROR
489         end
490         local active_set = self._properties:getProperty("configuration.active_config",
491                                               "default")
492         if self._configsets:haveConfig(active_set) then
493             self._rtcout:RTC_DEBUG("Active configuration set: "..active_set.." exists.")
494             self._configsets:activateConfigurationSet(active_set)
495             self._configsets:update(active_set)
496             self._rtcout:RTC_INFO("Initial active configuration set is "..active_set..".")
497         else
498             self._rtcout:RTC_DEBUG("Active configuration set: "..active_set.." does not exists.")
499             self._configsets:activateConfigurationSet("default")
500             self._configsets:update("default")
501             self._rtcout:RTC_INFO("Initial active configuration set is default-set.")
502         end
503         self:postOnInitialize(0)
504         return ret
505     end
506
507     -- 実行コンテキストの関連付け
508     -- @param exec_context 実行コンテキスト
509     -- @return 実行コンテキストのID
510     function obj:bindContext(exec_context)
511         --print(exec_context)
512         self._rtcout:RTC_TRACE("bindContext()")
513         if exec_context == nil then
514             return -1
515         end
516         for i =1,#self._ecMine do
517             if self._ecMine[i] == nil then
518                 self._ecMine[i] = exec_context
519                 self:onAttachExecutionContext(i)
520                 return i-1
521             end
522         end
523         table.insert(self._ecMine, exec_context)
524         return #self._ecMine - 1
525     end
526     -- 実行コンテキスト開始時コールバック関数実行
527     -- @param ec_id 実行コンテキストのID
528     -- @return リターンコード
529     function obj:on_startup(ec_id)
530         self._rtcout:RTC_TRACE("on_startup("..ec_id..")")
531         local ret = self._ReturnCode_t.RTC_ERROR
532         local success, exception = oil.pcall(
533             function()
534                 self:preOnStartup(ec_id)
535                 ret = self:onStartup(ec_id)
536             end)
537         if not success then
538             self._rtcout:RTC_ERROR(exception)
539             ret = self._ReturnCode_t.RTC_ERROR
540         end
541         self:postOnStartup(ec_id, ret)
542         return ret
543     end
544     -- 実行コンテキスト停止時コールバック関数実行
545     -- @param ec_id 実行コンテキストのID
546     -- @return リターンコード
547     function obj:on_shutdown(ec_id)
548         self._rtcout:RTC_TRACE("on_shutdown("..ec_id..")")
549         local ret = self._ReturnCode_t.RTC_ERROR
550         local success, exception = oil.pcall(
551             function()
552                 self:preOnShutdown(ec_id)
553                 ret = self:onShutdown(ec_id)
554             end)
555         if not success then
556             self._rtcout:RTC_ERROR(exception)
557             ret = self._ReturnCode_t.RTC_ERROR
558         end
559         self:postOnShutdown(ec_id, ret)
560         return ret
561     end
562     -- アクティブ状態遷移後コールバック関数実行
563     -- @param ec_id 実行コンテキストのID
564     -- @return リターンコード
565     function obj:on_activated(ec_id)
566         self._rtcout:RTC_TRACE("on_activated("..ec_id..")")
567         local ret = self._ReturnCode_t.RTC_ERROR
568         --print("on_activated1")
569         local success, exception = oil.pcall(
570             function()
571                 self:preOnActivated(ec_id)
572                 self._configsets:update()
573                 ret = self:onActivated(ec_id)
574                 self._portAdmin:activatePorts()
575         end)
576         if not success then
577             --print(exception)
578             self._rtcout:RTC_ERROR(exception)
579             ret = self._ReturnCode_t.RTC_ERROR
580         end
581         self:postOnActivated(ec_id, ret)
582         --print(type(ret))
583         return ret
584     end
585     -- 非アクティブ状態遷移後コールバック関数実行
586     -- @param ec_id 実行コンテキストのID
587     -- @return リターンコード
588     function obj:on_deactivated(ec_id)
589         self._rtcout:RTC_TRACE("on_deactivated("..ec_id..")")
590         local ret = self._ReturnCode_t.RTC_ERROR
591         local success, exception = oil.pcall(
592             function()
593                 self:preOnDeactivated(ec_id)
594                 self._portAdmin:deactivatePorts()
595                 ret = self:onDeactivated(ec_id)
596             end)
597         if not success then
598             self._rtcout:RTC_ERROR(exception)
599             ret = self._ReturnCode_t.RTC_ERROR
600         end
601         self:postOnDeactivated(ec_id, ret)
602         return ret
603     end
604     -- エラー状態遷移後コールバック関数実行
605     -- @param ec_id 実行コンテキストのID
606     -- @return リターンコード
607     function obj:on_aborting(ec_id)
608         self._rtcout:RTC_TRACE("on_aborting("..ec_id..")")
609         local ret = self._ReturnCode_t.RTC_ERROR
610         local success, exception = oil.pcall(
611             function()
612                 self:preOnAborting(ec_id)
613                 ret = self:onAborting(ec_id)
614             end)
615         if not success then
616             self._rtcout:RTC_ERROR(exception)
617             ret = self._ReturnCode_t.RTC_ERROR
618         end
619         self:postOnAborting(ec_id, ret)
620         return ret
621     end
622     -- エラー状態時コールバック関数実行
623     -- @param ec_id 実行コンテキストのID
624     -- @return リターンコード
625     function obj:on_error(ec_id)
626         self._rtcout:RTC_TRACE("on_error("..ec_id..")")
627         local ret = self._ReturnCode_t.RTC_ERROR
628         local success, exception = oil.pcall(
629             function()
630                 self:preOnError(ec_id)
631                 ret = self:onError(ec_id)
632             end)
633         if not success then
634             self._rtcout:RTC_ERROR(exception)
635             ret = self._ReturnCode_t.RTC_ERROR
636         end
637         self._configsets:update()
638         self:postOnError(ec_id, ret)
639         return ret
640     end
641     -- リセット実行時コールバック関数実行
642     -- @param ec_id 実行コンテキストのID
643     -- @return リターンコード
644     function obj:on_reset(ec_id)
645         self._rtcout:RTC_TRACE("on_reset("..ec_id..")")
646         local ret = self._ReturnCode_t.RTC_ERROR
647         local success, exception = oil.pcall(
648             function()
649                 self:preOnReset(ec_id)
650                 ret = self:onReset(ec_id)
651             end)
652         if not success then
653             self._rtcout:RTC_ERROR(exception)
654             ret = self._ReturnCode_t.RTC_ERROR
655         end
656         self:postOnReset(ec_id, ret)
657         return ret
658     end
659     -- アクティブ状態時コールバック関数実行
660     -- @param ec_id 実行コンテキストのID
661     -- @return リターンコード
662     function obj:on_execute(ec_id)
663         self._rtcout:RTC_TRACE("on_execute("..ec_id..")")
664         local ret = self._ReturnCode_t.RTC_ERROR
665         local success, exception = oil.pcall(
666             function()
667                 if self._readAll then
668                     self:readAll()
669                 end
670                 self:preOnExecute(ec_id)
671                 ret = self:onExecute(ec_id)
672                 if self._writeAll then
673                     self:writeAll()
674                 end
675             end)
676         if not success then
677             self._rtcout:RTC_ERROR(exception)
678             ret = self._ReturnCode_t.RTC_ERROR
679         end
680         self:postOnExecute(ec_id, ret)
681         return ret
682     end
683     -- 状態更新時コールバック関数実行
684     -- @param ec_id 実行コンテキストのID
685     -- @return リターンコード
686     function obj:on_state_update(ec_id)
687         self._rtcout:RTC_TRACE("on_state_update("..ec_id..")")
688         local ret = self._ReturnCode_t.RTC_ERROR
689         local success, exception = oil.pcall(
690             function()
691                 self:preOnStateUpdate(ec_id)
692                 ret = self:onStateUpdate(ec_id)
693                 self._configsets:update()
694             end)
695         if not success then
696             self._rtcout:RTC_ERROR(exception)
697             ret = self._ReturnCode_t.RTC_ERROR
698         end
699
700         self:postOnStateUpdate(ec_id, ret)
701         return ret
702     end
703     -- 実行周期変更時コールバック関数実行
704     -- @param ec_id 実行コンテキストのID
705     -- @return リターンコード
706     function obj:on_rate_changed(ec_id)
707         self._rtcout:RTC_TRACE("on_rate_changed("..ec_id..")")
708         local ret = self._ReturnCode_t.RTC_ERROR
709         local success, exception = oil.pcall(
710             function()
711                 self:preOnRateChanged(ec_id)
712                 ret = self:onRateChanged(ec_id)
713             end)
714         if not success then
715             self._rtcout:RTC_ERROR(exception)
716             ret = self._ReturnCode_t.RTC_ERROR
717         end
718         self:postOnRateChanged(ec_id, ret)
719         return ret
720     end
721     -- 全ポート読み込み
722     function obj:readAll()
723         self._rtcout:RTC_TRACE("readAll()")
724     end
725     -- 全ポート書き込み
726     function obj:writeAll()
727         self._rtcout:RTC_TRACE("writeAll()")
728     end
729     
730
731     function obj:addPreComponentActionListener(listener_type, memfunc, autoclean)
732         if autoclean == nil then
733             autoclean = true
734         end
735         local Noname = {}
736         
737         Noname.new = function(memfunc)
738             local _obj = {}
739             setmetatable(_obj, {__index=ComponentActionListener.PreComponentActionListener.new()})
740             _obj._memfunc = memfunc
741             function _obj:call(ec_id)
742                 self._memfunc(ec_id)
743             end
744             return _obj
745         end
746
747         listener = Noname.new(memfunc)
748         self._actionListeners.preaction_[listener_type]:addListener(listener, autoclean)
749         return listener
750     end
751
752     function obj:removePreComponentActionListener(listener_type, listener)
753         self._actionListeners.preaction_[listener_type]:removeListener(listener)
754     end
755
756
757     function obj:addPostComponentActionListener(listener_type, memfunc, autoclean)
758         if autoclean == nil then
759             autoclean = true
760         end
761         local Noname = {}
762         
763         Noname.new = function(memfunc)
764             local _obj = {}
765             setmetatable(_obj, {__index=ComponentActionListener.PostComponentActionListener.new()})
766             _obj._memfunc = memfunc
767             function _obj:call(ec_id)
768                 self._memfunc(ec_id)
769             end
770             return _obj
771         end
772
773         listener = Noname.new(memfunc)
774         self._actionListeners.postaction_[listener_type]:addListener(listener, autoclean)
775         return listener
776     end
777
778     function obj:removePostComponentActionListener(listener_type, listener)
779         self._actionListeners.postaction_[listener_type]:removeListener(listener)
780     end
781
782
783
784     function obj:addPortActionListener(listener_type, memfunc, autoclean)
785         if autoclean == nil then
786             autoclean = true
787         end
788         local Noname = {}
789         Noname.new = function(memfunc)
790             local _obj = {}
791             setmetatable(_obj, {__index=ComponentActionListener.PortActionListener.new()})
792             _obj._memfunc = memfunc
793             function _obj:call(ec_id)
794                 self._memfunc(ec_id)
795             end
796             return _obj
797         end
798
799         listener = Noname.new(memfunc)
800         self._actionListeners.portaction_[listener_type]:addListener(listener, autoclean)
801         return listener
802     end
803
804     function obj:removePortActionListener(listener_type, listener)
805         self._actionListeners.postaction_[listener_type]:removeListener(listener)
806     end
807
808
809
810     function obj:addExecutionContextActionListener(listener_type, memfunc, autoclean)
811         if autoclean == nil then
812             autoclean = true
813         end
814         local Noname = {}
815         Noname.new = function(memfunc)
816             local _obj = {}
817             setmetatable(_obj, {__index=ComponentActionListener.ExecutionContextActionListener.new()})
818             _obj._memfunc = memfunc
819             function _obj:call(ec_id)
820                 self._memfunc(ec_id)
821             end
822             return _obj
823         end
824
825         listener = Noname.new(memfunc)
826         self._actionListeners.ecaction_[listener_type]:addListener(listener, autoclean)
827         return listener
828     end
829
830     function obj:removeExecutionContextActionListener(listener_type, listener)
831         self._actionListeners.ecaction_[listener_type]:removeListener(listener)
832     end
833
834
835
836     -- 初期化前のコールバック関数
837     -- @param ec_id 実行コンテキストのID
838     function obj:preOnInitialize(ec_id)
839         self._actionListeners.preaction_[PreComponentActionListenerType.PRE_ON_INITIALIZE]:notify(ec_id)
840     end
841     -- 終了前のコールバック関数
842     -- @param ec_id 実行コンテキストのID
843     function obj:preOnFinalize(ec_id)
844         self._actionListeners.preaction_[PreComponentActionListenerType.PRE_ON_FINALIZE]:notify(ec_id)
845     end
846     -- 実行コンテキスト開始前のコールバック関数
847     -- @param ec_id 実行コンテキストのID
848     function obj:preOnStartup(ec_id)
849         self._actionListeners.preaction_[PreComponentActionListenerType.PRE_ON_STARTUP]:notify(ec_id)
850     end
851     -- 実行コンテキスト停止前のコールバック関数
852     -- @param ec_id 実行コンテキストのID
853     function obj:preOnShutdown(ec_id)
854         self._actionListeners.preaction_[PreComponentActionListenerType.PRE_ON_SHUTDOWN]:notify(ec_id)
855     end
856     -- アクティブ化前のコールバック関数
857     -- @param ec_id 実行コンテキストのID
858     function obj:preOnActivated(ec_id)
859         self._actionListeners.preaction_[PreComponentActionListenerType.PRE_ON_ACTIVATED]:notify(ec_id)
860     end
861     -- 非アクティブ化前のコールバック関数
862     -- @param ec_id 実行コンテキストのID
863     function obj:preOnDeactivated(ec_id)
864         self._actionListeners.preaction_[PreComponentActionListenerType.PRE_ON_DEACTIVATED]:notify(ec_id)
865     end
866     -- エラー状態遷移前のコールバック関数
867     -- @param ec_id 実行コンテキストのID
868     function obj:preOnAborting(ec_id)
869         self._actionListeners.preaction_[PreComponentActionListenerType.PRE_ON_ABORTING]:notify(ec_id)
870     end
871     -- エラー状態コールバック関数実行前のコールバック関数
872     -- @param ec_id 実行コンテキストのID
873     function obj:preOnError(ec_id)
874         self._actionListeners.preaction_[PreComponentActionListenerType.PRE_ON_ERROR]:notify(ec_id)
875     end
876     -- リセット実行前のコールバック関数
877     -- @param ec_id 実行コンテキストのID
878     function obj:preOnReset(ec_id)
879         self._actionListeners.preaction_[PreComponentActionListenerType.PRE_ON_RESET]:notify(ec_id)
880     end
881     -- アクティブ状態コールバック関数実行前のコールバック関数
882     -- @param ec_id 実行コンテキストのID
883     function obj:preOnExecute(ec_id)
884         self._actionListeners.preaction_[PreComponentActionListenerType.PRE_ON_EXECUTE]:notify(ec_id)
885     end
886     -- 状態更新前のコールバック関数
887     -- @param ec_id 実行コンテキストのID
888     function obj:preOnStateUpdate(ec_id)
889         self._actionListeners.preaction_[PreComponentActionListenerType.PRE_ON_STATE_UPDATE]:notify(ec_id)
890     end
891     -- 実行周期変更前のコールバック関数
892     -- @param ec_id 実行コンテキストのID
893     function obj:preOnRateChanged(ec_id)
894         self._actionListeners.preaction_[PreComponentActionListenerType.PRE_ON_RATE_CHANGED]:notify(ec_id)
895     end
896
897     -- 初期化後のコールバック関数
898     -- @param ec_id 実行コンテキストのID
899     function obj:postOnInitialize(ec_id, ret)
900         self._actionListeners.postaction_[PostComponentActionListenerType.POST_ON_INITIALIZE]:notify(ec_id, ret)
901     end
902     -- 終了後のコールバック関数
903     -- @param ec_id 実行コンテキストのID
904     function obj:postOnFinalize(ec_id, ret)
905         self._actionListeners.postaction_[PostComponentActionListenerType.POST_ON_FINALIZE]:notify(ec_id, ret)
906     end
907     -- 実行コンテキスト開始後のコールバック関数
908     -- @param ec_id 実行コンテキストのID
909     function obj:postOnStartup(ec_id, ret)
910         self._actionListeners.postaction_[PostComponentActionListenerType.POST_ON_STARTUP]:notify(ec_id, ret)
911     end
912     -- 実行コンテキスト停止後のコールバック関数
913     -- @param ec_id 実行コンテキストのID
914     function obj:postOnShutdown(ec_id, ret)
915         self._actionListeners.postaction_[PostComponentActionListenerType.POST_ON_SHUTDOWN]:notify(ec_id, ret)
916     end
917     -- アクティブ化後のコールバック関数
918     -- @param ec_id 実行コンテキストのID
919     function obj:postOnActivated(ec_id, ret)
920         self._actionListeners.postaction_[PostComponentActionListenerType.POST_ON_ACTIVATED]:notify(ec_id, ret)
921     end
922     -- 非アクティブ化後のコールバック関数
923     -- @param ec_id 実行コンテキストのID
924     function obj:postOnDeactivated(ec_id, ret)
925         self._actionListeners.postaction_[PostComponentActionListenerType.POST_ON_DEACTIVATED]:notify(ec_id, ret)
926     end
927     -- エラー状態遷移後のコールバック関数
928     -- @param ec_id 実行コンテキストのID
929     function obj:postOnAborting(ec_id, ret)
930         self._actionListeners.postaction_[PostComponentActionListenerType.POST_ON_ABORTING]:notify(ec_id, ret)
931     end
932     -- エラー状態コールバック関数実行後のコールバック関数
933     -- @param ec_id 実行コンテキストのID
934     function obj:postOnError(ec_id, ret)
935         self._actionListeners.postaction_[PostComponentActionListenerType.POST_ON_ERROR]:notify(ec_id, ret)
936     end
937     -- リセット実行後のコールバック関数
938     -- @param ec_id 実行コンテキストのID
939     function obj:postOnReset(ec_id, ret)
940         self._actionListeners.postaction_[PostComponentActionListenerType.POST_ON_RESET]:notify(ec_id, ret)
941     end
942     -- アクティブ状態コールバック関数実行後のコールバック関数
943     -- @param ec_id 実行コンテキストのID
944     function obj:postOnExecute(ec_id, ret)
945         self._actionListeners.postaction_[PostComponentActionListenerType.POST_ON_EXECUTE]:notify(ec_id, ret)
946     end
947     -- 状態更新後のコールバック関数
948     -- @param ec_id 実行コンテキストのID
949     function obj:postOnStateUpdate(ec_id, ret)
950         self._actionListeners.postaction_[PostComponentActionListenerType.POST_ON_STATE_UPDATE]:notify(ec_id, ret)
951     end
952     -- 実行周期変更後のコールバック関数
953     -- @param ec_id 実行コンテキストのID
954     function obj:postOnRateChanged(ec_id, ret)
955         self._actionListeners.postaction_[PostComponentActionListenerType.POST_ON_RATE_CHANGED]:notify(ec_id, ret)
956     end
957
958     -- コンフィギュレーションパラメータの変数をバインド
959     -- @param param_name パラメータ名
960     -- @param var 変数
961     -- @param def_val デフォルト値
962     -- @param trans 変換関数
963     -- @return true:バインド成功
964     function obj:bindParameter(param_name, var, def_val, trans)
965         self._rtcout:RTC_TRACE("bindParameter()")
966         if trans == nil then
967             trans = StringUtil.stringTo
968         end
969         --print(param_name, var, def_val, trans)
970         self._configsets:bindParameter(param_name, var, def_val, trans)
971         return true
972     end
973
974     -- コンフィギュレーション管理オブジェクト取得
975     -- @return コンフィギュレーション管理オブジェクト
976     function obj:getConfigService()
977         return self._configsets
978     end
979
980     -- コンフィギュレーションパラメータ更新
981     -- @param config_set コンフィギュレーションセット
982     function obj:updateParameters(config_set)
983         self._rtcout:RTC_TRACE("updateParameters("..config_set..")")
984         self._configsets:update(config_set)
985     end
986
987
988     -- 実行コンテキスト取得
989     -- @param ec_id 実行コンテキストのID
990     -- @return 実行コンテキスト
991     function obj:getExecutionContext(ec_id)
992         return self:get_context(ec_id)
993     end
994
995     -- 実行コンテキスト取得
996     -- @param ec_id 実行コンテキストのID
997     -- @return 実行コンテキスト
998     function obj:get_context(ec_id)
999
1000         self._rtcout:RTC_TRACE("get_context("..ec_id..")")
1001         ec_id = ec_id + 1
1002         if ec_id < RTObject.ECOTHER_OFFSET then
1003             if self._ecMine[ec_id] ~= nil then
1004                 return self._ecMine[ec_id]
1005             else
1006                 return oil.corba.idl.null
1007             end
1008         end
1009
1010
1011         local index = ec_id - ECOTHER_OFFSET
1012
1013         if self._ecOther[index] ~= nil then
1014             return self._ecOther[index]
1015         end
1016
1017         return oil.corba.idl.null
1018     end
1019
1020     -- 自身がオーナーの実行コンテキスト一覧を取得
1021     -- @return 実行コンテキスト一覧
1022     function obj:get_owned_contexts()
1023         self._rtcout:RTC_TRACE("get_owned_contexts()")
1024         local execlist = {}
1025         CORBA_SeqUtil.for_each(self._ecMine, ec_copy.new(execlist))
1026         --print(#execlist)
1027         return execlist
1028     end
1029
1030     -- 別のRTCがオーナーの実行コンテキスト一覧を取得
1031     -- @return 実行コンテキスト一覧
1032     function obj:get_participating_contexts()
1033         self._rtcout:RTC_TRACE("get_participating_contexts()")
1034         local execlist = {}
1035         CORBA_SeqUtil.for_each(self._ecOther, ec_copy.new(execlist))
1036         --print(#self._ecOther)
1037         return execlist
1038     end
1039
1040     -- 実行コンテキストのIDを取得
1041     -- @param cxt 実行コンテキスト
1042     -- @return ID
1043     function obj:get_context_handle(cxt)
1044         self._rtcout:RTC_TRACE("get_context_handle()")
1045
1046         --for i,v in ipairs(self._ecMine) do
1047         -- print(v)
1048         --end
1049         local num = CORBA_SeqUtil.find(self._ecMine, ec_find.new(cxt))
1050         --print(num)
1051         if num ~= -1 then
1052             return num-1
1053         end
1054
1055         num = CORBA_SeqUtil.find(self._ecOther, ec_find.new(cxt))
1056         if num ~= -1 then
1057             return num-1 + 1000
1058         end
1059
1060         return -1
1061     end
1062
1063     -- ネームサーバー登録名取得
1064     -- @return ネームサーバー登録名
1065     function obj:getNamingNames()
1066         self._rtcout:RTC_TRACE("getNamingNames()")
1067         --print(self._properties)
1068         local ret_str = StringUtil.split(self._properties:getProperty("naming.names"), ",")
1069         local ret = {}
1070         for k, v in pairs(ret_str) do
1071             v = StringUtil.eraseHeadBlank(v)
1072             v = StringUtil.eraseTailBlank(v)
1073             table.insert(ret, v)
1074         end
1075         return ret
1076     end
1077
1078     -- コンフィギュレーション取得
1079     -- @return コンフィギュレーション
1080     function obj:get_configuration()
1081         self._rtcout:RTC_TRACE("get_configuration()")
1082         if self._SdoConfig == nil then
1083             error(self._orb:newexcept{"SDOPackage::InterfaceNotImplemented",
1084                 description="InterfaceNotImplemented: get_configuration"
1085             })
1086         end
1087         return self._SdoConfig
1088     end
1089
1090     -- ポート追加
1091     -- @param port ポート
1092     -- @return true:登録成功、false:登録失敗
1093     function obj:addPort(port)
1094         self._rtcout:RTC_TRACE("addPort()")
1095         self._rtcout:RTC_TRACE("addPort(CorbaPort)")
1096         local propkey = "port.corbaport."
1097         local prop = self._properties:getNode(propkey)
1098         if prop ~= nil then
1099             self._properties:getNode(propkey):mergeProperties(self._properties:getNode("port.corba"))
1100         end
1101
1102         port:init(self._properties:getNode(propkey))
1103         port:setOwner(self)
1104
1105
1106         return self._portAdmin:addPort(port)
1107     end
1108
1109
1110
1111     -- インポート追加
1112     -- @param name ポート名
1113     -- @param inport インポート
1114     -- @return true:登録成功、false:登録失敗
1115     function obj:addInPort(name, inport)
1116         self._rtcout:RTC_TRACE("addInPort("..name..")")
1117
1118         local propkey = "port.inport."..name
1119         local prop_ = Properties.new({prop=self._properties:getNode(propkey)})
1120         prop_:mergeProperties(self._properties:getNode("port.inport.dataport"))
1121         inport:init(prop_)
1122
1123         inport:setOwner(self)
1124         inport:setPortConnectListenerHolder(self._portconnListeners)
1125         self:onAddPort(inport:getPortProfile())
1126
1127         local ret = self._portAdmin:addPort(inport)
1128
1129         if not ret then
1130             self._rtcout:RTC_ERROR("addInPort() failed.")
1131             return ret
1132         end
1133
1134
1135         table.insert(self._inports, inport)
1136
1137
1138         return ret
1139     end
1140
1141
1142     -- アウトポート追加
1143     -- @param name ポート名
1144     -- @param inport アウトポート
1145     -- @return true:登録成功、false:登録失敗
1146     function obj:addOutPort(name, outport)
1147         self._rtcout:RTC_TRACE("addOutPort("..name..")")
1148
1149         local propkey = "port.outport."..name
1150         local prop_ = Properties.new({prop=self._properties:getNode(propkey)})
1151         prop_:mergeProperties(self._properties:getNode("port.outport.dataport"))
1152         outport:init(prop_)
1153
1154         outport:setOwner(self)
1155         outport:setPortConnectListenerHolder(self._portconnListeners)
1156         self:onAddPort(outport:getPortProfile())
1157
1158         local ret = self._portAdmin:addPort(outport)
1159
1160         if not ret then
1161             self._rtcout:RTC_ERROR("addOutPort() failed.")
1162             return ret
1163         end
1164
1165
1166         table.insert(self._outports, outport)
1167
1168
1169         return ret
1170     end
1171
1172     -- インポート削除
1173     -- @param name ポート名
1174     -- @param inport インポート
1175     -- @return true:削除成功、false:削除失敗
1176     function obj:removeInPort(port)
1177         self._rtcout:RTC_TRACE("removeInPort()")
1178         local ret = self:removePort(port)
1179
1180         if ret ~= nil then
1181             for i, inport in ipairs(self._inports) do
1182                 if port == inport then
1183                     table.remove(self._inports, i)
1184                     return true
1185                 end
1186             end
1187         end
1188         return false
1189     end
1190
1191     -- アウトポート削除
1192     -- @param name ポート名
1193     -- @param inport アウトポート
1194     -- @return true:削除成功、false:削除失敗
1195     function obj:removeOutPort(port)
1196         self._rtcout:RTC_TRACE("removeOutPort()")
1197         local ret = self:removePort(port)
1198
1199         if ret ~= nil then
1200             for i, outport in ipairs(self._outports) do
1201                 if port == outport then
1202                     table.remove(self._outports, i)
1203                     return true
1204                 end
1205             end
1206         end
1207         return false
1208     end
1209
1210
1211     -- ポート削除
1212     -- @param port ポート
1213     -- @return true:削除成功、false:削除失敗
1214     function obj:removePort(port)
1215         self._rtcout:RTC_TRACE("removePort()")
1216         self:onRemovePort(port:getPortProfile())
1217         return self._portAdmin:removePort(port)
1218     end
1219
1220     -- プロファイル取得
1221     -- @return プロファイル
1222     function obj:get_component_profile()
1223         self._rtcout:RTC_TRACE("get_component_profile()")
1224
1225         local prop_ = {instance_name = self._properties:getProperty("instance_name"),
1226                  type_name = self._properties:getProperty("type_name"),
1227                  description = self._properties:getProperty("description"),
1228                  version = self._properties:getProperty("version"),
1229                  vendor = self._properties:getProperty("vendor"),
1230                  category = self._properties:getProperty("category"),
1231                  port_profiles = self._portAdmin:getPortProfileList(),
1232                  parent = self._profile.parent,
1233                  properties = self._profile.properties}
1234         NVUtil.copyFromProperties(self._profile.properties, self._properties)
1235         --print(oil.corba.idl.null)
1236         return prop_
1237     end
1238
1239     -- ポート追加時のコールバック実行
1240     -- @param pprof ポートプロファイル
1241     function obj:onAddPort(pprof)
1242         self._actionListeners.portaction_[PortActionListenerType.ADD_PORT]:notify(pprof)
1243     end
1244     -- ポート削除時のコールバック実行
1245     -- @param pprof ポートプロファイル
1246     function obj:onRemovePort(pprof)
1247         self._actionListeners.portaction_[PortActionListenerType.REMOVE_PORT]:notify(pprof)
1248     end
1249     -- 実行コンテキストアタッチ時のコールバック実行
1250     -- @param ec_id 実行コンテキストのID
1251     function obj:onAttachExecutionContext(ec_id)
1252         
1253         self._actionListeners.ecaction_[ExecutionContextActionListenerType.EC_ATTACHED]:notify(ec_id)
1254     end
1255     -- 実行コンテキストデタッチ時のコールバック実行
1256     -- @param ec_id 実行コンテキストのID
1257     function obj:onDetachExecutionContext(pprof)
1258         self._actionListeners.ecaction_[ExecutionContextActionListenerType.EC_DETACHED]:notify(ec_id)
1259     end
1260
1261     -- 生存確認
1262     -- @param exec_context 実行コンテキスト
1263     -- @return true:生存、false:消滅
1264     function obj:is_alive(exec_context)
1265         self._rtcout:RTC_TRACE("is_alive()")
1266
1267         for i, ec in ipairs(self._ecMine) do
1268             --if exec_context:_is_equivalent(ec) then
1269             local Manager = require "openrtm.Manager"
1270             local orb = Manager:instance():getORB()
1271
1272             if NVUtil._is_equivalent(exec_context, ec, exec_context.getObjRef, ec.getObjRef) then
1273                 return true
1274             end
1275         end
1276
1277
1278         for i, ec in ipairs(self._ecOther) do
1279             if ec == nil then
1280                 if NVUtil._is_equivalent(exec_context, ec, exec_context.getObjRef, ec.getObjRef) then
1281                     return true
1282                 end
1283             end
1284         end
1285
1286         return false
1287     end
1288
1289     -- RTCの終了実行
1290     -- @return リターンコード
1291     function obj:exit()
1292         self._rtcout:RTC_TRACE("exit()")
1293         if self._created then
1294             return self._ReturnCode_t.PRECONDITION_NOT_MET
1295         end
1296         if self._exiting then
1297             return self._ReturnCode_t.RTC_OK
1298         end
1299
1300         for i, ec in ipairs(self._ecOther) do
1301             if not NVUtil._non_existent(ec) then
1302                 ec:remove_component(self:getObjRef())
1303             end
1304         end
1305
1306         self._exiting = true
1307         return self:finalize()
1308     end
1309
1310     -- 実行コンテキストのアタッチ
1311     -- @param exec_context 実行コンテキスト
1312     -- @return ID
1313     function obj:attach_context(exec_context)
1314         local ECOTHER_OFFSET = RTObject.ECOTHER_OFFSET
1315         self._rtcout:RTC_TRACE("attach_context()")
1316
1317         local ecs = exec_context
1318         if ecs == oil.corba.idl.null then
1319             return -1
1320         end
1321         
1322         
1323         for i,oec in ipairs(self._ecOther) do
1324             if oec == oil.corba.idl.null then
1325                 self._ecOther[i] = ecs
1326                 local ec_id = i + ECOTHER_OFFSET
1327                 self:onAttachExecutionContext(ec_id)
1328                 return ec_id
1329             end
1330         end
1331         table.insert(self._ecOther,ecs)
1332         local ec_id = tonumber(#self._ecOther - 1 + ECOTHER_OFFSET)
1333         self:onAttachExecutionContext(ec_id)
1334         return ec_id
1335     end
1336     -- 実行コンテキストのデタッチ
1337     -- @param ec_id 実行コンテキストのID
1338     -- @return リターンコードリターンコード
1339     function obj:detach_context(ec_id)
1340         ec_id = ec_id + 1
1341         local ECOTHER_OFFSET = RTObject.ECOTHER_OFFSET
1342         self._rtcout:RTC_TRACE("detach_context(%d)", ec_id)
1343         local len_ = #self._ecOther
1344
1345         if (tonumber(ec_id) < tonumber(ECOTHER_OFFSET)) or (tonumber(ec_id - ECOTHER_OFFSET) > len_) then
1346             return self._ReturnCode_t.BAD_PARAMETER
1347         end
1348     
1349         local index = tonumber(ec_id - ECOTHER_OFFSET)
1350         
1351         if index < 0 or self._ecOther[index] == oil.corba.idl.null then
1352             return self._ReturnCode_t.BAD_PARAMETER
1353         end
1354     
1355    
1356         self._ecOther[index] = oil.corba.idl.null
1357         self:onDetachExecutionContext(ec_id)
1358         return self._ReturnCode_t.RTC_OK
1359     end
1360
1361     -- ポート一覧取得
1362     -- @return ポート一覧
1363     function obj:get_ports()
1364         self._rtcout:RTC_TRACE("get_ports()")
1365         return self._portAdmin:getPortServiceList()
1366     end
1367
1368     -- オブジェクトリファレンス生成
1369     function obj:createRef()
1370         self._svr = self._orb:newservant(self, nil, "IDL:openrtm.aist.go.jp/OpenRTM/DataFlowComponent:1.0")
1371         --print(type(self._svr))
1372         self._objref = RTCUtil.getReference(self._orb, self._svr, "IDL:openrtm.aist.go.jp/OpenRTM/DataFlowComponent:1.0")
1373     end
1374
1375     -- 終了時コールバック実行
1376     -- @return リターンコード
1377     function obj:on_finalize()
1378         self._rtcout:RTC_TRACE("on_finalize()")
1379         local ret = self._ReturnCode_t.RTC_ERROR
1380         local success, exception = oil.pcall(
1381             function()
1382                 self:preOnFinalize(0)
1383                 ret = self:onFinalize()
1384             end)
1385         if not success then
1386             --print(exception)
1387             self._rtcout:RTC_ERROR(exception)
1388             ret = self._ReturnCode_t.RTC_ERROR
1389         end
1390         self:postOnFinalize(0, ret)
1391         return ret
1392     end
1393
1394     -- 終了処理
1395     function obj:shutdown()
1396         self._rtcout:RTC_TRACE("shutdown()")
1397         local success, exception = oil.pcall(
1398             function()
1399                 self:finalizePorts()
1400                 self:finalizeContexts()
1401                 --self._orb:deactivate(self._SdoConfigImpl)
1402                 --self._orb:deactivate(self._objref)
1403                 self._SdoConfigImpl:deactivate()
1404                 if self._svr ~= nil then
1405                     self._orb:deactivate(self._svr)
1406                 end
1407                 self._sdoservice:exit()
1408             end)
1409         if not success then
1410             --print(exception)
1411             self._rtcout:RTC_ERROR(exception)
1412         end
1413
1414         if self._manager ~= nil then
1415             self._rtcout:RTC_DEBUG("Cleanup on Manager")
1416             self._manager:notifyFinalized(self)
1417         end
1418
1419         self._actionListeners = nil
1420         self._portconnListeners = nil
1421
1422     end
1423
1424     -- 全ポートの終了
1425     function obj:finalizePorts()
1426         self._rtcout:RTC_TRACE("finalizePorts()")
1427         self._portAdmin:finalizePorts()
1428         self._inports = {}
1429         self._outports = {}
1430     end
1431
1432     -- 全実行コンテキストの終了
1433     function obj:finalizeContexts()
1434         self._rtcout:RTC_TRACE("finalizeContexts()")
1435
1436         for i,ec in ipairs(self._eclist) do
1437             ec:stop()
1438             local success, exception = oil.pcall(
1439                 function()
1440                     self._orb:deactivate(ec._svr)
1441                 end)
1442             if not success then
1443             end
1444             ec:exit()
1445         end
1446
1447         self._eclist = {}
1448     end
1449
1450     function obj:addSdoServiceProvider(prof, provider)
1451         return self._sdoservice:addSdoServiceProvider(prof, provider)
1452     end
1453
1454     function obj:removeSdoServiceProvider(id)
1455         return self._sdoservice:removeSdoServiceProvider(id)
1456     end
1457
1458     function obj:addSdoServiceConsumer(prof)
1459         return self._sdoservice:addSdoServiceConsumer(prof)
1460     end
1461
1462     function obj:removeSdoServiceConsumer(id)
1463         return self._sdoservice:removeSdoServiceConsumer(id)
1464     end
1465
1466
1467     function obj:get_sdo_service(_id)
1468         self._rtcout:RTC_TRACE("get_sdo_service(%s)", _id)
1469         self._sdoSvcProfiles = self._SdoConfigImpl:getServiceProfiles()
1470     
1471         if _id == "" then
1472             error(self._orb:newexcept{"SDOPackage::InvalidParameter",
1473                 description="get_service(): Empty name."
1474             })
1475         end
1476     
1477         local index = CORBA_SeqUtil.find(self._sdoSvcProfiles, svc_name(_id))
1478     
1479         if index < 0 then
1480             error(self._orb:newexcept{"SDOPackage::InvalidParameter",
1481                 description="get_service(): Not found"
1482             })
1483         end
1484         
1485     
1486         return self._sdoSvcProfiles[index].service
1487     end
1488
1489     obj:setInstanceName(uuid())
1490
1491     return obj
1492 end
1493
1494
1495
1496
1497 return RTObject

File lua\openrtm\RTObjectStateMachine.lua

1 ---------------------------------
2 --! @file RTObjectStateMachine.lua
3 --! @brief RTC状態遷移マシン定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local RTObjectStateMachine= {}
11 --_G["openrtm.RTObjectStateMachine"] = RTObjectStateMachine
12
13
14 local StateMachine = require "openrtm.StateMachine"
15 local StateHolder = StateMachine.StateHolder
16 local NVUtil = require "openrtm.NVUtil"
17
18 local NUM_OF_LIFECYCLESTATE = 4
19
20 local ActionPredicate = {}
21
22 -- アクション実行関数オブジェクト初期化
23 -- @param object 状態遷移マシン
24 -- @param func アクション
25 -- @return 関数オブジェクト
26 ActionPredicate.new = function(object, func)
27     local obj = {}
28     obj.instance = object
29     -- アクション実行関数
30     -- @param self 自身のオブジェクト
31     -- @param state 状態
32     local call_func = function(self, state)
33         func(self.instance, state)
34     end
35     setmetatable(obj, {__call=call_func})
36     return obj
37 end
38
39
40 RTObjectStateMachine.new = function(id, comp)
41     local obj = {}
42     local Manager = require "openrtm.Manager"
43     obj._ReturnCode_t = Manager:instance():getORB().types:lookup("::RTC::ReturnCode_t").labelvalue
44     obj._LifeCycleState = Manager:instance():getORB().types:lookup("::RTC::LifeCycleState").labelvalue
45     obj._id = id
46     obj._rtobj = comp
47     obj._sm = StateMachine.new(NUM_OF_LIFECYCLESTATE)
48     obj._ca   = false
49     obj._dfc  = false
50     obj._fsm  = false
51     obj._mode = false
52     obj._caVar   = nil
53     obj._dfcVar  = nil
54     obj._fsmVar  = nil
55     obj._modeVar = nil
56     obj._rtObjPtr = nil
57
58
59     -- RTCの設定
60     -- @param comp RTC
61     function obj:setComponentAction(comp)
62         if comp.getObjRef == nil then
63             self._caVar = comp
64         else
65             self._rtObjPtr = comp
66             self._caVar = comp:getObjRef()
67         end
68     end
69     -- データフローコンポーネントの設定
70     -- @param comp RTC
71     function obj:setDataFlowComponentAction(comp)
72     end
73     -- FSMコンポーネントの設定
74     -- @param comp RTC
75     function obj:setFsmParticipantAction(comp)
76     end
77     -- マルチモードコンポーネントの設定
78     -- @param comp RTC
79     function obj:setMultiModeComponentAction(comp)
80     end
81
82
83     -- 状態更新前の処理
84     function obj:workerPreDo()
85         return self._sm:worker_pre()
86     end
87
88     -- 状態更新時の処理
89     function obj:workerDo()
90         return self._sm:worker_do()
91     end
92
93     -- 状態更新後の処理
94     function obj:workerPostDo()
95         return self._sm:worker_post()
96     end
97
98     -- 状態の取得
99     -- @return 状態
100     function obj:getState()
101         --print(self._sm:getState())
102         return self._sm:getState()-1
103     end
104
105     -- 現在の状態が指定状態と一致するかの確認
106     -- @param state 状態
107     -- @return true:一致、false:不一致
108     function obj:isCurrentState(state)
109         --print(self:getState(),state)
110         return (self:getState() == state)
111     end
112
113     -- 状態遷移マシンで保持しているRTCが一致するかの確認
114     -- @param comp RTC
115     -- @return true:一致、false:不一致
116     function obj:isEquivalent(comp)
117         --local Manager = require "openrtm.Manager"
118         --orb = Manager:instance():getORB()
119         --print(self._rtobj,comp)
120         --print(comp:getInstanceName())
121         --print(self._rtobj:getInstanceName())
122         --return (orb:tostring(self._rtobj)==orb:tostring(comp))
123         --print("abcde")
124
125
126         --print(comp, self._rtobj)
127         return NVUtil._is_equivalent(comp, self._rtobj, comp.getObjRef, self._rtobj.getObjRef)
128         --return (comp:getInstanceName()==self._rtobj:getInstanceName())
129     end
130
131     -- 指定状態への移行
132     -- @param state 状態
133     function obj:goTo(state)
134         self._sm:goTo(state+1)
135     end
136
137     -- RTCのオブジェクトリファレンス取得
138     -- @return オブジェクトリファレンス
139     function obj:getComponentObj()
140
141         if self._rtObjPtr ~= nil then
142             return self._rtObjPtr
143         elseif self._caVar ~= nil then
144             return self._caVar
145         else
146             return nil
147         end
148     end
149     -- 実行コンテキスト開始時の処理実行
150     function obj:onStartup()
151         local comp = self:getComponentObj()
152         if comp ~= nil then
153             comp:on_startup(self._id)
154         end
155     end
156     -- 実行コンテキスト停止時の処理実行
157     function obj:onShutdown()
158         local comp = self:getComponentObj()
159         if comp ~= nil then
160             comp:on_shutdown(self._id)
161         end
162     end
163     -- アクティブ状態遷移後の処理実行
164     -- @param st RTCの状態
165     function obj:onActivated(st)
166         local comp = self:getComponentObj()
167         --print(self._caVar)
168         --print("test",self._caVar)
169         if comp == nil then
170             return
171         end
172         --local ret = self._caVar:on_activated(self._id)
173         --print(type(ret), type(self._ReturnCode_t.RTC_OK))
174         --if ret ~= "RTC_OK" then
175         --print("aaaa")
176         if NVUtil.getReturnCode(comp:on_activated(self._id)) ~= self._ReturnCode_t.RTC_OK then
177             --print("onActivated:ERROR")
178             self._sm:goTo(self._LifeCycleState.ERROR_STATE+1)
179         end
180         --print("OK")
181     end
182     -- 非アクティブ状態遷移後の処理実行
183     -- @param st RTCの状態
184     function obj:onDeactivated(st)
185         local comp = self:getComponentObj()
186         if comp == nil then
187             return
188         end
189         comp:on_deactivated(self._id)
190     end
191     -- エラー状態遷移時の処理実行
192     -- @param st RTCの状態
193     function obj:onAborting(st)
194         local comp = self:getComponentObj()
195         if comp == nil then
196             return
197         end
198         comp:on_aborting(self._id)
199     end
200     -- エラー状態の処理実行
201     -- @param st RTCの状態
202     function obj:onError(st)
203         local comp = self:getComponentObj()
204         if comp == nil then
205             return
206         end
207         comp:on_error(self._id)
208     end
209     -- リセット実行時の処理実行
210     -- @param st RTCの状態
211     function obj:onReset(st)
212         local comp = self:getComponentObj()
213         if comp == nil then
214             return
215         end
216         if NVUtil.getReturnCode(comp:on_reset(self._id)) ~= self._ReturnCode_t.RTC_OK then
217             self._sm:goTo(self._LifeCycleState.ERROR_STATE+1)
218         end
219     end
220     -- アクティブ状態の処理実行
221     -- @param st RTCの状態
222     function obj:onExecute(st)
223         local comp = self:getComponentObj()
224         if comp == nil then
225             return
226         end
227         if NVUtil.getReturnCode(comp:on_execute(self._id)) ~= self._ReturnCode_t.RTC_OK then
228             --print("onExecute:ERROR")
229             self._sm:goTo(self._LifeCycleState.ERROR_STATE+1)
230         end
231     end
232     -- 状態更新時の処理実行
233     -- @param st RTCの状態
234     function obj:onStateUpdate(st)
235         local comp = self:getComponentObj()
236         if comp == nil then
237             return
238         end
239         if NVUtil.getReturnCode(comp:on_state_update(self._id)) ~= self._ReturnCode_t.RTC_OK then
240             --print("onStateUpdate:ERROR")
241             self._sm:goTo(self._LifeCycleState.ERROR_STATE+1)
242         end
243     end
244     -- 周期変更後の処理実行
245     -- @param st RTCの状態
246     -- @return リターンコード
247     function obj:onRateChanged(st)
248         local comp = self:getComponentObj()
249         if comp == nil then
250             return
251         end
252         local ret = comp:on_rate_changed(self._id)
253         if ret ~= self._ReturnCode_t.RTC_OK then
254             self._sm:goTo(self._LifeCycleState.ERROR_STATE+1)
255         end
256         return ret
257     end
258     -- アクション実行
259     -- @param st RTCの状態
260     function obj:onAction(st)
261         local comp = self:getComponentObj()
262         if self._fsmVar == nil then
263             return
264         end
265         if self._fsmVar:on_action(self._id) ~= self._ReturnCode_t.RTC_OK then
266             self._sm:goTo(self._LifeCycleState.ERROR_STATE+1)
267         end
268     end
269     -- モード変更後の処理実行
270     -- @param st RTCの状態
271     function obj:onModeChanged(st)
272         local comp = self:getComponentObj()
273         if self._modeVar == nil then
274             return
275         end
276         if self._modeVar:on_mode_changed(self._id) ~= self._ReturnCode_t.RTC_OK then
277             self._sm:goTo(self._LifeCycleState.ERROR_STATE+1)
278         end
279     end
280     
281     function obj:getRTObject()
282         return self._rtobj
283     end
284
285     function obj:getExecutionContextHandle()
286         
287         return self._id
288     end
289
290     --print(comp)
291     obj:setComponentAction(comp)
292     --print(obj._caVar)
293     obj:setDataFlowComponentAction(comp)
294     obj:setFsmParticipantAction(comp)
295     obj:setMultiModeComponentAction(comp)
296
297     obj._sm:setListener(obj)
298     --print(obj.onActivated)
299     --obj:onActivated(1)
300     obj._sm:setEntryAction(obj._LifeCycleState.ACTIVE_STATE+1,
301                             ActionPredicate.new(obj, obj.onActivated))
302     obj._sm:setDoAction(obj._LifeCycleState.ACTIVE_STATE+1,
303                             ActionPredicate.new(obj, obj.onExecute))
304     obj._sm:setPostDoAction(obj._LifeCycleState.ACTIVE_STATE+1,
305                             ActionPredicate.new(obj, obj.onStateUpdate))
306     obj._sm:setExitAction(obj._LifeCycleState.ACTIVE_STATE+1,
307                             ActionPredicate.new(obj, obj.onDeactivated))
308     obj._sm:setEntryAction(obj._LifeCycleState.ERROR_STATE+1,
309                             ActionPredicate.new(obj, obj.onAborting))
310     obj._sm:setDoAction(obj._LifeCycleState.ERROR_STATE+1,
311                             ActionPredicate.new(obj, obj.onError))
312     obj._sm:setExitAction(obj._LifeCycleState.ERROR_STATE+1,
313                             ActionPredicate.new(obj, obj.onReset))
314     local st = StateHolder.new()
315     st.prev = obj._LifeCycleState.INACTIVE_STATE+1
316     st.curr = obj._LifeCycleState.INACTIVE_STATE+1
317     st.next = obj._LifeCycleState.INACTIVE_STATE+1
318     obj._sm:setStartState(st)
319     obj._sm:goTo(obj._LifeCycleState.INACTIVE_STATE+1)
320     return obj
321 end
322
323
324 return RTObjectStateMachine

File lua\openrtm\SdoConfiguration.lua

1 ---------------------------------
2 --! @file SdoConfiguration.lua
3 --! @brief コンフィギュレーション操作クラス定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local SdoConfiguration= {}
11 --_G["openrtm.SdoConfiguration"] = SdoConfiguration
12
13 local oil = require "oil"
14 local NVUtil = require "openrtm.NVUtil"
15 local Properties = require "openrtm.Properties"
16 local RTCUtil = require "openrtm.RTCUtil"
17
18 SdoConfiguration.Configuration_impl = {}
19
20
21 -- プロパティからコンフィギュレーションセットに変換
22 -- @param conf コンフィギュレーションセット
23 -- @param prop プロパティ
24 local toConfigurationSet = function(conf, prop)
25     conf.description = prop:getProperty("description")
26     conf.id = prop:getName()
27     --print(prop)
28     NVUtil.copyFromProperties(conf.configuration_data, prop)
29 end
30
31 -- コンフィギュレーションセットからプロパティに変換
32 -- @param prop プロパティ
33 -- @param conf コンフィギュレーションセット
34 local toProperties = function(prop, conf)
35     NVUtil.copyToProperties(prop, conf.configuration_data)
36 end
37
38 -- コンフィギュレーション操作オブジェクト初期化
39 -- @param configAdmin コンフィギュレーション管理オブジェクト
40 -- @param sdoServiceAdmin SDOサービス管理オブジェクト
41 -- @return コンフィギュレーション操作オブジェクト
42 SdoConfiguration.Configuration_impl.new = function(configAdmin, sdoServiceAdmin)
43     local obj = {}
44
45     obj._deviceProfile = {device_type="",manufacturer="",model="",version="",properties={}}
46     obj._serviceProfiles = {}
47     obj._parameters = {}
48     obj._configsets = configAdmin
49     obj._sdoservice = sdoServiceAdmin
50
51     obj._organizations = {}
52
53
54
55
56     local Manager = require "openrtm.Manager"
57     obj._orb = Manager:instance():getORB()
58     obj._svr = obj._orb:newservant(obj, nil, "IDL:org.omg/SDOPackage/Configuration:1.0")
59     obj._objref = RTCUtil.getReference(obj._orb, obj._svr, "IDL:org.omg/SDOPackage/Configuration:1.0")
60
61     obj._rtcout = Manager:instance():getLogbuf("rtobject.sdo_config")
62
63
64     -- オブジェクトリファレンス取得
65     -- @return オブジェクトリファレンス
66     function obj:getObjRef()
67         return self._objref
68     end
69
70     -- オブジェクトリファレンスの非アクティブ化
71     function obj:deactivate()
72         local Manager = require "openrtm.Manager"
73         Manager:instance():getORB():deactivate(self._svr)
74     end
75
76
77     -- コンフィギュレーションセット取得
78     -- @param config_id コンフィギュレーションセットのID
79     -- @return コンフィギュレーションセット
80     function obj:get_configuration_set(config_id)
81         self._rtcout:RTC_TRACE("get_configuration_set("..config_id..")")
82         if config_id == "" then
83             error(self._orb:newexcept{"SDOPackage::InvalidParameter",
84                     description="ID is empty"
85                 })
86         end
87         
88         if not self._configsets:haveConfig(config_id) then
89             self._rtcout:RTC_ERROR("No such ConfigurationSet")
90             error(self._orb:newexcept{"SDOPackage::InternalError",
91                     description="No such ConfigurationSet"
92                 })
93         end
94
95
96
97         local configset = self._configsets:getConfigurationSet(config_id)
98
99
100         local config = {id="",description="",configuration_data={}}
101         toConfigurationSet(config, configset)
102         return config
103     end
104
105     -- アクティブなコンフィギュレーションセット取得
106     -- @return コンフィギュレーションセット
107     function obj:get_active_configuration_set()
108         self._rtcout:RTC_TRACE("get_active_configuration_set()")
109         if not self._configsets:isActive() then
110             error(self._orb:newexcept{"SDOPackage::NotAvailable",
111                     description="NotAvailable: Configuration.get_active_configuration_set()"
112             })
113         end
114
115
116
117         local config = {id="",description="",configuration_data={}}
118         toConfigurationSet(config, self._configsets:getActiveConfigurationSet())
119         return config
120     end
121
122     -- 指定のコンフィギュレーションセットをアクティブにする
123     -- @param config_id コンフィギュレーションセットのID
124     -- @return true:アクティブ化成功
125     function obj:activate_configuration_set(config_id)
126         self._rtcout:RTC_TRACE("activate_configuration_set("..config_id..")")
127         if config_id == "" then
128             error(self._orb:newexcept{"SDOPackage::InvalidParameter",
129                     description="ID is empty."
130             })
131         end
132
133         if self._configsets:activateConfigurationSet(config_id) then
134             return true
135         else
136             error(self._orb:newexcept{"SDOPackage::InternalError",
137                     description="Configuration.activate_configuration_set()."
138             })
139         end
140     end
141
142     -- コンフィギュレーションセットの設定
143     -- @param configuration_set コンフィギュレーションセット
144     -- @return true:設定成功、false:設定失敗
145     function obj:set_configuration_set_values(configuration_set)
146         self._rtcout:RTC_TRACE("set_configuration_set_values()")
147         if configuration_set == nil or configuration_set.id == "" then
148             error(self._orb:newexcept{"SDOPackage::InvalidParameter",
149                     description="ID is empty."
150             })
151         end
152
153         local ret = nil
154         local success, exception = oil.pcall(
155             function()
156                 conf = Properties.new({key=configuration_set.id})
157                 toProperties(conf, configuration_set)
158
159                 ret = self._configsets:setConfigurationSetValues(conf)
160         end)
161         if not success then
162             self._rtcout:RTC_ERROR(exception)
163             error(self._orb:newexcept{"SDOPackage::InternalError",
164                     description="Configuration::set_configuration_set_values()"
165             })
166         end
167         return ret
168     end
169
170     -- デバイスプロファイル設定
171     -- 未実装
172     -- @param dProfile デバイスプロファイル
173     function obj:set_device_profile(dProfile)
174         self._rtcout:RTC_TRACE("set_device_profile()")
175         error(self._orb:newexcept{"SDOPackage::InvalidParameter",
176                     description="dProfile is empty."
177             })
178     end
179
180     -- サービスプロファイル追加
181     -- @param sProfile サービスプロファイル
182     -- @return true:追加成功
183     function obj:add_service_profile(sProfile)
184         self._rtcout:RTC_TRACE("add_service_profile()")
185         if sProfile == nil then
186             error(self._orb:newexcept{"SDOPackage::InvalidParameter",
187                     description="sProfile is empty."
188             })
189         end
190         local ret = false
191         local success, exception = oil.pcall(
192             function()
193                 ret = self._sdoservice:addSdoServiceConsumer(sProfile)
194         end)
195         if not success then
196             self._rtcout:RTC_ERROR(exception)
197             error(self._orb:newexcept{"SDOPackage::InternalError",
198                     description="Configuration.add_service_profile"
199             })
200         end
201         return ret
202     end
203     
204     -- オーガナイゼーションオブジェクト追加
205     -- 未実装
206     -- @param org オーガナイゼーションオブジェクト
207     function obj:add_organization(org)
208         self._rtcout:RTC_TRACE("add_organization()")
209         error(self._orb:newexcept{"SDOPackage::InvalidParameter",
210                     description="org is empty."
211             })
212     end
213
214     -- サービスプロファイル削除
215     -- @param id_ ID
216     -- @return true:削除成功
217     function obj:remove_service_profile(id_)
218         self._rtcout:RTC_TRACE("remove_service_profile("..id_..")")
219         if id_ == "" then
220             error(self._orb:newexcept{"SDOPackage::InvalidParameter",
221                     description="id is empty."
222             })
223         end
224         local ret = false
225         local success, exception = oil.pcall(
226             function()
227                 ret = self._sdoservice:removeSdoServiceConsumer(id_)
228         end)
229         if not success then
230             self._rtcout:RTC_ERROR(exception)
231             error(self._orb:newexcept{"SDOPackage::InternalError",
232                     description="Configuration.remove_service_profile"
233             })
234         end
235         return ret
236     end
237
238     -- オーガナイゼーションオブジェクト削除
239     -- 未実装
240     -- @param organization_id ID
241     function obj:remove_organization(organization_id)
242         self._rtcout:RTC_TRACE("remove_organization("..organization_id..")")
243         error(self._orb:newexcept{"SDOPackage::InvalidParameter",
244                     description="id is empty."
245             })
246     end
247
248     -- コンフィギュレーションパラメータ一覧取得
249     -- 未実装
250     -- @return コンフィギュレーションパラメータ一覧
251     function obj:get_configuration_parameters()
252         self._rtcout:RTC_TRACE("get_configuration_parameters()")
253         return self._parameters
254     end
255
256     -- コンフィギュレーションパラメータのNameValueリスト取得
257     -- 未実装
258     -- @return NameValueリスト取得
259     function obj:get_configuration_parameter_values()
260         self._rtcout:RTC_TRACE("get_configuration_parameter_values()")
261         local nvlist = {}
262         return nvlist
263     end
264
265     -- コンフィギュレーションパラメータの設定
266     -- 未実装
267     -- @param name パラメータ名
268     -- @param value 値
269     function obj:set_configuration_parameter(name, value)
270         self._rtcout:RTC_TRACE("set_configuration_parameter("..name..", value)")
271         error(self._orb:newexcept{"SDOPackage::InvalidParameter",
272                     description="Name/Value is empty."
273             })
274     end
275
276     -- コンフィギュレーションセット一覧取得
277     -- @return コンフィギュレーションセット一覧
278     function obj:get_configuration_sets()
279         self._rtcout:RTC_TRACE("get_configuration_sets()")
280         local config_sets = {}
281         local success, exception = oil.pcall(
282             function()
283                 local cf = self._configsets:getConfigurationSets()
284
285                 local len_ = #cf
286
287                 for i = 1,len_ do
288                     config_sets[i] = {id="",description="",configuration_data={}}
289                     toConfigurationSet(config_sets[i], cf[i])
290                 end
291             end)
292         if not success then
293             --print(exception)
294             self._rtcout:RTC_ERROR(exception)
295             error(self._orb:newexcept{"SDOPackage::InternalError",
296                     description="Configuration.get_configuration_sets"
297             })
298         end
299
300         return config_sets
301     end
302
303
304
305
306
307
308     return obj
309 end
310
311
312
313
314 return SdoConfiguration

File lua\openrtm\SdoServiceAdmin.lua

1 ---------------------------------
2 --! @file SdoServiceAdmin.lua
3 --! @brief SDOサービス管理クラス定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local SdoServiceAdmin= {}
11 local StringUtil = require "openrtm.StringUtil"
12 local SdoServiceProviderBase = require "openrtm.SdoServiceProviderBase"
13 local SdoServiceProviderFactory = SdoServiceProviderBase.SdoServiceProviderFactory
14 local StringUtil = require "openrtm.StringUtil"
15 local NVUtil = require "openrtm.NVUtil"
16 local SdoServiceConsumerBase = require "openrtm.SdoServiceConsumerBase"
17 local SdoServiceConsumerFactory = SdoServiceConsumerBase.SdoServiceConsumerFactory
18 local uuid = require "uuid"
19
20 --_G["openrtm.SdoServiceAdmin"] = SdoServiceAdmin
21
22
23 -- SDOサービス管理オブジェクト初期化
24 -- @param rtobj RTC
25 -- @return SDOサービス管理オブジェクト
26 SdoServiceAdmin.new = function(rtobj)
27     local obj = {}
28     obj._rtobj = rtobj
29     obj._consumerTypes = {}
30     obj._providers = {}
31     obj._consumers = {}
32     obj._allConsumerEnabled = false
33     local Manager = require "openrtm.Manager"
34     obj._manager = Manager:instance()
35     
36     obj._rtcout = obj._manager:getLogbuf("rtobject.sdo_config")
37     -- 初期化時にRTC設定
38     -- @param rtobj RTC
39     function obj:init(rtobj)
40         self._rtcout:RTC_TRACE("SdoServiceAdmin::SdoServiceAdmin(%s)",
41         rtobj:getProperties():getProperty("instance_name"))
42
43         local prop = self._rtobj:getProperties()
44
45         local enabledProviderTypes = StringUtil.split(prop:getProperty("sdo.service.provider.enabled_services"),",")
46         enabledProviderTypes = StringUtil.strip(enabledProviderTypes)
47         
48         self._rtcout:RTC_DEBUG("sdo.service.provider.enabled_services: %s", prop:getProperty("sdo.service.provider.enabled_services"))
49
50         local availableProviderTypes = SdoServiceProviderFactory:instance():getIdentifiers()
51         prop:setProperty("sdo.service.provider.available_services", tostring(StringUtil.flatten(availableProviderTypes)))
52         self._rtcout:RTC_DEBUG("sdo.service.provider.available_services: %s", prop:getProperty("sdo.service.provider.available_services"))
53
54
55         local activeProviderTypes = {}
56         
57         for i,ep_type in ipairs(enabledProviderTypes) do
58             local tmp = string.lower(ep_type)
59             
60             if tmp == "all" then
61                 --print(tmp)
62                 activeProviderTypes = availableProviderTypes
63                 self._rtcout:RTC_DEBUG("sdo.service.provider.enabled_services: ALL")
64                 break
65             end
66             for j,ap_type in ipairs(availableProviderTypes) do
67                 if ap_type == ep_type then
68                     table.insert(activeProviderTypes, ap_type)
69                 end
70             end
71         end
72
73         local factory = SdoServiceProviderFactory:instance()
74         for i,ap_type in ipairs(activeProviderTypes) do
75             local svc = factory:createObject(ap_type)
76             local propkey = self:ifrToKey(ap_type)
77             local properties = {}
78             NVUtil.copyFromProperties(properties, prop:getNode(tostring(propkey)))
79             local prof = {
80                 id = tostring(ap_type),
81                 interface_type = tostring(ap_type),
82                 properties = properties,
83                 service = svc._svr}
84                 
85                 
86
87             if not svc:init(rtobj, prof) then
88                 svc:finalize()
89             else
90                 table.insert(self._providers, svc)
91             end
92         end
93
94
95
96
97         local constypes = prop:getProperty("sdo.service.consumer.enabled_services")
98
99         
100         self._consumerTypes = StringUtil.split(constypes,",")
101         self._consumerTypes = StringUtil.strip(self._consumerTypes)
102         self._rtcout:RTC_DEBUG("sdo.service.consumer.enabled_services: %s", tostring(constypes))
103
104         prop:setProperty("sdo.service.consumer.available_services",
105             tostring(StringUtil.flatten(SdoServiceConsumerFactory:instance():getIdentifiers())))
106         self._rtcout:RTC_DEBUG("sdo.service.consumer.available_services: %s",
107             prop:getProperty("sdo.service.consumer.available_services"))
108
109         
110
111         for i, ctype in ipairs(self._consumerTypes) do
112             local tmp = string.lower(ctype)
113             if tmp == "all" then
114                 self._allConsumerEnabled = true
115                 self._rtcout:RTC_DEBUG("sdo_service.consumer_types: ALL")
116             end
117         end
118     end
119     -- 終了処理
120     function obj:exit()
121
122         for i, provider in ipairs(self._providers) do
123             provider:finalize()
124         end
125
126         self._providers = {}
127
128
129         for i, consumer in ipairs(self._consumers) do
130             consumer:finalize()
131         end
132
133         self._consumers = {}
134     end
135     
136     function obj:getServiceProviderProfiles()
137         local prof = {}
138         for i,provider in ipairs(self._providers) do
139             table.insert(prof, provider:getProfile())
140         end
141         return prof
142     end
143
144     function obj:getServiceProviderProfile(id)
145         local idstr = id
146
147         for i,provider in ipairs(self._providers) do
148             if idstr == tostring(provider:getProfile().id) then
149                 return provider:getProfile()
150             end
151         end
152
153         error(self._orb:newexcept{"SDOPackage::InvalidParameter",
154                 description=""
155             })
156     end
157
158     function obj:getServiceProvider(id)
159         local prof = self:getServiceProviderProfile(id)
160         return prof.service
161     end
162
163     function obj:addSdoServiceProvider(prof, provider)
164         self._rtcout:RTC_TRACE("SdoServiceAdmin::addSdoServiceProvider(if=%s)",
165                            prof.interface_type)
166         local id = prof.id
167         for i,provider in ipairs(self._providers) do
168             if id == tostring(provider:getProfile().id) then
169                 self._rtcout:RTC_ERROR("SDO service(id=%s, ifr=%s) already exists",
170                                tostring(prof.id), tostring(prof.interface_type))
171                 return false
172             end
173         end
174
175         table.insert(self._providers, provider)
176         return true
177     end
178
179     function obj:removeSdoServiceProvider(id)
180         self._rtcout:RTC_TRACE("removeSdoServiceProvider(%d)", id)
181     
182         local strid = id
183         
184         for i,provider in ipairs(self._providers) do
185             if strid == tostring(provider:getProfile().id) then
186                 provider:finalize()
187                 local factory = SdoServiceProviderFactory:instance()
188                 factory:deleteObject(self._providers[idx])
189                 table.remove(self._providers, i)
190                 self._rtcout:RTC_INFO("SDO service provider has been deleted: %s", id)
191                 return true
192             end
193         end
194            self._rtcout:RTC_WARN("Specified SDO service provider not found: %s", id)
195         return false
196     end
197
198     function obj:addSdoServiceConsumer(sProfile)
199         self._rtcout:RTC_TRACE("addSdoServiceConsumer(IFR = %s)",
200                            sProfile.interface_type)
201         local profile = sProfile
202     
203
204         if not self:isEnabledConsumerType(sProfile) then
205             self._rtcout:RTC_ERROR("Not supported consumer type. %s", profile.interface_type)
206             return false
207         end
208   
209         if not self:isExistingConsumerType(sProfile) then
210               self._rtcout:RTC_ERROR("type %s not exists.", profile.interface_type)
211             return false
212         end
213         if tostring(profile.id) ==  "" then
214             self._rtcout:RTC_WARN("No id specified. It should be given by clients.")
215             return false
216         end
217
218
219         local id = tostring(sProfile.id)
220         for i,consumer in ipairs(self._consumers) do
221               if id == tostring(self._consumers[i]:getProfile().id) then
222                 self._rtcout:RTC_INFO("Existing consumer is reinitilized.")
223                 self._rtcout:RTC_DEBUG("Propeteis are: %s",
224                                NVUtil.toString(sProfile.properties))
225                 return consumer:reinit(sProfile)
226             end
227         end
228
229
230         local factory = SdoServiceConsumerFactory:instance()
231         local ctype = tostring(profile.interface_type)
232         local consumer = factory:createObject(ctype)
233
234
235         if not consumer:init(self._rtobj, sProfile) then
236             self._rtcout:RTC_WARN("SDO service initialization was failed.")
237             self._rtcout:RTC_DEBUG("id: %s", tostring(sProfile.id))
238             self._rtcout:RTC_DEBUG("IFR: %s", tostring(sProfile.interface_type))
239             self._rtcout:RTC_DEBUG("properties: %s", NVUtil.toString(sProfile.properties))
240               factory:deleteObject(consumer)
241               self._rtcout:RTC_INFO("SDO consumer was deleted by initialization failure")
242             return false
243         end
244
245
246         table.insert(self._consumers, consumer)
247
248         return true
249     end
250
251     function obj:removeSdoServiceConsumer(id)
252         if id == "" then
253             self._rtcout:RTC_ERROR("removeSdoServiceConsumer(): id is invalid.")
254             return false
255         end
256         self._rtcout:RTC_TRACE("removeSdoServiceConsumer(id = %s)", id)
257
258         local strid = id
259
260         for idx,cons in ipairs(self._consumers) do
261             if strid == tostring(cons:getProfile().id) then
262                 cons:finalize()
263                 table.remove(self._consumers, idx)
264                 local factory = SdoServiceConsumerFactory:instance()
265                 factory:deleteObject(cons)
266                 self._rtcout:RTC_INFO("SDO service has been deleted: %s", id)
267                 return true
268             end
269         end
270
271         self._rtcout:RTC_WARN("Specified SDO consumer not found: %s", id)
272         return false
273     end
274
275     function obj:isEnabledConsumerType(sProfile)
276         if self._allConsumerEnabled then
277             return true
278         end
279
280         for i, consumer in ipairs(self._consumerTypes) do
281             if consumer == tostring(sProfile.interface_type) then
282                 self._rtcout:RTC_DEBUG("%s is supported SDO service.",
283                                tostring(sProfile.interface_type))
284                 return true
285             end
286         end
287
288         self._rtcout:RTC_WARN("Consumer type is not supported: %s",
289                           tostring(sProfile.interface_type))
290         return false
291     end
292
293     function obj:isExistingConsumerType(sProfile)
294         local factory = SdoServiceConsumerFactory:instance()
295         local consumerTypes = factory:getIdentifiers()
296         --print(#consumerTypes, sProfile.interface_type)
297         for i, consumer in ipairs(consumerTypes) do
298             if consumer == tostring(sProfile.interface_type) then
299                 self._rtcout:RTC_DEBUG("%s exists in the SDO service factory.", tostring(sProfile.interface_type))
300                 self._rtcout:RTC_PARANOID("Available SDO serices in the factory: %s", tostring(StringUtil.flatten(consumerTypes)))
301                 return true
302             end
303         end
304         self._rtcout:RTC_WARN("No available SDO service in the factory: %s",
305                           tostring(sProfile.interface_type))
306         return false
307     end
308
309     function obj:getUUID()
310         return uuid()
311     end
312
313     function obj:ifrToKey(ifr)
314         local ifrvstr = StringUtil.split(ifr, ":")
315         ifrvstr[2] = string.lower(ifrvstr[2])
316         ifrvstr[2] = string.gsub(ifrvstr[2], "%.", "_")
317         ifrvstr[2] = string.gsub(ifrvstr[2], "/", "%.")
318         return ifrvstr[2]
319     end
320
321     return obj
322 end
323
324
325 return SdoServiceAdmin

File lua\openrtm\SdoServiceConsumerBase.lua

Full coverage

File lua\openrtm\SdoServiceProviderBase.lua

1 ---------------------------------
2 --! @file SdoServiceProviderBase.lua
3 --! @brief SDOサービスプロバイダ基底クラス定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local SdoServiceProviderBase= {}
11 local GlobalFactory = require "openrtm.GlobalFactory"
12 local Factory = GlobalFactory.Factory
13 local RTCUtil = require "openrtm.RTCUtil"
14 --_G["openrtm.SdoServiceProviderBase"] = SdoServiceProviderBase
15
16 SdoServiceProviderBase.new = function()
17     local obj = {}
18     local Manager = require "openrtm.Manager"
19     obj._manager = Manager:instance()
20     obj._orb = obj._manager:getORB()
21
22     -- オブジェクトリファレンス生成
23     function obj:createRef()
24         self._svr = self._orb:newservant(self, nil, "IDL:org.omg/SDOPackage/SDOService:1.0")
25         self._objref = RTCUtil.getReference(self._orb, self._svr, "IDL:org.omg/SDOPackage/SDOService:1.0")
26     end
27     function obj:init(rtobj, profile)
28
29     end
30     function obj:reinit(profile)
31         
32     end
33     function obj:getProfile()
34         
35     end
36     function obj:finalize()
37         local Manager = require "openrtm.Manager"
38         Manager:instance():getORB():deactivate(self._svr)
39     end
40     return obj
41 end
42
43
44 SdoServiceProviderBase.SdoServiceProviderFactory = {}
45 setmetatable(SdoServiceProviderBase.SdoServiceProviderFactory, {__index=Factory.new()})
46
47 function SdoServiceProviderBase.SdoServiceProviderFactory:instance()
48     return self
49 end
50
51
52 return SdoServiceProviderBase

File lua\openrtm\SimulatorExecutionContext.lua

1 ---------------------------------
2 --! @file SimulatorExecutionContext.lua
3 --! @brief トリガ駆動実行コンテキスト定義
4 ---------------------------------
5
6
7 --[[
8 Copyright (c) 2017 Nobuhiko Miyamoto
9 ]]
10
11 local SimulatorExecutionContext= {}
12 --_G["openrtm.SimulatorExecutionContext"] = SimulatorExecutionContext
13
14 local ExecutionContextBase = require "openrtm.ExecutionContextBase"
15
16 local ExecutionContextBase = require "openrtm.ExecutionContextBase"
17 local ExecutionContextFactory = ExecutionContextBase.ExecutionContextFactory
18 local ECFactory = require "openrtm.ECFactory"
19 local oil = require "oil"
20
21 local RTCUtil = require "openrtm.RTCUtil"
22
23 local OpenHRPExecutionContext = require "openrtm.OpenHRPExecutionContext"
24
25
26 -- シミュレーション用コンテキスト初期化
27 -- @return SimulatorExecutionContext
28 SimulatorExecutionContext.new = function()
29     local obj = {}
30     setmetatable(obj, {__index=OpenHRPExecutionContext.new()})
31     local Manager = require "openrtm.Manager"
32
33
34     obj._svr = Manager:instance():getORB():newservant(obj, nil, "IDL:openrtm.aist.go.jp/OpenRTM/ExtTrigExecutionContextService:1.0")
35     local ref = RTCUtil.getReference(Manager:instance():getORB(), obj._svr, "IDL:openrtm.aist.go.jp/OpenRTM/ExtTrigExecutionContextService:1.0")
36     obj:setObjRef(ref)
37
38
39     
40     function obj:activate_component(comp)
41         
42         local rtobj = self._worker:findComponent(comp)
43         
44         if rtobj == nil then
45             return self._ReturnCode_t.BAD_PARAMETER
46         end
47         
48         if not rtobj:isCurrentState(self._LifeCycleState.INACTIVE_STATE) then
49             return self._ReturnCode_t.PRECONDITION_NOT_MET
50         end
51         
52       
53         self._syncActivation = false
54         self:activateComponent(comp)
55     
56         self:invokeWorkerPreDo()
57
58         if rtobj:isCurrentState(self._LifeCycleState.ACTIVE_STATE) then
59             return self._ReturnCode_t.RTC_OK
60         end
61
62         return self._ReturnCode_t.RTC_ERROR
63     end
64
65
66     function obj:deactivate_component(comp)
67         local rtobj = self._worker:findComponent(comp)
68         if rtobj == nil then
69             return self._ReturnCode_t.BAD_PARAMETER
70         end
71         if not rtobj:isCurrentState(self._LifeCycleState.ACTIVE_STATE) then
72             return self._ReturnCode_t.PRECONDITION_NOT_MET
73         end
74       
75         self._syncDeactivation = false
76         self:deactivateComponent(comp)
77     
78         self:invokeWorkerPreDo()
79         self:invokeWorkerDo()
80         self:invokeWorkerPostDo()
81
82
83         if rtobj:isCurrentState(self._LifeCycleState.INACTIVE_STATE) then
84             return self._ReturnCode_t.RTC_OK
85         end
86
87         return self._ReturnCode_t.RTC_ERROR
88     end
89
90
91     function obj:reset_component(comp)
92         local rtobj = self._worker:findComponent(comp)
93         if rtobj == nil then
94             return self._ReturnCode_t.BAD_PARAMETER
95         end
96         if not rtobj:isCurrentState(self._LifeCycleState.ERROR_STATE) then
97             return self._ReturnCode_t.PRECONDITION_NOT_MET
98         end
99       
100         self._syncReset = false
101         self:resetComponent(comp)
102     
103         self:invokeWorkerPreDo()
104         self:invokeWorkerDo()
105         self:invokeWorkerPostDo()
106
107
108         if rtobj:isCurrentState(self._LifeCycleState.INACTIVE_STATE) then
109             return self._ReturnCode_t.RTC_OK
110         end
111
112         return self._ReturnCode_t.RTC_ERROR
113     end
114
115     return obj
116 end
117
118
119 -- SimulatorExecutionContext生成ファクトリ登録関数
120 SimulatorExecutionContext.Init = function(manager)
121     ExecutionContextFactory:instance():addFactory("SimulatorExecutionContext",
122         SimulatorExecutionContext.new,
123         ECFactory.ECDelete)
124 end
125
126
127 return SimulatorExecutionContext

File lua\openrtm\StateMachine.lua

Full coverage

File lua\openrtm\StringUtil.lua

1 ---------------------------------
2 --! @file StringUtil.lua
3 --! @brief 文字列操作関数定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local StringUtil= {}
11 --_G["openrtm.StringUtil"] = StringUtil
12
13
14 -- 文字列先頭の空白削除
15 -- @param _str 文字列
16 -- @return 空白削除後の文字列
17 StringUtil.eraseHeadBlank = function(_str)
18     return (string.gsub(_str, "^%s*(.-)$", "%1"))
19 end
20
21 -- 文字列末尾の空白削除
22 -- @param _str 文字列
23 -- @return 空白削除後の文字列
24 StringUtil.eraseTailBlank = function(_str)
25     return (string.gsub(_str, "^(.-)%s*$", "%1"))
26 end
27
28 -- 文字列先頭と末尾の空白削除
29 -- @param _str 文字列
30 -- @return 空白削除後の文字列
31 StringUtil.eraseBothEndsBlank = function(_str)
32     return (string.gsub(_str, "^%s*(.-)%s*$", "%1"))
33 end
34
35
36 -- 文字列の正規化
37 -- @param _str 文字列
38 -- @return 正規化後の文字列
39 StringUtil.normalize = function(_str)
40     local ret = string.gsub(_str, "^%s*(.-)%s*$", "%1")
41     return string.lower(ret)
42 end
43
44 -- リストの要素全ての文字列の前後の空白を削除
45 -- @param str_list 文字列のリスト
46 -- @return 前後の空白削除後の文字列のリスト
47 StringUtil.strip = function(str_list)
48     local ret = {}
49     for k,v in ipairs(str_list) do
50         table.insert(ret, StringUtil.eraseBothEndsBlank(v))
51     end
52     return ret
53 end
54
55 -- 文字列にエスケープ文字が含まれるかを判定
56 -- @param _str 文字列
57 -- @param pos 位置
58 -- @return true;エスケープ文字が含まれる、false:含まれない
59 StringUtil.isEscaped = function(_str, pos)
60     --pos = pos-1
61
62     local i = 0
63     --print(string.sub(_str, pos, pos))
64     while pos >= 0 and string.sub(_str, pos, pos) == "\\" do
65         i = i+1
66         pos = pos-1
67     end
68
69     return (i % 2 == 1)
70 end
71
72
73 local unescape_functor = {}
74 -- エスケープ文字に変換する関数オブジェクト初期化
75 -- @return 関数オブジェクト
76 unescape_functor.new = function()
77     local obj = {}
78     obj.count  = 0
79     obj._str  = ""
80     -- エスケープ文字に変換する
81     -- @param self 自身のオブジェクト
82     -- @param c 文字
83     local call_func = function(self, c)
84         if c == "\\" then
85             self.count = self.count+1
86             if self.count % 2 == 0 then
87                 self._str = self._str..c
88             end
89         else
90             if self.count > 0 and self.count % 2 == 1 then
91                 self.count = 0
92                 if c == 't' then
93                     self._str=self._str..'\t'
94                 elseif c == 'n' then
95                     self._str=self._str..'\n'
96                 elseif c == 'f' then
97                     self._str=self._str..'\f'
98                 elseif c == 'r' then
99                     self._str=self._str..'\r'
100                 elseif c == '\"' then
101                     self._str=self._str..'\"'
102                 elseif c == '\'' then
103                     self._str=self._str..'\''
104                 else
105                     self._str=self._str..c
106                 end
107             else
108                 self.count = 0
109                 self._str=self._str..c
110             end
111         end
112     end
113     setmetatable(obj, {__call=call_func})
114     return obj
115 end
116
117 -- 文字列のアンエスケープ
118 -- @param _str 文字列
119 -- @return アンエスケープ後の文字列
120 StringUtil.unescape = function(_str)
121     local functor = unescape_functor.new()
122     for i=1,#_str do
123         functor(string.sub(_str,i,i))
124     end
125     return functor._str
126 end
127
128 -- テーブルのコピー
129 -- @param orig コピー物のテーブル
130 -- @return コピー後のテーブル
131 StringUtil.copy = function(orig)
132     local copy = {}
133     if type(orig) == 'table' then
134         for k, v in ipairs(orig) do
135             copy[k] = v
136         end
137     else
138         copy = orig
139     end
140     return copy
141 end
142
143 -- テーブルのコピー
144 -- @param orig コピー物のテーブル
145 -- @return コピー後のテーブル
146 StringUtil.deepcopy = function(orig)
147     local copy = {}
148     if type(orig) == 'table' then
149         for k, v in pairs(orig) do
150             copy[k] = StringUtil.deepcopy(v)
151         end
152     else
153         copy = orig
154     end
155     return copy
156 end
157
158
159
160 -- 文字列の分割
161 -- @param input 文字列
162 -- @param delimiter 分割文字
163 -- @return 文字列のリスト
164 StringUtil.split = function(input, delimiter)
165     --print(input:find(delimiter))
166     if string.find(input, delimiter) == nil then
167         return { input }
168     end
169     local result = {}
170     local pat = "(.-)" .. delimiter .. "()"
171     local lastPos = 0
172     for part, pos in string.gmatch(input, pat) do
173         table.insert(result, part)
174         lastPos = pos
175     end
176     table.insert(result, string.sub(input, lastPos))
177     return result
178 end
179
180 -- テーブルを標準出力
181 -- @param tbl テーブル
182 StringUtil.print_table = function(tbl)
183     for k, v in pairs(tbl) do
184         if type(v)=="table" then
185             --print( k..":" )
186             StringUtil.print_table(v)
187         else
188             print( k, v )
189         end
190     end
191 end
192
193 -- 文字列をboolに変換
194 -- @param _str 文字列
195 -- @param yes trueの場合の文字列
196 -- @param no falseの場合の文字列
197 -- @param default_value デフォルト値
198 -- @return bool値
199 StringUtil.toBool = function(_str, yes, no, default_value)
200     if default_value == nil then
201         default_value = true
202     end
203     --print(_str)
204     _str = _str:lower()
205     yes = yes:lower()
206     no = no:lower()
207     if _str:match(yes) ~= nil then
208         return true
209     elseif _str:match(no) ~= nil then
210         return false
211     end
212     return default_value
213 end
214
215
216
217 -- 数値を文字列に変換
218 -- @param n 数値
219 -- @return 文字列
220 StringUtil.otos = function(n)
221     return ""..n
222 end
223
224 -- テーブルに値が含まれるかの判定
225 -- @param tbl テーブル
226 -- @param val 値
227 -- @return true;含まれる、false:含まれない
228 StringUtil.in_value = function(tbl, val)
229     for k, v in pairs (tbl) do
230         if v==val then
231             return true
232         end
233     end
234     return false
235 end
236
237 -- テーブルにキーが含まれるかの判定
238 -- @param tbl テーブル
239 -- @param key キー
240 -- @return true;含まれる、false:含まれない
241 StringUtil.in_key = function(tbl, key)
242     if tbl[key] ~= nil then
243         return true
244     end
245     return false
246 end
247
248 -- テーブルから重複する値を削除
249 -- @param sv テーブル
250 -- @return 値削除後のテーブル
251 StringUtil.unique_sv = function(sv)
252     local unique_strvec = StringUtil.unique_strvec.new()
253     for i,v in ipairs(sv) do
254         unique_strvec(v)
255     end
256     return unique_strvec._str
257 end
258
259 StringUtil.unique_strvec = {}
260
261 -- テーブルに同じ値が含まれなかった場合に追加する関数オブジェクト初期化
262 -- @return 関数オブジェクト
263 StringUtil.unique_strvec.new = function()
264     local obj = {}
265     obj._str = {}
266     -- テーブルに同じ値が含まれなかった場合に追加する
267     -- @param self 自身のオブジェクト
268     -- @param s 値
269     -- @return テーブル
270     local call_func = function(self, s)
271         if not StringUtil.in_value(self._str, s) then
272             table.insert(self._str, s)
273             return self._str
274         end
275     end
276     setmetatable(obj, {__call=call_func})
277     return obj
278 end
279
280 -- テーブルを文字列に変換
281 -- @param sv テーブル
282 -- @param delimiter 区切り文字
283 -- @return 文字列
284 StringUtil.flatten = function(sv, delimiter)
285     if delimiter == nil then
286         delimiter = ", "
287     end
288     if #sv == 0 then
289         return ""
290     end
291     local _str = table.concat(sv, delimiter)
292
293     return _str
294 end
295
296 -- テーブルに指定の値が含まれる数を取得
297 -- @param tbl テーブル
298 -- @param value 値
299 -- @return 含まれていた数
300 StringUtil.table_count = function(tbl, value)
301     local count = 0
302     for i, v in ipairs(tbl) do
303         if value == v then
304             count = count+1
305         end
306     end
307     return count
308 end
309
310 -- テーブルに指定の値が何番目に含まれているかを取得
311 -- @param tbl テーブル
312 -- @param value 値
313 -- @return キー
314 StringUtil.table_index = function(tbl, value)
315     for i, v in ipairs(tbl) do
316         if value == v then
317             return i
318         end
319     end
320     return -1
321 end
322
323 -- テーブルに値が含まれるかの確認
324 -- @param _list テーブル、文字列の場合はテーブルに変換
325 -- @param value 値
326 -- @param ignore_case true:小文字化して判定
327 -- @return true:含まれる、false:含まれない
328 StringUtil.includes = function(_list, value, ignore_case)
329     if ignore_case == nil then
330         ignore_case = true
331     end
332
333     if not (type(_list) == "table" or type(_list) == "string") then
334
335         return false
336     end
337
338     if type(_list) == "string" then
339         _list = StringUtil.split(_list, ",")
340     end
341
342
343     local tmp_list = _list
344     if ignore_case then
345         value = string.lower(value)
346         tmp_list = {}
347         for i, v in ipairs(_list) do
348             table.insert(tmp_list, string.lower(v))
349         end
350     end
351     if StringUtil.table_count(tmp_list, value) > 0 then
352         return true
353     end
354
355     return false
356 end
357
358 -- 文字列をリストに変換
359 -- @param _type 変換後の型
360 -- @param _str 文字列
361 -- @return ret(true:変換成功),リスト
362 StringUtil._stringToList = function(_type, _str)
363
364     local list_ = StringUtil.split(_str, ",")
365     local ans = {}
366     if #_type < #list_ then
367         local sub = #list_ - #_type
368         for i = 1,sub do
369             table.insert(_type, _type[1])
370         end
371     elseif #_type > #list_ then
372         local sub = #_type - #list_
373         for i = #list_,#_type do
374             table.remove(_type, i)
375         end
376     end
377     for i = 1,#list_ do
378         if type(_type[i]) == "number" then
379             table.insert(ans, tonumber(list_[i]))
380         elseif type(_type[i]) == "string" then
381             table.insert(ans, tostring(list_[i]))
382         end
383     end
384
385     return true, ans
386
387
388 end
389
390 -- 文字列を指定した型に変換
391 -- @param _type 変換後の型
392 -- @param _str 文字列
393 -- @return ret(true:変換成功、false:変換失敗)、変換後の値
394 StringUtil.stringTo = function(_type, _str)
395     if type(_type) == "number" then
396         local value = tonumber(_str)
397         if value ~= nil then
398             return true, value
399         else
400             return false, _type
401         end
402     elseif type(_type) == "string" then
403         local value = tostring(_str)
404         if value ~= nil then
405             return true, value
406         else
407             return false, _type
408         end
409     elseif type(_type) == "table" then
410         return StringUtil._stringToList(_type, _str)
411     else
412         return false, _type
413     end
414
415 end
416
417 -- 文字列から設定か可能なオプションのリスト取得
418 -- @param options 文字列
419 -- @return オプション一覧。optargがtrueの場合はオプションの後ろに値を設定する。
420 StringUtil.createopt = function(options)
421     local ret = {}
422     local pos = 1
423     while pos <= #options do
424         local opt = string.sub(options,pos,pos)
425         ret[opt] = {}
426         pos = pos + 1
427         if pos <= #options then
428             local opt2 = string.sub(options,pos,pos)
429             if opt2 == ":" then
430                 ret[opt].optarg = true
431                 pos = pos + 1
432             else
433                 ret[opt].optarg = false
434             end
435         end
436     end
437     return ret
438 end
439
440 -- 文字列からオプション取得
441 -- @param arg 文字列
442 -- @param options オプション一覧の文字列
443 -- @return オプション一覧。optargに値が入る。
444 StringUtil.getopt = function(arg, options)
445     local ret = {}
446     local pos = 1
447     local opt = StringUtil.createopt(options)
448     --for i,v in pairs(opt) do
449     -- print(i,v.value)
450     --end
451     while pos <= #arg do
452         arg[pos] = StringUtil.eraseBothEndsBlank(arg[pos])
453         if #arg[pos] <= 1 then
454             pos = pos + 1
455         elseif string.sub(arg[pos],1,1) == "-" then
456             local _id = string.sub(arg[pos],2)
457             if opt[_id] ~= nil then
458                 local v = {id=_id}
459                 if opt[_id].optarg then
460                     pos = pos+1
461                     if pos <= #arg then
462                         v.optarg = arg[pos]
463                     end
464                 end
465                 --print(v)
466                 table.insert(ret, v)
467             end
468             pos = pos + 1
469         else
470             pos = pos + 1
471         end
472     end
473     return ret
474 end
475
476 -- パスからディレクトリパスを取り出し
477 -- @param path パス
478 -- @return ディレクトリパス
479 StringUtil.dirname = function(path)
480     local delimiter = "\\"
481     if string.find(path, "/", 1, true) ~= nil then
482         delimiter = "/"
483     end
484     local path_list = StringUtil.split(path, delimiter)
485     path_list[#path_list] = nil
486     local ret = StringUtil.flatten(path_list, delimiter)
487     if #ret == 0 then
488         return ret
489     else
490         return ret..delimiter
491     end
492     
493 end
494
495
496 -- パスからファイル名を取得
497 -- @param path パス
498 -- @return ファイル名
499 StringUtil.basename = function(path)
500     local delimiter = "\\"
501     if string.find(path, "/", 1, true) ~= nil then
502         delimiter = "/"
503     end
504     local path_list = StringUtil.split(path, delimiter)
505
506     return path_list[#path_list]
507 end
508
509
510 -- テーブルの要素数取得
511 -- @param tbl テーブル
512 -- @return 要素数
513 StringUtil.getKeyCount = function(tbl)
514     local ret = 0
515     for k,v in pairs(tbl) do
516         ret = ret + 1
517     end
518     return ret
519 end
520
521 -- 文字列がURLかを判定
522 -- @param str 文字列
523 -- @return true:URL
524 StringUtil.isURL = function(str)
525     if str == "" then
526         return false
527     end
528
529     local pos,c = string.find(str, "://")
530     if pos ~= 1 and pos ~= nil then
531         return true
532     end
533     return false
534 end
535
536
537
538
539 -- 文字列が絶対パスかを判定
540 -- @param 文字列
541 -- @return true:絶対パス
542 StringUtil.isAbsolutePath = function(str)
543     if string.sub(str,1,1) == "/" then
544         return true
545     end
546     if string.match(string.sub(str,1,1), '[a-zA-Z]') then
547         if string.sub(str,2,2) == ":" and (string.sub(str,3,3) == "\\" or string.sub(str,3,3) == "/") then
548             return true
549         end
550     end
551     if string.sub(str,1,1) == "\\" and string.sub(str,2,2) == "\\" then
552         return true
553     end
554
555   return false
556 end
557
558 -- URL形式の文字列からパラメータを取得
559 -- @param _str URL形式の文字列
560 -- param?key1=value1&key2=value2
561 -- @return パラメータを格納したテーブル
562 StringUtil.urlparam2map = function(_str)
563     local qpos = string.find(_str, "?")
564     if qpos == nil then
565         qpos = 0
566     else
567         qpos = qpos+1
568     end
569     local tmp = StringUtil.split(string.sub(_str, qpos), "&")
570     local retmap = {}
571     for k, v in ipairs(tmp) do
572         pos = string.find(v, "=")
573         if pos ~= nil then
574             retmap[string.sub(v,1,pos-1)] = string.sub(v, pos+1)
575         else
576             retmap[v] = ""
577         end
578     end
579     return retmap
580 end
581
582
583 return StringUtil

File lua\openrtm\SystemLogger.lua

1 ---------------------------------
2 --! @file SystemLogger.lua
3 --! @brief ロガー管理クラス定義
4 --! SILENT ログ出力無し
5 --! 出力する場合は以下の8段階
6 --! FATAL、ERROR、WARN、INFO、DEBUG、TRACE、VERBOSE、PARANOID
7 --! 現状、loggingライブラリの都合で以下の5段階になっている
8 --! FATAL、ERROR、WARN、INFO、DEBUG
9 --! DEBUG、TRACE、VERBOSE、PARANOIDはDEBUGの出力になる
10 ---------------------------------
11
12 --[[
13 Copyright (c) 2017 Nobuhiko Miyamoto
14 ]]
15
16 local Logger= {}
17 --_G["openrtm.SystemLogger"] = SystemLogger
18
19 Logger.LogStream = {}
20 local NO_LOGGER = true
21
22 Logger.SILENT = 0
23 Logger.FATAL = 1
24 Logger.ERROR = 2
25 Logger.WARN = 3
26 Logger.INFO = 4
27 Logger.DEBUG = 5
28 Logger.TRACE = 6
29 Logger.VERBOSE = 7
30 Logger.PARANOID = 8
31
32 -- 文字列をログレベルに変換
33 -- @oaram lv 文字列
34 -- @return ログレベル
35 Logger.strToLogLevel = function(lv)
36     if lv == "SILENT" then
37         return Logger.SILENT
38     elseif lv == "FATAL" then
39         return Logger.FATAL
40     elseif lv == "ERROR" then
41         return Logger.ERROR
42     elseif lv == "WARN" then
43         return Logger.WARN
44     elseif lv == "INFO" then
45         return Logger.INFO
46     elseif lv == "DEBUG" then
47         return Logger.DEBUG
48     elseif lv == "TRACE" then
49         return Logger.TRACE
50     elseif lv == "VERBOSE" then
51         return Logger.VERBOSE
52     elseif lv == "PARANOID" then
53         return Logger.PARANOID
54     else
55         return Logger.INFO
56     end
57 end
58
59
60 Logger.printf = function(fmt)
61     return fmt
62 end
63
64 -- ロガーストリーム初期化
65 -- @return ロガーストリーム
66 Logger.LogStream.new = function()
67     local obj = {}
68     obj._LogLock = false
69     obj._logger_name = ""
70     obj._loggerObj = {}
71     obj._log_enable = true
72     
73     -- ロガーストリーム終了処理
74     function obj:shutdown()
75         for k,v in pairs(self._loggerObj) do
76             v:shutdown()
77         end
78         self._loggerObj = {}
79     end
80     
81     -- ロガー追加
82     -- @param loggerObj ロガー
83     function obj:addLogger(loggerObj)
84         table.insert(self._loggerObj, loggerObj)
85     end
86     
87     
88
89     -- ログレベル設定
90     -- @param level ログレベル(文字列)
91     function obj:setLogLevel(level)
92         local lvl = Logger.strToLogLevel(level)
93         for k,v in pairs(self._loggerObj) do
94             v:setLogLevel(lvl)
95         end
96     end
97     
98     function obj:setLogLock(lock)
99         if lock == 1 then
100             self._LogLock = true
101         elseif lock == 0 then
102             self._LogLock = false
103         end
104     end
105     
106     function obj:enableLogLock()
107         self._LogLock = true
108     end
109     
110     function obj:disableLogLock()
111         self._LogLock = false
112     end
113     
114     -- ログ出力
115     -- @param LV ログレベル
116     -- @param msg 出力フォーマット
117     -- @param ... 値
118     function obj:RTC_LOG(LV, msg, ...)
119         if self._log_enable then
120         --self.acquire()
121             msg = tostring(msg)
122             for k,v in pairs(self._loggerObj) do
123                 v:log(msg:format(...), LV, self._logger_name)
124             end
125       
126         end
127         --self.release()
128     end
129     
130     -- ログ出力(FATAL)
131     -- @param msg 出力フォーマット
132     -- @param ... 値
133     function obj:RTC_FATAL(msg, ...)
134         --self.acquire()
135         if self._log_enable then
136             msg = tostring(msg)
137             for k,v in pairs(self._loggerObj) do
138                 v:log(msg:format(...), Logger.FATAL, self._logger_name)
139             end
140         end
141         --self.release()
142     end
143     
144     -- ログ出力(ERROR)
145     -- @param msg 出力フォーマット
146     -- @param ... 値
147     function obj:RTC_ERROR(msg, ...)
148         --self.acquire()
149         if self._log_enable then
150             msg = tostring(msg)
151             for k,v in pairs(self._loggerObj) do
152                 v:log(msg:format(...), Logger.ERROR, self._logger_name)
153             end
154         end
155         --self.release()
156     end
157     
158     -- ログ出力(WARN)
159     -- @param msg 出力フォーマット
160     -- @param ... 値
161     function obj:RTC_WARN(msg, ...)
162         --self.acquire()
163         if self._log_enable then
164             msg = tostring(msg)
165             for k,v in pairs(self._loggerObj) do
166                 v:log(msg:format(...), Logger.WARN, self._logger_name)
167             end
168         end
169         --self.release()
170     end
171     
172     -- ログ出力(INFO)
173     -- @param msg 出力フォーマット
174     -- @param ... 値
175     function obj:RTC_INFO(msg, ...)
176         --self.acquire()
177         if self._log_enable then
178             msg = tostring(msg)
179             for k,v in pairs(self._loggerObj) do
180                 v:log(msg:format(...), Logger.INFO, self._logger_name)
181             end
182         end
183         --self.release()
184     end
185     
186     -- ログ出力(DEBUG)
187     -- @param msg 出力フォーマット
188     -- @param ... 値
189     function obj:RTC_DEBUG(msg, ...)
190         --self.acquire()
191         if self._log_enable then
192             msg = tostring(msg)
193             for k,v in pairs(self._loggerObj) do
194                 v:log(msg:format(...), Logger.DEBUG, self._logger_name)
195             end
196         end
197         --self.release()
198     end
199     
200     -- ログ出力(TRACE)
201     -- @param msg 出力フォーマット
202     -- @param ... 値
203     function obj:RTC_TRACE(msg, ...)
204         --self.acquire()
205         if self._log_enable then
206             msg = tostring(msg)
207             for k,v in pairs(self._loggerObj) do
208                 v:log(msg:format(...), Logger.TRACE, self._logger_name)
209             end
210         end
211         --self.release()
212     end
213     
214     -- ログ出力(VERBOSE)
215     -- @param msg 出力フォーマット
216     -- @param ... 値
217     function obj:RTC_VERBOSE(msg, ...)
218         --self.acquire()
219         if self._log_enable then
220             msg = tostring(msg)
221             for k,v in pairs(self._loggerObj) do
222                 v:log(msg:format(...), Logger.VERBOSE, self._logger_name)
223             end
224         end
225         --self.release()
226     end
227     
228     -- ログ出力(PARANOID)
229     -- @param msg 出力フォーマット
230     -- @param ... 値
231     function obj:RTC_PARANOID(msg, ...)
232         --self.acquire()
233         if self._log_enable then
234             msg = tostring(msg)
235             for k,v in pairs(self._loggerObj) do
236                 v:log(msg:format(...), Logger.PARANOID, self._logger_name)
237             end
238         end
239         --self.release()
240     end
241     
242     -- 指定名のロガー取得
243     -- @param name ロガー名
244     -- @return ロガー
245     function obj:getLogger(name)
246         local syslogger = {}
247         for k,v in pairs(self) do
248             syslogger[k] = v
249         end
250         syslogger._logger_name = name
251         return syslogger
252     end
253
254
255
256     return obj
257 end
258
259
260
261
262 return Logger

File lua\openrtm\Task.lua

Full coverage

File lua\openrtm\Timer.lua

1 ---------------------------------
2 --! @file Timer.lua
3 --! @brief タイマ関連の関数定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local Timer= {}
11 --_G["openrtm.Timer"] = Timer
12
13 local oil = require "oil"
14
15 Timer.new = function()
16     local obj = {}
17     return obj
18 end
19
20 -- 一定時間待機
21 -- @param tm 待機時間
22 Timer.sleep = function(tm)
23     if oil.VERSION == "OiL 0.6" then
24         oil.sleep(tm)
25     else
26         oil.tasks:suspend(tm)
27     end
28 end
29
30
31 return Timer

File lua\openrtm\TimeValue.lua

1 ---------------------------------
2 --! @file TimeValue.lua
3 --! @brief 時間ヘルパ関数定義
4 ---------------------------------
5
6 --[[
7 Copyright (c) 2017 Nobuhiko Miyamoto
8 ]]
9
10 local TimeValue= {}
11 --_G["openrtm.TimeValue"] = TimeValue
12
13 local TIMEVALUE_ONE_SECOND_IN_USECS = 1000000
14
15 -- 時間ヘルパ関数オブジェクト初期化
16 -- @return 関数オブジェクト
17 TimeValue.new = function(sec, usec)
18     local obj = {}
19     -- 時間を引く際のオペレータ
20     -- @param self 自身のオブジェクト
21     -- @param tm 引く時間関数オブジェクト
22     -- @return 引き算後の時間
23     local sub_func = function(self, tm)
24         local res = TimeValue.new()
25         --print("test",self.tv_sec, self.tv_usec, tm.tv_sec, tm.tv_usec)
26         if self.tv_sec >= tm.tv_sec then
27             if self.tv_usec >= tm.tv_usec then
28                 res.tv_sec  = self.tv_sec  - tm.tv_sec
29                 res.tv_usec = self.tv_usec - tm.tv_usec
30             else
31                 res.tv_sec  = self.tv_sec  - tm.tv_sec - 1
32                 res.tv_usec = (self.tv_usec + TIMEVALUE_ONE_SECOND_IN_USECS) - tm.tv_usec
33             end
34         else
35             if tm.tv_usec >= self.tv_usec then
36                 res.tv_sec  = -(tm.tv_sec  - self.tv_sec)
37                 res.tv_usec = -(tm.tv_usec - self.tv_usec)
38             else
39                 res.tv_sec  = -(tm.tv_sec - self.tv_sec - 1)
40                 res.tv_usec = -(tm.tv_usec + TIMEVALUE_ONE_SECOND_IN_USECS) + self.tv_usec
41             end
42         end
43
44         res:normalize()
45         return res
46     end
47     -- 時間を足す際のオペレータ
48     -- @param self 自身のオブジェクト
49     -- @param tm 足す時間関数オブジェクト
50     -- @return 足し算後の時間
51     local add_func = function(self, tm)
52         local res = TimeValue.new()
53         res.tv_sec  = self.tv_sec  + tm.tv_sec
54         res.tv_usec = self.tv_usec + tm.tv_usec
55         if res.tv_usec > TIMEVALUE_ONE_SECOND_IN_USECS then
56             res.tv_sec = res.tv_sec + 1
57             res.tv_usec = res.tv_usec - TIMEVALUE_ONE_SECOND_IN_USECS
58         end
59         res:normalize()
60         return res
61     end
62     -- 時間を文字列に変換するオペレータ
63     -- @param self 自身のオブジェクト
64     -- @return 文字列
65     local str_func = function(self)
66         local ret = ""..self.tv_sec..(self.tv_usec / TIMEVALUE_ONE_SECOND_IN_USECS)
67         return ret
68     end
69
70
71     setmetatable(obj, {__add =add_func,__sub=sub_func,__tostring=str_func})
72     -- 秒数取得
73     -- @return 秒数
74     function obj:sec()
75         return self.tv_sec
76     end
77     -- マイクロ秒数取得
78     -- @return マイクロ秒数
79     function obj:usec()
80         return self.tv_usec
81     end
82     -- 時間設定
83     -- @param _time 時間
84     -- @return 自身のオブジェクト
85     function obj:set_time(_time)
86         self.tv_sec  = _time - _time%1
87         self.tv_usec = (_time - self.tv_sec) * TIMEVALUE_ONE_SECOND_IN_USECS
88         self.tv_usec = self.tv_usec - self.tv_usec%1
89         return self
90     end
91     -- 時間を数値に変換
92     -- @return 数値
93     function obj:toDouble()
94         return self.tv_sec + self.tv_usec / TIMEVALUE_ONE_SECOND_IN_USECS
95     end
96     -- 時間の正負を判定
97     -- @return 1:正、-1:負、0:0
98     function obj:sign()
99         if self.tv_sec > 0 then
100             return 1
101         end
102         if self.tv_sec < 0 then
103             return -1
104         end
105         if self.tv_usec > 0 then
106             return 1
107         end
108         if self.tv_usec < 0 then
109             return -1
110         end
111         return 0
112     end
113
114     -- 時間の正規化
115     -- マイクロ秒数が1000000を超えていた場合に秒に変換
116     function obj:normalize()
117         if self.tv_usec >= TIMEVALUE_ONE_SECOND_IN_USECS then
118             self.tv_sec = self.tv_sec + 1
119             self.tv_usec = self.tv_usec - TIMEVALUE_ONE_SECOND_IN_USECS
120
121             while self.tv_usec >= TIMEVALUE_ONE_SECOND_IN_USECS do
122                 self.tv_sec = self.tv_sec + 1
123                 self.tv_usec = self.tv_usec - TIMEVALUE_ONE_SECOND_IN_USECS
124             end
125
126         elseif self.tv_usec <= -TIMEVALUE_ONE_SECOND_IN_USECS then
127             self.tv_sec = self.tv_sec - 1
128             self.tv_usec = self.tv_usec + TIMEVALUE_ONE_SECOND_IN_USECS
129
130             while self.tv_usec <= -TIMEVALUE_ONE_SECOND_IN_USECS do
131                 self.tv_sec = self.tv_sec - 1
132                 self.tv_usec = self.tv_usec + TIMEVALUE_ONE_SECOND_IN_USECS
133             end
134         end
135
136
137         if self.tv_sec >= 1 and self.tv_usec < 0 then
138             self.tv_sec = self.tv_sec - 1
139             self.tv_usec = self.tv_usec + TIMEVALUE_ONE_SECOND_IN_USECS
140
141         elseif self.tv_sec < 0 and self.tv_usec > 0 then
142             self.tv_sec = self.tv_sec + 1
143             self.tv_usec = self.tv_usec - TIMEVALUE_ONE_SECOND_IN_USECS
144         end
145     end
146
147     if type(sec) == "string" then
148         sec = tonumber(sec)
149     end
150     if type(usec) == "string" then
151         usec = tonumber(usec)
152     end
153     if sec ~= nil and usec == nil then
154         local dbHalfAdj_ = 0.0
155         if sec >= 0.0 then
156             dbHalfAdj_ = 0.5
157         else
158             dbHalfAdj_ = -0.5
159         end
160
161         obj.tv_sec = sec - sec%1
162         obj.tv_usec = (sec - obj.tv_sec) *
163                           TIMEVALUE_ONE_SECOND_IN_USECS + dbHalfAdj_
164         obj.tv_usec = obj.tv_usec - obj.tv_usec%1
165         obj:normalize()
166
167         return obj
168     end
169     if sec == nil then
170       obj.tv_sec = 0
171     else
172       obj.tv_sec = sec - sec%1
173     end
174
175     if usec == nil then
176       obj.tv_usec = 0
177     else
178       obj.tv_usec = usec - usec%1
179     end
180     obj:normalize()
181     return obj
182
183 end
184
185
186 return TimeValue

File lua\openrtm\version.lua

Full coverage

Generated by lcovtools in 17.5 seconds.