Coverage Report

Overview

Source coverage:85%
Total line count:21735
Total valid lines:11835
Total visited lines:10135

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

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

1 ---------------------------------
2 --! @file OpenHRPExecutionContext.lua
3 --! @brief トリガ駆動実行コンテキスト定義
4 ---------------------------------
5
6
7 --[[
8 Copyright (c) 2017 Nobuhiko Miyamoto
9 ]]
10
11 local OpenHRPExecutionContext= {}
12 --_G["openrtm.OpenHRPExecutionContext"] = OpenHRPExecutionContext
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 DEFAULT_PERIOD = 0.000001
24
25
26 -- トリガ駆動実行コンテキスト初期化
27 -- @return OpenHRPExecutionContext
28 OpenHRPExecutionContext.new = function()
29     local obj = {}
30     setmetatable(obj, {__index=ExecutionContextBase.new("exttrig_sync_ec")})
31     local Manager = require "openrtm.Manager"
32     obj._ReturnCode_t = Manager:instance():getORB().types:lookup("::RTC::ReturnCode_t").labelvalue
33     obj._ExecutionKind = Manager:instance():getORB().types:lookup("::RTC::ExecutionKind").labelvalue
34     obj._rtcout = Manager:instance():getLogbuf("rtobject.exttrig_sync_ec")
35     obj._rtcout:RTC_TRACE("OpenHRPExecutionContext.__init__()")
36
37     obj._svr = Manager:instance():getORB():newservant(obj, nil, "IDL:openrtm.aist.go.jp/OpenRTM/ExtTrigExecutionContextService:1.0")
38     local ref = RTCUtil.getReference(Manager:instance():getORB(), obj._svr, "IDL:openrtm.aist.go.jp/OpenRTM/ExtTrigExecutionContextService:1.0")
39
40     obj:setObjRef(ref)
41     obj:setKind(obj._ExecutionKind.PERIODIC)
42     obj:setRate(1.0 / DEFAULT_PERIOD)
43
44     obj._count  = 0
45
46     -- RTC処理実行関数
47     function obj:tick()
48         self._rtcout:RTC_TRACE("tick()")
49         if not self:isRunning() then
50             return
51         end
52         self:invokeWorkerPreDo()
53         local t0_ = os.clock()
54         self:invokeWorkerDo()
55         local t1_ = os.clock()
56         self:invokeWorkerPostDo()
57         local t2_ = os.clock()
58
59         local period_ = self:getPeriod()
60
61
62         if self._count > 1000 then
63             
64             local excdotm = t1_ - t0_
65             local excpdotm = t2_ - t1_
66             local slptm_ = period_:toDouble() - (t2_ - t0_)
67             self._rtcout:RTC_PARANOID("Period: "..period_:toDouble().." [s]")
68             self._rtcout:RTC_PARANOID("Exec-Do: "..excdotm.." [s]")
69             self._rtcout:RTC_PARANOID("Exec-PostDo: "..excpdotm.." [s]")
70             self._rtcout:RTC_PARANOID("Sleep: "..slptm_.." [s]")
71         end
72         local t3_ = os.clock()
73         if period_:toDouble() > (t2_ - t0_) then
74             if self._count > 1000 then
75                 self._rtcout:RTC_PARANOID("sleeping...")
76                 local slptm_ = period_:toDouble() - (t2_ - t0_)
77                 oil.tasks:suspend(slptm_)
78             end
79         end
80
81         if self._count > 1000 then
82             local t4_ = os.clock()
83             self._rtcout:RTC_PARANOID("Slept: "..(t4_ - t3_).." [s]")
84             self._count = 0
85         end
86         self._count = self._count + 1
87     end
88
89     return obj
90 end
91
92 -- OpenHRPExecutionContext生成ファクトリ登録関数
93 OpenHRPExecutionContext.Init = function(manager)
94     ExecutionContextFactory:instance():addFactory("OpenHRPExecutionContext",
95         OpenHRPExecutionContext.new,
96         ECFactory.ECDelete)
97     ExecutionContextFactory:instance():addFactory("SynchExtTriggerEC",
98         OpenHRPExecutionContext.new,
99         ECFactory.ECDelete)
100 end
101
102
103 return OpenHRPExecutionContext

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
14 local CORBA_SeqUtil = require "openrtm.CORBA_SeqUtil"
15 local Properties = require "openrtm.Properties"
16 local ConnectorListener = require "openrtm.ConnectorListener"
17 local ConnectorListeners = ConnectorListener.ConnectorListeners
18 local PublisherBase = require "openrtm.PublisherBase"
19 local PublisherFactory = PublisherBase.PublisherFactory
20 local PortBase = require "openrtm.PortBase"
21 local StringUtil = require "openrtm.StringUtil"
22
23
24 local ConnectorDataListenerType = ConnectorListener.ConnectorDataListenerType
25 local ConnectorListenerType = ConnectorListener.ConnectorListenerType
26 local ConnectorDataListener = ConnectorListener.ConnectorDataListener
27 local ConnectorListener = ConnectorListener.ConnectorListener
28
29
30 local InPortConsumer = require "openrtm.InPortConsumer"
31 local InPortConsumerFactory = InPortConsumer.InPortConsumerFactory
32 local OutPortProvider = require "openrtm.OutPortProvider"
33 local OutPortProviderFactory = OutPortProvider.OutPortProviderFactory
34
35 local NVUtil = require "openrtm.NVUtil"
36
37 local ConnectorBase = require "openrtm.ConnectorBase"
38 local ConnectorInfo = ConnectorBase.ConnectorInfo
39
40 local OutPortPushConnector = require "openrtm.OutPortPushConnector"
41 local OutPortPullConnector = require "openrtm.OutPortPullConnector"
42
43 -- アウトポート基底オブジェクト初期化
44 -- @param name ポート名
45 -- @param data_type データ型
46 -- @return アウトポート
47 OutPortBase.new = function(name, data_type)
48  local obj = {}
49  setmetatable(obj, {__index=PortBase.new(name)})
50  local Manager = require "openrtm.Manager"
51  obj._ReturnCode_t = Manager:instance():getORB().types:lookup("::RTC::ReturnCode_t").labelvalue
52
53  obj._rtcout = Manager:instance():getLogbuf(name)
54  obj._rtcout:RTC_DEBUG("Port name: "..name)
55
56  --local svr = Manager:instance():getORB():newservant(obj, nil, "IDL:omg.org/RTC/PortService:1.0")
57  --local str = Manager:instance():getORB():tostring(svr)
58  --obj._objref = Manager:instance():getORB():newproxy(str,"IDL:omg.org/RTC/PortService:1.0")
59  --obj._profile.port_ref = obj._objref
60
61
62
63     obj._rtcout:RTC_DEBUG("setting port.port_type: DataOutPort")
64     obj:addProperty("port.port_type", "DataOutPort")
65
66  local _data_type = string.sub(data_type, 3)
67  _data_type = string.gsub(_data_type, "::", "/")
68  _data_type = "IDL:".._data_type..":1.0"
69     obj._rtcout:RTC_DEBUG("setting dataport.data_type: "..tostring(data_type))
70     obj:addProperty("dataport.data_type", _data_type)
71
72
73     local factory = PublisherFactory:instance()
74     local pubs = StringUtil.flatten(factory:getIdentifiers())
75  pubs = StringUtil.eraseHeadBlank(pubs)
76
77
78
79     obj._rtcout:RTC_DEBUG("available subscription_type: "..pubs)
80     obj:addProperty("dataport.subscription_type", pubs)
81     obj:addProperty("dataport.io_mode", pubs)
82
83     obj._properties    = Properties.new()
84     obj._name          = name
85     obj._connectors    = {}
86     obj._consumers     = {}
87     obj._providerTypes = ""
88     obj._consumerTypes = ""
89  obj._data_type = data_type
90
91
92     obj._listeners = ConnectorListeners.new()
93
94  -- 初期化時にプロパティを設定する
95  -- @param prop プロパティ
96  function obj:init(prop)
97   self._rtcout:RTC_TRACE("init()")
98   self:createRef()
99
100   self._properties:mergeProperties(prop)
101
102
103   self:configure()
104
105
106   self:initConsumers()
107   self:initProviders()
108
109
110   local num = tonumber(self._properties:getProperty("connection_limit","-1"))
111   if num == nil then
112    self._rtcout:RTC_ERROR("invalid connection_limit value: "..self._properties:getProperty("connection_limit"))
113   end
114   self:setConnectionLimit(num)
115
116     end
117     -- 未実装
118  function obj:configure()
119  end
120     -- 利用可能なサービスコンシューマ一覧初期化
121     -- InPortConsumerFactoryからサービスコンシューマ一覧を取得する
122     -- 「consumer_types」のプロパティが「all」の場合は、
123     -- 利用可能なサービスコンシューマを全て利用可能にする
124  function obj:initConsumers()
125   self._rtcout:RTC_TRACE("initConsumers()")
126
127
128   local factory = InPortConsumerFactory:instance()
129   local consumer_types = factory:getIdentifiers()
130   --print(StringUtil.flatten(consumer_types))
131   self._rtcout:RTC_PARANOID("available InPortConsumer: "..StringUtil.flatten(consumer_types))
132   local tmp_str = StringUtil.normalize(self._properties:getProperty("consumer_types"))
133   --print(self._properties:getProperty("consumer_types"))
134
135   if self._properties:hasKey("consumer_types") and tmp_str  ~= "all" then
136    self._rtcout:RTC_DEBUG("allowed consumers: "..self._properties:getProperty("consumer_types"))
137
138    local temp_types = consumer_types
139    consumer_types = {}
140    local active_types = StringUtil.split(self._properties:getProperty("consumer_types"), ",")
141
142    table.sort(temp_types)
143    table.sort(active_types)
144
145    consumer_types = temp_types
146
147    for i, v in ipairs(active_types) do
148     consumer_types[#consumer_types+1] = v
149    end
150
151   end
152
153
154
155
156   if #consumer_types > 0 then
157    self._rtcout:RTC_PARANOID("dataflow_type push is supported")
158    self:appendProperty("dataport.dataflow_type", "push")
159    for i, consumer_type in ipairs(consumer_types) do
160     self:appendProperty("dataport.interface_type",consumer_type)
161    end
162   end
163
164
165
166   self._consumerTypes = consumer_types
167  end
168  -- 利用可能なサービスプロバイダ一覧初期化
169  -- OutPortProviderFactoryからサービスプロバイダ一覧を取得する
170     -- 「provider_types」のプロパティが「all」の場合は、
171     -- 利用可能なサービスプロバイダを全て利用可能にする
172  function obj:initProviders()
173   self._rtcout:RTC_TRACE("initProviders()")
174
175
176   local factory = OutPortProviderFactory:instance()
177   local provider_types  = factory:getIdentifiers()
178   self._rtcout:RTC_PARANOID("available OutPortProviders: "..StringUtil.flatten(provider_types))
179   local tmp_str = StringUtil.normalize(self._properties:getProperty("provider_types"))
180   if self._properties:hasKey("provider_types") and tmp_str  ~= "all" then
181    self._rtcout:RTC_DEBUG("allowed providers: "..self._properties:getProperty("allowed"))
182
183    local temp_types = provider_types
184    provider_types = {}
185    local active_types = StringUtil.split(self._properties:getProperty("provider_types"), ",")
186
187    table.sort(temp_types)
188    table.sort(active_types)
189
190    provider_types = temp_types
191
192    for i, v in ipairs(active_types) do
193     provider_types[#provider_types+1] = v
194    end
195   end
196
197
198
199   if #provider_types > 0 then
200    self._rtcout:RTC_PARANOID("dataflow_type pull is supported")
201    self:appendProperty("dataport.dataflow_type", "pull")
202    for i, provider_type in ipairs(provider_types) do
203     self:appendProperty("dataport.interface_type",provider_type)
204    end
205   end
206
207   self._providerTypes = provider_types
208  end
209
210  -- コネクタプロファイルからインターフェース取得
211  -- push型の場合はコンシューマ生成して、コネクタを生成する
212  -- @param cprof コネクタプロファイル
213  -- コネクタプロファイルの以下のノードからプロパティを取得
214  -- dataport
215  -- dataport.outport
216  -- @return リターンコード
217  -- RTC_OK:正常終了
218  -- BAD_PARAMETER:コンシューマ生成失敗、不正なデータフロー型
219  -- RTC_ERROR:コネクタ生成失敗
220  function obj:subscribeInterfaces(cprof)
221   self._rtcout:RTC_TRACE("subscribeInterfaces()")
222
223
224
225   --print(self._properties)
226
227   local prop = Properties.new(self._properties)
228
229
230   local conn_prop = Properties.new()
231
232   NVUtil.copyToProperties(conn_prop, cprof.properties)
233   --print(cprof.properties[1].value)
234
235
236   prop:mergeProperties(conn_prop:getNode("dataport"))
237
238
239   prop:mergeProperties(conn_prop:getNode("dataport.outport"))
240
241
242   local dflow_type = StringUtil.normalize(prop:getProperty("dataflow_type"))
243   local profile = ConnectorInfo.new(cprof.name,
244           cprof.connector_id,
245           CORBA_SeqUtil.refToVstring(cprof.ports),
246           prop)
247
248   --[[local success, exception = oil.pcall(
249    function()
250     print(prop)
251    end)
252   print(exception)]]
253         --print(dflow_type)
254         --print(prop)
255         --print(dflow_type)
256         --print(prop)
257         if dflow_type == "push" then
258             self._rtcout:RTC_PARANOID("dataflow_type = push .... create PushConnector")
259
260             consumer = self:createConsumer(cprof, prop)
261
262             --print(consumer)
263             if consumer == nil then
264                 return self._ReturnCode_t.BAD_PARAMETER
265             end
266
267
268             local connector = self:createConnector(cprof, prop, {consumer_ = consumer})
269             --print(connector)
270
271
272
273             if connector == nil then
274                 return self._ReturnCode_t.RTC_ERROR
275             end
276
277             local ret = connector:setConnectorInfo(profile)
278             if ret == self._ReturnCode_t.RTC_OK then
279                 self._rtcout:RTC_DEBUG("subscribeInterfaces() successfully finished.")
280             end
281
282
283             return self._ReturnCode_t.RTC_OK
284         elseif dflow_type == "pull" then
285             local conn = self:getConnectorById(cprof.connector_id)
286             if conn == nil then
287                 self._rtcout:RTC_ERROR("specified connector not found: "..cprof.connector_id)
288                 return self._ReturnCode_t.RTC_ERROR
289             end
290
291             local ret = conn:setConnectorInfo(profile)
292
293             if ret == self._ReturnCode_t.RTC_OK then
294                 self._rtcout:RTC_DEBUG("subscribeInterfaces() successfully finished.")
295             end
296
297             return ret
298         end
299
300         self._rtcout:RTC_ERROR("unsupported dataflow_type")
301
302         return self._ReturnCode_t.BAD_PARAMETER
303     end
304
305     -- プロバイダの初期化してインターフェースをコネクタプロファイルに登録
306     -- pull型の場合はプロバイダを生成して、コネクタを生成する
307     -- @param cprof コネクタプロファイル
308     -- コネクタプロファイルの以下のノードからプロパティを取得
309     -- dataport
310     -- dataport.outport
311     -- @return リターンコード
312     -- RTC_OK:正常終了
313     -- BAD_PARAMETER:プロバイダの初期化失敗、不正なデータフロー型
314     -- RTC_ERROR:コネクタ生成失敗
315     function obj:publishInterfaces(cprof)
316         self._rtcout:RTC_TRACE("publishInterfaces()")
317
318
319         local retval = self:_publishInterfaces()
320         if retval ~= self._ReturnCode_t.RTC_OK then
321             return retval
322         end
323
324
325         local prop = Properties.new(self._properties)
326
327         local conn_prop = Properties.new()
328
329         NVUtil.copyToProperties(conn_prop, cprof.properties)
330         prop:mergeProperties(conn_prop:getNode("dataport"))
331
332         prop:mergeProperties(conn_prop:getNode("dataport.outport"))
333
334
335
336         local dflow_type = StringUtil.normalize(prop:getProperty("dataflow_type"))
337
338         if dflow_type == "push" then
339             self._rtcout:RTC_PARANOID("dataflow_type = push .... do nothing")
340             return self._ReturnCode_t.RTC_OK
341
342         elseif dflow_type == "pull" then
343             self._rtcout:RTC_PARANOID("dataflow_type = pull .... create PullConnector")
344
345             provider = self:createProvider(cprof, prop)
346             if provider == nil then
347                 return self._ReturnCode_t.BAD_PARAMETER
348             end
349
350
351             local connector = self:createConnector(cprof, prop, {provider_ = provider})
352             if connector == nil then
353                 return self._ReturnCode_t.RTC_ERROR
354             end
355
356
357             provider:setConnector(connector)
358
359             self._rtcout:RTC_DEBUG("publishInterface() successfully finished.")
360             return self._ReturnCode_t.RTC_OK
361         end
362
363         self._rtcout:RTC_ERROR("unsupported dataflow_type")
364
365         return self._ReturnCode_t.BAD_PARAMETER
366     end
367
368     -- コネクタ生成
369     -- @param cprof コネクタプロファイル
370     -- @param prop プロパティ
371     -- @param args args.provider_:プロバイダ、args.consumer_:コンシューマ
372     -- @return コネクタオブジェクト
373     function obj:createConnector(cprof, prop, args)
374         local provider_ = args.provider_
375         local consumer_ = args.consumer_
376         local profile = ConnectorInfo.new(cprof.name,
377                                     cprof.connector_id,
378                                     CORBA_SeqUtil.refToVstring(cprof.ports),
379                                     prop)
380         local connector = nil
381
382         local ret = nil
383         local success, exception = oil.pcall(
384             function()
385                 if consumer_ ~= nil then
386                     connector = OutPortPushConnector.new(profile, consumer_,
387                                                         self._listeners)
388
389                 elseif provider_  ~= nil then
390                     connector = OutPortPullConnector.new(profile, provider_,
391                                                         self._listeners)
392
393                 else
394                     self._rtcout:RTC_ERROR("provider or consumer is not passed. returned 0;")
395                     ret = nil
396                     return
397                 end
398
399
400
401
402                 if consumer_ ~= nil then
403                     self._rtcout:RTC_TRACE("OutPortPushConnector created")
404                 elseif provider_ ~= nil then
405                     self._rtcout:RTC_TRACE("OutPortPullConnector created")
406                 end
407
408
409                 table.insert(self._connectors, connector)
410                 self._rtcout:RTC_PARANOID("connector push backed: "..#self._connectors)
411                 ret = connector
412                 return
413             end)
414         if not success then
415             --print(exception)
416             self._rtcout:RTC_ERROR("OutPortPushConnector creation failed")
417             self._rtcout:RTC_ERROR(exception)
418             return nil
419         end
420         return ret
421     end
422
423     -- サービスプロバイダ作成
424     -- 「interface_type」の要素にインターフェース型を指定
425     -- 「provider」のノードにプロバイダのプロパティを指定
426     -- @param cprof コネクタプロファイル
427     -- @param prop プロパティ
428     -- @return プロバイダ
429     function obj:createProvider(cprof, prop)
430
431         if prop:getProperty("interface_type") == "" or
432               not StringUtil.includes(self._providerTypes, prop:getProperty("interface_type")) then
433             self._rtcout:RTC_ERROR("no provider found")
434             self._rtcout:RTC_DEBUG("interface_type: "..prop:getProperty("interface_type"))
435             self._rtcout:RTC_DEBUG("interface_types: "..
436                                  StringUtil.flatten(self._providerTypes))
437             return nil
438         end
439
440         self._rtcout:RTC_DEBUG("interface_type: "..prop:getProperty("interface_type"))
441         local provider = OutPortProviderFactory:instance():createObject(prop:getProperty("interface_type"))
442
443         if provider ~= nil then
444             self._rtcout:RTC_DEBUG("provider created")
445             provider:init(prop:getNode("provider"))
446
447             if not provider:publishInterface(cprof.properties) then
448                 self._rtcout:RTC_ERROR("publishing interface information error")
449                 OutPortProviderFactory:instance():deleteObject(provider)
450                 return nil
451             end
452
453             return provider
454         end
455
456         self._rtcout:RTC_ERROR("provider creation failed")
457         return nil
458     end
459     
460     -- サービスコンシューマ作成
461     -- 「interface_type」の要素にインターフェース型を指定
462     -- 「consumer」のノードにコンシューマのプロパティを指定
463     -- @param cprof コネクタプロファイル
464     -- @param prop プロパティ
465     -- @return コンシューマ
466     function obj:createConsumer(cprof, prop)
467         --print(prop:getProperty("interface_type"))
468         --print(StringUtil.includes(self._consumerTypes, prop:getProperty("interface_type")))
469         if prop:getProperty("interface_type") == "" or
470             not StringUtil.includes(self._consumerTypes, prop:getProperty("interface_type")) then
471             self._rtcout:RTC_ERROR("no consumer found")
472             self._rtcout:RTC_DEBUG("interface_type: "..prop:getProperty("interface_type"))
473             self._rtcout:RTC_DEBUG("interface_types: "..StringUtil.flatten(self._consumerTypes))
474             return nil
475         end
476
477
478         self._rtcout:RTC_DEBUG("interface_type: "..prop:getProperty("interface_type"))
479         local consumer = InPortConsumerFactory:instance():createObject(prop:getProperty("interface_type"))
480
481
482         if consumer ~= nil then
483             self._rtcout:RTC_DEBUG("consumer created")
484             consumer:init(prop:getNode("consumer"))
485
486             if not consumer:subscribeInterface(cprof.properties) then
487                 self._rtcout:RTC_ERROR("interface subscription failed.")
488                 InPortConsumerFactory:instance():deleteObject(provider)
489                 return nil
490             end
491             return consumer
492         end
493
494         self._rtcout:RTC_ERROR("provider creation failed")
495         return nil
496     end
497
498     -- IDからコネクタを取得
499     -- @param id 識別子
500     -- @return コネクタ
501     function obj:getConnectorById(id)
502         self._rtcout:RTC_TRACE("getConnectorById(id = "..id..")")
503
504         for i, con in pairs(self._connectors) do
505             if id == con:id() then
506                 return con
507             end
508         end
509
510         self._rtcout:RTC_WARN("ConnectorProfile with the id("..id..") not found.")
511         return nil
512     end
513
514     -- 指定コネクタプロファイルのコネクタを削除
515     -- @param connector_profile コネクタプロファイル
516     function obj:unsubscribeInterfaces(connector_profile)
517         self._rtcout:RTC_TRACE("unsubscribeInterfaces()")
518
519         local id = connector_profile.connector_id
520         self._rtcout:RTC_PARANOID("connector_id: "..id)
521
522         for i, con in pairs(self._connectors) do
523             if id == con:id() then
524                 con:deactivate()
525                 con:disconnect()
526                 self._connectors[i] = nil
527                 self._rtcout:RTC_TRACE("delete connector: "..id)
528                 return
529             end
530         end
531
532
533         self._rtcout:RTC_ERROR("specified connector not found: "..id)
534     end
535
536     -- インターフェースのアクティブ化
537     function obj:activateInterfaces()
538         self._rtcout:RTC_TRACE("activateInterfaces()")
539         for i, con in pairs(self._connectors) do
540             con:activate()
541             self._rtcout:RTC_DEBUG("activate connector: "..
542                                 con:name().." "..con:id())
543         end
544     end
545
546     -- インターフェースの非アクティブ化
547     function obj:deactivateInterfaces()
548         self._rtcout:RTC_TRACE("deactivateInterfaces()")
549         for i, con in pairs(self._connectors) do
550             con:deactivate()
551             self._rtcout:RTC_DEBUG("deactivate connector: "..
552                                 con:name().." "..con:id())
553         end
554     end
555
556
557     function obj:addConnectorDataListener(listener_type, listener, autoclean)
558         if autoclean == nil then
559             autoclean = true
560         end
561         self._rtcout:RTC_TRACE("addConnectorDataListener()")
562
563            if listener_type < ConnectorDataListenerType.CONNECTOR_DATA_LISTENER_NUM then
564             self._rtcout:RTC_TRACE("addConnectorDataListener(%s)", ConnectorDataListener.toString(listener_type))
565               self._listeners.connectorData_[listener_type]:addListener(listener, autoclean)
566             return
567         end
568
569         self._rtcout:RTC_ERROR("addConnectorDataListener(): Unknown Listener Type")
570
571     end
572
573     function obj:removeConnectorDataListener(listener_type, listener)
574         self._rtcout:RTC_TRACE("removeConnectorDataListener()")
575
576         if listener_type < ConnectorDataListenerType.CONNECTOR_DATA_LISTENER_NUM then
577             self._rtcout:RTC_TRACE("removeConnectorDataListener(%s)", ConnectorDataListener.toString(listener_type))
578             self._listeners.connectorData_[listener_type]:removeListener(listener)
579             return
580         end
581
582         self._rtcout:RTC_ERROR("removeConnectorDataListener(): Unknown Listener Type")
583     end
584     
585
586     function obj:addConnectorListener(listener_type, listener, autoclean)
587         if autoclean == nil then
588             autoclean = true
589         end
590         self._rtcout:RTC_TRACE("addConnectorListener()")
591
592            if listener_type < ConnectorListenerType.CONNECTOR_LISTENER_NUM then
593             self._rtcout:RTC_TRACE("addConnectorListener(%s)", ConnectorListener.toString(listener_type))
594               self._listeners.connector_[listener_type]:addListener(listener, autoclean)
595             return
596         end
597
598         self._rtcout:RTC_ERROR("addConnectorListener(): Unknown 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._rtcout:RTC_TRACE("removeConnectorListener(%s)", ConnectorListener.toString(listener_type))
607             self._listeners.connector_[listener_type]:removeListener(listener)
608             return
609         end
610
611         self._rtcout:RTC_ERROR("removeConnectorListener(): Unknown Listener Type")
612     end
613     
614
615     return obj
616 end
617
618
619 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
26
27
28
29 -- 周期実行コンテキスト初期化
30 -- @return 周期実行コンテキスト
31 PeriodicExecutionContext.new = function()
32     local obj = {}
33     setmetatable(obj, {__index=ExecutionContextBase.new("periodic_ec")})
34     local Manager = require "openrtm.Manager"
35     obj._ReturnCode_t = Manager:instance():getORB().types:lookup("::RTC::ReturnCode_t").labelvalue
36     obj._ExecutionKind = Manager:instance():getORB().types:lookup("::RTC::ExecutionKind").labelvalue
37     obj._rtcout = Manager:instance():getLogbuf("rtobject.periodic_ec")
38     obj._rtcout:RTC_TRACE("PeriodicExecutionContext.__init__()")
39     obj._svc = false
40     obj._nowait = false
41
42     --ref = Manager:instance():getORB():tostring(obj)
43     obj._svr = Manager:instance():getORB():newservant(obj, nil, "IDL:omg.org/RTC/ExecutionContextService:1.0")
44     local ref = RTCUtil.getReference(Manager:instance():getORB(), obj._svr, "IDL:omg.org/RTC/ExecutionContextService:1.0")
45     --print(ref:_non_existent())
46     --print(ref:start())
47     --print(svr)
48     obj:setObjRef(ref)
49     obj:setKind(obj._ExecutionKind.PERIODIC)
50     obj:setRate(1.0 / DEFAULT_PERIOD)
51     obj._rtcout:RTC_DEBUG("Actual rate: "..obj._profile:getPeriod():sec().." [sec], "..obj._profile:getPeriod():usec().." [usec]")
52
53     obj._cpu = {}
54
55     -- コルーチンで周期実行処理
56     -- @return 0:正常
57     function obj:svc()
58         self._rtcout:RTC_TRACE("svc()")
59         local count_ = 0
60
61
62
63         while(self:threadRunning()) do
64             self:invokeWorkerPreDo()
65             local t0_ = os.clock()
66             self:invokeWorkerDo()
67             self:invokeWorkerPostDo()
68             local t1_ = os.clock()
69             local period_ = self:getPeriod()
70             if count_ > 1000 then
71                 local exctm_ = t1_ - t0_
72                 local slptm_ = period_:toDouble() - exctm_
73                 self._rtcout:RTC_PARANOID("Period: "..period_:toDouble().." [s]")
74                 self._rtcout:RTC_PARANOID("Execution: "..exctm_.." [s]")
75                 self._rtcout:RTC_PARANOID("Sleep: "..slptm_.." [s]")
76             end
77
78
79             local t2_ = os.clock()
80
81             if not self._nowait and period_:toDouble() > (t1_ - t0_) then
82                 if count_ > 1000 then
83                     self._rtcout:RTC_PARANOID("sleeping...")
84                 end
85                 --print(period_:toDouble())
86                 local slptm_ = period_:toDouble() - (t1_ - t0_)
87                 --print(slptm_)
88                 oil.tasks:suspend(slptm_)
89             else
90                 coroutine.yield(1)
91             end
92
93             --oil.tasks:suspend(1)
94
95
96             if count_ > 1000 then
97                 local t3_ = os.clock()
98                 self._rtcout:RTC_PARANOID("Slept: "..(t3_ - t2_).." [s]")
99                 count_ = 0
100             end
101             count_ = count_ + 1
102
103         end
104
105         self._rtcout:RTC_DEBUG("Thread terminated.")
106         return 0
107     end
108
109     -- コルーチンの処理開始
110     -- @return 0:正常
111     function obj:open()
112         self._rtcout:RTC_TRACE("open()")
113         Task.start(self)
114         return 0
115     end
116     -- 開始時実行関数
117     -- @return リターンコード
118     function obj:onStarted()
119         if not self._svc then
120             self._svc = true
121             self:open()
122         end
123         return self._ReturnCode_t.RTC_OK
124     end
125     -- 終了時実行関数
126     -- @return リターンコード
127     function obj:onStopped()
128         if self._svc then
129             self._svc = false
130             --self:wait(0)
131         end
132         return self._ReturnCode_t.RTC_OK
133     end
134     -- コルーチンが動作しているかの確認
135     -- @return true:動作中、false:停止済み
136     function obj:threadRunning()
137         return self._svc
138     end
139     return obj
140 end
141
142 -- 周期実行コンテキスト生成ファクトリ登録
143 PeriodicExecutionContext.Init = function(manager)
144     ExecutionContextFactory:instance():addFactory("PeriodicExecutionContext",
145         PeriodicExecutionContext.new,
146         ECFactory.ECDelete)
147 end
148
149 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     if retval ~= self._ReturnCode_t.RTC_OK then
229      self._rtcout:RTC_ERROR("Connection failed. cleanup.")
230      self:disconnect(connector_profile.connector_id)
231     end
232    end)
233   if not success then
234    --print(exception)
235    self._rtcout:RTC_ERROR(exception)
236    return self._ReturnCode_t.BAD_PARAMETER, connector_profile
237   end
238   --print(retval)
239   --local conn_prof = {name="",
240   --     connector_id="",
241   --     ports={},
242   --     properties={}}
243   return retval, connector_profile
244  end
245
246  -- コネクタ切断
247  -- @param connector_id コネクタID
248  -- @return リターンコード
249  function obj:disconnect(connector_id)
250   self._rtcout:RTC_TRACE("disconnect("..connector_id..")")
251
252   local index = self:findConnProfileIndex(connector_id)
253
254   if index < 0 then
255    self._rtcout:RTC_ERROR("Invalid connector id: "..connector_id)
256    return self._ReturnCode_t.BAD_PARAMETER
257   end
258
259   local prof = self._profile.connector_profiles[index]
260
261
262
263   if #prof.ports < 1 then
264    self._rtcout:RTC_FATAL("ConnectorProfile has empty port list.")
265    return self._ReturnCode_t.PRECONDITION_NOT_MET
266   end
267   local ret = self._ReturnCode_t.RTC_ERROR
268   local success, exception = oil.pcall(
269    function()
270     ret = prof.ports[1]:notify_disconnect(connector_id)
271    end)
272   if not success then
273    self._rtcout:RTC_WARN(exception)
274   end
275
276
277   if ret ~= self._ReturnCode_t.RTC_OK then
278    self._rtcout:RTC_ERROR("notify_disconnect() for all ports failed.")
279    return self._ReturnCode_t.RTC_ERROR
280   else
281    return ret
282   end
283  end
284
285  -- コネクタ切断実行関数
286  -- @param connector_id コネクタID
287  -- @return リターンコード
288  function obj:notify_disconnect(connector_id)
289   self._rtcout:RTC_TRACE("notify_disconnect("..connector_id..")")
290
291   local index = self:findConnProfileIndex(connector_id)
292
293   if index < 0 then
294    self._rtcout:RTC_ERROR("Invalid connector id: "..connector_id)
295    return self._rtcout.BAD_PARAMETER
296   end
297
298   local prof = {name = self._profile.connector_profiles[index].name,
299     connector_id = self._profile.connector_profiles[index].connector_id,
300     ports = self._profile.connector_profiles[index].ports,
301     properties = self._profile.connector_profiles[index].properties}
302
303   self:onNotifyDisconnect(self:getName(), prof)
304
305   local retval = self:disconnectNext(prof)
306   self:onDisconnectNextport(self:getName(), prof, retval)
307
308   if self._onUnsubscribeInterfaces ~= nil then
309    self._onUnsubscribeInterfaces(prof)
310   end
311   self:onUnsubscribeInterfaces(self:getName(), prof)
312   self:unsubscribeInterfaces(prof)
313
314   if self._onDisconnected ~= nil then
315    self._onDisconnected(prof)
316   end
317
318   table.remove(self._profile.connector_profiles, index)
319
320   self:onDisconnected(self:getName(), prof, retval)
321   return retval
322  end
323
324  -- コネクタ接続実行関数
325  -- @param connector_profile コネクタプロファイル
326  -- @return リターンコード、コネクタプロファイル
327  function obj:notify_connect(connector_profile)
328
329   self._rtcout:RTC_TRACE("notify_connect()")
330
331
332
333   local prop = Properties.new()
334   NVUtil.copyToProperties(prop, connector_profile.properties)
335
336
337   local default_value = StringUtil.toBool(self._properties:getProperty("allow_dup_connection"), "YES","NO",false)
338
339   if not StringUtil.toBool(prop:getProperty("dataport.allow_dup_connection"), "YES","NO",default_value) then
340   end
341
342
343   local retval = {}
344
345   self:onNotifyConnect(self:getName(),connector_profile)
346
347
348   retval[1] = self:publishInterfaces(connector_profile)
349   --for i, v in ipairs(connector_profile.properties) do
350   -- print(v.name, v.value)
351   --end
352
353   if retval[1] ~= self._ReturnCode_t.RTC_OK then
354    self._rtcout:RTC_ERROR("publishInterfaces() in notify_connect() failed.")
355   end
356
357   self:onPublishInterfaces(self:getName(), connector_profile, retval[1])
358   if self._onPublishInterfaces ~= nil then
359    self._onPublishInterfaces(connector_profile)
360   end
361
362
363   retval[2], connector_profile = self:connectNext(connector_profile)
364   retval[2] = NVUtil.getReturnCode(retval[2])
365   --print("test2", retval[2])
366   if retval[2] ~= self._ReturnCode_t.RTC_OK then
367    self._rtcout:RTC_ERROR("connectNext() in notify_connect() failed.")
368   end
369
370
371   self:onConnectNextport(self:getName(), connector_profile, retval[2])
372
373   if self._onSubscribeInterfaces ~= nil then
374    self._onSubscribeInterfaces(connector_profile)
375   end
376
377   retval[3] = self:subscribeInterfaces(connector_profile)
378   if retval[3] ~= self._ReturnCode_t.RTC_OK then
379    self._rtcout:RTC_ERROR("subscribeInterfaces() in notify_connect() failed.")
380   end
381
382
383   self:onSubscribeInterfaces(self:getName(), connector_profile, retval[3])
384
385   self._rtcout:RTC_PARANOID(#self._profile.connector_profiles.." connectors are existing")
386
387
388   local index = self:findConnProfileIndex(connector_profile.connector_id)
389
390   --print(index)
391   if index < 0 then
392    table.insert(self._profile.connector_profiles, connector_profile)
393    --print(#self._profile.connector_profiles)
394    self._rtcout:RTC_PARANOID("New connector_id. Push backed.")
395
396   else
397    self._profile.connector_profiles[index] = connector_profile
398    self._rtcout:RTC_PARANOID("Existing connector_id. Updated.")
399   end
400
401
402
403   for i, ret in ipairs(retval) do
404    --print(i,ret)
405    if ret ~= self._ReturnCode_t.RTC_OK then
406     self:onConnected(self:getName(), connector_profile, ret)
407     return ret, connector_profile
408    end
409   end
410
411
412
413   if self._onConnected ~= nil then
414    self._onConnected(connector_profile)
415   end
416   self:onConnected(self:getName(), connector_profile, self._ReturnCode_t.RTC_OK)
417
418   local conn_prof = {name=connector_profile.name,
419        connector_id=connector_profile.connector_id,
420        ports=connector_profile.ports,
421        properties={}}
422
423   for i,v in ipairs(connector_profile.properties) do
424    conn_prof.properties[i] = {name=v.name, value=NVUtil.any_from_any(v.value)}
425    --print(v.name, v.value)
426    --print(conn_prof.properties[i].name, conn_prof.properties[i].value)
427   end
428
429
430   return self._ReturnCode_t.RTC_OK, conn_prof
431  end
432
433  -- コネクタ一覧更新
434  function obj:updateConnectors()
435
436   local connector_ids = {}
437   local clist = self._profile.connector_profiles
438
439   for i, cprof in ipairs(clist) do
440    if not self:checkPorts(cprof.ports) then
441     table.insert(connector_ids, cprof.connector_id)
442     self._rtcout:RTC_WARN("Dead connection: "..cprof.connector_id)
443    end
444   end
445
446   for i, cid in ipairs(connector_ids) do
447    self:disconnect(cid)
448   end
449
450     end
451
452  -- コネクタ一覧取得
453  -- @return コネクタ一覧
454  function obj:connectors()
455   self._rtcout:RTC_TRACE("connectors(): size = "..#self._connectors)
456   return self._connectors
457  end
458
459  -- ポートが生存しているかを確認
460  -- @param ports ポート
461  -- @return true:生存、false:消滅済み
462   function obj:checkPorts(ports)
463   local ret = true
464   for i, port in ipairs(ports) do
465    --print(NVUtil._non_existent(port))
466    if NVUtil._non_existent(port) then
467     self._rtcout:RTC_WARN("Dead Port reference detected.")
468     ret = false
469    end
470   end
471
472   return ret
473  end
474
475  -- IDが空かを判定
476  -- @param コネクタプロファイル
477  -- @return true:空
478   function obj:isEmptyId(connector_profile)
479   return (connector_profile.connector_id == "")
480  end
481
482  -- コネクタIDがすでに登録済みかを確認
483  -- @param id_ コネクタID
484  -- @return true:登録済み、false:未登録
485   function obj:isExistingConnId(id_)
486   return (CORBA_SeqUtil.find(self._profile.connector_profiles,
487                                            find_conn_id.new(id_)) >= 0)
488  end
489
490  -- コネクタ接続実行時のコールバック実行
491  -- @param portname ポート名
492  -- @param profile ポートプロファイル
493  function obj:onNotifyConnect(portname, profile)
494   if self._portconnListeners ~= nil then
495    local _type = PortConnectListenerType.ON_NOTIFY_CONNECT
496    self._portconnListeners.portconnect_[_type]:notify(portname, profile)
497   end
498     end
499     -- コネクタ切断実行時のコールバック実行
500  -- @param portname ポート名
501  -- @param profile ポートプロファイル
502  function obj:onNotifyDisconnect(portname, profile)
503   if self._portconnListeners ~= nil then
504    local _type = PortConnectListenerType.ON_NOTIFY_DISCONNECT
505    self._portconnListeners.portconnect_[_type]:notify(portname, profile)
506   end
507     end
508     -- インターフェス解放時のコールバック実行
509  -- @param portname ポート名
510  -- @param profile ポートプロファイル
511  function obj:onUnsubscribeInterfaces(portname, profile)
512   if self._portconnListeners ~= nil then
513    local _type = PortConnectListenerType.ON_UNSUBSCRIBE_INTERFACES
514    self._portconnListeners.portconnect_[_type]:notify(portname, profile)
515   end
516     end
517     -- インターフェス登録時のコールバック実行
518  -- @param portname ポート名
519  -- @param profile ポートプロファイル
520  -- @param ret リターンコード
521  function obj:onPublishInterfaces(portname, profile, ret)
522   if self._portconnListeners ~= nil then
523    local _type = PortConnectRetListenerType.ON_PUBLISH_INTERFACES
524    self._portconnListeners.portconnret_[_type]:notify(portname, profile, ret)
525   end
526     end
527     -- 次のポート接続時のコールバック実行
528  -- @param portname ポート名
529  -- @param profile ポートプロファイル
530  -- @param ret リターンコード
531  function obj:onConnectNextport(portname, profile, ret)
532   if self._portconnListeners ~= nil then
533    local _type = PortConnectRetListenerType.ON_CONNECT_NEXTPORT
534    self._portconnListeners.portconnret_[_type]:notify(portname, profile, ret)
535   end
536     end
537     -- インターフェ-ス取得時のコールバック実行
538  -- @param portname ポート名
539  -- @param profile ポートプロファイル
540  -- @param ret リターンコード
541  function obj:onSubscribeInterfaces(portname, profile, ret)
542   if self._portconnListeners ~= nil then
543    local _type = PortConnectRetListenerType.ON_SUBSCRIBE_INTERFACES
544    self._portconnListeners.portconnret_[_type]:notify(portname, profile, ret)
545   end
546     end
547     -- コネクタ接続後のコールバック実行
548  -- @param portname ポート名
549  -- @param profile ポートプロファイル
550  -- @param ret リターンコード
551  function obj:onConnected(portname, profile, ret)
552   if self._portconnListeners ~= nil then
553    local _type = PortConnectRetListenerType.ON_CONNECTED
554    self._portconnListeners.portconnret_[_type]:notify(portname, profile, ret)
555   end
556     end
557     -- 次のポート切断時のコールバック実行
558  -- @param portname ポート名
559  -- @param profile ポートプロファイル
560  -- @param ret リターンコード
561  function obj:onDisconnectNextport(portname, profile, ret)
562   if self._portconnListeners ~= nil then
563    local _type = PortConnectRetListenerType.ON_DISCONNECT_NEXT
564    self._portconnListeners.portconnret_[_type]:notify(portname, profile, ret)
565   end
566     end
567     -- コネクタ接断後のコールバック実行
568  -- @param portname ポート名
569  -- @param profile ポートプロファイル
570  -- @param ret リターンコード
571  function obj:onDisconnected(portname, profile, ret)
572   if self._portconnListeners ~= nil then
573    local _type = PortConnectRetListenerType.ON_DISCONNECTED
574    self._portconnListeners.portconnret_[_type]:notify(portname, profile, ret)
575   end
576     end
577
578  -- ポート名取得
579  -- @return ポート名
580  function obj:getName()
581   self._rtcout:RTC_TRACE("getName() = "..self._profile.name)
582   return self._profile.name
583  end
584
585  -- インターフェースをコネクタプロファイルに登録
586  -- @param connector_profile コネクタプロファイル
587  -- @return リターンコード
588  function obj:publishInterfaces(connector_profile)
589   --print("publishInterfaces")
590   return self._ReturnCode_t.BAD_PARAMETER
591  end
592
593  -- コネクタ接続可能かの判定
594  -- @return リターンコード
595  function obj:_publishInterfaces()
596   if not (self._connectionLimit < 0) then
597    if self._connectionLimit <= #self._profile.connector_profiles then
598     self._rtcout:RTC_PARANOID("Connected number has reached the limitation.")
599     self._rtcout:RTC_PARANOID("Can connect the port up to "..self._connectionLimit.." ports.")
600     self._rtcout:RTC_PARANOID(#self._profile.connector_profiles.." connectors are existing")
601     return self._ReturnCode_t.RTC_ERROR
602    end
603   end
604
605   return self._ReturnCode_t.RTC_OK
606  end
607
608  -- 次のポートを接続
609  -- @param connector_profile コネクタプロファイル
610  -- @return リターンコード、コネクタプロファイル
611  function obj:connectNext(connector_profile)
612   --print("test:",self,self._profile.port_ref)
613   --print(connector_profile.ports[1]:get_port_profile().name)
614   local index = CORBA_SeqUtil.find(connector_profile.ports,
615            find_port_ref.new(self._profile.port_ref))
616   --print(index)
617
618
619
620   if index < 0 then
621    return self._ReturnCode_t.BAD_PARAMETER, connector_profile
622   end
623
624   index = index + 1
625   --print(index)
626   local p = connector_profile.ports[index]
627   --print(p)
628   if p ~= nil then
629    --[[for i,v in ipairs(connector_profile.properties) do
630     print(v.name,v.value)
631    end]]
632             local prop = {}
633             for i, v in ipairs(connector_profile.properties) do
634                 prop[i] = {name=v.name, value=NVUtil.any_from_any(v.value)}
635             end
636             connector_profile.properties = prop
637             return p:notify_connect(connector_profile)
638         end
639
640         return self._ReturnCode_t.RTC_OK, connector_profile
641     end
642     -- 次のポートを切断
643     -- @param connector_profile コネクタプロファイル
644     -- @return リターンコード
645     function obj:disconnectNext(connector_profile)
646
647         local index = CORBA_SeqUtil.find(connector_profile.ports,
648                                                 find_port_ref.new(self._profile.port_ref))
649         if index < 0 then
650             return self._ReturnCode_t.BAD_PARAMETER
651         end
652
653         if index == #connector_profile.ports then
654             return self._ReturnCode_t.RTC_OK
655         end
656
657         index = index + 1
658
659
660
661         local p = connector_profile.ports[index]
662         --print(p,index)
663         local ret = self._ReturnCode_t.RTC_ERROR
664         while p ~= nil do
665             local success, exception = oil.pcall(
666                 function()
667                     index = index + 1
668                     ret = p:notify_disconnect(connector_profile.connector_id)
669                 end)
670
671             if not success then
672                 self._rtcout:RTC_WARN(exception)
673             end
674             p = connector_profile.ports[index]
675
676         end
677
678
679         return ret
680     end
681
682     -- IDからコネクタプロファイル取得
683     -- @param id_ コネクタID
684     -- @return 配列の番号
685     function obj:findConnProfileIndex(id_)
686         return CORBA_SeqUtil.find(self._profile.connector_profiles,
687                                            find_conn_id.new(id_))
688     end
689     -- コネクタプロファイルにUUIDを設定
690     -- @param connector_profile コネクタプロファイル
691     function obj:setUUID(connector_profile)
692         connector_profile.connector_id = self:getUUID()
693         --print(connector_profile.connector_id)
694     end
695     -- UUID生成
696     -- @return UUID
697     function obj:getUUID()
698         return uuid()
699     end
700     -- コネクタプロファイルからインターフェース取得
701     -- @param cprof コネクタプロファイル
702     -- @return リターンコード
703     function obj:subscribeInterfaces(connector_profile)
704         return self._ReturnCode_t.BAD_PARAMETER
705     end
706     -- プロファイルの設定
707     -- @param _key キー
708     -- @param _value 値
709     function obj:addProperty(_key, _value)
710         table.insert(self._profile.properties, {name=_key, value=_value})
711     end
712     -- プロファイルの設定追加
713     -- @param _key キー
714     -- @param _value 値
715     function obj:appendProperty(key, value)
716         --print(key, value)
717         NVUtil.appendStringValue(self._profile.properties, key, value)
718         --print(self._profile.properties)
719     end
720     -- コネクタプロファイルのインターフェース設定解除
721     -- @return リターンコード
722     function obj:unsubscribeInterfaces(connector_profile)
723         return self._ReturnCode_t.BAD_PARAMETER
724     end
725     -- コネクタ最大数設定
726     -- @param limit_value コネクタ最大数
727     function obj:setConnectionLimit(limit_value)
728         self._connectionLimit = limit_value
729     end
730
731     -- インターフェース追加
732     -- @param _instance_name インスタンス名
733     -- @param _type_name 型名
734     -- @param pol 方向
735     -- @return true:追加成功、false:追加失敗
736     function obj:appendInterface(_instance_name, _type_name, pol)
737         local index = CORBA_SeqUtil.find(self._profile.interfaces,
738                                     find_interface.new(_instance_name, pol))
739
740         if index >= 0 then
741             return false
742         end
743
744
745         local prof = {instance_name=_instance_name, type_name=_type_name, polarity=pol}
746         table.insert(self._profile.interfaces, prof)
747
748         return true
749     end
750
751     -- オーナーのRTC設定
752     -- @param owner RTC
753     function obj:setOwner(owner)
754         local prof = owner:get_component_profile()
755         self._ownerInstanceName = prof.instance_name
756         self._rtcout:RTC_TRACE("setOwner("..self._ownerInstanceName..")")
757
758
759         local plist = StringUtil.split(self._profile.name, "%.")
760         if self._ownerInstanceName == "" then
761             self._rtcout:RTC_ERROR("Owner is not set.")
762             self._rtcout:RTC_ERROR("addXXXPort() should be called in onInitialize().")
763         end
764         local portname = self._ownerInstanceName.."."..plist[#plist]
765
766         if owner.getObjRef == nil then
767             self._profile.owner = owner
768         else
769             self._profile.owner = owner:getObjRef()
770         end
771         self._profile.name = portname
772     end
773
774     -- ポートコネクタコールバックの設定
775     -- @param portconnListeners ポートコネクタコールバック関数
776     function obj:setPortConnectListenerHolder(portconnListeners)
777         self._portconnListeners = portconnListeners
778     end
779
780     -- オブジェクトリファレンス取得
781     -- @return オブジェクトリファレンス
782     function obj:getPortRef()
783         self._rtcout:RTC_TRACE("getPortRef()")
784         return self._profile.port_ref
785     end
786     function obj:getObjRef()
787         return self._objref
788     end
789
790     -- プロファイル取得
791     -- @return プロファイル
792     function obj:getProfile()
793         self._rtcout:RTC_TRACE("getProfile()")
794         return self._profile
795     end
796
797     -- 全コネクタ切断
798     -- @return リターンコード
799     function obj:disconnect_all()
800         self._rtcout:RTC_TRACE("disconnect_all()")
801
802         local plist = self._profile.connector_profiles
803
804
805         local retcode = self._ReturnCode_t.RTC_OK
806         local len_ = #plist
807         self._rtcout:RTC_DEBUG("disconnecting "..len_.." connections.")
808
809
810
811         for i, con in ipairs(plist) do
812             tmpret = self:disconnect(con.connector_id)
813             if tmpret ~= self._ReturnCode_t.RTC_OK then
814                 retcode = tmpret
815             end
816         end
817
818
819         return retcode
820     end
821
822     -- オブジェクトリファレンス設定
823     -- @param port_ref オブジェクトリファレンス
824     function obj:setPortRef(port_ref)
825         self._rtcout:RTC_TRACE("setPortRef()")
826         self._profile.port_ref = port_ref
827     end
828
829     -- オブジェクトリファレンス生成
830     function obj:createRef()
831         --print("createRef")
832         local Manager = require "openrtm.Manager"
833         self._svr = Manager:instance():getORB():newservant(self, nil, "IDL:omg.org/RTC/PortService:1.0")
834         self._objref = RTCUtil.getReference(Manager:instance():getORB(), self._svr, "IDL:omg.org/RTC/PortService:1.0")
835         self._profile.port_ref = self._objref
836     end
837
838     -- インターフェースの非アクティブ化
839     function obj:deactivate()
840         local Manager = require "openrtm.Manager"
841         if self._svr ~= nil then
842             Manager:instance():getORB():deactivate(self._svr)
843         end
844     end
845
846     return obj
847 end
848
849
850 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   return orb:newproxy(ior,idl)
29  elseif oil.VERSION == "OiL 0.5" then
30   return orb:newproxy(ior,nil,idl)
31  end
32  return nil
33 end
34
35 -- オブジェクトリファレンス取得
36 -- @param orb ORB
37 -- @param servant サーバント
38 -- @param idl IDLファイル
39 -- @return オブジェクトリファレンス
40 RTCUtil.getReference = function(orb, servant, idl)
41  if oil.VERSION == "OiL 0.4 beta" then
42   local ior = orb:tostring(servant)
43   return RTCUtil.newproxy(orb, ior, idl)
44  elseif oil.VERSION == "OiL 0.5" then
45   return servant
46  end
47  return nil
48 end
49
50 -- データのインスタンスをデータ型から取得
51 -- @param data_type データ型(文字列)
52 -- @return データのインスタンス
53 RTCUtil.instantiateDataType = function(data_type)
54  local Manager = require "openrtm.Manager"
55  local orb = Manager:getORB()
56  local data = orb.types:lookup(data_type)
57  local ret = {}
58  for k,v in pairs(data.fields) do
59   RTCUtil.getDataType(v, ret)
60  end
61  return ret
62  --return {tm={sec=0,nsec=0},data={}}
63 end
64
65 -- データの要素を抽出する
66 -- @param data データ
67 -- @param ret データのインスタンス
68 RTCUtil.getDataType = function(data, ret)
69  if data.type_def ~= nil then
70   --print(data.type_def._type)
71   if data.type_def._type == "struct" then
72    ret[data.name] = {}
73   elseif data.type_def._type == "ulong" then
74    ret[data.name] = 0
75    return
76   elseif data.type_def._type == "long" then
77    ret[data.name] = 0
78    return
79   elseif data.type_def._type == "short" then
80    ret[data.name] = 0
81    return
82   elseif data.type_def._type == "ushort" then
83    ret[data.name] = 0
84    return
85   elseif data.type_def._type == "octet" then
86    ret[data.name] = 0x00
87    return
88   elseif data.type_def._type == "string" then
89    ret[data.name] = ""
90    return
91   elseif data.type_def._type == "float" then
92    ret[data.name] = 0
93    return
94   elseif data.type_def._type == "double" then
95    ret[data.name] = 0
96    return
97   --[[
98   elseif data.type_def._type == "ufloat" then
99    ret[data.name] = 0
100    return
101   elseif data.type_def._type == "udouble" then
102    ret[data.name] = 0
103    return
104   --]]
105         elseif data.type_def._type == "char" then
106             ret[data.name] = ""
107             return
108         elseif data.type_def._type == "boolean" then
109             ret[data.name] = true
110             return
111         elseif data.type_def._type == "sequence" then
112             ret[data.name] = {}
113             return
114         else
115             ret[data.name] = 0
116             return
117         end
118         for k,v in pairs(data.type_def.fields) do
119             RTCUtil.getDataType(v, ret[data.name])
120         end
121     end
122 end
123
124
125 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\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 41.2 seconds.