[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