[openrtm-commit:01704] r648 - trunk/OpenRTM-aist-Python/OpenRTM_aist
openrtm @ openrtm.org
openrtm @ openrtm.org
2016年 2月 1日 (月) 19:47:32 JST
Author: miyamoto
Date: 2016-02-01 19:47:32 +0900 (Mon, 01 Feb 2016)
New Revision: 648
Modified:
trunk/OpenRTM-aist-Python/OpenRTM_aist/CorbaNaming.py
trunk/OpenRTM-aist-Python/OpenRTM_aist/Manager.py
trunk/OpenRTM-aist-Python/OpenRTM_aist/NamingManager.py
Log:
[incompat,new_func,->RELENG_1_2] Topic-based connection has been implemented. refs #3406
Modified: trunk/OpenRTM-aist-Python/OpenRTM_aist/CorbaNaming.py
===================================================================
--- trunk/OpenRTM-aist-Python/OpenRTM_aist/CorbaNaming.py 2016-02-01 10:36:16 UTC (rev 647)
+++ trunk/OpenRTM-aist-Python/OpenRTM_aist/CorbaNaming.py 2016-02-01 10:47:32 UTC (rev 648)
@@ -1109,8 +1109,8 @@
# @brief ネームコンポーネントの文字列表現を取得する
#
# 指定した範囲のネームコンポーネントの文字列表現を取得する。
- # 文字列表現は、NameComponentの構成が{Nc[0],Nc[1],Nc[2]・・・}の場合、
- # Nc[0]id.Nc[0].kind/Nc[1]id.Nc[1].kind/Nc[2].id/Nc[2].kind・・・
+ # 文字列表現は、NameComponentの構成が{Nc[0],Nc[1],Nc[2]・・・}の場合、
+ # Nc[0]id.Nc[0].kind/Nc[1]id.Nc[1].kind/Nc[2].id/Nc[2].kind・・・
# という形式で取得できる。
# 取得した文字列の長さが指定した長さ以上の場合は、
# 指定した長さで切り捨てられる。
@@ -1244,3 +1244,83 @@
print _exc_str
return
+
+ ##
+ # @if jp
+ # @brief 与えられたパス以下の指定されたkindのバインディングを取得する
+ # @param self
+ # @param string_name パス
+ # @param string_kind kind
+ # @return バインディングのリスト
+ # @else
+ #
+ # @brief Get all the binding with specified kind under given naming path
+ # @param self
+ # @param string_name path
+ # @param string_kind kind
+ # @return
+ # @endif
+ # BindingList_var listByKind(const char* string_name,const char* string_kind)
+ def listByKind(self, string_name, string_kind):
+ if not string_name:
+ return []
+ if not string_kind:
+ return []
+ kind = string_kind
+ tmp_bl = self.listBinding(string_name)
+ bl = []
+ tmp_len = len(tmp_bl)
+ list_len = 0
+ for b in tmp_bl:
+ if b.binding_type == CosNaming.nobject:
+ last_index = len(b.binding_name)-1
+ tmp = b.binding_name[last_index].kind
+ if kind != tmp:
+ continue
+ bl.append(b)
+
+ return bl
+
+ ##
+ # @if jp
+ # @brief 与えられた Naming パス以下のすべてのバインディングを取得する
+ # @param self
+ # @param string_name Namingパス
+ # @return バインディングのリスト
+ # @else
+ #
+ # @brief Get all the binding under given naming path
+ # @param self
+ # @param string_name
+ # @return
+ # @endif
+ # BindingList_var list(const char* string_name)
+ def listBinding(self, string_name):
+ if not string_name:
+ return
+ obj = self.resolveStr(string_name)
+ #obj = self.getRootContext()
+ if CORBA.is_nil(obj):
+ return []
+ nc = obj._narrow(obj)
+ if CORBA.is_nil(nc):
+ return []
+ max_list_size = 65536
+
+ bl, bi = obj.list(max_list_size)
+
+
+ max_remaining = max_list_size - len(bl)
+ more_bindings = CORBA.is_nil(bi)
+
+
+ if not more_bindings:
+ while not more_bindings and (max_remaining > 0):
+
+ (tmp_bl, more_bindings) = bi.next_n(max_remaining)
+ for i in tmp_bl:
+ bl.append(i)
+
+ max_remaining = max_list_size - len(tmp_bl[0])
+
+ return bl
\ No newline at end of file
Modified: trunk/OpenRTM-aist-Python/OpenRTM_aist/Manager.py
===================================================================
--- trunk/OpenRTM-aist-Python/OpenRTM_aist/Manager.py 2016-02-01 10:36:16 UTC (rev 647)
+++ trunk/OpenRTM-aist-Python/OpenRTM_aist/Manager.py 2016-02-01 10:47:32 UTC (rev 648)
@@ -972,8 +972,9 @@
self._namingManager.bindObject(name, comp)
self._listeners.naming_.postBind(comp, names)
+ self.publishPorts(comp)
+ self.subscribePorts(comp)
-
return True
@@ -1326,7 +1327,7 @@
tm)
-
+
return
@@ -2392,10 +2393,227 @@
+ ##
+ # @if jp
+ #
+ # @brief 指定したRTコンポーネントの保持するポートをNamingServiceにバインドする
+ # ポートのpublish_topicというプロパティでトピック名を設定し、トピック名のコンテキストの下に登録
+ #
+ #
+ # @param self
+ # @param comp RTコンポーネント
+ #
+ # @else
+ #
+ # @brief
+ # @param self
+ # @param comp
+ #
+ # @endif
+ # void publishPorts(RTObject_impl* comp)
+ def publishPorts(self, comp):
+ ports = comp.get_ports()
+ for p in ports:
+ prof = p.get_port_profile()
+ prop = OpenRTM_aist.Properties()
+ OpenRTM_aist.NVUtil.copyToProperties(prop, prof.properties)
+
+ if (prop.hasKey("publish_topic") is None or not str(prop.getProperty("publish_topic"))) and (prop.hasKey("subscribe_topic") is None or not str(prop.getProperty("subscribe_topic"))) and (prop.hasKey("rendezvous_point") is None or not str(prop.getProperty("rendezvous_point"))):
+ continue
+ if prop.getProperty("port.port_type") == "DataOutPort":
+ name = "dataports.port_cxt/"
+ name += str(prop.getProperty("publish_topic")) + ".topic_cxt/"
+ name += prof.name
+ name += ".outport"
+ elif prop.getProperty("port.port_type") == "DataInPort":
+ name = "dataports.port_cxt/"
+ name += str(prop.getProperty("publish_topic")) + ".topic_cxt/"
+ name += prof.name
+ name += ".inport"
+ elif prop.getProperty("port.port_type") == "CorbaPort":
+ name = "svcports.port_cxt/"
+ name += str(prop.getProperty("publish_topic")) + ".topic_cxt/"
+ name += prof.name
+ name += ".svc"
+
+ else:
+
+ self._rtcout.RTC_WARN("Unknown port type: %s" % str(prop.getProperty("port.port_type")))
+ continue
+
+
+ port = self._poa.reference_to_servant(p)
+
+ self._namingManager.bindPortObject(name, port)
+
##
# @if jp
+ #
+ # @brief 指定したRTコンポーネントの保持するポートを同じトピック名以下の接続可能なポートと接続
+ #
+ #
+ # @param self
+ # @param comp RTコンポーネント
+ #
+ # @else
+ #
+ # @brief
+ # @param self
+ # @param comp
+ #
+ # @endif
+ # void subscribePorts(RTObject_impl* comp)
+ def subscribePorts(self, comp):
+ ports = comp.get_ports()
+
+ for p in ports:
+
+ prof = p.get_port_profile()
+ prop = OpenRTM_aist.Properties()
+ OpenRTM_aist.NVUtil.copyToProperties(prop, prof.properties)
+
+ if (prop.hasKey("publish_topic") is None or not str(prop.getProperty("publish_topic"))) and (prop.hasKey("subscribe_topic") is None or not str(prop.getProperty("subscribe_topic"))) and (prop.hasKey("rendezvous_point") is None or not str(prop.getProperty("rendezvous_point"))):
+ continue
+
+
+
+
+ if prop.getProperty("port.port_type") == "DataOutPort":
+ name = "dataports.port_cxt/"
+ name += str(prop.getProperty("publish_topic")) + ".topic_cxt"
+
+ nsports = self.getPortsOnNameServers(name, "inport")
+
+ self.connectDataPorts(p, nsports)
+
+ elif prop.getProperty("port.port_type") == "DataInPort":
+ name = "dataports.port_cxt/"
+ name += str(prop.getProperty("publish_topic")) + ".topic_cxt"
+ nsports = self.getPortsOnNameServers(name, "outport")
+ self.connectDataPorts(p, nsports)
+
+ elif prop.getProperty("port.port_type") == "CorbaPort":
+ name = "svcports.port_cxt/"
+ name += str(prop.getProperty("publish_topic")) + ".topic_cxt"
+ nsports = self.getPortsOnNameServers(name, "svc")
+ self.connectServicePorts(p, nsports)
+
+ ##
+ # @if jp
+ #
+ # @brief 与えられたパス以下の指定されたkindのポートを取得する
+ #
+ # @param self
+ # @param nsname パス
+ # @param kind kind
+ # @return ポートのオブジェクトリファレンスのリスト
+ #
+ # @else
+ #
+ # @brief
+ # @param self
+ # @param nsname
+ # @param kind
+ # @return
+ #
+ # @endif
+ # PortServiceList_var getPortsOnNameServers(std::string nsname,std::string kind)
+ def getPortsOnNameServers(self, nsname, kind):
+ ports = []
+ ns = self._namingManager._names
+ for n in ns:
+ noc = n.ns
+ if noc is None:
+ continue
+ cns = noc._cosnaming
+
+ bl = cns.listByKind(nsname,kind)
+
+ for b in bl:
+ if b.binding_type != CosNaming.nobject:
+ continue
+ tmp = b.binding_name[0].id + "." + b.binding_name[0].kind
+
+ nspath = "/" + nsname + "/" + tmp
+ nspath.replace("\\","")
+
+ obj = cns.resolveStr(nspath)
+ portsvc = obj
+
+ if CORBA.is_nil(portsvc):
+ continue
+
+ try:
+ p = portsvc.get_port_profile()
+
+ except:
+ continue
+ ports.append(portsvc)
+
+ return ports
+
+ ##
+ # @if jp
+ # @brief 指定したデータポートを指定したリスト内のデータポート全てと接続する
+ # @param self
+ # @param port 対象のデータポート
+ # @param target_ports 接続対象のデータポートのリスト
+ # @else
+ #
+ # @brief
+ # @param self
+ # @param port
+ # @param target_ports
+ # @endif
+ # void connectDataPorts(PortService_ptr port,PortServiceList_var& target_ports)
+ def connectDataPorts(self, port, target_ports):
+ for p in target_ports:
+ if port._is_equivalent(p):
+ continue
+ con_name = ""
+ p0 = port.get_port_profile()
+ p1 = p.get_port_profile()
+ con_name += p0.name
+ con_name += ":"
+ con_name += p1.name
+ prop = OpenRTM_aist.Properties()
+ if RTC.RTC_OK != OpenRTM_aist.CORBA_RTCUtil.connect(con_name,prop,port,p):
+ self._rtcout.RTC_ERROR("Connection error in topic connection.")
+
+
+ ##
+ # @if jp
+ # @brief 指定したサービスポートを指定したリスト内のサービスポート全てと接続する
+ # @param self
+ # @param port 対象のサービスポート
+ # @param target_ports 接続対象のサービスポートのリスト
+ # @else
+ #
+ # @brief
+ # @param self
+ # @param port
+ # @param target_ports
+ # @endif
+ # void connectServicePorts(PortService_ptr port,PortServiceList_var& target_ports)
+ def connectServicePorts(self, port, target_ports):
+ for p in target_ports:
+ if port._is_equivalent(p):
+ continue
+ con_name = ""
+ p0 = port.get_port_profile()
+ p1 = p.get_port_profile()
+ con_name += p0.name
+ con_name += ":"
+ con_name += p1.name
+ prop = OpenRTM_aist.Properties()
+ if RTC.RTC_OK != OpenRTM_aist.CORBA_RTCUtil.connect(con_name,prop,port,p):
+ self._rtcout.RTC_ERROR("Connection error in topic connection.")
+
+
+ ##
+ # @if jp
# @brief 起動時にrtc.confで指定したポートを接続する
# 例:
# manager.components.preconnect: RTC0.port0:RTC0.port1(interface_type=corba_cdr&dataport.dataflow_type=pull&~),~
Modified: trunk/OpenRTM-aist-Python/OpenRTM_aist/NamingManager.py
===================================================================
--- trunk/OpenRTM-aist-Python/OpenRTM_aist/NamingManager.py 2016-02-01 10:36:16 UTC (rev 647)
+++ trunk/OpenRTM-aist-Python/OpenRTM_aist/NamingManager.py 2016-02-01 10:47:32 UTC (rev 648)
@@ -166,6 +166,31 @@
##
# @if jp
#
+ # @brief 指定した CORBA オブジェクトのNamingServiceへバインド
+ #
+ # 指定した CORBA オブジェクトを指定した名称で CORBA NamingService へ
+ # バインドする。
+ #
+ # @param self
+ # @param name バインド時の名称
+ # @param port バインド対象オブジェクト
+ #
+ # @else
+ #
+ # @endif
+ def bindPortObject(self, name, port):
+ self._rtcout.RTC_TRACE("bindPortObject(name = %s, port)", name)
+ try:
+ self._cosnaming.rebindByString(name, port.getPortRef(), True)
+ except:
+ self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
+
+ return
+
+
+ ##
+ # @if jp
+ #
# @brief 指定した CORBA オブジェクトをNamingServiceからアンバインド
#
# 指定した CORBA オブジェクトを CORBA NamingService からアンバインドする。
@@ -207,6 +232,9 @@
return self._cosnaming.isAlive()
+
+
+
##
# @if jp
#
@@ -251,8 +279,10 @@
self._namesMutex = threading.RLock()
self._compNames = []
self._mgrNames = []
+ self._portNames = []
self._compNamesMutex = threading.RLock()
self._mgrNamesMutex = threading.RLock()
+ self._portNamesMutex = threading.RLock()
##
@@ -274,7 +304,7 @@
self._rtcout.RTC_TRACE("NamingManager::registerNameServer(%s, %s)",
(method, name_server))
name = self.createNamingObj(method, name_server)
- self._names.append(self.Names(method, name_server, name))
+ self._names.append(self.NameServer(method, name_server, name))
##
@@ -318,7 +348,36 @@
self.registerMgrName(name, mgr)
+ ##
+ # @if jp
+ #
+ # @brief 指定したポートのNamingServiceへバインド
+ #
+ # @param self
+ # @param name バインド時の名称
+ # @param port バインド対象のポート
+ #
+ # @else
+ #
+ # @param self
+ # @param name
+ # @param port
+ #
+ # @endif
+ # void bindPortObject(const char* name, PortBase* port)
+ def bindPortObject(self, name, port):
+ self._rtcout.RTC_TRACE("NamingManager::bindPortObject(%s)", name)
+ guard = OpenRTM_aist.ScopedLock(self._namesMutex)
+ for i in range(len(self._names)):
+ if self._names[i].ns:
+ try:
+ self._names[i].ns.bindPortObject(name, port)
+ except:
+ del self._names[i].ns
+ self._names[i].ns = 0
+ self.registerPortName(name, port)
+
##
# @if jp
#
@@ -386,6 +445,7 @@
self._names[i].ns.unbindObject(name)
self.unregisterCompName(name)
self.unregisterMgrName(name)
+ self.unregisterPortName(name)
##
@@ -416,6 +476,13 @@
self.unbindObject(self._mgrNames[idx].name)
+ guard = OpenRTM_aist.ScopedLock(self._portNamesMutex)
+ len_ = len(self._portNames)
+ for i in range(len_):
+ idx = (len_ - 1) - i
+ self.unbindObject(self._portNames[idx].name)
+
+
##
# @if jp
#
@@ -525,7 +592,31 @@
self._mgrNames.append(self.Mgr(name, mgr))
return
+ ##
+ # @if jp
+ #
+ # @brief NameServer に登録するポートの設定
+ #
+ #
+ # @param self
+ # @param name ポートの登録時名称
+ # @param port 登録対象オブジェクト
+ #
+ # @else
+ # @param self
+ # @param name
+ # @param port
+ #
+ # @endif
+ def registerPortName(self, name, port):
+ for i in range(len(self._portNames)):
+ if self._portNames[i].name == name:
+ self._portNames[i].port = port
+ return
+ self._portNames.append(self.Port(name, port))
+ return
+
##
# @if jp
#
@@ -562,6 +653,31 @@
##
# @if jp
#
+ # @brief NameServer に登録するポートの設定解除
+ #
+ #
+ # @param self
+ # @param name 設定解除対象ポートの名称
+ #
+ # @else
+ #
+ # @param self
+ # @param name
+ #
+ # @endif
+ def unregisterPortName(self, name):
+ len_ = len(self._portNames)
+ for i in range(len_):
+ idx = (len_ -1) - i
+ if self._portNames[idx].name == name:
+ del self._portNames[idx]
+ return
+ return
+
+
+ ##
+ # @if jp
+ #
# @brief コンポネントをリバインドする
#
# ネームサーバと接続してコンポネントをリバインドする。
@@ -604,15 +720,34 @@
return
+ ##
+ # @if jp
+ #
+ # @brief 登録したネームサービスのリストを取得する
+ #
+ # @return ネームサービスのリスト
+ #
+ # @else
+ #
+ # @brief
+ #
+ # @return
+ #
+ # @endif
+ #
+ # std::vector<NamingService*>& getNameServices();
+ def getNameServices(self):
+ return self._names
+
# Name Servers' method/name and object
##
# @if jp
- # @class Names
+ # @class NameServer
# @brief NameServer 管理用クラス
# @else
#
# @endif
- class Names:
+ class NameServer:
def __init__(self, meth, name, naming):
self.method = meth
self.nsname = name
@@ -637,3 +772,16 @@
def __init__(self, n, obj):
self.name = n
self.mgr = obj
+
+
+ ##
+ # @if jp
+ # @class Port
+ # @brief ポート管理用クラス
+ # @else
+ #
+ # @endif
+ class Port:
+ def __init__(self, n, obj):
+ self.name = n
+ self.port = obj
More information about the openrtm-commit
mailing list