[openrtm-commit:01699] r643 - in trunk/OpenRTM-aist-Python/OpenRTM_aist: . ext
openrtm @ openrtm.org
openrtm @ openrtm.org
2016年 2月 1日 (月) 17:37:55 JST
Author: miyamoto
Date: 2016-02-01 17:37:55 +0900 (Mon, 01 Feb 2016)
New Revision: 643
Removed:
trunk/OpenRTM-aist-Python/OpenRTM_aist/CORBA_RTCUtil.py
trunk/OpenRTM-aist-Python/OpenRTM_aist/InPortDirectConsumer.py
trunk/OpenRTM-aist-Python/OpenRTM_aist/InPortDirectProvider.py
trunk/OpenRTM-aist-Python/OpenRTM_aist/InPortSHMConsumer.py
trunk/OpenRTM-aist-Python/OpenRTM_aist/InPortSHMProvider.py
trunk/OpenRTM-aist-Python/OpenRTM_aist/OutPortDirectConsumer.py
trunk/OpenRTM-aist-Python/OpenRTM_aist/OutPortDirectProvider.py
trunk/OpenRTM-aist-Python/OpenRTM_aist/OutPortSHMConsumer.py
trunk/OpenRTM-aist-Python/OpenRTM_aist/OutPortSHMProvider.py
trunk/OpenRTM-aist-Python/OpenRTM_aist/ext/ssl/
Modified:
trunk/OpenRTM-aist-Python/OpenRTM_aist/CorbaConsumer.py
trunk/OpenRTM-aist-Python/OpenRTM_aist/CorbaNaming.py
trunk/OpenRTM-aist-Python/OpenRTM_aist/FactoryInit.py
trunk/OpenRTM-aist-Python/OpenRTM_aist/InPort.py
trunk/OpenRTM-aist-Python/OpenRTM_aist/InPortBase.py
trunk/OpenRTM-aist-Python/OpenRTM_aist/InPortPullConnector.py
trunk/OpenRTM-aist-Python/OpenRTM_aist/Manager.py
trunk/OpenRTM-aist-Python/OpenRTM_aist/NamingManager.py
trunk/OpenRTM-aist-Python/OpenRTM_aist/OutPortBase.py
trunk/OpenRTM-aist-Python/OpenRTM_aist/OutPortPullConnector.py
trunk/OpenRTM-aist-Python/OpenRTM_aist/OutPortPushConnector.py
trunk/OpenRTM-aist-Python/OpenRTM_aist/PortBase.py
trunk/OpenRTM-aist-Python/OpenRTM_aist/__init__.py
Log:
remove from r632 to r642
Deleted: trunk/OpenRTM-aist-Python/OpenRTM_aist/CORBA_RTCUtil.py
===================================================================
--- trunk/OpenRTM-aist-Python/OpenRTM_aist/CORBA_RTCUtil.py 2016-02-01 05:29:04 UTC (rev 642)
+++ trunk/OpenRTM-aist-Python/OpenRTM_aist/CORBA_RTCUtil.py 2016-02-01 08:37:55 UTC (rev 643)
@@ -1,1248 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: euc-jp -*-
-
-##
-# @file CORBA_RTCUtil.py
-# @brief CORBA RTC utility
-# @date $Date: 2016/01/08 $
-# @author Nobuhiko Miyamoto
-#
-
-import OpenRTM_aist
-import CORBA
-import RTC
-import SDOPackage
-
-##
-# @if jp
-#
-# @brief コンポーネントのプロパティ取得
-#
-#
-# @param rtc RTコンポーネント
-# @return コンポーネントのプロパティ
-#
-# @else
-#
-# @brief
-# @param rtc
-# @return
-#
-# @endif
-# coil::Properties get_component_profile(const RTC::RTObject_ptr rtc)
-def get_component_profile(rtc):
- prop = OpenRTM_aist.Properties()
- if CORBA.is_nil(rtc):
- return prop
- prof = rtc.get_component_profile()
- OpenRTM_aist.NVUtil.copyToProperties(prop, prof.properties)
- return prop
-
-
-
-
-##
-# @if jp
-#
-# @brief コンポーネントが終了しているかを判定
-#
-#
-# @param rtc RTコンポーネント
-# @return True:終了済み False:生存
-#
-# @else
-#
-# @brief
-# @param rtc RTコンポーネント
-# @return
-#
-# @endif
-def is_existing(rtc):
- try:
- rtc._non_existent()
- return False
- except CORBA.SystemException, ex:
- return True
- return True
-
-
-##
-# @if jp
-#
-# @brief RTCがデフォルトの実行コンテキストでalive状態かを判定する
-#
-# @param rtc RTコンポーネント
-# @return True:alive状態
-#
-# @param
-#
-# @else
-#
-# @brief
-# @param
-#
-# @endif
-def is_alive_in_default_ec(rtc):
- ec = get_actual_ec(rtc)
- if CORBA.is_nil(ec):
- return False
- return rtc.is_alive(ec)
-
-
-##
-# @if jp
-#
-# @brief RTコンポーネントに関連付けした実行コンテキストから指定したIDの実行コンテキストを取得
-#
-#
-# @param rtc 対象のRTコンポーネント
-# @param ec_id 実行コンテキストのID
-# @return 実行コンテキストのオブジェクトリファレンス
-#
-# @else
-#
-# @brief
-# @param rtc
-# @param ec_id
-# @return
-#
-# @endif
-# RTC::ExecutionContext_var get_actual_ec(const RTC::RTObject_ptr rtc,RTC::UniqueId ec_id = 0)
-def get_actual_ec(rtc, ec_id=0):
- if ec_id < 0:
- return RTC.ExecutionContext._nil
- if CORBA.is_nil(rtc):
- return RTC.ExecutionContext._nil
- if ec_id < 1000:
- eclist = rtc.get_owned_contexts()
- if ec_id >= len(eclist):
- return RTC.ExecutionContext._nil
- if CORBA.is_nil(eclist[ec_id]):
- return RTC.ExecutionContext._nil
- return eclist[ec_id]
- elif ec_id >= 1000:
- pec_id = ec_id - 1000
- eclist = rtc.get_participating_contexts()
- if pec_id >= len(eclist):
- return RTC.ExecutionContext._nil
- if CORBA.is_nil(eclist[pec_id]):
- return RTC.ExecutionContext._nil
- return eclist[pec_id]
- return RTC.ExecutionContext._nil
-
-
-
-##
-# @if jp
-#
-# @brief 対象のRTコンポーネントから指定した実行コンテキストのIDを取得する
-#
-#
-# @param rtc 対象のRTコンポーネント
-# @param ec 実行コンテキスト
-# @return 実行コンテキストのID
-# 指定した実行コンテキストがRTコンポーネントに関連付けられていなかった場合は-1を返す
-#
-# @else
-#
-# @brief
-# @param
-#
-# @endif
-def get_ec_id(rtc, ec):
- if CORBA.is_nil(rtc):
- return -1
-
- eclist_own = rtc.get_owned_contexts()
-
- count = 0
- for e in eclist_own:
- if not CORBA.is_nil(e):
- if e._is_equivalent(ec):
- return count
- count += 1
- eclist_pec = rtc.get_participating_contexts()
- count = 0
- for e in eclist_pec:
- if not CORBA.is_nil(e):
- if e._is_equivalent(ec):
- return count+1000
- count += 1
- return -1
-
-
-
-##
-# @if jp
-#
-# @brief RTCを指定した実行コンテキストでアクティベーションする
-#
-#
-# @param rtc 対象のRTコンポーネント
-# @param ec_id 実行コンテキストのID
-# @return RTC、ECのオブジェクトリファレンスがnilの場合はBAD_PARAMETERを返す
-# nilではない場合はactivate_component関数の戻り値を返す。RTC_OKの場合はアクティベーションが成功
-#
-# @else
-#
-# @brief
-# @param rtc
-# @param ec_id
-# @return
-#
-# @endif
-# RTC::ReturnCode_t activate(RTC::RTObject_ptr rtc, RTC::UniqueId ec_id = 0)
-def activate(rtc, ec_id=0):
- if CORBA.is_nil(rtc):
- return RTC.BAD_PARAMETER
- ec = get_actual_ec(rtc, ec_id)
- if CORBA.is_nil(ec):
- return RTC.BAD_PARAMETER
- return ec.activate_component(rtc)
-
-
-##
-# @if jp
-#
-# @brief RTCを指定した実行コンテキストで非アクティベーションする
-#
-#
-# @param rtc 対象のRTコンポーネント
-# @param ec_id 実行コンテキストのID
-# @return RTC、ECのオブジェクトリファレンスがnilの場合はBAD_PARAMETERを返す
-# nilではない場合はdeactivate_component関数の戻り値を返す。RTC_OKの場合は非アクティベーションが成功
-#
-# @else
-#
-# @brief
-# @param rtc
-# @param ec_id
-# @return
-#
-# @endif
-# RTC::ReturnCode_t deactivate(RTC::RTObject_ptr rtc, RTC::UniqueId ec_id = 0)
-def deactivate(rtc, ec_id=0):
- if CORBA.is_nil(rtc):
- return RTC.BAD_PARAMETER
- ec = get_actual_ec(rtc, ec_id)
- if CORBA.is_nil(ec):
- return RTC.BAD_PARAMETER
- return ec.deactivate_component(rtc)
-
-##
-# @if jp
-#
-# @brief RTCを指定した実行コンテキストでリセットする
-#
-#
-# @param rtc 対象のRTコンポーネント
-# @param ec_id 実行コンテキストのID
-# @return RTC、ECのオブジェクトリファレンスがnilの場合はBAD_PARAMETERを返す
-# nilではない場合はdeactivate_component関数の戻り値を返す。RTC_OKの場合はリセットが成功
-#
-# @else
-#
-# @brief
-# @param rtc
-# @param ec_id
-# @return
-#
-# @endif
-# RTC::ReturnCode_t reset(RTC::RTObject_ptr rtc, RTC::UniqueId ec_id = 0)
-def reset(rtc, ec_id=0):
- if CORBA.is_nil(rtc):
- return RTC.BAD_PARAMETER
- ec = get_actual_ec(rtc, ec_id)
- if CORBA.is_nil(ec):
- return RTC.BAD_PARAMETER
- return ec.reset_component(rtc)
-
-##
-# @if jp
-#
-# @brief 対象のRTコンポーネントの指定した実行コンテキストでの状態を取得
-#
-#
-# @param rtc 対象のRTコンポーネント
-# @param ec_id 実行コンテキストのID
-# @param ret RTCの状態
-# @return rtc、ecがnilの場合はFalseを返す。
-# nilではない場合はret[0]に状態を代入してTrueを返す。
-#
-# @else
-#
-# @brief
-# @param rtc
-# @param ec_id
-# @return
-#
-# @endif
-def get_state(rtc, ec_id=0, ret=[None]):
- if CORBA.is_nil(rtc):
- return False
- ec = get_actual_ec(rtc, ec_id)
- if CORBA.is_nil(ec):
- return False
- ret[0] = ec.get_component_state(rtc)
- return True
-
-##
-# @if jp
-#
-# @brief 対象のRTコンポーネントの指定した実行コンテキストでINACTIVE状態かどうか判定
-#
-#
-# @param rtc 対象のRTコンポーネント
-# @param ec_id 実行コンテキストのID
-# @return INACTIVE状態の時はTrue、それ以外はFalse
-# rtc、ecがnilの場合もFalseを返す
-#
-# @else
-#
-# @brief
-# @param rtc
-# @param ec_id
-# @return
-#
-# @endif
-def is_in_inactive(rtc, ec_id=0):
- ret = [None]
- if get_state(rtc, ec_id, ret):
- if ret[0] == RTC.INACTIVE_STATE:
- return True
- return False
-
-##
-# @if jp
-#
-# @brief 対象のRTコンポーネントの指定した実行コンテキストでACTIVE状態かどうか判定
-#
-#
-# @param rtc 対象のRTコンポーネント
-# @param ec_id 実行コンテキストのID
-# @return ACTIVE状態の時はTrue、それ以外はFalse
-# rtc、ecがnilの場合もFalseを返す
-#
-# @else
-#
-# @brief
-# @param rtc
-# @param ec_id
-# @return
-#
-# @endif
-def is_in_active(rtc, ec_id=0):
- ret = [None]
- if get_state(rtc, ec_id, ret):
- if ret[0] == RTC.ACTIVE_STATE:
- return True
- return False
-
-##
-# @if jp
-#
-# @brief 対象のRTコンポーネントの指定した実行コンテキストでERROR状態かどうか判定
-#
-#
-# @param rtc 対象のRTコンポーネント
-# @param ec_id 実行コンテキストのID
-# @return ERROR状態の時はTrue、それ以外はFalse
-# rtc、ecがnilの場合もFalseを返す
-#
-# @else
-#
-# @brief
-# @param rtc
-# @param ec_id
-# @return
-#
-# @endif
-def is_in_error(rtc, ec_id=0):
- ret = [None]
- if get_state(rtc, ec_id, ret):
- if ret[0] == RTC.ERROR_STATE:
- return True
- return False
-
-
-
-##
-# @if jp
-#
-# @brief RTCのデフォルトの実行コンテキストの実行周期を取得する
-#
-#
-# @param rtc RTコンポーネント
-# @return 実行周期
-#
-# @else
-#
-# @brief
-# @param ec
-# @return
-#
-# @endif
-def get_default_rate(rtc):
- ec = get_actual_ec(rtc)
- return ec.get_rate()
-
-
-##
-# @if jp
-#
-# @brief RTCのデフォルトの実行コンテキストの実行周期を設定する
-#
-#
-# @param rtc RTコンポーネント
-# @param rate 実行周期
-# @return set_rate関数の戻り値を返す。
-# RTC_OKで設定が成功
-#
-# @else
-#
-# @brief
-# @param ec
-#
-# @endif
-def set_default_rate(rtc, rate):
- ec = get_actual_ec(rtc)
- return ec.set_rate(rate)
-
-
-##
-# @if jp
-#
-# @brief RTCの指定IDの実行コンテキストの周期を設定
-#
-#
-# @param rtc 対象のRTコンポーネント
-# @param ec_id 指定の実行コンテキストのID
-# @return 実行周期
-#
-# @else
-#
-# @brief
-# @param ec
-# @return
-#
-# @endif
-def get_current_rate(rtc, ec_id):
- ec = get_actual_ec(rtc, ec_id)
- return ec.get_rate()
-
-
-##
-# @if jp
-#
-# @brief RTCの指定IDの実行コンテキストの周期を取得
-#
-#
-# @param rtc 対象のRTコンポーネント
-# @param ec_id 指定の実行コンテキストのID
-# @return set_rate関数の戻り値を返す。
-# RTC_OKで設定が成功
-#
-# @else
-#
-# @brief
-# @param
-#
-# @endif
-def set_current_rate(rtc, ec_id, rate):
- ec = get_actual_ec(rtc, ec_id)
- return ec.set_rate(rate)
-
-
-##
-# @if jp
-#
-# @brief 対象のRTCのデフォルトの実行コンテキストに指定のRTCを関連付ける
-#
-#
-# @param localcomp 対象のRTコンポーネント
-# @param othercomp 実行コンテキストに関連付けるRTコンポーネント
-# @return ecの取得に失敗した場合はRTC_ERRORを返す
-# そうでない場合はaddComponent関数の戻り値を返す。RTC_OKで接続成功。
-#
-# @else
-#
-# @brief
-# @param
-#
-# @endif
-def add_rtc_to_default_ec(localcomp, othercomp):
- ec = get_actual_ec(localcomp)
- if CORBA.is_nil(ec):
- return RTC.RTC_ERROR
- return ec.add_component(othercomp)
-
-
-##
-# @if jp
-#
-# @brief 対象のRTCのデフォルトの実行コンテキストの指定のRTCへの関連付けを解除する
-#
-#
-# @param localcomp 対象のRTコンポーネント
-# @param othercomp 実行コンテキストとの関連付けを解除するRTコンポーネント
-# @return ecの取得に失敗した場合はRTC_ERRORを返す
-# そうでない場合はremoveComponent関数の戻り値を返す。RTC_OKで接続成功。
-#
-# @else
-#
-# @brief
-# @param
-#
-# @endif
-def remove_rtc_to_default_ec(localcomp, othercomp):
- ec = get_actual_ec(localcomp)
- if CORBA.is_nil(ec):
- return RTC.RTC_ERROR
- return ec.remove_component(othercomp)
-
-
-##
-# @if jp
-#
-# @brief RTCのデフォルトの実行コンテキストに参加しているRTCのリストを取得する
-# 実行コンテキストがnilの場合は空のリストを返す
-#
-#
-# @param rtc RTコンポーネント
-# @return RTCのリスト
-#
-# @else
-#
-# @brief
-# @param ec
-# @return
-#
-# @endif
-def get_participants_rtc(rtc):
- ec = get_actual_ec(rtc)
- if CORBA.is_nil(ec):
- return []
- prifile = ec.get_profile()
- return prifile.participants
-
-
-##
-# @if jp
-#
-# @brief 指定したRTCの保持するポートの名前を取得
-#
-#
-# @param rtc 対象のRTコンポーネント
-# @return ポート名のリスト
-#
-# @else
-#
-# @brief
-# @param rtc
-# @return
-#
-# @endif
-def get_port_names(rtc):
- names = []
- if CORBA.is_nil(rtc):
- return names
- ports = rtc.get_ports()
- for p in ports:
- pp = p.get_port_profile()
- s = pp.name
- names.append(s)
- return names
-
-
-##
-# @if jp
-#
-# @brief 指定したRTCの保持するインポートの名前を取得
-#
-#
-# @param rtc 対象のRTコンポーネント
-# @return ポート名のリスト
-#
-# @else
-#
-# @brief
-# @param rtc
-# @return
-#
-# @endif
-def get_inport_names(rtc):
- names = []
- if CORBA.is_nil(rtc):
- return names
-
- ports = rtc.get_ports()
- for p in ports:
- pp = p.get_port_profile()
- prop = OpenRTM_aist.Properties()
- OpenRTM_aist.NVUtil.copyToProperties(prop, pp.properties)
- if prop.getProperty("port.port_type") == "DataInPort":
- s = pp.name
- names.append(s)
- return names
-
-
-##
-# @if jp
-#
-# @brief 指定したRTCの保持するアウトポートの名前を取得
-#
-#
-# @param rtc 対象のRTコンポーネント
-# @return ポート名のリスト
-#
-# @else
-#
-# @brief
-# @param rtc
-# @return
-#
-# @endif
-def get_outport_names(rtc):
- names = []
- if CORBA.is_nil(rtc):
- return names
-
- ports = rtc.get_ports()
- for p in ports:
- pp = p.get_port_profile()
- prop = OpenRTM_aist.Properties()
- OpenRTM_aist.NVUtil.copyToProperties(prop, pp.properties)
- if prop.getProperty("port.port_type") == "DataOutPort":
- s = pp.name
- names.append(s)
- return names
-
-
-
-##
-# @if jp
-#
-# @brief 指定したRTCの保持するサービスポートの名前を取得
-#
-#
-# @param rtc 対象のRTコンポーネント
-# @return ポート名のリスト
-#
-# @else
-#
-# @brief
-# @param rtc
-# @return
-#
-# @endif
-def get_svcport_names(rtc):
- names = []
- if CORBA.is_nil(rtc):
- return names
-
- ports = rtc.get_ports()
- for p in ports:
- pp = p.get_port_profile()
- prop = OpenRTM_aist.Properties()
- OpenRTM_aist.NVUtil.copyToProperties(prop, pp.properties)
- if prop.getProperty("port.port_type") == "CorbaPort":
- s = pp.name
- names.append(s)
- return names
-
-
-##
-# @if jp
-#
-# @brief 対象のRTCから指定した名前のポートを取得
-#
-#
-# @param rtc RTコンポーネント
-# @param name ポート名
-# @return ポート
-#
-# @else
-#
-# @brief
-# @param rtc
-# @param name
-# @return
-#
-# @endif
-#
-# RTC::PortService_var get_port_by_name(const RTC::RTObject_ptr rtc, std::string name)
-def get_port_by_name(rtc, name):
- if CORBA.is_nil(rtc):
- return RTC.PortService._nil
- ports = rtc.get_ports()
- for p in ports:
- pp = p.get_port_profile()
- s = pp.name
-
- if name == s:
- return p
-
- return RTC.PortService._nil
-
-
-##
-# @if jp
-#
-# @brief 指定したポートの保持しているコネクタの名前のリストを取得
-#
-#
-# @param port 対象のポート
-# @return コネクタ名のリスト
-#
-# @else
-#
-# @brief
-# @param port
-# @return
-#
-# @endif
-def get_connector_names(port):
- names = []
- if CORBA.is_nil(port):
- return names
- conprof = port.get_connector_profiles()
- for c in conprof:
- names.append(c.name)
- return names
-
-
-
-##
-# @if jp
-#
-# @brief 指定したポートの保持しているコネクタのIDのリストを取得
-#
-#
-# @param port 対象のポート
-# @return コネクタのIDのリスト
-#
-# @else
-#
-# @brief
-# @param port
-# @return
-#
-# @endif
-def get_connector_ids(port):
- ids = []
- if CORBA.is_nil(port):
- return ids
- conprof = port.get_connector_profiles()
- for c in conprof:
- ids.append(c.connector_id)
- return ids
-
-
-##
-# @if jp
-#
-# @brief 指定したポートを接続するためのコネクタプロファイルを取得
-#
-#
-# @param name コネクタ名
-# @param prop_arg 設定
-# @param port0 対象のポート1
-# @param port1 対象のポート2
-# @return コネクタプロファイル
-#
-# @else
-#
-# @brief
-# @param name
-# @param prop_arg
-# @param port0
-# @param port1
-# @return
-#
-# @endif
-# RTC::ConnectorProfile_var create_connector(const std::string name,const coil::Properties prop_arg,const RTC::PortService_ptr port0,const RTC::PortService_ptr port1)
-def create_connector(name, prop_arg, port0, port1):
- prop = prop_arg
- conn_prof = RTC.ConnectorProfile(name, "", [port0, port1],[])
-
-
-
- if not str(prop.getProperty("dataport.dataflow_type")):
- prop.setProperty("dataport.dataflow_type","push")
-
-
-
- if not str(prop.getProperty("dataport.interface_type")):
- prop.setProperty("dataport.interface_type","corba_cdr")
-
-
- conn_prof.properties = []
- OpenRTM_aist.NVUtil.copyFromProperties(conn_prof.properties, prop)
-
- return conn_prof
-
-
-
-
-
-##
-# @if jp
-#
-# @brief 指定したポート同士が接続されているかを判定
-#
-#
-# @param localport 対象のポート1
-# @param otherport 対象のポート2
-# @return True: 接続済み、False: 未接続
-#
-# @else
-#
-# @brief
-# @param name
-# @param prop_arg
-# @param port0
-# @param port1
-# @return
-#
-# @endif
-
-def already_connected(localport, otherport):
- conprof = localport.get_connector_profiles()
- for c in conprof:
- for p in c.ports:
- if p._is_equivalent(otherport):
- return True
-
- return False
-
-
-##
-# @if jp
-#
-# @brief 指定したポートを接続する
-#
-#
-# @param name コネクタ名
-# @param prop 設定
-# @param port0 対象のポート1
-# @param port1 対象のポート2
-# @return RTC、ECのオブジェクトリファレンスがnilの場合はBAD_PARAMETERを返す
-# nilではない場合はport0.connect関数の戻り値を返す。RTC_OKの場合は接続が成功
-#
-# @else
-#
-# @brief
-# @param name
-# @param prop
-# @param port0
-# @param port1
-# @return
-#
-# @endif
-# RTC::ReturnCode_t connect(const std::string name,const coil::Properties prop,const RTC::PortService_ptr port0,const RTC::PortService_ptr port1)
-def connect(name, prop, port0, port1):
- if CORBA.is_nil(port0):
- RTC.BAD_PARAMETER
- if CORBA.is_nil(port1):
- RTC.BAD_PARAMETER
- if port0._is_equivalent(port1):
- RTC.BAD_PARAMETER
- cprof = create_connector(name, prop, port0, port1)
- return port0.connect(cprof)[0]
-
-
-
-##
-# @if jp
-#
-# @brief 指定したポートと指定したリスト内のポート全てと接続する
-#
-#
-# @param name コネクタ名
-# @param prop 設定
-# @param port0 対象のポート
-# @param port1 対象のポートのリスト
-# @return 全ての接続が成功した場合はRTC_OKを返す。
-# connect関数がRTC_OK以外を返した場合はRTC_ERRORを返す。
-#
-#
-# @else
-#
-# @brief
-# @param name
-# @param prop
-# @param port0
-# @param port1
-# @return
-#
-# @endif
-# RTC::ReturnCode_t connect_multi(const std::string name,const coil::Properties prop,const RTC::PortService_ptr port,RTC::PortServiceList_var& target_ports)
-def connect_multi(name, prop, port, target_ports):
- ret = RTC.RTC_OK
-
- for p in target_ports:
- if p._is_equivalent(port):
- continue
- if already_connected(port, p):
- continue
- if RTC.RTC_OK != connect(name, prop, port, p):
- ret = RTC.RTC_ERROR
-
- return ret
-
-
-##
-# @if jp
-# @class find_port
-# @brief ポートを名前から検索
-#
-# @else
-# @class find_port
-# @brief ポートを名前から検索
-#
-# @endif
-#
-class find_port:
- ##
- # @if jp
- #
- # @brief コンストラクタ
- # 検索するポート名を指定する
- #
- #
- # @param self
- # @param name ポート名
- #
- # @else
- #
- # @brief
- # @param self
- # @param name
- #
- # @endif
- # find_port(const std::string name)
- def __init__(self, name):
- self._name = name
- ##
- # @if jp
- #
- # @brief 対象のポートの名前と指定したポート名が一致するか判定
- #
- #
- # @param self
- # @param p 対象のポート
- # @return True: 名前が一致、False: 名前が不一致
- #
- # @else
- #
- # @brief
- # @param self
- # @param p
- # @return
- #
- # @endif
- # bool operator()(RTC::PortService_var p)
- def __call__(self, p):
- prof = p.get_port_profile()
- c = prof.name
-
- return (self._name == c)
-
-##
-# @if jp
-#
-# @brief 対象のRTCの指定した名前のポートを接続する
-#
-#
-# @param name コネクタ名
-# @param prop 設定
-# @param rtc0 対象のRTCコンポーネント1
-# @param portName0 対象のポート名1
-# @param rtc1 対象のRTCコンポーネント2
-# @param portName1 対象のRTCコンポーネント2
-# @return RTC、ポートがnilの場合はBAD_PARAMETERを返す。
-# nilではない場合はport0.connect関数の戻り値を返す。RTC_OKの場合は接続が成功
-#
-# @else
-#
-# @brief
-# @param name
-# @param prop_arg
-# @param port0
-# @param port1
-#
-# @endif
-#
-# RTC::ReturnCode_t connect_by_name(std::string name, coil::Properties prop,RTC::RTObject_ptr rtc0,const std::string portName0,RTC::RTObject_ptr rtc1,const std::string portName1)
-def connect_by_name(name, prop, rtc0, portName0, rtc1, portName1):
- if CORBA.is_nil(rtc0):
- return RTC.BAD_PARAMETER
- if CORBA.is_nil(rtc1):
- return RTC.BAD_PARAMETER
-
- port0 = get_port_by_name(rtc0, portName0)
- if CORBA.is_nil(port0):
- return RTC.BAD_PARAMETER
-
- port1 = get_port_by_name(rtc1, portName1)
- if CORBA.is_nil(port1):
- return RTC.BAD_PARAMETER
-
- return connect(name, prop, port0, port1)
-
-
-##
-# @if jp
-#
-# @brief 指定のコネクタを切断する
-#
-#
-# @param connector_prof コネクタプロファイル
-# @return コネクタプロファイルで保持しているポートのオブジェクトリファレンスがnilの場合はBAD_PARAMETERを返す
-# nilではない場合はports[0].disconnect関数の戻り値を返す。RTC_OKの場合は切断が成功
-#
-# @else
-#
-# @brief
-# @param connector_prof
-# @return
-#
-# @endif
-def disconnect(connector_prof):
- ports = connector_prof.ports
- return disconnect_by_connector_id(ports[0], connector_prof.connector_id)
-
-
-
-##
-# @if jp
-#
-# @brief 対象のポートで指定した名前のコネクタを切断
-#
-#
-# @param port 対象のポート
-# @param name コネクタ名
-# @return portがnilの場合はBAD_PARAMETERを返す
-# nilではない場合はdisconnect関数の戻り値を返す。RTC_OKの場合は切断が成功
-#
-# @else
-#
-# @brief
-# @param
-#
-# @endif
-def disconnect_by_connector_name(port, name):
- if CORBA.is_nil(port):
- return RTC.BAD_PARAMETER
- conprof = port.get_connector_profiles()
- for c in conprof:
- if c.name == name:
- return disconnect(c)
- return RTC.BAD_PARAMETER
-
-
-
-
-##
-# @if jp
-#
-# @brief 対象のポートで指定したIDのコネクタを切断
-#
-#
-# @param port 対象のポート
-# @param name コネクタID
-# @return portがnilの場合はBAD_PARAMETERを返す
-# nilではない場合はdisconnect関数の戻り値を返す。RTC_OKの場合は切断が成功
-#
-# @else
-#
-# @brief
-# @param
-#
-# @endif
-def disconnect_by_connector_id(port, id):
- if CORBA.is_nil(port):
- return RTC.BAD_PARAMETER
- return port.disconnect(id)
-
-
-##
-# @if jp
-#
-# @brief 対象ポートと接続しているポートで指定したポート名と一致した場合に切断
-#
-#
-# @param localport 対象のポート
-# @param othername 接続しているポート名
-# @return ポートがnilの場合、localportの名前とothernameが一致する場合、接続しているポートの名前でothernameと一致するものがない場合にBAD_PARAMETERを返す
-# 上記の条件に当てはまらない場合はdisconnect関数の戻り値を返す。RTC_OKの場合は切断が成功
-#
-# @else
-#
-# @brief
-# @param
-#
-# @endif
-def disconnect_by_port_name(localport, othername):
- if CORBA.is_nil(localport):
- return RTC.BAD_PARAMETER
- prof = localport.get_port_profile()
- if prof.name == othername:
- return RTC.BAD_PARAMETER
-
- conprof = localport.get_connector_profiles()
- for c in conprof:
- for p in c.ports:
- if not CORBA.is_nil(p):
- pp = p.get_port_profile()
- if pp.name == othername:
- return disconnect(c)
- return RTC.BAD_PARAMETER
-
-
-##
-# @if jp
-#
-# @brief 指定したRTコンポーネントのコンフィギュレーション取得
-#
-#
-# @param rtc 対象のRTコンポーネント
-# @return rtcがnilの場合はNoneを返す。
-# nilではない場合はコンフィギュレーションを返す。
-#
-# @else
-#
-# @brief
-# @param
-# @return
-#
-# @endif
-def get_configuration(rtc):
- if CORBA.is_nil(rtc):
- return SDOPackage.Configuration._nil
-
- return rtc.get_configuration()
-
-
-##
-# @if jp
-#
-# @brief 指定したコンフィギュレーションセット名、パラメータ名のコンフィギュレーションパラメータを取得
-#
-#
-# @param conf コンフィギュレーション
-# @param confset_name コンフィギュレーションセット名
-# @param value_name パラメータ名
-# @return パラメータ
-#
-# @else
-#
-# @brief
-# @param rtc
-# @param confset_name
-# @param value_name
-# @param ret
-# @return
-#
-# @endif
-def get_parameter_by_key(rtc, confset_name, value_name):
- conf = rtc.get_configuration()
-
-
- confset = conf.get_configuration_set(confset_name)
- confData = confset.configuration_data
- prop = OpenRTM_aist.Properties()
- OpenRTM_aist.NVUtil.copyToProperties(prop, confData)
- return prop.getProperty(value_name)
-
-
-
-
-##
-# @if jp
-#
-# @brief 対象のRTCのアクティブなコンフィギュレーションセット名を取得する
-#
-# @param rtc RTコンポーネント
-# @return コンフィギュレーションセット名
-# コンフィギュレーションの取得に失敗した場合は空の文字列を返す
-#
-# @param
-#
-# @else
-#
-# @brief
-# @param
-#
-# @endif
-def get_current_configuration_name(rtc):
- conf = rtc.get_configuration()
- confset = conf.get_active_configuration_set()
- return confset.id
-
-##
-# @if jp
-#
-# @brief アクティブなコンフィギュレーションセットを取得
-#
-#
-# @param rtc 対象のRTコンポーネント
-# @return アクティブなコンフィギュレーションセット
-#
-# @else
-#
-# @brief
-# @param rtc
-# @return
-#
-# @endif
-def get_active_configuration(rtc):
- conf = rtc.get_configuration()
-
- confset = conf.get_active_configuration_set()
- confData = confset.configuration_data
- prop = OpenRTM_aist.Properties()
- OpenRTM_aist.NVUtil.copyToProperties(prop, confData)
- return prop
-
-
-
-
-
-##
-# @if jp
-#
-# @brief コンフィギュレーションパラメータを設定
-#
-#
-# @param confset_name コンフィギュレーションセット名
-# @param value_name パラメータ名
-# @param value パラメータ
-# @return True:設定に成功、False:設定に失敗
-#
-# @else
-#
-# @brief
-# @param confset_name
-# @param value_name
-# @param value
-# @return
-#
-# @endif
-def set_configuration(rtc, confset_name, value_name, value):
- conf = rtc.get_configuration()
-
- confset = conf.get_configuration_set(confset_name)
- confData = confset.configuration_data
- prop = OpenRTM_aist.Properties()
- OpenRTM_aist.NVUtil.copyToProperties(prop, confData)
- prop.setProperty(value_name,value)
- OpenRTM_aist.NVUtil.copyFromProperties(confData,prop)
- confset.configuration_data = confData
- conf.set_configuration_set_values(confset)
-
- conf.activate_configuration_set(confset_name)
- return True
-
-
-
\ No newline at end of file
Modified: trunk/OpenRTM-aist-Python/OpenRTM_aist/CorbaConsumer.py
===================================================================
--- trunk/OpenRTM-aist-Python/OpenRTM_aist/CorbaConsumer.py 2016-02-01 05:29:04 UTC (rev 642)
+++ trunk/OpenRTM-aist-Python/OpenRTM_aist/CorbaConsumer.py 2016-02-01 08:37:55 UTC (rev 643)
@@ -1,350 +1,333 @@
-#!/usr/bin/env python
-# -*- coding: euc-jp -*-
-
-
-##
-#
-# @file CorbaConsumer.py
-# @brief CORBA Consumer class
-# @date $Date: 2007/09/20 $
-# @author Noriaki Ando <n-ando at aist.go.jp> and Shinji Kurihara
-#
-# Copyright (C) 2006-2008
-# Noriaki Ando
-# Task-intelligence Research Group,
-# Intelligent Systems Research Institute,
-# National Institute of
-# Advanced Industrial Science and Technology (AIST), Japan
-# All rights reserved.
-
-
-from omniORB import CORBA
-import OpenRTM_aist
-
-##
-# @if jp
-# @class CorbaConsumerBase
-#
-# @brief オブジェクトリファレンスを保持するプレースホルダ基底クラス
-#
-# 通信手段として CORBA を選択した場合のコンシューマ実装のための基底クラス
-#
-# @since 0.4.0
-#
-# @else
-# @class ConsumerBase
-# @brief Placeholder base class to hold remote object reference.
-# @endif
-class CorbaConsumerBase:
- """
- """
-
-
-
- ##
- # @if jp
- #
- # @brief コンストラクタ
- #
- # @param self
- # @param consumer コピー元のCorbaConsumerBaseオブジェクト
- #
- # @else
- #
- # @brief Consructor
- #
- # @param self
- #
- # @endif
- def __init__(self, consumer=None):
- if consumer:
- self._objref = consumer._objref
- else:
- self._objref = None
-
-
- ##
- # @if jp
- #
- # @brief 代入演算子
- #
- # @param self
- # @param consumer 代入元
- #
- # @return 代入結果
- #
- # @else
- #
- # @brief Assignment operator
- #
- # @param self
- # @param consumer Copy source.
- #
- # @endif
- def equal(self, consumer):
- self._objref = consumer._objref
- return self
-
-
- ##
- # @if jp
- #
- # @brief CORBAオブジェクトをセットする
- #
- # 与えられたオブジェクトリファレンスは、ConsumerBase オブジェクト内に
- # CORBA::Object_var 型として保持される。
- #
- # @param self
- # @param obj CORBA オブジェクトのリファレンス
- #
- # @return obj が nil リファレンスの場合 false を返す。
- #
- # @else
- #
- # @brief Set CORBA Object
- #
- # The given CORBA Object is held as CORBA::Object_var type
- #
- # @param self
- # @param obj Object reference of CORBA object
- #
- # @return If obj is nil reference, it returns false.
- #
- # @endif
- def setObject(self, obj):
- if CORBA.is_nil(obj):
- return False
-
- self._objref = obj
- return True
-
-
- ##
- # @if jp
- #
- # @brief CORBAオブジェクトを取得する
- #
- # ConsumerBase オブジェクト内に CORBA::Object_var 型として保持されている
- # オブジェクトリファレンスを取得する。
- #
- # @param self
- #
- # @return obj CORBA オブジェクトのリファレンス
- #
- # @else
- #
- # @brief Get CORBA Object
- #
- # @param self
- #
- # @return Object reference of CORBA object
- #
- # @endif
- def getObject(self):
- return self._objref
-
-
- ##
- # @if jp
- #
- # @brief CORBAオブジェクトの設定をクリアする
- #
- # 設定されている CORBA オブジェクトをクリアする。
- # CORBAオブジェクトそのものに対しては何も操作しない。
- #
- # @param self
- #
- # @else
- #
- # @endif
- def releaseObject(self):
- self._objref = CORBA.Object._nil
-
-
-
-##
-# @if jp
-#
-# @class CorbaConsumer
-# @brief オブジェクトリファレンスを保持するプレースホルダクラス
-#
-# 引数で与えられた型のCORBAオブジェクトを保持する。
-# オブジェクトがセットされたときに、与えられた型で narrow されるので、
-# _ptr() で取得するリファレンスは、narrow 済みのリファレンスである。
-#
-# @since 0.4.0
-#
-# @else
-#
-# @class Consumer.CorbaConsumer
-# @brief Placeholder class to hold remote object reference.
-#
-# This class holds a type of object that given by parameter.
-# For internal use, _ptr type and _var type should be given as parameter.
-#
-# @since 0.4.0
-#
-# @endif
-class CorbaConsumer(CorbaConsumerBase):
- """
- """
-
-
-
- ##
- # @if jp
- #
- # @brief コンストラクタ
- #
- # @param self
- # @param interfaceType このホルダが保持するオブジェクトの型
- # (デフォルト値;None)
- # @param consumer このホルダが保持するオブジェクト(デフォルト値;None)
- #
- # @else
- #
- # @brief Consructor
- #
- # @endif
- def __init__(self, interfaceType=None, consumer=None):
- if interfaceType:
- self._interfaceType = interfaceType
- else:
- self._interfaceType = None
-
- if consumer:
- CorbaConsumerBase.__init__(self, consumer)
- self._var = consumer._var
- else:
- CorbaConsumerBase.__init__(self)
- self._var = None
-
- self._sev = None
-
-
- ##
- # @if jp
- #
- # @brief 代入演算子
- #
- # @param self
- # @param consumer 代入元
- #
- # @return 代入結果
- #
- # @else
- #
- # @brief Assignment operator
- #
- # @param self
- # @param consumer Copy source.
- #
- # @endif
- def equal(self, consumer):
- self._var = consumer._var
-
-
- def __del__(self):
- self.releaseObject()
-
-
- ##
- # @if jp
- # @brief オブジェクトをセットする
- #
- # ConsumerBase のオーバーライド。CORBA::Object_var にオブジェクトをセット
- # するとともに、パラメータの型で narrow したオブジェクトを保持する。
- #
- # @param self
- # @param obj CORBA Objecct
- #
- # @return オブジェクト設定結果
- # 設定対象オブジェクトが null の場合は false が返ってくる
- #
- # @else
- # @brief Set Object
- #
- # Override function of ConsumerBase. This operation set an Object to
- # CORBA:Object_var in the class, and this object is narrowed to
- # given parameter and stored in.
- #
- # @param self
- # @param obj CORBA Objecct
- #
- # @endif
- def setObject(self, obj):
- if not CorbaConsumerBase.setObject(self, obj):
- self.releaseObject()
- return False
-
- if self._interfaceType:
- self._var = obj._narrow(self._interfaceType)
- else:
- self._var = self._objref
-
-
-
- if not CORBA.is_nil(self._var):
- return True
-
- self.releaseObject()
- return False
-
-
- ##
- # @if jp
- # @brief ObjectType 型のオブジェクトのリファレンスを取得
- #
- # ObjectType に narrow済みのオブジェクトのリファレンスを取得する。
- # オブジェクトリファレンスを使用するには、setObject() でセット済みで
- # なければならない。
- # オブジェクトがセットされていなければ nil オブジェクトリファレンスが
- # 返される。
- #
- # @param self
- #
- # @return ObjectType に narrow 済みのオブジェクトのリファレンス
- #
- # @else
- # @brief Get Object reference narrowed as ObjectType
- #
- # This operation returns object reference narrowed as ObjectType.
- # To use the returned object reference, reference have to be set by
- # setObject().
- # If object is not set, this operation returns nil object reference.
- #
- # @return The object reference narrowed as ObjectType
- #
- # @endif
- def _ptr(self):
- #print dir(self._var)
- if self._sev is not None:
- return self._sev
- try:
- mgr = OpenRTM_aist.Manager.instance()
- self._sev = mgr._poa.reference_to_servant(self._var)
- if self._sev is not None:
- return self._sev
- except:
- return self._var
-
- return self._var
-
-
- ##
- # @if jp
- #
- # @brief CORBAオブジェクトの設定をクリアする
- #
- # 設定されている CORBA オブジェクトをクリアする。
- # CORBAオブジェクトそのものに対しては何も操作しない。
- #
- # @param self
- #
- # @else
- #
- # @endif
- def releaseObject(self):
- CorbaConsumerBase.releaseObject(self)
- self._var = CORBA.Object._nil
- self._sev = None
+#!/usr/bin/env python
+# -*- coding: euc-jp -*-
+
+
+##
+#
+# @file CorbaConsumer.py
+# @brief CORBA Consumer class
+# @date $Date: 2007/09/20 $
+# @author Noriaki Ando <n-ando at aist.go.jp> and Shinji Kurihara
+#
+# Copyright (C) 2006-2008
+# Noriaki Ando
+# Task-intelligence Research Group,
+# Intelligent Systems Research Institute,
+# National Institute of
+# Advanced Industrial Science and Technology (AIST), Japan
+# All rights reserved.
+
+
+from omniORB import CORBA
+
+##
+# @if jp
+# @class CorbaConsumerBase
+#
+# @brief オブジェクトリファレンスを保持するプレースホルダ基底クラス
+#
+# 通信手段として CORBA を選択した場合のコンシューマ実装のための基底クラス
+#
+# @since 0.4.0
+#
+# @else
+# @class ConsumerBase
+# @brief Placeholder base class to hold remote object reference.
+# @endif
+class CorbaConsumerBase:
+ """
+ """
+
+
+
+ ##
+ # @if jp
+ #
+ # @brief コンストラクタ
+ #
+ # @param self
+ # @param consumer コピー元のCorbaConsumerBaseオブジェクト
+ #
+ # @else
+ #
+ # @brief Consructor
+ #
+ # @param self
+ #
+ # @endif
+ def __init__(self, consumer=None):
+ if consumer:
+ self._objref = consumer._objref
+ else:
+ self._objref = None
+
+
+ ##
+ # @if jp
+ #
+ # @brief 代入演算子
+ #
+ # @param self
+ # @param consumer 代入元
+ #
+ # @return 代入結果
+ #
+ # @else
+ #
+ # @brief Assignment operator
+ #
+ # @param self
+ # @param consumer Copy source.
+ #
+ # @endif
+ def equal(self, consumer):
+ self._objref = consumer._objref
+ return self
+
+
+ ##
+ # @if jp
+ #
+ # @brief CORBAオブジェクトをセットする
+ #
+ # 与えられたオブジェクトリファレンスは、ConsumerBase オブジェクト内に
+ # CORBA::Object_var 型として保持される。
+ #
+ # @param self
+ # @param obj CORBA オブジェクトのリファレンス
+ #
+ # @return obj が nil リファレンスの場合 false を返す。
+ #
+ # @else
+ #
+ # @brief Set CORBA Object
+ #
+ # The given CORBA Object is held as CORBA::Object_var type
+ #
+ # @param self
+ # @param obj Object reference of CORBA object
+ #
+ # @return If obj is nil reference, it returns false.
+ #
+ # @endif
+ def setObject(self, obj):
+ if CORBA.is_nil(obj):
+ return False
+
+ self._objref = obj
+ return True
+
+
+ ##
+ # @if jp
+ #
+ # @brief CORBAオブジェクトを取得する
+ #
+ # ConsumerBase オブジェクト内に CORBA::Object_var 型として保持されている
+ # オブジェクトリファレンスを取得する。
+ #
+ # @param self
+ #
+ # @return obj CORBA オブジェクトのリファレンス
+ #
+ # @else
+ #
+ # @brief Get CORBA Object
+ #
+ # @param self
+ #
+ # @return Object reference of CORBA object
+ #
+ # @endif
+ def getObject(self):
+ return self._objref
+
+
+ ##
+ # @if jp
+ #
+ # @brief CORBAオブジェクトの設定をクリアする
+ #
+ # 設定されている CORBA オブジェクトをクリアする。
+ # CORBAオブジェクトそのものに対しては何も操作しない。
+ #
+ # @param self
+ #
+ # @else
+ #
+ # @endif
+ def releaseObject(self):
+ self._objref = CORBA.Object._nil
+
+
+
+##
+# @if jp
+#
+# @class CorbaConsumer
+# @brief オブジェクトリファレンスを保持するプレースホルダクラス
+#
+# 引数で与えられた型のCORBAオブジェクトを保持する。
+# オブジェクトがセットされたときに、与えられた型で narrow されるので、
+# _ptr() で取得するリファレンスは、narrow 済みのリファレンスである。
+#
+# @since 0.4.0
+#
+# @else
+#
+# @class Consumer.CorbaConsumer
+# @brief Placeholder class to hold remote object reference.
+#
+# This class holds a type of object that given by parameter.
+# For internal use, _ptr type and _var type should be given as parameter.
+#
+# @since 0.4.0
+#
+# @endif
+class CorbaConsumer(CorbaConsumerBase):
+ """
+ """
+
+
+
+ ##
+ # @if jp
+ #
+ # @brief コンストラクタ
+ #
+ # @param self
+ # @param interfaceType このホルダが保持するオブジェクトの型
+ # (デフォルト値;None)
+ # @param consumer このホルダが保持するオブジェクト(デフォルト値;None)
+ #
+ # @else
+ #
+ # @brief Consructor
+ #
+ # @endif
+ def __init__(self, interfaceType=None, consumer=None):
+ if interfaceType:
+ self._interfaceType = interfaceType
+ else:
+ self._interfaceType = None
+
+ if consumer:
+ CorbaConsumerBase.__init__(self, consumer)
+ self._var = consumer._var
+ else:
+ CorbaConsumerBase.__init__(self)
+ self._var = None
+
+
+ ##
+ # @if jp
+ #
+ # @brief 代入演算子
+ #
+ # @param self
+ # @param consumer 代入元
+ #
+ # @return 代入結果
+ #
+ # @else
+ #
+ # @brief Assignment operator
+ #
+ # @param self
+ # @param consumer Copy source.
+ #
+ # @endif
+ def equal(self, consumer):
+ self._var = consumer._var
+
+
+ def __del__(self):
+ self.releaseObject()
+
+
+ ##
+ # @if jp
+ # @brief オブジェクトをセットする
+ #
+ # ConsumerBase のオーバーライド。CORBA::Object_var にオブジェクトをセット
+ # するとともに、パラメータの型で narrow したオブジェクトを保持する。
+ #
+ # @param self
+ # @param obj CORBA Objecct
+ #
+ # @return オブジェクト設定結果
+ # 設定対象オブジェクトが null の場合は false が返ってくる
+ #
+ # @else
+ # @brief Set Object
+ #
+ # Override function of ConsumerBase. This operation set an Object to
+ # CORBA:Object_var in the class, and this object is narrowed to
+ # given parameter and stored in.
+ #
+ # @param self
+ # @param obj CORBA Objecct
+ #
+ # @endif
+ def setObject(self, obj):
+ if not CorbaConsumerBase.setObject(self, obj):
+ self.releaseObject()
+ return False
+
+ if self._interfaceType:
+ self._var = obj._narrow(self._interfaceType)
+ else:
+ self._var = self._objref
+
+ if not CORBA.is_nil(self._var):
+ return True
+
+ self.releaseObject()
+ return False
+
+
+ ##
+ # @if jp
+ # @brief ObjectType 型のオブジェクトのリファレンスを取得
+ #
+ # ObjectType に narrow済みのオブジェクトのリファレンスを取得する。
+ # オブジェクトリファレンスを使用するには、setObject() でセット済みで
+ # なければならない。
+ # オブジェクトがセットされていなければ nil オブジェクトリファレンスが
+ # 返される。
+ #
+ # @param self
+ #
+ # @return ObjectType に narrow 済みのオブジェクトのリファレンス
+ #
+ # @else
+ # @brief Get Object reference narrowed as ObjectType
+ #
+ # This operation returns object reference narrowed as ObjectType.
+ # To use the returned object reference, reference have to be set by
+ # setObject().
+ # If object is not set, this operation returns nil object reference.
+ #
+ # @return The object reference narrowed as ObjectType
+ #
+ # @endif
+ def _ptr(self):
+ return self._var
+
+
+ ##
+ # @if jp
+ #
+ # @brief CORBAオブジェクトの設定をクリアする
+ #
+ # 設定されている CORBA オブジェクトをクリアする。
+ # CORBAオブジェクトそのものに対しては何も操作しない。
+ #
+ # @param self
+ #
+ # @else
+ #
+ # @endif
+ def releaseObject(self):
+ CorbaConsumerBase.releaseObject(self)
+ self._var = CORBA.Object._nil
Modified: trunk/OpenRTM-aist-Python/OpenRTM_aist/CorbaNaming.py
===================================================================
--- trunk/OpenRTM-aist-Python/OpenRTM_aist/CorbaNaming.py 2016-02-01 05:29:04 UTC (rev 642)
+++ trunk/OpenRTM-aist-Python/OpenRTM_aist/CorbaNaming.py 2016-02-01 08:37:55 UTC (rev 643)
@@ -1,1326 +1,1246 @@
-#!/usr/bin/env python
-# -*- coding: euc-jp -*-
-
-
-##
-# \file CorbaNaming.py
-# \brief CORBA naming service helper class
-# \author Noriaki Ando <n-ando at aist.go.jp> and Shinji Kurihara
-#
-# Copyright (C) 2006-2008
-# Noriaki Ando
-# Task-intelligence Research Group,
-# Intelligent Systems Research Institute,
-# National Institute of
-# Advanced Industrial Science and Technology (AIST), Japan
-# All rights reserved.
-
-import omniORB.CORBA as CORBA
-import CosNaming
-import string
-import sys
-import traceback
-
-##
-# @if jp
-# @class CorbaNaming
-# @brief CORBA Naming Service ヘルパークラス
-#
-# このクラスは、CosNaming::NamingContext に対するラッパークラスである。
-# CosNaming::NamingContext が持つオペレーションとほぼ同じ機能の
-# オペレーションを提供するとともに、ネームコンポーネント CosNaming::Name
-# の代わりに文字列による名前表現を受け付けるオペレーションも提供する。
-#
-# オブジェクトは生成時、あるいは生成直後に CORBA ネームサーバに接続し
-# 以後、このネームサーバのルートコンテキストに対して種々のオペレーション
-# を処理する。
-# 深い階層のネーミングコンテキストの作成やオブジェクトのバインドにおいて、
-# 途中のコンテキストが存在しない場合でも、強制的にコンテキストをバインド
-# し目的のコンテキストやオブジェクトのバインドを行うこともできる。
-#
-# @since 0.4.0
-#
-# @else
-# @class CorbaNaming
-# @brief CORBA Naming Service helper class
-#
-# This class is a wrapper class of CosNaming::NamingContext.
-# Almost the same operations which CosNaming::NamingContext has are
-# provided, and some operation allows string naming representation of
-# context and object instead of CosNaming::Name.
-#
-# The object of the class would connect to a CORBA naming server at
-# the instantiation or immediately after instantiation.
-# After that the object invokes operations to the root context of it.
-# This class realizes forced binding to deep NamingContext, without binding
-# intermediate NamingContexts explicitly.
-#
-# @since 0.4.0
-#
-# @endif
-class CorbaNaming:
- """
- """
-
-
-
- ##
- # @if jp
- #
- # @brief コンストラクタ
- #
- # @param self
- # @param orb ORB
- # @param name_server ネームサーバの名称(デフォルト値:None)
- #
- # @else
- #
- # @brief Consructor
- #
- # @endif
- def __init__(self, orb, name_server=None):
- self._orb = orb
- self._nameServer = ""
- self._rootContext = CosNaming.NamingContext._nil
- self._blLength = 100
-
- if name_server:
- self._nameServer = "corbaloc::" + name_server + "/NameService"
- try:
- obj = orb.string_to_object(self._nameServer)
- self._rootContext = obj._narrow(CosNaming.NamingContext)
- if CORBA.is_nil(self._rootContext):
- print "CorbaNaming: Failed to narrow the root naming context."
-
- except CORBA.ORB.InvalidName:
- self.__print_exception()
- print "Service required is invalid [does not exist]."
-
- return
-
-
- ##
- # @if jp
- #
- # @brief デストラクタ
- #
- # @param self
- #
- # @else
- #
- # @brief destructor
- #
- # @endif
- def __del__(self):
- return
-
-
- ##
- # @if jp
- #
- # @brief ネーミングサービスの初期化
- #
- # 指定されたネームサーバ上のネーミングサービスを初期化します。
- #
- # @param self
- # @param name_server ネームサーバの名称
- #
- # @else
- #
- # @endif
- def init(self, name_server):
- self._nameServer = "corbaloc::" + name_server + "/NameService"
- obj = self._orb.string_to_object(self._nameServer)
- self._rootContext = obj._narrow(CosNaming.NamingContext)
- if CORBA.is_nil(self._rootContext):
- raise MemoryError
-
- return
-
-
- ##
- # @if jp
- #
- # @brief ルートコンテキストが生存しているかを返す。
- #
- # ルートコンテキストが生存しているかのチェックを行う。
- #
- # @param self
- # @else
- # @brief Check on whether the root context is alive.
- # Check on whether the root context is alive.
- # @param self
- # @endif
- # bool CorbaNaming::isAlive()
- def isAlive(self):
- try:
- if self._rootContext._non_existent():
- return False
- return True
- except:
- self.__print_exception()
- return False
-
- return False
-
-
- ##
- # @if jp
- #
- # @brief Object を bind する
- #
- # CosNaming::bind() とほぼ同等の働きをするが、常に与えられたネームサーバの
- # ルートコンテキストに対してbind()が呼び出される点が異なる。
- #
- # Name <name> と Object <obj> を当該 NamingContext 上にバインドする。
- # c_n が n 番目の NameComponent をあらわすとすると、
- # name が n 個の NameComponent から成るとき、以下のように扱われる。
- #
- # cxt->bind(<c_1, c_2, ... c_n>, obj) は以下の操作と同等である。
- # cxt->resolve(<c_1, ... c_(n-1)>)->bind(<c_n>, obj)
- #
- # すなわち、1番目からn-1番目のコンテキストを解決し、n-1番目のコンテキスト
- # 上に name <n> として obj を bind する。
- # 名前解決に参加する <c_1, ... c_(n-1)> の NemingContext は、
- # bindContext() や rebindContext() で既にバインド済みでなければならない。
- # もし <c_1, ... c_(n-1)> の NamingContext が存在しない場合には、
- # NotFound 例外が発生する。
- #
- # ただし、強制バインドフラグ force が true の時は、<c_1, ... c_(n-1)>
- # が存在しない場合にも、再帰的にコンテキストをバインドしながら、
- # 最終的に obj を名前 name <c_n> にバインドする。
- #
- # いずれの場合でも、n-1番目のコンテキスト上に name<n> のオブジェクト
- # (Object あるいは コンテキスト) がバインドされていれば
- # AlreadyBound 例外が発生する。
- #
- # @param self
- # @param name_list オブジェクトに付ける名前の NameComponent
- # @param obj 関連付けられる Object
- # @param force trueの場合、途中のコンテキストを強制的にバインドする
- # (デフォルト値:None)
- #
- # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
- # @exception CannotProceed 何らかの理由で処理を継続できない。
- # @exception InvalidName 引数 name_list の名前が不正。
- # @exception AlreadyBound name <c_n> の Object がすでにバインドされている。
- #
- # @else
- #
- # @brief
- #
- # @endif
- def bind(self, name_list, obj, force=None):
- if force is None :
- force = True
-
- try:
- self._rootContext.bind(name_list, obj)
- except CosNaming.NamingContext.NotFound:
- if force:
- self.bindRecursive(self._rootContext, name_list, obj)
- else:
- raise
- except CosNaming.NamingContext.CannotProceed, err:
- if force:
- self.bindRecursive(err.cxt, err.rest_of_name, obj)
- else:
- raise
- except CosNaming.NamingContext.AlreadyBound:
- self._rootContext.rebind(name_list, obj)
-
-
- ##
- # @if jp
- #
- # @brief Object を bind する
- #
- # Object を bind する際に与える名前が文字列表現であること以外は、bind()
- # と同じである。bind(toName(string_name), obj) と等価。
- #
- # @param self
- # @param string_name オブジェクトに付ける名前の文字列表現
- # @param obj 関連付けられるオブジェクト
- # @param force trueの場合、途中のコンテキストを強制的にバインドする
- # (デフォルト値:true)
- #
- # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
- # @exception CannotProceed 何らかの理由で処理を継続できない。
- # @exception InvalidName 引数 string_name の名前が不正。
- # @exception AlreadyBound name <n> の Object がすでにバインドされている。
- #
- # @else
- #
- # @brief
- #
- # @endif
- def bindByString(self, string_name, obj, force=True):
- self.bind(self.toName(string_name), obj, force)
-
-
- ##
- # @if jp
- #
- # @brief 途中のコンテキストを bind しながら Object を bind する
- #
- # context で与えられた NamingContext に対して、name で指定された
- # ネームコンポーネント <c_1, ... c_(n-1)> を NamingContext として
- # 解決しながら、名前 <c_n> に対して obj を bind する。
- # もし、<c_1, ... c_(n-1)> に対応する NamingContext がない場合には
- # 新たな NamingContext をバインドする。
- #
- # 最終的に <c_1, c_2, ..., c_(n-1)> に対応する NamingContext が生成
- # または解決された上で、CosNaming::bind(<c_n>, object) が呼び出される。
- # このとき、すでにバインディングが存在すれば AlreadyBound例外が発生する。
- #
- # 途中のコンテキストを解決する過程で、解決しようとするコンテキストと
- # 同じ名前の NamingContext ではない Binding が存在する場合、
- # CannotProceed 例外が発生し処理を中止する。
- #
- # @param self
- # @param context bind を開始する NamingContext
- # @param name_list オブジェクトに付ける名前のネームコンポーネント
- # @param obj 関連付けられるオブジェクト
- #
- # @exception CannotProceed <c_1, ..., c_(n-1)> に対応する NamingContext
- # のうちひとつが、すでに NamingContext 以外の object にバインド
- # されており、処理を継続できない。
- # @exception InvalidName 名前 name_list が不正
- # @exception AlreadyBound name <c_n> にすでに何らかの object がバインド
- # されている。
- # @else
- #
- # @brief
- #
- # @endif
- def bindRecursive(self, context, name_list, obj):
- length = len(name_list)
- cxt = context
- for i in range(length):
- if i == length -1:
- try:
- cxt.bind(self.subName(name_list, i, i), obj)
- except CosNaming.NamingContext.AlreadyBound:
- cxt.rebind(self.subName(name_list, i, i), obj)
- return
- else:
- if self.objIsNamingContext(cxt):
- cxt = self.bindOrResolveContext(cxt,self.subName(name_list, i, i))
- else:
- raise CosNaming.NamingContext.CannotProceed(cxt, self.subName(name_list, i))
- return
-
-
- ##
- # @if jp
- #
- # @brief Object を rebind する
- #
- # name_list で指定された Binding がすでに存在する場合を除いて bind() と同じ
- # である。バインディングがすでに存在する場合には、新しいバインディングに
- # 置き換えられる。
- #
- # @param self
- # @param name_list オブジェクトに付ける名前の NameComponent
- # @param obj 関連付けられるオブジェクト
- # @param force trueの場合、途中のコンテキストを強制的にバインドする
- # (デフォルト値:true)
- #
- # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
- # @exception CannotProceed 何らかの理由で処理を継続できない。
- # @exception InvalidName 名前 name_list が不正
- #
- # @else
- #
- # @brief
- #
- # @endif
- def rebind(self, name_list, obj, force=True):
- if force is None:
- force = True
-
- try:
- self._rootContext.rebind(name_list, obj)
-
- except CosNaming.NamingContext.NotFound:
- if force:
- self.rebindRecursive(self._rootContext, name_list, obj)
- else:
- self.__print_exception()
- raise
-
- except CosNaming.NamingContext.CannotProceed, err:
- if force:
- self.rebindRecursive(err.cxt, err,rest_of_name, obj)
- else:
- self.__print_exception()
- raise
-
- return
-
-
- ##
- # @if jp
- #
- # @brief Object を rebind する
- #
- # Object を rebind する際に与える名前が文字列表現であること以外は rebind()
- # と同じである。rebind(toName(string_name), obj) と等価。
- #
- # @param self
- # @param string_name オブジェクトに付ける名前の文字列表現
- # @param obj 関連付けられるオブジェクト
- # @param force trueの場合、途中のコンテキストを強制的にバインドする
- # (デフォルト値:true)
- #
- # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
- # @exception CannotProceed 何らかの理由で処理を継続できない。
- # @exception InvalidName 引数 string_name の名前が不正。
- #
- # @else
- #
- # @brief
- #
- # @endif
- def rebindByString(self, string_name, obj, force=True):
- self.rebind(self.toName(string_name), obj, force)
-
- return
-
-
- ##
- # @if jp
- #
- # @brief 途中のコンテキストを bind しながら Object を rebind する
- #
- # name_list <c_n> で指定された NamingContext もしくは Object がすでに存在する
- # 場合を除いて bindRecursive() と同じである。
- #
- # name_list <c_n> で指定されたバインディングがすでに存在する場合には、
- # 新しいバインディングに置き換えられる。
- #
- # @param self
- # @param context bind を開始する NamingContext
- # @param name_list オブジェクトに付ける名前の NameComponent
- # @param obj 関連付けられるオブジェクト
- #
- # @exception CannotProceed 途中のコンテキストが解決できない。
- # @exception InvalidName 与えられた name_list が不正。
- #
- # @else
- #
- # @brief
- #
- # @endif
- def rebindRecursive(self, context, name_list, obj):
- length = len(name_list)
- for i in range(length):
- if i == length - 1:
- context.rebind(self.subName(name_list, i, i), obj)
- return
- else:
- if self.objIsNamingContext(context):
- try:
- context = context.bind_new_context(self.subName(name_list, i, i))
- except CosNaming.NamingContext.AlreadyBound:
- obj_ = context.resolve(self.subName(name_list, i, i))
- context = obj_._narrow(CosNaming.NamingContext)
- else:
- raise CosNaming.NamingContext.CannotProceed(context, self.subName(name_list, i))
- return
-
-
- ##
- # @if jp
- #
- # @brief NamingContext を bind する
- #
- # bind 対象として指定された引数 name が文字列の場合は bindByString() と、
- # それ以外の場合は bind() と同じである。
- #
- # @param self
- # @param name オブジェクトに付ける名前
- # @param name_cxt 関連付けられる NamingContext
- # @param force trueの場合、途中のコンテキストを強制的にバインドする
- # (デフォルト値:True)
- #
- # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
- # @exception CannotProceed 何らかの理由で処理を継続できない。
- # @exception InvalidName 引数 name の名前が不正。
- # @exception AlreadyBound name <c_n> の Object がすでにバインドされている。
- #
- # @else
- #
- # @brief
- #
- # @endif
- def bindContext(self, name, name_cxt, force=True):
- if isinstance(name, basestring):
- self.bind(self.toName(name), name_cxt, force)
- else:
- self.bind(name, name_cxt, force)
- return
-
-
- ##
- # @if jp
- #
- # @brief NamingContext を bind する
- #
- # bind されるオブジェクトが NamingContext であることを除いて
- # bindRecursive() と同じである。
- #
- # @param self
- # @param context bind を開始する NamingContext
- # @param name_list オブジェクトに付ける名前のネームコンポーネント
- # @param name_cxt 関連付けられる NamingContext
- #
- # @else
- #
- # @brief
- #
- # @endif
- def bindContextRecursive(self, context, name_list, name_cxt):
- self.bindRecursive(context, name_list, name_cxt)
- return
-
-
- ##
- # @if jp
- #
- # @brief NamingContext を rebind する
- #
- # bind 対象として指定された引数 name が文字列の場合は rebindByString() と、
- # それ以外の場合は rebind() と同じである。
- # どちらの場合もバインディングがすでに存在する場合には、
- # 新しいバインディングに置き換えられる。
- #
- # @param self
- # @param name オブジェクトに付ける名前のネームコンポーネント
- # @param name_cxt 関連付けられる NamingContext
- # @param force trueの場合、途中のコンテキストを強制的にバインドする
- # (デフォルト値:true)
- #
- # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
- # @exception CannotProceed 何らかの理由で処理を継続できない。
- # @exception InvalidName 引数 name の名前が不正。
- #
- # @else
- #
- # @endif
- def rebindContext(self, name, name_cxt, force=True):
- if isinstance(name, basestring):
- self.rebind(self.toName(name), name_cxt, force)
- else:
- self.rebind(name, name_cxt, force)
- return
-
-
- ##
- # @if jp
- #
- # @brief 途中のコンテキストを再帰的に rebind し NamingContext を rebind する #
- # bind されるオブジェクトが NamingContext であることを除いて
- # rebindRecursive() と同じである。
- #
- # @param self
- # @param context bind を開始する NamingContext
- # @param name_list オブジェクトに付ける名前の NameComponent
- # @param name_cxt 関連付けられる NamingContext
- #
- # @else
- #
- # @brief
- #
- # @endif
- def rebindContextRecursive(self, context, name_list, name_cxt):
- self.rebindRecursive(context, name_list, name_cxt)
- return
-
-
- ##
- # @if jp
- #
- # @brief Object を name から解決する
- #
- # name に bind されているオブジェクト参照を返す。
- # ネームコンポーネント <c_1, c_2, ... c_n> は再帰的に解決される。
- #
- # 引数 name に与えられた値が文字列の場合にはまず最初に toName() によって
- # NameComponent に変換される。
- #
- # CosNaming::resolve() とほぼ同等の働きをするが、常に与えられた
- # ネームサーバのルートコンテキストに対して resolve() が呼び出される点が
- # 異なる。
- #
- # @param self
- # @param name 解決すべきオブジェクトの名前のネームコンポーネント
- #
- # @return 解決されたオブジェクト参照
- #
- # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
- # @exception CannotProceed 何らかの理由で処理を継続できない。
- # @exception InvalidName 引数 name の名前が不正。
- #
- # @else
- #
- # @endif
- def resolve(self, name):
- if isinstance(name, basestring):
- name_ = self.toName(name)
- else:
- name_ = name
-
- try:
- obj = self._rootContext.resolve(name_)
- return obj
- except CosNaming.NamingContext.NotFound, ex:
- self.__print_exception()
- return None
-
-
- ##
- # @if jp
- #
- # @brief 指定された名前のオブジェクトの bind を解除する
- #
- # name に bind されているオブジェクト参照を解除する。
- # ネームコンポーネント <c_1, c_2, ... c_n> は再帰的に解決される。
- #
- # 引数 name に与えられた値が文字列の場合にはまず最初に toName() によって
- # NameComponent に変換される。
- #
- # CosNaming::unbind() とほぼ同等の働きをするが、常に与えられた
- # ネームサーバのルートコンテキストに対して unbind() が呼び出される点が
- # 異なる。
- #
- # @param self
- # @param name 削除するオブジェクトのネームコンポーネント
- #
- # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
- # @exception CannotProceed 何らかの理由で処理を継続できない。
- # @exception InvalidName 引数 name の名前が不正。
- #
- # @else
- #
- # @endif
- # void unbind(const CosNaming::Name& name)
- # throw(NotFound, CannotProceed, InvalidName);
- def unbind(self, name):
- if isinstance(name, basestring):
- name_ = self.toName(name)
- else:
- name_ = name
-
- try:
- self._rootContext.unbind(name_)
- except:
- self.__print_exception()
-
- return
-
-
- ##
- # @if jp
- #
- # @brief 新しいコンテキストを生成する
- #
- # 与えられたネームサーバ上で生成された NamingContext を返す。
- # 返された NamingContext は bind されていない。
- #
- # @param self
- #
- # @return 生成された新しい NamingContext
- #
- # @else
- #
- # @endif
- def newContext(self):
- return self._rootContext.new_context()
-
-
- ##
- # @if jp
- #
- # @brief 新しいコンテキストを bind する
- #
- # 与えられた name に対して新しいコンテキストをバインドする。
- # 生成された NamingContext はネームサーバ上で生成されたものである。
- #
- # 引数 name に与えられた値が文字列の場合にはまず最初に toName() によって
- # NameComponent に変換される。
- #
- # @param self
- # @param name NamingContextに付ける名前のネームコンポーネント
- # @param force trueの場合、途中のコンテキストを強制的にバインドする
- # (デフォルト値:true)
- #
- # @return 生成された新しい NamingContext
- #
- # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
- # @exception CannotProceed 何らかの理由で処理を継続できない。
- # @exception InvalidName 引数 name の名前が不正。
- # @exception AlreadyBound name <n> の Object がすでにバインドされている。
- #
- # @else
- #
- # @endif
- def bindNewContext(self, name, force=True):
- if force is None:
- force = True
-
- if isinstance(name, basestring):
- name_ = self.toName(name)
- else:
- name_ = name
-
- try:
- return self._rootContext.bind_new_context(name_)
- except CosNaming.NamingContext.NotFound:
- if force:
- self.bindRecursive(self._rootContext, name_, self.newContext())
- else:
- self.__print_exception()
- raise
- except CosNaming.NamingContext.CannotProceed, err:
- if force:
- self.bindRecursive(err.cxt, err.rest_of_name, self.newContext())
- else:
- self.__print_exception()
- raise
- return None
-
-
- ##
- # @if jp
- #
- # @brief NamingContext を非アクティブ化する
- #
- # context で指定された NamingContext を非アクティブ化する。
- # context に他のコンテキストがバインドされている場合は NotEmpty 例外が
- # 発生する。
- #
- # @param self
- # @param context 非アクティブ化する NamingContext
- #
- # @exception NotEmpty 対象context に他のコンテキストがバインドされている。
- #
- # @else
- #
- # @else
- #
- # @brief Destroy the naming context
- #
- # Delete the specified naming context.
- # any bindings should be <unbind> in which the given context is bound to
- # some names before invoking <destroy> operation on it.
- #
- # @param context NamingContext which is destroied.
- #
- # @exception NotEmpty
- #
- # @else
- #
- # @endif
- def destroy(self, context):
- context.destroy()
-
-
- ##
- # @if jp
- # @brief NamingContext を再帰的に下って非アクティブ化する
- #
- # context で与えられた NamingContext に対して、name で指定された
- # ネームコンポーネント <c_1, ... c_(n-1)> を NamingContext として
- # 解決しながら、名前 <c_n> に対して 非アクティブ化を行う。
- #
- # @param self
- # @param context 非アクティブ化する NamingContext
- #
- # @exception NotEmpty 対象context に他のコンテキストがバインドされている。
- # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
- # @exception CannotProceed 何らかの理由で処理を継続できない。
- # @exception InvalidName 引数 name の名前が不正。
- #
- # @else
- # @brief Destroy the naming context recursively
- # @endif
- def destroyRecursive(self, context):
- cont = True
- bl = []
- bi = 0
- bl, bi = context.list(self._blLength)
- while cont:
- for i in range(len(bl)):
- if bl[i].binding_type == CosNaming.ncontext:
- obj = context.resolve(bl[i].binding_name)
- next_context = obj._narrow(CosNaming.NamingContext)
-
- self.destroyRecursive(next_context)
- context.unbind(bl[i].binding_name)
- next_context.destroy()
- elif bl[i].binding_type == CosNaming.nobject:
- context.unbind(bl[i].binding_name)
- else:
- assert(0)
- if CORBA.is_nil(bi):
- cont = False
- else:
- bi.next_n(self._blLength, bl)
-
- if not (CORBA.is_nil(bi)):
- bi.destroy()
- return
-
-
- ##
- # @if jp
- # @brief すべての Binding を削除する
- #
- # 登録されている全てのBinding を削除する。
- #
- # @param self
- #
- # @else
- # @brief Destroy all binding
- # @endif
- def clearAll(self):
- self.destroyRecursive(self._rootContext)
- return
-
-
- ##
- # @if jp
- # @brief 与えられた NamingContext の Binding を取得する
- #
- # 指定された NamingContext の Binding を取得する。
- #
- # @param self
- # @param name_cxt Binding 取得対象 NamingContext
- # @param how_many Binding を取得する階層の深さ
- # @param rbl 取得した Binding を保持するホルダ
- # @param rbi 取得した Binding をたどるためのイテレータ
- #
- # @else
- # @endif
- def list(self, name_cxt, how_many, rbl, rbi):
- bl, bi = name_cxt.list(how_many)
-
- for i in bl:
- rbl.append(bl)
-
- rbi.append(bi)
-
-
- #============================================================
- # interface of NamingContext
- #============================================================
-
- ##
- # @if jp
- # @brief 与えられた NameComponent の文字列表現を返す
- #
- # 指定された NameComponent を文字に変換する。
- #
- # @param self
- # @param name_list 変換対象 NameComponent
- #
- # @return 文字列変換結果
- #
- # @exception InvalidName 引数 name_list の名前が不正。
- #
- # @else
- # @brief Get string representation of given NameComponent
- # @endif
- def toString(self, name_list):
- if len(name_list) == 0:
- raise CosNaming.NamingContext.InvalidName
-
- slen = self.getNameLength(name_list)
- string_name = [""]
- self.nameToString(name_list, string_name, slen)
-
- return string_name[0]
-
-
- ##
- # @if jp
- # @brief 与えられた文字列表現を NameComponent に分解する
- #
- # 指定された文字列を NameComponent に変換する。
- #
- # @param self
- # @param sname 変換対象文字列
- #
- # @return NameComponent 変換結果
- #
- # @exception InvalidName 引数 sname が不正。
- #
- # @else
- # @brief Get NameComponent from gien string name representation
- # @endif
- def toName(self, sname):
- if not sname:
- raise CosNaming.NamingContext.InvalidName
-
- string_name = sname
- name_comps = []
-
- nc_length = 0
- nc_length = self.split(string_name, "/", name_comps)
-
- if not (nc_length > 0):
- raise CosNaming.NamingContext.InvalidName
-
- name_list = [CosNaming.NameComponent("","") for i in range(nc_length)]
-
- for i in range(nc_length):
- pos = string.rfind(name_comps[i][0:],".")
- if pos == -1:
- name_list[i].id = name_comps[i]
- name_list[i].kind = ""
- else:
- name_list[i].id = name_comps[i][0:pos]
- name_list[i].kind = name_comps[i][(pos+1):]
-
- return name_list
-
-
- ##
- # @if jp
- # @brief 与えられた addr と string_name から URL表現を取得する
- #
- # 指定されたアドレスと名称をURLに変換する。
- #
- # @param self
- # @param addr 変換対象アドレス
- # @param string_name 変換対象名称
- #
- # @return URL 変換結果
- #
- # @exception InvalidAddress 引数 addr が不正。
- # @exception InvalidName 引数 string_name が不正。
- #
- # @else
- # @brief Get URL representation from given addr and string_name
- # @endif
- def toUrl(self, addr, string_name):
- return self._rootContext.to_url(addr, string_name)
-
-
- ##
- # @if jp
- # @brief 与えられた文字列表現を resolve しオブジェクトを返す
- #
- # 指定された文字列表現をresolveし,オブジェクトを取得する。
- #
- # @param self
- # @param string_name 取得対象オブジェクト文字列表現
- #
- # @return 解決されたオブジェクト
- #
- # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
- # @exception CannotProceed 何らかの理由で処理を継続できない。
- # @exception InvalidName 引数 name の名前が不正。
- # @exception AlreadyBound name <n> の Object がすでにバインドされている。
- #
- # @else
- # @brief Resolve from name of string representation and get object
- # @endif
- def resolveStr(self, string_name):
- return self.resolve(self.toName(string_name))
-
-
- #============================================================
- # Find functions
- #============================================================
-
- ##
- # @if jp
- #
- # @brief オブジェクトの名前をバインドまたは解決する
- #
- # 指定されたコンテキストに対してオブジェクトを NameComponent で指定された
- # 位置にバインドする。
- # 同一箇所に既に他の要素がバインド済みの場合は、既存のバインド済み要素を
- # 取得する。
- #
- # @param self
- # @param context bind もしくは resole 対象コンテキスト
- # @param name_list オブジェクトに付ける名前の NameComponent
- # @param obj 関連付けられる Object
- #
- # @return NameComponent で指定された位置にバインドされているオブジェクト
- #
- # @else
- # @brief Bind of resolve the given name component
- # @endif
- def bindOrResolve(self, context, name_list, obj):
- try:
- context.bind_context(name_list, obj)
- return obj
- except CosNaming.NamingContext.AlreadyBound:
- obj = context.resolve(name_list)
- return obj
- return CORBA.Object._nil
-
-
- ##
- # @if jp
- #
- # @brief コンテキストの名前をバインドまたは解決する
- #
- # 指定されたコンテキストに対して Contextを NameComponent で指定された位置に
- # バインドする。
- # Context が空の場合は新規コンテキストを生成してバインドする。
- # 同一箇所に既に他の要素がバインド済みの場合は、既存のバインド済み要素を
- # 取得する。
- #
- # @param self
- # @param context bind もしくは resole 対象コンテキスト
- # @param name_list コンテキストに付ける名前の NameComponent
- # @param new_context 関連付けられる Context(デフォルト値:None)
- #
- # @return NameComponent で指定された位置にバインドされているContext
- #
- # @else
- # @brief Bind of resolve the given name component
- # @endif
- def bindOrResolveContext(self, context, name_list, new_context=None):
- if new_context is None:
- new_cxt = self.newContext()
- else:
- new_cxt = new_context
-
- obj = self.bindOrResolve(context, name_list, new_cxt)
- return obj._narrow(CosNaming.NamingContext)
-
-
- ##
- # @if jp
- # @brief ネームサーバの名前を取得する
- #
- # 設定したネームサーバの名前を取得する。
- #
- # @param self
- #
- # @return ネームサーバの名前
- #
- # @else
- # @brief Get the name of naming server
- # @endif
- def getNameServer(self):
- return self._nameServer
-
-
- ##
- # @if jp
- # @brief ルートコンテキストを取得する
- #
- # 設定したネームサーバのルートコンテキストを取得する。
- #
- # @param self
- #
- # @return ネームサーバのルートコンテキスト
- #
- # @else
- # @brief Get the root context
- # @endif
- def getRootContext(self):
- return self._rootContext
-
-
- ##
- # @if jp
- # @brief オブジェクトがネーミングコンテキストか判別する
- #
- # 指定した要素がネーミングコンテキストか判別する
- #
- # @param self
- # @param obj 判別対象要素
- #
- # @return 判別結果(ネーミングコンテキスト:true、それ以外:false)
- #
- # @else
- # @brief Whether the object is NamingContext
- # @endif
- def objIsNamingContext(self, obj):
- nc = obj._narrow(CosNaming.NamingContext)
- if CORBA.is_nil(nc):
- return False
- else:
- return True
-
-
- ##
- # @if jp
- # @brief 与えられた名前がネーミングコンテキストかどうか判別する
- #
- # NameComponent もしくは文字列で指定した要素がネーミングコンテキストか
- # 判別する
- #
- # @param self
- # @param name_list 判別対象
- #
- # @return 判別結果(ネーミングコンテキスト:true、それ以外:false)
- #
- # @else
- # @brief Whether the given name component is NamingContext
- # @endif
- def nameIsNamingContext(self, name_list):
- return self.objIsNamingContext(self.resolve(name_list))
-
-
- ##
- # @if jp
- # @brief ネームコンポーネントの部分を返す
- #
- # 指定された範囲のネームコンポーネントを取得する。
- # 終了位置が指定されていない場合は、最後の要素を除いたネームコンポーネント
- # を返す。
- #
- # @param self
- # @param name_list 検索対象NameComponent
- # @param begin 取得範囲開始位置
- # @param end 取得範囲終了位置(デフォルト値:None)
- #
- # @return NameComponent 取得結果
- #
- # @else
- # @brief Get subset of given name component
- # @endif
- def subName(self, name_list, begin, end = None):
- if end is None or end < 0:
- end = len(name_list) - 1
-
- sub_len = end - (begin -1)
- objId = ""
- kind = ""
-
- sub_name = []
- for i in range(sub_len):
- sub_name.append(name_list[begin + i])
-
- return sub_name
-
-
- ##
- # @if jp
- # @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・・・
- # という形式で取得できる。
- # 取得した文字列の長さが指定した長さ以上の場合は、
- # 指定した長さで切り捨てられる。
- #
- # @param self
- # @param name_list 取得対象NameComponent
- # @param string_name 取得結果文字列
- # @param slen 取得対象文字列最大値
- #
- # @else
- # @brief Get string representation of name component
- # @endif
- def nameToString(self, name_list, string_name, slen):
- for i in range(len(name_list)):
- for id_ in name_list[i].id:
- if id_ == "/" or id_ == "." or id_ == "\\":
- string_name[0] += "\\"
- string_name[0] += id_
-
- if name_list[i].id == "" or name_list[i].kind != "":
- string_name[0] += "."
-
- for kind_ in name_list[i].kind:
- if kind_ == "/" or kind_ == "." or kind_ == "\\":
- string_name[0] += "\\"
- string_name[0] += kind_
-
- string_name[0] += "/"
-
-
- ##
- # @if jp
- # @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・・・
- # という形式で取得できる。
- #
- # @param self
- # @param name_list 取得対象NameComponent
- #
- # @return 指定したネームコンポーネントの文字列長さ
- #
- # @else
- # @brief Get string length of the name component's string representation
- # @endif
- def getNameLength(self, name_list):
- slen = 0
-
- for i in range(len(name_list)):
- for id_ in name_list[i].id:
- if id_ == "/" or id_ == "." or id_ == "\\":
- slen += 1
- slen += 1
- if name_list[i].id == "" or name_list[i].kind == "":
- slen += 1
-
- for kind_ in name_list[i].kind:
- if kind_ == "/" or kind_ == "." or kind_ == "\\":
- slen += 1
- slen += 1
-
- slen += 1
-
- return slen
-
-
- ##
- # @if jp
- # @brief 文字列の分割
- #
- # 文字列を指定したデリミタで分割する。
- #
- # @param self
- # @param input 分割対象文字列
- # @param delimiter 分割用デリミタ
- # @param results 分割結果
- #
- # @return 分割した文字列の要素数
- #
- # @else
- # @brief Split of string
- # @endif
- def split(self, input, delimiter, results):
- delim_size = len(delimiter)
- found_pos = 0
- begin_pos = 0
- pre_pos = 0
- substr_size = 0
-
- if input[0:delim_size] == delimiter:
- begin_pos = delim_size
- pre_pos = delim_size
-
- while 1:
- found_pos = string.find(input[begin_pos:],delimiter)
- if found_pos == -1:
- results.append(input[pre_pos:])
- break
-
- if found_pos > 0 and input[found_pos + begin_pos - 1] == "\\":
- begin_pos += found_pos + delim_size
- else:
- substr_size = found_pos + (begin_pos - pre_pos)
- if substr_size > 0:
- results.append(input[pre_pos:(pre_pos+substr_size)])
- begin_pos += found_pos + delim_size
- pre_pos = begin_pos
-
- return len(results)
-
-
- ##
- # @if jp
- #
- # @brief 例外情報出力
- # 例外情報を出力する。
- #
- # @else
- #
- # @brief Print exception information
- # Print exception information
- # @endif
- def __print_exception(self):
- if sys.version_info[0:3] >= (2, 4, 0):
- print traceback.format_exc()
- else:
- _exc_list = traceback.format_exception(*sys.exc_info())
- _exc_str = "".join(_exc_list)
- 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
+#!/usr/bin/env python
+# -*- coding: euc-jp -*-
+
+
+##
+# \file CorbaNaming.py
+# \brief CORBA naming service helper class
+# \author Noriaki Ando <n-ando at aist.go.jp> and Shinji Kurihara
+#
+# Copyright (C) 2006-2008
+# Noriaki Ando
+# Task-intelligence Research Group,
+# Intelligent Systems Research Institute,
+# National Institute of
+# Advanced Industrial Science and Technology (AIST), Japan
+# All rights reserved.
+
+import omniORB.CORBA as CORBA
+import CosNaming
+import string
+import sys
+import traceback
+
+##
+# @if jp
+# @class CorbaNaming
+# @brief CORBA Naming Service ヘルパークラス
+#
+# このクラスは、CosNaming::NamingContext に対するラッパークラスである。
+# CosNaming::NamingContext が持つオペレーションとほぼ同じ機能の
+# オペレーションを提供するとともに、ネームコンポーネント CosNaming::Name
+# の代わりに文字列による名前表現を受け付けるオペレーションも提供する。
+#
+# オブジェクトは生成時、あるいは生成直後に CORBA ネームサーバに接続し
+# 以後、このネームサーバのルートコンテキストに対して種々のオペレーション
+# を処理する。
+# 深い階層のネーミングコンテキストの作成やオブジェクトのバインドにおいて、
+# 途中のコンテキストが存在しない場合でも、強制的にコンテキストをバインド
+# し目的のコンテキストやオブジェクトのバインドを行うこともできる。
+#
+# @since 0.4.0
+#
+# @else
+# @class CorbaNaming
+# @brief CORBA Naming Service helper class
+#
+# This class is a wrapper class of CosNaming::NamingContext.
+# Almost the same operations which CosNaming::NamingContext has are
+# provided, and some operation allows string naming representation of
+# context and object instead of CosNaming::Name.
+#
+# The object of the class would connect to a CORBA naming server at
+# the instantiation or immediately after instantiation.
+# After that the object invokes operations to the root context of it.
+# This class realizes forced binding to deep NamingContext, without binding
+# intermediate NamingContexts explicitly.
+#
+# @since 0.4.0
+#
+# @endif
+class CorbaNaming:
+ """
+ """
+
+
+
+ ##
+ # @if jp
+ #
+ # @brief コンストラクタ
+ #
+ # @param self
+ # @param orb ORB
+ # @param name_server ネームサーバの名称(デフォルト値:None)
+ #
+ # @else
+ #
+ # @brief Consructor
+ #
+ # @endif
+ def __init__(self, orb, name_server=None):
+ self._orb = orb
+ self._nameServer = ""
+ self._rootContext = CosNaming.NamingContext._nil
+ self._blLength = 100
+
+ if name_server:
+ self._nameServer = "corbaloc::" + name_server + "/NameService"
+ try:
+ obj = orb.string_to_object(self._nameServer)
+ self._rootContext = obj._narrow(CosNaming.NamingContext)
+ if CORBA.is_nil(self._rootContext):
+ print "CorbaNaming: Failed to narrow the root naming context."
+
+ except CORBA.ORB.InvalidName:
+ self.__print_exception()
+ print "Service required is invalid [does not exist]."
+
+ return
+
+
+ ##
+ # @if jp
+ #
+ # @brief デストラクタ
+ #
+ # @param self
+ #
+ # @else
+ #
+ # @brief destructor
+ #
+ # @endif
+ def __del__(self):
+ return
+
+
+ ##
+ # @if jp
+ #
+ # @brief ネーミングサービスの初期化
+ #
+ # 指定されたネームサーバ上のネーミングサービスを初期化します。
+ #
+ # @param self
+ # @param name_server ネームサーバの名称
+ #
+ # @else
+ #
+ # @endif
+ def init(self, name_server):
+ self._nameServer = "corbaloc::" + name_server + "/NameService"
+ obj = self._orb.string_to_object(self._nameServer)
+ self._rootContext = obj._narrow(CosNaming.NamingContext)
+ if CORBA.is_nil(self._rootContext):
+ raise MemoryError
+
+ return
+
+
+ ##
+ # @if jp
+ #
+ # @brief ルートコンテキストが生存しているかを返す。
+ #
+ # ルートコンテキストが生存しているかのチェックを行う。
+ #
+ # @param self
+ # @else
+ # @brief Check on whether the root context is alive.
+ # Check on whether the root context is alive.
+ # @param self
+ # @endif
+ # bool CorbaNaming::isAlive()
+ def isAlive(self):
+ try:
+ if self._rootContext._non_existent():
+ return False
+ return True
+ except:
+ self.__print_exception()
+ return False
+
+ return False
+
+
+ ##
+ # @if jp
+ #
+ # @brief Object を bind する
+ #
+ # CosNaming::bind() とほぼ同等の働きをするが、常に与えられたネームサーバの
+ # ルートコンテキストに対してbind()が呼び出される点が異なる。
+ #
+ # Name <name> と Object <obj> を当該 NamingContext 上にバインドする。
+ # c_n が n 番目の NameComponent をあらわすとすると、
+ # name が n 個の NameComponent から成るとき、以下のように扱われる。
+ #
+ # cxt->bind(<c_1, c_2, ... c_n>, obj) は以下の操作と同等である。
+ # cxt->resolve(<c_1, ... c_(n-1)>)->bind(<c_n>, obj)
+ #
+ # すなわち、1番目からn-1番目のコンテキストを解決し、n-1番目のコンテキスト
+ # 上に name <n> として obj を bind する。
+ # 名前解決に参加する <c_1, ... c_(n-1)> の NemingContext は、
+ # bindContext() や rebindContext() で既にバインド済みでなければならない。
+ # もし <c_1, ... c_(n-1)> の NamingContext が存在しない場合には、
+ # NotFound 例外が発生する。
+ #
+ # ただし、強制バインドフラグ force が true の時は、<c_1, ... c_(n-1)>
+ # が存在しない場合にも、再帰的にコンテキストをバインドしながら、
+ # 最終的に obj を名前 name <c_n> にバインドする。
+ #
+ # いずれの場合でも、n-1番目のコンテキスト上に name<n> のオブジェクト
+ # (Object あるいは コンテキスト) がバインドされていれば
+ # AlreadyBound 例外が発生する。
+ #
+ # @param self
+ # @param name_list オブジェクトに付ける名前の NameComponent
+ # @param obj 関連付けられる Object
+ # @param force trueの場合、途中のコンテキストを強制的にバインドする
+ # (デフォルト値:None)
+ #
+ # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
+ # @exception CannotProceed 何らかの理由で処理を継続できない。
+ # @exception InvalidName 引数 name_list の名前が不正。
+ # @exception AlreadyBound name <c_n> の Object がすでにバインドされている。
+ #
+ # @else
+ #
+ # @brief
+ #
+ # @endif
+ def bind(self, name_list, obj, force=None):
+ if force is None :
+ force = True
+
+ try:
+ self._rootContext.bind(name_list, obj)
+ except CosNaming.NamingContext.NotFound:
+ if force:
+ self.bindRecursive(self._rootContext, name_list, obj)
+ else:
+ raise
+ except CosNaming.NamingContext.CannotProceed, err:
+ if force:
+ self.bindRecursive(err.cxt, err.rest_of_name, obj)
+ else:
+ raise
+ except CosNaming.NamingContext.AlreadyBound:
+ self._rootContext.rebind(name_list, obj)
+
+
+ ##
+ # @if jp
+ #
+ # @brief Object を bind する
+ #
+ # Object を bind する際に与える名前が文字列表現であること以外は、bind()
+ # と同じである。bind(toName(string_name), obj) と等価。
+ #
+ # @param self
+ # @param string_name オブジェクトに付ける名前の文字列表現
+ # @param obj 関連付けられるオブジェクト
+ # @param force trueの場合、途中のコンテキストを強制的にバインドする
+ # (デフォルト値:true)
+ #
+ # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
+ # @exception CannotProceed 何らかの理由で処理を継続できない。
+ # @exception InvalidName 引数 string_name の名前が不正。
+ # @exception AlreadyBound name <n> の Object がすでにバインドされている。
+ #
+ # @else
+ #
+ # @brief
+ #
+ # @endif
+ def bindByString(self, string_name, obj, force=True):
+ self.bind(self.toName(string_name), obj, force)
+
+
+ ##
+ # @if jp
+ #
+ # @brief 途中のコンテキストを bind しながら Object を bind する
+ #
+ # context で与えられた NamingContext に対して、name で指定された
+ # ネームコンポーネント <c_1, ... c_(n-1)> を NamingContext として
+ # 解決しながら、名前 <c_n> に対して obj を bind する。
+ # もし、<c_1, ... c_(n-1)> に対応する NamingContext がない場合には
+ # 新たな NamingContext をバインドする。
+ #
+ # 最終的に <c_1, c_2, ..., c_(n-1)> に対応する NamingContext が生成
+ # または解決された上で、CosNaming::bind(<c_n>, object) が呼び出される。
+ # このとき、すでにバインディングが存在すれば AlreadyBound例外が発生する。
+ #
+ # 途中のコンテキストを解決する過程で、解決しようとするコンテキストと
+ # 同じ名前の NamingContext ではない Binding が存在する場合、
+ # CannotProceed 例外が発生し処理を中止する。
+ #
+ # @param self
+ # @param context bind を開始する NamingContext
+ # @param name_list オブジェクトに付ける名前のネームコンポーネント
+ # @param obj 関連付けられるオブジェクト
+ #
+ # @exception CannotProceed <c_1, ..., c_(n-1)> に対応する NamingContext
+ # のうちひとつが、すでに NamingContext 以外の object にバインド
+ # されており、処理を継続できない。
+ # @exception InvalidName 名前 name_list が不正
+ # @exception AlreadyBound name <c_n> にすでに何らかの object がバインド
+ # されている。
+ # @else
+ #
+ # @brief
+ #
+ # @endif
+ def bindRecursive(self, context, name_list, obj):
+ length = len(name_list)
+ cxt = context
+ for i in range(length):
+ if i == length -1:
+ try:
+ cxt.bind(self.subName(name_list, i, i), obj)
+ except CosNaming.NamingContext.AlreadyBound:
+ cxt.rebind(self.subName(name_list, i, i), obj)
+ return
+ else:
+ if self.objIsNamingContext(cxt):
+ cxt = self.bindOrResolveContext(cxt,self.subName(name_list, i, i))
+ else:
+ raise CosNaming.NamingContext.CannotProceed(cxt, self.subName(name_list, i))
+ return
+
+
+ ##
+ # @if jp
+ #
+ # @brief Object を rebind する
+ #
+ # name_list で指定された Binding がすでに存在する場合を除いて bind() と同じ
+ # である。バインディングがすでに存在する場合には、新しいバインディングに
+ # 置き換えられる。
+ #
+ # @param self
+ # @param name_list オブジェクトに付ける名前の NameComponent
+ # @param obj 関連付けられるオブジェクト
+ # @param force trueの場合、途中のコンテキストを強制的にバインドする
+ # (デフォルト値:true)
+ #
+ # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
+ # @exception CannotProceed 何らかの理由で処理を継続できない。
+ # @exception InvalidName 名前 name_list が不正
+ #
+ # @else
+ #
+ # @brief
+ #
+ # @endif
+ def rebind(self, name_list, obj, force=True):
+ if force is None:
+ force = True
+
+ try:
+ self._rootContext.rebind(name_list, obj)
+
+ except CosNaming.NamingContext.NotFound:
+ if force:
+ self.rebindRecursive(self._rootContext, name_list, obj)
+ else:
+ self.__print_exception()
+ raise
+
+ except CosNaming.NamingContext.CannotProceed, err:
+ if force:
+ self.rebindRecursive(err.cxt, err,rest_of_name, obj)
+ else:
+ self.__print_exception()
+ raise
+
+ return
+
+
+ ##
+ # @if jp
+ #
+ # @brief Object を rebind する
+ #
+ # Object を rebind する際に与える名前が文字列表現であること以外は rebind()
+ # と同じである。rebind(toName(string_name), obj) と等価。
+ #
+ # @param self
+ # @param string_name オブジェクトに付ける名前の文字列表現
+ # @param obj 関連付けられるオブジェクト
+ # @param force trueの場合、途中のコンテキストを強制的にバインドする
+ # (デフォルト値:true)
+ #
+ # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
+ # @exception CannotProceed 何らかの理由で処理を継続できない。
+ # @exception InvalidName 引数 string_name の名前が不正。
+ #
+ # @else
+ #
+ # @brief
+ #
+ # @endif
+ def rebindByString(self, string_name, obj, force=True):
+ self.rebind(self.toName(string_name), obj, force)
+
+ return
+
+
+ ##
+ # @if jp
+ #
+ # @brief 途中のコンテキストを bind しながら Object を rebind する
+ #
+ # name_list <c_n> で指定された NamingContext もしくは Object がすでに存在する
+ # 場合を除いて bindRecursive() と同じである。
+ #
+ # name_list <c_n> で指定されたバインディングがすでに存在する場合には、
+ # 新しいバインディングに置き換えられる。
+ #
+ # @param self
+ # @param context bind を開始する NamingContext
+ # @param name_list オブジェクトに付ける名前の NameComponent
+ # @param obj 関連付けられるオブジェクト
+ #
+ # @exception CannotProceed 途中のコンテキストが解決できない。
+ # @exception InvalidName 与えられた name_list が不正。
+ #
+ # @else
+ #
+ # @brief
+ #
+ # @endif
+ def rebindRecursive(self, context, name_list, obj):
+ length = len(name_list)
+ for i in range(length):
+ if i == length - 1:
+ context.rebind(self.subName(name_list, i, i), obj)
+ return
+ else:
+ if self.objIsNamingContext(context):
+ try:
+ context = context.bind_new_context(self.subName(name_list, i, i))
+ except CosNaming.NamingContext.AlreadyBound:
+ obj_ = context.resolve(self.subName(name_list, i, i))
+ context = obj_._narrow(CosNaming.NamingContext)
+ else:
+ raise CosNaming.NamingContext.CannotProceed(context, self.subName(name_list, i))
+ return
+
+
+ ##
+ # @if jp
+ #
+ # @brief NamingContext を bind する
+ #
+ # bind 対象として指定された引数 name が文字列の場合は bindByString() と、
+ # それ以外の場合は bind() と同じである。
+ #
+ # @param self
+ # @param name オブジェクトに付ける名前
+ # @param name_cxt 関連付けられる NamingContext
+ # @param force trueの場合、途中のコンテキストを強制的にバインドする
+ # (デフォルト値:True)
+ #
+ # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
+ # @exception CannotProceed 何らかの理由で処理を継続できない。
+ # @exception InvalidName 引数 name の名前が不正。
+ # @exception AlreadyBound name <c_n> の Object がすでにバインドされている。
+ #
+ # @else
+ #
+ # @brief
+ #
+ # @endif
+ def bindContext(self, name, name_cxt, force=True):
+ if isinstance(name, basestring):
+ self.bind(self.toName(name), name_cxt, force)
+ else:
+ self.bind(name, name_cxt, force)
+ return
+
+
+ ##
+ # @if jp
+ #
+ # @brief NamingContext を bind する
+ #
+ # bind されるオブジェクトが NamingContext であることを除いて
+ # bindRecursive() と同じである。
+ #
+ # @param self
+ # @param context bind を開始する NamingContext
+ # @param name_list オブジェクトに付ける名前のネームコンポーネント
+ # @param name_cxt 関連付けられる NamingContext
+ #
+ # @else
+ #
+ # @brief
+ #
+ # @endif
+ def bindContextRecursive(self, context, name_list, name_cxt):
+ self.bindRecursive(context, name_list, name_cxt)
+ return
+
+
+ ##
+ # @if jp
+ #
+ # @brief NamingContext を rebind する
+ #
+ # bind 対象として指定された引数 name が文字列の場合は rebindByString() と、
+ # それ以外の場合は rebind() と同じである。
+ # どちらの場合もバインディングがすでに存在する場合には、
+ # 新しいバインディングに置き換えられる。
+ #
+ # @param self
+ # @param name オブジェクトに付ける名前のネームコンポーネント
+ # @param name_cxt 関連付けられる NamingContext
+ # @param force trueの場合、途中のコンテキストを強制的にバインドする
+ # (デフォルト値:true)
+ #
+ # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
+ # @exception CannotProceed 何らかの理由で処理を継続できない。
+ # @exception InvalidName 引数 name の名前が不正。
+ #
+ # @else
+ #
+ # @endif
+ def rebindContext(self, name, name_cxt, force=True):
+ if isinstance(name, basestring):
+ self.rebind(self.toName(name), name_cxt, force)
+ else:
+ self.rebind(name, name_cxt, force)
+ return
+
+
+ ##
+ # @if jp
+ #
+ # @brief 途中のコンテキストを再帰的に rebind し NamingContext を rebind する #
+ # bind されるオブジェクトが NamingContext であることを除いて
+ # rebindRecursive() と同じである。
+ #
+ # @param self
+ # @param context bind を開始する NamingContext
+ # @param name_list オブジェクトに付ける名前の NameComponent
+ # @param name_cxt 関連付けられる NamingContext
+ #
+ # @else
+ #
+ # @brief
+ #
+ # @endif
+ def rebindContextRecursive(self, context, name_list, name_cxt):
+ self.rebindRecursive(context, name_list, name_cxt)
+ return
+
+
+ ##
+ # @if jp
+ #
+ # @brief Object を name から解決する
+ #
+ # name に bind されているオブジェクト参照を返す。
+ # ネームコンポーネント <c_1, c_2, ... c_n> は再帰的に解決される。
+ #
+ # 引数 name に与えられた値が文字列の場合にはまず最初に toName() によって
+ # NameComponent に変換される。
+ #
+ # CosNaming::resolve() とほぼ同等の働きをするが、常に与えられた
+ # ネームサーバのルートコンテキストに対して resolve() が呼び出される点が
+ # 異なる。
+ #
+ # @param self
+ # @param name 解決すべきオブジェクトの名前のネームコンポーネント
+ #
+ # @return 解決されたオブジェクト参照
+ #
+ # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
+ # @exception CannotProceed 何らかの理由で処理を継続できない。
+ # @exception InvalidName 引数 name の名前が不正。
+ #
+ # @else
+ #
+ # @endif
+ def resolve(self, name):
+ if isinstance(name, basestring):
+ name_ = self.toName(name)
+ else:
+ name_ = name
+
+ try:
+ obj = self._rootContext.resolve(name_)
+ return obj
+ except CosNaming.NamingContext.NotFound, ex:
+ self.__print_exception()
+ return None
+
+
+ ##
+ # @if jp
+ #
+ # @brief 指定された名前のオブジェクトの bind を解除する
+ #
+ # name に bind されているオブジェクト参照を解除する。
+ # ネームコンポーネント <c_1, c_2, ... c_n> は再帰的に解決される。
+ #
+ # 引数 name に与えられた値が文字列の場合にはまず最初に toName() によって
+ # NameComponent に変換される。
+ #
+ # CosNaming::unbind() とほぼ同等の働きをするが、常に与えられた
+ # ネームサーバのルートコンテキストに対して unbind() が呼び出される点が
+ # 異なる。
+ #
+ # @param self
+ # @param name 削除するオブジェクトのネームコンポーネント
+ #
+ # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
+ # @exception CannotProceed 何らかの理由で処理を継続できない。
+ # @exception InvalidName 引数 name の名前が不正。
+ #
+ # @else
+ #
+ # @endif
+ # void unbind(const CosNaming::Name& name)
+ # throw(NotFound, CannotProceed, InvalidName);
+ def unbind(self, name):
+ if isinstance(name, basestring):
+ name_ = self.toName(name)
+ else:
+ name_ = name
+
+ try:
+ self._rootContext.unbind(name_)
+ except:
+ self.__print_exception()
+
+ return
+
+
+ ##
+ # @if jp
+ #
+ # @brief 新しいコンテキストを生成する
+ #
+ # 与えられたネームサーバ上で生成された NamingContext を返す。
+ # 返された NamingContext は bind されていない。
+ #
+ # @param self
+ #
+ # @return 生成された新しい NamingContext
+ #
+ # @else
+ #
+ # @endif
+ def newContext(self):
+ return self._rootContext.new_context()
+
+
+ ##
+ # @if jp
+ #
+ # @brief 新しいコンテキストを bind する
+ #
+ # 与えられた name に対して新しいコンテキストをバインドする。
+ # 生成された NamingContext はネームサーバ上で生成されたものである。
+ #
+ # 引数 name に与えられた値が文字列の場合にはまず最初に toName() によって
+ # NameComponent に変換される。
+ #
+ # @param self
+ # @param name NamingContextに付ける名前のネームコンポーネント
+ # @param force trueの場合、途中のコンテキストを強制的にバインドする
+ # (デフォルト値:true)
+ #
+ # @return 生成された新しい NamingContext
+ #
+ # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
+ # @exception CannotProceed 何らかの理由で処理を継続できない。
+ # @exception InvalidName 引数 name の名前が不正。
+ # @exception AlreadyBound name <n> の Object がすでにバインドされている。
+ #
+ # @else
+ #
+ # @endif
+ def bindNewContext(self, name, force=True):
+ if force is None:
+ force = True
+
+ if isinstance(name, basestring):
+ name_ = self.toName(name)
+ else:
+ name_ = name
+
+ try:
+ return self._rootContext.bind_new_context(name_)
+ except CosNaming.NamingContext.NotFound:
+ if force:
+ self.bindRecursive(self._rootContext, name_, self.newContext())
+ else:
+ self.__print_exception()
+ raise
+ except CosNaming.NamingContext.CannotProceed, err:
+ if force:
+ self.bindRecursive(err.cxt, err.rest_of_name, self.newContext())
+ else:
+ self.__print_exception()
+ raise
+ return None
+
+
+ ##
+ # @if jp
+ #
+ # @brief NamingContext を非アクティブ化する
+ #
+ # context で指定された NamingContext を非アクティブ化する。
+ # context に他のコンテキストがバインドされている場合は NotEmpty 例外が
+ # 発生する。
+ #
+ # @param self
+ # @param context 非アクティブ化する NamingContext
+ #
+ # @exception NotEmpty 対象context に他のコンテキストがバインドされている。
+ #
+ # @else
+ #
+ # @else
+ #
+ # @brief Destroy the naming context
+ #
+ # Delete the specified naming context.
+ # any bindings should be <unbind> in which the given context is bound to
+ # some names before invoking <destroy> operation on it.
+ #
+ # @param context NamingContext which is destroied.
+ #
+ # @exception NotEmpty
+ #
+ # @else
+ #
+ # @endif
+ def destroy(self, context):
+ context.destroy()
+
+
+ ##
+ # @if jp
+ # @brief NamingContext を再帰的に下って非アクティブ化する
+ #
+ # context で与えられた NamingContext に対して、name で指定された
+ # ネームコンポーネント <c_1, ... c_(n-1)> を NamingContext として
+ # 解決しながら、名前 <c_n> に対して 非アクティブ化を行う。
+ #
+ # @param self
+ # @param context 非アクティブ化する NamingContext
+ #
+ # @exception NotEmpty 対象context に他のコンテキストがバインドされている。
+ # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
+ # @exception CannotProceed 何らかの理由で処理を継続できない。
+ # @exception InvalidName 引数 name の名前が不正。
+ #
+ # @else
+ # @brief Destroy the naming context recursively
+ # @endif
+ def destroyRecursive(self, context):
+ cont = True
+ bl = []
+ bi = 0
+ bl, bi = context.list(self._blLength)
+ while cont:
+ for i in range(len(bl)):
+ if bl[i].binding_type == CosNaming.ncontext:
+ obj = context.resolve(bl[i].binding_name)
+ next_context = obj._narrow(CosNaming.NamingContext)
+
+ self.destroyRecursive(next_context)
+ context.unbind(bl[i].binding_name)
+ next_context.destroy()
+ elif bl[i].binding_type == CosNaming.nobject:
+ context.unbind(bl[i].binding_name)
+ else:
+ assert(0)
+ if CORBA.is_nil(bi):
+ cont = False
+ else:
+ bi.next_n(self._blLength, bl)
+
+ if not (CORBA.is_nil(bi)):
+ bi.destroy()
+ return
+
+
+ ##
+ # @if jp
+ # @brief すべての Binding を削除する
+ #
+ # 登録されている全てのBinding を削除する。
+ #
+ # @param self
+ #
+ # @else
+ # @brief Destroy all binding
+ # @endif
+ def clearAll(self):
+ self.destroyRecursive(self._rootContext)
+ return
+
+
+ ##
+ # @if jp
+ # @brief 与えられた NamingContext の Binding を取得する
+ #
+ # 指定された NamingContext の Binding を取得する。
+ #
+ # @param self
+ # @param name_cxt Binding 取得対象 NamingContext
+ # @param how_many Binding を取得する階層の深さ
+ # @param rbl 取得した Binding を保持するホルダ
+ # @param rbi 取得した Binding をたどるためのイテレータ
+ #
+ # @else
+ # @endif
+ def list(self, name_cxt, how_many, rbl, rbi):
+ bl, bi = name_cxt.list(how_many)
+
+ for i in bl:
+ rbl.append(bl)
+
+ rbi.append(bi)
+
+
+ #============================================================
+ # interface of NamingContext
+ #============================================================
+
+ ##
+ # @if jp
+ # @brief 与えられた NameComponent の文字列表現を返す
+ #
+ # 指定された NameComponent を文字に変換する。
+ #
+ # @param self
+ # @param name_list 変換対象 NameComponent
+ #
+ # @return 文字列変換結果
+ #
+ # @exception InvalidName 引数 name_list の名前が不正。
+ #
+ # @else
+ # @brief Get string representation of given NameComponent
+ # @endif
+ def toString(self, name_list):
+ if len(name_list) == 0:
+ raise CosNaming.NamingContext.InvalidName
+
+ slen = self.getNameLength(name_list)
+ string_name = [""]
+ self.nameToString(name_list, string_name, slen)
+
+ return string_name[0]
+
+
+ ##
+ # @if jp
+ # @brief 与えられた文字列表現を NameComponent に分解する
+ #
+ # 指定された文字列を NameComponent に変換する。
+ #
+ # @param self
+ # @param sname 変換対象文字列
+ #
+ # @return NameComponent 変換結果
+ #
+ # @exception InvalidName 引数 sname が不正。
+ #
+ # @else
+ # @brief Get NameComponent from gien string name representation
+ # @endif
+ def toName(self, sname):
+ if not sname:
+ raise CosNaming.NamingContext.InvalidName
+
+ string_name = sname
+ name_comps = []
+
+ nc_length = 0
+ nc_length = self.split(string_name, "/", name_comps)
+
+ if not (nc_length > 0):
+ raise CosNaming.NamingContext.InvalidName
+
+ name_list = [CosNaming.NameComponent("","") for i in range(nc_length)]
+
+ for i in range(nc_length):
+ pos = string.rfind(name_comps[i][0:],".")
+ if pos == -1:
+ name_list[i].id = name_comps[i]
+ name_list[i].kind = ""
+ else:
+ name_list[i].id = name_comps[i][0:pos]
+ name_list[i].kind = name_comps[i][(pos+1):]
+
+ return name_list
+
+
+ ##
+ # @if jp
+ # @brief 与えられた addr と string_name から URL表現を取得する
+ #
+ # 指定されたアドレスと名称をURLに変換する。
+ #
+ # @param self
+ # @param addr 変換対象アドレス
+ # @param string_name 変換対象名称
+ #
+ # @return URL 変換結果
+ #
+ # @exception InvalidAddress 引数 addr が不正。
+ # @exception InvalidName 引数 string_name が不正。
+ #
+ # @else
+ # @brief Get URL representation from given addr and string_name
+ # @endif
+ def toUrl(self, addr, string_name):
+ return self._rootContext.to_url(addr, string_name)
+
+
+ ##
+ # @if jp
+ # @brief 与えられた文字列表現を resolve しオブジェクトを返す
+ #
+ # 指定された文字列表現をresolveし,オブジェクトを取得する。
+ #
+ # @param self
+ # @param string_name 取得対象オブジェクト文字列表現
+ #
+ # @return 解決されたオブジェクト
+ #
+ # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
+ # @exception CannotProceed 何らかの理由で処理を継続できない。
+ # @exception InvalidName 引数 name の名前が不正。
+ # @exception AlreadyBound name <n> の Object がすでにバインドされている。
+ #
+ # @else
+ # @brief Resolve from name of string representation and get object
+ # @endif
+ def resolveStr(self, string_name):
+ return self.resolve(self.toName(string_name))
+
+
+ #============================================================
+ # Find functions
+ #============================================================
+
+ ##
+ # @if jp
+ #
+ # @brief オブジェクトの名前をバインドまたは解決する
+ #
+ # 指定されたコンテキストに対してオブジェクトを NameComponent で指定された
+ # 位置にバインドする。
+ # 同一箇所に既に他の要素がバインド済みの場合は、既存のバインド済み要素を
+ # 取得する。
+ #
+ # @param self
+ # @param context bind もしくは resole 対象コンテキスト
+ # @param name_list オブジェクトに付ける名前の NameComponent
+ # @param obj 関連付けられる Object
+ #
+ # @return NameComponent で指定された位置にバインドされているオブジェクト
+ #
+ # @else
+ # @brief Bind of resolve the given name component
+ # @endif
+ def bindOrResolve(self, context, name_list, obj):
+ try:
+ context.bind_context(name_list, obj)
+ return obj
+ except CosNaming.NamingContext.AlreadyBound:
+ obj = context.resolve(name_list)
+ return obj
+ return CORBA.Object._nil
+
+
+ ##
+ # @if jp
+ #
+ # @brief コンテキストの名前をバインドまたは解決する
+ #
+ # 指定されたコンテキストに対して Contextを NameComponent で指定された位置に
+ # バインドする。
+ # Context が空の場合は新規コンテキストを生成してバインドする。
+ # 同一箇所に既に他の要素がバインド済みの場合は、既存のバインド済み要素を
+ # 取得する。
+ #
+ # @param self
+ # @param context bind もしくは resole 対象コンテキスト
+ # @param name_list コンテキストに付ける名前の NameComponent
+ # @param new_context 関連付けられる Context(デフォルト値:None)
+ #
+ # @return NameComponent で指定された位置にバインドされているContext
+ #
+ # @else
+ # @brief Bind of resolve the given name component
+ # @endif
+ def bindOrResolveContext(self, context, name_list, new_context=None):
+ if new_context is None:
+ new_cxt = self.newContext()
+ else:
+ new_cxt = new_context
+
+ obj = self.bindOrResolve(context, name_list, new_cxt)
+ return obj._narrow(CosNaming.NamingContext)
+
+
+ ##
+ # @if jp
+ # @brief ネームサーバの名前を取得する
+ #
+ # 設定したネームサーバの名前を取得する。
+ #
+ # @param self
+ #
+ # @return ネームサーバの名前
+ #
+ # @else
+ # @brief Get the name of naming server
+ # @endif
+ def getNameServer(self):
+ return self._nameServer
+
+
+ ##
+ # @if jp
+ # @brief ルートコンテキストを取得する
+ #
+ # 設定したネームサーバのルートコンテキストを取得する。
+ #
+ # @param self
+ #
+ # @return ネームサーバのルートコンテキスト
+ #
+ # @else
+ # @brief Get the root context
+ # @endif
+ def getRootContext(self):
+ return self._rootContext
+
+
+ ##
+ # @if jp
+ # @brief オブジェクトがネーミングコンテキストか判別する
+ #
+ # 指定した要素がネーミングコンテキストか判別する
+ #
+ # @param self
+ # @param obj 判別対象要素
+ #
+ # @return 判別結果(ネーミングコンテキスト:true、それ以外:false)
+ #
+ # @else
+ # @brief Whether the object is NamingContext
+ # @endif
+ def objIsNamingContext(self, obj):
+ nc = obj._narrow(CosNaming.NamingContext)
+ if CORBA.is_nil(nc):
+ return False
+ else:
+ return True
+
+
+ ##
+ # @if jp
+ # @brief 与えられた名前がネーミングコンテキストかどうか判別する
+ #
+ # NameComponent もしくは文字列で指定した要素がネーミングコンテキストか
+ # 判別する
+ #
+ # @param self
+ # @param name_list 判別対象
+ #
+ # @return 判別結果(ネーミングコンテキスト:true、それ以外:false)
+ #
+ # @else
+ # @brief Whether the given name component is NamingContext
+ # @endif
+ def nameIsNamingContext(self, name_list):
+ return self.objIsNamingContext(self.resolve(name_list))
+
+
+ ##
+ # @if jp
+ # @brief ネームコンポーネントの部分を返す
+ #
+ # 指定された範囲のネームコンポーネントを取得する。
+ # 終了位置が指定されていない場合は、最後の要素を除いたネームコンポーネント
+ # を返す。
+ #
+ # @param self
+ # @param name_list 検索対象NameComponent
+ # @param begin 取得範囲開始位置
+ # @param end 取得範囲終了位置(デフォルト値:None)
+ #
+ # @return NameComponent 取得結果
+ #
+ # @else
+ # @brief Get subset of given name component
+ # @endif
+ def subName(self, name_list, begin, end = None):
+ if end is None or end < 0:
+ end = len(name_list) - 1
+
+ sub_len = end - (begin -1)
+ objId = ""
+ kind = ""
+
+ sub_name = []
+ for i in range(sub_len):
+ sub_name.append(name_list[begin + i])
+
+ return sub_name
+
+
+ ##
+ # @if jp
+ # @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・・・
+ # という形式で取得できる。
+ # 取得した文字列の長さが指定した長さ以上の場合は、
+ # 指定した長さで切り捨てられる。
+ #
+ # @param self
+ # @param name_list 取得対象NameComponent
+ # @param string_name 取得結果文字列
+ # @param slen 取得対象文字列最大値
+ #
+ # @else
+ # @brief Get string representation of name component
+ # @endif
+ def nameToString(self, name_list, string_name, slen):
+ for i in range(len(name_list)):
+ for id_ in name_list[i].id:
+ if id_ == "/" or id_ == "." or id_ == "\\":
+ string_name[0] += "\\"
+ string_name[0] += id_
+
+ if name_list[i].id == "" or name_list[i].kind != "":
+ string_name[0] += "."
+
+ for kind_ in name_list[i].kind:
+ if kind_ == "/" or kind_ == "." or kind_ == "\\":
+ string_name[0] += "\\"
+ string_name[0] += kind_
+
+ string_name[0] += "/"
+
+
+ ##
+ # @if jp
+ # @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・・・
+ # という形式で取得できる。
+ #
+ # @param self
+ # @param name_list 取得対象NameComponent
+ #
+ # @return 指定したネームコンポーネントの文字列長さ
+ #
+ # @else
+ # @brief Get string length of the name component's string representation
+ # @endif
+ def getNameLength(self, name_list):
+ slen = 0
+
+ for i in range(len(name_list)):
+ for id_ in name_list[i].id:
+ if id_ == "/" or id_ == "." or id_ == "\\":
+ slen += 1
+ slen += 1
+ if name_list[i].id == "" or name_list[i].kind == "":
+ slen += 1
+
+ for kind_ in name_list[i].kind:
+ if kind_ == "/" or kind_ == "." or kind_ == "\\":
+ slen += 1
+ slen += 1
+
+ slen += 1
+
+ return slen
+
+
+ ##
+ # @if jp
+ # @brief 文字列の分割
+ #
+ # 文字列を指定したデリミタで分割する。
+ #
+ # @param self
+ # @param input 分割対象文字列
+ # @param delimiter 分割用デリミタ
+ # @param results 分割結果
+ #
+ # @return 分割した文字列の要素数
+ #
+ # @else
+ # @brief Split of string
+ # @endif
+ def split(self, input, delimiter, results):
+ delim_size = len(delimiter)
+ found_pos = 0
+ begin_pos = 0
+ pre_pos = 0
+ substr_size = 0
+
+ if input[0:delim_size] == delimiter:
+ begin_pos = delim_size
+ pre_pos = delim_size
+
+ while 1:
+ found_pos = string.find(input[begin_pos:],delimiter)
+ if found_pos == -1:
+ results.append(input[pre_pos:])
+ break
+
+ if found_pos > 0 and input[found_pos + begin_pos - 1] == "\\":
+ begin_pos += found_pos + delim_size
+ else:
+ substr_size = found_pos + (begin_pos - pre_pos)
+ if substr_size > 0:
+ results.append(input[pre_pos:(pre_pos+substr_size)])
+ begin_pos += found_pos + delim_size
+ pre_pos = begin_pos
+
+ return len(results)
+
+
+ ##
+ # @if jp
+ #
+ # @brief 例外情報出力
+ # 例外情報を出力する。
+ #
+ # @else
+ #
+ # @brief Print exception information
+ # Print exception information
+ # @endif
+ def __print_exception(self):
+ if sys.version_info[0:3] >= (2, 4, 0):
+ print traceback.format_exc()
+ else:
+ _exc_list = traceback.format_exception(*sys.exc_info())
+ _exc_str = "".join(_exc_list)
+ print _exc_str
+
+ return
Modified: trunk/OpenRTM-aist-Python/OpenRTM_aist/FactoryInit.py
===================================================================
--- trunk/OpenRTM-aist-Python/OpenRTM_aist/FactoryInit.py 2016-02-01 05:29:04 UTC (rev 642)
+++ trunk/OpenRTM-aist-Python/OpenRTM_aist/FactoryInit.py 2016-02-01 08:37:55 UTC (rev 643)
@@ -34,12 +34,4 @@
OpenRTM_aist.InPortCorbaCdrConsumerInit()
OpenRTM_aist.OutPortCorbaCdrConsumerInit()
OpenRTM_aist.OutPortCorbaCdrProviderInit()
- OpenRTM_aist.InPortDirectProviderInit()
- OpenRTM_aist.InPortDirectConsumerInit()
- OpenRTM_aist.OutPortDirectProviderInit()
- OpenRTM_aist.OutPortDirectConsumerInit()
- OpenRTM_aist.InPortSHMProviderInit()
- OpenRTM_aist.InPortSHMConsumerInit()
- OpenRTM_aist.OutPortSHMProviderInit()
- OpenRTM_aist.OutPortSHMConsumerInit()
Modified: trunk/OpenRTM-aist-Python/OpenRTM_aist/InPort.py
===================================================================
--- trunk/OpenRTM-aist-Python/OpenRTM_aist/InPort.py 2016-02-01 05:29:04 UTC (rev 642)
+++ trunk/OpenRTM-aist-Python/OpenRTM_aist/InPort.py 2016-02-01 08:37:55 UTC (rev 643)
@@ -1,468 +1,372 @@
-#!/usr/bin/env python
-# -*- coding: euc-jp -*-
-
-##
-# @file InPort.py
-# @brief InPort template class
-# @date $Date: 2007/09/20 $
-# @author Noriaki Ando <n-ando at aist.go.jp> and Shinji Kurihara
-#
-# Copyright (C) 2003-2008
-# Task-intelligence Research Group,
-# Intelligent Systems Research Institute,
-# National Institute of
-# Advanced Industrial Science and Technology (AIST), Japan
-# All rights reserved.
-
-from omniORB import *
-from omniORB import any
-import sys
-import copy
-import time
-
-import OpenRTM_aist
-
-##
-# @if jp
-#
-# @class InPort
-#
-# @brief InPort クラス
-#
-# InPort の実装クラス。
-# InPort は内部にリングバッファを持ち、外部から送信されたデータを順次
-# このリングバッファに格納する。リングバッファのサイズはデフォルトで64と
-# なっているが、コンストラクタ引数によりサイズを指定することができる。
-# データはフラグによって未読、既読状態が管理され、isNew(), getNewDataLen()
-# getNewList(), getNewListReverse() 等のメソッドによりハンドリングすることが
-# できる。
-#
-# @since 0.2.0
-#
-# @else
-#
-# @class InPort
-#
-# @brief InPort template class
-#
-# This class template provides interfaces to input port.
-# Component developer can define input value, which act as input
-# port from other components, using this template.
-# This is class template. This class have to be incarnated class as port
-# value types. This value types are previously define RtComponent IDL.
-# ex. type T: TimedFload, TimedLong etc...
-#
-# @since 0.2.0
-#
-# @endif
-class InPort(OpenRTM_aist.InPortBase):
- """
- """
-
-
-
- ##
- # @if jp
- #
- # @brief コンストラクタ
- #
- # コンストラクタ。
- #
- # @param self
- # @param name InPort 名。InPortBase:name() により参照される。
- # @param value この InPort にバインドされる変数
- # @param read_block 読込ブロックフラグ。
- # データ読込時に未読データがない場合、次のデータ受信までブロックする
- # かどうかを設定(デフォルト値:False)
- # @param write_block 書込ブロックフラグ。
- # データ書込時にバッファがフルであった場合、バッファに空きができる
- # までブロックするかどうかを設定(デフォルト値:False)
- # @param read_timeout 読込ブロックを指定していない場合の、データ読取タイム
- # アウト時間(ミリ秒)(デフォルト値:0)
- # @param write_timeout 書込ブロックを指定していない場合の、データ書込タイム
- # アウト時間(ミリ秒)(デフォルト値:0)
- #
- # @else
- #
- # @brief A constructor.
- #
- # Setting channel name and registering channel value.
- #
- # @param self
- # @param name A name of the InPort. This name is referred by
- # InPortBase::name().
- # @param value A channel value related with the channel.
- # @param read_block
- # @param write_block
- # @param read_timeout
- # @param write_timeout
- #
- # @endif
- def __init__(self, name, value, buffer=None,
- read_block=False, write_block=False,
- read_timeout=0, write_timeout = 0):
- OpenRTM_aist.InPortBase.__init__(self, name, OpenRTM_aist.toTypename(value))
- self._name = name
- self._value = value
- self._OnRead = None
- self._OnReadConvert = None
-
- self._directNewData = False
- self._valueMutex = threading.RLock()
- self._outPortConnectorList = []
-
-
- def __del__(self, InPortBase=OpenRTM_aist.InPortBase):
- InPortBase.__del__(self)
- return
-
- ##
- # @if jp
- # @brief ポート名称を取得する。
- #
- # ポート名称を取得する。
- #
- # @param self
- #
- # @return ポート名称
- #
- # @else
- #
- # @endif
- #
- # const char* name()
- def name(self):
- return self._name
-
-
- ##
- # @if jp
- # @brief 最新データか確認
- #
- # 現在のバッファ位置に格納されているデータが最新データか確認する。
- #
- # @param self
- #
- # @return 最新データ確認結果
- # ( true:最新データ.データはまだ読み出されていない
- # false:過去のデータ.データは既に読み出されている)
- #
- # @else
- #
- # @endif
- #
- # bool isNew()
- def isNew(self):
- self._rtcout.RTC_TRACE("isNew()")
-
-
- guard = OpenRTM_aist.ScopedLock(self._valueMutex)
- if self._directNewData == True:
- self._rtcout.RTC_TRACE("isNew() returns true because of direct write.")
- return True
- del guard
-
- if len(self._connectors) == 0:
- self._rtcout.RTC_DEBUG("no connectors")
- return False
-
- r = self._connectors[0].getBuffer().readable()
- if r > 0:
- self._rtcout.RTC_DEBUG("isNew() = True, readable data: %d",r)
- return True
-
- self._rtcout.RTC_DEBUG("isNew() = False, no readable data")
- return False
-
-
- ##
- # @if jp
- #
- # @brief バッファが空かどうか確認する
- #
- # InPortのバッファが空かどうかを bool 値で返す。
- # 空の場合は true, 未読データがある場合は false を返す。
- #
- # @return true バッファは空
- # false バッファに未読データがある
- #
- # @else
- #
- # @brief Check whether the data is newest
- #
- # Check whether the data stored at a current buffer position is newest.
- #
- # @return Newest data check result
- # ( true:Newest data. Data has not been readout yet.
- # false:Past data.Data has already been readout.)
- #
- # @endif
- #
- # bool isEmpty()
- def isEmpty(self):
- self._rtcout.RTC_TRACE("isEmpty()")
- if self._directNewData == True:
- return False
- if len(self._connectors) == 0:
- self._rtcout.RTC_DEBUG("no connectors")
- return True
-
- r = self._connectors[0].getBuffer().readable()
- if r == 0:
- self._rtcout.RTC_DEBUG("isEmpty() = true, buffer is empty")
- return True
-
- self._rtcout.RTC_DEBUG("isEmpty() = false, data exists in the buffer")
- return False
-
-
- ##
- # @if jp
- #
- # @brief DataPort から値を読み出す
- #
- # InPortに書き込まれたデータを読みだす。接続数が0、またはバッファに
- # データが書き込まれていない状態で読みだした場合の戻り値は不定である。
- # バッファが空の状態のとき、
- # 事前に設定されたモード (readback, do_nothing, block) に応じて、
- # 以下のような動作をする。
- #
- # - readback: 最後の値を読みなおす。
- #
- # - do_nothing: 何もしない
- #
- # - block: ブロックする。タイムアウトが設定されている場合は、
- # タイムアウトするまで待つ。
- #
- # バッファが空の状態では、InPortにバインドされた変数の値が返される。
- # したがって、初回読み出し時には不定値を返す可能性がある。
- # この関数を利用する際には、
- #
- # - isNew(), isEmpty() と併用し、事前にバッファ状態をチェックする。
- #
- # - 初回読み出し時に不定値を返さないようにバインド変数を事前に初期化する
- #
- #
- # 各コールバック関数は以下のように呼び出される。
- # - OnRead: read() 関数が呼ばれる際に必ず呼ばれる。
- #
- # - OnReadConvert: データの読み出しが成功した場合、読みだしたデータを
- # 引数としてOnReadConvertが呼び出され、戻り値をread()が戻り値
- # として返す。
- #
- # - OnEmpty: バッファが空のためデータの読み出しに失敗した場合呼び出される。
- # OnEmpty の戻り値を read() の戻り値として返す。
- #
- # - OnBufferTimeout: データフロー型がPush型の場合に、読み出し
- # タイムアウトのためにデータの読み出しに失敗した場合に呼ばれる。
- #
- # - OnRecvTimeout: データフロー型がPull型の場合に、読み出しタイムアウト
- # のためにデータ読み出しに失敗した場合に呼ばれる。
- #
- # - OnReadError: 上記以外の理由で読みだしに失敗した場合に呼ばれる。
- # 理由としては、バッファ設定の不整合、例外の発生などが考えられる
- # が通常は起こりえないためバグの可能性がある。
- #
- # @return 読み出したデータ
- #
- # @else
- #
- # @brief Readout the value from DataPort
- #
- # Readout the value from DataPort
- #
- # - When Callback functor OnRead is already set, OnRead will be invoked
- # before reading from the buffer held by DataPort.
- # - When the buffer held by DataPort can detect the underflow,
- # and when it detected the underflow at reading, callback functor
- # OnUnderflow will be invoked.
- # - When callback functor OnReadConvert is already set, the return value of
- # operator() of OnReadConvert will be the return value of read().
- # - When timeout of reading is already set by setReadTimeout(),
- # it waits for only timeout time until the state of the buffer underflow
- # is reset, and if OnUnderflow is already set, this will be invoked to
- # return.
- #
- # @return Readout data
- #
- # @endif
- #
- # DataType read()
- def read(self):
- self._rtcout.RTC_TRACE("DataType read()")
-
- if self._OnRead is not None:
- self._OnRead()
- self._rtcout.RTC_TRACE("OnRead called")
-
- guard = OpenRTM_aist.ScopedLock(self._valueMutex)
- if self._directNewData == True:
-
- self._rtcout.RTC_TRACE("Direct data transfer")
- if self._OnReadConvert is not None:
- self._value = self._OnReadConvert(self._value)
- self._rtcout.RTC_TRACE("OnReadConvert for direct data called")
- self._directNewData = False
- return self._value
- del guard
-
-
- if len(self._outPortConnectorList) > 0:
- data = self._outPortConnectorList[0].read()
- self._listeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_BUFFER_READ].notify(self._profile, data)
- #self._outPortListeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_BUFFER_READ].notify(self._profile, data)
- self._rtcout.RTC_TRACE("ON_BUFFER_READ(InPort,OutPort), ")
- self._rtcout.RTC_TRACE("callback called in direct mode.")
- self._listeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_RECEIVED].notify(self._profile, data)
- #self._outPortListeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_RECEIVED].notify(self._profile, data)
- self._rtcout.RTC_TRACE("ON_RECEIVED(InPort,OutPort), ")
- self._rtcout.RTC_TRACE("callback called in direct mode.")
- self._value = data
- return self._value
-
- if len(self._connectors) == 0:
- self._rtcout.RTC_DEBUG("no connectors")
- return self._value
-
- _val = copy.deepcopy(self._value)
- cdr = [_val]
- ret = self._connectors[0].read(cdr)
-
-
- if ret == OpenRTM_aist.DataPortStatus.PORT_OK:
- self._rtcout.RTC_DEBUG("data read succeeded")
- self._value = cdr[0]
-
- if self._OnReadConvert is not None:
- self._value = self._OnReadConvert(self._value)
- self._rtcout.RTC_DEBUG("OnReadConvert called")
- return self._value
- return self._value
-
- elif ret == OpenRTM_aist.DataPortStatus.BUFFER_EMPTY:
- self._rtcout.RTC_WARN("buffer empty")
- return self._value
-
- elif ret == OpenRTM_aist.DataPortStatus.BUFFER_TIMEOUT:
- self._rtcout.RTC_WARN("buffer read timeout")
- return self._value
-
- self._rtcout.RTC_ERROR("unknown retern value from buffer.read()")
- return self._value
-
-
- ##
- # @if jp
- #
- # @brief バインドされた変数に InPort バッファの最新値を読み込む
- #
- # バインドされたデータに InPort の最新値を読み込む。
- # コンストラクタで変数と InPort がバインドされていなければならない。
- # このメソッドはポリモーフィックに使用される事を前提としているため、
- # 型に依存しない引数、戻り値となっている。
- #
- # @param self
- #
- # @else
- #
- # @brief Read into bound T-type data from current InPort
- #
- # @endif
- def update(self):
- self.read()
-
-
- ##
- # @if jp
- #
- # @brief InPort バッファへデータ読み込み時のコールバックの設定
- #
- # InPort が持つバッファからデータが読み込まれる直前に呼ばれるコールバック
- # オブジェクトを設定する。
- #
- # @param self
- # @param on_read 設定対象コールバックオブジェクト
- #
- # @else
- #
- # @endif
- def setOnRead(self, on_read):
- self._OnRead = on_read
-
-
- ##
- # @if jp
- #
- # @brief InPort バッファへデータ読み出し時のコールバックの設定
- #
- # InPort が持つバッファからデータが読み出される際に呼ばれるコールバック
- # オブジェクトを設定する。コールバックオブジェクトの戻り値がread()メソッド
- # の呼出結果となる。
- #
- # @param self
- # @param on_rconvert 設定対象コールバックオブジェクト
- #
- # @else
- #
- # @endif
- def setOnReadConvert(self, on_rconvert):
- self._OnReadConvert = on_rconvert
-
- ##
- # @if jp
- #
- # @brief データをダイレクトに書き込む
- #
- # @param self
- # @param data 書き込むデータ
- #
- # @else
- # @brief
- #
- # @param self
- # @param data
- # @endif
- # void write(const DataType& data)
- def write(self, data):
- guard = OpenRTM_aist.ScopedLock(self._valueMutex)
- self._value = data
- self._directNewData = True
- del guard
-
- ##
- # @if jp
- # @brief ダイレクト通信用のOutPortPullConnectorを追加
- # @param self
- # @param outPortConnector outPortPullConnector
- # @return OutPortのサーバント(取得に失敗した場合はNone)
- # @else
- # @brief Getting local peer InPort if available
- # @param self
- # @param profile
- # @return
- # @endif
- #
- # OutPortBase*
- # setOutPortConnector(const OutPortPullConnector_impl outPortConnector)
- def addOutPortConnector(self, outPortConnector):
- self._outPortConnectorList.append(outPortConnector)
-
-
-
- ##
- # @if jp
- # @brief ダイレクト通信用のOutPortPullConnectorを削除
- # @param self
- # @param outPortConnector outPortPullConnector
- # @else
- # @brief Getting local peer InPort if available
- # @param self
- # @param profile
- # @return
- # @endif
- #
- # OutPortBase*
- # setOutPortConnector(const OutPortPullConnector_impl outPortConnector)
- def removeOutPortConnector(self, outPortConnector):
- self._outPortConnectorList.remove(outPortConnector)
-
\ No newline at end of file
+#!/usr/bin/env python
+# -*- coding: euc-jp -*-
+
+##
+# @file InPort.py
+# @brief InPort template class
+# @date $Date: 2007/09/20 $
+# @author Noriaki Ando <n-ando at aist.go.jp> and Shinji Kurihara
+#
+# Copyright (C) 2003-2008
+# Task-intelligence Research Group,
+# Intelligent Systems Research Institute,
+# National Institute of
+# Advanced Industrial Science and Technology (AIST), Japan
+# All rights reserved.
+
+from omniORB import *
+from omniORB import any
+import sys
+import copy
+import time
+
+import OpenRTM_aist
+
+##
+# @if jp
+#
+# @class InPort
+#
+# @brief InPort クラス
+#
+# InPort の実装クラス。
+# InPort は内部にリングバッファを持ち、外部から送信されたデータを順次
+# このリングバッファに格納する。リングバッファのサイズはデフォルトで64と
+# なっているが、コンストラクタ引数によりサイズを指定することができる。
+# データはフラグによって未読、既読状態が管理され、isNew(), getNewDataLen()
+# getNewList(), getNewListReverse() 等のメソッドによりハンドリングすることが
+# できる。
+#
+# @since 0.2.0
+#
+# @else
+#
+# @class InPort
+#
+# @brief InPort template class
+#
+# This class template provides interfaces to input port.
+# Component developer can define input value, which act as input
+# port from other components, using this template.
+# This is class template. This class have to be incarnated class as port
+# value types. This value types are previously define RtComponent IDL.
+# ex. type T: TimedFload, TimedLong etc...
+#
+# @since 0.2.0
+#
+# @endif
+class InPort(OpenRTM_aist.InPortBase):
+ """
+ """
+
+
+
+ ##
+ # @if jp
+ #
+ # @brief コンストラクタ
+ #
+ # コンストラクタ。
+ #
+ # @param self
+ # @param name InPort 名。InPortBase:name() により参照される。
+ # @param value この InPort にバインドされる変数
+ # @param read_block 読込ブロックフラグ。
+ # データ読込時に未読データがない場合、次のデータ受信までブロックする
+ # かどうかを設定(デフォルト値:False)
+ # @param write_block 書込ブロックフラグ。
+ # データ書込時にバッファがフルであった場合、バッファに空きができる
+ # までブロックするかどうかを設定(デフォルト値:False)
+ # @param read_timeout 読込ブロックを指定していない場合の、データ読取タイム
+ # アウト時間(ミリ秒)(デフォルト値:0)
+ # @param write_timeout 書込ブロックを指定していない場合の、データ書込タイム
+ # アウト時間(ミリ秒)(デフォルト値:0)
+ #
+ # @else
+ #
+ # @brief A constructor.
+ #
+ # Setting channel name and registering channel value.
+ #
+ # @param self
+ # @param name A name of the InPort. This name is referred by
+ # InPortBase::name().
+ # @param value A channel value related with the channel.
+ # @param read_block
+ # @param write_block
+ # @param read_timeout
+ # @param write_timeout
+ #
+ # @endif
+ def __init__(self, name, value, buffer=None,
+ read_block=False, write_block=False,
+ read_timeout=0, write_timeout = 0):
+ OpenRTM_aist.InPortBase.__init__(self, name, OpenRTM_aist.toTypename(value))
+ self._name = name
+ self._value = value
+ self._OnRead = None
+ self._OnReadConvert = None
+
+
+ def __del__(self, InPortBase=OpenRTM_aist.InPortBase):
+ InPortBase.__del__(self)
+ return
+
+ ##
+ # @if jp
+ # @brief ポート名称を取得する。
+ #
+ # ポート名称を取得する。
+ #
+ # @param self
+ #
+ # @return ポート名称
+ #
+ # @else
+ #
+ # @endif
+ #
+ # const char* name()
+ def name(self):
+ return self._name
+
+
+ ##
+ # @if jp
+ # @brief 最新データか確認
+ #
+ # 現在のバッファ位置に格納されているデータが最新データか確認する。
+ #
+ # @param self
+ #
+ # @return 最新データ確認結果
+ # ( true:最新データ.データはまだ読み出されていない
+ # false:過去のデータ.データは既に読み出されている)
+ #
+ # @else
+ #
+ # @endif
+ #
+ # bool isNew()
+ def isNew(self):
+ self._rtcout.RTC_TRACE("isNew()")
+
+ if len(self._connectors) == 0:
+ self._rtcout.RTC_DEBUG("no connectors")
+ return False
+
+ r = self._connectors[0].getBuffer().readable()
+ if r > 0:
+ self._rtcout.RTC_DEBUG("isNew() = True, readable data: %d",r)
+ return True
+
+ self._rtcout.RTC_DEBUG("isNew() = False, no readable data")
+ return False
+
+
+ ##
+ # @if jp
+ #
+ # @brief バッファが空かどうか確認する
+ #
+ # InPortのバッファが空かどうかを bool 値で返す。
+ # 空の場合は true, 未読データがある場合は false を返す。
+ #
+ # @return true バッファは空
+ # false バッファに未読データがある
+ #
+ # @else
+ #
+ # @brief Check whether the data is newest
+ #
+ # Check whether the data stored at a current buffer position is newest.
+ #
+ # @return Newest data check result
+ # ( true:Newest data. Data has not been readout yet.
+ # false:Past data.Data has already been readout.)
+ #
+ # @endif
+ #
+ # bool isEmpty()
+ def isEmpty(self):
+ self._rtcout.RTC_TRACE("isEmpty()")
+
+ if len(self._connectors) == 0:
+ self._rtcout.RTC_DEBUG("no connectors")
+ return True
+
+ r = self._connectors[0].getBuffer().readable()
+ if r == 0:
+ self._rtcout.RTC_DEBUG("isEmpty() = true, buffer is empty")
+ return True
+
+ self._rtcout.RTC_DEBUG("isEmpty() = false, data exists in the buffer")
+ return False
+
+
+ ##
+ # @if jp
+ #
+ # @brief DataPort から値を読み出す
+ #
+ # InPortに書き込まれたデータを読みだす。接続数が0、またはバッファに
+ # データが書き込まれていない状態で読みだした場合の戻り値は不定である。
+ # バッファが空の状態のとき、
+ # 事前に設定されたモード (readback, do_nothing, block) に応じて、
+ # 以下のような動作をする。
+ #
+ # - readback: 最後の値を読みなおす。
+ #
+ # - do_nothing: 何もしない
+ #
+ # - block: ブロックする。タイムアウトが設定されている場合は、
+ # タイムアウトするまで待つ。
+ #
+ # バッファが空の状態では、InPortにバインドされた変数の値が返される。
+ # したがって、初回読み出し時には不定値を返す可能性がある。
+ # この関数を利用する際には、
+ #
+ # - isNew(), isEmpty() と併用し、事前にバッファ状態をチェックする。
+ #
+ # - 初回読み出し時に不定値を返さないようにバインド変数を事前に初期化する
+ #
+ #
+ # 各コールバック関数は以下のように呼び出される。
+ # - OnRead: read() 関数が呼ばれる際に必ず呼ばれる。
+ #
+ # - OnReadConvert: データの読み出しが成功した場合、読みだしたデータを
+ # 引数としてOnReadConvertが呼び出され、戻り値をread()が戻り値
+ # として返す。
+ #
+ # - OnEmpty: バッファが空のためデータの読み出しに失敗した場合呼び出される。
+ # OnEmpty の戻り値を read() の戻り値として返す。
+ #
+ # - OnBufferTimeout: データフロー型がPush型の場合に、読み出し
+ # タイムアウトのためにデータの読み出しに失敗した場合に呼ばれる。
+ #
+ # - OnRecvTimeout: データフロー型がPull型の場合に、読み出しタイムアウト
+ # のためにデータ読み出しに失敗した場合に呼ばれる。
+ #
+ # - OnReadError: 上記以外の理由で読みだしに失敗した場合に呼ばれる。
+ # 理由としては、バッファ設定の不整合、例外の発生などが考えられる
+ # が通常は起こりえないためバグの可能性がある。
+ #
+ # @return 読み出したデータ
+ #
+ # @else
+ #
+ # @brief Readout the value from DataPort
+ #
+ # Readout the value from DataPort
+ #
+ # - When Callback functor OnRead is already set, OnRead will be invoked
+ # before reading from the buffer held by DataPort.
+ # - When the buffer held by DataPort can detect the underflow,
+ # and when it detected the underflow at reading, callback functor
+ # OnUnderflow will be invoked.
+ # - When callback functor OnReadConvert is already set, the return value of
+ # operator() of OnReadConvert will be the return value of read().
+ # - When timeout of reading is already set by setReadTimeout(),
+ # it waits for only timeout time until the state of the buffer underflow
+ # is reset, and if OnUnderflow is already set, this will be invoked to
+ # return.
+ #
+ # @return Readout data
+ #
+ # @endif
+ #
+ # DataType read()
+ def read(self):
+ self._rtcout.RTC_TRACE("DataType read()")
+
+ if self._OnRead is not None:
+ self._OnRead()
+ self._rtcout.RTC_TRACE("OnRead called")
+
+ if len(self._connectors) == 0:
+ self._rtcout.RTC_DEBUG("no connectors")
+ return self._value
+
+ _val = copy.deepcopy(self._value)
+ cdr = [_val]
+ ret = self._connectors[0].read(cdr)
+
+
+ if ret == OpenRTM_aist.DataPortStatus.PORT_OK:
+ self._rtcout.RTC_DEBUG("data read succeeded")
+ self._value = cdr[0]
+
+ if self._OnReadConvert is not None:
+ self._value = self._OnReadConvert(self._value)
+ self._rtcout.RTC_DEBUG("OnReadConvert called")
+ return self._value
+ return self._value
+
+ elif ret == OpenRTM_aist.DataPortStatus.BUFFER_EMPTY:
+ self._rtcout.RTC_WARN("buffer empty")
+ return self._value
+
+ elif ret == OpenRTM_aist.DataPortStatus.BUFFER_TIMEOUT:
+ self._rtcout.RTC_WARN("buffer read timeout")
+ return self._value
+
+ self._rtcout.RTC_ERROR("unknown retern value from buffer.read()")
+ return self._value
+
+
+ ##
+ # @if jp
+ #
+ # @brief バインドされた変数に InPort バッファの最新値を読み込む
+ #
+ # バインドされたデータに InPort の最新値を読み込む。
+ # コンストラクタで変数と InPort がバインドされていなければならない。
+ # このメソッドはポリモーフィックに使用される事を前提としているため、
+ # 型に依存しない引数、戻り値となっている。
+ #
+ # @param self
+ #
+ # @else
+ #
+ # @brief Read into bound T-type data from current InPort
+ #
+ # @endif
+ def update(self):
+ self.read()
+
+
+ ##
+ # @if jp
+ #
+ # @brief InPort バッファへデータ読み込み時のコールバックの設定
+ #
+ # InPort が持つバッファからデータが読み込まれる直前に呼ばれるコールバック
+ # オブジェクトを設定する。
+ #
+ # @param self
+ # @param on_read 設定対象コールバックオブジェクト
+ #
+ # @else
+ #
+ # @endif
+ def setOnRead(self, on_read):
+ self._OnRead = on_read
+
+
+ ##
+ # @if jp
+ #
+ # @brief InPort バッファへデータ読み出し時のコールバックの設定
+ #
+ # InPort が持つバッファからデータが読み出される際に呼ばれるコールバック
+ # オブジェクトを設定する。コールバックオブジェクトの戻り値がread()メソッド
+ # の呼出結果となる。
+ #
+ # @param self
+ # @param on_rconvert 設定対象コールバックオブジェクト
+ #
+ # @else
+ #
+ # @endif
+ def setOnReadConvert(self, on_rconvert):
+ self._OnReadConvert = on_rconvert
Modified: trunk/OpenRTM-aist-Python/OpenRTM_aist/InPortBase.py
===================================================================
--- trunk/OpenRTM-aist-Python/OpenRTM_aist/InPortBase.py 2016-02-01 05:29:04 UTC (rev 642)
+++ trunk/OpenRTM-aist-Python/OpenRTM_aist/InPortBase.py 2016-02-01 08:37:55 UTC (rev 643)
@@ -1,1239 +1,1229 @@
-#!/usr/bin/env python
-# -*- coding: euc-jp -*-
-
-##
-# @file InPortBase.py
-# @brief RTC::Port implementation for InPort
-# @date $Date: 2008-01-13 15:06:40 $
-# @author Noriaki Ando <n-ando at aist.go.jp> and Shinji Kurihara
-#
-# Copyright (C) 2006-2009
-# Noriaki Ando
-# Task-intelligence Research Group,
-# Intelligent Systems Research Institute,
-# National Institute of
-# Advanced Industrial Science and Technology (AIST), Japan
-# All rights reserved.
-#
-
-import copy
-import threading
-import OpenRTM_aist
-import RTC
-
-##
-# @if jp
-# @namespace RTC
-#
-# @brief RTコンポーネント
-#
-# @else
-#
-# @namespace RTC
-#
-# @brief RT-Component
-#
-# @endif
-#
-
-##
-# @if jp
-# @class InPortBase
-# @brief InPort 用 Port
-#
-# データ入力ポートの実装クラス。
-#
-# @since 0.4.0
-#
-# @else
-# @class InPortBase
-# @brief Port for InPort
-#
-# This is an implementation class for the data input port.
-#
-# @since 0.4.0
-#
-# @endif
-#
-class InPortBase(OpenRTM_aist.PortBase, OpenRTM_aist.DataPortStatus):
- """
- """
-
- ##
- # @if jp
- # @brief コンストラクタ
- #
- # コンストラクタ
- #
- # @param name ポート名称
- # @param inport 当該データ入力ポートに関連付けるInPortオブジェクト
- # InPortオブジェクトで扱うデータ型、バッファタイプも指定する
- # @param prop ポート設定用プロパティ
- #
- # @else
- # @brief Constructor
- #
- # Constructor
- #
- # @param name Port name
- # @param inport InPort object that is associated with this data input port.
- # Specify also the data type and the buffer type used in
- # the InPort object.
- # @param prop Property for setting ports
- #
- # @endif
- #
- # InPortBase(const char* name, const char* data_type);
- def __init__(self, name, data_type):
- OpenRTM_aist.PortBase.__init__(self,name)
- self._rtcout.RTC_DEBUG("Port name: %s", name)
- self._singlebuffer = True
- self._thebuffer = None
- self._properties = OpenRTM_aist.Properties()
- self._providerTypes = ""
- self._consumerTypes = ""
- self._connectors = []
- self._connector_mutex = threading.RLock()
-
- # PortProfile::properties を設定
- self._rtcout.RTC_DEBUG("setting port.port_type: DataInPort")
- self.addProperty("port.port_type", "DataInPort")
-
- self._rtcout.RTC_DEBUG("setting port.data_type: %s", data_type)
- self.addProperty("dataport.data_type", data_type)
-
- self.addProperty("dataport.subscription_type", "Any")
- self._value = None
- self._listeners = OpenRTM_aist.ConnectorListeners()
-
-
- ##
- # @if jp
- # @brief デストラクタ
- #
- # デストラクタ
- #
- # @else
- # @brief Destructor
- #
- # Destructor
- #
- # @endif
- #
- def __del__(self, PortBase=OpenRTM_aist.PortBase):
- self._rtcout.RTC_TRACE("InPortBase destructor")
-
- if len(self._connectors) != 0:
- self._rtcout.RTC_ERROR("connector.size should be 0 in InPortBase's dtor.")
- # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
- for connector in self._connectors:
- connector.disconnect()
-
- if self._thebuffer is not None:
- OpenRTM_aist.CdrBufferFactory.instance().deleteObject(self._thebuffer)
- if not self._singlebuffer:
- self._rtcout.RTC_ERROR("Although singlebuffer flag is true, the buffer != 0")
-
- PortBase.__del__(self)
- return
-
-
- ##
- # @if jp
- # @brief プロパティの初期化
- #
- # 指定されたプロパティで初期化する。
- #
- # @param prop 設定するプロパティ
- # @else
- # @brief Initializing properties
- #
- # This method initializes the port in the specified property.
- #
- # @param prop Property for setting ports
- # @endif
- #
- # void init(coil::Properties& prop);
- def init(self,prop):
- self._rtcout.RTC_TRACE("init()")
- self._properties.mergeProperties(prop)
- if self._singlebuffer:
- self._rtcout.RTC_DEBUG("single buffer mode.")
- self._thebuffer = OpenRTM_aist.CdrBufferFactory.instance().createObject("ring_buffer")
-
- if self._thebuffer is None:
- self._rtcout.RTC_ERROR("default buffer creation failed")
- else:
- self._rtcout.RTC_DEBUG("multi buffer mode.")
-
- self.initProviders()
- self.initConsumers()
-
- num = [-1]
- if not OpenRTM_aist.stringTo(num, self._properties.getProperty("connection_limit","-1")):
- self._rtcout.RTC_ERROR("invalid connection_limit value: %s",
- self._properties.getProperty("connection_limit"))
-
- self.setConnectionLimit(num[0])
- return
-
-
- ##
- # @if jp
- # @brief RTObject_impl::readAll()から呼ばれる仮想関数
- #
- # DataPort からデータを読み出す
- #
- # @return true:成功,false:失敗
- # @else
- # @brief It is a virtual method that is called from RTObject_impl::readAll().
- # This method reads out data from DataPort.
- #
- # @return true:Success,false:Failure
- # @endif
- #
- # virtual bool read() = 0;
- def read(self):
- pass
-
- ##
- # @if jp
- # @brief プロパティを取得する
- #
- # InPortのプロパティを取得する。
- #
- # @return プロパティ
- #
- # @else
- #
- # @brief Get properties
- #
- # Getting properties of this InPort
- #
- # @return InPort's properties
- #
- # @endif
- #
- def properties(self):
- self._rtcout.RTC_TRACE("properties()")
- return self._properties
-
-
- ##
- # @if jp
- # @brief Connector を取得
- #
- # 現在所有しているコネクタを取得する。
- #
- # @return connector のリスト
- #
- # @else
- #
- # @brief Connector list
- #
- # This operation returns connector list
- #
- # @return connector list
- #
- # @endif
- #
- # const std::vector<InPortConnector*>& connectors();
- def connectors(self):
- self._rtcout.RTC_TRACE("connectors(): size = %d", len(self._connectors))
- # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
- return self._connectors
-
-
- ##
- # @if jp
- # @brief ConnectorProfile を取得
- #
- # 現在所有しているコネクタのProfileを取得する。
- #
- # @return ConnectorProfile のリスト
- #
- # @else
- #
- # @brief ConnectorProfile list
- #
- # This operation returns ConnectorProfile list
- #
- # @return connector list
- #
- # @endif
- #
- # ConnectorInfoList getConnectorProfiles();
- def getConnectorProfiles(self):
- self._rtcout.RTC_TRACE("getConnectorProfiles(): size = %d", len(self._connectors))
- profs = []
- # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
- for con in self._connectors:
- profs.append(con.profile())
-
- return profs
-
- ##
- # @if jp
- # @brief ConnectorId を取得
- #
- # 現在所有しているコネクタのIDを取得する。
- #
- # @return ConnectorId のリスト
- #
- # @else
- #
- # @brief ConnectorId list
- #
- # This operation returns ConnectorId list
- #
- # @return connector list
- #
- # @endif
- #
- # coil::vstring getConnectorIds();
- def getConnectorIds(self):
- ids = []
-
- # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
- for con in self._connectors:
- ids.append(con.id())
-
- self._rtcout.RTC_TRACE("getConnectorIds(): %s", OpenRTM_aist.flatten(ids))
- return ids
-
- ##
- # @if jp
- # @brief Connectorの名前を取得
- #
- # 現在所有しているコネクタの名前を取得する。
- #
- # @return Connector名のリスト
- #
- # @else
- #
- # @brief Connector name list
- #
- # This operation returns Connector name list
- #
- # @return connector name list
- #
- # @endif
- #
- # coil::vstring getConnectorNames();
- def getConnectorNames(self):
- names = []
- # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
- for con in self._connectors:
- names.append(con.name())
-
- self._rtcout.RTC_TRACE("getConnectorNames(): %s", OpenRTM_aist.flatten(names))
- return names
-
- ##
- # @if jp
- # @brief ConnectorProfileをIDで取得
- #
- # 現在所有しているコネクタをIDで取得する。
- #
- # @param id Connector ID
- # @return コネクタへのポインタ
- #
- # @else
- #
- # @brief Getting ConnectorProfile by ID
- #
- # This operation returns Connector specified by ID.
- #
- # @param id Connector ID
- # @return A pointer to connector
- #
- # @endif
- #
- # InPortConnector* getConnectorById(const char* id);
- def getConnectorById(self, id):
- self._rtcout.RTC_TRACE("getConnectorById(id = %s)", id)
-
- for con in self._connectors:
- if id == con.id():
- return con
-
- self._rtcout.RTC_WARN("ConnectorProfile with the id(%s) not found.", id)
- return None
-
- ##
- # @if jp
- # @brief ConnectorProfileを名前で取得
- #
- # 現在所有しているコネクタを名前で取得する。
- #
- # @param name Connector name
- # @return コネクタへのポインタ
- #
- # @else
- #
- # @brief Getting Connector by name
- #
- # This operation returns Connector specified by name.
- #
- # @param id Connector ID
- # @return A pointer to connector
- #
- # @endif
- #
- # InPortConnector* getConnectorByName(const char* name);
- def getConnectorByName(self, name):
- self._rtcout.RTC_TRACE("getConnectorByName(name = %s)", name)
-
- for con in self._connectors:
- if name == con.name():
- return con
-
- self._rtcout.RTC_WARN("ConnectorProfile with the name(%s) not found.", name)
- return None
-
- ##
- # @if jp
- # @brief ConnectorProfileをIDで取得
- #
- # 現在所有しているコネクタをIDで取得する。
- #
- # @param id Connector ID
- # @param prof ConnectorProfile
- # @return false 指定したIDがない
- #
- # @else
- #
- # @brief Getting ConnectorProfile by name
- #
- # This operation returns ConnectorProfile specified by name
- #
- # @param id Connector ID
- # @param prof ConnectorProfile
- # @return false specified ID does not exist
- #
- # @endif
- #
- # bool getConnectorProfileById(const char* id,
- # ConnectorInfo& prof);
- def getConnectorProfileById(self, id, prof):
- self._rtcout.RTC_TRACE("getConnectorProfileById(id = %s)", id)
-
- # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
- conn = self.getConnectorById(id)
- if not conn:
- return False
- prof[0] = conn.profile()
- return True
-
-
- ##
- # @if jp
- # @brief ConnectorProfileを名前で取得
- #
- # 現在所有しているコネクタを名前で取得する。
- #
- # @param name Connector name
- # @param prof ConnectorProfile
- # @return false 指定した名前がない
- #
- # @else
- #
- # @brief Getting ConnectorProfile by name
- #
- # This operation returns ConnectorProfile specified by name
- #
- # @param id Connector ID
- # @param prof ConnectorProfile
- # @return false specified name does not exist
- #
- # @endif
- #
- # bool getConnectorProfileByName(const char* name,
- # ConnectorInfo& prof);
- def getConnectorProfileByName(self, name, prof):
- self._rtcout.RTC_TRACE("getConnectorProfileByName(name = %s)", name)
-
- # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
- conn = self.getConnectorByName(name)
- if not conn:
- return False
- prof[0] = conn.profile()
- return True
-
-
- ##
- # @if jp
- #
- # @brief [CORBA interface] Port の接続を行う
- #
- # 与えられた ConnectoionProfile の情報に基づき、Port間の接続を確立
- # する。この関数は主にアプリケーションプログラムやツールから呼び出
- # すことを前提としている。
- #
- # @param connector_profile ConnectorProfile
- # @return ReturnCode_t 型のリターンコード
- #
- # @else
- #
- # @brief [CORBA interface] Connect the Port
- #
- # This operation establishes connection according to the given
- # ConnectionProfile inforamtion. This function is premised on
- # calling from mainly application program or tools.
- #
- # @param connector_profile The ConnectorProfile.
- # @return ReturnCode_t The return code of ReturnCode_t type.
- #
- # @endif
- #
- def connect(self, connector_profile):
- self._rtcout.RTC_TRACE("InPortBase.connect()")
-
- if OpenRTM_aist.NVUtil.find_index(connector_profile.properties,
- "dataport.serializer.cdr.endian") is -1:
- self._rtcout.RTC_TRACE("ConnectorProfile dataport.serializer.cdr.endian set.")
- connector_profile.properties.append(OpenRTM_aist.NVUtil.newNV("dataport.serializer.cdr.endian","little,big"))
-
- return OpenRTM_aist.PortBase.connect(self, connector_profile)
-
- ##
- # @if jp
- #
- # @brief InPortを activates する
- #
- # InPortを activate する。
- #
- # @else
- #
- # @brief Activate all Port interfaces
- #
- # This operation activate all interfaces that is registered in the
- # ports.
- #
- # @endif
- #
- # void activateInterfaces();
- def activateInterfaces(self):
- self._rtcout.RTC_TRACE("activateInterfaces()")
-
- # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
- for connector in self._connectors:
- connector.activate()
- self._rtcout.RTC_DEBUG("activate connector: %s %s",
- (connector.name(),connector.id()))
-
- return
-
-
- ##
- # @if jp
- #
- # @brief 全ての Port のインターフェースを deactivates する
- #
- # Port に登録されている全てのインターフェースを deactivate する。
- #
- # @else
- #
- # @brief Deactivate all Port interfaces
- #
- # This operation deactivate all interfaces that is registered in the
- # ports.
- #
- # @endif
- #
- # void deactivateInterfaces();
- def deactivateInterfaces(self):
- self._rtcout.RTC_TRACE("deactivateInterfaces()")
-
- # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
- for connector in self._connectors:
- connector.deactivate()
- self._rtcout.RTC_DEBUG("deactivate connector: %s %s",
- (connector.name(),connector.id()))
- return
-
-
- ##
- # @if jp
- # @brief ConnectorDataListener リスナを追加する
- #
- # バッファ書き込みまたは読み出しイベントに関連する各種リスナを設定する。
- #
- # 設定できるリスナのタイプとコールバックイベントは以下の通り
- #
- # - ON_BUFFER_WRITE: バッファ書き込み時
- # - ON_BUFFER_FULL: バッファフル時
- # - ON_BUFFER_WRITE_TIMEOUT: バッファ書き込みタイムアウト時
- # - ON_BUFFER_OVERWRITE: バッファ上書き時
- # - ON_BUFFER_READ: バッファ読み出し時
- # - ON_SEND: InProtへの送信時
- # - ON_RECEIVED: InProtへの送信完了時
- # - ON_SEND_ERTIMEOUT: OutPort側タイムアウト時
- # - ON_SEND_ERERROR: OutPort側エラー時
- # - ON_RECEIVER_FULL: InProt側バッファフル時
- # - ON_RECEIVER_TIMEOUT: InProt側バッファタイムアウト時
- # - ON_RECEIVER_ERROR: InProt側エラー時
- #
- # リスナは ConnectorDataListener を継承し、以下のシグニチャを持つ
- # operator() を実装している必要がある。
- #
- # ConnectorDataListener::
- # operator()(const ConnectorProfile&, const cdrStream&)
- #
- # デフォルトでは、この関数に与えたリスナオブジェクトの所有権は
- # OutPortに移り、OutPort解体時もしくは、
- # removeConnectorDataListener() により削除時に自動的に解体される。
- # リスナオブジェクトの所有権を呼び出し側で維持したい場合は、第3引
- # 数に false を指定し、自動的な解体を抑制することができる。
- #
- # @param listener_type リスナタイプ
- # @param listener リスナオブジェクトへのポインタ
- # @param autoclean リスナオブジェクトの自動的解体を行うかどうかのフラグ
- #
- # @else
- # @brief Adding BufferDataListener type listener
- #
- # This operation adds certain listeners related to buffer writing and
- # reading events.
- # The following listener types are available.
- #
- # - ON_BUFFER_WRITE: At the time of buffer write
- # - ON_BUFFER_FULL: At the time of buffer full
- # - ON_BUFFER_WRITE_TIMEOUT: At the time of buffer write timeout
- # - ON_BUFFER_OVERWRITE: At the time of buffer overwrite
- # - ON_BUFFER_READ: At the time of buffer read
- # - ON_SEND: At the time of sending to InPort
- # - ON_RECEIVED: At the time of finishing sending to InPort
- # - ON_SENDER_TIMEOUT: At the time of timeout of OutPort
- # - ON_SENDER_ERROR: At the time of error of OutPort
- # - ON_RECEIVER_FULL: At the time of bufferfull of InPort
- # - ON_RECEIVER_TIMEOUT: At the time of timeout of InPort
- # - ON_RECEIVER_ERROR: At the time of error of InPort
- #
- # Listeners should have the following function operator().
- #
- # ConnectorDataListener::
- # operator()(const ConnectorProfile&, const cdrStream&)
- #
- # The ownership of the given listener object is transferred to
- # this OutPort object in default. The given listener object will
- # be destroied automatically in the OutPort's dtor or if the
- # listener is deleted by removeConnectorDataListener() function.
- # If you want to keep ownership of the listener object, give
- # "false" value to 3rd argument to inhibit automatic destruction.
- #
- # @param listener_type A listener type
- # @param listener A pointer to a listener object
- # @param autoclean A flag for automatic listener destruction
- #
- # @endif
- #
- # void
- # addConnectorDataListener(ConnectorDataListenerType type,
- # ConnectorDataListener* listener,
- # bool autoclean)
- def addConnectorDataListener(self, listener_type, listener, autoclean = True):
- self._rtcout.RTC_TRACE("addConnectorDataListener()")
-
- if listener_type < OpenRTM_aist.ConnectorDataListenerType.CONNECTOR_DATA_LISTENER_NUM:
- self._listeners.connectorData_[listener_type].addListener(listener, autoclean)
- return
-
- self._rtcout.RTC_ERROR("addConnectorDataListener(): Invalid listener type.")
- return
-
-
- ##
- # @if jp
- # @brief ConnectorDataListener リスナを削除する
- #
- # 設定した各種リスナを削除する。
- #
- # @param listener_type リスナタイプ
- # @param listener リスナオブジェクトへのポインタ
- #
- # @else
- # @brief Removing BufferDataListener type listener
- #
- # This operation removes a specified listener.
- #
- # @param listener_type A listener type
- # @param listener A pointer to a listener object
- #
- # @endif
- #
- # void removeConnectorDataListener(ConnectorDataListenerType type,
- # ConnectorDataListener* listener)
- def removeConnectorDataListener(self, listener_type, listener):
- self._rtcout.RTC_TRACE("removeConnectorDataListener()")
-
- if listener_type < OpenRTM_aist.ConnectorDataListenerType.CONNECTOR_DATA_LISTENER_NUM:
- self._listeners.connectorData_[listener_type].removeListener(listener)
- return
-
- self._rtcout.RTC_ERROR("removeConnectorDataListener(): Invalid listener type.")
- return
-
-
- ##
- # @if jp
- # @brief ConnectorListener リスナを追加する
- #
- # バッファ書き込みまたは読み出しイベントに関連する各種リスナを設定する。
- #
- # 設定できるリスナのタイプは
- #
- # - ON_BUFFER_EMPTY: バッファが空の場合
- # - ON_BUFFER_READTIMEOUT: バッファが空でタイムアウトした場合
- #
- # リスナは以下のシグニチャを持つ operator() を実装している必要がある。
- #
- # ConnectorListener::operator()(const ConnectorProfile&)
- #
- # デフォルトでは、この関数に与えたリスナオブジェクトの所有権は
- # OutPortに移り、OutPort解体時もしくは、
- # removeConnectorListener() により削除時に自動的に解体される。
- # リスナオブジェクトの所有権を呼び出し側で維持したい場合は、第3引
- # 数に false を指定し、自動的な解体を抑制することができる。
- #
- # @param listener_type リスナタイプ
- # @param listener リスナオブジェクトへのポインタ
- # @param autoclean リスナオブジェクトの自動的解体を行うかどうかのフラグ
- #
- # @else
- # @brief Adding ConnectorListener type listener
- #
- # This operation adds certain listeners related to buffer writing and
- # reading events.
- # The following listener types are available.
- #
- # - ON_BUFFER_EMPTY: At the time of buffer empty
- # - ON_BUFFER_READTIMEOUT: At the time of buffer read timeout
- #
- # Listeners should have the following function operator().
- #
- # ConnectorListener::operator()(const ConnectorProfile&)
- #
- # The ownership of the given listener object is transferred to
- # this OutPort object in default. The given listener object will
- # be destroied automatically in the OutPort's dtor or if the
- # listener is deleted by removeConnectorListener() function.
- # If you want to keep ownership of the listener object, give
- # "false" value to 3rd argument to inhibit automatic destruction.
- #
- # @param listener_type A listener type
- # @param listener A pointer to a listener object
- # @param autoclean A flag for automatic listener destruction
- #
- # @endif
- #
- # void addConnectorListener(ConnectorListenerType type,
- # ConnectorListener* listener,
- # bool autoclean)
- def addConnectorListener(self, listener_type, listener, autoclean = True):
- self._rtcout.RTC_TRACE("addConnectorListener()")
-
- if listener_type < OpenRTM_aist.ConnectorListenerType.CONNECTOR_LISTENER_NUM:
- self._listeners.connector_[listener_type].addListener(listener, autoclean)
- return
-
- self._rtcout.RTC_ERROR("addConnectorListener(): Invalid listener type.")
- return
-
-
- ##
- # @if jp
- # @brief ConnectorDataListener リスナを削除する
- #
- # 設定した各種リスナを削除する。
- #
- # @param listener_type リスナタイプ
- # @param listener リスナオブジェクトへのポインタ
- #
- # @else
- # @brief Removing BufferDataListener type listener
- #
- # This operation removes a specified listener.
- #
- # @param listener_type A listener type
- # @param listener A pointer to a listener object
- #
- # @endif
- #
- # void removeConnectorListener(ConnectorListenerType type,
- # ConnectorListener* listener)
- def removeConnectorListener(self, listener_type, listener):
- self._rtcout.RTC_TRACE("removeConnectorListener()")
-
- if listener_type < OpenRTM_aist.ConnectorListenerType.CONNECTOR_LISTENER_NUM:
- self._listeners.connector_[listener_type].removeListener(listener)
- return
-
- self._rtcout.RTC_ERROR("removeConnectorListener(): Invalid listener type.")
- return
-
-
- ##
- # @if jp
- # @brief Interface情報を公開する
- #
- # Interface情報を公開する。
- # 引数の ConnectorProfile に格納されている dataflow_type が push 型
- # の場合は、指定された interface_type の InPortProvider に関する情報
- # を ConnectorProfile::properties に書込み呼び出し側に戻す。
- #
- # dataport.dataflow_type
- #
- # @param connector_profile コネクタプロファイル
- #
- # @return ReturnCode_t 型のリターンコード
- #
- # @else
- # @brief Publish interface information
- #
- # Publish interface information.
- # Assign the Provider information that owned by this port
- # to ConnectorProfile#properties
- #
- # @param connector_profile The connector profile
- #
- # @return The return code of ReturnCode_t type
- #
- # @endif
- #
- # ReturnCode_t publishInterfaces(ConnectorProfile& connector_profile);
- def publishInterfaces(self, cprof):
- self._rtcout.RTC_TRACE("publishInterfaces()")
-
- retval = self._publishInterfaces()
- if retval != RTC.RTC_OK:
- return retval
-
- # prop: [port.outport].
- prop = copy.deepcopy(self._properties)
-
- conn_prop = OpenRTM_aist.Properties()
- OpenRTM_aist.NVUtil.copyToProperties(conn_prop, cprof.properties)
- prop.mergeProperties(conn_prop.getNode("dataport")) # marge ConnectorProfile
-
- # marge ConnectorProfile for buffer property.
- prop.mergeProperties(conn_prop.getNode("dataport.inport"))
-
- #
- # ここで, ConnectorProfile からの properties がマージされたため、
- # prop["dataflow_type"]: データフロータイプ
- # prop["interface_type"]: インターフェースタイプ
- # などがアクセス可能になる。
- #
- dflow_type = prop.getProperty("dataflow_type")
- dflow_type = OpenRTM_aist.normalize([dflow_type])
-
- if dflow_type == "push":
- self._rtcout.RTC_DEBUG("dataflow_type = push .... create PushConnector")
-
- # create InPortProvider
- provider = self.createProvider(cprof, prop)
-
- if not provider:
- self._rtcout.RTC_ERROR("InPort provider creation failed.")
- return RTC.BAD_PARAMETER
-
- # create InPortPushConnector
- connector = self.createConnector(cprof, prop, provider_=provider)
- if not connector:
- self._rtcout.RTC_ERROR("PushConnector creation failed.")
- return RTC.RTC_ERROR
-
- connector.setDataType(self._value)
- provider.setConnector(connector) # So that a provider gets endian information from a connector.
-
- self._rtcout.RTC_DEBUG("publishInterfaces() successfully finished.")
- return RTC.RTC_OK
-
- elif dflow_type == "pull":
- self._rtcout.RTC_DEBUG("dataflow_type = pull .... do nothing")
- return RTC.RTC_OK
-
- self._rtcout.RTC_ERROR("unsupported dataflow_type")
- return RTC.BAD_PARAMETER
-
-
- ##
- # @if jp
- # @brief Interfaceに接続する
- #
- # Interfaceに接続する。
- # Portが所有するConsumerに適合するProviderに関する情報を
- # ConnectorProfile#properties から抽出し、
- # ConsumerにCORBAオブジェクト参照を設定する。
- #
- # @param connector_profile コネクタ・プロファイル
- #
- # @return ReturnCode_t 型のリターンコード
- #
- # @else
- # @brief Subscribe to the interface
- #
- # Subscribe to interface.
- # Derive Provider information that matches Consumer owned by the Port
- # from ConnectorProfile#properties and
- # set the Consumer to the reference of the CORBA object.
- #
- # @param connector_profile The connector profile
- #
- # @return ReturnCode_t The return code of ReturnCode_t type
- #
- # @endif
- #
- # ReturnCode_t subscribeInterfaces(const ConnectorProfile& connector_profile);
- def subscribeInterfaces(self, cprof):
- self._rtcout.RTC_TRACE("subscribeInterfaces()")
-
- # prop: [port.outport].
- prop = copy.deepcopy(self._properties)
- conn_prop = OpenRTM_aist.Properties()
- OpenRTM_aist.NVUtil.copyToProperties(conn_prop, cprof.properties)
- prop.mergeProperties(conn_prop.getNode("dataport")) # marge ConnectorProfile
- prop.mergeProperties(conn_prop.getNode("dataport.inport")) # marge ConnectorProfile for buffer property.
-
- #
- # ここで, ConnectorProfile からの properties がマージされたため、
- # prop["dataflow_type"]: データフロータイプ
- # prop["interface_type"]: インターフェースタイプ
- # などがアクセス可能になる。
- #
- dflow_type = prop.getProperty("dataflow_type")
- dtype = [dflow_type]
- OpenRTM_aist.normalize(dtype)
- dflow_type = dtype[0]
-
- profile = OpenRTM_aist.ConnectorInfo(cprof.name,
- cprof.connector_id,
- OpenRTM_aist.CORBA_SeqUtil.refToVstring(cprof.ports),
- prop)
- if dflow_type == "push":
- self._rtcout.RTC_DEBUG("dataflow_type = push .... do nothing")
-
- conn = self.getConnectorById(cprof.connector_id)
-
- if not conn:
- self._rtcout.RTC_ERROR("specified connector not found: %s",
- cprof.connector_id)
- return RTC.RTC_ERROR
-
- ret = conn.setConnectorInfo(profile)
- if ret == RTC.RTC_OK:
- self._rtcout.RTC_DEBUG("subscribeInterfaces() successfully finished.")
-
- return ret
-
- elif dflow_type == "pull":
- self._rtcout.RTC_DEBUG("dataflow_type = pull .... create PullConnector")
-
- # create OutPortConsumer
- consumer = self.createConsumer(cprof, prop)
- if not consumer:
- return RTC.BAD_PARAMETER
-
- # create InPortPullConnector
- connector = self.createConnector(cprof, prop, consumer_=consumer)
- if not connector:
- return RTC.RTC_ERROR
-
- ret = connector.setConnectorInfo(profile)
-
- if ret == RTC.RTC_OK:
- self._rtcout.RTC_DEBUG("publishInterface() successfully finished.")
-
- return ret
-
- self._rtcout.RTC_ERROR("unsupported dataflow_type")
- return RTC.BAD_PARAMETER
-
-
- ##
- # @if jp
- # @brief Interfaceへの接続を解除する
- #
- # Interfaceへの接続を解除する。
- # 与えられたConnectorProfileに関連するConsumerに設定された全てのObjectを
- # 解放し接続を解除する。
- #
- # @param connector_profile コネクタ・プロファイル
- #
- # @else
- # @brief Disconnect the interface connection
- #
- # Disconnect the interface connection.
- # Release all objects set in Consumer associated with
- # given ConnectorProfile and unscribe the interface.
- #
- # @param connector_profile The connector profile
- #
- # @endif
- #
- # void unsubscribeInterfaces(const ConnectorProfile& connector_profile);
- def unsubscribeInterfaces(self, connector_profile):
- self._rtcout.RTC_TRACE("unsubscribeInterfaces()")
-
- id = connector_profile.connector_id
- self._rtcout.RTC_PARANOID("connector_id: %s", id)
-
- len_ = len(self._connectors)
- for i in range(len_):
- idx = (len_ - 1) - i
- # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
- if id == self._connectors[idx].id():
- # Connector's dtor must call disconnect()
- self._connectors[idx].deactivate()
- self._connectors[idx].disconnect()
- del self._connectors[idx]
- self._rtcout.RTC_TRACE("delete connector: %s", id)
- return
-
- self._rtcout.RTC_ERROR("specified connector not found: %s", id)
- return
-
-
- ##
- # @if jp
- # @brief InPort provider の初期化
- # @else
- # @brief InPort provider initialization
- # @endif
- #
- # void initProviders();
- def initProviders(self):
- self._rtcout.RTC_TRACE("initProviders()")
-
- # create InPort providers
- factory = OpenRTM_aist.InPortProviderFactory.instance()
- provider_types = factory.getIdentifiers()
-
- self._rtcout.RTC_DEBUG("available providers: %s",
- OpenRTM_aist.flatten(provider_types))
-
- if self._properties.hasKey("provider_types") and \
- OpenRTM_aist.normalize(self._properties.getProperty("provider_types")) != "all":
- self._rtcout.RTC_DEBUG("allowed providers: %s",
- self._properties.getProperty("provider_types"))
-
- temp_types = provider_types
- provider_types = []
- active_types = OpenRTM_aist.split(self._properties.getProperty("provider_types"), ",")
-
- temp_types.sort()
- active_types.sort()
-
- set_ptypes = set(temp_types).intersection(set(active_types))
- provider_types = provider_types + list(set_ptypes)
-
- # InPortProvider supports "push" dataflow type
- if len(provider_types) > 0:
- self._rtcout.RTC_DEBUG("dataflow_type push is supported")
- self.appendProperty("dataport.dataflow_type", "push")
- for provider_type in provider_types:
- self.appendProperty("dataport.interface_type",provider_type)
-
-
- self._providerTypes = provider_types
- return
-
-
- ##
- # @if jp
- # @brief OutPort consumer の初期化
- # @else
- # @brief OutPort consumer initialization
- # @endif
- #
- # void initConsumers();
- def initConsumers(self):
- self._rtcout.RTC_TRACE("initConsumers()")
-
- # create OuPort consumers
- factory = OpenRTM_aist.OutPortConsumerFactory.instance()
- consumer_types = factory.getIdentifiers()
- self._rtcout.RTC_DEBUG("available consumers: %s",
- OpenRTM_aist.flatten(consumer_types))
-
- if self._properties.hasKey("consumer_types") and \
- OpenRTM_aist.normalize(self._properties.getProperty("consumer_types")) != "all":
- self._rtcout.RTC_DEBUG("allowed consumers: %s",
- self._properties.getProperty("consumer_types"))
-
- temp_types = consumer_types
- consumer_types = []
- active_types = OpenRTM_aist.split(self._properties.getProperty("consumer_types"), ",")
-
- temp_types.sort()
- active_types.sort()
-
- set_ctypes = set(temp_types).intersection(set(active_types))
- consumer_types = consumer_types + list(set_ctypes)
-
- # OutPortConsumer supports "pull" dataflow type
- if len(consumer_types) > 0:
- self._rtcout.RTC_PARANOID("dataflow_type pull is supported")
- self.appendProperty("dataport.dataflow_type", "pull")
- for consumer_type in consumer_types:
- self.appendProperty("dataport.interface_type",consumer_type)
-
-
- self._consumerTypes = consumer_types
- return
-
-
- ##
- # @if jp
- # @brief InPort provider の生成
- #
- # InPortProvider を生成し、情報を ConnectorProfile に公開する。
- # 生成に失敗した場合 0 を返す。
- #
- # @else
- # @brief InPort provider creation
- # @endif
- #
- # InPortProvider*
- # createProvider(ConnectorProfile& cprof, coil::Properties& prop);
- def createProvider(self, cprof, prop):
- if not prop.getProperty("interface_type") and \
- not OpenRTM_aist.includes(self._providerTypes, prop.getProperty("interface_type")):
- self._rtcout.RTC_ERROR("no provider found")
- self._rtcout.RTC_DEBUG("interface_type: %s", prop.getProperty("interface_type"))
- self._rtcout.RTC_DEBUG("interface_types: %s",
- OpenRTM_aist.flatten(self._providerTypes))
- return 0
-
-
- self._rtcout.RTC_DEBUG("interface_type: %s", prop.getProperty("interface_type"))
- provider = OpenRTM_aist.InPortProviderFactory.instance().createObject(prop.getProperty("interface_type"))
-
- if provider != 0:
- self._rtcout.RTC_DEBUG("provider created")
- provider.init(prop.getNode("provider"))
-
- if not provider.publishInterface(cprof.properties):
- self._rtcout.RTC_ERROR("publishing interface information error")
- OpenRTM_aist.InPortProviderFactory.instance().deleteObject(provider)
- return 0
- return provider
-
- self._rtcout.RTC_ERROR("provider creation failed")
- return 0
-
-
- ##
- # @if jp
- # @brief OutPort consumer の生成
- #
- # OutPortConsumer を生成する。
- # 生成に失敗した場合 0 を返す。
- #
- # @else
- # @brief InPort provider creation
- # @endif
- #
- # OutPortConsumer*
- # createConsumer(const ConnectorProfile& cprof, coil::Properties& prop);
- def createConsumer(self, cprof, prop):
- if not prop.getProperty("interface_type") and \
- not OpenRTM_aist.includes(self._consumerTypes, prop.getProperty("interface_type")):
- self._rtcout.RTC_ERROR("no consumer found")
- self._rtcout.RTC_DEBUG("interface_type: %s", prop.getProperty("interface_type"))
- self._rtcout.RTC_DEBUG("interface_types: %s",
- OpenRTM_aist.flatten(self._consumerTypes))
- return 0
-
- self._rtcout.RTC_DEBUG("interface_type: %s", prop.getProperty("interface_type"))
- consumer = OpenRTM_aist.OutPortConsumerFactory.instance().createObject(prop.getProperty("interface_type"))
-
- if consumer != 0:
- self._rtcout.RTC_DEBUG("consumer created")
-
- consumer.init(prop.getNode("consumer"))
-
- if not consumer.subscribeInterface(cprof.properties):
- self._rtcout.RTC_ERROR("interface subscription failed.")
- OpenRTM_aist.OutPortConsumerFactory.instance().deleteObject(consumer)
- return 0
- return consumer
-
- self._rtcout.RTC_ERROR("consumer creation failed")
- return 0
-
-
- ##
- # @if jp
- # @brief InPortPushConnector の生成
- #
- # Connector を生成し、生成が成功すれば m_connectors に保存する。
- # 生成に失敗した場合 0 を返す。
- #
- # @else
- # @brief InPortPushConnector creation
- # @endif
- #
- # InPortConnector*
- # createConnector(ConnectorProfile& cprof, coil::Properties& prop,
- # InPortProvider* provider);
- def createConnector(self, cprof, prop, provider_=None, consumer_=None):
- profile = OpenRTM_aist.ConnectorInfo(cprof.name,
- cprof.connector_id,
- OpenRTM_aist.CORBA_SeqUtil.refToVstring(cprof.ports),
- prop)
- connector = None
-
-
- try:
- if provider_ is not None:
- if self._singlebuffer:
- connector = OpenRTM_aist.InPortPushConnector(profile, provider_,
- self._listeners,
- self._thebuffer)
- else:
- connector = OpenRTM_aist.InPortPushConnector(profile, provider_,
- self._listeners)
-
- elif consumer_ is not None:
- if self._singlebuffer:
- connector = OpenRTM_aist.InPortPullConnector(profile, consumer_,
- self._listeners,
- self._thebuffer)
- else:
- connector = OpenRTM_aist.InPortPullConnector(profile, consumer_,
- self._listeners)
-
- else:
- self._rtcout.RTC_ERROR("provider or consumer is not passed. returned 0;")
- return 0
-
-
- if connector is None:
- self._rtcout.RTC_ERROR("InPortConnector creation failed")
- return 0
-
- if provider_ is not None:
- self._rtcout.RTC_TRACE("InPortPushConnector created")
- elif consumer_ is not None:
- self._rtcout.RTC_TRACE("InPortPullConnector created")
-
-
-
-
-
-
- # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
- self._connectors.append(connector)
- self._rtcout.RTC_PARANOID("connector push backed: %d", len(self._connectors))
- return connector
- except:
- self._rtcout.RTC_ERROR("InPortPushConnector creation failed")
- self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
- return 0
-
- self._rtcout.RTC_FATAL("never comes here: createConnector()")
- return 0
-
-
+#!/usr/bin/env python
+# -*- coding: euc-jp -*-
+
+##
+# @file InPortBase.py
+# @brief RTC::Port implementation for InPort
+# @date $Date: 2008-01-13 15:06:40 $
+# @author Noriaki Ando <n-ando at aist.go.jp> and Shinji Kurihara
+#
+# Copyright (C) 2006-2009
+# Noriaki Ando
+# Task-intelligence Research Group,
+# Intelligent Systems Research Institute,
+# National Institute of
+# Advanced Industrial Science and Technology (AIST), Japan
+# All rights reserved.
+#
+
+import copy
+import threading
+import OpenRTM_aist
+import RTC
+
+##
+# @if jp
+# @namespace RTC
+#
+# @brief RTコンポーネント
+#
+# @else
+#
+# @namespace RTC
+#
+# @brief RT-Component
+#
+# @endif
+#
+
+##
+# @if jp
+# @class InPortBase
+# @brief InPort 用 Port
+#
+# データ入力ポートの実装クラス。
+#
+# @since 0.4.0
+#
+# @else
+# @class InPortBase
+# @brief Port for InPort
+#
+# This is an implementation class for the data input port.
+#
+# @since 0.4.0
+#
+# @endif
+#
+class InPortBase(OpenRTM_aist.PortBase, OpenRTM_aist.DataPortStatus):
+ """
+ """
+
+ ##
+ # @if jp
+ # @brief コンストラクタ
+ #
+ # コンストラクタ
+ #
+ # @param name ポート名称
+ # @param inport 当該データ入力ポートに関連付けるInPortオブジェクト
+ # InPortオブジェクトで扱うデータ型、バッファタイプも指定する
+ # @param prop ポート設定用プロパティ
+ #
+ # @else
+ # @brief Constructor
+ #
+ # Constructor
+ #
+ # @param name Port name
+ # @param inport InPort object that is associated with this data input port.
+ # Specify also the data type and the buffer type used in
+ # the InPort object.
+ # @param prop Property for setting ports
+ #
+ # @endif
+ #
+ # InPortBase(const char* name, const char* data_type);
+ def __init__(self, name, data_type):
+ OpenRTM_aist.PortBase.__init__(self,name)
+ self._rtcout.RTC_DEBUG("Port name: %s", name)
+ self._singlebuffer = True
+ self._thebuffer = None
+ self._properties = OpenRTM_aist.Properties()
+ self._providerTypes = ""
+ self._consumerTypes = ""
+ self._connectors = []
+ self._connector_mutex = threading.RLock()
+
+ # PortProfile::properties を設定
+ self._rtcout.RTC_DEBUG("setting port.port_type: DataInPort")
+ self.addProperty("port.port_type", "DataInPort")
+
+ self._rtcout.RTC_DEBUG("setting port.data_type: %s", data_type)
+ self.addProperty("dataport.data_type", data_type)
+
+ self.addProperty("dataport.subscription_type", "Any")
+ self._value = None
+ self._listeners = OpenRTM_aist.ConnectorListeners()
+
+
+ ##
+ # @if jp
+ # @brief デストラクタ
+ #
+ # デストラクタ
+ #
+ # @else
+ # @brief Destructor
+ #
+ # Destructor
+ #
+ # @endif
+ #
+ def __del__(self, PortBase=OpenRTM_aist.PortBase):
+ self._rtcout.RTC_TRACE("InPortBase destructor")
+
+ if len(self._connectors) != 0:
+ self._rtcout.RTC_ERROR("connector.size should be 0 in InPortBase's dtor.")
+ # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
+ for connector in self._connectors:
+ connector.disconnect()
+
+ if self._thebuffer is not None:
+ OpenRTM_aist.CdrBufferFactory.instance().deleteObject(self._thebuffer)
+ if not self._singlebuffer:
+ self._rtcout.RTC_ERROR("Although singlebuffer flag is true, the buffer != 0")
+
+ PortBase.__del__(self)
+ return
+
+
+ ##
+ # @if jp
+ # @brief プロパティの初期化
+ #
+ # 指定されたプロパティで初期化する。
+ #
+ # @param prop 設定するプロパティ
+ # @else
+ # @brief Initializing properties
+ #
+ # This method initializes the port in the specified property.
+ #
+ # @param prop Property for setting ports
+ # @endif
+ #
+ # void init(coil::Properties& prop);
+ def init(self,prop):
+ self._rtcout.RTC_TRACE("init()")
+ self._properties.mergeProperties(prop)
+ if self._singlebuffer:
+ self._rtcout.RTC_DEBUG("single buffer mode.")
+ self._thebuffer = OpenRTM_aist.CdrBufferFactory.instance().createObject("ring_buffer")
+
+ if self._thebuffer is None:
+ self._rtcout.RTC_ERROR("default buffer creation failed")
+ else:
+ self._rtcout.RTC_DEBUG("multi buffer mode.")
+
+ self.initProviders()
+ self.initConsumers()
+
+ num = [-1]
+ if not OpenRTM_aist.stringTo(num, self._properties.getProperty("connection_limit","-1")):
+ self._rtcout.RTC_ERROR("invalid connection_limit value: %s",
+ self._properties.getProperty("connection_limit"))
+
+ self.setConnectionLimit(num[0])
+ return
+
+
+ ##
+ # @if jp
+ # @brief RTObject_impl::readAll()から呼ばれる仮想関数
+ #
+ # DataPort からデータを読み出す
+ #
+ # @return true:成功,false:失敗
+ # @else
+ # @brief It is a virtual method that is called from RTObject_impl::readAll().
+ # This method reads out data from DataPort.
+ #
+ # @return true:Success,false:Failure
+ # @endif
+ #
+ # virtual bool read() = 0;
+ def read(self):
+ pass
+
+ ##
+ # @if jp
+ # @brief プロパティを取得する
+ #
+ # InPortのプロパティを取得する。
+ #
+ # @return プロパティ
+ #
+ # @else
+ #
+ # @brief Get properties
+ #
+ # Getting properties of this InPort
+ #
+ # @return InPort's properties
+ #
+ # @endif
+ #
+ def properties(self):
+ self._rtcout.RTC_TRACE("properties()")
+ return self._properties
+
+
+ ##
+ # @if jp
+ # @brief Connector を取得
+ #
+ # 現在所有しているコネクタを取得する。
+ #
+ # @return connector のリスト
+ #
+ # @else
+ #
+ # @brief Connector list
+ #
+ # This operation returns connector list
+ #
+ # @return connector list
+ #
+ # @endif
+ #
+ # const std::vector<InPortConnector*>& connectors();
+ def connectors(self):
+ self._rtcout.RTC_TRACE("connectors(): size = %d", len(self._connectors))
+ # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
+ return self._connectors
+
+
+ ##
+ # @if jp
+ # @brief ConnectorProfile を取得
+ #
+ # 現在所有しているコネクタのProfileを取得する。
+ #
+ # @return ConnectorProfile のリスト
+ #
+ # @else
+ #
+ # @brief ConnectorProfile list
+ #
+ # This operation returns ConnectorProfile list
+ #
+ # @return connector list
+ #
+ # @endif
+ #
+ # ConnectorInfoList getConnectorProfiles();
+ def getConnectorProfiles(self):
+ self._rtcout.RTC_TRACE("getConnectorProfiles(): size = %d", len(self._connectors))
+ profs = []
+ # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
+ for con in self._connectors:
+ profs.append(con.profile())
+
+ return profs
+
+ ##
+ # @if jp
+ # @brief ConnectorId を取得
+ #
+ # 現在所有しているコネクタのIDを取得する。
+ #
+ # @return ConnectorId のリスト
+ #
+ # @else
+ #
+ # @brief ConnectorId list
+ #
+ # This operation returns ConnectorId list
+ #
+ # @return connector list
+ #
+ # @endif
+ #
+ # coil::vstring getConnectorIds();
+ def getConnectorIds(self):
+ ids = []
+
+ # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
+ for con in self._connectors:
+ ids.append(con.id())
+
+ self._rtcout.RTC_TRACE("getConnectorIds(): %s", OpenRTM_aist.flatten(ids))
+ return ids
+
+ ##
+ # @if jp
+ # @brief Connectorの名前を取得
+ #
+ # 現在所有しているコネクタの名前を取得する。
+ #
+ # @return Connector名のリスト
+ #
+ # @else
+ #
+ # @brief Connector name list
+ #
+ # This operation returns Connector name list
+ #
+ # @return connector name list
+ #
+ # @endif
+ #
+ # coil::vstring getConnectorNames();
+ def getConnectorNames(self):
+ names = []
+ # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
+ for con in self._connectors:
+ names.append(con.name())
+
+ self._rtcout.RTC_TRACE("getConnectorNames(): %s", OpenRTM_aist.flatten(names))
+ return names
+
+ ##
+ # @if jp
+ # @brief ConnectorProfileをIDで取得
+ #
+ # 現在所有しているコネクタをIDで取得する。
+ #
+ # @param id Connector ID
+ # @return コネクタへのポインタ
+ #
+ # @else
+ #
+ # @brief Getting ConnectorProfile by ID
+ #
+ # This operation returns Connector specified by ID.
+ #
+ # @param id Connector ID
+ # @return A pointer to connector
+ #
+ # @endif
+ #
+ # InPortConnector* getConnectorById(const char* id);
+ def getConnectorById(self, id):
+ self._rtcout.RTC_TRACE("getConnectorById(id = %s)", id)
+
+ for con in self._connectors:
+ if id == con.id():
+ return con
+
+ self._rtcout.RTC_WARN("ConnectorProfile with the id(%s) not found.", id)
+ return None
+
+ ##
+ # @if jp
+ # @brief ConnectorProfileを名前で取得
+ #
+ # 現在所有しているコネクタを名前で取得する。
+ #
+ # @param name Connector name
+ # @return コネクタへのポインタ
+ #
+ # @else
+ #
+ # @brief Getting Connector by name
+ #
+ # This operation returns Connector specified by name.
+ #
+ # @param id Connector ID
+ # @return A pointer to connector
+ #
+ # @endif
+ #
+ # InPortConnector* getConnectorByName(const char* name);
+ def getConnectorByName(self, name):
+ self._rtcout.RTC_TRACE("getConnectorByName(name = %s)", name)
+
+ for con in self._connectors:
+ if name == con.name():
+ return con
+
+ self._rtcout.RTC_WARN("ConnectorProfile with the name(%s) not found.", name)
+ return None
+
+ ##
+ # @if jp
+ # @brief ConnectorProfileをIDで取得
+ #
+ # 現在所有しているコネクタをIDで取得する。
+ #
+ # @param id Connector ID
+ # @param prof ConnectorProfile
+ # @return false 指定したIDがない
+ #
+ # @else
+ #
+ # @brief Getting ConnectorProfile by name
+ #
+ # This operation returns ConnectorProfile specified by name
+ #
+ # @param id Connector ID
+ # @param prof ConnectorProfile
+ # @return false specified ID does not exist
+ #
+ # @endif
+ #
+ # bool getConnectorProfileById(const char* id,
+ # ConnectorInfo& prof);
+ def getConnectorProfileById(self, id, prof):
+ self._rtcout.RTC_TRACE("getConnectorProfileById(id = %s)", id)
+
+ # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
+ conn = self.getConnectorById(id)
+ if not conn:
+ return False
+ prof[0] = conn.profile()
+ return True
+
+
+ ##
+ # @if jp
+ # @brief ConnectorProfileを名前で取得
+ #
+ # 現在所有しているコネクタを名前で取得する。
+ #
+ # @param name Connector name
+ # @param prof ConnectorProfile
+ # @return false 指定した名前がない
+ #
+ # @else
+ #
+ # @brief Getting ConnectorProfile by name
+ #
+ # This operation returns ConnectorProfile specified by name
+ #
+ # @param id Connector ID
+ # @param prof ConnectorProfile
+ # @return false specified name does not exist
+ #
+ # @endif
+ #
+ # bool getConnectorProfileByName(const char* name,
+ # ConnectorInfo& prof);
+ def getConnectorProfileByName(self, name, prof):
+ self._rtcout.RTC_TRACE("getConnectorProfileByName(name = %s)", name)
+
+ # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
+ conn = self.getConnectorByName(name)
+ if not conn:
+ return False
+ prof[0] = conn.profile()
+ return True
+
+
+ ##
+ # @if jp
+ #
+ # @brief [CORBA interface] Port の接続を行う
+ #
+ # 与えられた ConnectoionProfile の情報に基づき、Port間の接続を確立
+ # する。この関数は主にアプリケーションプログラムやツールから呼び出
+ # すことを前提としている。
+ #
+ # @param connector_profile ConnectorProfile
+ # @return ReturnCode_t 型のリターンコード
+ #
+ # @else
+ #
+ # @brief [CORBA interface] Connect the Port
+ #
+ # This operation establishes connection according to the given
+ # ConnectionProfile inforamtion. This function is premised on
+ # calling from mainly application program or tools.
+ #
+ # @param connector_profile The ConnectorProfile.
+ # @return ReturnCode_t The return code of ReturnCode_t type.
+ #
+ # @endif
+ #
+ def connect(self, connector_profile):
+ self._rtcout.RTC_TRACE("InPortBase.connect()")
+
+ if OpenRTM_aist.NVUtil.find_index(connector_profile.properties,
+ "dataport.serializer.cdr.endian") is -1:
+ self._rtcout.RTC_TRACE("ConnectorProfile dataport.serializer.cdr.endian set.")
+ connector_profile.properties.append(OpenRTM_aist.NVUtil.newNV("dataport.serializer.cdr.endian","little,big"))
+
+ return OpenRTM_aist.PortBase.connect(self, connector_profile)
+
+ ##
+ # @if jp
+ #
+ # @brief InPortを activates する
+ #
+ # InPortを activate する。
+ #
+ # @else
+ #
+ # @brief Activate all Port interfaces
+ #
+ # This operation activate all interfaces that is registered in the
+ # ports.
+ #
+ # @endif
+ #
+ # void activateInterfaces();
+ def activateInterfaces(self):
+ self._rtcout.RTC_TRACE("activateInterfaces()")
+
+ # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
+ for connector in self._connectors:
+ connector.activate()
+ self._rtcout.RTC_DEBUG("activate connector: %s %s",
+ (connector.name(),connector.id()))
+
+ return
+
+
+ ##
+ # @if jp
+ #
+ # @brief 全ての Port のインターフェースを deactivates する
+ #
+ # Port に登録されている全てのインターフェースを deactivate する。
+ #
+ # @else
+ #
+ # @brief Deactivate all Port interfaces
+ #
+ # This operation deactivate all interfaces that is registered in the
+ # ports.
+ #
+ # @endif
+ #
+ # void deactivateInterfaces();
+ def deactivateInterfaces(self):
+ self._rtcout.RTC_TRACE("deactivateInterfaces()")
+
+ # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
+ for connector in self._connectors:
+ connector.deactivate()
+ self._rtcout.RTC_DEBUG("deactivate connector: %s %s",
+ (connector.name(),connector.id()))
+ return
+
+
+ ##
+ # @if jp
+ # @brief ConnectorDataListener リスナを追加する
+ #
+ # バッファ書き込みまたは読み出しイベントに関連する各種リスナを設定する。
+ #
+ # 設定できるリスナのタイプとコールバックイベントは以下の通り
+ #
+ # - ON_BUFFER_WRITE: バッファ書き込み時
+ # - ON_BUFFER_FULL: バッファフル時
+ # - ON_BUFFER_WRITE_TIMEOUT: バッファ書き込みタイムアウト時
+ # - ON_BUFFER_OVERWRITE: バッファ上書き時
+ # - ON_BUFFER_READ: バッファ読み出し時
+ # - ON_SEND: InProtへの送信時
+ # - ON_RECEIVED: InProtへの送信完了時
+ # - ON_SEND_ERTIMEOUT: OutPort側タイムアウト時
+ # - ON_SEND_ERERROR: OutPort側エラー時
+ # - ON_RECEIVER_FULL: InProt側バッファフル時
+ # - ON_RECEIVER_TIMEOUT: InProt側バッファタイムアウト時
+ # - ON_RECEIVER_ERROR: InProt側エラー時
+ #
+ # リスナは ConnectorDataListener を継承し、以下のシグニチャを持つ
+ # operator() を実装している必要がある。
+ #
+ # ConnectorDataListener::
+ # operator()(const ConnectorProfile&, const cdrStream&)
+ #
+ # デフォルトでは、この関数に与えたリスナオブジェクトの所有権は
+ # OutPortに移り、OutPort解体時もしくは、
+ # removeConnectorDataListener() により削除時に自動的に解体される。
+ # リスナオブジェクトの所有権を呼び出し側で維持したい場合は、第3引
+ # 数に false を指定し、自動的な解体を抑制することができる。
+ #
+ # @param listener_type リスナタイプ
+ # @param listener リスナオブジェクトへのポインタ
+ # @param autoclean リスナオブジェクトの自動的解体を行うかどうかのフラグ
+ #
+ # @else
+ # @brief Adding BufferDataListener type listener
+ #
+ # This operation adds certain listeners related to buffer writing and
+ # reading events.
+ # The following listener types are available.
+ #
+ # - ON_BUFFER_WRITE: At the time of buffer write
+ # - ON_BUFFER_FULL: At the time of buffer full
+ # - ON_BUFFER_WRITE_TIMEOUT: At the time of buffer write timeout
+ # - ON_BUFFER_OVERWRITE: At the time of buffer overwrite
+ # - ON_BUFFER_READ: At the time of buffer read
+ # - ON_SEND: At the time of sending to InPort
+ # - ON_RECEIVED: At the time of finishing sending to InPort
+ # - ON_SENDER_TIMEOUT: At the time of timeout of OutPort
+ # - ON_SENDER_ERROR: At the time of error of OutPort
+ # - ON_RECEIVER_FULL: At the time of bufferfull of InPort
+ # - ON_RECEIVER_TIMEOUT: At the time of timeout of InPort
+ # - ON_RECEIVER_ERROR: At the time of error of InPort
+ #
+ # Listeners should have the following function operator().
+ #
+ # ConnectorDataListener::
+ # operator()(const ConnectorProfile&, const cdrStream&)
+ #
+ # The ownership of the given listener object is transferred to
+ # this OutPort object in default. The given listener object will
+ # be destroied automatically in the OutPort's dtor or if the
+ # listener is deleted by removeConnectorDataListener() function.
+ # If you want to keep ownership of the listener object, give
+ # "false" value to 3rd argument to inhibit automatic destruction.
+ #
+ # @param listener_type A listener type
+ # @param listener A pointer to a listener object
+ # @param autoclean A flag for automatic listener destruction
+ #
+ # @endif
+ #
+ # void
+ # addConnectorDataListener(ConnectorDataListenerType type,
+ # ConnectorDataListener* listener,
+ # bool autoclean)
+ def addConnectorDataListener(self, listener_type, listener, autoclean = True):
+ self._rtcout.RTC_TRACE("addConnectorDataListener()")
+
+ if listener_type < OpenRTM_aist.ConnectorDataListenerType.CONNECTOR_DATA_LISTENER_NUM:
+ self._listeners.connectorData_[listener_type].addListener(listener, autoclean)
+ return
+
+ self._rtcout.RTC_ERROR("addConnectorDataListener(): Invalid listener type.")
+ return
+
+
+ ##
+ # @if jp
+ # @brief ConnectorDataListener リスナを削除する
+ #
+ # 設定した各種リスナを削除する。
+ #
+ # @param listener_type リスナタイプ
+ # @param listener リスナオブジェクトへのポインタ
+ #
+ # @else
+ # @brief Removing BufferDataListener type listener
+ #
+ # This operation removes a specified listener.
+ #
+ # @param listener_type A listener type
+ # @param listener A pointer to a listener object
+ #
+ # @endif
+ #
+ # void removeConnectorDataListener(ConnectorDataListenerType type,
+ # ConnectorDataListener* listener)
+ def removeConnectorDataListener(self, listener_type, listener):
+ self._rtcout.RTC_TRACE("removeConnectorDataListener()")
+
+ if listener_type < OpenRTM_aist.ConnectorDataListenerType.CONNECTOR_DATA_LISTENER_NUM:
+ self._listeners.connectorData_[listener_type].removeListener(listener)
+ return
+
+ self._rtcout.RTC_ERROR("removeConnectorDataListener(): Invalid listener type.")
+ return
+
+
+ ##
+ # @if jp
+ # @brief ConnectorListener リスナを追加する
+ #
+ # バッファ書き込みまたは読み出しイベントに関連する各種リスナを設定する。
+ #
+ # 設定できるリスナのタイプは
+ #
+ # - ON_BUFFER_EMPTY: バッファが空の場合
+ # - ON_BUFFER_READTIMEOUT: バッファが空でタイムアウトした場合
+ #
+ # リスナは以下のシグニチャを持つ operator() を実装している必要がある。
+ #
+ # ConnectorListener::operator()(const ConnectorProfile&)
+ #
+ # デフォルトでは、この関数に与えたリスナオブジェクトの所有権は
+ # OutPortに移り、OutPort解体時もしくは、
+ # removeConnectorListener() により削除時に自動的に解体される。
+ # リスナオブジェクトの所有権を呼び出し側で維持したい場合は、第3引
+ # 数に false を指定し、自動的な解体を抑制することができる。
+ #
+ # @param listener_type リスナタイプ
+ # @param listener リスナオブジェクトへのポインタ
+ # @param autoclean リスナオブジェクトの自動的解体を行うかどうかのフラグ
+ #
+ # @else
+ # @brief Adding ConnectorListener type listener
+ #
+ # This operation adds certain listeners related to buffer writing and
+ # reading events.
+ # The following listener types are available.
+ #
+ # - ON_BUFFER_EMPTY: At the time of buffer empty
+ # - ON_BUFFER_READTIMEOUT: At the time of buffer read timeout
+ #
+ # Listeners should have the following function operator().
+ #
+ # ConnectorListener::operator()(const ConnectorProfile&)
+ #
+ # The ownership of the given listener object is transferred to
+ # this OutPort object in default. The given listener object will
+ # be destroied automatically in the OutPort's dtor or if the
+ # listener is deleted by removeConnectorListener() function.
+ # If you want to keep ownership of the listener object, give
+ # "false" value to 3rd argument to inhibit automatic destruction.
+ #
+ # @param listener_type A listener type
+ # @param listener A pointer to a listener object
+ # @param autoclean A flag for automatic listener destruction
+ #
+ # @endif
+ #
+ # void addConnectorListener(ConnectorListenerType type,
+ # ConnectorListener* listener,
+ # bool autoclean)
+ def addConnectorListener(self, listener_type, listener, autoclean = True):
+ self._rtcout.RTC_TRACE("addConnectorListener()")
+
+ if listener_type < OpenRTM_aist.ConnectorListenerType.CONNECTOR_LISTENER_NUM:
+ self._listeners.connector_[listener_type].addListener(listener, autoclean)
+ return
+
+ self._rtcout.RTC_ERROR("addConnectorListener(): Invalid listener type.")
+ return
+
+
+ ##
+ # @if jp
+ # @brief ConnectorDataListener リスナを削除する
+ #
+ # 設定した各種リスナを削除する。
+ #
+ # @param listener_type リスナタイプ
+ # @param listener リスナオブジェクトへのポインタ
+ #
+ # @else
+ # @brief Removing BufferDataListener type listener
+ #
+ # This operation removes a specified listener.
+ #
+ # @param listener_type A listener type
+ # @param listener A pointer to a listener object
+ #
+ # @endif
+ #
+ # void removeConnectorListener(ConnectorListenerType type,
+ # ConnectorListener* listener)
+ def removeConnectorListener(self, listener_type, listener):
+ self._rtcout.RTC_TRACE("removeConnectorListener()")
+
+ if listener_type < OpenRTM_aist.ConnectorListenerType.CONNECTOR_LISTENER_NUM:
+ self._listeners.connector_[listener_type].removeListener(listener)
+ return
+
+ self._rtcout.RTC_ERROR("removeConnectorListener(): Invalid listener type.")
+ return
+
+
+ ##
+ # @if jp
+ # @brief Interface情報を公開する
+ #
+ # Interface情報を公開する。
+ # 引数の ConnectorProfile に格納されている dataflow_type が push 型
+ # の場合は、指定された interface_type の InPortProvider に関する情報
+ # を ConnectorProfile::properties に書込み呼び出し側に戻す。
+ #
+ # dataport.dataflow_type
+ #
+ # @param connector_profile コネクタプロファイル
+ #
+ # @return ReturnCode_t 型のリターンコード
+ #
+ # @else
+ # @brief Publish interface information
+ #
+ # Publish interface information.
+ # Assign the Provider information that owned by this port
+ # to ConnectorProfile#properties
+ #
+ # @param connector_profile The connector profile
+ #
+ # @return The return code of ReturnCode_t type
+ #
+ # @endif
+ #
+ # ReturnCode_t publishInterfaces(ConnectorProfile& connector_profile);
+ def publishInterfaces(self, cprof):
+ self._rtcout.RTC_TRACE("publishInterfaces()")
+
+ retval = self._publishInterfaces()
+ if retval != RTC.RTC_OK:
+ return retval
+
+ # prop: [port.outport].
+ prop = copy.deepcopy(self._properties)
+
+ conn_prop = OpenRTM_aist.Properties()
+ OpenRTM_aist.NVUtil.copyToProperties(conn_prop, cprof.properties)
+ prop.mergeProperties(conn_prop.getNode("dataport")) # marge ConnectorProfile
+
+ # marge ConnectorProfile for buffer property.
+ prop.mergeProperties(conn_prop.getNode("dataport.inport"))
+
+ #
+ # ここで, ConnectorProfile からの properties がマージされたため、
+ # prop["dataflow_type"]: データフロータイプ
+ # prop["interface_type"]: インターフェースタイプ
+ # などがアクセス可能になる。
+ #
+ dflow_type = prop.getProperty("dataflow_type")
+ dflow_type = OpenRTM_aist.normalize([dflow_type])
+
+ if dflow_type == "push":
+ self._rtcout.RTC_DEBUG("dataflow_type = push .... create PushConnector")
+
+ # create InPortProvider
+ provider = self.createProvider(cprof, prop)
+
+ if not provider:
+ self._rtcout.RTC_ERROR("InPort provider creation failed.")
+ return RTC.BAD_PARAMETER
+
+ # create InPortPushConnector
+ connector = self.createConnector(cprof, prop, provider_=provider)
+ if not connector:
+ self._rtcout.RTC_ERROR("PushConnector creation failed.")
+ return RTC.RTC_ERROR
+
+ connector.setDataType(self._value)
+ provider.setConnector(connector) # So that a provider gets endian information from a connector.
+
+ self._rtcout.RTC_DEBUG("publishInterfaces() successfully finished.")
+ return RTC.RTC_OK
+
+ elif dflow_type == "pull":
+ self._rtcout.RTC_DEBUG("dataflow_type = pull .... do nothing")
+ return RTC.RTC_OK
+
+ self._rtcout.RTC_ERROR("unsupported dataflow_type")
+ return RTC.BAD_PARAMETER
+
+
+ ##
+ # @if jp
+ # @brief Interfaceに接続する
+ #
+ # Interfaceに接続する。
+ # Portが所有するConsumerに適合するProviderに関する情報を
+ # ConnectorProfile#properties から抽出し、
+ # ConsumerにCORBAオブジェクト参照を設定する。
+ #
+ # @param connector_profile コネクタ・プロファイル
+ #
+ # @return ReturnCode_t 型のリターンコード
+ #
+ # @else
+ # @brief Subscribe to the interface
+ #
+ # Subscribe to interface.
+ # Derive Provider information that matches Consumer owned by the Port
+ # from ConnectorProfile#properties and
+ # set the Consumer to the reference of the CORBA object.
+ #
+ # @param connector_profile The connector profile
+ #
+ # @return ReturnCode_t The return code of ReturnCode_t type
+ #
+ # @endif
+ #
+ # ReturnCode_t subscribeInterfaces(const ConnectorProfile& connector_profile);
+ def subscribeInterfaces(self, cprof):
+ self._rtcout.RTC_TRACE("subscribeInterfaces()")
+
+ # prop: [port.outport].
+ prop = copy.deepcopy(self._properties)
+ conn_prop = OpenRTM_aist.Properties()
+ OpenRTM_aist.NVUtil.copyToProperties(conn_prop, cprof.properties)
+ prop.mergeProperties(conn_prop.getNode("dataport")) # marge ConnectorProfile
+ prop.mergeProperties(conn_prop.getNode("dataport.inport")) # marge ConnectorProfile for buffer property.
+
+ #
+ # ここで, ConnectorProfile からの properties がマージされたため、
+ # prop["dataflow_type"]: データフロータイプ
+ # prop["interface_type"]: インターフェースタイプ
+ # などがアクセス可能になる。
+ #
+ dflow_type = prop.getProperty("dataflow_type")
+ dtype = [dflow_type]
+ OpenRTM_aist.normalize(dtype)
+ dflow_type = dtype[0]
+
+ profile = OpenRTM_aist.ConnectorInfo(cprof.name,
+ cprof.connector_id,
+ OpenRTM_aist.CORBA_SeqUtil.refToVstring(cprof.ports),
+ prop)
+ if dflow_type == "push":
+ self._rtcout.RTC_DEBUG("dataflow_type = push .... do nothing")
+
+ conn = self.getConnectorById(cprof.connector_id)
+
+ if not conn:
+ self._rtcout.RTC_ERROR("specified connector not found: %s",
+ cprof.connector_id)
+ return RTC.RTC_ERROR
+
+ ret = conn.setConnectorInfo(profile)
+ if ret == RTC.RTC_OK:
+ self._rtcout.RTC_DEBUG("subscribeInterfaces() successfully finished.")
+
+ return ret
+
+ elif dflow_type == "pull":
+ self._rtcout.RTC_DEBUG("dataflow_type = pull .... create PullConnector")
+
+ # create OutPortConsumer
+ consumer = self.createConsumer(cprof, prop)
+ if not consumer:
+ return RTC.BAD_PARAMETER
+
+ # create InPortPullConnector
+ connector = self.createConnector(cprof, prop, consumer_=consumer)
+ if not connector:
+ return RTC.RTC_ERROR
+
+ ret = connector.setConnectorInfo(profile)
+
+ if ret == RTC.RTC_OK:
+ self._rtcout.RTC_DEBUG("publishInterface() successfully finished.")
+
+ return ret
+
+ self._rtcout.RTC_ERROR("unsupported dataflow_type")
+ return RTC.BAD_PARAMETER
+
+
+ ##
+ # @if jp
+ # @brief Interfaceへの接続を解除する
+ #
+ # Interfaceへの接続を解除する。
+ # 与えられたConnectorProfileに関連するConsumerに設定された全てのObjectを
+ # 解放し接続を解除する。
+ #
+ # @param connector_profile コネクタ・プロファイル
+ #
+ # @else
+ # @brief Disconnect the interface connection
+ #
+ # Disconnect the interface connection.
+ # Release all objects set in Consumer associated with
+ # given ConnectorProfile and unscribe the interface.
+ #
+ # @param connector_profile The connector profile
+ #
+ # @endif
+ #
+ # void unsubscribeInterfaces(const ConnectorProfile& connector_profile);
+ def unsubscribeInterfaces(self, connector_profile):
+ self._rtcout.RTC_TRACE("unsubscribeInterfaces()")
+
+ id = connector_profile.connector_id
+ self._rtcout.RTC_PARANOID("connector_id: %s", id)
+
+ len_ = len(self._connectors)
+ for i in range(len_):
+ idx = (len_ - 1) - i
+ # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
+ if id == self._connectors[idx].id():
+ # Connector's dtor must call disconnect()
+ self._connectors[idx].deactivate()
+ self._connectors[idx].disconnect()
+ del self._connectors[idx]
+ self._rtcout.RTC_TRACE("delete connector: %s", id)
+ return
+
+ self._rtcout.RTC_ERROR("specified connector not found: %s", id)
+ return
+
+
+ ##
+ # @if jp
+ # @brief InPort provider の初期化
+ # @else
+ # @brief InPort provider initialization
+ # @endif
+ #
+ # void initProviders();
+ def initProviders(self):
+ self._rtcout.RTC_TRACE("initProviders()")
+
+ # create InPort providers
+ factory = OpenRTM_aist.InPortProviderFactory.instance()
+ provider_types = factory.getIdentifiers()
+
+ self._rtcout.RTC_DEBUG("available providers: %s",
+ OpenRTM_aist.flatten(provider_types))
+
+ if self._properties.hasKey("provider_types") and \
+ OpenRTM_aist.normalize(self._properties.getProperty("provider_types")) != "all":
+ self._rtcout.RTC_DEBUG("allowed providers: %s",
+ self._properties.getProperty("provider_types"))
+
+ temp_types = provider_types
+ provider_types = []
+ active_types = OpenRTM_aist.split(self._properties.getProperty("provider_types"), ",")
+
+ temp_types.sort()
+ active_types.sort()
+
+ set_ptypes = set(temp_types).intersection(set(active_types))
+ provider_types = provider_types + list(set_ptypes)
+
+ # InPortProvider supports "push" dataflow type
+ if len(provider_types) > 0:
+ self._rtcout.RTC_DEBUG("dataflow_type push is supported")
+ self.appendProperty("dataport.dataflow_type", "push")
+ self.appendProperty("dataport.interface_type",
+ OpenRTM_aist.flatten(provider_types))
+
+ self._providerTypes = provider_types
+ return
+
+
+ ##
+ # @if jp
+ # @brief OutPort consumer の初期化
+ # @else
+ # @brief OutPort consumer initialization
+ # @endif
+ #
+ # void initConsumers();
+ def initConsumers(self):
+ self._rtcout.RTC_TRACE("initConsumers()")
+
+ # create OuPort consumers
+ factory = OpenRTM_aist.OutPortConsumerFactory.instance()
+ consumer_types = factory.getIdentifiers()
+ self._rtcout.RTC_DEBUG("available consumers: %s",
+ OpenRTM_aist.flatten(consumer_types))
+
+ if self._properties.hasKey("consumer_types") and \
+ OpenRTM_aist.normalize(self._properties.getProperty("consumer_types")) != "all":
+ self._rtcout.RTC_DEBUG("allowed consumers: %s",
+ self._properties.getProperty("consumer_types"))
+
+ temp_types = consumer_types
+ consumer_types = []
+ active_types = OpenRTM_aist.split(self._properties.getProperty("consumer_types"), ",")
+
+ temp_types.sort()
+ active_types.sort()
+
+ set_ctypes = set(temp_types).intersection(set(active_types))
+ consumer_types = consumer_types + list(set_ctypes)
+
+ # OutPortConsumer supports "pull" dataflow type
+ if len(consumer_types) > 0:
+ self._rtcout.RTC_PARANOID("dataflow_type pull is supported")
+ self.appendProperty("dataport.dataflow_type", "pull")
+ self.appendProperty("dataport.interface_type",
+ OpenRTM_aist.flatten(consumer_types))
+
+ self._consumerTypes = consumer_types
+ return
+
+
+ ##
+ # @if jp
+ # @brief InPort provider の生成
+ #
+ # InPortProvider を生成し、情報を ConnectorProfile に公開する。
+ # 生成に失敗した場合 0 を返す。
+ #
+ # @else
+ # @brief InPort provider creation
+ # @endif
+ #
+ # InPortProvider*
+ # createProvider(ConnectorProfile& cprof, coil::Properties& prop);
+ def createProvider(self, cprof, prop):
+ if not prop.getProperty("interface_type") and \
+ not OpenRTM_aist.includes(self._providerTypes, prop.getProperty("interface_type")):
+ self._rtcout.RTC_ERROR("no provider found")
+ self._rtcout.RTC_DEBUG("interface_type: %s", prop.getProperty("interface_type"))
+ self._rtcout.RTC_DEBUG("interface_types: %s",
+ OpenRTM_aist.flatten(self._providerTypes))
+ return 0
+
+
+ self._rtcout.RTC_DEBUG("interface_type: %s", prop.getProperty("interface_type"))
+ provider = OpenRTM_aist.InPortProviderFactory.instance().createObject(prop.getProperty("interface_type"))
+
+ if provider != 0:
+ self._rtcout.RTC_DEBUG("provider created")
+ provider.init(prop.getNode("provider"))
+
+ if not provider.publishInterface(cprof.properties):
+ self._rtcout.RTC_ERROR("publishing interface information error")
+ OpenRTM_aist.InPortProviderFactory.instance().deleteObject(provider)
+ return 0
+ return provider
+
+ self._rtcout.RTC_ERROR("provider creation failed")
+ return 0
+
+
+ ##
+ # @if jp
+ # @brief OutPort consumer の生成
+ #
+ # OutPortConsumer を生成する。
+ # 生成に失敗した場合 0 を返す。
+ #
+ # @else
+ # @brief InPort provider creation
+ # @endif
+ #
+ # OutPortConsumer*
+ # createConsumer(const ConnectorProfile& cprof, coil::Properties& prop);
+ def createConsumer(self, cprof, prop):
+ if not prop.getProperty("interface_type") and \
+ not OpenRTM_aist.includes(self._consumerTypes, prop.getProperty("interface_type")):
+ self._rtcout.RTC_ERROR("no consumer found")
+ self._rtcout.RTC_DEBUG("interface_type: %s", prop.getProperty("interface_type"))
+ self._rtcout.RTC_DEBUG("interface_types: %s",
+ OpenRTM_aist.flatten(self._consumerTypes))
+ return 0
+
+ self._rtcout.RTC_DEBUG("interface_type: %s", prop.getProperty("interface_type"))
+ consumer = OpenRTM_aist.OutPortConsumerFactory.instance().createObject(prop.getProperty("interface_type"))
+
+ if consumer != 0:
+ self._rtcout.RTC_DEBUG("consumer created")
+ consumer.init(prop.getNode("consumer"))
+
+ if not consumer.subscribeInterface(cprof.properties):
+ self._rtcout.RTC_ERROR("interface subscription failed.")
+ OpenRTM_aist.OutPortConsumerFactory.instance().deleteObject(consumer)
+ return 0
+ return consumer
+
+ self._rtcout.RTC_ERROR("consumer creation failed")
+ return 0
+
+
+ ##
+ # @if jp
+ # @brief InPortPushConnector の生成
+ #
+ # Connector を生成し、生成が成功すれば m_connectors に保存する。
+ # 生成に失敗した場合 0 を返す。
+ #
+ # @else
+ # @brief InPortPushConnector creation
+ # @endif
+ #
+ # InPortConnector*
+ # createConnector(ConnectorProfile& cprof, coil::Properties& prop,
+ # InPortProvider* provider);
+ def createConnector(self, cprof, prop, provider_=None, consumer_=None):
+ profile = OpenRTM_aist.ConnectorInfo(cprof.name,
+ cprof.connector_id,
+ OpenRTM_aist.CORBA_SeqUtil.refToVstring(cprof.ports),
+ prop)
+ connector = None
+
+
+ try:
+ if provider_ is not None:
+ if self._singlebuffer:
+ connector = OpenRTM_aist.InPortPushConnector(profile, provider_,
+ self._listeners,
+ self._thebuffer)
+ else:
+ connector = OpenRTM_aist.InPortPushConnector(profile, provider_,
+ self._listeners)
+
+ elif consumer_ is not None:
+ if self._singlebuffer:
+ connector = OpenRTM_aist.InPortPullConnector(profile, consumer_,
+ self._listeners,
+ self._thebuffer)
+ else:
+ connector = OpenRTM_aist.InPortPullConnector(profile, consumer_,
+ self._listeners)
+
+ else:
+ self._rtcout.RTC_ERROR("provider or consumer is not passed. returned 0;")
+ return 0
+
+
+ if connector is None:
+ self._rtcout.RTC_ERROR("InPortConnector creation failed")
+ return 0
+
+ if provider_ is not None:
+ self._rtcout.RTC_TRACE("InPortPushConnector created")
+ elif consumer_ is not None:
+ self._rtcout.RTC_TRACE("InPortPullConnector created")
+
+ # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
+ self._connectors.append(connector)
+ self._rtcout.RTC_PARANOID("connector push backed: %d", len(self._connectors))
+ return connector
+ except:
+ self._rtcout.RTC_ERROR("InPortPushConnector creation failed")
+ self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
+ return 0
+
+ self._rtcout.RTC_FATAL("never comes here: createConnector()")
+ return 0
Deleted: trunk/OpenRTM-aist-Python/OpenRTM_aist/InPortDirectConsumer.py
===================================================================
--- trunk/OpenRTM-aist-Python/OpenRTM_aist/InPortDirectConsumer.py 2016-02-01 05:29:04 UTC (rev 642)
+++ trunk/OpenRTM-aist-Python/OpenRTM_aist/InPortDirectConsumer.py 2016-02-01 08:37:55 UTC (rev 643)
@@ -1,206 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: euc-jp -*-
-
-##
-# @file InPortDirectConsumer.py
-# @brief InPortDirectConsumer class
-# @date $Date: 2016/01/08 $
-# @author Nobuhiko Miyamoto
-#
-
-
-import sys
-from omniORB import any
-from omniORB import CORBA
-import OpenRTM_aist
-import OpenRTM
-
-##
-# @if jp
-#
-# @class InPortDirectConsumer
-#
-# @brief InPortDirectConsumer クラス
-#
-# データをダイレクトに書き込むpush型通信を実現するInPortコンシュマークラス
-#
-# @else
-# @class InPortDirectConsumer
-#
-# @brief InPortDirectConsumer class
-#
-#
-#
-# @endif
-#
-class InPortDirectConsumer(OpenRTM_aist.InPortConsumer):
- """
- """
-
- ##
- # @if jp
- # @brief コンストラクタ
- #
- # コンストラクタ
- #
- # @param self
- #
- # @else
- # @brief Constructor
- #
- # Constructor
- #
- # @param self
- #
- # @endif
- #
- def __init__(self):
- OpenRTM_aist.InPortConsumer.__init__(self)
- self._rtcout = OpenRTM_aist.Manager.instance().getLogbuf("InPortDirectConsumer")
- self._properties = None
- return
-
- ##
- # @if jp
- # @brief デストラクタ
- #
- # デストラクタ
- #
- # @param self
- #
- # @else
- # @brief Destructor
- #
- # Destructor
- #
- # @param self
- #
- # @endif
- #
- def __del__(self):
- self._rtcout.RTC_PARANOID("~InPortDirectConsumer()")
-
- return
-
- ##
- # @if jp
- # @brief 設定初期化
- #
- # InPortConsumerの各種設定を行う
- #
- # @self
- #
- #
- # @else
- # @brief Initializing configuration
- #
- #
- # @endif
- #
- # virtual void init(coil::Properties& prop);
- def init(self, prop):
- self._rtcout.RTC_TRACE("init()")
- self._properties = prop
- return
-
- ##
- # @if jp
- # @brief
- #
- # @param self
- # @param data
- # @return
- #
- # @else
- # @brief
- #
- # @param self
- # @param data
- # @return
- #
- # @endif
- #
- # virtual ReturnCode put(const cdrMemoryStream& data);
- def put(self, data):
- self._rtcout.RTC_PARANOID("put()")
-
-
- return self.UNKNOWN_ERROR
-
- ##
- # @if jp
- # @brief InterfaceProfile情報を公開する
- #
- #
- # @param self
- # @param properties InterfaceProfile情報を受け取るプロパティ
- #
- # @else
- # @brief Publish InterfaceProfile information
- #
- #
- # @param self
- # @param properties Properties to get InterfaceProfile information
- #
- # @endif
- #
- # virtual void publishInterfaceProfile(SDOPackage::NVList& properties);
- def publishInterfaceProfile(self, properties):
- return
-
- ##
- # @if jp
- # @brief データ送信通知への登録
- #
- # @param self
- # @param properties 登録情報
- #
- # @return 登録処理結果(登録成功:true、登録失敗:false)
- #
- # @else
- # @brief Subscribe to the data sending notification
- #
- # @param self
- # @param properties Information for subscription
- #
- # @return Subscription result (Successful:true, Failed:false)
- #
- # @endif
- #
- # virtual bool subscribeInterface(const SDOPackage::NVList& properties);
- def subscribeInterface(self, properties):
- self._rtcout.RTC_TRACE("subscribeInterface()")
-
-
- return True
-
- ##
- # @if jp
- # @brief データ送信通知からの登録解除
- #
- # @param self
- # @param properties 登録解除情報
- #
- # @else
- # @brief Unsubscribe the data send notification
- #
- #
- # @param self
- # @param properties Information for unsubscription
- #
- # @endif
- #
- # virtual void unsubscribeInterface(const SDOPackage::NVList& properties);
- def unsubscribeInterface(self, properties):
- self._rtcout.RTC_TRACE("unsubscribeInterface()")
-
- return
-
-
-
-
-def InPortDirectConsumerInit():
- factory = OpenRTM_aist.InPortConsumerFactory.instance()
- factory.addFactory("direct",
- OpenRTM_aist.InPortDirectConsumer,
- OpenRTM_aist.Delete)
Deleted: trunk/OpenRTM-aist-Python/OpenRTM_aist/InPortDirectProvider.py
===================================================================
--- trunk/OpenRTM-aist-Python/OpenRTM_aist/InPortDirectProvider.py 2016-02-01 05:29:04 UTC (rev 642)
+++ trunk/OpenRTM-aist-Python/OpenRTM_aist/InPortDirectProvider.py 2016-02-01 08:37:55 UTC (rev 643)
@@ -1,174 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: euc-jp -*-
-
-##
-# @file InPortDirectProvider.py
-# @brief InPortDirectProvider class
-# @date $Date: 2016/01/08 $
-# @author Nobuhiko Miyamoto
-#
-
-import sys
-from omniORB import *
-from omniORB import any
-
-import OpenRTM_aist
-import OpenRTM__POA,OpenRTM
-
-##
-# @if jp
-# @class InPortDirectProvider
-# @brief InPortDirectProvider クラス
-#
-# データをダイレクトに書き込むpush型通信を実現するInPortプロバイダクラス
-#
-# @param self
-#
-# @else
-# @class InPortDirectProvider
-# @brief InPortDirectProvider class
-#
-#
-# @param self
-#
-# @endif
-#
-class InPortDirectProvider(OpenRTM_aist.InPortProvider):
-
- """
- """
-
- ##
- # @if jp
- # @brief コンストラクタ
- #
- # コンストラクタ
- #
- # @param self
- #
- # @else
- # @brief Constructor
- #
- # @param self
- #
- # @endif
- #
- def __init__(self):
- OpenRTM_aist.InPortProvider.__init__(self)
-
- # PortProfile setting
- self.setInterfaceType("direct")
-
-
-
- self._buffer = None
-
- self._profile = None
- self._listeners = None
- #self._connector = None
-
-
-
- return
-
- ##
- # @if jp
- # @brief デストラクタ
- #
- # デストラクタ
- #
- # @param self
- #
- # @else
- # @brief Destructor
- #
- # Destructor
- #
- # @param self
- #
- # @endif
- #
- def __del__(self):
-
- return
-
- ## void init(coil::Properties& prop);
- def init(self, prop):
- pass
-
- ## void setBuffer(BufferBase<cdrMemoryStream>* buffer);
- def setBuffer(self, buffer):
- self._buffer = buffer
- return
-
- # void setListener(ConnectorInfo& info,
- # ConnectorListeners* listeners);
- def setListener(self, info, listeners):
- self._profile = info
- self._listeners = listeners
- return
-
-
- ## void onBufferWrite(const cdrMemoryStream& data)
- def onBufferWrite(self, data):
- if self._listeners is not None and self._profile is not None:
- self._listeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_BUFFER_WRITE].notify(self._profile, data)
- return
-
-
- ## inline void onBufferFull(const cdrMemoryStream& data)
- def onBufferFull(self, data):
- if self._listeners is not None and self._profile is not None:
- self._listeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_BUFFER_FULL].notify(self._profile, data)
- return
-
-
- ## inline void onBufferWriteTimeout(const cdrMemoryStream& data)
- def onBufferWriteTimeout(self, data):
- if self._listeners is not None and self._profile is not None:
- self._listeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_BUFFER_WRITE_TIMEOUT].notify(self._profile, data)
- return
-
- ## inline void onBufferWriteOverwrite(const cdrMemoryStream& data)
- def onBufferWriteOverwrite(self, data):
- if self._listeners is not None and self._profile is not None:
- self._listeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_BUFFER_OVERWRITE].notify(self._profile, data)
- return
-
-
- ## inline void onReceived(const cdrMemoryStream& data)
- def onReceived(self, data):
- if self._listeners is not None and self._profile is not None:
- self._listeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_RECEIVED].notify(self._profile, data)
- return
-
-
- ## inline void onReceiverFull(const cdrMemoryStream& data)
- def onReceiverFull(self, data):
- if self._listeners is not None and self._profile is not None:
- self._listeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_RECEIVER_FULL].notify(self._profile, data)
- return
-
-
- ## inline void onReceiverTimeout(const cdrMemoryStream& data)
- def onReceiverTimeout(self, data):
- if self._listeners is not None and self._profile is not None:
- self._listeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_RECEIVER_TIMEOUT].notify(self._profile, data)
- return
-
-
- ## inline void onReceiverError(const cdrMemoryStream& data)
- def onReceiverError(self, data):
- if self._listeners is not None and self._profile is not None:
- self._listeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_RECEIVER_ERROR].notify(self._profile, data)
- return
-
-
-
-
-
-def InPortDirectProviderInit():
- factory = OpenRTM_aist.InPortProviderFactory.instance()
- factory.addFactory("direct",
- OpenRTM_aist.InPortDirectProvider,
- OpenRTM_aist.Delete)
Modified: trunk/OpenRTM-aist-Python/OpenRTM_aist/InPortPullConnector.py
===================================================================
--- trunk/OpenRTM-aist-Python/OpenRTM_aist/InPortPullConnector.py 2016-02-01 05:29:04 UTC (rev 642)
+++ trunk/OpenRTM-aist-Python/OpenRTM_aist/InPortPullConnector.py 2016-02-01 08:37:55 UTC (rev 643)
@@ -1,330 +1,321 @@
-#!/usr/bin/env python
-# -*- coding: euc-jp -*-
-
-##
-# @file InPortPullConnector.py
-# @brief InPortPull type connector class
-# @date $Date$
-# @author Noriaki Ando <n-ando at aist.go.jp> and Shinji Kurihara
-#
-# Copyright (C) 2009
-# Noriaki Ando
-# Task-intelligence Research Group,
-# Intelligent Systems Research Institute,
-# National Institute of
-# Advanced Industrial Science and Technology (AIST), Japan
-# All rights reserved.
-#
-
-from omniORB import *
-from omniORB import any
-
-import OpenRTM_aist
-
-
-##
-# @if jp
-# @class InPortPullConnector
-# @brief InPortPullConnector クラス
-#
-# InPort の pull 型データフローのための Connector クラス。このオブ
-# ジェクトは、接続時に dataflow_type に pull が指定された場合、
-# InPort によって生成・所有され、OutPortPullConnector と対になって、
-# データポートの pull 型のデータフローを実現する。一つの接続に対して、
-# 一つのデータストリームを提供する唯一の Connector が対応する。
-# Connector は 接続時に生成される UUID 形式の ID により区別される。
-#
-# InPortPullConnector は以下の三つのオブジェクトを所有し管理する。
-#
-# - InPortConsumer
-# - Buffer
-#
-# OutPort に書き込まれたデータは OutPortPullConnector::write() に渡
-# され Buffer に書き込まれる。InPort::read(),
-# InPortPullConnector::read() は結果として、OutPortConsumer::get()
-# を呼び出し、OutPortPullConnector の持つバッファからデータを読み出
-# し、InPortPullConnector のもつバッファにデータを書き込む。
-#
-# @since 1.0.0
-#
-# @else
-# @class InPortPullConnector
-# @brief InPortPullConnector class
-#
-# Connector class of InPort for pull type dataflow. When "pull" is
-# specified as dataflow_type at the time of establishing
-# connection, this object is generated and owned by the InPort.
-# This connector and InPortPullConnector make a pair and realize
-# pull type dataflow of data ports. One connector corresponds to
-# one connection which provides a data stream. Connector is
-# distinguished by ID of the UUID that is generated at establishing
-# connection.
-#
-# InPortPullConnector owns and manages the following objects.
-#
-# - InPortConsumer
-# - Buffer
-#
-# Data written into the OutPort is passed to the
-# OutPortPullConnector::write(), and is written into the buffer.
-# Consequently, InPort::read() and InPortPullConnector::read() call
-# OutPortConsumer::get(), and it reads data from the buffer of
-# OutPortPullConnector. Finally data would be written into the
-# InPortPullConnector's buffer.
-#
-# @since 1.0.0
-#
-# @endif
-#
-class InPortPullConnector(OpenRTM_aist.InPortConnector):
- """
- """
-
- ##
- # @if jp
- # @brief コンストラクタ
- #
- # InPortPullConnector のコンストラクタはオブジェクト生成時に下記
- # を引数にとる。ConnectorInfo は接続情報を含み、この情報に従いバッ
- # ファ等を生成する。OutPort インターフェースのプロバイダオブジェク
- # トへのポインタを取り、所有権を持つので、InPortPullConnector は
- # OutPortConsumer の解体責任を持つ。各種イベントに対するコールバッ
- # ク機構を提供する ConnectorListeners を持ち、適切なタイミングでコー
- # ルバックを呼び出す。データバッファがもし InPortBase から提供さ
- # れる場合はそのポインタを取る。
- #
- # @param info ConnectorInfo
- # @param consumer OutPortConsumer
- # @param listeners ConnectorListeners 型のリスナオブジェクトリスト
- # @param buffer CdrBufferBase 型のバッファ
- #
- # @else
- # @brief Constructor
- #
- # InPortPullConnector's constructor is given the following
- # arguments. According to ConnectorInfo which includes
- # connection information, a buffer is created. It is also given
- # a pointer to the consumer object for the OutPort interface.
- # The owner-ship of the pointer is owned by this
- # OutPortPullConnector, it has responsibility to destruct the
- # OutPortConsumer. OutPortPullConnector also has
- # ConnectorListeners to provide event callback mechanisms, and
- # they would be called at the proper timing. If data buffer is
- # given by OutPortBase, the pointer to the buffer is also given
- # as arguments.
- #
- # @param info ConnectorInfo
- # @param consumer OutPortConsumer
- # @param listeners ConnectorListeners type lsitener object list
- # @param buffer CdrBufferBase type buffer
- #
- # @endif
- #
- # InPortPullConnector(ConnectorInfo info,
- # OutPortConsumer* consumer,
- # ConnectorListeners& listeners,
- # CdrBufferBase* buffer = 0);
- def __init__(self, info, consumer, listeners, buffer = 0):
- OpenRTM_aist.InPortConnector.__init__(self, info, buffer)
- self._consumer = consumer
- self._listeners = listeners
-
-
- if buffer == 0:
- self._buffer = self.createBuffer(self._profile)
-
- if self._buffer == 0 or not self._consumer:
- raise
-
- self._buffer.init(info.properties.getNode("buffer"))
- self._consumer.init(info.properties)
- self._consumer.setBuffer(self._buffer)
- self._consumer.setListener(info, self._listeners)
- self.onConnect()
- return
-
-
- ##
- # @if jp
- # @brief デストラクタ
- #
- # disconnect() が呼ばれ、consumer, publisher, buffer が解体・削除される。
- #
- # @else
- #
- # @brief Destructor
- #
- # This operation calls disconnect(), which destructs and deletes
- # the consumer, the publisher and the buffer.
- #
- # @endif
- #
- def __del__(self):
- return
-
-
- ##
- # @if jp
- # @brief read 関数
- #
- # OutPortConsumer からデータを取得する。正常に読み出せた場合、戻り
- # 値は PORT_OK となり、data に読み出されたデータが格納される。それ
- # 以外の場合には、エラー値として BUFFER_EMPTY, TIMEOUT,
- # PRECONDITION_NOT_MET, PORT_ERROR が返される。
- #
- # @return PORT_OK 正常終了
- # BUFFER_EMPTY バッファは空である
- # TIMEOUT タイムアウトした
- # PRECONDITION_NOT_MET 事前条件を満たさない
- # PORT_ERROR その他のエラー
- #
- # @else
- # @brief Destructor
- #
- # This function get data from OutPortConsumer. If data is read
- # properly, this function will return PORT_OK return code. Except
- # normal return, BUFFER_EMPTY, TIMEOUT, PRECONDITION_NOT_MET and
- # PORT_ERROR will be returned as error codes.
- #
- # @return PORT_OK Normal return
- # BUFFER_EMPTY Buffer empty
- # TIMEOUT Timeout
- # PRECONDITION_NOT_MET Preconditin not met
- # PORT_ERROR Other error
- #
- # @endif
- #
- # virtual ReturnCode read(cdrMemoryStream& data);
- def read(self, data):
- self._rtcout.RTC_TRACE("InPortPullConnector.read()")
- if not self._consumer:
- return self.PORT_ERROR
-
-
-
- cdr_data = [None]
- ret = self._consumer.get(cdr_data)
-
- if ret == self.PORT_OK:
- # CDR -> (conversion) -> data
- if self._endian is not None:
- data[0] = cdrUnmarshal(any.to_any(data[0]).typecode(),cdr_data[0],self._endian)
-
- else:
- self._rtcout.RTC_ERROR("unknown endian from connector")
- return OpenRTM_aist.BufferStatus.PRECONDITION_NOT_MET
-
- return ret
-
-
- ##
- # @if jp
- # @brief 接続解除関数
- #
- # Connector が保持している接続を解除する
- #
- # @else
- # @brief Disconnect connection
- #
- # This operation disconnect this connection
- #
- # @endif
- #
- # virtual ReturnCode disconnect();
- def disconnect(self):
- self._rtcout.RTC_TRACE("disconnect()")
- self.onDisconnect()
- # delete consumer
- if self._consumer:
- OpenRTM_aist.OutPortConsumerFactory.instance().deleteObject(self._consumer)
- self._consumer = 0
-
- return self.PORT_OK
-
- ##
- # @if jp
- # @brief アクティブ化
- #
- # このコネクタをアクティブ化する
- #
- # @else
- #
- # @brief Connector activation
- #
- # This operation activates this connector
- #
- # @endif
- #
- # virtual void activate(){}; // do nothing
- def activate(self): # do nothing
- pass
-
- ##
- # @if jp
- # @brief 非アクティブ化
- #
- # このコネクタを非アクティブ化する
- #
- # @else
- #
- # @brief Connector deactivation
- #
- # This operation deactivates this connector
- #
- # @endif
- #
- # virtual void deactivate(){}; // do nothing
- def deactivate(self): # do nothing
- pass
-
- ##
- # @if jp
- # @brief Bufferの生成
- #
- # 与えられた接続情報に基づきバッファを生成する。
- #
- # @param info 接続情報
- # @return バッファへのポインタ
- #
- # @else
- # @brief create buffer
- #
- # This function creates a buffer based on given information.
- #
- # @param info Connector information
- # @return The poitner to the buffer
- #
- # @endif
- #
- # CdrBufferBase* createBuffer(Profile& profile);
- def createBuffer(self, profile):
- buf_type = profile.properties.getProperty("buffer_type","ring_buffer")
- return OpenRTM_aist.CdrBufferFactory.instance().createObject(buf_type)
-
- ##
- # @if jp
- # @brief 接続確立時にコールバックを呼ぶ
- # @else
- # @brief Invoke callback when connection is established
- # @endif
- # void onConnect()
- def onConnect(self):
- if self._listeners and self._profile:
- self._listeners.connector_[OpenRTM_aist.ConnectorListenerType.ON_CONNECT].notify(self._profile)
- return
-
- ##
- # @if jp
- # @brief 接続切断時にコールバックを呼ぶ
- # @else
- # @brief Invoke callback when connection is destroied
- # @endif
- # void onDisconnect()
- def onDisconnect(self):
- if self._listeners and self._profile:
- self._listeners.connector_[OpenRTM_aist.ConnectorListenerType.ON_DISCONNECT].notify(self._profile)
- return
-
-
-
-
+#!/usr/bin/env python
+# -*- coding: euc-jp -*-
+
+##
+# @file InPortPullConnector.py
+# @brief InPortPull type connector class
+# @date $Date$
+# @author Noriaki Ando <n-ando at aist.go.jp> and Shinji Kurihara
+#
+# Copyright (C) 2009
+# Noriaki Ando
+# Task-intelligence Research Group,
+# Intelligent Systems Research Institute,
+# National Institute of
+# Advanced Industrial Science and Technology (AIST), Japan
+# All rights reserved.
+#
+
+from omniORB import *
+from omniORB import any
+
+import OpenRTM_aist
+
+
+##
+# @if jp
+# @class InPortPullConnector
+# @brief InPortPullConnector クラス
+#
+# InPort の pull 型データフローのための Connector クラス。このオブ
+# ジェクトは、接続時に dataflow_type に pull が指定された場合、
+# InPort によって生成・所有され、OutPortPullConnector と対になって、
+# データポートの pull 型のデータフローを実現する。一つの接続に対して、
+# 一つのデータストリームを提供する唯一の Connector が対応する。
+# Connector は 接続時に生成される UUID 形式の ID により区別される。
+#
+# InPortPullConnector は以下の三つのオブジェクトを所有し管理する。
+#
+# - InPortConsumer
+# - Buffer
+#
+# OutPort に書き込まれたデータは OutPortPullConnector::write() に渡
+# され Buffer に書き込まれる。InPort::read(),
+# InPortPullConnector::read() は結果として、OutPortConsumer::get()
+# を呼び出し、OutPortPullConnector の持つバッファからデータを読み出
+# し、InPortPullConnector のもつバッファにデータを書き込む。
+#
+# @since 1.0.0
+#
+# @else
+# @class InPortPullConnector
+# @brief InPortPullConnector class
+#
+# Connector class of InPort for pull type dataflow. When "pull" is
+# specified as dataflow_type at the time of establishing
+# connection, this object is generated and owned by the InPort.
+# This connector and InPortPullConnector make a pair and realize
+# pull type dataflow of data ports. One connector corresponds to
+# one connection which provides a data stream. Connector is
+# distinguished by ID of the UUID that is generated at establishing
+# connection.
+#
+# InPortPullConnector owns and manages the following objects.
+#
+# - InPortConsumer
+# - Buffer
+#
+# Data written into the OutPort is passed to the
+# OutPortPullConnector::write(), and is written into the buffer.
+# Consequently, InPort::read() and InPortPullConnector::read() call
+# OutPortConsumer::get(), and it reads data from the buffer of
+# OutPortPullConnector. Finally data would be written into the
+# InPortPullConnector's buffer.
+#
+# @since 1.0.0
+#
+# @endif
+#
+class InPortPullConnector(OpenRTM_aist.InPortConnector):
+ """
+ """
+
+ ##
+ # @if jp
+ # @brief コンストラクタ
+ #
+ # InPortPullConnector のコンストラクタはオブジェクト生成時に下記
+ # を引数にとる。ConnectorInfo は接続情報を含み、この情報に従いバッ
+ # ファ等を生成する。OutPort インターフェースのプロバイダオブジェク
+ # トへのポインタを取り、所有権を持つので、InPortPullConnector は
+ # OutPortConsumer の解体責任を持つ。各種イベントに対するコールバッ
+ # ク機構を提供する ConnectorListeners を持ち、適切なタイミングでコー
+ # ルバックを呼び出す。データバッファがもし InPortBase から提供さ
+ # れる場合はそのポインタを取る。
+ #
+ # @param info ConnectorInfo
+ # @param consumer OutPortConsumer
+ # @param listeners ConnectorListeners 型のリスナオブジェクトリスト
+ # @param buffer CdrBufferBase 型のバッファ
+ #
+ # @else
+ # @brief Constructor
+ #
+ # InPortPullConnector's constructor is given the following
+ # arguments. According to ConnectorInfo which includes
+ # connection information, a buffer is created. It is also given
+ # a pointer to the consumer object for the OutPort interface.
+ # The owner-ship of the pointer is owned by this
+ # OutPortPullConnector, it has responsibility to destruct the
+ # OutPortConsumer. OutPortPullConnector also has
+ # ConnectorListeners to provide event callback mechanisms, and
+ # they would be called at the proper timing. If data buffer is
+ # given by OutPortBase, the pointer to the buffer is also given
+ # as arguments.
+ #
+ # @param info ConnectorInfo
+ # @param consumer OutPortConsumer
+ # @param listeners ConnectorListeners type lsitener object list
+ # @param buffer CdrBufferBase type buffer
+ #
+ # @endif
+ #
+ # InPortPullConnector(ConnectorInfo info,
+ # OutPortConsumer* consumer,
+ # ConnectorListeners& listeners,
+ # CdrBufferBase* buffer = 0);
+ def __init__(self, info, consumer, listeners, buffer = 0):
+ OpenRTM_aist.InPortConnector.__init__(self, info, buffer)
+ self._consumer = consumer
+ self._listeners = listeners
+ if buffer == 0:
+ self._buffer = self.createBuffer(self._profile)
+
+ if self._buffer == 0 or not self._consumer:
+ raise
+
+ self._buffer.init(info.properties.getNode("buffer"))
+ self._consumer.setBuffer(self._buffer)
+ self._consumer.setListener(info, self._listeners)
+ self.onConnect()
+ return
+
+
+ ##
+ # @if jp
+ # @brief デストラクタ
+ #
+ # disconnect() が呼ばれ、consumer, publisher, buffer が解体・削除される。
+ #
+ # @else
+ #
+ # @brief Destructor
+ #
+ # This operation calls disconnect(), which destructs and deletes
+ # the consumer, the publisher and the buffer.
+ #
+ # @endif
+ #
+ def __del__(self):
+ return
+
+
+ ##
+ # @if jp
+ # @brief read 関数
+ #
+ # OutPortConsumer からデータを取得する。正常に読み出せた場合、戻り
+ # 値は PORT_OK となり、data に読み出されたデータが格納される。それ
+ # 以外の場合には、エラー値として BUFFER_EMPTY, TIMEOUT,
+ # PRECONDITION_NOT_MET, PORT_ERROR が返される。
+ #
+ # @return PORT_OK 正常終了
+ # BUFFER_EMPTY バッファは空である
+ # TIMEOUT タイムアウトした
+ # PRECONDITION_NOT_MET 事前条件を満たさない
+ # PORT_ERROR その他のエラー
+ #
+ # @else
+ # @brief Destructor
+ #
+ # This function get data from OutPortConsumer. If data is read
+ # properly, this function will return PORT_OK return code. Except
+ # normal return, BUFFER_EMPTY, TIMEOUT, PRECONDITION_NOT_MET and
+ # PORT_ERROR will be returned as error codes.
+ #
+ # @return PORT_OK Normal return
+ # BUFFER_EMPTY Buffer empty
+ # TIMEOUT Timeout
+ # PRECONDITION_NOT_MET Preconditin not met
+ # PORT_ERROR Other error
+ #
+ # @endif
+ #
+ # virtual ReturnCode read(cdrMemoryStream& data);
+ def read(self, data):
+ self._rtcout.RTC_TRACE("InPortPullConnector.read()")
+ if not self._consumer:
+ return self.PORT_ERROR
+
+ cdr_data = [None]
+ ret = self._consumer.get(cdr_data)
+
+ if ret == self.PORT_OK:
+ # CDR -> (conversion) -> data
+ if self._endian is not None:
+ data[0] = cdrUnmarshal(any.to_any(data[0]).typecode(),cdr_data[0],self._endian)
+
+ else:
+ self._rtcout.RTC_ERROR("unknown endian from connector")
+ return OpenRTM_aist.BufferStatus.PRECONDITION_NOT_MET
+
+ return ret
+
+
+ ##
+ # @if jp
+ # @brief 接続解除関数
+ #
+ # Connector が保持している接続を解除する
+ #
+ # @else
+ # @brief Disconnect connection
+ #
+ # This operation disconnect this connection
+ #
+ # @endif
+ #
+ # virtual ReturnCode disconnect();
+ def disconnect(self):
+ self._rtcout.RTC_TRACE("disconnect()")
+ self.onDisconnect()
+ # delete consumer
+ if self._consumer:
+ OpenRTM_aist.OutPortConsumerFactory.instance().deleteObject(self._consumer)
+ self._consumer = 0
+
+ return self.PORT_OK
+
+ ##
+ # @if jp
+ # @brief アクティブ化
+ #
+ # このコネクタをアクティブ化する
+ #
+ # @else
+ #
+ # @brief Connector activation
+ #
+ # This operation activates this connector
+ #
+ # @endif
+ #
+ # virtual void activate(){}; // do nothing
+ def activate(self): # do nothing
+ pass
+
+ ##
+ # @if jp
+ # @brief 非アクティブ化
+ #
+ # このコネクタを非アクティブ化する
+ #
+ # @else
+ #
+ # @brief Connector deactivation
+ #
+ # This operation deactivates this connector
+ #
+ # @endif
+ #
+ # virtual void deactivate(){}; // do nothing
+ def deactivate(self): # do nothing
+ pass
+
+ ##
+ # @if jp
+ # @brief Bufferの生成
+ #
+ # 与えられた接続情報に基づきバッファを生成する。
+ #
+ # @param info 接続情報
+ # @return バッファへのポインタ
+ #
+ # @else
+ # @brief create buffer
+ #
+ # This function creates a buffer based on given information.
+ #
+ # @param info Connector information
+ # @return The poitner to the buffer
+ #
+ # @endif
+ #
+ # CdrBufferBase* createBuffer(Profile& profile);
+ def createBuffer(self, profile):
+ buf_type = profile.properties.getProperty("buffer_type","ring_buffer")
+ return OpenRTM_aist.CdrBufferFactory.instance().createObject(buf_type)
+
+ ##
+ # @if jp
+ # @brief 接続確立時にコールバックを呼ぶ
+ # @else
+ # @brief Invoke callback when connection is established
+ # @endif
+ # void onConnect()
+ def onConnect(self):
+ if self._listeners and self._profile:
+ self._listeners.connector_[OpenRTM_aist.ConnectorListenerType.ON_CONNECT].notify(self._profile)
+ return
+
+ ##
+ # @if jp
+ # @brief 接続切断時にコールバックを呼ぶ
+ # @else
+ # @brief Invoke callback when connection is destroied
+ # @endif
+ # void onDisconnect()
+ def onDisconnect(self):
+ if self._listeners and self._profile:
+ self._listeners.connector_[OpenRTM_aist.ConnectorListenerType.ON_DISCONNECT].notify(self._profile)
+ return
Deleted: trunk/OpenRTM-aist-Python/OpenRTM_aist/InPortSHMConsumer.py
===================================================================
--- trunk/OpenRTM-aist-Python/OpenRTM_aist/InPortSHMConsumer.py 2016-02-01 05:29:04 UTC (rev 642)
+++ trunk/OpenRTM-aist-Python/OpenRTM_aist/InPortSHMConsumer.py 2016-02-01 08:37:55 UTC (rev 643)
@@ -1,177 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: euc-jp -*-
-
-##
-# @file InPortSHMConsumer.py
-# @brief InPortSHMConsumer class
-# @date $Date: 2016-01-12 $
-# @author Nobuhiko Miyamoto
-#
-
-
-import sys
-from omniORB import any
-from omniORB import CORBA
-import OpenRTM_aist
-import OpenRTM
-import mmap, os
-from omniORB import cdrMarshal
-import CORBA
-
-##
-# @if jp
-#
-# @class InPortSHMConsumer
-#
-# @brief InPortSHMConsumer クラス
-#
-# 通信手段に 共有メモリ を利用した入力ポートコンシューマの実装クラス。
-#
-#
-# @else
-# @class InPortCorbaCdrConsumer
-#
-# @brief InPortCorbaCdrConsumer class
-#
-#
-#
-# @endif
-#
-class InPortSHMConsumer(OpenRTM_aist.InPortCorbaCdrConsumer):
- """
- """
-
- ##
- # @if jp
- # @brief コンストラクタ
- #
- # コンストラクタ
- #
- # @param self
- #
- # @else
- # @brief Constructor
- #
- # Constructor
- #
- # @param self
- #
- # @endif
- #
- def __init__(self):
- OpenRTM_aist.InPortCorbaCdrConsumer.__init__(self)
- self._rtcout = OpenRTM_aist.Manager.instance().getLogbuf("InPortSHMConsumer")
- self._properties = None
- self._shmem = None
- self.shm_address = ""
- return
-
- ##
- # @if jp
- # @brief デストラクタ
- #
- # デストラクタ
- #
- # @param self
- # @param CorbaConsumer
- #
- # @else
- # @brief Destructor
- #
- # Destructor
- #
- # @param self
- # @param CorbaConsumer
- #
- # @endif
- #
- def __del__(self, CorbaConsumer=OpenRTM_aist.CorbaConsumer):
- self._rtcout.RTC_PARANOID("~InPortSHMConsumer()")
- CorbaConsumer.__del__(self)
- if self._shmem:
- self._shmem.close()
- return
-
- ##
- # @if jp
- # @brief 設定初期化
- #
- # InPortConsumerの各種設定を行う
- # プロバイダでコネクタプロファイルに共有メモリの空間名を保存するため、init関数で共有メモリの初期化を行う
- #
- # @param self
- # @param prop コネクタプロパティ
- #
- # @else
- # @brief Initializing configuration
- #
- #
- # @endif
- #
- # virtual void init(coil::Properties& prop);
- def init(self, prop):
-
- self._rtcout.RTC_TRACE("init()")
- self._properties = prop
-
-
- self.shm_address = prop.getProperty("shared_memory.address")
- if self.shm_address:
- if self._shmem is None:
- self._shmem = mmap.mmap(0, 256, self.shm_address, mmap.ACCESS_WRITE)
- return
-
- ##
- # @if jp
- # @brief 接続先へのデータ送信
- #
- # 接続先のポートへデータを送信する
- #
- #
- # CORBAでデータサイズだけ送信して、データは共有メモリに書き込む
- #
- # @param self
- # @param data 送信するデータ
- # @return リターンコード
- #
- # @else
- # @brief Send data to the destination port
- #
- # @param self
- # @param data
- # @return
- #
- # @endif
- #
- # virtual ReturnCode put(const cdrMemoryStream& data);
- def put(self, data):
- self._rtcout.RTC_PARANOID("put()")
-
- try:
- ref_ = self.getObject()
- if ref_:
- inportcdr = ref_._narrow(OpenRTM.InPortCdr)
- #print dir(ref_)
- if self._shmem is not None:
- self._shmem.seek(os.SEEK_SET)
-
- self._shmem.write(data)
- data_size = len(data)
- mar_data_size = cdrMarshal(CORBA.TC_ushort, data_size)
-
- return self.convertReturnCode(inportcdr.put(mar_data_size))
- return self.CONNECTION_LOST
- except:
- self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
- return self.CONNECTION_LOST
-
-
-
- return self.UNKNOWN_ERROR
-
-
-def InPortSHMConsumerInit():
- factory = OpenRTM_aist.InPortConsumerFactory.instance()
- factory.addFactory("shared_memory",
- OpenRTM_aist.InPortSHMConsumer,
- OpenRTM_aist.Delete)
Deleted: trunk/OpenRTM-aist-Python/OpenRTM_aist/InPortSHMProvider.py
===================================================================
--- trunk/OpenRTM-aist-Python/OpenRTM_aist/InPortSHMProvider.py 2016-02-01 05:29:04 UTC (rev 642)
+++ trunk/OpenRTM-aist-Python/OpenRTM_aist/InPortSHMProvider.py 2016-02-01 08:37:55 UTC (rev 643)
@@ -1,177 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: euc-jp -*-
-
-##
-# @file InPortSHMProvider.py
-# @brief InPortSHMProvider class
-# @date $Date: 2016/01/08 $
-# @author Nobuhiko Miyamoto
-
-
-import sys
-from omniORB import *
-from omniORB import any
-
-import OpenRTM_aist
-import OpenRTM__POA,OpenRTM
-import mmap
-from omniORB import cdrUnmarshal
-import CORBA
-
-##
-# @if jp
-# @class InPortSHMProvider
-# @brief InPortSHMProvider クラス
-#
-# 通信手段に 共有メモリ を利用した入力ポートプロバイダーの実装クラス。
-#
-#
-# @else
-# @class InPortCorbaCdrProvider
-# @brief InPortCorbaCdrProvider class
-#
-#
-#
-# @endif
-#
-class InPortSHMProvider(OpenRTM_aist.InPortCorbaCdrProvider):
-
- """
- """
-
- ##
- # @if jp
- # @brief コンストラクタ
- #
- # コンストラクタ
- # Interface Typeにはshared_memoryを指定する
- # 共有メモリの空間名はUUIDで作成し、コネクタプロファイルのdataport.shared_memory.addressに保存する
- #
- # self
- #
- # @else
- # @brief Constructor
- #
- # Constructor
- #
- # self
- # @endif
- #
- def __init__(self):
- OpenRTM_aist.InPortCorbaCdrProvider.__init__(self)
-
- # PortProfile setting
- self.setInterfaceType("shared_memory")
-
-
-
- self._buffer = None
-
- self._profile = None
- self._listeners = None
- self._shmem = None
-
- self.shm_address = str(OpenRTM_aist.uuid1())
- self._properties.append(OpenRTM_aist.NVUtil.newNV("dataport.shared_memory.address",self.shm_address))
-
-
- return
-
- ##
- # @if jp
- # @brief デストラクタ
- #
- # デストラクタ
- #
- # @param self
- #
- # @else
- # @brief Destructor
- #
- # Destructor
- #
- # @param self
- #
- # @endif
- #
- def __del__(self):
- oid = OpenRTM_aist.Manager.instance().getPOA.servant_to_id(self)
- OpenRTM_aist.Manager.instance().getPOA.deactivate_object(oid)
-
- return
-
-
- # void init(coil::Properties& prop)
- def init(self, prop):
-
- #print prop
- pass
-
-
-
- ##
- # @if jp
- # @brief バッファにデータを書き込む
- #
- # CORBAでデータサイズだけ受信して、共有メモリからデータを取り出しバッファに書き込む
- #
- # @param data 書込対象データ
- #
- # @else
- # @brief
- #
- #
- #
- # @param data
- #
- # @endif
- #
- # ::OpenRTM::PortStatus put(const ::OpenRTM::CdrData& data)
- # throw (CORBA::SystemException);
- def put(self, data):
- #print self._connector.profile().properties
- #self._connector.profile().properties.setProperty("dataport.dataflow_type","push")
- try:
- self._rtcout.RTC_PARANOID("InPortCorbaCdrProvider.put()")
-
- if not self._buffer:
- self.onReceiverError(data)
- return OpenRTM.PORT_ERROR
-
- self._rtcout.RTC_PARANOID("received data size: %d", len(data))
-
- self.onReceived(data)
-
- if not self._connector:
- return OpenRTM.PORT_ERROR
-
- data_size = cdrUnmarshal(CORBA.TC_ushort, data)
-
- #if self._shmem is None:
- self._shmem = mmap.mmap(0, data_size, self.shm_address, mmap.ACCESS_READ)
- #shm_data = cdrUnmarshal(any.to_any(self._connector._dataType).typecode(), self._shmem.read(16),self._connector._endian)
- shm_data = self._shmem.read(data_size)
- #print dir(self._connector._provider._this())
- #print self._connector._provider._this()
- ret = self._connector.write(shm_data)
-
-
- return self.convertReturn(ret, shm_data)
-
- except:
- self._rtcout.RTC_TRACE(OpenRTM_aist.Logger.print_exception())
- return OpenRTM.UNKNOWN_ERROR
- return OpenRTM.UNKNOWN_ERROR
-
-
-
-
- return self.convertReturn(ret, data)
-
-
-
-def InPortSHMProviderInit():
- factory = OpenRTM_aist.InPortProviderFactory.instance()
- factory.addFactory("shared_memory",
- OpenRTM_aist.InPortSHMProvider,
- OpenRTM_aist.Delete)
Modified: trunk/OpenRTM-aist-Python/OpenRTM_aist/Manager.py
===================================================================
--- trunk/OpenRTM-aist-Python/OpenRTM_aist/Manager.py 2016-02-01 05:29:04 UTC (rev 642)
+++ trunk/OpenRTM-aist-Python/OpenRTM_aist/Manager.py 2016-02-01 08:37:55 UTC (rev 643)
@@ -1,3086 +1,2724 @@
-#!/usr/bin/env python
-# -*- coding: euc-jp -*-
-
-##
-# @file Manager.py
-# @brief RTComponent manager class
-# @date $Date: $
-# @author Noriaki Ando <n-ando at aist.go.jp> and Shinji Kurihara
-#
-# Copyright (C) 2006-2008
-# Task-intelligence Research Group,
-# Intelligent Systems Research Institute,
-# National Institute of
-# Advanced Industrial Science and Technology (AIST), Japan
-# All rights reserved.
-
-import threading
-import string
-import signal, os
-import traceback
-import sys
-import time
-from omniORB import CORBA, PortableServer
-from types import IntType, ListType
-
-import OpenRTM_aist
-import RTC
-import SDOPackage
-import CosNaming
-
-
-#------------------------------------------------------------
-# static var
-#------------------------------------------------------------
-
-##
-# @if jp
-# @brief 唯一の Manager へのポインタ
-# @else
-# @brief The pointer to the Manager
-# @endif
-manager = None
-
-##
-# @if jp
-# @brief 唯一の Manager へのポインタに対する mutex
-# @else
-# @brief The mutex of the pointer to the Manager
-# @endif
-mutex = threading.RLock()
-
-##
-# @if jp
-# @brief Windows用Alarm
-# @else
-# @brief Alarm for Windows
-# @endif
-import os
-import time
-import threading
-
-class Alarm (threading.Thread):
- def __init__ (self, timeout):
- threading.Thread.__init__ (self)
- self.timeout = timeout
- self.setDaemon(True)
- def run (self):
- time.sleep(self.timeout)
- os._exit(1)
-
-##
-# @if jp
-# @brief 終了処理
-#
-# マネージャを終了させる
-#
-# @param signum シグナル番号
-# @param frame 現在のスタックフレーム
-#
-# @else
-#
-# @endif
-def handler(signum, frame):
- mgr = OpenRTM_aist.Manager.instance()
- mgr.terminate()
- import os
- if os.sep == '/':
- signal.alarm(2)
- else:
- alarm = Alarm(2)
- alarm.start()
-
-
-##
-# @if jp
-# @class Manager
-# @brief Manager クラス
-#
-# コンポーネントなど各種の情報管理を行うマネージャクラス。
-#
-# @since 0.2.0
-#
-# @else
-# @class Manager
-# @brief Manager class
-# @endif
-class Manager:
- """
- """
-
-
-
- ##
- # @if jp
- # @brief コピーコンストラクタ
- #
- # コピーコンストラクタ
- #
- # @param self
- # @param _manager コピー元マネージャオブジェクト(デフォルト値:None)
- #
- # @else
- # @brief Protected Copy Constructor
- #
- # @endif
- def __init__(self, _manager=None):
- self._initProc = None
- self._runner = None
- self._terminator = None
- self._compManager = OpenRTM_aist.ObjectManager(self.InstanceName)
- self._factory = OpenRTM_aist.ObjectManager(self.FactoryPredicate)
- self._ecfactory = OpenRTM_aist.ObjectManager(self.ECFactoryPredicate)
- self._terminate = self.Term()
- self._ecs = []
- self._timer = None
- self._orb = None
- self._poa = None
- self._poaManager = None
- self._finalized = self.Finalized()
- self._listeners = OpenRTM_aist.ManagerActionListeners()
- signal.signal(signal.SIGINT, handler)
-
- return
-
-
- ##
- # @if jp
- # @brief マネージャの初期化
- #
- # マネージャを初期化する static 関数。
- # マネージャをコマンドライン引数を与えて初期化する。
- # マネージャを使用する場合は、必ずこの初期化メンバ関数 init() を
- # 呼ばなければならない。
- # マネージャのインスタンスを取得する方法として、init(), instance() の
- # 2つの static 関数が用意されているが、初期化はinit()でしか行われないため、
- # Manager の生存期間の一番最初にはinit()を呼ぶ必要がある。
- #
- # ※マネージャの初期化処理
- # - initManager: 引数処理、configファイルの読み込み、サブシステム初期化
- # - initLogger: Logger初期化
- # - initORB: ORB 初期化
- # - initNaming: NamingService 初期化
- # - initExecutionContext: ExecutionContext factory 初期化
- # - initTimer: Timer 初期化
- #
- # @param argv コマンドライン引数
- #
- # @return Manager の唯一のインスタンスの参照
- #
- # @else
- # @brief Initializa manager
- #
- # This is the static function to tintialize the Manager.
- # The Manager is initialized by given arguments.
- # At the starting the manager, this static function "must" be called from
- # application program. The manager has two static functions to get
- # the instance, "init()" and "instance()". Since initializing
- # process is only performed by the "init()" function, the "init()" has
- # to be called at the beginning of the lifecycle of the Manager.
- # function.
- #
- # @param argv The array of the command line arguments.
- #
- # @endif
- def init(*arg):
- global manager
- global mutex
-
- if len(arg) == 1:
- argv = arg[0]
- elif len(arg) == 2 and \
- isinstance(arg[0], IntType) and \
- isinstance(arg[1], ListType):
- # for 0.4.x
- argv = arg[1]
- else:
- print "Invalid arguments for init()"
- print "init(argc,argv) or init(argv)"
-
- if manager is None:
- guard = OpenRTM_aist.ScopedLock(mutex)
- if manager is None:
- manager = Manager()
- manager.initManager(argv)
- manager.initLogger()
- manager.initORB()
- manager.initNaming()
- manager.initFactories()
- manager.initExecContext()
- manager.initComposite()
- manager.initTimer()
- manager.initManagerServant()
-
- return manager
-
- init = staticmethod(init)
-
-
- ##
- # @if jp
- # @brief マネージャのインスタンスの取得
- #
- # マネージャのインスタンスを取得する static 関数。
- # この関数を呼ぶ前に、必ずこの初期化関数 init() が呼ばれている必要がある。
- #
- # @return Manager の唯一のインスタンスの参照
- #
- # @else
- #
- # @brief Get instance of the manager
- #
- # This is the static function to get the instance of the Manager.
- # Before calling this function, ensure that the initialization function
- # "init()" is called.
- #
- # @return The only instance reference of the manager
- #
- # @endif
- def instance():
- global manager
- global mutex
-
- if manager is None:
- guard = OpenRTM_aist.ScopedLock(mutex)
- if manager is None:
- manager = Manager()
- manager.initManager(None)
- manager.initLogger()
- manager.initORB()
- manager.initNaming()
- manager.initFactories()
- manager.initExecContext()
- manager.initComposite()
- manager.initTimer()
- manager.initManagerServant()
-
- return manager
-
- instance = staticmethod(instance)
-
-
- ##
- # @if jp
- # @brief マネージャ終了処理
- #
- # マネージャの終了処理を実行する。
- #
- # @param self
- #
- # @else
- #
- # @endif
- def terminate(self):
- if self._terminator:
- self._terminator.terminate()
-
-
- ##
- # @if jp
- # @brief マネージャ・シャットダウン
- #
- # マネージャの終了処理を実行する。
- # ORB終了後、同期を取って終了する。
- #
- # @param self
- #
- # @else
- #
- # @endif
- def shutdown(self):
- self._rtcout.RTC_TRACE("Manager.shutdown()")
- self._listeners.manager_.preShutdown()
- self.shutdownComponents()
- self.shutdownNaming()
- self.shutdownORB()
- self.shutdownManager()
-
- if self._runner:
- self._runner.wait()
- else:
- self.join()
-
- self._listeners.manager_.postShutdown()
- self.shutdownLogger()
- global manager
- if manager:
- manager = None
-
-
- ##
- # @if jp
- # @brief マネージャ終了処理の待ち合わせ
- #
- # 同期を取るため、マネージャ終了処理の待ち合わせを行う。
- #
- # @param self
- #
- # @else
- #
- # @endif
- def join(self):
- self._rtcout.RTC_TRACE("Manager.wait()")
- guard = OpenRTM_aist.ScopedLock(self._terminate.mutex)
- self._terminate.waiting += 1
- del guard
- while 1:
- guard = OpenRTM_aist.ScopedLock(self._terminate.mutex)
- #if self._terminate.waiting > 1:
- if self._terminate.waiting > 0:
- break
- del guard
- time.sleep(0.001)
-
-
- ##
- # @if jp
- #
- # @brief 初期化プロシージャのセット
- #
- # このオペレーションはユーザが行うモジュール等の初期化プロシージャ
- # を設定する。ここで設定されたプロシージャは、マネージャが初期化され、
- # アクティブ化された後、適切なタイミングで実行される。
- #
- # @param self
- # @param proc 初期化プロシージャの関数ポインタ
- #
- # @else
- #
- # @brief Run the Manager
- #
- # This operation sets the initial procedure call to process module
- # initialization, other user defined initialization and so on.
- # The given procedure will be called at the proper timing after the
- # manager initialization, activation and run.
- #
- # @param proc A function pointer to the initial procedure call
- #
- # @endif
- def setModuleInitProc(self, proc):
- self._initProc = proc
- return
-
-
- ##
- # @if jp
- #
- # @brief Managerのアクティブ化
- #
- # このオペレーションは以下の処理を行う
- # - CORBA POAManager のアクティブ化
- # - マネージャCORBAオブジェクトのアクティブ化
- # - Manager オブジェクトへの初期化プロシージャの実行
- #
- # このオペレーションは、マネージャの初期化後、runManager()
- # の前に呼ぶ必要がある。
- #
- # @param self
- #
- # @return 処理結果(アクティブ化成功:true、失敗:false)
- #
- # @else
- #
- # @brief Activate Manager
- #
- # This operation do the following,
- # - Activate CORBA POAManager
- # - Activate Manager CORBA object
- # - Execute the initial procedure call of the Manager
- #
- # This operationo should be invoked after Manager:init(),
- # and before tunManager().
- #
- # @endif
- def activateManager(self):
- self._rtcout.RTC_TRACE("Manager.activateManager()")
-
- try:
- self.getPOAManager().activate()
- self._rtcout.RTC_TRACE("POA Manager activated.")
- except:
- self._rtcout.RTC_ERROR("Exception: POA Manager activation failed.")
- self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
- return False
-
- lsvc_ = [s.strip() for s in self._config.getProperty("manager.local_service.modules").split(",")]
- for svc_ in lsvc_:
- if len(svc_) == 0: continue
- basename_ = svc_.split(".")[0]+"Init"
- try:
- self._module.load(svc_, basename_)
- except:
- self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
-
- self.initLocalService()
-
- mods = [s.strip() for s in self._config.getProperty("manager.modules.preload").split(",")]
-
- for i in range(len(mods)):
- if mods[i] is None or mods[i] == "":
- continue
- tmp = [mods[i]]
- OpenRTM_aist.eraseHeadBlank(tmp)
- OpenRTM_aist.eraseTailBlank(tmp)
- mods[i] = tmp[0]
-
- basename = os.path.basename(mods[i]).split(".")[0]
- basename += "Init"
-
- try:
- self._module.load(mods[i], basename)
- except:
- self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
- self.__try_direct_load(basename)
-
- sdofactory_ = OpenRTM_aist.SdoServiceConsumerFactory.instance()
- self._config.setProperty("sdo.service.consumer.available_services",
- OpenRTM_aist.flatten(sdofactory_.getIdentifiers()))
- if self._initProc:
- self._initProc(self)
-
- self.initPreCreation()
- self.initPreActivation()
- self.initPreConnection()
-
- return True
-
-
- ##
- # @if jp
- #
- # @brief Managerの実行
- #
- # このオペレーションはマネージャのメインループを実行する。
- # このメインループ内では、CORBA ORBのイベントループ等が
- # 処理される。デフォルトでは、このオペレーションはブロックし、
- # Manager::destroy() が呼ばれるまで処理を戻さない。
- # 引数 no_block が true に設定されている場合は、内部でイベントループ
- # を処理するスレッドを起動し、ブロックせずに処理を戻す。
- #
- # @param self
- # @param no_block false: ブロッキングモード, true: ノンブロッキングモード
- #
- # @else
- #
- # @brief Run the Manager
- #
- # This operation processes the main event loop of the Manager.
- # In this main loop, CORBA's ORB event loop or other processes
- # are performed. As the default behavior, this operation is going to
- # blocking mode and never returns until manager::destroy() is called.
- # When the given argument "no_block" is set to "true", this operation
- # creates a thread to process the event loop internally, and it doesn't
- # block and returns.
- #
- # @param no_block false: Blocking mode, true: non-blocking mode.
- #
- # @endif
- def runManager(self, no_block=None):
- if no_block is None:
- no_block = False
-
- if no_block:
- self._rtcout.RTC_TRACE("Manager.runManager(): non-blocking mode")
- self._runner = self.OrbRunner(self._orb)
- else:
- self._rtcout.RTC_TRACE("Manager.runManager(): blocking mode")
- try:
- self._orb.run()
- self._rtcout.RTC_TRACE("Manager.runManager(): ORB was terminated")
- self.join()
- except:
- self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
-
- return
-
-
- ##
- # @if jp
- # @brief [CORBA interface] モジュールのロード
- #
- # 指定したコンポーネントのモジュールをロードするとともに、
- # 指定した初期化関数を実行する。
- #
- # @param self
- # @param fname モジュールファイル名
- # @param initfunc 初期化関数名
- #
- # @else
- #
- # @brief [CORBA interface] Load module
- #
- # Load module (shared library, DLL etc..) by file name,
- # and invoke initialize function.
- #
- # @param fname The module file name
- # @param initfunc The initialize function name
- #
- # @endif
- def load(self, fname, initfunc):
- self._rtcout.RTC_TRACE("Manager.load(fname = %s, initfunc = %s)",
- (fname, initfunc))
- self._listeners.module_.preLoad(fname, initfunc)
- try:
- fname_ = fname.split(os.sep)
- if len(fname_) > 1:
- fname_ = fname_[-1]
- else:
- fname_ = fname_[0]
-
- if not initfunc:
- mod = [s.strip() for s in fname_.split(".")]
- initfunc = mod[0]+"Init"
- path = self._module.load(fname, initfunc)
- self._rtcout.RTC_DEBUG("module path: %s", path)
- self._listeners.module_.postLoad(path, initfunc)
- except:
- self.__try_direct_load(fname)
-
- return
-
-
- ##
- # @if jp
- #
- # @brief モジュールのアンロード
- #
- # モジュールをアンロードする
- #
- # @param self
- # @param fname モジュールのファイル名
- #
- # @else
- #
- # @brief Unload module
- #
- # Unload shared library.
- #
- # @param pathname Module file name
- #
- # @endif
- def unload(self, fname):
- self._rtcout.RTC_TRACE("Manager.unload()")
- self._listeners.module_.preUnload(fname)
- self._module.unload(fname)
- self._listeners.module_.postUnload(fname)
- return
-
-
- ##
- # @if jp
- #
- # @brief 全モジュールのアンロード
- #
- # モジュールをすべてアンロードする
- #
- # @param self
- #
- # @else
- #
- # @brief Unload module
- #
- # Unload all loaded shared library.
- #
- # @endif
- def unloadAll(self):
- self._rtcout.RTC_TRACE("Manager.unloadAll()")
- self._module.unloadAll()
- return
-
-
- ##
- # @if jp
- # @brief ロード済みのモジュールリストを取得する
- #
- # 現在マネージャにロードされているモジュールのリストを取得する。
- #
- # @param self
- #
- # @return ロード済みモジュールリスト
- #
- # @else
- # @brief Get loaded module names
- # @endif
- # std::vector<coil::Properties> getLoadedModules();
- def getLoadedModules(self):
- self._rtcout.RTC_TRACE("Manager.getLoadedModules()")
- return self._module.getLoadedModules()
-
-
- ##
- # @if jp
- # @brief ロード可能なモジュールリストを取得する
- #
- # ロード可能モジュールのリストを取得する。
- # (現在はModuleManager側で未実装)
- #
- # @param self
- #
- # @return ロード可能モジュール リスト
- #
- # @else
- # @brief Get loadable module names
- # @endif
- def getLoadableModules(self):
- self._rtcout.RTC_TRACE("Manager.getLoadableModules()")
- return self._module.getLoadableModules()
-
-
- #============================================================
- # Component Factory Management
- #============================================================
-
- ##
- # @if jp
- # @brief RTコンポーネント用ファクトリを登録する
- #
- # RTコンポーネントのインスタンスを生成するための
- # Factoryを登録する。
- #
- # @param self
- # @param profile RTコンポーネント プロファイル
- # @param new_func RTコンポーネント生成用関数
- # @param delete_func RTコンポーネント破棄用関数
- #
- # @return 登録処理結果(登録成功:true、失敗:false)
- #
- # @else
- # @brief Register RT-Component Factory
- # @endif
- def registerFactory(self, profile, new_func, delete_func):
- self._rtcout.RTC_TRACE("Manager.registerFactory(%s)", profile.getProperty("type_name"))
- try:
- factory = OpenRTM_aist.FactoryPython(profile, new_func, delete_func)
- self._factory.registerObject(factory)
- return True
- except:
- self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
- return False
-
- return
-
-
- ##
- # @if jp
- # @brief ファクトリのプロファイルを取得
- #
- # ファクトリのプロファイルを取得する。
- #
- # @return ファクトリのプロファイル
- #
- # @else
- # @brief Get profiles of factories.
- #
- # Get profiles of factories.
- #
- # @return profiles of factories
- #
- # @endif
- #
- def getFactoryProfiles(self):
- factories = self._factory.getObjects()
-
- if not factories:
- return []
-
- props = []
- for factory in factories:
- props.append(factory.profile())
-
- return props
-
-
- ##
- # @if jp
- # @brief ExecutionContext用ファクトリを登録する
- #
- # ExecutionContextのインスタンスを生成するためのFactoryを登録する。
- #
- # @param self
- # @param name 生成対象ExecutionContext名称
- # @param new_func ExecutionContext生成用関数
- # @param delete_func ExecutionContext破棄用関数
- #
- # @return 登録処理結果(登録成功:true、失敗:false)
- #
- # @else
- # @brief Register ExecutionContext Factory
- # @endif
- def registerECFactory(self, name, new_func, delete_func):
- self._rtcout.RTC_TRACE("Manager.registerECFactory(%s)", name)
- try:
- self._ecfactory.registerObject(OpenRTM_aist.ECFactoryPython(name, new_func, delete_func))
- return True
- except:
- self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
- return False
-
- return False
-
-
- ##
- # @if jp
- # @brief ファクトリ全リストを取得する
- #
- # 登録されているファクトリの全リストを取得する。
- #
- # @param self
- #
- # @return 登録ファクトリ リスト
- #
- # @else
- # @brief Get the list of all RT-Component Factory
- # @endif
- def getModulesFactories(self):
- self._rtcout.RTC_TRACE("Manager.getModulesFactories()")
-
- self._modlist = []
- for _obj in self._factory._objects._obj:
- self._modlist.append(_obj.profile().getProperty("implementation_id"))
- return self._modlist
-
-
- #============================================================
- # Component management
- #============================================================
-
- ##
- # @if jp
- # @brief RTコンポーネントを生成する
- #
- # 指定したRTコンポーネントのインスタンスを登録されたFactory経由
- # で生成する。
- #
- # 生成されるコンポーネントの各種プロファイルは以下の優先順位で
- # 設定される。
- #
- # -# createComponent() の引数で与えられたプロファイル
- # -# rtc.confで指定された外部ファイルで与えられたプロファイル
- # --# category.instance_name.config_file
- # --# category.component_type.config_file
- # -# コードに埋め込まれたプロファイル
- #
- # インスタンス生成が成功した場合、併せて以下の処理を実行する。
- # - 外部ファイルで設定したコンフィギュレーション情報の読み込み,設定
- # - ExecutionContextのバインド,動作開始
- # - ネーミングサービスへの登録
- #
- # @param comp_args 生成対象RTコンポーネントIDおよびコンフィギュレー
- # ション引数。フォーマットは大きく分けて "id" と "configuration"
- # 部分が存在する。
- #
- # comp_args: [id]?[configuration]
- # id は必須、configurationはオプション
- # id: RTC:[vendor]:[category]:[implementation_id]:[version]
- # RTC は固定かつ必須
- # vendor, category, version はオプション
- # implementation_id は必須
- # オプションを省略する場合でも ":" は省略不可
- # configuration: [key0]=[value0]&[key1]=[value1]&[key2]=[value2].....
- # RTCが持つPropertiesの値をすべて上書きすることができる。
- # key=value の形式で記述し、"&" で区切る
- #
- # 例えば、
- # RTC:jp.go.aist:example:ConfigSample:1.0?conf.default.str_param0=munya
- # RTC::example:ConfigSample:?conf.default.int_param0=100
- #
- # @return 生成したRTコンポーネントのインスタンス
- #
- # @else
- # @brief Create RT-Components
- #
- # Create specified RT-Component's instances via registered Factory.
- # When its instances have been created successfully, the following
- # processings are also executed.
- # - Read and set configuration information that was set by external file.
- # - Bind ExecutionContext and start operation.
- # - Register to naming service.
- #
- # @param module_name Target RT-Component names for the creation
- #
- # @return Created RT-Component's instances
- #
- # @endif
- #
- def createComponent(self, comp_args):
- self._rtcout.RTC_TRACE("Manager.createComponent(%s)", comp_args)
- self._listeners.rtclifecycle_.preCreate(comp_args)
- comp_prop = OpenRTM_aist.Properties()
- comp_id = OpenRTM_aist.Properties()
-
- if not self.procComponentArgs(comp_args, comp_id, comp_prop):
- return None
-
- if comp_prop.findNode("exported_ports"):
- exported_ports = OpenRTM_aist.split(comp_prop.getProperty("exported_ports"),
- ",")
- exported_ports_str = ""
- for i in range(len(exported_ports)):
- keyval = OpenRTM_aist.split(exported_ports[i], ".")
- if len(keyval) > 2:
- exported_ports_str += (keyval[0] + "." + keyval[-1])
- else:
- exported_ports_str += exported_ports[i]
-
- if i != (len(exported_ports) - 1) :
- exported_ports_str += ","
-
- comp_prop.setProperty("exported_ports", exported_ports_str)
- comp_prop.setProperty("conf.default.exported_ports", exported_ports_str)
-
- factory = self._factory.find(comp_id)
- if factory is None:
- self._rtcout.RTC_ERROR("createComponent: Factory not found: %s",
- comp_id.getProperty("implementation_id"))
-
- # automatic module loading
- mp = self._module.getLoadableModules()
- self._rtcout.RTC_INFO("%d loadable modules found", len(mp))
-
- found_obj = None
- predicate = self.ModulePredicate(comp_id)
- for _obj in mp:
- if predicate(_obj):
- found_obj = _obj
- break
-
- if not found_obj:
- self._rtcout.RTC_ERROR("No module for %s in loadable modules list",
- comp_id.getProperty("implementation_id"))
- return None
-
- if not found_obj.findNode("module_file_name"):
- self._rtcout.RTC_ERROR("Hmm...module_file_name key not found.")
- return 0
-
- # module loading
- self._rtcout.RTC_INFO("Loading module: %s", found_obj.getProperty("module_file_name"))
- self.load(found_obj.getProperty("module_file_name"), "")
- factory = self._factory.find(comp_id)
- if not factory:
- self._rtcout.RTC_ERROR("Factory not found for loaded module: %s",
- comp_id.getProperty("implementation_id"))
- return 0
-
-
- # get default configuration of component.
- prop = factory.profile()
-
- inherit_prop = ["config.version",
- "openrtm.name",
- "openrtm.version",
- "os.name",
- "os.release",
- "os.version",
- "os.arch",
- "os.hostname",
- "corba.endpoint",
- "corba.id",
- "exec_cxt.periodic.type",
- "exec_cxt.periodic.rate",
- "exec_cxt.event_driven.type",
- "exec_cxt.sync_transition",
- "exec_cxt.sync_activation",
- "exec_cxt.sync_deactivation",
- "exec_cxt.sync_reset",
- "exec_cxt.transition_timeout",
- "exec_cxt.activation_timeout",
- "exec_cxt.deactivation_timeout",
- "exec_cxt.reset_timeout",
- "logger.enable",
- "logger.log_level",
- "naming.enable",
- "naming.type",
- "naming.formats"]
-
- for i in range(len(inherit_prop)):
- if self._config.findNode(inherit_prop[i]):
- prop.setProperty(inherit_prop[i],self._config.getProperty(inherit_prop[i]))
-
- comp = factory.create(self)
-
- if comp is None:
- self._rtcout.RTC_ERROR("createComponent: RTC creation failed: %s",
- comp_id.getProperty("implementation_id"))
- return None
- self._rtcout.RTC_TRACE("RTC Created: %s", comp_id.getProperty("implementation_id"))
- self._listeners.rtclifecycle_.postCreate(comp)
-
- # The property specified by the parameter of createComponent() is merged.
- # The property("instance_name") specified by the parameter of createComponent()
- # must be merged here.
- prop.mergeProperties(comp_prop)
-
- #------------------------------------------------------------
- # Load configuration file specified in "rtc.conf"
- #
- # rtc.conf:
- # [category].[type_name].config_file = file_name
- # [category].[instance_name].config_file = file_name
- self._listeners.rtclifecycle_.preConfigure(prop)
- self.configureComponent(comp,prop)
- self._listeners.rtclifecycle_.postConfigure(prop)
-
- # The property specified by the parameter of createComponent() is set.
- # The property("exported_ports") specified by the parameter of createComponent()
- # must be set here.
- #comp.setProperties(comp_prop)
-
- # Component initialization
- self._listeners.rtclifecycle_.preInitialize()
- if comp.initialize() != RTC.RTC_OK:
- self._rtcout.RTC_TRACE("RTC initialization failed: %s",
- comp_id.getProperty("implementation_id"))
- self._rtcout.RTC_TRACE("%s was finalized", comp_id.getProperty("implementation_id"))
- if comp.exit() != RTC.RTC_OK:
- self._rtcout.RTC_DEBUG("%s finalization was failed.",
- comp_id.getProperty("implementation_id"))
- return None
-
- self._rtcout.RTC_TRACE("RTC initialization succeeded: %s",
- comp_id.getProperty("implementation_id"))
- self._listeners.rtclifecycle_.postInitialize()
- self.registerComponent(comp)
- return comp
-
-
-
- ##
- # @if jp
- # @brief RTコンポーネントを直接 Manager に登録する
- #
- # 指定したRTコンポーネントのインスタンスをファクトリ経由ではなく
- # 直接マネージャに登録する。
- #
- # @param self
- # @param comp 登録対象RTコンポーネントのインスタンス
- #
- # @return 登録処理結果(登録成功:true、失敗:false)
- #
- # @else
- # @brief Register RT-Component directly without Factory
- # @endif
- def registerComponent(self, comp):
- self._rtcout.RTC_TRACE("Manager.registerComponent(%s)", comp.getInstanceName())
-
- self._compManager.registerObject(comp)
- names = comp.getNamingNames()
-
- self._listeners.naming_.preBind(comp, names)
- for name in names:
- self._rtcout.RTC_TRACE("Bind name: %s", name)
- self._namingManager.bindObject(name, comp)
- self._listeners.naming_.postBind(comp, names)
-
- self.publishPorts(comp)
- self.subscribePorts(comp)
-
- return True
-
-
- ##
- # @if jp
- # @brief RTコンポーネントの登録を解除する
- #
- # 指定したRTコンポーネントの登録を解除する。
- #
- # @param self
- # @param comp 登録解除対象RTコンポーネントのインスタンス
- #
- # @return 登録解除処理結果(解除成功:true、解除失敗:false)
- #
- # @else
- # @brief Register RT-Component directly without Factory
- # @endif
- def unregisterComponent(self, comp):
- self._rtcout.RTC_TRACE("Manager.unregisterComponent(%s)", comp.getInstanceName())
- self._compManager.unregisterObject(comp.getInstanceName())
- names = comp.getNamingNames()
-
- self._listeners.naming_.preUnbind(comp, names)
- for name in names:
- self._rtcout.RTC_TRACE("Unbind name: %s", name)
- self._namingManager.unbindObject(name)
- self._listeners.naming_.postUnbind(comp, names)
-
- return True
-
-
- ##
- # @if jp
- # @brief Contextを生成する
- #
- # @return 生成したConetextのインスタンス
- #
- # @else
- # @brief Create Context
- #
- # @return Created Context's instances
- #
- # @endif
- #
- # ExecutionContextBase* createContext(const char* ec_args);
- def createContext(self, ec_args):
- self._rtcout.RTC_TRACE("Manager.createContext()")
- self._rtcout.RTC_TRACE("ExecutionContext type: %s",
- self._config.getProperty("exec_cxt.periodic.type"))
- ec_id = [""]
- ec_prop = OpenRTM_aist.Properties()
-
- if not self.procContextArgs(ec_args, ec_id, ec_prop):
- return None
-
- factory = self._ecfactory.find(ec_id[0])
-
- if factory == None:
- self._rtcout.RTC_ERROR("Factory not found: %s", ec_id[0])
- return None
-
- ec = factory.create()
- return ec
-
-
- ##
- # @if jp
- # @brief Manager に登録されているRTコンポーネントを削除する(未実装)
- #
- # マネージャに登録されているRTコンポーネントを削除する。
- #
- # @param self
- # @param instance_name 削除対象RTコンポーネントのインスタンス名
- #
- # @else
- # @brief Unregister RT-Component that is registered in the Manager
- # @endif
- def deleteComponent(self, instance_name=None, comp=None):
- if instance_name:
- self._rtcout.RTC_TRACE("Manager.deleteComponent(%s)", instance_name)
- _comp = self._compManager.find(instance_name)
- if _comp is None:
- self._rtcout.RTC_WARN("RTC %s was not found in manager.", instance_name)
- return
- self.deleteComponent(comp=_comp)
-
- elif comp:
- self._rtcout.RTC_TRACE("Manager.deleteComponent(RTObject_impl)")
- # cleanup from manager's table, and naming serivce
- self.unregisterComponent(comp)
-
- comp_id = comp.getProperties()
- factory = self._factory.find(comp_id)
-
- if not factory:
- self._rtcout.RTC_DEBUG("Factory not found: %s",
- comp_id.getProperty("implementation_id"))
- return
- else:
- self._rtcout.RTC_DEBUG("Factory found: %s",
- comp_id.getProperty("implementation_id"))
- factory.destroy(comp)
-
-
- if OpenRTM_aist.toBool(self._config.getProperty("manager.shutdown_on_nortcs"),
- "YES","NO",True) and \
- not OpenRTM_aist.toBool(self._config.getProperty("manager.is_master"),
- "YES","NO",False):
- comps = self.getComponents()
- if len(comps) == 0:
- self.shutdown()
-
- return
-
-
- ##
- # @if jp
- # @brief Manager に登録されているRTコンポーネントを検索する
- #
- # Manager に登録されているRTコンポーネントを指定した名称で検索し、
- # 合致するコンポーネントを取得する。
- #
- # @param self
- # @param instance_name 検索対象RTコンポーネントの名称
- #
- # @return 名称が一致するRTコンポーネントのインスタンス
- #
- # @else
- # @brief Get RT-Component's pointer
- # @endif
- def getComponent(self, instance_name):
- self._rtcout.RTC_TRACE("Manager.getComponent(%s)", instance_name)
- return self._compManager.find(instance_name)
-
-
- ##
- # @if jp
- # @brief Manager に登録されている全RTコンポーネントを取得する
- #
- # Manager に登録されているRTコンポーネントの全インスタンスを取得する。
- #
- # @param self
- #
- # @return 全RTコンポーネントのインスタンスリスト
- #
- # @else
- # @brief Get all RT-Component's pointer
- # @endif
- def getComponents(self):
- self._rtcout.RTC_TRACE("Manager.getComponents()")
- return self._compManager.getObjects()
-
-
- # void Manager::
- # addManagerActionListener(RTM::ManagerActionListener* listener,
- # bool autoclean)
- def addManagerActionListener(self, listener,autoclean=True):
- self._listeners.manager_.addListener(listener, autoclean)
- return
-
-
- # void Manager::
- # removeManagerActionListener(RTM::ManagerActionListener* listener)
- def removeManagerActionListener(self, listener):
- self._listeners.manager_.removeListener(listener)
- return
-
-
- # void Manager::
- # addModuleActionListener(RTM::ModuleActionListener* listener,
- # bool autoclean)
- def addModuleActionListener(self, listener, autoclean=True):
- self._listeners.module_.addListener(listener, autoclean)
- return
-
-
- # void Manager::
- # removeModuleActionListener(RTM::ModuleActionListener* listener)
- def removeModuleActionListener(self, listener):
- self._listeners.module_.removeListener(listener)
- return
-
-
- # void Manager::
- # addRtcLifecycleActionListener(RTM::RtcLifecycleActionListener* listener,
- # bool autoclean)
- def addRtcLifecycleActionListener(self, listener, autoclean=True):
- self._listeners.rtclifecycle_.addListener(listener, autoclean)
- return
-
-
- # void Manager::
- # removeRtcLifecycleActionListener(RTM::RtcLifecycleActionListener* listener)
- def removeRtcLifecycleActionListener(self, listener):
- self._listeners.rtclifecycle_.removeListener(listener)
- return
-
-
- # void Manager::
- # addNamingActionListener(RTM::NamingActionListener* listener,
- # bool autoclean)
- def addNamingActionListener(self, listener, autoclean=True):
- self._listeners.naming_.addListener(listener, autoclean)
- return
-
-
- # void Manager::
- # removeNamingActionListener(RTM::NamingActionListener* listener)
- def removeNamingActionListener(self, listener):
- self._listeners.naming_.removeListener(listener)
- return
-
-
- # void Manager::
- # addLocalServiceActionListener(RTM::LocalServiceActionListener* listener,
- # bool autoclean)
- def addLocalServiceActionListener(self, listener, autoclean=True):
- self._listeners.localservice_.addListener(listener, autoclean)
- return
-
-
- # void Manager::
- # removeLocalServiceActionListener(RTM::LocalServiceActionListener* listener)
- def removeLocalServiceActionListener(self, listener):
- self._listeners.localservice_.removeListener(listener)
- return
-
-
- #============================================================
- # CORBA 関連
- #============================================================
-
- ##
- # @if jp
- # @brief ORB のポインタを取得する
- #
- # Manager に設定された ORB のポインタを取得する。
- #
- # @param self
- #
- # @return ORB オブジェクト
- #
- # @else
- # @brief Get the pointer to the ORB
- # @endif
- def getORB(self):
- self._rtcout.RTC_TRACE("Manager.getORB()")
- return self._orb
-
-
- ##
- # @if jp
- # @brief Manager が持つ RootPOA のポインタを取得する
- #
- # Manager に設定された RootPOA へのポインタを取得する。
- #
- # @param self
- #
- # @return RootPOAオブジェクト
- #
- # @else
- # @brief Get the pointer to the RootPOA
- # @endif
- def getPOA(self):
- self._rtcout.RTC_TRACE("Manager.getPOA()")
- return self._poa
-
-
- ##
- # @if jp
- # @brief Manager が持つ POAManager を取得する
- #
- # Manager に設定された POAMAnager を取得する。
- #
- # @param self
- #
- # @return POAマネージャ
- #
- # @else
- #
- # @endif
- def getPOAManager(self):
- self._rtcout.RTC_TRACE("Manager.getPOAManager()")
- return self._poaManager
-
-
-
- #============================================================
- # Manager initialize and finalization
- #============================================================
-
- ##
- # @if jp
- # @brief Manager の内部初期化処理
- #
- # Manager の内部初期化処理を実行する。
- # - Manager コンフィギュレーションの設定
- # - ログ出力ファイルの設定
- # - 終了処理用スレッドの生成
- # - タイマ用スレッドの生成(タイマ使用時)
- #
- # @param self
- # @param argv コマンドライン引数
- #
- # @else
- # @brief Manager internal initialization
- # @endif
- def initManager(self, argv):
- config = OpenRTM_aist.ManagerConfig(argv)
- self._config = OpenRTM_aist.Properties()
- config.configure(self._config)
- self._config.setProperty("logger.file_name",self.formatString(self._config.getProperty("logger.file_name"),
- self._config))
- self._module = OpenRTM_aist.ModuleManager(self._config)
- self._terminator = self.Terminator(self)
- guard = OpenRTM_aist.ScopedLock(self._terminate.mutex)
- self._terminate.waiting = 0
- del guard
-
- if OpenRTM_aist.toBool(self._config.getProperty("timer.enable"), "YES", "NO", True):
- tm = OpenRTM_aist.TimeValue(0, 100000)
- tick = self._config.getProperty("timer.tick")
- if tick != "":
- tm = tm.set_time(float(tick))
- if self._timer:
- self._timer.stop()
- self._timer.join()
- self._timer = OpenRTM_aist.Timer(tm)
- self._timer.start()
-
- if OpenRTM_aist.toBool(self._config.getProperty("manager.shutdown_auto"),
- "YES", "NO", True) and \
- not OpenRTM_aist.toBool(self._config.getProperty("manager.is_master"),
- "YES", "NO", False):
- tm = OpenRTM_aist.TimeValue(10, 0)
- if self._config.findNode("manager.auto_shutdown_duration"):
- duration = float(self._config.getProperty("manager.auto_shutdown_duration"))
- if duration:
- tm.set_time(duration)
-
- if self._timer:
- self._timer.registerListenerObj(self,
- OpenRTM_aist.Manager.shutdownOnNoRtcs,
- tm)
-
- if self._timer:
- tm = OpenRTM_aist.TimeValue(1, 0)
- self._timer.registerListenerObj(self,
- OpenRTM_aist.Manager.cleanupComponents,
- tm)
-
-
- lmpm_ = [s.strip() for s in self._config.getProperty("manager.preload.modules").split(",")]
- for mpm_ in lmpm_:
- tmp = [mpm_]
- OpenRTM_aist.eraseHeadBlank(tmp)
- OpenRTM_aist.eraseTailBlank(tmp)
- mpm_ = tmp[0]
- if len(mpm_) == 0:
- continue
- basename_ = mpm_.split(".")[0]+"Init"
- try:
- self._module.load(mpm_, basename_)
- except:
- self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
-
- return
-
-
- ##
- # @if jp
- # @brief Manager の終了処理(未実装)
- #
- # Manager を終了する
- # (ただし,現在は未実装)
- #
- # @param self
- #
- # @else
- #
- # @endif
- def shutdownManager(self):
- self._rtcout.RTC_TRACE("Manager.shutdownManager()")
- if self._timer:
- self._timer.stop()
- self._timer.join()
- self._timer = None
-
- return
-
-
- ##
- # @if jp
- # @brief Manager の終了処理
- #
- # configuration の "manager.shutdown_on_nortcs" YES で、
- # コンポーネントが登録されていない場合 Manager を終了する。
- #
- # @else
- # @brief Shutdown Manager
- #
- # This method shutdowns Manager as follows.
- # - "Manager.shutdown_on_nortcs" of configuration is YES.
- # - The component is not registered.
- #
- # @endif
- #
- # void shutdownOnNoRtcs();
- def shutdownOnNoRtcs(self):
- self._rtcout.RTC_TRACE("Manager::shutdownOnNoRtcs()")
- if OpenRTM_aist.toBool(self._config.getProperty("manager.shutdown_on_nortcs"),
- "YES", "NO", True):
-
- comps = self.getComponents()
-
- if len(comps) == 0:
- self.shutdown()
-
- return
-
-
- #============================================================
- # Logger initialize and terminator
- #============================================================
-
- ##
- # @if jp
- # @brief System logger の初期化
- #
- # System logger の初期化を実行する。
- # コンフィギュレーションファイルに設定された情報に基づき、
- # ロガーの初期化,設定を実行する。
- #
- # @param self
- #
- # @return 初期化実行結果(初期化成功:true、初期化失敗:false)
- #
- # @else
- # @brief System logger initialization
- # @endif
- def initLogger(self):
-
- if not OpenRTM_aist.toBool(self._config.getProperty("logger.enable"), "YES", "NO", True):
- self._rtcout = OpenRTM_aist.LogStream()
- return True
-
- logfile = "./rtc.log"
-
- logouts = self._config.getProperty("logger.file_name")
- logouts = [s.strip() for s in logouts.split(",")]
-
- self._rtcout = None
-
- for i in range(len(logouts)):
- tmp = [logouts[i]]
- OpenRTM_aist.eraseHeadBlank(tmp)
- OpenRTM_aist.eraseTailBlank(tmp)
- logouts[i] = tmp[0]
- if logouts[i].lower() == "stdout":
- if self._rtcout is None:
- self._rtcout = OpenRTM_aist.LogStream("manager","STDOUT")
- else:
- self._rtcout.addHandler(logouts[i])
- else:
- if logouts[i] == "":
- logfile = "./rtc.log"
- else:
- logfile = logouts[i]
-
- if self._rtcout is None:
- self._rtcout = OpenRTM_aist.LogStream("manager","FILE", logfile)
- else:
- self._rtcout.addHandler("FILE",logfile)
-
- self._rtcout.setLogLevel(self._config.getProperty("logger.log_level"))
- self._rtcout.setLogLock(OpenRTM_aist.toBool(self._config.getProperty("logger.stream_lock"),
- "enable", "disable", False))
-
- self._rtcout.RTC_INFO("%s", self._config.getProperty("openrtm.version"))
- self._rtcout.RTC_INFO("Copyright (C) 2003-2010")
- self._rtcout.RTC_INFO(" Noriaki Ando")
- self._rtcout.RTC_INFO(" Intelligent Systems Research Institute, AIST")
- self._rtcout.RTC_INFO("Manager starting.")
- self._rtcout.RTC_INFO("Starting local logging.")
-
- return True
-
-
- ##
- # @if jp
- # @brief System Logger の終了処理(未実装)
- #
- # System Loggerの終了処理を実行する。
- # (現在は未実装)
- #
- # @param self
- #
- # @else
- # @brief System Logger finalization
- # @endif
- def shutdownLogger(self):
- self._rtcout.RTC_TRACE("Manager.shutdownLogger()")
- self._rtcout.shutdown()
- return
-
-
- #============================================================
- # ORB initialization and finalization
- #============================================================
-
- ##
- # @if jp
- # @brief CORBA ORB の初期化処理
- #
- # 設定情報を元にORBを初期化する。
- #
- # @param self
- #
- # @return ORB 初期化処理結果(初期化成功:true、初期化失敗:false)
- #
- # @else
- # @brief CORBA ORB initialization
- # @endif
- def initORB(self):
- self._rtcout.RTC_TRACE("Manager.initORB()")
- try:
- args = OpenRTM_aist.split(self.createORBOptions(), " ")
- args.insert(0,"manager")
- argv = OpenRTM_aist.toArgv(args)
-
- self._orb = CORBA.ORB_init(argv)
-
- self._poa = self._orb.resolve_initial_references("RootPOA")
- if CORBA.is_nil(self._poa):
- self._rtcout.RTC_ERROR("Could not resolve RootPOA")
- return False
-
- self._poaManager = self._poa._get_the_POAManager()
-
- except:
- self._rtcout.RTC_ERROR("Exception: Caught unknown exception in initORB().")
- self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
- return False
-
- return True
-
-
- ##
- # @if jp
- # @brief ORB のコマンドラインオプション作成
- #
- # コンフィギュレーション情報に設定された内容から
- # ORB の起動時オプションを作成する。
- #
- # @param self
- #
- # @return ORB 起動時オプション
- #
- # @else
- # @brief ORB command option creation
- # @endif
- def createORBOptions(self):
- opt = self._config.getProperty("corba.args")
- self._rtcout.RTC_DEBUG("corba.args: %s",opt)
-
- endpoints = []
- self.createORBEndpoints(endpoints)
- opt = [opt]
- self.createORBEndpointOption(opt,endpoints)
-
- self._rtcout.RTC_PARANOID("ORB options: %s", opt[0])
-
- return opt[0]
-
-
- ##
- # @if jp
- # @brief エンドポイントの生成
- #
- # コンフィグレーションからエンドポイントを生成する。
- #
- # @param endpoints エンドポイントリスト
- #
- # @else
- # @brief Create Endpoints
- #
- # Create Endpoints from the configuration.
- #
- # @param endpoints Endpoints list
- #
- # @endif
- #
- # void createORBEndpoints(coil::vstring& endpoints);
- def createORBEndpoints(self, endpoints):
-
- # corba.endpoint is obsolete
- # corba.endpoints with comma separated values are acceptable
- if self._config.findNode("corba.endpoints"):
- endpoints_ = [s.strip() for s in self._config.getProperty("corba.endpoints").split(",")]
- for ep in endpoints_:
- endpoints.append(ep)
-
- self._rtcout.RTC_DEBUG("corba.endpoints: %s", self._config.getProperty("corba.endpoints"))
-
- if self._config.findNode("corba.endpoint"):
- endpoints_ = [s.strip() for s in self._config.getProperty("corba.endpoint").split(",")]
- for ep in endpoints_:
- endpoints.append(ep)
- self._rtcout.RTC_DEBUG("corba.endpoint: %s", self._config.getProperty("corba.endpoint"))
-
- # If this process has master manager,
- # master manager's endpoint inserted at the top of endpoints
- self._rtcout.RTC_DEBUG("manager.is_master: %s",
- self._config.getProperty("manager.is_master"))
-
- if OpenRTM_aist.toBool(self._config.getProperty("manager.is_master"), "YES", "NO", False):
- mm = self._config.getProperty("corba.master_manager", ":2810")
- mmm = [s.strip() for s in mm.split(":")]
- if len(mmm) == 2:
- endpoints.insert(0, ":" + mmm[1])
- else:
- endpoints.insert(0, ":2810")
-
- endpoints = OpenRTM_aist.unique_sv(endpoints)
-
- return
-
-
- ##
- # @if jp
- # @brief ORB の Endpoint のコマンドラインオプション作成
- # @param opt コマンドラインオプション
- # @param endpoints エンドポイントリスト
- #
- # @else
- # @brief Create a command optional line of Endpoint of ORB.
- # @param opt ORB options
- # @param endpoints Endpoints list
- #
- # @endif
- # void createORBEndpointOption(std::string& opt, coil::vstring& endpoints);
- def createORBEndpointOption(self, opt, endpoints):
- corba = self._config.getProperty("corba.id")
- self._rtcout.RTC_DEBUG("corba.id: %s", corba)
-
- for i in range(len(endpoints)):
- if endpoints[i]:
- endpoint = endpoints[i]
- else:
- continue
-
- self._rtcout.RTC_DEBUG("Endpoint is : %s", endpoint)
- if endpoint.find(":") == -1:
- endpoint += ":"
-
- if corba == "omniORB":
- endpoint = OpenRTM_aist.normalize([endpoint])
- if OpenRTM_aist.normalize([endpoint]) == "all:":
- opt[0] += " -ORBendPointPublishAllIFs 1"
- else:
- opt[0] += " -ORBendPoint giop:tcp:" + endpoint
-
- elif corba == "TAO":
- opt[0] += "-ORBEndPoint iiop://" + endpoint
- elif corba == "MICO":
- opt[0] += "-ORBIIOPAddr inet:" + endpoint
-
- endpoints[i] = endpoint
-
- return
-
-
- ##
- # @if jp
- # @brief ORB の終了処理
- #
- # ORB の終了処理を実行する。
- # 実行待ちの処理が存在する場合には、その処理が終了するまで待つ。
- # 実際の終了処理では、POA Managerを非活性化し、 ORB のシャットダウンを実行
- # する。
- #
- # @param self
- #
- # @else
- # @brief ORB finalization
- # @endif
- def shutdownORB(self):
- self._rtcout.RTC_TRACE("Manager.shutdownORB()")
- if not self._orb:
- return
-
- try:
- while self._orb.work_pending():
- self._rtcout.RTC_PARANOID("Pending work still exists.")
- if self._orb.work_pending():
- self._orb.perform_work()
- pass
-
- self._rtcout.RTC_DEBUG("No pending works of ORB. Shutting down POA and ORB.")
- except:
- self._rtcout.RTC_TRACE(OpenRTM_aist.Logger.print_exception())
- pass
-
- if not CORBA.is_nil(self._poa):
- try:
- if not CORBA.is_nil(self._poaManager):
- self._poaManager.deactivate(False, True)
- self._rtcout.RTC_DEBUG("POA Manager was deactivated.")
- self._poa.destroy(False, True)
- self._poa = PortableServer.POA._nil
- self._rtcout.RTC_DEBUG("POA was destroyed.")
- except CORBA.SystemException, ex:
- self._rtcout.RTC_ERROR("Caught SystemException during root POA destruction")
- self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
- except:
- self._rtcout.RTC_ERROR("Caught unknown exception during destruction")
- self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
-
- if self._orb:
- try:
- self._orb.shutdown(True)
- self._rtcout.RTC_DEBUG("ORB was shutdown.")
- self._orb = CORBA.Object._nil
- except CORBA.SystemException, ex:
- self._rtcout.RTC_ERROR("Caught CORBA::SystemException during ORB shutdown.")
- self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
- except:
- self._rtcout.RTC_ERROR("Caught unknown exception during ORB shutdown.")
- self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
-
-
- #============================================================
- # NamingService initialization and finalization
- #============================================================
-
- ##
- # @if jp
- # @brief NamingManager の初期化
- #
- # NamingManager の初期化処理を実行する。
- # ただし、 NamingManager を使用しないようにプロパティ情報に設定されている
- # 場合には何もしない。
- # NamingManager を使用する場合、プロパティ情報に設定されている
- # デフォルト NamingServer を登録する。
- # また、定期的に情報を更新するように設定されている場合には、指定された周期
- # で自動更新を行うためのタイマを起動するとともに、更新用メソッドをタイマに
- # 登録する。
- #
- # @param self
- #
- # @return 初期化処理結果(初期化成功:true、初期化失敗:false)
- #
- # @else
- #
- # @endif
- def initNaming(self):
- self._rtcout.RTC_TRACE("Manager.initNaming()")
- self._namingManager = OpenRTM_aist.NamingManager(self)
-
- if not OpenRTM_aist.toBool(self._config.getProperty("naming.enable"), "YES", "NO", True):
- return True
-
- meths = OpenRTM_aist.split(self._config.getProperty("naming.type"),",")
-
- for meth in meths:
- names = OpenRTM_aist.split(self._config.getProperty(meth+".nameservers"), ",")
- for name in names:
- self._rtcout.RTC_TRACE("Register Naming Server: %s/%s", (meth, name))
- self._namingManager.registerNameServer(meth,name)
-
- if OpenRTM_aist.toBool(self._config.getProperty("naming.update.enable"), "YES", "NO", True):
- tm = OpenRTM_aist.TimeValue(10,0)
- intr = self._config.getProperty("naming.update.interval")
- if intr != "":
- tm = OpenRTM_aist.TimeValue(intr)
-
- if self._timer:
- self._timer.registerListenerObj(self._namingManager,OpenRTM_aist.NamingManager.update,tm)
-
- return True
-
-
- ##
- # @if jp
- # @brief NamingManager の終了処理
- #
- # NamingManager を終了する。
- # 登録されている全要素をアンバインドし、終了する。
- #
- # @param self
- #
- # @else
- #
- # @endif
- def shutdownNaming(self):
- self._rtcout.RTC_TRACE("Manager.shutdownNaming()")
- comps = self.getComponents()
-
- for comp in comps:
- names = comp.getNamingNames()
- self._listeners.naming_.preUnbind(comp, names);
- for name in names:
- self._namingManager.unbindObject(name)
- self._listeners.naming_.postUnbind(comp, names);
-
- self._namingManager.unbindAll()
- return
-
-
- ##
- # @if jp
- # @brief ExecutionContextManager の初期化
- #
- # 使用する各 ExecutionContext の初期化処理を実行し、各 ExecutionContext
- # 生成用 Factory を ExecutionContextManager に登録する。
- #
- # @param self
- #
- # @return ExecutionContextManager 初期化処理実行結果
- # (初期化成功:true、初期化失敗:false)
- #
- # @else
- #
- # @endif
- def initExecContext(self):
- self._rtcout.RTC_TRACE("Manager.initExecContext()")
- OpenRTM_aist.PeriodicExecutionContextInit(self)
- OpenRTM_aist.ExtTrigExecutionContextInit(self)
- OpenRTM_aist.OpenHRPExecutionContextInit(self)
- return True
-
-
- ##
- # @if jp
- # @brief PeriodicECSharedComposite の初期化
- #
- # @return PeriodicECSharedComposite 初期化処理実行結果
- # (初期化成功:true、初期化失敗:false)
- #
- # @else
- # @brief PeriodicECSharedComposite initialization
- #
- # @return PeriodicECSharedComposite initialization result
- # (Successful:true, Failed:false)
- #
- # @endif
- #
- def initComposite(self):
- self._rtcout.RTC_TRACE("Manager.initComposite()")
- OpenRTM_aist.PeriodicECSharedCompositeInit(self)
- return True
-
-
- ##
- # @if jp
- # @brief ファクトリの初期化
- #
- # バッファ、スレッド、パブリッシャ、プロバイダ、コンシューマの
- # ファクトリを初期化する。
- #
- # @return ファクトリ初期化処理実行結果
- # (初期化成功:true、初期化失敗:false)
- #
- # @else
- # @brief Factories initialization
- #
- # Initialize buffer factories, thread factories, publisher factories,
- # provider factories, and consumer factories.
- #
- # @return PeriodicECSharedComposite initialization result
- # (Successful:true, Failed:false)
- #
- # @endif
- #
- def initFactories(self):
- self._rtcout.RTC_TRACE("Manager.initFactories()")
- OpenRTM_aist.FactoryInit()
- return True
-
-
- ##
- # @if jp
- # @brief Timer の初期化
- #
- # 使用する各 Timer の初期化処理を実行する。
- # (現状の実装では何もしない)
- #
- # @param self
- #
- # @return Timer 初期化処理実行結果(初期化成功:true、初期化失敗:false)
- #
- # @else
- #
- # @endif
- def initTimer(self):
- return True
-
-
- ##
- # @if jp
- # @brief ManagerServant の初期化
- #
- # @return Timer 初期化処理実行結果(初期化成功:true、初期化失敗:false)
- #
- # @else
- # @brief ManagerServant initialization
- #
- # @return Timer Initialization result (Successful:true, Failed:false)
- #
- # @endif
- #
- def initManagerServant(self):
- self._rtcout.RTC_TRACE("Manager.initManagerServant()")
- if not OpenRTM_aist.toBool(self._config.getProperty("manager.corba_servant"),
- "YES","NO",True):
- return True
-
- self._mgrservant = OpenRTM_aist.ManagerServant()
- prop = self._config.getNode("manager")
- names = OpenRTM_aist.split(prop.getProperty("naming_formats"),",")
-
- if OpenRTM_aist.toBool(prop.getProperty("is_master"),
- "YES","NO",True):
- for name in names:
- mgr_name = self.formatString(name, prop)
- self._namingManager.bindManagerObject(mgr_name, self._mgrservant)
-
- otherref = None
-
- try:
- otherref = file(self._config.getProperty("manager.refstring_path"),'r')
- refstring = otherref.readline()
- otherref.close()
- except:
- try:
- reffile = file(self._config.getProperty("manager.refstring_path"),'w')
- except:
- self._rtcout.RTC_WARN(OpenRTM_aist.Logger.print_exception())
- return False
- else:
- reffile.write(self._orb.object_to_string(self._mgrservant.getObjRef()))
- reffile.close()
- return True
-
-
- # bool Manager::initLocalService()
- def initLocalService(self):
- self._rtcout.RTC_TRACE("Manager::initLocalService()")
- admin_ = OpenRTM_aist.LocalServiceAdmin.instance()
- prop_ = OpenRTM_aist.Properties(prop=self._config.getNode("manager.local_service"))
- admin_.init(prop_)
- self._rtcout.RTC_DEBUG("LocalServiceAdmin's properties:")
- self._rtcout.RTC_DEBUG("%s",prop_)
-
- svclist_ = admin_.getServiceProfiles()
- for svc_ in svclist_:
- self._rtcout.RTC_INFO("Available local service: %s (%s)",
- (svc_.name, svc_.uuid))
- return True
-
-
- ##
- # @if jp
- # @brief NamingManager に登録されている全コンポーネントの終了処理
- #
- # NamingManager に登録されているRTコンポーネントおよび ExecutionContext の
- # リストを取得し、全コンポーネントを終了する。
- #
- # @param self
- #
- # @else
- #
- # @endif
- def shutdownComponents(self):
- self._rtcout.RTC_TRACE("Manager.shutdownComponents()")
- comps = self._namingManager.getObjects()
- for comp in comps:
- try:
- comp.exit()
- p = OpenRTM_aist.Properties(key=comp.getInstanceName())
- p.mergeProperties(comp.getProperties())
- except:
- self._rtcout.RTC_TRACE(OpenRTM_aist.Logger.print_exception())
- pass
-
- for ec in self._ecs:
- try:
- self._poa.deactivate_object(self._poa.servant_to_id(ec))
- except:
- self._rtcout.RTC_TRACE(OpenRTM_aist.Logger.print_exception())
- pass
-
-
- ##
- # @if jp
- # @brief RTコンポーネントの登録解除
- #
- # 指定したRTコンポーネントのインスタンスをネーミングサービスから
- # 登録解除する。
- #
- # @param self
- # @param comp 登録解除対象RTコンポーネント
- #
- # @else
- #
- # @endif
- def cleanupComponent(self, comp):
- self._rtcout.RTC_TRACE("Manager.cleanupComponent()")
- self.unregisterComponent(comp)
-
- return
-
-
- ##
- # @if jp
- # @brief RTコンポーネントの削除する
- #
- # notifyFinalized()によって登録されたRTコンポーネントを削除する。
- #
- # @else
- # @brief This method deletes RT-Components.
- #
- # This method deletes RT-Components registered by notifyFinalized().
- #
- # @endif
- #
- # void cleanupComponents();
- def cleanupComponents(self):
- self._rtcout.RTC_VERBOSE("Manager.cleanupComponents()")
- guard = OpenRTM_aist.ScopedLock(self._finalized.mutex)
- self._rtcout.RTC_VERBOSE("%d components are marked as finalized.",
- len(self._finalized.comps))
- for _comp in self._finalized.comps:
- self.deleteComponent(comp=_comp)
-
- self._finalized.comps = []
- del guard
- return
-
-
- ##
- # @if jp
- # @brief RTコンポーネントの削除する
- #
- # 削除するRTコンポーネントを登録する。
- # 登録されたRTコンポーネントは cleanupComponents() で削除される。
- #
- # @param 削除するRTコンポーネント
- #
- # @else
- # @brief This method deletes RT-Components.
- #
- # The deleted RT-Component is registered. The registered RT-Components
- # are deleted by cleanupComponents().
- #
- # @param Deleted RT component
- # @endif
- #
- # void notifyFinalized(RTObject_impl* comp);
- def notifyFinalized(self, comp):
- self._rtcout.RTC_TRACE("Manager.notifyFinalized()")
- guard = OpenRTM_aist.ScopedLock(self._finalized.mutex)
- self._finalized.comps.append(comp)
- del guard
- return
-
-
- ##
- # @if jp
- # @brief createComponentの引数を処理する
- # @ param self
- # @ param comp_arg(str)
- # @ param comp_id(Properties object)
- # @ param comp_conf(Properties object)
- # @ return True or False
- # @else
- #
- # @endif
- #
- # bool procComponentArgs(const char* comp_arg,
- # coil::Properties& comp_id,
- # coil::Properties& comp_conf)
- def procComponentArgs(self, comp_arg, comp_id, comp_conf):
- id_and_conf = [s.strip() for s in comp_arg.split("?")]
- if len(id_and_conf) != 1 and len(id_and_conf) != 2:
- self._rtcout.RTC_ERROR("Invalid arguments. Two or more '?'")
- return False
-
- if id_and_conf[0].find(":") == -1:
- id_and_conf[0] = "RTC:::" + id_and_conf[0] + ":"
-
- id = [s.strip() for s in id_and_conf[0].split(":")]
-
- if len(id) != 5:
- self._rtcout.RTC_ERROR("Invalid RTC id format.")
- return False
-
- prof = ["RTC", "vendor", "category", "implementation_id", "version"]
-
- if id[0] != prof[0]:
- self._rtcout.RTC_ERROR("Invalid id type.")
- return False
-
- for i in [1,2,3,4]:
- comp_id.setProperty(prof[i], id[i])
- self._rtcout.RTC_TRACE("RTC basic profile %s: %s", (prof[i], id[i]))
-
- if len(id_and_conf) == 2:
- conf = [s.strip() for s in id_and_conf[1].split("&")]
- for i in range(len(conf)):
- keyval = [s.strip() for s in conf[i].split("=")]
- if len(keyval) > 1:
- comp_conf.setProperty(keyval[0],keyval[1])
- self._rtcout.RTC_TRACE("RTC property %s: %s", (keyval[0], keyval[1]))
-
- return True
-
-
- # bool procContextArgs(const char* ec_args,
- # std::string& ec_id,
- # coil::Properties& ec_conf);
- def procContextArgs(self, ec_args, ec_id, ec_conf):
- id_and_conf = [s.strip() for s in ec_args.split("?")]
-
- if len(id_and_conf) != 1 and len(id_and_conf) != 2:
- self._rtcout.RTC_ERROR("Invalid arguments. Two or more '?'")
- return False
-
- if (id_and_conf[0] == "") or id_and_conf[0] is None:
- self._rtcout.RTC_ERROR("Empty ExecutionContext's name")
- return False
-
- ec_id[0] = id_and_conf[0]
-
- if len(id_and_conf) == 2:
- conf = [s.strip() for s in id_and_conf[1].split("&")]
- for i in range(len(conf)):
- k = [s.strip() for s in conf[i].split("=")]
- ec_conf.setProperty(k[0],k[1])
- self._rtcout.RTC_TRACE("EC property %s: %s",(k[0],k[1]))
-
- return True
-
-
- ##
- # @if jp
- # @brief RTコンポーネントのコンフィギュレーション処理
- #
- # RTコンポーネントの型およびインスタンス毎に記載されたプロパティファイルの
- # 情報を読み込み、コンポーネントに設定する。
- # また、各コンポーネントの NamingService 登録時の名称を取得し、設定する。
- #
- # @param self
- # @param comp コンフィギュレーション対象RTコンポーネント
- #
- # @else
- #
- # @endif
- # void configureComponent(RTObject_impl* comp, const coil::Properties& prop);
- def configureComponent(self, comp, prop):
- category = comp.getCategory()
- type_name = comp.getTypeName()
- inst_name = comp.getInstanceName()
-
- type_conf = category + "." + type_name + ".config_file"
- name_conf = category + "." + inst_name + ".config_file"
-
- type_prop = OpenRTM_aist.Properties()
-
- name_prop = OpenRTM_aist.Properties()
- config_fname = []
-
- if self._config.getProperty(name_conf) != "":
- try:
- conff = open(self._config.getProperty(name_conf))
- name_prop.load(conff)
- self._rtcout.RTC_INFO("Component instance conf file: %s loaded.",
- self._config.getProperty(name_conf))
- self._rtcout.RTC_DEBUG(name_prop)
- config_fname.append(self._config.getProperty(name_conf))
- except:
- print "Not found. : %s" % self._config.getProperty(name_conf)
- self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
- else:
- name_prop.load(conff)
-
- if self._config.findNode(category + "." + inst_name):
- temp_ = OpenRTM_aist.Properties(prop=self._config.getNode(category+"."+inst_name))
- keys_ = temp_.propertyNames()
- if not (len(keys_) == 1 and keys_[-1] == "config_file"):
- name_prop.mergeProperties(self._config.getNode(category + "." + inst_name))
- self._rtcout.RTC_INFO("Component name conf exists in rtc.conf. Merged.")
- self._rtcout.RTC_DEBUG(name_prop)
- if self._config.findNode("config_file"):
- config_fname.append(self._config.getProperty("config_file"))
-
- if self._config.getProperty(type_conf) != "":
- try:
- conff = open(self._config.getProperty(type_conf))
- type_prop.load(conff)
- self._rtcout.RTC_INFO("Component type conf file: %s loaded.",
- self._config.getProperty(type_conf))
- self._rtcout.RTC_DEBUG(type_prop)
- config_fname.append(self._config.getProperty(type_conf))
- except:
- print "Not found. : %s" % self._config.getProperty(type_conf)
- self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
- else:
- type_prop.load(conff)
-
- if self._config.findNode(category + "." + type_name):
- temp_ = OpenRTM_aist.Properties(prop=self._config.getNode(category+"."+type_name))
- keys_ = temp_.propertyNames()
- if not (len(keys_) == 1 and keys_[-1] == "config_file"):
- type_prop.mergeProperties(self._config.getNode(category + "." + type_name))
- self._rtcout.RTC_INFO("Component type conf exists in rtc.conf. Merged.")
- self._rtcout.RTC_DEBUG(type_prop)
- if self._config.findNode("config_file"):
- config_fname.append(self._config.getProperty("config_file"))
-
- comp.setProperties(prop)
- type_prop.mergeProperties(name_prop)
- type_prop.setProperty("config_file",OpenRTM_aist.flatten(OpenRTM_aist.unique_sv(config_fname)))
- comp.setProperties(type_prop)
-
- comp_prop = OpenRTM_aist.Properties(prop=comp.getProperties())
-
- naming_formats = self._config.getProperty("naming.formats")
- if comp_prop.findNode("naming.formats"):
- naming_formats = comp_prop.getProperty("naming.formats")
- naming_formats = OpenRTM_aist.flatten(OpenRTM_aist.unique_sv(OpenRTM_aist.split(naming_formats, ",")))
-
- naming_names = self.formatString(naming_formats, comp.getProperties())
- comp.getProperties().setProperty("naming.formats",naming_formats)
- comp.getProperties().setProperty("naming.names",naming_names)
- return
-
-
- ##
- # @if jp
- # @brief プロパティ情報のマージ
- #
- # 指定されたファイル内に設定されているプロパティ情報をロードし、
- # 既存の設定済みプロパティとマージする。
- #
- # @param self
- # @param prop マージ対象プロパティ
- # @param file_name プロパティ情報が記述されているファイル名
- #
- # @return マージ処理実行結果(マージ成功:true、マージ失敗:false)
- #
- # @else
- #
- # @endif
- def mergeProperty(self, prop, file_name):
- if file_name == "":
- self._rtcout.RTC_ERROR("Invalid configuration file name.")
- return False
-
- if file_name[0] != '\0':
-
- try:
- conff = open(file_name)
- except:
- print "Not found. : %s" % file_name
- self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
- else:
- prop.load(conff)
- conff.close()
- return True
-
- return False
-
-
- ##
- # @if jp
- # @brief NamingServer に登録する際の登録情報を組み立てる
- #
- # 指定された書式とプロパティ情報を基に NameServer に登録する際の情報を
- # 組み立てる。
- # 各書式指定用文字の意味は以下のとおり
- # - % : コンテキストの区切り
- # - n : インスタンス名称
- # - t : 型名
- # - m : 型名
- # - v : バージョン
- # - V : ベンダー
- # - c : カテゴリ
- # - h : ホスト名
- # - M : マネージャ名
- # - p : プロセスID
- #
- # @param self
- # @param naming_format NamingService 登録情報書式指定
- # @param prop 使用するプロパティ情報
- #
- # @return 指定書式変換結果
- #
- # @else
- #
- # @endif
- def formatString(self, naming_format, prop):
- name_ = naming_format
- str_ = ""
- count = 0
- len_ = len(name_)
- it = iter(name_)
-
- try:
- while 1:
- n = it.next()
- if n == '%':
- count+=1
- if not (count % 2):
- str_ += n
- elif n == '$':
- count = 0
- n = it.next()
- if n == '{' or n == '(':
- n = it.next()
- env = ""
- for i in xrange(len_):
- if n == '}' or n == ')':
- break
- env += n
- n = it.next()
- envval = os.getenv(env)
- if envval:
- str_ += envval
- else:
- str_ += n
- else:
- if count > 0 and (count % 2):
- count = 0
- if n == "n": str_ += prop.getProperty("instance_name")
- elif n == "t": str_ += prop.getProperty("type_name")
- elif n == "m": str_ += prop.getProperty("type_name")
- elif n == "v": str_ += prop.getProperty("version")
- elif n == "V": str_ += prop.getProperty("vendor")
- elif n == "c": str_ += prop.getProperty("category")
- elif n == "h": str_ += self._config.getProperty("manager.os.hostname")
- elif n == "M": str_ += self._config.getProperty("manager.name")
- elif n == "p": str_ += str(self._config.getProperty("manager.pid"))
- else: str_ += n
- else:
- count = 0
- str_ += n
- except:
- # Caught StopIteration exception.
- return str_
-
- return str_
-
-
- ##
- # @if jp
- # @brief ログバッファの取得
- #
- # マネージャに設定したログバッファを取得する。
- #
- # @param self
- #
- # @return マネージャに設定したログバッファ
- #
- # @else
- #
- # @endif
- def getLogbuf(self,name="manager"):
- if not OpenRTM_aist.toBool(self._config.getProperty("logger.enable"), "YES", "NO", True):
- return OpenRTM_aist.LogStream()
-
- logbuf = OpenRTM_aist.LogStream(name)
- logbuf.setLogLevel(self._config.getProperty("logger.log_level"))
- return logbuf
-
-
- ##
- # @if jp
- # @brief マネージャコンフィギュレーションの取得
- #
- # マネージャに設定したコンフィギュレーションを取得する。
- #
- # @param self
- #
- # @return マネージャのコンフィギュレーション
- #
- # @else
- #
- # @endif
- def getConfig(self):
- return self._config
-
-
- ##
- # @if jp
- # @brief コンポーネントファイル(.py)から
- #
- # マネージャに設定したコンフィギュレーションを取得する。
- #
- # @param self
- #
- # @return マネージャのコンフィギュレーション
- #
- # @else
- #
- # @endif
- def __try_direct_load(self, file_name):
- try:
- pathChanged=False
- splitted_name = os.path.split(file_name)
- save_path = sys.path[:]
- sys.path.append(splitted_name[0])
- import_name = splitted_name[-1].split(".py")[0]
- mo = __import__(import_name)
- sys.path = save_path
- _spec = getattr(mo,import_name.lower()+"_spec",None)
- _klass = getattr(mo,import_name,None)
- if _spec and _klass:
- prof = OpenRTM_aist.Properties(defaults_str=_spec)
- self.registerFactory(prof,
- _klass,
- OpenRTM_aist.Delete)
- except:
- self._rtcout.RTC_ERROR("Module load error: %s", file_name)
- self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
-
- return
-
-
-
-
- ##
- # @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&~),~
- # @param self
- # @else
- #
- # @brief
- # @param self
- # @endif
- # void initPreConnection()
- def initPreConnection(self):
- self._rtcout.RTC_TRACE("Connection pre-creation: %s" % str(self._config.getProperty("manager.components.preconnect")))
- connectors = str(self._config.getProperty("manager.components.preconnect")).split(",")
- for c in connectors:
- tmp = [c]
- OpenRTM_aist.eraseHeadBlank(tmp)
- OpenRTM_aist.eraseTailBlank(tmp)
- c = tmp[0]
- if len(c) == 0:
- continue
- conn_prop = c.split("(")
- if len(conn_prop) < 2:
- self._rtcout.RTC_ERROR("Invalid format for pre-connection.")
- continue
- conn_prop[1] = conn_prop[1].replace(")","")
- comp_ports = conn_prop[0].split(":")
- if len(comp_ports) != 2:
- self._rtcout.RTC_ERROR("Invalid format for pre-connection.")
- self._rtcout.RTC_ERROR("Format must be Comp0.port0:Comp1.port1")
- continue
-
- comp0_name = comp_ports[0].split(".")[0]
- comp0 = self.getComponent(comp0_name)
-
- if comp0 is None:
- self._rtcout.RTC_ERROR("%s not found." % comp0_name)
- continue
-
- port0_var = OpenRTM_aist.CORBA_RTCUtil.get_port_by_name(comp0.getObjRef(), comp_ports[0])
- if CORBA.is_nil(port0_var):
- self._rtcout.RTC_DEBUG("port %s found: " % comp_ports[0])
- continue
-
- comp1_name = comp_ports[1].split(".")[0]
- comp1 = self.getComponent(comp1_name)
-
- if comp1 is None:
- self._rtcout.RTC_ERROR("%s not found." % comp1_name)
- continue
-
- port1_var = OpenRTM_aist.CORBA_RTCUtil.get_port_by_name(comp1.getObjRef(), comp_ports[1])
- if CORBA.is_nil(port1_var):
- self._rtcout.RTC_DEBUG("port %s found: " % comp_ports[1])
- continue
-
- prop = OpenRTM_aist.Properties()
- opt_props = conn_prop[1].split("&")
- for o in opt_props:
- temp = o.split("=")
- if len(temp) == 2:
- prop.setProperty("dataport."+temp[0],temp[1])
- if RTC.RTC_OK != OpenRTM_aist.CORBA_RTCUtil.connect(c, prop, port0_var, port1_var):
- self._rtcout.RTC_ERROR("Connection error: %s" % c)
-
-
-
-
- ##
- # @if jp
- # @brief 起動時にrtc.confで指定したRTCをアクティベーションする
- # 例:
- # manager.components.preactivate RTC1,RTC2~
- # @param self
- # @else
- #
- # @brief
- # @param self
- # @endif
- # void initPreActivation()
- def initPreActivation(self):
-
- self._rtcout.RTC_TRACE("Components pre-activation: %s" % str(self._config.getProperty("manager.components.preactivate")))
- comps = str(self._config.getProperty("manager.components.preactivate")).split(",")
- for c in comps:
- tmp = [c]
- OpenRTM_aist.eraseHeadBlank(tmp)
- OpenRTM_aist.eraseTailBlank(tmp)
- c = tmp[0]
- if c:
- comp = self.getComponent(c)
-
- if comp is None:
- self._rtcout.RTC_ERROR("%s not found." % c)
- continue
- ret = OpenRTM_aist.CORBA_RTCUtil.activate(comp.getObjRef())
- if ret != RTC.RTC_OK:
- self._rtcout.RTC_ERROR("%s activation filed." % c)
- else:
- self._rtcout.RTC_INFO("%s activated." % c)
-
-
- ##
- # @if jp
- # @brief 起動時にrtc.confで指定したRTCを生成する
- # 例:
- # manager.components.precreate RTC1,RTC2~
- # @param self
- # @else
- #
- # @brief
- # @param self
- # @endif
- # void initPreCreation()
- def initPreCreation(self):
- comps = [s.strip() for s in self._config.getProperty("manager.components.precreate").split(",")]
- for i in range(len(comps)):
- if comps[i] is None or comps[i] == "":
- continue
- tmp = [comps[i]]
- OpenRTM_aist.eraseHeadBlank(tmp)
- OpenRTM_aist.eraseTailBlank(tmp)
- comps[i] = tmp[0]
-
- self.createComponent(comps[i])
-
-
-
- #============================================================
- # コンポーネントマネージャ
- #============================================================
- ##
- # @if jp
- # @class InstanceName
- # @brief ObjectManager 検索用ファンクタ
- #
- # @else
- #
- # @endif
- class InstanceName:
- """
- """
-
- ##
- # @if jp
- # @brief コンストラクタ
- #
- # コンストラクタ
- #
- # @param self
- # @param name 検索対象コンポーネント名称(デフォルト値:None)
- # @param factory 検索対象ファクトリ名称(デフォルト値:None)
- #
- # @else
- #
- # @endif
- def __init__(self, name=None, factory=None, prop=None):
- if prop:
- self._name = prop.getInstanceName()
- if factory:
- self._name = factory.getInstanceName()
- elif name:
- self._name = name
-
- def __call__(self, factory):
- return self._name == factory.getInstanceName()
-
-
-
- #============================================================
- # コンポーネントファクトリ
- #============================================================
- ##
- # @if jp
- # @class FactoryPredicate
- # @brief コンポーネントファクトリ検索用ファンクタ
- #
- # @else
- #
- # @endif
- class FactoryPredicate:
-
- def __init__(self, name=None, prop=None, factory=None):
- if name:
- self._vendor = ""
- self._category = ""
- self._impleid = name
- self._version = ""
- elif prop:
- self._vendor = prop.getProperty("vendor")
- self._category = prop.getProperty("category")
- self._impleid = prop.getProperty("implementation_id")
- self._version = prop.getProperty("version")
- elif factory:
- self._vendor = factory.profile().getProperty("vendor")
- self._category = factory.profile().getProperty("category")
- self._impleid = factory.profile().getProperty("implementation_id")
- self._version = factory.profile().getProperty("version")
-
-
- def __call__(self, factory):
- if self._impleid == "":
- return False
-
- _prop = OpenRTM_aist.Properties(prop=factory.profile())
-
- if self._impleid != _prop.getProperty("implementation_id"):
- return False
-
- if self._vendor != "" and self._vendor != _prop.getProperty("vendor"):
- return False
-
- if self._category != "" and self._category != _prop.getProperty("category"):
- return False
-
- if self._version != "" and self._version != _prop.getProperty("version"):
- return False
-
- return True
-
-
-
- #============================================================
- # ExecutionContextファクトリ
- #============================================================
- ##
- # @if jp
- # @class ECFactoryPredicate
- # @brief ExecutionContextファクトリ検索用ファンクタ
- #
- # @else
- #
- # @endif
- class ECFactoryPredicate:
-
-
-
- def __init__(self, name=None, factory=None):
- if name:
- self._name = name
- elif factory:
- self._name = factory.name()
-
- def __call__(self, factory):
- return self._name == factory.name()
-
-
- #============================================================
- # Module Fanctor
- #============================================================
- ##
- # @if jp
- # @class ModulePredicate
- # @brief Module検索用ファンクタ
- #
- # @else
- #
- # @endif
- class ModulePredicate:
-
- # ModulePredicate(coil::Properties& prop)
- def __init__(self, prop):
- self._prop = prop
- return
-
- # bool operator()(coil::Properties& prop)
- def __call__(self, prop):
-
- if self._prop.getProperty("implementation_id") != prop.getProperty("implementation_id"):
- return False
-
- if self._prop.getProperty("vendor") and \
- self._prop.getProperty("vendor") != prop.getProperty("vendor"):
- return False
-
- if self._prop.getProperty("category") and \
- self._prop.getProperty("category") != prop.getProperty("category"):
- return False
-
- if self._prop.getProperty("version") and \
- self._prop.getProperty("version") != prop.getProperty("version"):
- return False
-
- return True
-
-
- #------------------------------------------------------------
- # ORB runner
- #------------------------------------------------------------
- ##
- # @if jp
- # @class OrbRunner
- # @brief OrbRunner クラス
- #
- # ORB 実行用ヘルパークラス。
- #
- # @since 0.4.0
- #
- # @else
- # @class OrbRunner
- # @brief OrbRunner class
- # @endif
- class OrbRunner:
- """
- """
-
- ##
- # @if jp
- # @brief コンストラクタ
- #
- # コンストラクタ
- #
- # @param self
- # @param orb ORB
- #
- # @else
- # @brief Constructor
- #
- # @endif
- def __init__(self, orb):
- self._orb = orb
- self._th = threading.Thread(target=self.run)
- self._th.start()
-
-
- def __del__(self):
- self._th.join()
- self._th = None
- return
-
-
- ##
- # @if jp
- # @brief ORB 実行処理
- #
- # ORB 実行
- #
- # @param self
- #
- # @else
- #
- # @endif
- def run(self):
- try:
- self._orb.run()
- #Manager.instance().shutdown()
- except:
- print OpenRTM_aist.Logger.print_exception()
- pass
- return
-
-
- ##
- # @if jp
- # @brief ORB wait処理
- #
- # ORB wait
- #
- # @param self
- #
- # @else
- #
- # @endif
- def wait(self):
- return
-
- ##
- # @if jp
- # @brief ORB 終了処理(未実装)
- #
- # ORB 終了処理
- #
- # @param self
- # @param flags 終了処理フラグ
- #
- # @return 終了処理結果
- #
- # @else
- #
- # @endif
- def close(self, flags):
- return 0
-
-
- #------------------------------------------------------------
- # Manager Terminator
- #------------------------------------------------------------
- ##
- # @if jp
- # @class Terminator
- # @brief Terminator クラス
- #
- # ORB 終了用ヘルパークラス。
- #
- # @since 0.4.0
- #
- # @else
- #
- # @endif
- class Terminator:
- """
- """
-
- ##
- # @if jp
- # @brief コンストラクタ
- #
- # コンストラクタ
- #
- # @param self
- # @param manager マネージャ・オブジェクト
- #
- # @else
- # @brief Constructor
- #
- # @endif
- def __init__(self, manager):
- self._manager = manager
-
-
- ##
- # @if jp
- # @brief 終了処理
- #
- # ORB,マネージャ終了処理を開始する。
- #
- # @param self
- #
- # @else
- #
- # @endif
- def terminate(self):
- self._manager.shutdown()
-
-
-
- ##
- # @if jp
- # @class Term
- # @brief Term クラス
- #
- # 終了用ヘルパークラス。
- #
- # @since 0.4.0
- #
- # @else
- #
- # @endif
- class Term:
- def __init__(self):
- self.waiting = 0
- self.mutex = threading.RLock()
-
-
- class Finalized:
- def __init__(self):
- self.mutex = threading.RLock()
- self.comps = []
+#!/usr/bin/env python
+# -*- coding: euc-jp -*-
+
+##
+# @file Manager.py
+# @brief RTComponent manager class
+# @date $Date: $
+# @author Noriaki Ando <n-ando at aist.go.jp> and Shinji Kurihara
+#
+# Copyright (C) 2006-2008
+# Task-intelligence Research Group,
+# Intelligent Systems Research Institute,
+# National Institute of
+# Advanced Industrial Science and Technology (AIST), Japan
+# All rights reserved.
+
+import threading
+import string
+import signal, os
+import traceback
+import sys
+import time
+from omniORB import CORBA, PortableServer
+from types import IntType, ListType
+
+import OpenRTM_aist
+import RTC
+import SDOPackage
+
+
+#------------------------------------------------------------
+# static var
+#------------------------------------------------------------
+
+##
+# @if jp
+# @brief 唯一の Manager へのポインタ
+# @else
+# @brief The pointer to the Manager
+# @endif
+manager = None
+
+##
+# @if jp
+# @brief 唯一の Manager へのポインタに対する mutex
+# @else
+# @brief The mutex of the pointer to the Manager
+# @endif
+mutex = threading.RLock()
+
+##
+# @if jp
+# @brief Windows用Alarm
+# @else
+# @brief Alarm for Windows
+# @endif
+import os
+import time
+import threading
+
+class Alarm (threading.Thread):
+ def __init__ (self, timeout):
+ threading.Thread.__init__ (self)
+ self.timeout = timeout
+ self.setDaemon(True)
+ def run (self):
+ time.sleep(self.timeout)
+ os._exit(1)
+
+##
+# @if jp
+# @brief 終了処理
+#
+# マネージャを終了させる
+#
+# @param signum シグナル番号
+# @param frame 現在のスタックフレーム
+#
+# @else
+#
+# @endif
+def handler(signum, frame):
+ mgr = OpenRTM_aist.Manager.instance()
+ mgr.terminate()
+ import os
+ if os.sep == '/':
+ signal.alarm(2)
+ else:
+ alarm = Alarm(2)
+ alarm.start()
+
+
+##
+# @if jp
+# @class Manager
+# @brief Manager クラス
+#
+# コンポーネントなど各種の情報管理を行うマネージャクラス。
+#
+# @since 0.2.0
+#
+# @else
+# @class Manager
+# @brief Manager class
+# @endif
+class Manager:
+ """
+ """
+
+
+
+ ##
+ # @if jp
+ # @brief コピーコンストラクタ
+ #
+ # コピーコンストラクタ
+ #
+ # @param self
+ # @param _manager コピー元マネージャオブジェクト(デフォルト値:None)
+ #
+ # @else
+ # @brief Protected Copy Constructor
+ #
+ # @endif
+ def __init__(self, _manager=None):
+ self._initProc = None
+ self._runner = None
+ self._terminator = None
+ self._compManager = OpenRTM_aist.ObjectManager(self.InstanceName)
+ self._factory = OpenRTM_aist.ObjectManager(self.FactoryPredicate)
+ self._ecfactory = OpenRTM_aist.ObjectManager(self.ECFactoryPredicate)
+ self._terminate = self.Term()
+ self._ecs = []
+ self._timer = None
+ self._orb = None
+ self._poa = None
+ self._poaManager = None
+ self._finalized = self.Finalized()
+ self._listeners = OpenRTM_aist.ManagerActionListeners()
+ signal.signal(signal.SIGINT, handler)
+
+ return
+
+
+ ##
+ # @if jp
+ # @brief マネージャの初期化
+ #
+ # マネージャを初期化する static 関数。
+ # マネージャをコマンドライン引数を与えて初期化する。
+ # マネージャを使用する場合は、必ずこの初期化メンバ関数 init() を
+ # 呼ばなければならない。
+ # マネージャのインスタンスを取得する方法として、init(), instance() の
+ # 2つの static 関数が用意されているが、初期化はinit()でしか行われないため、
+ # Manager の生存期間の一番最初にはinit()を呼ぶ必要がある。
+ #
+ # ※マネージャの初期化処理
+ # - initManager: 引数処理、configファイルの読み込み、サブシステム初期化
+ # - initLogger: Logger初期化
+ # - initORB: ORB 初期化
+ # - initNaming: NamingService 初期化
+ # - initExecutionContext: ExecutionContext factory 初期化
+ # - initTimer: Timer 初期化
+ #
+ # @param argv コマンドライン引数
+ #
+ # @return Manager の唯一のインスタンスの参照
+ #
+ # @else
+ # @brief Initializa manager
+ #
+ # This is the static function to tintialize the Manager.
+ # The Manager is initialized by given arguments.
+ # At the starting the manager, this static function "must" be called from
+ # application program. The manager has two static functions to get
+ # the instance, "init()" and "instance()". Since initializing
+ # process is only performed by the "init()" function, the "init()" has
+ # to be called at the beginning of the lifecycle of the Manager.
+ # function.
+ #
+ # @param argv The array of the command line arguments.
+ #
+ # @endif
+ def init(*arg):
+ global manager
+ global mutex
+
+ if len(arg) == 1:
+ argv = arg[0]
+ elif len(arg) == 2 and \
+ isinstance(arg[0], IntType) and \
+ isinstance(arg[1], ListType):
+ # for 0.4.x
+ argv = arg[1]
+ else:
+ print "Invalid arguments for init()"
+ print "init(argc,argv) or init(argv)"
+
+ if manager is None:
+ guard = OpenRTM_aist.ScopedLock(mutex)
+ if manager is None:
+ manager = Manager()
+ manager.initManager(argv)
+ manager.initLogger()
+ manager.initORB()
+ manager.initNaming()
+ manager.initFactories()
+ manager.initExecContext()
+ manager.initComposite()
+ manager.initTimer()
+ manager.initManagerServant()
+
+ return manager
+
+ init = staticmethod(init)
+
+
+ ##
+ # @if jp
+ # @brief マネージャのインスタンスの取得
+ #
+ # マネージャのインスタンスを取得する static 関数。
+ # この関数を呼ぶ前に、必ずこの初期化関数 init() が呼ばれている必要がある。
+ #
+ # @return Manager の唯一のインスタンスの参照
+ #
+ # @else
+ #
+ # @brief Get instance of the manager
+ #
+ # This is the static function to get the instance of the Manager.
+ # Before calling this function, ensure that the initialization function
+ # "init()" is called.
+ #
+ # @return The only instance reference of the manager
+ #
+ # @endif
+ def instance():
+ global manager
+ global mutex
+
+ if manager is None:
+ guard = OpenRTM_aist.ScopedLock(mutex)
+ if manager is None:
+ manager = Manager()
+ manager.initManager(None)
+ manager.initLogger()
+ manager.initORB()
+ manager.initNaming()
+ manager.initFactories()
+ manager.initExecContext()
+ manager.initComposite()
+ manager.initTimer()
+ manager.initManagerServant()
+
+ return manager
+
+ instance = staticmethod(instance)
+
+
+ ##
+ # @if jp
+ # @brief マネージャ終了処理
+ #
+ # マネージャの終了処理を実行する。
+ #
+ # @param self
+ #
+ # @else
+ #
+ # @endif
+ def terminate(self):
+ if self._terminator:
+ self._terminator.terminate()
+
+
+ ##
+ # @if jp
+ # @brief マネージャ・シャットダウン
+ #
+ # マネージャの終了処理を実行する。
+ # ORB終了後、同期を取って終了する。
+ #
+ # @param self
+ #
+ # @else
+ #
+ # @endif
+ def shutdown(self):
+ self._rtcout.RTC_TRACE("Manager.shutdown()")
+ self._listeners.manager_.preShutdown()
+ self.shutdownComponents()
+ self.shutdownNaming()
+ self.shutdownORB()
+ self.shutdownManager()
+
+ if self._runner:
+ self._runner.wait()
+ else:
+ self.join()
+
+ self._listeners.manager_.postShutdown()
+ self.shutdownLogger()
+ global manager
+ if manager:
+ manager = None
+
+
+ ##
+ # @if jp
+ # @brief マネージャ終了処理の待ち合わせ
+ #
+ # 同期を取るため、マネージャ終了処理の待ち合わせを行う。
+ #
+ # @param self
+ #
+ # @else
+ #
+ # @endif
+ def join(self):
+ self._rtcout.RTC_TRACE("Manager.wait()")
+ guard = OpenRTM_aist.ScopedLock(self._terminate.mutex)
+ self._terminate.waiting += 1
+ del guard
+ while 1:
+ guard = OpenRTM_aist.ScopedLock(self._terminate.mutex)
+ #if self._terminate.waiting > 1:
+ if self._terminate.waiting > 0:
+ break
+ del guard
+ time.sleep(0.001)
+
+
+ ##
+ # @if jp
+ #
+ # @brief 初期化プロシージャのセット
+ #
+ # このオペレーションはユーザが行うモジュール等の初期化プロシージャ
+ # を設定する。ここで設定されたプロシージャは、マネージャが初期化され、
+ # アクティブ化された後、適切なタイミングで実行される。
+ #
+ # @param self
+ # @param proc 初期化プロシージャの関数ポインタ
+ #
+ # @else
+ #
+ # @brief Run the Manager
+ #
+ # This operation sets the initial procedure call to process module
+ # initialization, other user defined initialization and so on.
+ # The given procedure will be called at the proper timing after the
+ # manager initialization, activation and run.
+ #
+ # @param proc A function pointer to the initial procedure call
+ #
+ # @endif
+ def setModuleInitProc(self, proc):
+ self._initProc = proc
+ return
+
+
+ ##
+ # @if jp
+ #
+ # @brief Managerのアクティブ化
+ #
+ # このオペレーションは以下の処理を行う
+ # - CORBA POAManager のアクティブ化
+ # - マネージャCORBAオブジェクトのアクティブ化
+ # - Manager オブジェクトへの初期化プロシージャの実行
+ #
+ # このオペレーションは、マネージャの初期化後、runManager()
+ # の前に呼ぶ必要がある。
+ #
+ # @param self
+ #
+ # @return 処理結果(アクティブ化成功:true、失敗:false)
+ #
+ # @else
+ #
+ # @brief Activate Manager
+ #
+ # This operation do the following,
+ # - Activate CORBA POAManager
+ # - Activate Manager CORBA object
+ # - Execute the initial procedure call of the Manager
+ #
+ # This operationo should be invoked after Manager:init(),
+ # and before tunManager().
+ #
+ # @endif
+ def activateManager(self):
+ self._rtcout.RTC_TRACE("Manager.activateManager()")
+
+ try:
+ self.getPOAManager().activate()
+ self._rtcout.RTC_TRACE("POA Manager activated.")
+ except:
+ self._rtcout.RTC_ERROR("Exception: POA Manager activation failed.")
+ self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
+ return False
+
+ lsvc_ = [s.strip() for s in self._config.getProperty("manager.local_service.modules").split(",")]
+ for svc_ in lsvc_:
+ if len(svc_) == 0: continue
+ basename_ = svc_.split(".")[0]+"Init"
+ try:
+ self._module.load(svc_, basename_)
+ except:
+ self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
+
+ self.initLocalService()
+
+ mods = [s.strip() for s in self._config.getProperty("manager.modules.preload").split(",")]
+
+ for i in range(len(mods)):
+ if mods[i] is None or mods[i] == "":
+ continue
+ tmp = [mods[i]]
+ OpenRTM_aist.eraseHeadBlank(tmp)
+ OpenRTM_aist.eraseTailBlank(tmp)
+ mods[i] = tmp[0]
+
+ basename = os.path.basename(mods[i]).split(".")[0]
+ basename += "Init"
+
+ try:
+ self._module.load(mods[i], basename)
+ except:
+ self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
+ self.__try_direct_load(basename)
+
+ sdofactory_ = OpenRTM_aist.SdoServiceConsumerFactory.instance()
+ self._config.setProperty("sdo.service.consumer.available_services",
+ OpenRTM_aist.flatten(sdofactory_.getIdentifiers()))
+ if self._initProc:
+ self._initProc(self)
+
+ comps = [s.strip() for s in self._config.getProperty("manager.components.precreate").split(",")]
+ for i in range(len(comps)):
+ if comps[i] is None or comps[i] == "":
+ continue
+ tmp = [comps[i]]
+ OpenRTM_aist.eraseHeadBlank(tmp)
+ OpenRTM_aist.eraseTailBlank(tmp)
+ comps[i] = tmp[0]
+
+ self.createComponent(comps[i])
+
+ return True
+
+
+ ##
+ # @if jp
+ #
+ # @brief Managerの実行
+ #
+ # このオペレーションはマネージャのメインループを実行する。
+ # このメインループ内では、CORBA ORBのイベントループ等が
+ # 処理される。デフォルトでは、このオペレーションはブロックし、
+ # Manager::destroy() が呼ばれるまで処理を戻さない。
+ # 引数 no_block が true に設定されている場合は、内部でイベントループ
+ # を処理するスレッドを起動し、ブロックせずに処理を戻す。
+ #
+ # @param self
+ # @param no_block false: ブロッキングモード, true: ノンブロッキングモード
+ #
+ # @else
+ #
+ # @brief Run the Manager
+ #
+ # This operation processes the main event loop of the Manager.
+ # In this main loop, CORBA's ORB event loop or other processes
+ # are performed. As the default behavior, this operation is going to
+ # blocking mode and never returns until manager::destroy() is called.
+ # When the given argument "no_block" is set to "true", this operation
+ # creates a thread to process the event loop internally, and it doesn't
+ # block and returns.
+ #
+ # @param no_block false: Blocking mode, true: non-blocking mode.
+ #
+ # @endif
+ def runManager(self, no_block=None):
+ if no_block is None:
+ no_block = False
+
+ if no_block:
+ self._rtcout.RTC_TRACE("Manager.runManager(): non-blocking mode")
+ self._runner = self.OrbRunner(self._orb)
+ else:
+ self._rtcout.RTC_TRACE("Manager.runManager(): blocking mode")
+ try:
+ self._orb.run()
+ self._rtcout.RTC_TRACE("Manager.runManager(): ORB was terminated")
+ self.join()
+ except:
+ self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
+
+ return
+
+
+ ##
+ # @if jp
+ # @brief [CORBA interface] モジュールのロード
+ #
+ # 指定したコンポーネントのモジュールをロードするとともに、
+ # 指定した初期化関数を実行する。
+ #
+ # @param self
+ # @param fname モジュールファイル名
+ # @param initfunc 初期化関数名
+ #
+ # @else
+ #
+ # @brief [CORBA interface] Load module
+ #
+ # Load module (shared library, DLL etc..) by file name,
+ # and invoke initialize function.
+ #
+ # @param fname The module file name
+ # @param initfunc The initialize function name
+ #
+ # @endif
+ def load(self, fname, initfunc):
+ self._rtcout.RTC_TRACE("Manager.load(fname = %s, initfunc = %s)",
+ (fname, initfunc))
+ self._listeners.module_.preLoad(fname, initfunc)
+ try:
+ fname_ = fname.split(os.sep)
+ if len(fname_) > 1:
+ fname_ = fname_[-1]
+ else:
+ fname_ = fname_[0]
+
+ if not initfunc:
+ mod = [s.strip() for s in fname_.split(".")]
+ initfunc = mod[0]+"Init"
+ path = self._module.load(fname, initfunc)
+ self._rtcout.RTC_DEBUG("module path: %s", path)
+ self._listeners.module_.postLoad(path, initfunc)
+ except:
+ self.__try_direct_load(fname)
+
+ return
+
+
+ ##
+ # @if jp
+ #
+ # @brief モジュールのアンロード
+ #
+ # モジュールをアンロードする
+ #
+ # @param self
+ # @param fname モジュールのファイル名
+ #
+ # @else
+ #
+ # @brief Unload module
+ #
+ # Unload shared library.
+ #
+ # @param pathname Module file name
+ #
+ # @endif
+ def unload(self, fname):
+ self._rtcout.RTC_TRACE("Manager.unload()")
+ self._listeners.module_.preUnload(fname)
+ self._module.unload(fname)
+ self._listeners.module_.postUnload(fname)
+ return
+
+
+ ##
+ # @if jp
+ #
+ # @brief 全モジュールのアンロード
+ #
+ # モジュールをすべてアンロードする
+ #
+ # @param self
+ #
+ # @else
+ #
+ # @brief Unload module
+ #
+ # Unload all loaded shared library.
+ #
+ # @endif
+ def unloadAll(self):
+ self._rtcout.RTC_TRACE("Manager.unloadAll()")
+ self._module.unloadAll()
+ return
+
+
+ ##
+ # @if jp
+ # @brief ロード済みのモジュールリストを取得する
+ #
+ # 現在マネージャにロードされているモジュールのリストを取得する。
+ #
+ # @param self
+ #
+ # @return ロード済みモジュールリスト
+ #
+ # @else
+ # @brief Get loaded module names
+ # @endif
+ # std::vector<coil::Properties> getLoadedModules();
+ def getLoadedModules(self):
+ self._rtcout.RTC_TRACE("Manager.getLoadedModules()")
+ return self._module.getLoadedModules()
+
+
+ ##
+ # @if jp
+ # @brief ロード可能なモジュールリストを取得する
+ #
+ # ロード可能モジュールのリストを取得する。
+ # (現在はModuleManager側で未実装)
+ #
+ # @param self
+ #
+ # @return ロード可能モジュール リスト
+ #
+ # @else
+ # @brief Get loadable module names
+ # @endif
+ def getLoadableModules(self):
+ self._rtcout.RTC_TRACE("Manager.getLoadableModules()")
+ return self._module.getLoadableModules()
+
+
+ #============================================================
+ # Component Factory Management
+ #============================================================
+
+ ##
+ # @if jp
+ # @brief RTコンポーネント用ファクトリを登録する
+ #
+ # RTコンポーネントのインスタンスを生成するための
+ # Factoryを登録する。
+ #
+ # @param self
+ # @param profile RTコンポーネント プロファイル
+ # @param new_func RTコンポーネント生成用関数
+ # @param delete_func RTコンポーネント破棄用関数
+ #
+ # @return 登録処理結果(登録成功:true、失敗:false)
+ #
+ # @else
+ # @brief Register RT-Component Factory
+ # @endif
+ def registerFactory(self, profile, new_func, delete_func):
+ self._rtcout.RTC_TRACE("Manager.registerFactory(%s)", profile.getProperty("type_name"))
+ try:
+ factory = OpenRTM_aist.FactoryPython(profile, new_func, delete_func)
+ self._factory.registerObject(factory)
+ return True
+ except:
+ self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
+ return False
+
+ return
+
+
+ ##
+ # @if jp
+ # @brief ファクトリのプロファイルを取得
+ #
+ # ファクトリのプロファイルを取得する。
+ #
+ # @return ファクトリのプロファイル
+ #
+ # @else
+ # @brief Get profiles of factories.
+ #
+ # Get profiles of factories.
+ #
+ # @return profiles of factories
+ #
+ # @endif
+ #
+ def getFactoryProfiles(self):
+ factories = self._factory.getObjects()
+
+ if not factories:
+ return []
+
+ props = []
+ for factory in factories:
+ props.append(factory.profile())
+
+ return props
+
+
+ ##
+ # @if jp
+ # @brief ExecutionContext用ファクトリを登録する
+ #
+ # ExecutionContextのインスタンスを生成するためのFactoryを登録する。
+ #
+ # @param self
+ # @param name 生成対象ExecutionContext名称
+ # @param new_func ExecutionContext生成用関数
+ # @param delete_func ExecutionContext破棄用関数
+ #
+ # @return 登録処理結果(登録成功:true、失敗:false)
+ #
+ # @else
+ # @brief Register ExecutionContext Factory
+ # @endif
+ def registerECFactory(self, name, new_func, delete_func):
+ self._rtcout.RTC_TRACE("Manager.registerECFactory(%s)", name)
+ try:
+ self._ecfactory.registerObject(OpenRTM_aist.ECFactoryPython(name, new_func, delete_func))
+ return True
+ except:
+ self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
+ return False
+
+ return False
+
+
+ ##
+ # @if jp
+ # @brief ファクトリ全リストを取得する
+ #
+ # 登録されているファクトリの全リストを取得する。
+ #
+ # @param self
+ #
+ # @return 登録ファクトリ リスト
+ #
+ # @else
+ # @brief Get the list of all RT-Component Factory
+ # @endif
+ def getModulesFactories(self):
+ self._rtcout.RTC_TRACE("Manager.getModulesFactories()")
+
+ self._modlist = []
+ for _obj in self._factory._objects._obj:
+ self._modlist.append(_obj.profile().getProperty("implementation_id"))
+ return self._modlist
+
+
+ #============================================================
+ # Component management
+ #============================================================
+
+ ##
+ # @if jp
+ # @brief RTコンポーネントを生成する
+ #
+ # 指定したRTコンポーネントのインスタンスを登録されたFactory経由
+ # で生成する。
+ #
+ # 生成されるコンポーネントの各種プロファイルは以下の優先順位で
+ # 設定される。
+ #
+ # -# createComponent() の引数で与えられたプロファイル
+ # -# rtc.confで指定された外部ファイルで与えられたプロファイル
+ # --# category.instance_name.config_file
+ # --# category.component_type.config_file
+ # -# コードに埋め込まれたプロファイル
+ #
+ # インスタンス生成が成功した場合、併せて以下の処理を実行する。
+ # - 外部ファイルで設定したコンフィギュレーション情報の読み込み,設定
+ # - ExecutionContextのバインド,動作開始
+ # - ネーミングサービスへの登録
+ #
+ # @param comp_args 生成対象RTコンポーネントIDおよびコンフィギュレー
+ # ション引数。フォーマットは大きく分けて "id" と "configuration"
+ # 部分が存在する。
+ #
+ # comp_args: [id]?[configuration]
+ # id は必須、configurationはオプション
+ # id: RTC:[vendor]:[category]:[implementation_id]:[version]
+ # RTC は固定かつ必須
+ # vendor, category, version はオプション
+ # implementation_id は必須
+ # オプションを省略する場合でも ":" は省略不可
+ # configuration: [key0]=[value0]&[key1]=[value1]&[key2]=[value2].....
+ # RTCが持つPropertiesの値をすべて上書きすることができる。
+ # key=value の形式で記述し、"&" で区切る
+ #
+ # 例えば、
+ # RTC:jp.go.aist:example:ConfigSample:1.0?conf.default.str_param0=munya
+ # RTC::example:ConfigSample:?conf.default.int_param0=100
+ #
+ # @return 生成したRTコンポーネントのインスタンス
+ #
+ # @else
+ # @brief Create RT-Components
+ #
+ # Create specified RT-Component's instances via registered Factory.
+ # When its instances have been created successfully, the following
+ # processings are also executed.
+ # - Read and set configuration information that was set by external file.
+ # - Bind ExecutionContext and start operation.
+ # - Register to naming service.
+ #
+ # @param module_name Target RT-Component names for the creation
+ #
+ # @return Created RT-Component's instances
+ #
+ # @endif
+ #
+ def createComponent(self, comp_args):
+ self._rtcout.RTC_TRACE("Manager.createComponent(%s)", comp_args)
+ self._listeners.rtclifecycle_.preCreate(comp_args)
+ comp_prop = OpenRTM_aist.Properties()
+ comp_id = OpenRTM_aist.Properties()
+
+ if not self.procComponentArgs(comp_args, comp_id, comp_prop):
+ return None
+
+ if comp_prop.findNode("exported_ports"):
+ exported_ports = OpenRTM_aist.split(comp_prop.getProperty("exported_ports"),
+ ",")
+ exported_ports_str = ""
+ for i in range(len(exported_ports)):
+ keyval = OpenRTM_aist.split(exported_ports[i], ".")
+ if len(keyval) > 2:
+ exported_ports_str += (keyval[0] + "." + keyval[-1])
+ else:
+ exported_ports_str += exported_ports[i]
+
+ if i != (len(exported_ports) - 1) :
+ exported_ports_str += ","
+
+ comp_prop.setProperty("exported_ports", exported_ports_str)
+ comp_prop.setProperty("conf.default.exported_ports", exported_ports_str)
+
+ factory = self._factory.find(comp_id)
+ if factory is None:
+ self._rtcout.RTC_ERROR("createComponent: Factory not found: %s",
+ comp_id.getProperty("implementation_id"))
+
+ # automatic module loading
+ mp = self._module.getLoadableModules()
+ self._rtcout.RTC_INFO("%d loadable modules found", len(mp))
+
+ found_obj = None
+ predicate = self.ModulePredicate(comp_id)
+ for _obj in mp:
+ if predicate(_obj):
+ found_obj = _obj
+ break
+
+ if not found_obj:
+ self._rtcout.RTC_ERROR("No module for %s in loadable modules list",
+ comp_id.getProperty("implementation_id"))
+ return None
+
+ if not found_obj.findNode("module_file_name"):
+ self._rtcout.RTC_ERROR("Hmm...module_file_name key not found.")
+ return 0
+
+ # module loading
+ self._rtcout.RTC_INFO("Loading module: %s", found_obj.getProperty("module_file_name"))
+ self.load(found_obj.getProperty("module_file_name"), "")
+ factory = self._factory.find(comp_id)
+ if not factory:
+ self._rtcout.RTC_ERROR("Factory not found for loaded module: %s",
+ comp_id.getProperty("implementation_id"))
+ return 0
+
+
+ # get default configuration of component.
+ prop = factory.profile()
+
+ inherit_prop = ["config.version",
+ "openrtm.name",
+ "openrtm.version",
+ "os.name",
+ "os.release",
+ "os.version",
+ "os.arch",
+ "os.hostname",
+ "corba.endpoint",
+ "corba.id",
+ "exec_cxt.periodic.type",
+ "exec_cxt.periodic.rate",
+ "exec_cxt.event_driven.type",
+ "exec_cxt.sync_transition",
+ "exec_cxt.sync_activation",
+ "exec_cxt.sync_deactivation",
+ "exec_cxt.sync_reset",
+ "exec_cxt.transition_timeout",
+ "exec_cxt.activation_timeout",
+ "exec_cxt.deactivation_timeout",
+ "exec_cxt.reset_timeout",
+ "logger.enable",
+ "logger.log_level",
+ "naming.enable",
+ "naming.type",
+ "naming.formats"]
+
+ for i in range(len(inherit_prop)):
+ if self._config.findNode(inherit_prop[i]):
+ prop.setProperty(inherit_prop[i],self._config.getProperty(inherit_prop[i]))
+
+ comp = factory.create(self)
+
+ if comp is None:
+ self._rtcout.RTC_ERROR("createComponent: RTC creation failed: %s",
+ comp_id.getProperty("implementation_id"))
+ return None
+ self._rtcout.RTC_TRACE("RTC Created: %s", comp_id.getProperty("implementation_id"))
+ self._listeners.rtclifecycle_.postCreate(comp)
+
+ # The property specified by the parameter of createComponent() is merged.
+ # The property("instance_name") specified by the parameter of createComponent()
+ # must be merged here.
+ prop.mergeProperties(comp_prop)
+
+ #------------------------------------------------------------
+ # Load configuration file specified in "rtc.conf"
+ #
+ # rtc.conf:
+ # [category].[type_name].config_file = file_name
+ # [category].[instance_name].config_file = file_name
+ self._listeners.rtclifecycle_.preConfigure(prop)
+ self.configureComponent(comp,prop)
+ self._listeners.rtclifecycle_.postConfigure(prop)
+
+ # The property specified by the parameter of createComponent() is set.
+ # The property("exported_ports") specified by the parameter of createComponent()
+ # must be set here.
+ #comp.setProperties(comp_prop)
+
+ # Component initialization
+ self._listeners.rtclifecycle_.preInitialize()
+ if comp.initialize() != RTC.RTC_OK:
+ self._rtcout.RTC_TRACE("RTC initialization failed: %s",
+ comp_id.getProperty("implementation_id"))
+ self._rtcout.RTC_TRACE("%s was finalized", comp_id.getProperty("implementation_id"))
+ if comp.exit() != RTC.RTC_OK:
+ self._rtcout.RTC_DEBUG("%s finalization was failed.",
+ comp_id.getProperty("implementation_id"))
+ return None
+
+ self._rtcout.RTC_TRACE("RTC initialization succeeded: %s",
+ comp_id.getProperty("implementation_id"))
+ self._listeners.rtclifecycle_.postInitialize()
+ self.registerComponent(comp)
+ return comp
+
+
+
+ ##
+ # @if jp
+ # @brief RTコンポーネントを直接 Manager に登録する
+ #
+ # 指定したRTコンポーネントのインスタンスをファクトリ経由ではなく
+ # 直接マネージャに登録する。
+ #
+ # @param self
+ # @param comp 登録対象RTコンポーネントのインスタンス
+ #
+ # @return 登録処理結果(登録成功:true、失敗:false)
+ #
+ # @else
+ # @brief Register RT-Component directly without Factory
+ # @endif
+ def registerComponent(self, comp):
+ self._rtcout.RTC_TRACE("Manager.registerComponent(%s)", comp.getInstanceName())
+
+ self._compManager.registerObject(comp)
+ names = comp.getNamingNames()
+
+ self._listeners.naming_.preBind(comp, names)
+ for name in names:
+ self._rtcout.RTC_TRACE("Bind name: %s", name)
+ self._namingManager.bindObject(name, comp)
+ self._listeners.naming_.postBind(comp, names)
+
+ return True
+
+
+ ##
+ # @if jp
+ # @brief RTコンポーネントの登録を解除する
+ #
+ # 指定したRTコンポーネントの登録を解除する。
+ #
+ # @param self
+ # @param comp 登録解除対象RTコンポーネントのインスタンス
+ #
+ # @return 登録解除処理結果(解除成功:true、解除失敗:false)
+ #
+ # @else
+ # @brief Register RT-Component directly without Factory
+ # @endif
+ def unregisterComponent(self, comp):
+ self._rtcout.RTC_TRACE("Manager.unregisterComponent(%s)", comp.getInstanceName())
+ self._compManager.unregisterObject(comp.getInstanceName())
+ names = comp.getNamingNames()
+
+ self._listeners.naming_.preUnbind(comp, names)
+ for name in names:
+ self._rtcout.RTC_TRACE("Unbind name: %s", name)
+ self._namingManager.unbindObject(name)
+ self._listeners.naming_.postUnbind(comp, names)
+
+ return True
+
+
+ ##
+ # @if jp
+ # @brief Contextを生成する
+ #
+ # @return 生成したConetextのインスタンス
+ #
+ # @else
+ # @brief Create Context
+ #
+ # @return Created Context's instances
+ #
+ # @endif
+ #
+ # ExecutionContextBase* createContext(const char* ec_args);
+ def createContext(self, ec_args):
+ self._rtcout.RTC_TRACE("Manager.createContext()")
+ self._rtcout.RTC_TRACE("ExecutionContext type: %s",
+ self._config.getProperty("exec_cxt.periodic.type"))
+ ec_id = [""]
+ ec_prop = OpenRTM_aist.Properties()
+
+ if not self.procContextArgs(ec_args, ec_id, ec_prop):
+ return None
+
+ factory = self._ecfactory.find(ec_id[0])
+
+ if factory == None:
+ self._rtcout.RTC_ERROR("Factory not found: %s", ec_id[0])
+ return None
+
+ ec = factory.create()
+ return ec
+
+
+ ##
+ # @if jp
+ # @brief Manager に登録されているRTコンポーネントを削除する(未実装)
+ #
+ # マネージャに登録されているRTコンポーネントを削除する。
+ #
+ # @param self
+ # @param instance_name 削除対象RTコンポーネントのインスタンス名
+ #
+ # @else
+ # @brief Unregister RT-Component that is registered in the Manager
+ # @endif
+ def deleteComponent(self, instance_name=None, comp=None):
+ if instance_name:
+ self._rtcout.RTC_TRACE("Manager.deleteComponent(%s)", instance_name)
+ _comp = self._compManager.find(instance_name)
+ if _comp is None:
+ self._rtcout.RTC_WARN("RTC %s was not found in manager.", instance_name)
+ return
+ self.deleteComponent(comp=_comp)
+
+ elif comp:
+ self._rtcout.RTC_TRACE("Manager.deleteComponent(RTObject_impl)")
+ # cleanup from manager's table, and naming serivce
+ self.unregisterComponent(comp)
+
+ comp_id = comp.getProperties()
+ factory = self._factory.find(comp_id)
+
+ if not factory:
+ self._rtcout.RTC_DEBUG("Factory not found: %s",
+ comp_id.getProperty("implementation_id"))
+ return
+ else:
+ self._rtcout.RTC_DEBUG("Factory found: %s",
+ comp_id.getProperty("implementation_id"))
+ factory.destroy(comp)
+
+
+ if OpenRTM_aist.toBool(self._config.getProperty("manager.shutdown_on_nortcs"),
+ "YES","NO",True) and \
+ not OpenRTM_aist.toBool(self._config.getProperty("manager.is_master"),
+ "YES","NO",False):
+ comps = self.getComponents()
+ if len(comps) == 0:
+ self.shutdown()
+
+ return
+
+
+ ##
+ # @if jp
+ # @brief Manager に登録されているRTコンポーネントを検索する
+ #
+ # Manager に登録されているRTコンポーネントを指定した名称で検索し、
+ # 合致するコンポーネントを取得する。
+ #
+ # @param self
+ # @param instance_name 検索対象RTコンポーネントの名称
+ #
+ # @return 名称が一致するRTコンポーネントのインスタンス
+ #
+ # @else
+ # @brief Get RT-Component's pointer
+ # @endif
+ def getComponent(self, instance_name):
+ self._rtcout.RTC_TRACE("Manager.getComponent(%s)", instance_name)
+ return self._compManager.find(instance_name)
+
+
+ ##
+ # @if jp
+ # @brief Manager に登録されている全RTコンポーネントを取得する
+ #
+ # Manager に登録されているRTコンポーネントの全インスタンスを取得する。
+ #
+ # @param self
+ #
+ # @return 全RTコンポーネントのインスタンスリスト
+ #
+ # @else
+ # @brief Get all RT-Component's pointer
+ # @endif
+ def getComponents(self):
+ self._rtcout.RTC_TRACE("Manager.getComponents()")
+ return self._compManager.getObjects()
+
+
+ # void Manager::
+ # addManagerActionListener(RTM::ManagerActionListener* listener,
+ # bool autoclean)
+ def addManagerActionListener(self, listener,autoclean=True):
+ self._listeners.manager_.addListener(listener, autoclean)
+ return
+
+
+ # void Manager::
+ # removeManagerActionListener(RTM::ManagerActionListener* listener)
+ def removeManagerActionListener(self, listener):
+ self._listeners.manager_.removeListener(listener)
+ return
+
+
+ # void Manager::
+ # addModuleActionListener(RTM::ModuleActionListener* listener,
+ # bool autoclean)
+ def addModuleActionListener(self, listener, autoclean=True):
+ self._listeners.module_.addListener(listener, autoclean)
+ return
+
+
+ # void Manager::
+ # removeModuleActionListener(RTM::ModuleActionListener* listener)
+ def removeModuleActionListener(self, listener):
+ self._listeners.module_.removeListener(listener)
+ return
+
+
+ # void Manager::
+ # addRtcLifecycleActionListener(RTM::RtcLifecycleActionListener* listener,
+ # bool autoclean)
+ def addRtcLifecycleActionListener(self, listener, autoclean=True):
+ self._listeners.rtclifecycle_.addListener(listener, autoclean)
+ return
+
+
+ # void Manager::
+ # removeRtcLifecycleActionListener(RTM::RtcLifecycleActionListener* listener)
+ def removeRtcLifecycleActionListener(self, listener):
+ self._listeners.rtclifecycle_.removeListener(listener)
+ return
+
+
+ # void Manager::
+ # addNamingActionListener(RTM::NamingActionListener* listener,
+ # bool autoclean)
+ def addNamingActionListener(self, listener, autoclean=True):
+ self._listeners.naming_.addListener(listener, autoclean)
+ return
+
+
+ # void Manager::
+ # removeNamingActionListener(RTM::NamingActionListener* listener)
+ def removeNamingActionListener(self, listener):
+ self._listeners.naming_.removeListener(listener)
+ return
+
+
+ # void Manager::
+ # addLocalServiceActionListener(RTM::LocalServiceActionListener* listener,
+ # bool autoclean)
+ def addLocalServiceActionListener(self, listener, autoclean=True):
+ self._listeners.localservice_.addListener(listener, autoclean)
+ return
+
+
+ # void Manager::
+ # removeLocalServiceActionListener(RTM::LocalServiceActionListener* listener)
+ def removeLocalServiceActionListener(self, listener):
+ self._listeners.localservice_.removeListener(listener)
+ return
+
+
+ #============================================================
+ # CORBA 関連
+ #============================================================
+
+ ##
+ # @if jp
+ # @brief ORB のポインタを取得する
+ #
+ # Manager に設定された ORB のポインタを取得する。
+ #
+ # @param self
+ #
+ # @return ORB オブジェクト
+ #
+ # @else
+ # @brief Get the pointer to the ORB
+ # @endif
+ def getORB(self):
+ self._rtcout.RTC_TRACE("Manager.getORB()")
+ return self._orb
+
+
+ ##
+ # @if jp
+ # @brief Manager が持つ RootPOA のポインタを取得する
+ #
+ # Manager に設定された RootPOA へのポインタを取得する。
+ #
+ # @param self
+ #
+ # @return RootPOAオブジェクト
+ #
+ # @else
+ # @brief Get the pointer to the RootPOA
+ # @endif
+ def getPOA(self):
+ self._rtcout.RTC_TRACE("Manager.getPOA()")
+ return self._poa
+
+
+ ##
+ # @if jp
+ # @brief Manager が持つ POAManager を取得する
+ #
+ # Manager に設定された POAMAnager を取得する。
+ #
+ # @param self
+ #
+ # @return POAマネージャ
+ #
+ # @else
+ #
+ # @endif
+ def getPOAManager(self):
+ self._rtcout.RTC_TRACE("Manager.getPOAManager()")
+ return self._poaManager
+
+
+
+ #============================================================
+ # Manager initialize and finalization
+ #============================================================
+
+ ##
+ # @if jp
+ # @brief Manager の内部初期化処理
+ #
+ # Manager の内部初期化処理を実行する。
+ # - Manager コンフィギュレーションの設定
+ # - ログ出力ファイルの設定
+ # - 終了処理用スレッドの生成
+ # - タイマ用スレッドの生成(タイマ使用時)
+ #
+ # @param self
+ # @param argv コマンドライン引数
+ #
+ # @else
+ # @brief Manager internal initialization
+ # @endif
+ def initManager(self, argv):
+ config = OpenRTM_aist.ManagerConfig(argv)
+ self._config = OpenRTM_aist.Properties()
+ config.configure(self._config)
+ self._config.setProperty("logger.file_name",self.formatString(self._config.getProperty("logger.file_name"),
+ self._config))
+ self._module = OpenRTM_aist.ModuleManager(self._config)
+ self._terminator = self.Terminator(self)
+ guard = OpenRTM_aist.ScopedLock(self._terminate.mutex)
+ self._terminate.waiting = 0
+ del guard
+
+ if OpenRTM_aist.toBool(self._config.getProperty("timer.enable"), "YES", "NO", True):
+ tm = OpenRTM_aist.TimeValue(0, 100000)
+ tick = self._config.getProperty("timer.tick")
+ if tick != "":
+ tm = tm.set_time(float(tick))
+ if self._timer:
+ self._timer.stop()
+ self._timer.join()
+ self._timer = OpenRTM_aist.Timer(tm)
+ self._timer.start()
+
+ if OpenRTM_aist.toBool(self._config.getProperty("manager.shutdown_auto"),
+ "YES", "NO", True) and \
+ not OpenRTM_aist.toBool(self._config.getProperty("manager.is_master"),
+ "YES", "NO", False):
+ tm = OpenRTM_aist.TimeValue(10, 0)
+ if self._config.findNode("manager.auto_shutdown_duration"):
+ duration = float(self._config.getProperty("manager.auto_shutdown_duration"))
+ if duration:
+ tm.set_time(duration)
+
+ if self._timer:
+ self._timer.registerListenerObj(self,
+ OpenRTM_aist.Manager.shutdownOnNoRtcs,
+ tm)
+
+ if self._timer:
+ tm = OpenRTM_aist.TimeValue(1, 0)
+ self._timer.registerListenerObj(self,
+ OpenRTM_aist.Manager.cleanupComponents,
+ tm)
+
+ return
+
+
+ ##
+ # @if jp
+ # @brief Manager の終了処理(未実装)
+ #
+ # Manager を終了する
+ # (ただし,現在は未実装)
+ #
+ # @param self
+ #
+ # @else
+ #
+ # @endif
+ def shutdownManager(self):
+ self._rtcout.RTC_TRACE("Manager.shutdownManager()")
+ if self._timer:
+ self._timer.stop()
+ self._timer.join()
+ self._timer = None
+
+ return
+
+
+ ##
+ # @if jp
+ # @brief Manager の終了処理
+ #
+ # configuration の "manager.shutdown_on_nortcs" YES で、
+ # コンポーネントが登録されていない場合 Manager を終了する。
+ #
+ # @else
+ # @brief Shutdown Manager
+ #
+ # This method shutdowns Manager as follows.
+ # - "Manager.shutdown_on_nortcs" of configuration is YES.
+ # - The component is not registered.
+ #
+ # @endif
+ #
+ # void shutdownOnNoRtcs();
+ def shutdownOnNoRtcs(self):
+ self._rtcout.RTC_TRACE("Manager::shutdownOnNoRtcs()")
+ if OpenRTM_aist.toBool(self._config.getProperty("manager.shutdown_on_nortcs"),
+ "YES", "NO", True):
+
+ comps = self.getComponents()
+
+ if len(comps) == 0:
+ self.shutdown()
+
+ return
+
+
+ #============================================================
+ # Logger initialize and terminator
+ #============================================================
+
+ ##
+ # @if jp
+ # @brief System logger の初期化
+ #
+ # System logger の初期化を実行する。
+ # コンフィギュレーションファイルに設定された情報に基づき、
+ # ロガーの初期化,設定を実行する。
+ #
+ # @param self
+ #
+ # @return 初期化実行結果(初期化成功:true、初期化失敗:false)
+ #
+ # @else
+ # @brief System logger initialization
+ # @endif
+ def initLogger(self):
+
+ if not OpenRTM_aist.toBool(self._config.getProperty("logger.enable"), "YES", "NO", True):
+ self._rtcout = OpenRTM_aist.LogStream()
+ return True
+
+ logfile = "./rtc.log"
+
+ logouts = self._config.getProperty("logger.file_name")
+ logouts = [s.strip() for s in logouts.split(",")]
+
+ self._rtcout = None
+
+ for i in range(len(logouts)):
+ tmp = [logouts[i]]
+ OpenRTM_aist.eraseHeadBlank(tmp)
+ OpenRTM_aist.eraseTailBlank(tmp)
+ logouts[i] = tmp[0]
+ if logouts[i].lower() == "stdout":
+ if self._rtcout is None:
+ self._rtcout = OpenRTM_aist.LogStream("manager","STDOUT")
+ else:
+ self._rtcout.addHandler(logouts[i])
+ else:
+ if logouts[i] == "":
+ logfile = "./rtc.log"
+ else:
+ logfile = logouts[i]
+
+ if self._rtcout is None:
+ self._rtcout = OpenRTM_aist.LogStream("manager","FILE", logfile)
+ else:
+ self._rtcout.addHandler("FILE",logfile)
+
+ self._rtcout.setLogLevel(self._config.getProperty("logger.log_level"))
+ self._rtcout.setLogLock(OpenRTM_aist.toBool(self._config.getProperty("logger.stream_lock"),
+ "enable", "disable", False))
+
+ self._rtcout.RTC_INFO("%s", self._config.getProperty("openrtm.version"))
+ self._rtcout.RTC_INFO("Copyright (C) 2003-2010")
+ self._rtcout.RTC_INFO(" Noriaki Ando")
+ self._rtcout.RTC_INFO(" Intelligent Systems Research Institute, AIST")
+ self._rtcout.RTC_INFO("Manager starting.")
+ self._rtcout.RTC_INFO("Starting local logging.")
+
+ return True
+
+
+ ##
+ # @if jp
+ # @brief System Logger の終了処理(未実装)
+ #
+ # System Loggerの終了処理を実行する。
+ # (現在は未実装)
+ #
+ # @param self
+ #
+ # @else
+ # @brief System Logger finalization
+ # @endif
+ def shutdownLogger(self):
+ self._rtcout.RTC_TRACE("Manager.shutdownLogger()")
+ self._rtcout.shutdown()
+ return
+
+
+ #============================================================
+ # ORB initialization and finalization
+ #============================================================
+
+ ##
+ # @if jp
+ # @brief CORBA ORB の初期化処理
+ #
+ # 設定情報を元にORBを初期化する。
+ #
+ # @param self
+ #
+ # @return ORB 初期化処理結果(初期化成功:true、初期化失敗:false)
+ #
+ # @else
+ # @brief CORBA ORB initialization
+ # @endif
+ def initORB(self):
+ self._rtcout.RTC_TRACE("Manager.initORB()")
+ try:
+ args = OpenRTM_aist.split(self.createORBOptions(), " ")
+ args.insert(0,"manager")
+ argv = OpenRTM_aist.toArgv(args)
+ self._orb = CORBA.ORB_init(argv)
+
+ self._poa = self._orb.resolve_initial_references("RootPOA")
+ if CORBA.is_nil(self._poa):
+ self._rtcout.RTC_ERROR("Could not resolve RootPOA")
+ return False
+
+ self._poaManager = self._poa._get_the_POAManager()
+
+ except:
+ self._rtcout.RTC_ERROR("Exception: Caught unknown exception in initORB().")
+ self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
+ return False
+
+ return True
+
+
+ ##
+ # @if jp
+ # @brief ORB のコマンドラインオプション作成
+ #
+ # コンフィギュレーション情報に設定された内容から
+ # ORB の起動時オプションを作成する。
+ #
+ # @param self
+ #
+ # @return ORB 起動時オプション
+ #
+ # @else
+ # @brief ORB command option creation
+ # @endif
+ def createORBOptions(self):
+ opt = self._config.getProperty("corba.args")
+ self._rtcout.RTC_DEBUG("corba.args: %s",opt)
+
+ endpoints = []
+ self.createORBEndpoints(endpoints)
+ opt = [opt]
+ self.createORBEndpointOption(opt,endpoints)
+
+ self._rtcout.RTC_PARANOID("ORB options: %s", opt[0])
+
+ return opt[0]
+
+
+ ##
+ # @if jp
+ # @brief エンドポイントの生成
+ #
+ # コンフィグレーションからエンドポイントを生成する。
+ #
+ # @param endpoints エンドポイントリスト
+ #
+ # @else
+ # @brief Create Endpoints
+ #
+ # Create Endpoints from the configuration.
+ #
+ # @param endpoints Endpoints list
+ #
+ # @endif
+ #
+ # void createORBEndpoints(coil::vstring& endpoints);
+ def createORBEndpoints(self, endpoints):
+
+ # corba.endpoint is obsolete
+ # corba.endpoints with comma separated values are acceptable
+ if self._config.findNode("corba.endpoints"):
+ endpoints_ = [s.strip() for s in self._config.getProperty("corba.endpoints").split(",")]
+ for ep in endpoints_:
+ endpoints.append(ep)
+
+ self._rtcout.RTC_DEBUG("corba.endpoints: %s", self._config.getProperty("corba.endpoints"))
+
+ if self._config.findNode("corba.endpoint"):
+ endpoints_ = [s.strip() for s in self._config.getProperty("corba.endpoint").split(",")]
+ for ep in endpoints_:
+ endpoints.append(ep)
+ self._rtcout.RTC_DEBUG("corba.endpoint: %s", self._config.getProperty("corba.endpoint"))
+
+ # If this process has master manager,
+ # master manager's endpoint inserted at the top of endpoints
+ self._rtcout.RTC_DEBUG("manager.is_master: %s",
+ self._config.getProperty("manager.is_master"))
+
+ if OpenRTM_aist.toBool(self._config.getProperty("manager.is_master"), "YES", "NO", False):
+ mm = self._config.getProperty("corba.master_manager", ":2810")
+ mmm = [s.strip() for s in mm.split(":")]
+ if len(mmm) == 2:
+ endpoints.insert(0, ":" + mmm[1])
+ else:
+ endpoints.insert(0, ":2810")
+
+ endpoints = OpenRTM_aist.unique_sv(endpoints)
+
+ return
+
+
+ ##
+ # @if jp
+ # @brief ORB の Endpoint のコマンドラインオプション作成
+ # @param opt コマンドラインオプション
+ # @param endpoints エンドポイントリスト
+ #
+ # @else
+ # @brief Create a command optional line of Endpoint of ORB.
+ # @param opt ORB options
+ # @param endpoints Endpoints list
+ #
+ # @endif
+ # void createORBEndpointOption(std::string& opt, coil::vstring& endpoints);
+ def createORBEndpointOption(self, opt, endpoints):
+ corba = self._config.getProperty("corba.id")
+ self._rtcout.RTC_DEBUG("corba.id: %s", corba)
+
+ for i in range(len(endpoints)):
+ if endpoints[i]:
+ endpoint = endpoints[i]
+ else:
+ continue
+
+ self._rtcout.RTC_DEBUG("Endpoint is : %s", endpoint)
+ if endpoint.find(":") == -1:
+ endpoint += ":"
+
+ if corba == "omniORB":
+ endpoint = OpenRTM_aist.normalize([endpoint])
+ if OpenRTM_aist.normalize([endpoint]) == "all:":
+ opt[0] += " -ORBendPointPublishAllIFs 1"
+ else:
+ opt[0] += " -ORBendPoint giop:tcp:" + endpoint
+
+ elif corba == "TAO":
+ opt[0] += "-ORBEndPoint iiop://" + endpoint
+ elif corba == "MICO":
+ opt[0] += "-ORBIIOPAddr inet:" + endpoint
+
+ endpoints[i] = endpoint
+
+ return
+
+
+ ##
+ # @if jp
+ # @brief ORB の終了処理
+ #
+ # ORB の終了処理を実行する。
+ # 実行待ちの処理が存在する場合には、その処理が終了するまで待つ。
+ # 実際の終了処理では、POA Managerを非活性化し、 ORB のシャットダウンを実行
+ # する。
+ #
+ # @param self
+ #
+ # @else
+ # @brief ORB finalization
+ # @endif
+ def shutdownORB(self):
+ self._rtcout.RTC_TRACE("Manager.shutdownORB()")
+ if not self._orb:
+ return
+
+ try:
+ while self._orb.work_pending():
+ self._rtcout.RTC_PARANOID("Pending work still exists.")
+ if self._orb.work_pending():
+ self._orb.perform_work()
+ pass
+
+ self._rtcout.RTC_DEBUG("No pending works of ORB. Shutting down POA and ORB.")
+ except:
+ self._rtcout.RTC_TRACE(OpenRTM_aist.Logger.print_exception())
+ pass
+
+ if not CORBA.is_nil(self._poa):
+ try:
+ if not CORBA.is_nil(self._poaManager):
+ self._poaManager.deactivate(False, True)
+ self._rtcout.RTC_DEBUG("POA Manager was deactivated.")
+ self._poa.destroy(False, True)
+ self._poa = PortableServer.POA._nil
+ self._rtcout.RTC_DEBUG("POA was destroyed.")
+ except CORBA.SystemException, ex:
+ self._rtcout.RTC_ERROR("Caught SystemException during root POA destruction")
+ self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
+ except:
+ self._rtcout.RTC_ERROR("Caught unknown exception during destruction")
+ self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
+
+ if self._orb:
+ try:
+ self._orb.shutdown(True)
+ self._rtcout.RTC_DEBUG("ORB was shutdown.")
+ self._orb = CORBA.Object._nil
+ except CORBA.SystemException, ex:
+ self._rtcout.RTC_ERROR("Caught CORBA::SystemException during ORB shutdown.")
+ self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
+ except:
+ self._rtcout.RTC_ERROR("Caught unknown exception during ORB shutdown.")
+ self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
+
+
+ #============================================================
+ # NamingService initialization and finalization
+ #============================================================
+
+ ##
+ # @if jp
+ # @brief NamingManager の初期化
+ #
+ # NamingManager の初期化処理を実行する。
+ # ただし、 NamingManager を使用しないようにプロパティ情報に設定されている
+ # 場合には何もしない。
+ # NamingManager を使用する場合、プロパティ情報に設定されている
+ # デフォルト NamingServer を登録する。
+ # また、定期的に情報を更新するように設定されている場合には、指定された周期
+ # で自動更新を行うためのタイマを起動するとともに、更新用メソッドをタイマに
+ # 登録する。
+ #
+ # @param self
+ #
+ # @return 初期化処理結果(初期化成功:true、初期化失敗:false)
+ #
+ # @else
+ #
+ # @endif
+ def initNaming(self):
+ self._rtcout.RTC_TRACE("Manager.initNaming()")
+ self._namingManager = OpenRTM_aist.NamingManager(self)
+
+ if not OpenRTM_aist.toBool(self._config.getProperty("naming.enable"), "YES", "NO", True):
+ return True
+
+ meths = OpenRTM_aist.split(self._config.getProperty("naming.type"),",")
+
+ for meth in meths:
+ names = OpenRTM_aist.split(self._config.getProperty(meth+".nameservers"), ",")
+ for name in names:
+ self._rtcout.RTC_TRACE("Register Naming Server: %s/%s", (meth, name))
+ self._namingManager.registerNameServer(meth,name)
+
+ if OpenRTM_aist.toBool(self._config.getProperty("naming.update.enable"), "YES", "NO", True):
+ tm = OpenRTM_aist.TimeValue(10,0)
+ intr = self._config.getProperty("naming.update.interval")
+ if intr != "":
+ tm = OpenRTM_aist.TimeValue(intr)
+
+ if self._timer:
+ self._timer.registerListenerObj(self._namingManager,OpenRTM_aist.NamingManager.update,tm)
+
+ return True
+
+
+ ##
+ # @if jp
+ # @brief NamingManager の終了処理
+ #
+ # NamingManager を終了する。
+ # 登録されている全要素をアンバインドし、終了する。
+ #
+ # @param self
+ #
+ # @else
+ #
+ # @endif
+ def shutdownNaming(self):
+ self._rtcout.RTC_TRACE("Manager.shutdownNaming()")
+ comps = self.getComponents()
+
+ for comp in comps:
+ names = comp.getNamingNames()
+ self._listeners.naming_.preUnbind(comp, names);
+ for name in names:
+ self._namingManager.unbindObject(name)
+ self._listeners.naming_.postUnbind(comp, names);
+
+ self._namingManager.unbindAll()
+ return
+
+
+ ##
+ # @if jp
+ # @brief ExecutionContextManager の初期化
+ #
+ # 使用する各 ExecutionContext の初期化処理を実行し、各 ExecutionContext
+ # 生成用 Factory を ExecutionContextManager に登録する。
+ #
+ # @param self
+ #
+ # @return ExecutionContextManager 初期化処理実行結果
+ # (初期化成功:true、初期化失敗:false)
+ #
+ # @else
+ #
+ # @endif
+ def initExecContext(self):
+ self._rtcout.RTC_TRACE("Manager.initExecContext()")
+ OpenRTM_aist.PeriodicExecutionContextInit(self)
+ OpenRTM_aist.ExtTrigExecutionContextInit(self)
+ OpenRTM_aist.OpenHRPExecutionContextInit(self)
+ return True
+
+
+ ##
+ # @if jp
+ # @brief PeriodicECSharedComposite の初期化
+ #
+ # @return PeriodicECSharedComposite 初期化処理実行結果
+ # (初期化成功:true、初期化失敗:false)
+ #
+ # @else
+ # @brief PeriodicECSharedComposite initialization
+ #
+ # @return PeriodicECSharedComposite initialization result
+ # (Successful:true, Failed:false)
+ #
+ # @endif
+ #
+ def initComposite(self):
+ self._rtcout.RTC_TRACE("Manager.initComposite()")
+ OpenRTM_aist.PeriodicECSharedCompositeInit(self)
+ return True
+
+
+ ##
+ # @if jp
+ # @brief ファクトリの初期化
+ #
+ # バッファ、スレッド、パブリッシャ、プロバイダ、コンシューマの
+ # ファクトリを初期化する。
+ #
+ # @return ファクトリ初期化処理実行結果
+ # (初期化成功:true、初期化失敗:false)
+ #
+ # @else
+ # @brief Factories initialization
+ #
+ # Initialize buffer factories, thread factories, publisher factories,
+ # provider factories, and consumer factories.
+ #
+ # @return PeriodicECSharedComposite initialization result
+ # (Successful:true, Failed:false)
+ #
+ # @endif
+ #
+ def initFactories(self):
+ self._rtcout.RTC_TRACE("Manager.initFactories()")
+ OpenRTM_aist.FactoryInit()
+ return True
+
+
+ ##
+ # @if jp
+ # @brief Timer の初期化
+ #
+ # 使用する各 Timer の初期化処理を実行する。
+ # (現状の実装では何もしない)
+ #
+ # @param self
+ #
+ # @return Timer 初期化処理実行結果(初期化成功:true、初期化失敗:false)
+ #
+ # @else
+ #
+ # @endif
+ def initTimer(self):
+ return True
+
+
+ ##
+ # @if jp
+ # @brief ManagerServant の初期化
+ #
+ # @return Timer 初期化処理実行結果(初期化成功:true、初期化失敗:false)
+ #
+ # @else
+ # @brief ManagerServant initialization
+ #
+ # @return Timer Initialization result (Successful:true, Failed:false)
+ #
+ # @endif
+ #
+ def initManagerServant(self):
+ self._rtcout.RTC_TRACE("Manager.initManagerServant()")
+ if not OpenRTM_aist.toBool(self._config.getProperty("manager.corba_servant"),
+ "YES","NO",True):
+ return True
+
+ self._mgrservant = OpenRTM_aist.ManagerServant()
+ prop = self._config.getNode("manager")
+ names = OpenRTM_aist.split(prop.getProperty("naming_formats"),",")
+
+ if OpenRTM_aist.toBool(prop.getProperty("is_master"),
+ "YES","NO",True):
+ for name in names:
+ mgr_name = self.formatString(name, prop)
+ self._namingManager.bindManagerObject(mgr_name, self._mgrservant)
+
+ otherref = None
+
+ try:
+ otherref = file(self._config.getProperty("manager.refstring_path"),'r')
+ refstring = otherref.readline()
+ otherref.close()
+ except:
+ try:
+ reffile = file(self._config.getProperty("manager.refstring_path"),'w')
+ except:
+ self._rtcout.RTC_WARN(OpenRTM_aist.Logger.print_exception())
+ return False
+ else:
+ reffile.write(self._orb.object_to_string(self._mgrservant.getObjRef()))
+ reffile.close()
+ return True
+
+
+ # bool Manager::initLocalService()
+ def initLocalService(self):
+ self._rtcout.RTC_TRACE("Manager::initLocalService()")
+ admin_ = OpenRTM_aist.LocalServiceAdmin.instance()
+ prop_ = OpenRTM_aist.Properties(prop=self._config.getNode("manager.local_service"))
+ admin_.init(prop_)
+ self._rtcout.RTC_DEBUG("LocalServiceAdmin's properties:")
+ self._rtcout.RTC_DEBUG("%s",prop_)
+
+ svclist_ = admin_.getServiceProfiles()
+ for svc_ in svclist_:
+ self._rtcout.RTC_INFO("Available local service: %s (%s)",
+ (svc_.name, svc_.uuid))
+ return True
+
+
+ ##
+ # @if jp
+ # @brief NamingManager に登録されている全コンポーネントの終了処理
+ #
+ # NamingManager に登録されているRTコンポーネントおよび ExecutionContext の
+ # リストを取得し、全コンポーネントを終了する。
+ #
+ # @param self
+ #
+ # @else
+ #
+ # @endif
+ def shutdownComponents(self):
+ self._rtcout.RTC_TRACE("Manager.shutdownComponents()")
+ comps = self._namingManager.getObjects()
+ for comp in comps:
+ try:
+ comp.exit()
+ p = OpenRTM_aist.Properties(key=comp.getInstanceName())
+ p.mergeProperties(comp.getProperties())
+ except:
+ self._rtcout.RTC_TRACE(OpenRTM_aist.Logger.print_exception())
+ pass
+
+ for ec in self._ecs:
+ try:
+ self._poa.deactivate_object(self._poa.servant_to_id(ec))
+ except:
+ self._rtcout.RTC_TRACE(OpenRTM_aist.Logger.print_exception())
+ pass
+
+
+ ##
+ # @if jp
+ # @brief RTコンポーネントの登録解除
+ #
+ # 指定したRTコンポーネントのインスタンスをネーミングサービスから
+ # 登録解除する。
+ #
+ # @param self
+ # @param comp 登録解除対象RTコンポーネント
+ #
+ # @else
+ #
+ # @endif
+ def cleanupComponent(self, comp):
+ self._rtcout.RTC_TRACE("Manager.cleanupComponent()")
+ self.unregisterComponent(comp)
+
+ return
+
+
+ ##
+ # @if jp
+ # @brief RTコンポーネントの削除する
+ #
+ # notifyFinalized()によって登録されたRTコンポーネントを削除する。
+ #
+ # @else
+ # @brief This method deletes RT-Components.
+ #
+ # This method deletes RT-Components registered by notifyFinalized().
+ #
+ # @endif
+ #
+ # void cleanupComponents();
+ def cleanupComponents(self):
+ self._rtcout.RTC_VERBOSE("Manager.cleanupComponents()")
+ guard = OpenRTM_aist.ScopedLock(self._finalized.mutex)
+ self._rtcout.RTC_VERBOSE("%d components are marked as finalized.",
+ len(self._finalized.comps))
+ for _comp in self._finalized.comps:
+ self.deleteComponent(comp=_comp)
+
+ self._finalized.comps = []
+ del guard
+ return
+
+
+ ##
+ # @if jp
+ # @brief RTコンポーネントの削除する
+ #
+ # 削除するRTコンポーネントを登録する。
+ # 登録されたRTコンポーネントは cleanupComponents() で削除される。
+ #
+ # @param 削除するRTコンポーネント
+ #
+ # @else
+ # @brief This method deletes RT-Components.
+ #
+ # The deleted RT-Component is registered. The registered RT-Components
+ # are deleted by cleanupComponents().
+ #
+ # @param Deleted RT component
+ # @endif
+ #
+ # void notifyFinalized(RTObject_impl* comp);
+ def notifyFinalized(self, comp):
+ self._rtcout.RTC_TRACE("Manager.notifyFinalized()")
+ guard = OpenRTM_aist.ScopedLock(self._finalized.mutex)
+ self._finalized.comps.append(comp)
+ del guard
+ return
+
+
+ ##
+ # @if jp
+ # @brief createComponentの引数を処理する
+ # @ param self
+ # @ param comp_arg(str)
+ # @ param comp_id(Properties object)
+ # @ param comp_conf(Properties object)
+ # @ return True or False
+ # @else
+ #
+ # @endif
+ #
+ # bool procComponentArgs(const char* comp_arg,
+ # coil::Properties& comp_id,
+ # coil::Properties& comp_conf)
+ def procComponentArgs(self, comp_arg, comp_id, comp_conf):
+ id_and_conf = [s.strip() for s in comp_arg.split("?")]
+ if len(id_and_conf) != 1 and len(id_and_conf) != 2:
+ self._rtcout.RTC_ERROR("Invalid arguments. Two or more '?'")
+ return False
+
+ if id_and_conf[0].find(":") == -1:
+ id_and_conf[0] = "RTC:::" + id_and_conf[0] + ":"
+
+ id = [s.strip() for s in id_and_conf[0].split(":")]
+
+ if len(id) != 5:
+ self._rtcout.RTC_ERROR("Invalid RTC id format.")
+ return False
+
+ prof = ["RTC", "vendor", "category", "implementation_id", "version"]
+
+ if id[0] != prof[0]:
+ self._rtcout.RTC_ERROR("Invalid id type.")
+ return False
+
+ for i in [1,2,3,4]:
+ comp_id.setProperty(prof[i], id[i])
+ self._rtcout.RTC_TRACE("RTC basic profile %s: %s", (prof[i], id[i]))
+
+ if len(id_and_conf) == 2:
+ conf = [s.strip() for s in id_and_conf[1].split("&")]
+ for i in range(len(conf)):
+ keyval = [s.strip() for s in conf[i].split("=")]
+ if len(keyval) > 1:
+ comp_conf.setProperty(keyval[0],keyval[1])
+ self._rtcout.RTC_TRACE("RTC property %s: %s", (keyval[0], keyval[1]))
+
+ return True
+
+
+ # bool procContextArgs(const char* ec_args,
+ # std::string& ec_id,
+ # coil::Properties& ec_conf);
+ def procContextArgs(self, ec_args, ec_id, ec_conf):
+ id_and_conf = [s.strip() for s in ec_args.split("?")]
+
+ if len(id_and_conf) != 1 and len(id_and_conf) != 2:
+ self._rtcout.RTC_ERROR("Invalid arguments. Two or more '?'")
+ return False
+
+ if (id_and_conf[0] == "") or id_and_conf[0] is None:
+ self._rtcout.RTC_ERROR("Empty ExecutionContext's name")
+ return False
+
+ ec_id[0] = id_and_conf[0]
+
+ if len(id_and_conf) == 2:
+ conf = [s.strip() for s in id_and_conf[1].split("&")]
+ for i in range(len(conf)):
+ k = [s.strip() for s in conf[i].split("=")]
+ ec_conf.setProperty(k[0],k[1])
+ self._rtcout.RTC_TRACE("EC property %s: %s",(k[0],k[1]))
+
+ return True
+
+
+ ##
+ # @if jp
+ # @brief RTコンポーネントのコンフィギュレーション処理
+ #
+ # RTコンポーネントの型およびインスタンス毎に記載されたプロパティファイルの
+ # 情報を読み込み、コンポーネントに設定する。
+ # また、各コンポーネントの NamingService 登録時の名称を取得し、設定する。
+ #
+ # @param self
+ # @param comp コンフィギュレーション対象RTコンポーネント
+ #
+ # @else
+ #
+ # @endif
+ # void configureComponent(RTObject_impl* comp, const coil::Properties& prop);
+ def configureComponent(self, comp, prop):
+ category = comp.getCategory()
+ type_name = comp.getTypeName()
+ inst_name = comp.getInstanceName()
+
+ type_conf = category + "." + type_name + ".config_file"
+ name_conf = category + "." + inst_name + ".config_file"
+
+ type_prop = OpenRTM_aist.Properties()
+
+ name_prop = OpenRTM_aist.Properties()
+ config_fname = []
+
+ if self._config.getProperty(name_conf) != "":
+ try:
+ conff = open(self._config.getProperty(name_conf))
+ name_prop.load(conff)
+ self._rtcout.RTC_INFO("Component instance conf file: %s loaded.",
+ self._config.getProperty(name_conf))
+ self._rtcout.RTC_DEBUG(name_prop)
+ config_fname.append(self._config.getProperty(name_conf))
+ except:
+ print "Not found. : %s" % self._config.getProperty(name_conf)
+ self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
+ else:
+ name_prop.load(conff)
+
+ if self._config.findNode(category + "." + inst_name):
+ temp_ = OpenRTM_aist.Properties(prop=self._config.getNode(category+"."+inst_name))
+ keys_ = temp_.propertyNames()
+ if not (len(keys_) == 1 and keys_[-1] == "config_file"):
+ name_prop.mergeProperties(self._config.getNode(category + "." + inst_name))
+ self._rtcout.RTC_INFO("Component name conf exists in rtc.conf. Merged.")
+ self._rtcout.RTC_DEBUG(name_prop)
+ if self._config.findNode("config_file"):
+ config_fname.append(self._config.getProperty("config_file"))
+
+ if self._config.getProperty(type_conf) != "":
+ try:
+ conff = open(self._config.getProperty(type_conf))
+ type_prop.load(conff)
+ self._rtcout.RTC_INFO("Component type conf file: %s loaded.",
+ self._config.getProperty(type_conf))
+ self._rtcout.RTC_DEBUG(type_prop)
+ config_fname.append(self._config.getProperty(type_conf))
+ except:
+ print "Not found. : %s" % self._config.getProperty(type_conf)
+ self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
+ else:
+ type_prop.load(conff)
+
+ if self._config.findNode(category + "." + type_name):
+ temp_ = OpenRTM_aist.Properties(prop=self._config.getNode(category+"."+type_name))
+ keys_ = temp_.propertyNames()
+ if not (len(keys_) == 1 and keys_[-1] == "config_file"):
+ type_prop.mergeProperties(self._config.getNode(category + "." + type_name))
+ self._rtcout.RTC_INFO("Component type conf exists in rtc.conf. Merged.")
+ self._rtcout.RTC_DEBUG(type_prop)
+ if self._config.findNode("config_file"):
+ config_fname.append(self._config.getProperty("config_file"))
+
+ comp.setProperties(prop)
+ type_prop.mergeProperties(name_prop)
+ type_prop.setProperty("config_file",OpenRTM_aist.flatten(OpenRTM_aist.unique_sv(config_fname)))
+ comp.setProperties(type_prop)
+
+ comp_prop = OpenRTM_aist.Properties(prop=comp.getProperties())
+
+ naming_formats = self._config.getProperty("naming.formats")
+ if comp_prop.findNode("naming.formats"):
+ naming_formats = comp_prop.getProperty("naming.formats")
+ naming_formats = OpenRTM_aist.flatten(OpenRTM_aist.unique_sv(OpenRTM_aist.split(naming_formats, ",")))
+
+ naming_names = self.formatString(naming_formats, comp.getProperties())
+ comp.getProperties().setProperty("naming.formats",naming_formats)
+ comp.getProperties().setProperty("naming.names",naming_names)
+ return
+
+
+ ##
+ # @if jp
+ # @brief プロパティ情報のマージ
+ #
+ # 指定されたファイル内に設定されているプロパティ情報をロードし、
+ # 既存の設定済みプロパティとマージする。
+ #
+ # @param self
+ # @param prop マージ対象プロパティ
+ # @param file_name プロパティ情報が記述されているファイル名
+ #
+ # @return マージ処理実行結果(マージ成功:true、マージ失敗:false)
+ #
+ # @else
+ #
+ # @endif
+ def mergeProperty(self, prop, file_name):
+ if file_name == "":
+ self._rtcout.RTC_ERROR("Invalid configuration file name.")
+ return False
+
+ if file_name[0] != '\0':
+
+ try:
+ conff = open(file_name)
+ except:
+ print "Not found. : %s" % file_name
+ self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
+ else:
+ prop.load(conff)
+ conff.close()
+ return True
+
+ return False
+
+
+ ##
+ # @if jp
+ # @brief NamingServer に登録する際の登録情報を組み立てる
+ #
+ # 指定された書式とプロパティ情報を基に NameServer に登録する際の情報を
+ # 組み立てる。
+ # 各書式指定用文字の意味は以下のとおり
+ # - % : コンテキストの区切り
+ # - n : インスタンス名称
+ # - t : 型名
+ # - m : 型名
+ # - v : バージョン
+ # - V : ベンダー
+ # - c : カテゴリ
+ # - h : ホスト名
+ # - M : マネージャ名
+ # - p : プロセスID
+ #
+ # @param self
+ # @param naming_format NamingService 登録情報書式指定
+ # @param prop 使用するプロパティ情報
+ #
+ # @return 指定書式変換結果
+ #
+ # @else
+ #
+ # @endif
+ def formatString(self, naming_format, prop):
+ name_ = naming_format
+ str_ = ""
+ count = 0
+ len_ = len(name_)
+ it = iter(name_)
+
+ try:
+ while 1:
+ n = it.next()
+ if n == '%':
+ count+=1
+ if not (count % 2):
+ str_ += n
+ elif n == '$':
+ count = 0
+ n = it.next()
+ if n == '{' or n == '(':
+ n = it.next()
+ env = ""
+ for i in xrange(len_):
+ if n == '}' or n == ')':
+ break
+ env += n
+ n = it.next()
+ envval = os.getenv(env)
+ if envval:
+ str_ += envval
+ else:
+ str_ += n
+ else:
+ if count > 0 and (count % 2):
+ count = 0
+ if n == "n": str_ += prop.getProperty("instance_name")
+ elif n == "t": str_ += prop.getProperty("type_name")
+ elif n == "m": str_ += prop.getProperty("type_name")
+ elif n == "v": str_ += prop.getProperty("version")
+ elif n == "V": str_ += prop.getProperty("vendor")
+ elif n == "c": str_ += prop.getProperty("category")
+ elif n == "h": str_ += self._config.getProperty("manager.os.hostname")
+ elif n == "M": str_ += self._config.getProperty("manager.name")
+ elif n == "p": str_ += str(self._config.getProperty("manager.pid"))
+ else: str_ += n
+ else:
+ count = 0
+ str_ += n
+ except:
+ # Caught StopIteration exception.
+ return str_
+
+ return str_
+
+
+ ##
+ # @if jp
+ # @brief ログバッファの取得
+ #
+ # マネージャに設定したログバッファを取得する。
+ #
+ # @param self
+ #
+ # @return マネージャに設定したログバッファ
+ #
+ # @else
+ #
+ # @endif
+ def getLogbuf(self,name="manager"):
+ if not OpenRTM_aist.toBool(self._config.getProperty("logger.enable"), "YES", "NO", True):
+ return OpenRTM_aist.LogStream()
+
+ logbuf = OpenRTM_aist.LogStream(name)
+ logbuf.setLogLevel(self._config.getProperty("logger.log_level"))
+ return logbuf
+
+
+ ##
+ # @if jp
+ # @brief マネージャコンフィギュレーションの取得
+ #
+ # マネージャに設定したコンフィギュレーションを取得する。
+ #
+ # @param self
+ #
+ # @return マネージャのコンフィギュレーション
+ #
+ # @else
+ #
+ # @endif
+ def getConfig(self):
+ return self._config
+
+
+ ##
+ # @if jp
+ # @brief コンポーネントファイル(.py)から
+ #
+ # マネージャに設定したコンフィギュレーションを取得する。
+ #
+ # @param self
+ #
+ # @return マネージャのコンフィギュレーション
+ #
+ # @else
+ #
+ # @endif
+ def __try_direct_load(self, file_name):
+ try:
+ pathChanged=False
+ splitted_name = os.path.split(file_name)
+ save_path = sys.path[:]
+ sys.path.append(splitted_name[0])
+ import_name = splitted_name[-1].split(".py")[0]
+ mo = __import__(import_name)
+ sys.path = save_path
+ _spec = getattr(mo,import_name.lower()+"_spec",None)
+ _klass = getattr(mo,import_name,None)
+ if _spec and _klass:
+ prof = OpenRTM_aist.Properties(defaults_str=_spec)
+ self.registerFactory(prof,
+ _klass,
+ OpenRTM_aist.Delete)
+ except:
+ self._rtcout.RTC_ERROR("Module load error: %s", file_name)
+ self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
+
+ return
+
+
+
+ #============================================================
+ # コンポーネントマネージャ
+ #============================================================
+ ##
+ # @if jp
+ # @class InstanceName
+ # @brief ObjectManager 検索用ファンクタ
+ #
+ # @else
+ #
+ # @endif
+ class InstanceName:
+ """
+ """
+
+ ##
+ # @if jp
+ # @brief コンストラクタ
+ #
+ # コンストラクタ
+ #
+ # @param self
+ # @param name 検索対象コンポーネント名称(デフォルト値:None)
+ # @param factory 検索対象ファクトリ名称(デフォルト値:None)
+ #
+ # @else
+ #
+ # @endif
+ def __init__(self, name=None, factory=None, prop=None):
+ if prop:
+ self._name = prop.getInstanceName()
+ if factory:
+ self._name = factory.getInstanceName()
+ elif name:
+ self._name = name
+
+ def __call__(self, factory):
+ return self._name == factory.getInstanceName()
+
+
+
+ #============================================================
+ # コンポーネントファクトリ
+ #============================================================
+ ##
+ # @if jp
+ # @class FactoryPredicate
+ # @brief コンポーネントファクトリ検索用ファンクタ
+ #
+ # @else
+ #
+ # @endif
+ class FactoryPredicate:
+
+ def __init__(self, name=None, prop=None, factory=None):
+ if name:
+ self._vendor = ""
+ self._category = ""
+ self._impleid = name
+ self._version = ""
+ elif prop:
+ self._vendor = prop.getProperty("vendor")
+ self._category = prop.getProperty("category")
+ self._impleid = prop.getProperty("implementation_id")
+ self._version = prop.getProperty("version")
+ elif factory:
+ self._vendor = factory.profile().getProperty("vendor")
+ self._category = factory.profile().getProperty("category")
+ self._impleid = factory.profile().getProperty("implementation_id")
+ self._version = factory.profile().getProperty("version")
+
+
+ def __call__(self, factory):
+ if self._impleid == "":
+ return False
+
+ _prop = OpenRTM_aist.Properties(prop=factory.profile())
+
+ if self._impleid != _prop.getProperty("implementation_id"):
+ return False
+
+ if self._vendor != "" and self._vendor != _prop.getProperty("vendor"):
+ return False
+
+ if self._category != "" and self._category != _prop.getProperty("category"):
+ return False
+
+ if self._version != "" and self._version != _prop.getProperty("version"):
+ return False
+
+ return True
+
+
+
+ #============================================================
+ # ExecutionContextファクトリ
+ #============================================================
+ ##
+ # @if jp
+ # @class ECFactoryPredicate
+ # @brief ExecutionContextファクトリ検索用ファンクタ
+ #
+ # @else
+ #
+ # @endif
+ class ECFactoryPredicate:
+
+
+
+ def __init__(self, name=None, factory=None):
+ if name:
+ self._name = name
+ elif factory:
+ self._name = factory.name()
+
+ def __call__(self, factory):
+ return self._name == factory.name()
+
+
+ #============================================================
+ # Module Fanctor
+ #============================================================
+ ##
+ # @if jp
+ # @class ModulePredicate
+ # @brief Module検索用ファンクタ
+ #
+ # @else
+ #
+ # @endif
+ class ModulePredicate:
+
+ # ModulePredicate(coil::Properties& prop)
+ def __init__(self, prop):
+ self._prop = prop
+ return
+
+ # bool operator()(coil::Properties& prop)
+ def __call__(self, prop):
+
+ if self._prop.getProperty("implementation_id") != prop.getProperty("implementation_id"):
+ return False
+
+ if self._prop.getProperty("vendor") and \
+ self._prop.getProperty("vendor") != prop.getProperty("vendor"):
+ return False
+
+ if self._prop.getProperty("category") and \
+ self._prop.getProperty("category") != prop.getProperty("category"):
+ return False
+
+ if self._prop.getProperty("version") and \
+ self._prop.getProperty("version") != prop.getProperty("version"):
+ return False
+
+ return True
+
+
+ #------------------------------------------------------------
+ # ORB runner
+ #------------------------------------------------------------
+ ##
+ # @if jp
+ # @class OrbRunner
+ # @brief OrbRunner クラス
+ #
+ # ORB 実行用ヘルパークラス。
+ #
+ # @since 0.4.0
+ #
+ # @else
+ # @class OrbRunner
+ # @brief OrbRunner class
+ # @endif
+ class OrbRunner:
+ """
+ """
+
+ ##
+ # @if jp
+ # @brief コンストラクタ
+ #
+ # コンストラクタ
+ #
+ # @param self
+ # @param orb ORB
+ #
+ # @else
+ # @brief Constructor
+ #
+ # @endif
+ def __init__(self, orb):
+ self._orb = orb
+ self._th = threading.Thread(target=self.run)
+ self._th.start()
+
+
+ def __del__(self):
+ self._th.join()
+ self._th = None
+ return
+
+
+ ##
+ # @if jp
+ # @brief ORB 実行処理
+ #
+ # ORB 実行
+ #
+ # @param self
+ #
+ # @else
+ #
+ # @endif
+ def run(self):
+ try:
+ self._orb.run()
+ #Manager.instance().shutdown()
+ except:
+ print OpenRTM_aist.Logger.print_exception()
+ pass
+ return
+
+
+ ##
+ # @if jp
+ # @brief ORB wait処理
+ #
+ # ORB wait
+ #
+ # @param self
+ #
+ # @else
+ #
+ # @endif
+ def wait(self):
+ return
+
+ ##
+ # @if jp
+ # @brief ORB 終了処理(未実装)
+ #
+ # ORB 終了処理
+ #
+ # @param self
+ # @param flags 終了処理フラグ
+ #
+ # @return 終了処理結果
+ #
+ # @else
+ #
+ # @endif
+ def close(self, flags):
+ return 0
+
+
+ #------------------------------------------------------------
+ # Manager Terminator
+ #------------------------------------------------------------
+ ##
+ # @if jp
+ # @class Terminator
+ # @brief Terminator クラス
+ #
+ # ORB 終了用ヘルパークラス。
+ #
+ # @since 0.4.0
+ #
+ # @else
+ #
+ # @endif
+ class Terminator:
+ """
+ """
+
+ ##
+ # @if jp
+ # @brief コンストラクタ
+ #
+ # コンストラクタ
+ #
+ # @param self
+ # @param manager マネージャ・オブジェクト
+ #
+ # @else
+ # @brief Constructor
+ #
+ # @endif
+ def __init__(self, manager):
+ self._manager = manager
+
+
+ ##
+ # @if jp
+ # @brief 終了処理
+ #
+ # ORB,マネージャ終了処理を開始する。
+ #
+ # @param self
+ #
+ # @else
+ #
+ # @endif
+ def terminate(self):
+ self._manager.shutdown()
+
+
+
+ ##
+ # @if jp
+ # @class Term
+ # @brief Term クラス
+ #
+ # 終了用ヘルパークラス。
+ #
+ # @since 0.4.0
+ #
+ # @else
+ #
+ # @endif
+ class Term:
+ def __init__(self):
+ self.waiting = 0
+ self.mutex = threading.RLock()
+
+
+ class Finalized:
+ def __init__(self):
+ self.mutex = threading.RLock()
+ self.comps = []
Modified: trunk/OpenRTM-aist-Python/OpenRTM_aist/NamingManager.py
===================================================================
--- trunk/OpenRTM-aist-Python/OpenRTM_aist/NamingManager.py 2016-02-01 05:29:04 UTC (rev 642)
+++ trunk/OpenRTM-aist-Python/OpenRTM_aist/NamingManager.py 2016-02-01 08:37:55 UTC (rev 643)
@@ -1,787 +1,639 @@
-#!/usr/bin/env python
-# -*- coding: euc-jp -*-
-
-##
-# @file NamingManager.py
-# @brief naming Service helper class
-# @date $Date: 2007/08/27$
-# @author Noriaki Ando <n-ando at aist.go.jp> and Shinji Kurihara
-#
-# Copyright (C) 2006-2008
-# Task-intelligence Research Group,
-# Intelligent Systems Research Institute,
-# National Institute of
-# Advanced Industrial Science and Technology (AIST), Japan
-# All rights reserved.
-
-
-import threading
-import traceback
-import sys
-
-import OpenRTM_aist
-
-
-##
-# @if jp
-#
-# @class NamingBase
-# @brief NamingService 管理用抽象クラス
-#
-# NamingServer 管理用抽象インターフェースクラス。
-# 具象管理クラスは、以下の関数の実装を提供しなければならない。
-# - bindObject() : 指定したオブジェクトのNamingServiceへのバインド
-# - unbindObject() : 指定したオブジェクトのNamingServiceからのアンバインド
-#
-# @since 0.4.0
-#
-# @else
-#
-# @endif
-class NamingBase:
- """
- """
-
- ##
- # @if jp
- #
- # @brief NamingServiceへバインドする関数(サブクラス実装用)
- #
- # 指定したオブジェクトをNamingServiceへバインドする<BR>
- # ※サブクラスでの実装参照用
- #
- # @param self
- # @param name バインド時の名称
- # @param rtobj バインド対象オブジェクト
- #
- # @else
- #
- # @endif
- def bindObject(self, name, rtobj):
- pass
-
-
- ##
- # @if jp
- #
- # @brief NamingServiceからアンバインドする関数(サブクラス実装用)
- #
- # 指定したオブジェクトをNamingServiceからアンバインドする<BR>
- # ※サブクラスでの実装参照用
- #
- # @param self
- # @param name アンバインド対象オブジェクト
- #
- # @else
- #
- # @endif
- def unbindObject(self, name):
- pass
-
- ##
- # @if jp
- #
- # @brief ネームサーバの生存を確認する。
- #
- # @return true:生存している, false:生存していない
- #
- # @else
- #
- # @brief Check if the name service is alive
- #
- # @return true: alive, false:non not alive
- #
- # @endif
- #
- # virtual bool isAlive() = 0;
- def isAlive(self):
- pass
-
-
-##
-# @if jp
-#
-# @class NamingOnCorba
-# @brief CORBA 用 NamingServer 管理クラス
-#
-# CORBA 用 NamingServer 管理用クラス。
-# CORBA コンポーネントのNamingServiceへの登録、解除などを管理する。
-#
-# @since 0.4.0
-#
-# @else
-#
-# @biref ModuleManager class
-#
-# @endif
-class NamingOnCorba(NamingBase):
- """
- """
-
- ##
- # @if jp
- #
- # @brief コンストラクタ
- #
- # コンストラクタ
- #
- # @param self
- # @param orb ORB
- # @param names NamingServer 名称
- #
- # @else
- #
- # @endif
- def __init__(self, orb, names):
- self._rtcout = OpenRTM_aist.Manager.instance().getLogbuf('manager.namingoncorba')
- self._cosnaming = OpenRTM_aist.CorbaNaming(orb,names)
- self._endpoint = ""
- self._replaceEndpoint = False
-
- ##
- # @if jp
- #
- # @brief 指定した CORBA オブジェクトのNamingServiceへバインド
- #
- # 指定した CORBA オブジェクトを指定した名称で CORBA NamingService へ
- # バインドする。
- #
- # @param self
- # @param name バインド時の名称
- # @param rtobj or mgr バインド対象オブジェクト
- #
- # @else
- #
- # @endif
- def bindObject(self, name, rtobj):
- self._rtcout.RTC_TRACE("bindObject(name = %s, rtobj or mgr)", name)
- try:
- self._cosnaming.rebindByString(name, rtobj.getObjRef(), True)
- except:
- self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
-
- return
-
-
- ##
- # @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 からアンバインドする。
- #
- # @param self
- # @param name アンバインド対象オブジェクト
- #
- # @else
- #
- # @endif
- def unbindObject(self, name):
- self._rtcout.RTC_TRACE("unbindObject(name = %s)", name)
- try:
- self._cosnaming.unbind(name)
- except:
- self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
-
- return
-
-
- ##
- # @if jp
- #
- # @brief ネームサーバの生存を確認する。
- #
- # @return true:生存している, false:生存していない
- #
- # @else
- #
- # @brief Check if the name service is alive
- #
- # @return true: alive, false:non not alive
- #
- # @endif
- #
- # virtual bool isAlive();
- def isAlive(self):
- self._rtcout.RTC_TRACE("isAlive()")
- return self._cosnaming.isAlive()
-
-
-
-
-
-##
-# @if jp
-#
-# @class NamingManager
-# @brief NamingServer 管理クラス
-#
-# NamingServer 管理用クラス。
-# コンポーネントのNamingServiceへの登録、解除などを管理する。
-#
-# @since 0.4.0
-#
-# @else
-#
-# @biref ModuleManager class
-#
-# @endif
-class NamingManager:
- """
- """
-
-
-
- ##
- # @if jp
- #
- # @brief コンストラクタ
- #
- # コンストラクタ
- #
- # @param self
- # @param manager マネージャオブジェクト
- #
- # @else
- #
- # @endif
- def __init__(self, manager):
- self._manager = manager
- self._rtcout = manager.getLogbuf('manager.namingmanager')
- #self._rtcout.setLogLevel(manager.getConfig().getProperty("logger.log_level"))
- #self._rtcout.setLogLock(OpenRTM_aist.toBool(manager.getConfig().getProperty("logger.stream_lock"), "enable", "disable", False))
- self._names = []
- self._namesMutex = threading.RLock()
- self._compNames = []
- self._mgrNames = []
- self._portNames = []
- self._compNamesMutex = threading.RLock()
- self._mgrNamesMutex = threading.RLock()
- self._portNamesMutex = threading.RLock()
-
-
- ##
- # @if jp
- #
- # @brief NameServer の登録
- #
- # 指定した形式の NameServer を登録する。
- # 現在指定可能な形式は CORBA のみ。
- #
- # @param self
- # @param method NamingService の形式
- # @param name_server 登録する NameServer の名称
- #
- # @else
- #
- # @endif
- def registerNameServer(self, method, name_server):
- self._rtcout.RTC_TRACE("NamingManager::registerNameServer(%s, %s)",
- (method, name_server))
- name = self.createNamingObj(method, name_server)
- self._names.append(self.NameServer(method, name_server, name))
-
-
- ##
- # @if jp
- #
- # @brief 指定したオブジェクトのNamingServiceへバインド
- #
- # 指定したオブジェクトを指定した名称で CORBA NamingService へバインドする。
- #
- # @param self
- # @param name バインド時の名称
- # @param rtobj バインド対象オブジェクト
- #
- # @else
- #
- # @endif
- def bindObject(self, name, rtobj):
- self._rtcout.RTC_TRACE("NamingManager::bindObject(%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.bindObject(name, rtobj)
- except:
- del self._names[i].ns
- self._names[i].ns = 0
-
- self.registerCompName(name, rtobj)
-
-
- def bindManagerObject(self, name, mgr):
- self._rtcout.RTC_TRACE("NamingManager::bindManagerObject(%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.bindObject(name, mgr)
- except:
- del self._names[i].ns
- self._names[i].ns = 0
-
- 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
- #
- # @brief NamingServer の情報の更新
- #
- # 設定されている NameServer 内に登録されているオブジェクトの情報を
- # 更新する。
- #
- # @param self
- #
- # @else
- #
- # @endif
- def update(self):
- self._rtcout.RTC_TRACE("NamingManager::update()")
- guard = OpenRTM_aist.ScopedLock(self._namesMutex)
- rebind = OpenRTM_aist.toBool(self._manager.getConfig().getProperty("naming.update.rebind"),
- "YES","NO",False)
- for i in range(len(self._names)):
- if self._names[i].ns is None:
- self._rtcout.RTC_DEBUG("Retrying connection to %s/%s",
- (self._names[i].method,
- self._names[i].nsname))
- self.retryConnection(self._names[i])
-
- else:
- try:
- if rebind:
- self.bindCompsTo(self._names[i].ns)
- if not self._names[i].ns.isAlive():
- self._rtcout.RTC_INFO("Name server: %s (%s) disappeared.",
- (self._names[i].nsname,
- self._names[i].method))
- del self._names[i].ns
- self._names[i].ns = None
- except:
- self._rtcout.RTC_INFO("Name server: %s (%s) disappeared.",
- (self._names[i].nsname,
- self._names[i].method))
- del self._names[i].ns
- self._names[i].ns = None
-
-
- return
-
-
- ##
- # @if jp
- #
- # @brief 指定したオブジェクトをNamingServiceからアンバインド
- #
- # 指定したオブジェクトを NamingService からアンバインドする。
- #
- # @param self
- # @param name アンバインド対象オブジェクト
- #
- # @else
- #
- # @endif
- def unbindObject(self, name):
- self._rtcout.RTC_TRACE("NamingManager::unbindObject(%s)", name)
- guard = OpenRTM_aist.ScopedLock(self._namesMutex)
- for i in range(len(self._names)):
- if self._names[i].ns:
- self._names[i].ns.unbindObject(name)
- self.unregisterCompName(name)
- self.unregisterMgrName(name)
- self.unregisterPortName(name)
-
-
- ##
- # @if jp
- #
- # @brief 全てのオブジェクトをNamingServiceからアンバインド
- #
- # 全てのオブジェクトを CORBA NamingService からアンバインドする。
- #
- # @param self
- #
- # @else
- #
- # @endif
- def unbindAll(self):
- self._rtcout.RTC_TRACE("NamingManager::unbindAll(): %d names.", len(self._compNames))
-
- guard = OpenRTM_aist.ScopedLock(self._compNamesMutex)
- len_ = len(self._compNames)
- for i in range(len_):
- idx = (len_ - 1) - i
- self.unbindObject(self._compNames[idx].name)
-
- guard = OpenRTM_aist.ScopedLock(self._mgrNamesMutex)
- len_ = len(self._mgrNames)
- for i in range(len_):
- idx = (len_ - 1) - i
- 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
- #
- # @brief バインドされている全てのオブジェクトを取得
- #
- # バインドされている全てのオブジェクトを 取得する。
- #
- # @param self
- #
- # @return バインド済みオブジェクト リスト
- #
- # @else
- #
- # @endif
- def getObjects(self):
- comps = []
- guard = OpenRTM_aist.ScopedLock(self._compNamesMutex)
- for i in range(len(self._compNames)):
- comps.append(self._compNames[i].rtobj)
- return comps
-
-
- ##
- # @if jp
- #
- # @brief NameServer 管理用オブジェクトの生成
- #
- # 指定した型のNameServer 管理用オブジェクトを生成する。
- #
- # @param self
- # @param method NamingService 形式
- # @param name_server NameServer 名称
- #
- # @return 生成した NameServer オブジェクト
- #
- # @else
- #
- # @endif
- def createNamingObj(self, method, name_server):
- self._rtcout.RTC_TRACE("createNamingObj(method = %s, nameserver = %s)",
- (method, name_server))
- mth = method
- if mth == "corba":
- try:
- name = OpenRTM_aist.NamingOnCorba(self._manager.getORB(),name_server)
- if name is None:
- return None
- self._rtcout.RTC_INFO("NameServer connection succeeded: %s/%s",
- (method, name_server))
- return name
- except:
- self._rtcout.RTC_INFO("NameServer connection failed: %s/%s",
- (method, name_server))
- return None
-
- return None
-
-
- ##
- # @if jp
- #
- # @brief 設定済みコンポーネントを NameServer に登録
- #
- # 設定済みコンポーネントを指定した NameServer に登録する。
- #
- # @param self
- # @param ns 登録対象 NameServer
- #
- # @else
- #
- # @endif
- def bindCompsTo(self, ns):
- for i in range(len(self._compNames)):
- ns.bindObject(self._compNames[i].name, self._compNames[i].rtobj)
-
-
- ##
- # @if jp
- #
- # @brief NameServer に登録するコンポーネントの設定
- #
- # NameServer に登録するコンポーネントを設定する。
- #
- # @param self
- # @param name コンポーネントの登録時名称
- # @param rtobj 登録対象オブジェクト
- #
- # @else
- #
- # @endif
- def registerCompName(self, name, rtobj):
- for i in range(len(self._compNames)):
- if self._compNames[i].name == name:
- self._compNames[i].rtobj = rtobj
- return
-
- self._compNames.append(self.Comps(name, rtobj))
- return
-
-
- def registerMgrName(self, name, mgr):
- for i in range(len(self._mgrNames)):
- if self._mgrNames[i].name == name:
- self._mgrNames[i].mgr = mgr
- return
-
- 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
- #
- # @brief NameServer に登録するコンポーネントの設定解除
- #
- # NameServer に登録するコンポーネントの設定を解除する。
- #
- # @param self
- # @param name 設定解除対象コンポーネントの名称
- #
- # @else
- #
- # @endif
- def unregisterCompName(self, name):
- len_ = len(self._compNames)
- for i in range(len_):
- idx = (len_-1) - i
- if self._compNames[idx].name == name:
- del self._compNames[idx]
- return
- return
-
-
- def unregisterMgrName(self, name):
- len_ = len(self._mgrNames)
- for i in range(len_):
- idx = (len_ -1) - i
- if self._mgrNames[idx].name == name:
- del self._mgrNames[idx]
- return
- return
-
-
- ##
- # @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 コンポネントをリバインドする
- #
- # ネームサーバと接続してコンポネントをリバインドする。
- #
- # @param ns NameServer
- #
- # @else
- #
- # @brief Rebind the component to NameServer
- #
- # Connect with the NameServer and rebind the component.
- #
- # @param ns NameServer
- #
- # @endif
- #
- # void retryConnection(Names* ns);
- def retryConnection(self, ns):
- # recreate NamingObj
- nsobj = 0
- try:
- nsobj = self.createNamingObj(ns.method, ns.nsname)
- if nsobj != 0: # if succeed
- self._rtcout.RTC_INFO("Connected to a name server: %s/%s",
- (ns.method, ns.nsname))
- ns.ns = nsobj
- self.bindCompsTo(nsobj) # rebind all comps to new NS
- return
- else:
- self._rtcout.RTC_DEBUG("Name service: %s/%s still not available.",
- (ns.method, ns.nsname))
-
- except:
- self._rtcout.RTC_DEBUG("Name server: %s/%s disappeared again.",
- (ns.method, ns.nsname))
- if nsobj != 0:
- del ns.ns
- ns.ns = 0
-
- 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 NameServer
- # @brief NameServer 管理用クラス
- # @else
- #
- # @endif
- class NameServer:
- def __init__(self, meth, name, naming):
- self.method = meth
- self.nsname = name
- self.ns = naming
-
-
- # Components' name and object
- ##
- # @if jp
- # @class Comps
- # @brief コンポーネント管理用クラス
- # @else
- #
- # @endif
- class Comps:
- def __init__(self, n, obj):
- self.name = n
- self.rtobj = obj
-
-
- class Mgr:
- 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
+#!/usr/bin/env python
+# -*- coding: euc-jp -*-
+
+##
+# @file NamingManager.py
+# @brief naming Service helper class
+# @date $Date: 2007/08/27$
+# @author Noriaki Ando <n-ando at aist.go.jp> and Shinji Kurihara
+#
+# Copyright (C) 2006-2008
+# Task-intelligence Research Group,
+# Intelligent Systems Research Institute,
+# National Institute of
+# Advanced Industrial Science and Technology (AIST), Japan
+# All rights reserved.
+
+
+import threading
+import traceback
+import sys
+
+import OpenRTM_aist
+
+
+##
+# @if jp
+#
+# @class NamingBase
+# @brief NamingService 管理用抽象クラス
+#
+# NamingServer 管理用抽象インターフェースクラス。
+# 具象管理クラスは、以下の関数の実装を提供しなければならない。
+# - bindObject() : 指定したオブジェクトのNamingServiceへのバインド
+# - unbindObject() : 指定したオブジェクトのNamingServiceからのアンバインド
+#
+# @since 0.4.0
+#
+# @else
+#
+# @endif
+class NamingBase:
+ """
+ """
+
+ ##
+ # @if jp
+ #
+ # @brief NamingServiceへバインドする関数(サブクラス実装用)
+ #
+ # 指定したオブジェクトをNamingServiceへバインドする<BR>
+ # ※サブクラスでの実装参照用
+ #
+ # @param self
+ # @param name バインド時の名称
+ # @param rtobj バインド対象オブジェクト
+ #
+ # @else
+ #
+ # @endif
+ def bindObject(self, name, rtobj):
+ pass
+
+
+ ##
+ # @if jp
+ #
+ # @brief NamingServiceからアンバインドする関数(サブクラス実装用)
+ #
+ # 指定したオブジェクトをNamingServiceからアンバインドする<BR>
+ # ※サブクラスでの実装参照用
+ #
+ # @param self
+ # @param name アンバインド対象オブジェクト
+ #
+ # @else
+ #
+ # @endif
+ def unbindObject(self, name):
+ pass
+
+ ##
+ # @if jp
+ #
+ # @brief ネームサーバの生存を確認する。
+ #
+ # @return true:生存している, false:生存していない
+ #
+ # @else
+ #
+ # @brief Check if the name service is alive
+ #
+ # @return true: alive, false:non not alive
+ #
+ # @endif
+ #
+ # virtual bool isAlive() = 0;
+ def isAlive(self):
+ pass
+
+
+##
+# @if jp
+#
+# @class NamingOnCorba
+# @brief CORBA 用 NamingServer 管理クラス
+#
+# CORBA 用 NamingServer 管理用クラス。
+# CORBA コンポーネントのNamingServiceへの登録、解除などを管理する。
+#
+# @since 0.4.0
+#
+# @else
+#
+# @biref ModuleManager class
+#
+# @endif
+class NamingOnCorba(NamingBase):
+ """
+ """
+
+ ##
+ # @if jp
+ #
+ # @brief コンストラクタ
+ #
+ # コンストラクタ
+ #
+ # @param self
+ # @param orb ORB
+ # @param names NamingServer 名称
+ #
+ # @else
+ #
+ # @endif
+ def __init__(self, orb, names):
+ self._rtcout = OpenRTM_aist.Manager.instance().getLogbuf('manager.namingoncorba')
+ self._cosnaming = OpenRTM_aist.CorbaNaming(orb,names)
+ self._endpoint = ""
+ self._replaceEndpoint = False
+
+ ##
+ # @if jp
+ #
+ # @brief 指定した CORBA オブジェクトのNamingServiceへバインド
+ #
+ # 指定した CORBA オブジェクトを指定した名称で CORBA NamingService へ
+ # バインドする。
+ #
+ # @param self
+ # @param name バインド時の名称
+ # @param rtobj or mgr バインド対象オブジェクト
+ #
+ # @else
+ #
+ # @endif
+ def bindObject(self, name, rtobj):
+ self._rtcout.RTC_TRACE("bindObject(name = %s, rtobj or mgr)", name)
+ try:
+ self._cosnaming.rebindByString(name, rtobj.getObjRef(), True)
+ except:
+ self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
+
+ return
+
+
+ ##
+ # @if jp
+ #
+ # @brief 指定した CORBA オブジェクトをNamingServiceからアンバインド
+ #
+ # 指定した CORBA オブジェクトを CORBA NamingService からアンバインドする。
+ #
+ # @param self
+ # @param name アンバインド対象オブジェクト
+ #
+ # @else
+ #
+ # @endif
+ def unbindObject(self, name):
+ self._rtcout.RTC_TRACE("unbindObject(name = %s)", name)
+ try:
+ self._cosnaming.unbind(name)
+ except:
+ self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
+
+ return
+
+
+ ##
+ # @if jp
+ #
+ # @brief ネームサーバの生存を確認する。
+ #
+ # @return true:生存している, false:生存していない
+ #
+ # @else
+ #
+ # @brief Check if the name service is alive
+ #
+ # @return true: alive, false:non not alive
+ #
+ # @endif
+ #
+ # virtual bool isAlive();
+ def isAlive(self):
+ self._rtcout.RTC_TRACE("isAlive()")
+ return self._cosnaming.isAlive()
+
+
+##
+# @if jp
+#
+# @class NamingManager
+# @brief NamingServer 管理クラス
+#
+# NamingServer 管理用クラス。
+# コンポーネントのNamingServiceへの登録、解除などを管理する。
+#
+# @since 0.4.0
+#
+# @else
+#
+# @biref ModuleManager class
+#
+# @endif
+class NamingManager:
+ """
+ """
+
+
+
+ ##
+ # @if jp
+ #
+ # @brief コンストラクタ
+ #
+ # コンストラクタ
+ #
+ # @param self
+ # @param manager マネージャオブジェクト
+ #
+ # @else
+ #
+ # @endif
+ def __init__(self, manager):
+ self._manager = manager
+ self._rtcout = manager.getLogbuf('manager.namingmanager')
+ #self._rtcout.setLogLevel(manager.getConfig().getProperty("logger.log_level"))
+ #self._rtcout.setLogLock(OpenRTM_aist.toBool(manager.getConfig().getProperty("logger.stream_lock"), "enable", "disable", False))
+ self._names = []
+ self._namesMutex = threading.RLock()
+ self._compNames = []
+ self._mgrNames = []
+ self._compNamesMutex = threading.RLock()
+ self._mgrNamesMutex = threading.RLock()
+
+
+ ##
+ # @if jp
+ #
+ # @brief NameServer の登録
+ #
+ # 指定した形式の NameServer を登録する。
+ # 現在指定可能な形式は CORBA のみ。
+ #
+ # @param self
+ # @param method NamingService の形式
+ # @param name_server 登録する NameServer の名称
+ #
+ # @else
+ #
+ # @endif
+ def registerNameServer(self, method, name_server):
+ 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))
+
+
+ ##
+ # @if jp
+ #
+ # @brief 指定したオブジェクトのNamingServiceへバインド
+ #
+ # 指定したオブジェクトを指定した名称で CORBA NamingService へバインドする。
+ #
+ # @param self
+ # @param name バインド時の名称
+ # @param rtobj バインド対象オブジェクト
+ #
+ # @else
+ #
+ # @endif
+ def bindObject(self, name, rtobj):
+ self._rtcout.RTC_TRACE("NamingManager::bindObject(%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.bindObject(name, rtobj)
+ except:
+ del self._names[i].ns
+ self._names[i].ns = 0
+
+ self.registerCompName(name, rtobj)
+
+
+ def bindManagerObject(self, name, mgr):
+ self._rtcout.RTC_TRACE("NamingManager::bindManagerObject(%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.bindObject(name, mgr)
+ except:
+ del self._names[i].ns
+ self._names[i].ns = 0
+
+ self.registerMgrName(name, mgr)
+
+
+ ##
+ # @if jp
+ #
+ # @brief NamingServer の情報の更新
+ #
+ # 設定されている NameServer 内に登録されているオブジェクトの情報を
+ # 更新する。
+ #
+ # @param self
+ #
+ # @else
+ #
+ # @endif
+ def update(self):
+ self._rtcout.RTC_TRACE("NamingManager::update()")
+ guard = OpenRTM_aist.ScopedLock(self._namesMutex)
+ rebind = OpenRTM_aist.toBool(self._manager.getConfig().getProperty("naming.update.rebind"),
+ "YES","NO",False)
+ for i in range(len(self._names)):
+ if self._names[i].ns is None:
+ self._rtcout.RTC_DEBUG("Retrying connection to %s/%s",
+ (self._names[i].method,
+ self._names[i].nsname))
+ self.retryConnection(self._names[i])
+
+ else:
+ try:
+ if rebind:
+ self.bindCompsTo(self._names[i].ns)
+ if not self._names[i].ns.isAlive():
+ self._rtcout.RTC_INFO("Name server: %s (%s) disappeared.",
+ (self._names[i].nsname,
+ self._names[i].method))
+ del self._names[i].ns
+ self._names[i].ns = None
+ except:
+ self._rtcout.RTC_INFO("Name server: %s (%s) disappeared.",
+ (self._names[i].nsname,
+ self._names[i].method))
+ del self._names[i].ns
+ self._names[i].ns = None
+
+
+ return
+
+
+ ##
+ # @if jp
+ #
+ # @brief 指定したオブジェクトをNamingServiceからアンバインド
+ #
+ # 指定したオブジェクトを NamingService からアンバインドする。
+ #
+ # @param self
+ # @param name アンバインド対象オブジェクト
+ #
+ # @else
+ #
+ # @endif
+ def unbindObject(self, name):
+ self._rtcout.RTC_TRACE("NamingManager::unbindObject(%s)", name)
+ guard = OpenRTM_aist.ScopedLock(self._namesMutex)
+ for i in range(len(self._names)):
+ if self._names[i].ns:
+ self._names[i].ns.unbindObject(name)
+ self.unregisterCompName(name)
+ self.unregisterMgrName(name)
+
+
+ ##
+ # @if jp
+ #
+ # @brief 全てのオブジェクトをNamingServiceからアンバインド
+ #
+ # 全てのオブジェクトを CORBA NamingService からアンバインドする。
+ #
+ # @param self
+ #
+ # @else
+ #
+ # @endif
+ def unbindAll(self):
+ self._rtcout.RTC_TRACE("NamingManager::unbindAll(): %d names.", len(self._compNames))
+
+ guard = OpenRTM_aist.ScopedLock(self._compNamesMutex)
+ len_ = len(self._compNames)
+ for i in range(len_):
+ idx = (len_ - 1) - i
+ self.unbindObject(self._compNames[idx].name)
+
+ guard = OpenRTM_aist.ScopedLock(self._mgrNamesMutex)
+ len_ = len(self._mgrNames)
+ for i in range(len_):
+ idx = (len_ - 1) - i
+ self.unbindObject(self._mgrNames[idx].name)
+
+
+ ##
+ # @if jp
+ #
+ # @brief バインドされている全てのオブジェクトを取得
+ #
+ # バインドされている全てのオブジェクトを 取得する。
+ #
+ # @param self
+ #
+ # @return バインド済みオブジェクト リスト
+ #
+ # @else
+ #
+ # @endif
+ def getObjects(self):
+ comps = []
+ guard = OpenRTM_aist.ScopedLock(self._compNamesMutex)
+ for i in range(len(self._compNames)):
+ comps.append(self._compNames[i].rtobj)
+ return comps
+
+
+ ##
+ # @if jp
+ #
+ # @brief NameServer 管理用オブジェクトの生成
+ #
+ # 指定した型のNameServer 管理用オブジェクトを生成する。
+ #
+ # @param self
+ # @param method NamingService 形式
+ # @param name_server NameServer 名称
+ #
+ # @return 生成した NameServer オブジェクト
+ #
+ # @else
+ #
+ # @endif
+ def createNamingObj(self, method, name_server):
+ self._rtcout.RTC_TRACE("createNamingObj(method = %s, nameserver = %s)",
+ (method, name_server))
+ mth = method
+ if mth == "corba":
+ try:
+ name = OpenRTM_aist.NamingOnCorba(self._manager.getORB(),name_server)
+ if name is None:
+ return None
+ self._rtcout.RTC_INFO("NameServer connection succeeded: %s/%s",
+ (method, name_server))
+ return name
+ except:
+ self._rtcout.RTC_INFO("NameServer connection failed: %s/%s",
+ (method, name_server))
+ return None
+
+ return None
+
+
+ ##
+ # @if jp
+ #
+ # @brief 設定済みコンポーネントを NameServer に登録
+ #
+ # 設定済みコンポーネントを指定した NameServer に登録する。
+ #
+ # @param self
+ # @param ns 登録対象 NameServer
+ #
+ # @else
+ #
+ # @endif
+ def bindCompsTo(self, ns):
+ for i in range(len(self._compNames)):
+ ns.bindObject(self._compNames[i].name, self._compNames[i].rtobj)
+
+
+ ##
+ # @if jp
+ #
+ # @brief NameServer に登録するコンポーネントの設定
+ #
+ # NameServer に登録するコンポーネントを設定する。
+ #
+ # @param self
+ # @param name コンポーネントの登録時名称
+ # @param rtobj 登録対象オブジェクト
+ #
+ # @else
+ #
+ # @endif
+ def registerCompName(self, name, rtobj):
+ for i in range(len(self._compNames)):
+ if self._compNames[i].name == name:
+ self._compNames[i].rtobj = rtobj
+ return
+
+ self._compNames.append(self.Comps(name, rtobj))
+ return
+
+
+ def registerMgrName(self, name, mgr):
+ for i in range(len(self._mgrNames)):
+ if self._mgrNames[i].name == name:
+ self._mgrNames[i].mgr = mgr
+ return
+
+ self._mgrNames.append(self.Mgr(name, mgr))
+ return
+
+
+ ##
+ # @if jp
+ #
+ # @brief NameServer に登録するコンポーネントの設定解除
+ #
+ # NameServer に登録するコンポーネントの設定を解除する。
+ #
+ # @param self
+ # @param name 設定解除対象コンポーネントの名称
+ #
+ # @else
+ #
+ # @endif
+ def unregisterCompName(self, name):
+ len_ = len(self._compNames)
+ for i in range(len_):
+ idx = (len_-1) - i
+ if self._compNames[idx].name == name:
+ del self._compNames[idx]
+ return
+ return
+
+
+ def unregisterMgrName(self, name):
+ len_ = len(self._mgrNames)
+ for i in range(len_):
+ idx = (len_ -1) - i
+ if self._mgrNames[idx].name == name:
+ del self._mgrNames[idx]
+ return
+ return
+
+
+ ##
+ # @if jp
+ #
+ # @brief コンポネントをリバインドする
+ #
+ # ネームサーバと接続してコンポネントをリバインドする。
+ #
+ # @param ns NameServer
+ #
+ # @else
+ #
+ # @brief Rebind the component to NameServer
+ #
+ # Connect with the NameServer and rebind the component.
+ #
+ # @param ns NameServer
+ #
+ # @endif
+ #
+ # void retryConnection(Names* ns);
+ def retryConnection(self, ns):
+ # recreate NamingObj
+ nsobj = 0
+ try:
+ nsobj = self.createNamingObj(ns.method, ns.nsname)
+ if nsobj != 0: # if succeed
+ self._rtcout.RTC_INFO("Connected to a name server: %s/%s",
+ (ns.method, ns.nsname))
+ ns.ns = nsobj
+ self.bindCompsTo(nsobj) # rebind all comps to new NS
+ return
+ else:
+ self._rtcout.RTC_DEBUG("Name service: %s/%s still not available.",
+ (ns.method, ns.nsname))
+
+ except:
+ self._rtcout.RTC_DEBUG("Name server: %s/%s disappeared again.",
+ (ns.method, ns.nsname))
+ if nsobj != 0:
+ del ns.ns
+ ns.ns = 0
+
+ return
+
+
+ # Name Servers' method/name and object
+ ##
+ # @if jp
+ # @class Names
+ # @brief NameServer 管理用クラス
+ # @else
+ #
+ # @endif
+ class Names:
+ def __init__(self, meth, name, naming):
+ self.method = meth
+ self.nsname = name
+ self.ns = naming
+
+
+ # Components' name and object
+ ##
+ # @if jp
+ # @class Comps
+ # @brief コンポーネント管理用クラス
+ # @else
+ #
+ # @endif
+ class Comps:
+ def __init__(self, n, obj):
+ self.name = n
+ self.rtobj = obj
+
+
+ class Mgr:
+ def __init__(self, n, obj):
+ self.name = n
+ self.mgr = obj
Modified: trunk/OpenRTM-aist-Python/OpenRTM_aist/OutPortBase.py
===================================================================
--- trunk/OpenRTM-aist-Python/OpenRTM_aist/OutPortBase.py 2016-02-01 05:29:04 UTC (rev 642)
+++ trunk/OpenRTM-aist-Python/OpenRTM_aist/OutPortBase.py 2016-02-01 08:37:55 UTC (rev 643)
@@ -1,1296 +1,1245 @@
-#!/usr/bin/env python
-# -*- coding: euc-jp -*-
-
-##
-# @file OutPortBase.py
-# @brief OutPortBase base class
-# @date $Date: 2007/09/19 $
-# @author Noriaki Ando <n-ando at aist.go.jp> and Shinji Kurihara
-#
-# Copyright (C) 2003-2008
-# Task-intelligence Research Group,
-# Intelligent Systems Research Institute,
-# National Institute of
-# Advanced Industrial Science and Technology (AIST), Japan
-# All rights reserved.
-
-import copy
-import threading
-import OpenRTM_aist
-import RTC
-
-##
-# @if jp
-#
-# @class OutPortBase
-#
-# @brief OutPort 基底クラス
-#
-# OutPort の基底クラス。
-#
-#
-#
-# Properties: port.outport
-# プロパティは
-#
-# - port.outport
-# - port.outport.[name]
-# ConnectorProfile.properties の場合は
-# - dataport.outport
-#
-# 以下に指定したものが渡される。
-# (port.outport.[name]が優先される)
-# さらに、一部のプロパティは接続時に ConnectorProfile により
-# 渡される場合があり、その場合は ConnectorProfile が優先される。
-#
-# - input.throughput.profile: enable
-# - input.throughput.update_rate: count [n/count]
-# - input.throughput.total_bytes: [bytes]
-# - input.throughput.total_count: [n]
-# - input.throughput.max_size: [bytes]
-# - input.throughput.min_size: [bytes]
-# - input.throughput.avg_size: [bytes]
-# - input.throughput.byte_sec: [bytes/sec]
-#
-# - output.throughput.profile: enable
-# - output.throughput.update_rate: count [n/count]
-# - output.throughput.total_bytes: [bytes]
-# - output.throughput.total_count:[n]
-# - output.throughput.max_size: [bytes]
-# - output.throughput.min_size: [bytes]
-# - output.throughput.avg_size: [bytes]
-# - output.throughput.max_sendtime: [sec]
-# - output.throughput.min_sendtime: [sec]
-# - output.throughput.avg_sendtime: [sec]
-# - output.throughput.byte_sec: [bytes/sec]
-#
-# dataport.dataflow_type
-# dataport.interface_type
-# dataport.subscription_type
-#
-# [buffer]
-#
-# - buffer.type:
-# 利用可能なバッファのタイプ
-# ConnectorProfile の場合は利用するバッファのタイプ
-# 無指定の場合はデフォルトの ringbuffer が使用される。
-# ex. ringbuffer, shmbuffer, doublebuffer, etc.
-# 正し、Consumer, Publisher のタイプによっては特定のバッファ型を
-# 要求するがあるための、その場合は指定は無効となる。
-#
-# - buffer.length:
-# バッファの長さ
-#
-# - buffer.write.full_policy:
-# 上書きするかどうかのポリシー
-# overwrite (上書き), do_nothing (何もしない), block (ブロックする)
-# block を指定した場合、次の timeout 値を指定すれば、指定時間後
-# 書き込み不可能であればタイムアウトする。
-#
-# - buffer.write.timeout:
-# タイムアウト時間を [sec] で指定する。
-# 1 sec -> 1.0, 1 ms -> 0.001, タイムアウトしない -> 0.0
-#
-# - buffer.read.empty_policy:
-# バッファが空のときの読み出しポリシー
-# last (最後の要素), do_nothing (何もしない), block (ブロックする)
-# block を指定した場合、次の timeout 値を指定すれば、指定時間後
-# 読み出し不可能であればタイムアウトする。
-#
-# - buffer.read.timeout:
-# タイムアウト時間 [sec] で指定する。
-# 1sec -> 1.0, 1ms -> 0.001, タイムアウトしない -> 0.0
-#
-# - その他バッファ毎に固有なオプション
-#
-#
-# [publihser]
-#
-# - publisher.types:
-# 利用可能な Publisher のタイプ
-# new, periodic, flush, etc..
-#
-# - publisher.push.policy:
-# InPortへデータを送信するポリシー
-# all: バッファにたまっているすべて送信
-# fifo: バッファをFIFOとみなして送信
-# skip: 古いデータから一定数を間引いて送信
-# new: 常に新しいデータのみを送信
-#
-# - publisher.push.skip_rate:
-# push.policy=skip のときのスキップ率
-# n: n要素毎にひとつ送信
-#
-# - publisher.periodic.rate:
-#
-# - publisher.thread.type:
-# Publisher のスレッドのタイプ
-# - publisher.thread.measurement.exec_time: yes/no
-# - publisher.thread.measurement.exec_count: number
-# - publisher.thread.measurement.period_time: yes/no
-# - publisher.thread.measurement.period_count: number
-#
-# [interface]
-#
-# - interface.types:
-# OutPort interfaceのタイプ
-# ex. corba_cdr, corba_any, raw_tcp などカンマ区切りで指定。何も
-# 指定しなければ利用可能なすべてのプロバイダが使用される
-#
-#
-#
-#
-# OutPort 側の connect() では以下のシーケンスで処理が行われる。
-#
-# 1. OutPort に関連する connector 情報の生成およびセット
-#
-# 2. InPortに関連する connector 情報の取得
-# - ConnectorProfile::properties["dataport.corba_any.inport_ref"]に
-# OutPortAny のオブジェクトリファレンスが設定されている場合、
-# リファレンスを取得してConsumerオブジェクトにセットする。
-# リファレンスがセットされていなければ無視して継続。
-# (OutPortがconnect() 呼び出しのエントリポイントの場合は、
-# InPortのオブジェクトリファレンスはセットされていないはずである。)
-# 3. PortBase::connect() をコール
-# Portの接続の基本処理が行われる。
-# 4. 上記2.でInPortのリファレンスが取得できなければ、再度InPortに
-# 関連する connector 情報を取得する。
-#
-# 5. ConnectorProfile::properties で与えられた情報から、
-# OutPort側の初期化処理を行う。
-#
-# - [dataport.interface_type]
-# -- CORBA_Any の場合:
-# InPortAny を通してデータ交換される。
-# ConnectorProfile::properties["dataport.corba_any.inport_ref"]に
-# InPortAny のオブジェクトリファレンスをセットする。
-# -- RawTCP の場合: Raw TCP socket を通してデータ交換される。
-# ConnectorProfile::properties["dataport.raw_tcp.server_addr"]
-# にInPort側のサーバアドレスをセットする。
-#
-# - [dataport.dataflow_type]
-# -- Pushの場合: Subscriberを生成する。Subscriberのタイプは、
-# dataport.subscription_type に設定されている。
-# -- Pullの場合: InPort側がデータをPull型で取得するため、
-# 特に何もする必要が無い。
-#
-# - [dataport.subscription_type]
-# -- Onceの場合: SubscriberOnceを生成する。
-# -- Newの場合: SubscriberNewを生成する。
-# -- Periodicの場合: SubscriberPeriodicを生成する。
-#
-# - [dataport.push_interval]
-# -- dataport.subscription_type=Periodicの場合周期を設定する。
-#
-# 6. 上記の処理のうち一つでもエラーであれば、エラーリターンする。
-# 正常に処理が行われた場合はRTC::RTC_OKでリターンする。
-#
-# @since 0.2.0
-#
-# @else
-#
-# @class OutPortBase
-#
-# @brief Output base class.
-#
-# The base class of OutPort<T> which are implementations of OutPort
-#
-# Form a kind of Observer pattern with OutPortBase and PublisherBase.
-# attach(), detach(), notify() of OutPortBase and
-# push() of PublisherBase are methods associated with the Observer pattern.
-#
-# @since 0.2.0
-#
-# @endif
-#
-class OutPortBase(OpenRTM_aist.PortBase,OpenRTM_aist.DataPortStatus):
- """
- """
-
- ##
- # @if jp
- # @brief Provider を削除するための Functor
- # @else
- # @brief Functor to delete Providers
- # @endif
- #
- class provider_cleanup:
- def __init__(self):
- self._factory = OpenRTM_aist.OutPortProviderFactory.instance()
-
- def __call__(self, p):
- self._factory.deleteObject(p)
-
- ##
- # @if jp
- # @brief Connector を削除するための Functor
- # @else
- # @brief Functor to delete Connectors
- # @endif
- #
- class connector_cleanup:
- def __init__(self):
- pass
-
- def __call__(self, c):
- del c
-
-
- ##
- # @if jp
- # @brief コンストラクタ
- #
- # コンストラクタ。
- #
- # @param self
- # @param name ポート名
- #
- # @else
- #
- # @brief A constructor of OutPortBase class.
- #
- # Constructor of OutPortBase.
- #
- # @endif
- # OutPortBase::OutPortBase(const char* name, const char* data_type)
- def __init__(self, name, data_type):
- OpenRTM_aist.PortBase.__init__(self,name)
- self._rtcout.RTC_DEBUG("Port name: %s", name)
-
- self._rtcout.RTC_DEBUG("setting port.port_type: DataOutPort")
- self.addProperty("port.port_type", "DataOutPort")
-
- self._rtcout.RTC_DEBUG("setting dataport.data_type: %s", data_type)
- self.addProperty("dataport.data_type", data_type)
-
- # publisher list
- factory = OpenRTM_aist.PublisherFactory.instance()
- pubs = OpenRTM_aist.flatten(factory.getIdentifiers())
-
- # blank characters are deleted for RTSE's bug
- pubs = pubs.lstrip()
-
- self._rtcout.RTC_DEBUG("available subscription_type: %s", pubs)
- self.addProperty("dataport.subscription_type", pubs)
-
- self._properties = OpenRTM_aist.Properties()
- self._name = name
- self._connectors = []
- self._consumers = []
- self._providerTypes = ""
- self._consumerTypes = ""
- self._connector_mutex = threading.RLock()
-
- self._listeners = OpenRTM_aist.ConnectorListeners()
- return
-
-
- ##
- # @if jp
- # @brief デストラクタ
- #
- # デストラクタ。
- # 登録された全ての Publisher を削除する。
- #
- # @param self
- #
- # @else
- #
- # @brief destructor
- #
- # Destructor
- #
- # @endif
- def __del__(self, PortBase=OpenRTM_aist.PortBase):
- self._rtcout.RTC_TRACE("OutPortBase destructor")
- # connector のクリーンナップ
- OpenRTM_aist.CORBA_SeqUtil.for_each(self._connectors,
- self.connector_cleanup())
- PortBase.__del__(self)
- return
-
-
- ##
- # @if jp
- # @brief プロパティの初期化
- #
- # OutPortのプロパティを初期化する
- #
- # @else
- #
- # @brief Initializing properties
- #
- # This operation initializes outport's properties
- #
- # @endif
- #
- # void init(coil::Properties& prop);
- def init(self, prop):
- self._rtcout.RTC_TRACE("init()")
-
- self._properties.mergeProperties(prop)
-
- self.configure()
-
- self.initConsumers()
- self.initProviders()
-
- num = [-1]
- if not OpenRTM_aist.stringTo(num, self._properties.getProperty("connection_limit","-1")):
- self._rtcout.RTC_ERROR("invalid connection_limit value: %s",
- self._properties.getProperty("connection_limit"))
-
- self.setConnectionLimit(num[0])
- return
-
- ##
- # @if jp
- #
- # @brief データ書き込み
- #
- # ポートへデータを書き込む。
- # バインドされた変数に設定された値をポートに書き込む。
- #
- # @return 書き込み処理結果(書き込み成功:true、書き込み失敗:false)
- #
- # @else
- #
- # @brief Write data
- #
- # Write data to the port.
- # Write the value, which was set to the bound variable, to the port.
- #
- # @return Writing result (Successful:true, Failed:false)
- #
- # @endif
- #
- # virtual bool write() = 0;
- def write(self):
- pass
-
-
- ##
- # @if jp
- #
- # @brief [CORBA interface] Port の接続を行う
- #
- # 与えられた ConnectoionProfile の情報に基づき、Port間の接続を確立
- # する。この関数は主にアプリケーションプログラムやツールから呼び出
- # すことを前提としている。
- #
- # @param connector_profile ConnectorProfile
- # @return ReturnCode_t 型のリターンコード
- #
- # @else
- #
- # @brief [CORBA interface] Connect the Port
- #
- # This operation establishes connection according to the given
- # ConnectionProfile inforamtion. This function is premised on
- # calling from mainly application program or tools.
- #
- # @param connector_profile The ConnectorProfile.
- # @return ReturnCode_t The return code of ReturnCode_t type.
- #
- # @endif
- #
- def connect(self, connector_profile):
- self._rtcout.RTC_TRACE("OutPortBase.connect()")
-
- if OpenRTM_aist.NVUtil.find_index(connector_profile.properties,
- "dataport.serializer.cdr.endian") is -1:
- self._rtcout.RTC_TRACE("ConnectorProfile dataport.serializer.cdr.endian set.")
- connector_profile.properties.append(OpenRTM_aist.NVUtil.newNV("dataport.serializer.cdr.endian","little,big"))
-
- return OpenRTM_aist.PortBase.connect(self, connector_profile)
-
-
- ##
- # @if jp
- # @brief プロパティを取得する
- #
- # OutPortのプロパティを取得する。
- #
- # @return プロパティ
- #
- # @else
- #
- # @brief Get properties
- #
- # Getting properties of this OutPort
- #
- # @return OutPort's properties
- #
- # @endif
- #
- # coil::Properties& OutPortBase::properties()
- def properties(self):
- self._rtcout.RTC_TRACE("properties()")
- return self._properties
-
-
- ##
- # @if jp
- # @brief Connector を取得
- # @else
- # @brief Connector list
- # @endif
- #
- # const std::vector<OutPortConnector*>& OutPortBase::connectors()
- def connectors(self):
- self._rtcout.RTC_TRACE("connectors(): size = %d", len(self._connectors))
- return self._connectors
-
-
- ##
- # @if jp
- # @brief ConnectorProfile を取得
- # @else
- # @brief ConnectorProfile list
- # @endif
- #
- # ConnectorBase::ConnectorInfoList OutPortBase::getConnectorProfiles()
- def getConnectorProfiles(self):
- self._rtcout.RTC_TRACE("getConnectorProfiles(): size = %d", len(self._connectors))
- profs = []
- for con in self._connectors:
- profs.append(con.profile())
-
- return profs
-
-
- ##
- # @if jp
- # @brief ConnectorId を取得
- # @else
- # @brief ConnectorId list
- # @endif
- #
- # coil::vstring OutPortBase::getConnectorIds()
- def getConnectorIds(self):
- ids = []
-
- for con in self._connectors:
- ids.append(con.id())
-
- self._rtcout.RTC_TRACE("getConnectorIds(): %s", OpenRTM_aist.flatten(ids))
- return ids
-
-
- ##
- # @if jp
- # @brief Connectorの名前を取得
- # @else
- # @brief Connector name list
- # @endif
- #
- # coil::vstring OutPortBase::getConnectorNames()
- def getConnectorNames(self):
- names = []
- for con in self._connectors:
- names.append(con.name())
-
- self._rtcout.RTC_TRACE("getConnectorNames(): %s", OpenRTM_aist.flatten(names))
- return names
-
-
- ##
- # @if jp
- # @brief ConnectorProfileをIDで取得
- #
- # 現在所有しているコネクタをIDで取得する。
- #
- # @param id Connector ID
- # @return コネクタへのポインタ
- #
- # @else
- #
- # @brief Getting ConnectorProfile by ID
- #
- # This operation returns Connector specified by ID.
- #
- # @param id Connector ID
- # @return A pointer to connector
- #
- # @endif
- #
- # OutPortConnector* getConnectorById(const char* id);
- def getConnectorById(self, id):
- self._rtcout.RTC_TRACE("getConnectorById(id = %s)", id)
-
- for (i,con) in enumerate(self._connectors):
- if id == con.id():
- return self._connectors[i]
-
- self._rtcout.RTC_WARN("ConnectorProfile with the id(%s) not found.", id)
- return 0
-
- ##
- # @if jp
- # @brief ConnectorProfileを名前で取得
- #
- # 現在所有しているコネクタを名前で取得する。
- #
- # @param name Connector name
- # @return コネクタへのポインタ
- #
- # @else
- #
- # @brief Getting Connector by name
- #
- # This operation returns Connector specified by name.
- #
- # @param id Connector ID
- # @return A pointer to connector
- #
- # @endif
- #
- # OutPortConnector* getConnectorByName(const char* name);
- def getConnectorByName(self, name):
- self._rtcout.RTC_TRACE("getConnectorByName(name = %s)", name)
-
- for (i,con) in enumerate(self._connectors):
- if name == con.name():
- return self._connectors[i]
-
- self._rtcout.RTC_WARN("ConnectorProfile with the name(%s) not found.", name)
- return 0
-
-
- ##
- # @if jp
- # @brief ConnectorProfileをIDで取得
- # @else
- # @brief Getting ConnectorProfile by name
- # @endif
- #
- # bool OutPortBase::getConnectorProfileById(const char* id,
- # ConnectorInfo& prof)
- def getConnectorProfileById(self, id, prof):
- self._rtcout.RTC_TRACE("getConnectorProfileById(id = %s)", id)
-
- conn = self.getConnectorById(id)
-
- if not conn:
- return False
-
- prof[0] = conn.profile()
- return True
-
-
- ##
- # @if jp
- # @brief ConnectorProfileを名前で取得
- # @else
- # @brief Getting ConnectorProfile by name
- # @endif
- #
- # bool OutPortBase::getConnectorProfileByName(const char* name,
- # ConnectorInfo& prof)
- def getConnectorProfileByName(self, name, prof):
- self._rtcout.RTC_TRACE("getConnectorProfileByName(name = %s)", name)
-
- conn = self.getConnectorByName(name)
-
- if not conn:
- return False
-
- prof[0] = conn.profile()
- return True
-
-
- ##
- # @if jp
- # @brief OutPortを activates する
- # @else
- # @brief Activate all Port interfaces
- # @endif
- #
- # void OutPortBase::activateInterfaces()
- def activateInterfaces(self):
- self._rtcout.RTC_TRACE("activateInterfaces()")
- for con in self._connectors:
- con.activate()
-
-
- ##
- # @if jp
- # @brief 全ての Port のインターフェースを deactivates する
- # @else
- # @brief Deactivate all Port interfaces
- # @endif
- #
- # void OutPortBase::deactivateInterfaces()
- def deactivateInterfaces(self):
- self._rtcout.RTC_TRACE("deactivateInterfaces()")
- for con in self._connectors:
- con.deactivate()
-
-
- ##
- # @if jp
- # @brief ConnectorDataListener リスナを追加する
- #
- # バッファ書き込みまたは読み出しイベントに関連する各種リスナを設定する。
- #
- # 設定できるリスナのタイプとコールバックイベントは以下の通り
- #
- # - ON_BUFFER_WRITE: バッファ書き込み時
- # - ON_BUFFER_FULL: バッファフル時
- # - ON_BUFFER_WRITE_TIMEOUT: バッファ書き込みタイムアウト時
- # - ON_BUFFER_OVERWRITE: バッファ上書き時
- # - ON_BUFFER_READ: バッファ読み出し時
- # - ON_SEND: InProtへの送信時
- # - ON_RECEIVED: InProtへの送信完了時
- # - ON_SEND_ERTIMEOUT: OutPort側タイムアウト時
- # - ON_SEND_ERERROR: OutPort側エラー時
- # - ON_RECEIVER_FULL: InProt側バッファフル時
- # - ON_RECEIVER_TIMEOUT: InProt側バッファタイムアウト時
- # - ON_RECEIVER_ERROR: InProt側エラー時
- #
- # リスナは ConnectorDataListener を継承し、以下のシグニチャを持つ
- # operator() を実装している必要がある。
- #
- # ConnectorDataListener::
- # operator()(const ConnectorProfile&, const cdrStream&)
- #
- # デフォルトでは、この関数に与えたリスナオブジェクトの所有権は
- # OutPortに移り、OutPort解体時もしくは、
- # removeConnectorDataListener() により削除時に自動的に解体される。
- # リスナオブジェクトの所有権を呼び出し側で維持したい場合は、第3引
- # 数に false を指定し、自動的な解体を抑制することができる。
- #
- # @param listener_type リスナタイプ
- # @param listener リスナオブジェクトへのポインタ
- # @param autoclean リスナオブジェクトの自動的解体を行うかどうかのフラグ
- #
- # @else
- # @brief Adding BufferDataListener type listener
- #
- # This operation adds certain listeners related to buffer writing and
- # reading events.
- # The following listener types are available.
- #
- # - ON_BUFFER_WRITE: At the time of buffer write
- # - ON_BUFFER_FULL: At the time of buffer full
- # - ON_BUFFER_WRITE_TIMEOUT: At the time of buffer write timeout
- # - ON_BUFFER_OVERWRITE: At the time of buffer overwrite
- # - ON_BUFFER_READ: At the time of buffer read
- # - ON_SEND: At the time of sending to InPort
- # - ON_RECEIVED: At the time of finishing sending to InPort
- # - ON_SENDER_TIMEOUT: At the time of timeout of OutPort
- # - ON_SENDER_ERROR: At the time of error of OutPort
- # - ON_RECEIVER_FULL: At the time of bufferfull of InPort
- # - ON_RECEIVER_TIMEOUT: At the time of timeout of InPort
- # - ON_RECEIVER_ERROR: At the time of error of InPort
- #
- # Listeners should have the following function operator().
- #
- # ConnectorDataListener::
- # operator()(const ConnectorProfile&, const cdrStream&)
- #
- # The ownership of the given listener object is transferred to
- # this OutPort object in default. The given listener object will
- # be destroied automatically in the OutPort's dtor or if the
- # listener is deleted by removeConnectorDataListener() function.
- # If you want to keep ownership of the listener object, give
- # "false" value to 3rd argument to inhibit automatic destruction.
- #
- # @param listener_type A listener type
- # @param listener A pointer to a listener object
- # @param autoclean A flag for automatic listener destruction
- #
- # @endif
- #
- # void addConnectorDataListener(ConnectorDataListenerType listener_type,
- # ConnectorDataListener* listener,
- # bool autoclean = true);
- def addConnectorDataListener(self, listener_type, listener, autoclean = True):
- self._rtcout.RTC_TRACE("addConnectorDataListener()")
- if listener_type < OpenRTM_aist.ConnectorDataListenerType.CONNECTOR_DATA_LISTENER_NUM:
- self._rtcout.RTC_TRACE("addConnectorDataListener(%s)",
- OpenRTM_aist.ConnectorDataListener.toString(listener_type))
- self._listeners.connectorData_[listener_type].addListener(listener, autoclean)
- return
-
- self._rtcout.RTC_ERROR("addConnectorDataListener(): Unknown Listener Type")
- return
-
-
- ##
- # @if jp
- # @brief ConnectorDataListener リスナを削除する
- #
- # 設定した各種リスナを削除する。
- #
- # @param listener_type リスナタイプ
- # @param listener リスナオブジェクトへのポインタ
- #
- # @else
- # @brief Removing BufferDataListener type listener
- #
- # This operation removes a specified listener.
- #
- # @param listener_type A listener type
- # @param listener A pointer to a listener object
- #
- # @endif
- #
- # void removeConnectorDataListener(ConnectorDataListenerType listener_type,
- # ConnectorDataListener* listener);
- def removeConnectorDataListener(self, listener_type, listener):
- self._rtcout.RTC_TRACE("removeConnectorDataListener()")
-
- if listener_type < OpenRTM_aist.ConnectorDataListenerType.CONNECTOR_DATA_LISTENER_NUM:
- self._rtcout.RTC_TRACE("removeConnectorDataListener(%s)",
- OpenRTM_aist.ConnectorDataListener.toString(listener_type))
- self._listeners.connectorData_[listener_type].removeListener(listener)
- return
-
- self._rtcout.RTC_ERROR("removeConnectorDataListener(): Unknown Listener Type")
- return
-
-
- ##
- # @if jp
- # @brief ConnectorListener リスナを追加する
- #
- # バッファ書き込みまたは読み出しイベントに関連する各種リスナを設定する。
- #
- # 設定できるリスナのタイプは
- #
- # - ON_BUFFER_EMPTY: バッファが空の場合
- # - ON_BUFFER_READTIMEOUT: バッファが空でタイムアウトした場合
- #
- # リスナは以下のシグニチャを持つ operator() を実装している必要がある。
- #
- # ConnectorListener::operator()(const ConnectorProfile&)
- #
- # デフォルトでは、この関数に与えたリスナオブジェクトの所有権は
- # OutPortに移り、OutPort解体時もしくは、
- # removeConnectorListener() により削除時に自動的に解体される。
- # リスナオブジェクトの所有権を呼び出し側で維持したい場合は、第3引
- # 数に false を指定し、自動的な解体を抑制することができる。
- #
- # @param listener_type リスナタイプ
- # @param listener リスナオブジェクトへのポインタ
- # @param autoclean リスナオブジェクトの自動的解体を行うかどうかのフラグ
- #
- # @else
- # @brief Adding ConnectorListener type listener
- #
- # This operation adds certain listeners related to buffer writing and
- # reading events.
- # The following listener types are available.
- #
- # - ON_BUFFER_EMPTY: At the time of buffer empty
- # - ON_BUFFER_READTIMEOUT: At the time of buffer read timeout
- #
- # Listeners should have the following function operator().
- #
- # ConnectorListener::operator()(const ConnectorProfile&)
- #
- # The ownership of the given listener object is transferred to
- # this OutPort object in default. The given listener object will
- # be destroied automatically in the OutPort's dtor or if the
- # listener is deleted by removeConnectorListener() function.
- # If you want to keep ownership of the listener object, give
- # "false" value to 3rd argument to inhibit automatic destruction.
- #
- # @param listener_type A listener type
- # @param listener A pointer to a listener object
- # @param autoclean A flag for automatic listener destruction
- #
- # @endif
- #
- # void addConnectorListener(ConnectorListenerType callback_type,
- # ConnectorListener* listener,
- # bool autoclean = true);
- def addConnectorListener(self, callback_type, listener, autoclean = True):
- self._rtcout.RTC_TRACE("addConnectorListener()")
-
- if callback_type < OpenRTM_aist.ConnectorListenerType.CONNECTOR_LISTENER_NUM:
- self._rtcout.RTC_TRACE("addConnectorListener(%s)",
- OpenRTM_aist.ConnectorListener.toString(callback_type))
- self._listeners.connector_[callback_type].addListener(listener, autoclean)
- return
- self._rtcout.RTC_ERROR("addConnectorListener(): Unknown Listener Type")
- return
-
-
- ##
- # @if jp
- # @brief ConnectorDataListener リスナを削除する
- #
- # 設定した各種リスナを削除する。
- #
- # @param listener_type リスナタイプ
- # @param listener リスナオブジェクトへのポインタ
- #
- # @else
- # @brief Removing BufferDataListener type listener
- #
- # This operation removes a specified listener.
- #
- # @param listener_type A listener type
- # @param listener A pointer to a listener object
- #
- # @endif
- #
- # void removeConnectorListener(ConnectorListenerType callback_type,
- # ConnectorListener* listener);
- def removeConnectorListener(self, callback_type, listener):
- self._rtcout.RTC_TRACE("removeConnectorListener()")
-
- if callback_type < OpenRTM_aist.ConnectorListenerType.CONNECTOR_LISTENER_NUM:
- self._rtcout.RTC_TRACE("removeConnectorListener(%s)",
- OpenRTM_aist.ConnectorListener.toString(callback_type))
- self._listeners.connector_[callback_type].removeListener(listener)
- return
- self._rtcout.RTC_ERROR("removeConnectorListener(): Unknown Listener Type")
- return
-
-
- ##
- # @if jp
- # @brief OutPortの設定を行う
- # @else
- # @brief Configureing outport
- # @endif
- #
- #void OutPortBase::configure()
- def configure(self):
- pass
-
-
- ##
- # @if jp
- # @brief Interface情報を公開する
- # @else
- # @brief Publish interface information
- # @endif
- #
- # ReturnCode_t OutPortBase::publishInterfaces(ConnectorProfile& cprof)
- def publishInterfaces(self, cprof):
- self._rtcout.RTC_TRACE("publishInterfaces()")
-
- retval = self._publishInterfaces()
- if retval != RTC.RTC_OK:
- return retval
-
- # prop: [port.outport].
- prop = copy.deepcopy(self._properties)
-
- conn_prop = OpenRTM_aist.Properties()
-
- OpenRTM_aist.NVUtil.copyToProperties(conn_prop, cprof.properties)
- prop.mergeProperties(conn_prop.getNode("dataport")) # marge ConnectorProfile
-
- """
- # marge ConnectorProfile for buffer property.
- # e.g.
- # prof[buffer.write.full_policy]
- # << cprof[dataport.outport.buffer.write.full_policy]
- #
- """
- prop.mergeProperties(conn_prop.getNode("dataport.outport"))
-
-
- #
- # ここで, ConnectorProfile からの properties がマージされたため、
- # prop["dataflow_type"]: データフロータイプ
- # prop["interface_type"]: インターフェースタイプ
- # などがアクセス可能になる。
- dflow_type = OpenRTM_aist.normalize([prop.getProperty("dataflow_type")])
-
- if dflow_type == "push":
- self._rtcout.RTC_PARANOID("dataflow_type = push .... do nothing")
- return RTC.RTC_OK
-
- elif dflow_type == "pull":
- self._rtcout.RTC_PARANOID("dataflow_type = pull .... create PullConnector")
-
- provider = self.createProvider(cprof, prop)
- if not provider:
- return RTC.BAD_PARAMETER
-
- # create InPortPushConnector
- connector = self.createConnector(cprof, prop, provider_ = provider)
- if not connector:
- return RTC.RTC_ERROR
-
- # connector set
- provider.setConnector(connector)
-
- self._rtcout.RTC_DEBUG("publishInterface() successfully finished.")
- return RTC.RTC_OK
-
- self._rtcout.RTC_ERROR("unsupported dataflow_type")
-
- return RTC.BAD_PARAMETER
-
-
- ##
- # @if jp
- # @brief Interface情報を取得する
- # @else
- # @brief Subscribe interface
- # @endif
- #
- # ReturnCode_t OutPortBase::subscribeInterfaces(const ConnectorProfile& cprof)
- def subscribeInterfaces(self, cprof):
- self._rtcout.RTC_TRACE("subscribeInterfaces()")
-
- # prop: [port.outport].
- prop = copy.deepcopy(self._properties)
-
- conn_prop = OpenRTM_aist.Properties()
- OpenRTM_aist.NVUtil.copyToProperties(conn_prop, cprof.properties)
- prop.mergeProperties(conn_prop.getNode("dataport")) # marge ConnectorProfile
- """
- # marge ConnectorProfile for buffer property.
- # e.g.
- # prof[buffer.write.full_policy]
- # << cprof[dataport.outport.buffer.write.full_policy]
- """
- prop.mergeProperties(conn_prop.getNode("dataport.outport"))
-
- #
- # ここで, ConnectorProfile からの properties がマージされたため、
- # prop["dataflow_type"]: データフロータイプ
- # prop["interface_type"]: インターフェースタイプ
- # などがアクセス可能になる。
- #
- dflow_type = OpenRTM_aist.normalize([prop.getProperty("dataflow_type")])
-
- profile = OpenRTM_aist.ConnectorInfo(cprof.name,
- cprof.connector_id,
- OpenRTM_aist.CORBA_SeqUtil.refToVstring(cprof.ports),
- prop)
- if dflow_type == "push":
- self._rtcout.RTC_PARANOID("dataflow_type = push .... create PushConnector")
-
- # interface
- consumer = self.createConsumer(cprof, prop)
- if not consumer:
- return RTC.BAD_PARAMETER
-
- # create OutPortPushConnector
- connector = self.createConnector(cprof, prop, consumer_ = consumer)
- if not connector:
- return RTC.RTC_ERROR
-
- ret = connector.setConnectorInfo(profile)
-
- if ret == RTC.RTC_OK:
- self._rtcout.RTC_DEBUG("subscribeInterfaces() successfully finished.")
-
- return ret
-
- elif dflow_type == "pull":
- self._rtcout.RTC_PARANOID("dataflow_type = pull.")
-
- conn = self.getConnectorById(cprof.connector_id)
- if not conn:
- self._rtcout.RTC_ERROR("specified connector not found: %s",
- cprof.connector_id)
- return RTC.RTC_ERROR
-
- ret = conn.setConnectorInfo(profile)
-
- if ret == RTC.RTC_OK:
- self._rtcout.RTC_DEBUG("subscribeInterfaces() successfully finished.")
-
- return ret
-
- self._rtcout.RTC_ERROR("unsupported dataflow_type")
- return RTC.BAD_PARAMETER
-
-
- ##
- # @if jp
- # @brief 登録されているInterface情報を解除する
- # @else
- # @brief Unsubscribe interface
- # @endif
- #
- # void
- # OutPortBase::unsubscribeInterfaces(const ConnectorProfile& connector_profile)
- def unsubscribeInterfaces(self, connector_profile):
- self._rtcout.RTC_TRACE("unsubscribeInterfaces()")
-
- id = connector_profile.connector_id
- self._rtcout.RTC_PARANOID("connector_id: %s", id)
-
- len_ = len(self._connectors)
- for i in range(len_):
- idx = (len_ - 1) - i
- if id == self._connectors[idx].id():
- # Connector's dtor must call disconnect()
- self._connectors[idx].deactivate()
- self._connectors[idx].disconnect()
- del self._connectors[idx]
- self._rtcout.RTC_TRACE("delete connector: %s", id)
- return
-
- self._rtcout.RTC_ERROR("specified connector not found: %s", id)
- return
-
-
- ##
- # @if jp
- # @brief OutPort provider の初期化
- # @else
- # @brief OutPort provider initialization
- # @endif
- #
- # void OutPortBase::initProviders()
- def initProviders(self):
- self._rtcout.RTC_TRACE("initProviders()")
-
- # create OutPort providers
- factory = OpenRTM_aist.OutPortProviderFactory.instance()
- provider_types = factory.getIdentifiers()
- self._rtcout.RTC_PARANOID("available OutPortProviders: %s",
- OpenRTM_aist.flatten(provider_types))
-
- if self._properties.hasKey("provider_types") and \
- OpenRTM_aist.normalize(self._properties.getProperty("provider_types")) != "all":
- self._rtcout.RTC_DEBUG("allowed providers: %s",
- self._properties.getProperty("provider_types"))
-
- temp_types = provider_types
- provider_types = []
- active_types = OpenRTM_aist.split(self._properties.getProperty("provider_types"), ",")
-
- temp_types.sort()
- active_types.sort()
-
- set_ptypes = set(temp_types).intersection(set(active_types))
- provider_types = provider_types + list(set_ptypes)
-
- # OutPortProvider supports "pull" dataflow type
- if len(provider_types) > 0:
- self._rtcout.RTC_DEBUG("dataflow_type pull is supported")
- self.appendProperty("dataport.dataflow_type", "pull")
- for provider_type in provider_types:
- self.appendProperty("dataport.interface_type",provider_type)
-
- self._providerTypes = provider_types
-
-
- ##
- # @if jp
- # @brief InPort consumer の初期化
- # @else
- # @brief InPort consumer initialization
- # @endif
- #
- # void OutPortBase::initConsumers()
- def initConsumers(self):
- self._rtcout.RTC_TRACE("initConsumers()")
-
- # create InPort consumers
- factory = OpenRTM_aist.InPortConsumerFactory.instance()
- consumer_types = factory.getIdentifiers()
- self._rtcout.RTC_PARANOID("available InPortConsumer: %s",
- OpenRTM_aist.flatten(consumer_types))
-
- if self._properties.hasKey("consumer_types") and \
- OpenRTM_aist.normalize(self._properties.getProperty("consumer_types")) != "all":
- self._rtcout.RTC_DEBUG("allowed consumers: %s",
- self._properties.getProperty("consumer_types"))
-
- temp_types = consumer_types
- consumer_types = []
- active_types = OpenRTM_aist.split(self._properties.getProperty("consumer_types"), ",")
-
- temp_types.sort()
- active_types.sort()
-
- set_ctypes = set(temp_types).intersection(set(active_types))
- consumer_types = consumer_types + list(set_ctypes)
-
- # InPortConsumer supports "push" dataflow type
- if len(consumer_types) > 0:
- self._rtcout.RTC_PARANOID("dataflow_type push is supported")
- self.appendProperty("dataport.dataflow_type", "push")
- for consumer_type in consumer_types:
- self.appendProperty("dataport.interface_type",consumer_type)
-
- self._consumerTypes = consumer_types
-
-
- ##
- # @if jp
- # @brief OutPort provider の生成
- # @else
- # @brief OutPort provider creation
- # @endif
- #
- # OutPortProvider*
- # OutPortBase::createProvider(ConnectorProfile& cprof, coil::Properties& prop)
- def createProvider(self, cprof, prop):
- if prop.getProperty("interface_type") and \
- not OpenRTM_aist.includes(self._providerTypes, prop.getProperty("interface_type")):
- self._rtcout.RTC_ERROR("no provider found")
- self._rtcout.RTC_DEBUG("interface_type: %s", prop.getProperty("interface_type"))
- self._rtcout.RTC_DEBUG("interface_types: %s",
- OpenRTM_aist.flatten(self._providerTypes))
- return 0
-
- self._rtcout.RTC_DEBUG("interface_type: %s", prop.getProperty("interface_type"))
- provider = OpenRTM_aist.OutPortProviderFactory.instance().createObject(prop.getProperty("interface_type"))
-
- if provider != 0:
- self._rtcout.RTC_DEBUG("provider created")
- provider.init(prop.getNode("provider"))
-
- if not provider.publishInterface(cprof.properties):
- self._rtcout.RTC_ERROR("publishing interface information error")
- OpenRTM_aist.OutPortProviderFactory.instance().deleteObject(provider)
- return 0
-
- return provider
-
- self._rtcout.RTC_ERROR("provider creation failed")
- return 0
-
-
- ##
- # @if jp
- # @brief InPort consumer の生成
- # @else
- # @brief InPort consumer creation
- # @endif
- #
- # InPortConsumer* OutPortBase::createConsumer(const ConnectorProfile& cprof,
- # coil::Properties& prop)
- def createConsumer(self, cprof, prop):
- if prop.getProperty("interface_type") and \
- not self._consumerTypes.count(prop.getProperty("interface_type")):
- self._rtcout.RTC_ERROR("no consumer found")
- self._rtcout.RTC_DEBUG("interface_type: %s", prop.getProperty("interface_type"))
- self._rtcout.RTC_DEBUG("interface_types: %s",
- OpenRTM_aist.flatten(self._consumerTypes))
- return 0
-
- self._rtcout.RTC_DEBUG("interface_type: %s", prop.getProperty("interface_type"))
- consumer = OpenRTM_aist.InPortConsumerFactory.instance().createObject(prop.getProperty("interface_type"))
-
- if consumer != 0:
- self._rtcout.RTC_DEBUG("consumer created")
-
- consumer.init(prop.getNode("consumer"))
-
- if not consumer.subscribeInterface(cprof.properties):
- self._rtcout.RTC_ERROR("interface subscription failed.")
- OpenRTM_aist.InPortConsumerFactory.instance().deleteObject(consumer)
- return 0
-
- return consumer
-
- self._rtcout.RTC_ERROR("consumer creation failed")
- return 0
-
-
- ##
- # @if jp
- # @brief OutPortPushConnector の生成
- # @else
- # @brief OutPortPushConnector creation
- # @endif
- #
- # OutPortConnector*
- # OutPortBase::createConnector(const ConnectorProfile& cprof,
- # coil::Properties& prop,
- # InPortConsumer* consumer)
- def createConnector(self, cprof, prop, provider_ = None, consumer_ = None):
- profile = OpenRTM_aist.ConnectorInfo(cprof.name,
- cprof.connector_id,
- OpenRTM_aist.CORBA_SeqUtil.refToVstring(cprof.ports),
- prop)
-
- connector = None
- try:
-
- if consumer_ is not None:
- connector = OpenRTM_aist.OutPortPushConnector(profile, consumer_, self._listeners)
- elif provider_ is not None:
- connector = OpenRTM_aist.OutPortPullConnector(profile, provider_, self._listeners)
-
- else:
- self._rtcout.RTC_ERROR("provider or consumer is not passed. returned 0;")
- return 0
-
- if connector is None:
- self._rtcout.RTC_ERROR("OutPortConnector creation failed")
- return 0
-
- if consumer_ is not None:
- self._rtcout.RTC_TRACE("OutPortPushConnector created")
- elif provider_ is not None:
- self._rtcout.RTC_TRACE("OutPortPullConnector created")
-
- #interface_type = str(prop.getNode("interface_type")).replace(":","")
- #interface_type = OpenRTM_aist.StringUtil.normalize([interface_type])
-
- if OpenRTM_aist.StringUtil.normalize([prop.getProperty("interface_type")]) == "direct":
-
- inport = self.getLocalInPort(profile)
-
- if inport is None:
- self._rtcout.RTC_TRACE("interface_type is direct, ")
- self._rtcout.RTC_TRACE("but a peer InPort servant could not be obtained.")
- del connector
- return 0
-
- connector.setInPort(inport)
-
-
- self._connectors.append(connector)
- self._rtcout.RTC_PARANOID("connector push backed: %d", len(self._connectors))
- return connector
-
- except:
- self._rtcout.RTC_ERROR("Exeption: OutPortPushConnector creation failed")
- self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
- return 0
-
-
- self._rtcout.RTC_FATAL("never comes here: createConnector()")
- return 0
-
-
- ##
- # @if jp
- # @brief ローカルのピアInPortを取得
- # @param self
- # @param profile コネクタプロファイル
- # @return InPortのサーバント(取得に失敗した場合はNone)
- # @else
- # @brief Getting local peer InPort if available
- # @param self
- # @param profile
- # @return
- # @endif
- #
- # InPortBase*
- # getLocalInPort(const ConnectorInfo& profile)
- def getLocalInPort(self, profile):
- self._rtcout.RTC_DEBUG("Trying direct port connection.")
- orb = OpenRTM_aist.Manager.instance().getORB()
- self._rtcout.RTC_DEBUG("Current connector profile: name=%s, id=%s" % (profile.name, profile.id))
- for p in profile.ports:
- obj = orb.string_to_object(p)
- if self.getPortRef()._is_equivalent(obj):
- continue
- self._rtcout.RTC_DEBUG("Peer port found: %s." % p)
- try:
- poa = OpenRTM_aist.Manager.instance().getPOA()
- inport = poa.reference_to_servant(obj)
- self._rtcout.RTC_DEBUG("InPortBase servant pointer is obtained.")
- return inport
- except:
- self._rtcout.RTC_DEBUG("Peer port might be a remote port")
- return None
\ No newline at end of file
+#!/usr/bin/env python
+# -*- coding: euc-jp -*-
+
+##
+# @file OutPortBase.py
+# @brief OutPortBase base class
+# @date $Date: 2007/09/19 $
+# @author Noriaki Ando <n-ando at aist.go.jp> and Shinji Kurihara
+#
+# Copyright (C) 2003-2008
+# Task-intelligence Research Group,
+# Intelligent Systems Research Institute,
+# National Institute of
+# Advanced Industrial Science and Technology (AIST), Japan
+# All rights reserved.
+
+import copy
+import threading
+import OpenRTM_aist
+import RTC
+
+##
+# @if jp
+#
+# @class OutPortBase
+#
+# @brief OutPort 基底クラス
+#
+# OutPort の基底クラス。
+#
+#
+#
+# Properties: port.outport
+# プロパティは
+#
+# - port.outport
+# - port.outport.[name]
+# ConnectorProfile.properties の場合は
+# - dataport.outport
+#
+# 以下に指定したものが渡される。
+# (port.outport.[name]が優先される)
+# さらに、一部のプロパティは接続時に ConnectorProfile により
+# 渡される場合があり、その場合は ConnectorProfile が優先される。
+#
+# - input.throughput.profile: enable
+# - input.throughput.update_rate: count [n/count]
+# - input.throughput.total_bytes: [bytes]
+# - input.throughput.total_count: [n]
+# - input.throughput.max_size: [bytes]
+# - input.throughput.min_size: [bytes]
+# - input.throughput.avg_size: [bytes]
+# - input.throughput.byte_sec: [bytes/sec]
+#
+# - output.throughput.profile: enable
+# - output.throughput.update_rate: count [n/count]
+# - output.throughput.total_bytes: [bytes]
+# - output.throughput.total_count:[n]
+# - output.throughput.max_size: [bytes]
+# - output.throughput.min_size: [bytes]
+# - output.throughput.avg_size: [bytes]
+# - output.throughput.max_sendtime: [sec]
+# - output.throughput.min_sendtime: [sec]
+# - output.throughput.avg_sendtime: [sec]
+# - output.throughput.byte_sec: [bytes/sec]
+#
+# dataport.dataflow_type
+# dataport.interface_type
+# dataport.subscription_type
+#
+# [buffer]
+#
+# - buffer.type:
+# 利用可能なバッファのタイプ
+# ConnectorProfile の場合は利用するバッファのタイプ
+# 無指定の場合はデフォルトの ringbuffer が使用される。
+# ex. ringbuffer, shmbuffer, doublebuffer, etc.
+# 正し、Consumer, Publisher のタイプによっては特定のバッファ型を
+# 要求するがあるための、その場合は指定は無効となる。
+#
+# - buffer.length:
+# バッファの長さ
+#
+# - buffer.write.full_policy:
+# 上書きするかどうかのポリシー
+# overwrite (上書き), do_nothing (何もしない), block (ブロックする)
+# block を指定した場合、次の timeout 値を指定すれば、指定時間後
+# 書き込み不可能であればタイムアウトする。
+#
+# - buffer.write.timeout:
+# タイムアウト時間を [sec] で指定する。
+# 1 sec -> 1.0, 1 ms -> 0.001, タイムアウトしない -> 0.0
+#
+# - buffer.read.empty_policy:
+# バッファが空のときの読み出しポリシー
+# last (最後の要素), do_nothing (何もしない), block (ブロックする)
+# block を指定した場合、次の timeout 値を指定すれば、指定時間後
+# 読み出し不可能であればタイムアウトする。
+#
+# - buffer.read.timeout:
+# タイムアウト時間 [sec] で指定する。
+# 1sec -> 1.0, 1ms -> 0.001, タイムアウトしない -> 0.0
+#
+# - その他バッファ毎に固有なオプション
+#
+#
+# [publihser]
+#
+# - publisher.types:
+# 利用可能な Publisher のタイプ
+# new, periodic, flush, etc..
+#
+# - publisher.push.policy:
+# InPortへデータを送信するポリシー
+# all: バッファにたまっているすべて送信
+# fifo: バッファをFIFOとみなして送信
+# skip: 古いデータから一定数を間引いて送信
+# new: 常に新しいデータのみを送信
+#
+# - publisher.push.skip_rate:
+# push.policy=skip のときのスキップ率
+# n: n要素毎にひとつ送信
+#
+# - publisher.periodic.rate:
+#
+# - publisher.thread.type:
+# Publisher のスレッドのタイプ
+# - publisher.thread.measurement.exec_time: yes/no
+# - publisher.thread.measurement.exec_count: number
+# - publisher.thread.measurement.period_time: yes/no
+# - publisher.thread.measurement.period_count: number
+#
+# [interface]
+#
+# - interface.types:
+# OutPort interfaceのタイプ
+# ex. corba_cdr, corba_any, raw_tcp などカンマ区切りで指定。何も
+# 指定しなければ利用可能なすべてのプロバイダが使用される
+#
+#
+#
+#
+# OutPort 側の connect() では以下のシーケンスで処理が行われる。
+#
+# 1. OutPort に関連する connector 情報の生成およびセット
+#
+# 2. InPortに関連する connector 情報の取得
+# - ConnectorProfile::properties["dataport.corba_any.inport_ref"]に
+# OutPortAny のオブジェクトリファレンスが設定されている場合、
+# リファレンスを取得してConsumerオブジェクトにセットする。
+# リファレンスがセットされていなければ無視して継続。
+# (OutPortがconnect() 呼び出しのエントリポイントの場合は、
+# InPortのオブジェクトリファレンスはセットされていないはずである。)
+# 3. PortBase::connect() をコール
+# Portの接続の基本処理が行われる。
+# 4. 上記2.でInPortのリファレンスが取得できなければ、再度InPortに
+# 関連する connector 情報を取得する。
+#
+# 5. ConnectorProfile::properties で与えられた情報から、
+# OutPort側の初期化処理を行う。
+#
+# - [dataport.interface_type]
+# -- CORBA_Any の場合:
+# InPortAny を通してデータ交換される。
+# ConnectorProfile::properties["dataport.corba_any.inport_ref"]に
+# InPortAny のオブジェクトリファレンスをセットする。
+# -- RawTCP の場合: Raw TCP socket を通してデータ交換される。
+# ConnectorProfile::properties["dataport.raw_tcp.server_addr"]
+# にInPort側のサーバアドレスをセットする。
+#
+# - [dataport.dataflow_type]
+# -- Pushの場合: Subscriberを生成する。Subscriberのタイプは、
+# dataport.subscription_type に設定されている。
+# -- Pullの場合: InPort側がデータをPull型で取得するため、
+# 特に何もする必要が無い。
+#
+# - [dataport.subscription_type]
+# -- Onceの場合: SubscriberOnceを生成する。
+# -- Newの場合: SubscriberNewを生成する。
+# -- Periodicの場合: SubscriberPeriodicを生成する。
+#
+# - [dataport.push_interval]
+# -- dataport.subscription_type=Periodicの場合周期を設定する。
+#
+# 6. 上記の処理のうち一つでもエラーであれば、エラーリターンする。
+# 正常に処理が行われた場合はRTC::RTC_OKでリターンする。
+#
+# @since 0.2.0
+#
+# @else
+#
+# @class OutPortBase
+#
+# @brief Output base class.
+#
+# The base class of OutPort<T> which are implementations of OutPort
+#
+# Form a kind of Observer pattern with OutPortBase and PublisherBase.
+# attach(), detach(), notify() of OutPortBase and
+# push() of PublisherBase are methods associated with the Observer pattern.
+#
+# @since 0.2.0
+#
+# @endif
+#
+class OutPortBase(OpenRTM_aist.PortBase,OpenRTM_aist.DataPortStatus):
+ """
+ """
+
+ ##
+ # @if jp
+ # @brief Provider を削除するための Functor
+ # @else
+ # @brief Functor to delete Providers
+ # @endif
+ #
+ class provider_cleanup:
+ def __init__(self):
+ self._factory = OpenRTM_aist.OutPortProviderFactory.instance()
+
+ def __call__(self, p):
+ self._factory.deleteObject(p)
+
+ ##
+ # @if jp
+ # @brief Connector を削除するための Functor
+ # @else
+ # @brief Functor to delete Connectors
+ # @endif
+ #
+ class connector_cleanup:
+ def __init__(self):
+ pass
+
+ def __call__(self, c):
+ del c
+
+
+ ##
+ # @if jp
+ # @brief コンストラクタ
+ #
+ # コンストラクタ。
+ #
+ # @param self
+ # @param name ポート名
+ #
+ # @else
+ #
+ # @brief A constructor of OutPortBase class.
+ #
+ # Constructor of OutPortBase.
+ #
+ # @endif
+ # OutPortBase::OutPortBase(const char* name, const char* data_type)
+ def __init__(self, name, data_type):
+ OpenRTM_aist.PortBase.__init__(self,name)
+ self._rtcout.RTC_DEBUG("Port name: %s", name)
+
+ self._rtcout.RTC_DEBUG("setting port.port_type: DataOutPort")
+ self.addProperty("port.port_type", "DataOutPort")
+
+ self._rtcout.RTC_DEBUG("setting dataport.data_type: %s", data_type)
+ self.addProperty("dataport.data_type", data_type)
+
+ # publisher list
+ factory = OpenRTM_aist.PublisherFactory.instance()
+ pubs = OpenRTM_aist.flatten(factory.getIdentifiers())
+
+ # blank characters are deleted for RTSE's bug
+ pubs = pubs.lstrip()
+
+ self._rtcout.RTC_DEBUG("available subscription_type: %s", pubs)
+ self.addProperty("dataport.subscription_type", pubs)
+
+ self._properties = OpenRTM_aist.Properties()
+ self._name = name
+ self._connectors = []
+ self._consumers = []
+ self._providerTypes = ""
+ self._consumerTypes = ""
+ self._connector_mutex = threading.RLock()
+
+ self._listeners = OpenRTM_aist.ConnectorListeners()
+ return
+
+
+ ##
+ # @if jp
+ # @brief デストラクタ
+ #
+ # デストラクタ。
+ # 登録された全ての Publisher を削除する。
+ #
+ # @param self
+ #
+ # @else
+ #
+ # @brief destructor
+ #
+ # Destructor
+ #
+ # @endif
+ def __del__(self, PortBase=OpenRTM_aist.PortBase):
+ self._rtcout.RTC_TRACE("OutPortBase destructor")
+ # connector のクリーンナップ
+ OpenRTM_aist.CORBA_SeqUtil.for_each(self._connectors,
+ self.connector_cleanup())
+ PortBase.__del__(self)
+ return
+
+
+ ##
+ # @if jp
+ # @brief プロパティの初期化
+ #
+ # OutPortのプロパティを初期化する
+ #
+ # @else
+ #
+ # @brief Initializing properties
+ #
+ # This operation initializes outport's properties
+ #
+ # @endif
+ #
+ # void init(coil::Properties& prop);
+ def init(self, prop):
+ self._rtcout.RTC_TRACE("init()")
+
+ self._properties.mergeProperties(prop)
+
+ self.configure()
+
+ self.initConsumers()
+ self.initProviders()
+
+ num = [-1]
+ if not OpenRTM_aist.stringTo(num, self._properties.getProperty("connection_limit","-1")):
+ self._rtcout.RTC_ERROR("invalid connection_limit value: %s",
+ self._properties.getProperty("connection_limit"))
+
+ self.setConnectionLimit(num[0])
+ return
+
+ ##
+ # @if jp
+ #
+ # @brief データ書き込み
+ #
+ # ポートへデータを書き込む。
+ # バインドされた変数に設定された値をポートに書き込む。
+ #
+ # @return 書き込み処理結果(書き込み成功:true、書き込み失敗:false)
+ #
+ # @else
+ #
+ # @brief Write data
+ #
+ # Write data to the port.
+ # Write the value, which was set to the bound variable, to the port.
+ #
+ # @return Writing result (Successful:true, Failed:false)
+ #
+ # @endif
+ #
+ # virtual bool write() = 0;
+ def write(self):
+ pass
+
+
+ ##
+ # @if jp
+ #
+ # @brief [CORBA interface] Port の接続を行う
+ #
+ # 与えられた ConnectoionProfile の情報に基づき、Port間の接続を確立
+ # する。この関数は主にアプリケーションプログラムやツールから呼び出
+ # すことを前提としている。
+ #
+ # @param connector_profile ConnectorProfile
+ # @return ReturnCode_t 型のリターンコード
+ #
+ # @else
+ #
+ # @brief [CORBA interface] Connect the Port
+ #
+ # This operation establishes connection according to the given
+ # ConnectionProfile inforamtion. This function is premised on
+ # calling from mainly application program or tools.
+ #
+ # @param connector_profile The ConnectorProfile.
+ # @return ReturnCode_t The return code of ReturnCode_t type.
+ #
+ # @endif
+ #
+ def connect(self, connector_profile):
+ self._rtcout.RTC_TRACE("OutPortBase.connect()")
+
+ if OpenRTM_aist.NVUtil.find_index(connector_profile.properties,
+ "dataport.serializer.cdr.endian") is -1:
+ self._rtcout.RTC_TRACE("ConnectorProfile dataport.serializer.cdr.endian set.")
+ connector_profile.properties.append(OpenRTM_aist.NVUtil.newNV("dataport.serializer.cdr.endian","little,big"))
+
+ return OpenRTM_aist.PortBase.connect(self, connector_profile)
+
+
+ ##
+ # @if jp
+ # @brief プロパティを取得する
+ #
+ # OutPortのプロパティを取得する。
+ #
+ # @return プロパティ
+ #
+ # @else
+ #
+ # @brief Get properties
+ #
+ # Getting properties of this OutPort
+ #
+ # @return OutPort's properties
+ #
+ # @endif
+ #
+ # coil::Properties& OutPortBase::properties()
+ def properties(self):
+ self._rtcout.RTC_TRACE("properties()")
+ return self._properties
+
+
+ ##
+ # @if jp
+ # @brief Connector を取得
+ # @else
+ # @brief Connector list
+ # @endif
+ #
+ # const std::vector<OutPortConnector*>& OutPortBase::connectors()
+ def connectors(self):
+ self._rtcout.RTC_TRACE("connectors(): size = %d", len(self._connectors))
+ return self._connectors
+
+
+ ##
+ # @if jp
+ # @brief ConnectorProfile を取得
+ # @else
+ # @brief ConnectorProfile list
+ # @endif
+ #
+ # ConnectorBase::ConnectorInfoList OutPortBase::getConnectorProfiles()
+ def getConnectorProfiles(self):
+ self._rtcout.RTC_TRACE("getConnectorProfiles(): size = %d", len(self._connectors))
+ profs = []
+ for con in self._connectors:
+ profs.append(con.profile())
+
+ return profs
+
+
+ ##
+ # @if jp
+ # @brief ConnectorId を取得
+ # @else
+ # @brief ConnectorId list
+ # @endif
+ #
+ # coil::vstring OutPortBase::getConnectorIds()
+ def getConnectorIds(self):
+ ids = []
+
+ for con in self._connectors:
+ ids.append(con.id())
+
+ self._rtcout.RTC_TRACE("getConnectorIds(): %s", OpenRTM_aist.flatten(ids))
+ return ids
+
+
+ ##
+ # @if jp
+ # @brief Connectorの名前を取得
+ # @else
+ # @brief Connector name list
+ # @endif
+ #
+ # coil::vstring OutPortBase::getConnectorNames()
+ def getConnectorNames(self):
+ names = []
+ for con in self._connectors:
+ names.append(con.name())
+
+ self._rtcout.RTC_TRACE("getConnectorNames(): %s", OpenRTM_aist.flatten(names))
+ return names
+
+
+ ##
+ # @if jp
+ # @brief ConnectorProfileをIDで取得
+ #
+ # 現在所有しているコネクタをIDで取得する。
+ #
+ # @param id Connector ID
+ # @return コネクタへのポインタ
+ #
+ # @else
+ #
+ # @brief Getting ConnectorProfile by ID
+ #
+ # This operation returns Connector specified by ID.
+ #
+ # @param id Connector ID
+ # @return A pointer to connector
+ #
+ # @endif
+ #
+ # OutPortConnector* getConnectorById(const char* id);
+ def getConnectorById(self, id):
+ self._rtcout.RTC_TRACE("getConnectorById(id = %s)", id)
+
+ for (i,con) in enumerate(self._connectors):
+ if id == con.id():
+ return self._connectors[i]
+
+ self._rtcout.RTC_WARN("ConnectorProfile with the id(%s) not found.", id)
+ return 0
+
+ ##
+ # @if jp
+ # @brief ConnectorProfileを名前で取得
+ #
+ # 現在所有しているコネクタを名前で取得する。
+ #
+ # @param name Connector name
+ # @return コネクタへのポインタ
+ #
+ # @else
+ #
+ # @brief Getting Connector by name
+ #
+ # This operation returns Connector specified by name.
+ #
+ # @param id Connector ID
+ # @return A pointer to connector
+ #
+ # @endif
+ #
+ # OutPortConnector* getConnectorByName(const char* name);
+ def getConnectorByName(self, name):
+ self._rtcout.RTC_TRACE("getConnectorByName(name = %s)", name)
+
+ for (i,con) in enumerate(self._connectors):
+ if name == con.name():
+ return self._connectors[i]
+
+ self._rtcout.RTC_WARN("ConnectorProfile with the name(%s) not found.", name)
+ return 0
+
+
+ ##
+ # @if jp
+ # @brief ConnectorProfileをIDで取得
+ # @else
+ # @brief Getting ConnectorProfile by name
+ # @endif
+ #
+ # bool OutPortBase::getConnectorProfileById(const char* id,
+ # ConnectorInfo& prof)
+ def getConnectorProfileById(self, id, prof):
+ self._rtcout.RTC_TRACE("getConnectorProfileById(id = %s)", id)
+
+ conn = self.getConnectorById(id)
+
+ if not conn:
+ return False
+
+ prof[0] = conn.profile()
+ return True
+
+
+ ##
+ # @if jp
+ # @brief ConnectorProfileを名前で取得
+ # @else
+ # @brief Getting ConnectorProfile by name
+ # @endif
+ #
+ # bool OutPortBase::getConnectorProfileByName(const char* name,
+ # ConnectorInfo& prof)
+ def getConnectorProfileByName(self, name, prof):
+ self._rtcout.RTC_TRACE("getConnectorProfileByName(name = %s)", name)
+
+ conn = self.getConnectorByName(name)
+
+ if not conn:
+ return False
+
+ prof[0] = conn.profile()
+ return True
+
+
+ ##
+ # @if jp
+ # @brief OutPortを activates する
+ # @else
+ # @brief Activate all Port interfaces
+ # @endif
+ #
+ # void OutPortBase::activateInterfaces()
+ def activateInterfaces(self):
+ self._rtcout.RTC_TRACE("activateInterfaces()")
+ for con in self._connectors:
+ con.activate()
+
+
+ ##
+ # @if jp
+ # @brief 全ての Port のインターフェースを deactivates する
+ # @else
+ # @brief Deactivate all Port interfaces
+ # @endif
+ #
+ # void OutPortBase::deactivateInterfaces()
+ def deactivateInterfaces(self):
+ self._rtcout.RTC_TRACE("deactivateInterfaces()")
+ for con in self._connectors:
+ con.deactivate()
+
+
+ ##
+ # @if jp
+ # @brief ConnectorDataListener リスナを追加する
+ #
+ # バッファ書き込みまたは読み出しイベントに関連する各種リスナを設定する。
+ #
+ # 設定できるリスナのタイプとコールバックイベントは以下の通り
+ #
+ # - ON_BUFFER_WRITE: バッファ書き込み時
+ # - ON_BUFFER_FULL: バッファフル時
+ # - ON_BUFFER_WRITE_TIMEOUT: バッファ書き込みタイムアウト時
+ # - ON_BUFFER_OVERWRITE: バッファ上書き時
+ # - ON_BUFFER_READ: バッファ読み出し時
+ # - ON_SEND: InProtへの送信時
+ # - ON_RECEIVED: InProtへの送信完了時
+ # - ON_SEND_ERTIMEOUT: OutPort側タイムアウト時
+ # - ON_SEND_ERERROR: OutPort側エラー時
+ # - ON_RECEIVER_FULL: InProt側バッファフル時
+ # - ON_RECEIVER_TIMEOUT: InProt側バッファタイムアウト時
+ # - ON_RECEIVER_ERROR: InProt側エラー時
+ #
+ # リスナは ConnectorDataListener を継承し、以下のシグニチャを持つ
+ # operator() を実装している必要がある。
+ #
+ # ConnectorDataListener::
+ # operator()(const ConnectorProfile&, const cdrStream&)
+ #
+ # デフォルトでは、この関数に与えたリスナオブジェクトの所有権は
+ # OutPortに移り、OutPort解体時もしくは、
+ # removeConnectorDataListener() により削除時に自動的に解体される。
+ # リスナオブジェクトの所有権を呼び出し側で維持したい場合は、第3引
+ # 数に false を指定し、自動的な解体を抑制することができる。
+ #
+ # @param listener_type リスナタイプ
+ # @param listener リスナオブジェクトへのポインタ
+ # @param autoclean リスナオブジェクトの自動的解体を行うかどうかのフラグ
+ #
+ # @else
+ # @brief Adding BufferDataListener type listener
+ #
+ # This operation adds certain listeners related to buffer writing and
+ # reading events.
+ # The following listener types are available.
+ #
+ # - ON_BUFFER_WRITE: At the time of buffer write
+ # - ON_BUFFER_FULL: At the time of buffer full
+ # - ON_BUFFER_WRITE_TIMEOUT: At the time of buffer write timeout
+ # - ON_BUFFER_OVERWRITE: At the time of buffer overwrite
+ # - ON_BUFFER_READ: At the time of buffer read
+ # - ON_SEND: At the time of sending to InPort
+ # - ON_RECEIVED: At the time of finishing sending to InPort
+ # - ON_SENDER_TIMEOUT: At the time of timeout of OutPort
+ # - ON_SENDER_ERROR: At the time of error of OutPort
+ # - ON_RECEIVER_FULL: At the time of bufferfull of InPort
+ # - ON_RECEIVER_TIMEOUT: At the time of timeout of InPort
+ # - ON_RECEIVER_ERROR: At the time of error of InPort
+ #
+ # Listeners should have the following function operator().
+ #
+ # ConnectorDataListener::
+ # operator()(const ConnectorProfile&, const cdrStream&)
+ #
+ # The ownership of the given listener object is transferred to
+ # this OutPort object in default. The given listener object will
+ # be destroied automatically in the OutPort's dtor or if the
+ # listener is deleted by removeConnectorDataListener() function.
+ # If you want to keep ownership of the listener object, give
+ # "false" value to 3rd argument to inhibit automatic destruction.
+ #
+ # @param listener_type A listener type
+ # @param listener A pointer to a listener object
+ # @param autoclean A flag for automatic listener destruction
+ #
+ # @endif
+ #
+ # void addConnectorDataListener(ConnectorDataListenerType listener_type,
+ # ConnectorDataListener* listener,
+ # bool autoclean = true);
+ def addConnectorDataListener(self, listener_type, listener, autoclean = True):
+ self._rtcout.RTC_TRACE("addConnectorDataListener()")
+ if listener_type < OpenRTM_aist.ConnectorDataListenerType.CONNECTOR_DATA_LISTENER_NUM:
+ self._rtcout.RTC_TRACE("addConnectorDataListener(%s)",
+ OpenRTM_aist.ConnectorDataListener.toString(listener_type))
+ self._listeners.connectorData_[listener_type].addListener(listener, autoclean)
+ return
+
+ self._rtcout.RTC_ERROR("addConnectorDataListener(): Unknown Listener Type")
+ return
+
+
+ ##
+ # @if jp
+ # @brief ConnectorDataListener リスナを削除する
+ #
+ # 設定した各種リスナを削除する。
+ #
+ # @param listener_type リスナタイプ
+ # @param listener リスナオブジェクトへのポインタ
+ #
+ # @else
+ # @brief Removing BufferDataListener type listener
+ #
+ # This operation removes a specified listener.
+ #
+ # @param listener_type A listener type
+ # @param listener A pointer to a listener object
+ #
+ # @endif
+ #
+ # void removeConnectorDataListener(ConnectorDataListenerType listener_type,
+ # ConnectorDataListener* listener);
+ def removeConnectorDataListener(self, listener_type, listener):
+ self._rtcout.RTC_TRACE("removeConnectorDataListener()")
+
+ if listener_type < OpenRTM_aist.ConnectorDataListenerType.CONNECTOR_DATA_LISTENER_NUM:
+ self._rtcout.RTC_TRACE("removeConnectorDataListener(%s)",
+ OpenRTM_aist.ConnectorDataListener.toString(listener_type))
+ self._listeners.connectorData_[listener_type].removeListener(listener)
+ return
+
+ self._rtcout.RTC_ERROR("removeConnectorDataListener(): Unknown Listener Type")
+ return
+
+
+ ##
+ # @if jp
+ # @brief ConnectorListener リスナを追加する
+ #
+ # バッファ書き込みまたは読み出しイベントに関連する各種リスナを設定する。
+ #
+ # 設定できるリスナのタイプは
+ #
+ # - ON_BUFFER_EMPTY: バッファが空の場合
+ # - ON_BUFFER_READTIMEOUT: バッファが空でタイムアウトした場合
+ #
+ # リスナは以下のシグニチャを持つ operator() を実装している必要がある。
+ #
+ # ConnectorListener::operator()(const ConnectorProfile&)
+ #
+ # デフォルトでは、この関数に与えたリスナオブジェクトの所有権は
+ # OutPortに移り、OutPort解体時もしくは、
+ # removeConnectorListener() により削除時に自動的に解体される。
+ # リスナオブジェクトの所有権を呼び出し側で維持したい場合は、第3引
+ # 数に false を指定し、自動的な解体を抑制することができる。
+ #
+ # @param listener_type リスナタイプ
+ # @param listener リスナオブジェクトへのポインタ
+ # @param autoclean リスナオブジェクトの自動的解体を行うかどうかのフラグ
+ #
+ # @else
+ # @brief Adding ConnectorListener type listener
+ #
+ # This operation adds certain listeners related to buffer writing and
+ # reading events.
+ # The following listener types are available.
+ #
+ # - ON_BUFFER_EMPTY: At the time of buffer empty
+ # - ON_BUFFER_READTIMEOUT: At the time of buffer read timeout
+ #
+ # Listeners should have the following function operator().
+ #
+ # ConnectorListener::operator()(const ConnectorProfile&)
+ #
+ # The ownership of the given listener object is transferred to
+ # this OutPort object in default. The given listener object will
+ # be destroied automatically in the OutPort's dtor or if the
+ # listener is deleted by removeConnectorListener() function.
+ # If you want to keep ownership of the listener object, give
+ # "false" value to 3rd argument to inhibit automatic destruction.
+ #
+ # @param listener_type A listener type
+ # @param listener A pointer to a listener object
+ # @param autoclean A flag for automatic listener destruction
+ #
+ # @endif
+ #
+ # void addConnectorListener(ConnectorListenerType callback_type,
+ # ConnectorListener* listener,
+ # bool autoclean = true);
+ def addConnectorListener(self, callback_type, listener, autoclean = True):
+ self._rtcout.RTC_TRACE("addConnectorListener()")
+
+ if callback_type < OpenRTM_aist.ConnectorListenerType.CONNECTOR_LISTENER_NUM:
+ self._rtcout.RTC_TRACE("addConnectorListener(%s)",
+ OpenRTM_aist.ConnectorListener.toString(callback_type))
+ self._listeners.connector_[callback_type].addListener(listener, autoclean)
+ return
+ self._rtcout.RTC_ERROR("addConnectorListener(): Unknown Listener Type")
+ return
+
+
+ ##
+ # @if jp
+ # @brief ConnectorDataListener リスナを削除する
+ #
+ # 設定した各種リスナを削除する。
+ #
+ # @param listener_type リスナタイプ
+ # @param listener リスナオブジェクトへのポインタ
+ #
+ # @else
+ # @brief Removing BufferDataListener type listener
+ #
+ # This operation removes a specified listener.
+ #
+ # @param listener_type A listener type
+ # @param listener A pointer to a listener object
+ #
+ # @endif
+ #
+ # void removeConnectorListener(ConnectorListenerType callback_type,
+ # ConnectorListener* listener);
+ def removeConnectorListener(self, callback_type, listener):
+ self._rtcout.RTC_TRACE("removeConnectorListener()")
+
+ if callback_type < OpenRTM_aist.ConnectorListenerType.CONNECTOR_LISTENER_NUM:
+ self._rtcout.RTC_TRACE("removeConnectorListener(%s)",
+ OpenRTM_aist.ConnectorListener.toString(callback_type))
+ self._listeners.connector_[callback_type].removeListener(listener)
+ return
+ self._rtcout.RTC_ERROR("removeConnectorListener(): Unknown Listener Type")
+ return
+
+
+ ##
+ # @if jp
+ # @brief OutPortの設定を行う
+ # @else
+ # @brief Configureing outport
+ # @endif
+ #
+ #void OutPortBase::configure()
+ def configure(self):
+ pass
+
+
+ ##
+ # @if jp
+ # @brief Interface情報を公開する
+ # @else
+ # @brief Publish interface information
+ # @endif
+ #
+ # ReturnCode_t OutPortBase::publishInterfaces(ConnectorProfile& cprof)
+ def publishInterfaces(self, cprof):
+ self._rtcout.RTC_TRACE("publishInterfaces()")
+
+ retval = self._publishInterfaces()
+ if retval != RTC.RTC_OK:
+ return retval
+
+ # prop: [port.outport].
+ prop = copy.deepcopy(self._properties)
+
+ conn_prop = OpenRTM_aist.Properties()
+
+ OpenRTM_aist.NVUtil.copyToProperties(conn_prop, cprof.properties)
+ prop.mergeProperties(conn_prop.getNode("dataport")) # marge ConnectorProfile
+
+ """
+ # marge ConnectorProfile for buffer property.
+ # e.g.
+ # prof[buffer.write.full_policy]
+ # << cprof[dataport.outport.buffer.write.full_policy]
+ #
+ """
+ prop.mergeProperties(conn_prop.getNode("dataport.outport"))
+
+
+ #
+ # ここで, ConnectorProfile からの properties がマージされたため、
+ # prop["dataflow_type"]: データフロータイプ
+ # prop["interface_type"]: インターフェースタイプ
+ # などがアクセス可能になる。
+ dflow_type = OpenRTM_aist.normalize([prop.getProperty("dataflow_type")])
+
+ if dflow_type == "push":
+ self._rtcout.RTC_PARANOID("dataflow_type = push .... do nothing")
+ return RTC.RTC_OK
+
+ elif dflow_type == "pull":
+ self._rtcout.RTC_PARANOID("dataflow_type = pull .... create PullConnector")
+
+ provider = self.createProvider(cprof, prop)
+ if not provider:
+ return RTC.BAD_PARAMETER
+
+ # create InPortPushConnector
+ connector = self.createConnector(cprof, prop, provider_ = provider)
+ if not connector:
+ return RTC.RTC_ERROR
+
+ # connector set
+ provider.setConnector(connector)
+
+ self._rtcout.RTC_DEBUG("publishInterface() successfully finished.")
+ return RTC.RTC_OK
+
+ self._rtcout.RTC_ERROR("unsupported dataflow_type")
+
+ return RTC.BAD_PARAMETER
+
+
+ ##
+ # @if jp
+ # @brief Interface情報を取得する
+ # @else
+ # @brief Subscribe interface
+ # @endif
+ #
+ # ReturnCode_t OutPortBase::subscribeInterfaces(const ConnectorProfile& cprof)
+ def subscribeInterfaces(self, cprof):
+ self._rtcout.RTC_TRACE("subscribeInterfaces()")
+
+ # prop: [port.outport].
+ prop = copy.deepcopy(self._properties)
+
+ conn_prop = OpenRTM_aist.Properties()
+ OpenRTM_aist.NVUtil.copyToProperties(conn_prop, cprof.properties)
+ prop.mergeProperties(conn_prop.getNode("dataport")) # marge ConnectorProfile
+ """
+ # marge ConnectorProfile for buffer property.
+ # e.g.
+ # prof[buffer.write.full_policy]
+ # << cprof[dataport.outport.buffer.write.full_policy]
+ """
+ prop.mergeProperties(conn_prop.getNode("dataport.outport"))
+
+ #
+ # ここで, ConnectorProfile からの properties がマージされたため、
+ # prop["dataflow_type"]: データフロータイプ
+ # prop["interface_type"]: インターフェースタイプ
+ # などがアクセス可能になる。
+ #
+ dflow_type = OpenRTM_aist.normalize([prop.getProperty("dataflow_type")])
+
+ profile = OpenRTM_aist.ConnectorInfo(cprof.name,
+ cprof.connector_id,
+ OpenRTM_aist.CORBA_SeqUtil.refToVstring(cprof.ports),
+ prop)
+ if dflow_type == "push":
+ self._rtcout.RTC_PARANOID("dataflow_type = push .... create PushConnector")
+
+ # interface
+ consumer = self.createConsumer(cprof, prop)
+ if not consumer:
+ return RTC.BAD_PARAMETER
+
+ # create OutPortPushConnector
+ connector = self.createConnector(cprof, prop, consumer_ = consumer)
+ if not connector:
+ return RTC.RTC_ERROR
+
+ ret = connector.setConnectorInfo(profile)
+
+ if ret == RTC.RTC_OK:
+ self._rtcout.RTC_DEBUG("subscribeInterfaces() successfully finished.")
+
+ return ret
+
+ elif dflow_type == "pull":
+ self._rtcout.RTC_PARANOID("dataflow_type = pull.")
+
+ conn = self.getConnectorById(cprof.connector_id)
+ if not conn:
+ self._rtcout.RTC_ERROR("specified connector not found: %s",
+ cprof.connector_id)
+ return RTC.RTC_ERROR
+
+ ret = conn.setConnectorInfo(profile)
+
+ if ret == RTC.RTC_OK:
+ self._rtcout.RTC_DEBUG("subscribeInterfaces() successfully finished.")
+
+ return ret
+
+ self._rtcout.RTC_ERROR("unsupported dataflow_type")
+ return RTC.BAD_PARAMETER
+
+
+ ##
+ # @if jp
+ # @brief 登録されているInterface情報を解除する
+ # @else
+ # @brief Unsubscribe interface
+ # @endif
+ #
+ # void
+ # OutPortBase::unsubscribeInterfaces(const ConnectorProfile& connector_profile)
+ def unsubscribeInterfaces(self, connector_profile):
+ self._rtcout.RTC_TRACE("unsubscribeInterfaces()")
+
+ id = connector_profile.connector_id
+ self._rtcout.RTC_PARANOID("connector_id: %s", id)
+
+ len_ = len(self._connectors)
+ for i in range(len_):
+ idx = (len_ - 1) - i
+ if id == self._connectors[idx].id():
+ # Connector's dtor must call disconnect()
+ self._connectors[idx].deactivate()
+ self._connectors[idx].disconnect()
+ del self._connectors[idx]
+ self._rtcout.RTC_TRACE("delete connector: %s", id)
+ return
+
+ self._rtcout.RTC_ERROR("specified connector not found: %s", id)
+ return
+
+
+ ##
+ # @if jp
+ # @brief OutPort provider の初期化
+ # @else
+ # @brief OutPort provider initialization
+ # @endif
+ #
+ # void OutPortBase::initProviders()
+ def initProviders(self):
+ self._rtcout.RTC_TRACE("initProviders()")
+
+ # create OutPort providers
+ factory = OpenRTM_aist.OutPortProviderFactory.instance()
+ provider_types = factory.getIdentifiers()
+ self._rtcout.RTC_PARANOID("available OutPortProviders: %s",
+ OpenRTM_aist.flatten(provider_types))
+
+ if self._properties.hasKey("provider_types") and \
+ OpenRTM_aist.normalize(self._properties.getProperty("provider_types")) != "all":
+ self._rtcout.RTC_DEBUG("allowed providers: %s",
+ self._properties.getProperty("provider_types"))
+
+ temp_types = provider_types
+ provider_types = []
+ active_types = OpenRTM_aist.split(self._properties.getProperty("provider_types"), ",")
+
+ temp_types.sort()
+ active_types.sort()
+
+ set_ptypes = set(temp_types).intersection(set(active_types))
+ provider_types = provider_types + list(set_ptypes)
+
+ # OutPortProvider supports "pull" dataflow type
+ if len(provider_types) > 0:
+ self._rtcout.RTC_DEBUG("dataflow_type pull is supported")
+ self.appendProperty("dataport.dataflow_type", "pull")
+ self.appendProperty("dataport.interface_type",
+ OpenRTM_aist.flatten(provider_types))
+
+ self._providerTypes = provider_types
+
+
+ ##
+ # @if jp
+ # @brief InPort consumer の初期化
+ # @else
+ # @brief InPort consumer initialization
+ # @endif
+ #
+ # void OutPortBase::initConsumers()
+ def initConsumers(self):
+ self._rtcout.RTC_TRACE("initConsumers()")
+
+ # create InPort consumers
+ factory = OpenRTM_aist.InPortConsumerFactory.instance()
+ consumer_types = factory.getIdentifiers()
+ self._rtcout.RTC_PARANOID("available InPortConsumer: %s",
+ OpenRTM_aist.flatten(consumer_types))
+
+ if self._properties.hasKey("consumer_types") and \
+ OpenRTM_aist.normalize(self._properties.getProperty("consumer_types")) != "all":
+ self._rtcout.RTC_DEBUG("allowed consumers: %s",
+ self._properties.getProperty("consumer_types"))
+
+ temp_types = consumer_types
+ consumer_types = []
+ active_types = OpenRTM_aist.split(self._properties.getProperty("consumer_types"), ",")
+
+ temp_types.sort()
+ active_types.sort()
+
+ set_ctypes = set(temp_types).intersection(set(active_types))
+ consumer_types = consumer_types + list(set_ctypes)
+
+ # InPortConsumer supports "push" dataflow type
+ if len(consumer_types) > 0:
+ self._rtcout.RTC_PARANOID("dataflow_type push is supported")
+ self.appendProperty("dataport.dataflow_type", "push")
+ self.appendProperty("dataport.interface_type",
+ OpenRTM_aist.flatten(consumer_types))
+
+ self._consumerTypes = consumer_types
+
+
+ ##
+ # @if jp
+ # @brief OutPort provider の生成
+ # @else
+ # @brief OutPort provider creation
+ # @endif
+ #
+ # OutPortProvider*
+ # OutPortBase::createProvider(ConnectorProfile& cprof, coil::Properties& prop)
+ def createProvider(self, cprof, prop):
+ if prop.getProperty("interface_type") and \
+ not OpenRTM_aist.includes(self._providerTypes, prop.getProperty("interface_type")):
+ self._rtcout.RTC_ERROR("no provider found")
+ self._rtcout.RTC_DEBUG("interface_type: %s", prop.getProperty("interface_type"))
+ self._rtcout.RTC_DEBUG("interface_types: %s",
+ OpenRTM_aist.flatten(self._providerTypes))
+ return 0
+
+ self._rtcout.RTC_DEBUG("interface_type: %s", prop.getProperty("interface_type"))
+ provider = OpenRTM_aist.OutPortProviderFactory.instance().createObject(prop.getProperty("interface_type"))
+
+ if provider != 0:
+ self._rtcout.RTC_DEBUG("provider created")
+ provider.init(prop.getNode("provider"))
+
+ if not provider.publishInterface(cprof.properties):
+ self._rtcout.RTC_ERROR("publishing interface information error")
+ OpenRTM_aist.OutPortProviderFactory.instance().deleteObject(provider)
+ return 0
+
+ return provider
+
+ self._rtcout.RTC_ERROR("provider creation failed")
+ return 0
+
+
+ ##
+ # @if jp
+ # @brief InPort consumer の生成
+ # @else
+ # @brief InPort consumer creation
+ # @endif
+ #
+ # InPortConsumer* OutPortBase::createConsumer(const ConnectorProfile& cprof,
+ # coil::Properties& prop)
+ def createConsumer(self, cprof, prop):
+ if prop.getProperty("interface_type") and \
+ not self._consumerTypes.count(prop.getProperty("interface_type")):
+ self._rtcout.RTC_ERROR("no consumer found")
+ self._rtcout.RTC_DEBUG("interface_type: %s", prop.getProperty("interface_type"))
+ self._rtcout.RTC_DEBUG("interface_types: %s",
+ OpenRTM_aist.flatten(self._consumerTypes))
+ return 0
+
+ self._rtcout.RTC_DEBUG("interface_type: %s", prop.getProperty("interface_type"))
+ consumer = OpenRTM_aist.InPortConsumerFactory.instance().createObject(prop.getProperty("interface_type"))
+
+ if consumer != 0:
+ self._rtcout.RTC_DEBUG("consumer created")
+ consumer.init(prop.getNode("consumer"))
+
+ if not consumer.subscribeInterface(cprof.properties):
+ self._rtcout.RTC_ERROR("interface subscription failed.")
+ OpenRTM_aist.InPortConsumerFactory.instance().deleteObject(consumer)
+ return 0
+
+ return consumer
+
+ self._rtcout.RTC_ERROR("consumer creation failed")
+ return 0
+
+
+ ##
+ # @if jp
+ # @brief OutPortPushConnector の生成
+ # @else
+ # @brief OutPortPushConnector creation
+ # @endif
+ #
+ # OutPortConnector*
+ # OutPortBase::createConnector(const ConnectorProfile& cprof,
+ # coil::Properties& prop,
+ # InPortConsumer* consumer)
+ def createConnector(self, cprof, prop, provider_ = None, consumer_ = None):
+ profile = OpenRTM_aist.ConnectorInfo(cprof.name,
+ cprof.connector_id,
+ OpenRTM_aist.CORBA_SeqUtil.refToVstring(cprof.ports),
+ prop)
+
+ connector = None
+ try:
+
+ if consumer_ is not None:
+ connector = OpenRTM_aist.OutPortPushConnector(profile, consumer_, self._listeners)
+ elif provider_ is not None:
+ connector = OpenRTM_aist.OutPortPullConnector(profile, provider_, self._listeners)
+
+ else:
+ self._rtcout.RTC_ERROR("provider or consumer is not passed. returned 0;")
+ return 0
+
+ if connector is None:
+ self._rtcout.RTC_ERROR("OutPortConnector creation failed")
+ return 0
+
+ if consumer_ is not None:
+ self._rtcout.RTC_TRACE("OutPortPushConnector created")
+ elif provider_ is not None:
+ self._rtcout.RTC_TRACE("OutPortPullConnector created")
+
+ self._connectors.append(connector)
+ self._rtcout.RTC_PARANOID("connector push backed: %d", len(self._connectors))
+ return connector
+
+ except:
+ self._rtcout.RTC_ERROR("Exeption: OutPortPushConnector creation failed")
+ self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
+ return 0
+
+
+ self._rtcout.RTC_FATAL("never comes here: createConnector()")
+ return 0
Deleted: trunk/OpenRTM-aist-Python/OpenRTM_aist/OutPortDirectConsumer.py
===================================================================
--- trunk/OpenRTM-aist-Python/OpenRTM_aist/OutPortDirectConsumer.py 2016-02-01 05:29:04 UTC (rev 642)
+++ trunk/OpenRTM-aist-Python/OpenRTM_aist/OutPortDirectConsumer.py 2016-02-01 08:37:55 UTC (rev 643)
@@ -1,267 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: euc-jp -*-
-
-##
-# @file OutPortDirectConsumer.py
-# @brief OutPortDirectConsumer class
-# @date $Date: 2016/01/08 $
-# @author Nobuhiko Miyamoto
-#
-
-
-import sys
-from omniORB import any
-import OpenRTM_aist
-import OpenRTM
-
-##
-# @if jp
-#
-# @class InPortDirectConsumer
-#
-# @brief InPortDirectConsumer クラス
-#
-# データをダイレクトに書き込むpull型通信を実現するOutPortコンシュマークラス
-#
-# @else
-# @class InPortDirectConsumer
-#
-# @brief InPortDirectConsumer class
-#
-#
-#
-# @endif
-#
-class OutPortDirectConsumer(OpenRTM_aist.OutPortConsumer):
- """
- """
-
- ##
- # @if jp
- # @brief コンストラクタ
- #
- # コンストラクタ
- #
- # @param self
- #
- # @else
- # @brief Constructor
- #
- # Constructor
- #
- # @param self
- #
- # @endif
- #
- def __init__(self):
- OpenRTM_aist.OutPortConsumer.__init__(self)
- self._rtcout = OpenRTM_aist.Manager.instance().getLogbuf("OutPortDirectConsumer")
- self._listeners = None
- self._profile = None
- self._properties = None
- return
-
- ##
- # @if jp
- # @brief デストラクタ
- #
- # デストラクタ
- #
- # @param self
- #
- # @else
- # @brief Destructor
- #
- # Destructor
- #
- # @param self
- #
- # @endif
- #
- def __del__(self, CorbaConsumer=OpenRTM_aist.CorbaConsumer):
- self._rtcout.RTC_PARANOID("~OutPortDirectConsumer()")
-
- pass
-
-
- ##
- # @if jp
- # @brief 設定初期化
- #
- # InPortConsumerの各種設定を行う
- #
- # @self
- #
- #
- # @else
- # @brief Initializing configuration
- #
- #
- # @endif
- #
- # virtual void init(coil::Properties& prop);
- def init(self, prop):
- self._rtcout.RTC_TRACE("init()")
- self._properties = prop
- return
-
- ##
- # @if jp
- # @brief
- #
- # @param self
- # @param data
- # @return
- #
- # @else
- # @brief
- #
- # @param self
- # @param data
- # @return
- #
- # @endif
- #
- # virtual ReturnCode put(const cdrMemoryStream& data);
- def get(self, data):
- self._rtcout.RTC_PARANOID("get()")
- return self.UNKNOWN_ERROR
-
-
- # virtual void setBuffer(CdrBufferBase* buffer);
- def setBuffer(self, buffer):
- self._rtcout.RTC_TRACE("setBuffer()")
- return
-
-
- # void OutPortCorbaCdrConsumer::setListener(ConnectorInfo& info,
- # ConnectorListeners* listeners)
- def setListener(self, info, listeners):
- self._rtcout.RTC_TRACE("setListener()")
- self._listeners = listeners
- self._profile = info
- return
-
-
-
-
-
- ##
- # @if jp
- # @brief InterfaceProfile情報を公開する
- #
- #
- # @param self
- # @param properties InterfaceProfile情報を受け取るプロパティ
- #
- # @else
- # @brief Publish InterfaceProfile information
- #
- #
- # @param self
- # @param properties Properties to get InterfaceProfile information
- #
- # @endif
- #
- # virtual void publishInterfaceProfile(SDOPackage::NVList& properties);
- def subscribeInterface(self, properties):
- self._rtcout.RTC_TRACE("subscribeInterface()")
-
-
- return True
-
-
- ##
- # @if jp
- # @brief データ送信通知への登録
- #
- # @param self
- # @param properties 登録情報
- #
- # @return 登録処理結果(登録成功:true、登録失敗:false)
- #
- # @else
- # @brief Subscribe to the data sending notification
- #
- # @param self
- # @param properties Information for subscription
- #
- # @return Subscription result (Successful:true, Failed:false)
- #
- # @endif
- #
- # virtual bool subscribeInterface(const SDOPackage::NVList& properties);
- def unsubscribeInterface(self, properties):
- self._rtcout.RTC_TRACE("unsubscribeInterface()")
- return
-
-
-
-
-
-
- # inline void onBufferWrite(const cdrMemoryStream& data)
- def onBufferWrite(self, data):
- if self._listeners is not None and self._profile is not None:
- self._listeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_BUFFER_WRITE].notify(self._profile, data)
-
- return
-
-
- # inline void onBufferFull(const cdrMemoryStream& data)
- def onBufferFull(self, data):
- if self._listeners is not None and self._profile is not None:
- self._listeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_BUFFER_FULL].notify(self._profile, data)
-
- return
-
-
- # inline void onReceived(const cdrMemoryStream& data)
- def onReceived(self, data):
- if self._listeners is not None and self._profile is not None:
- self._listeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_RECEIVED].notify(self._profile, data)
-
- return
-
-
- # inline void onReceiverFull(const cdrMemoryStream& data)
- def onReceiverFull(self, data):
- if self._listeners is not None and self._profile is not None:
- self._listeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_RECEIVER_FULL].notify(self._profile, data)
-
- return
-
-
- ##
- # @brief Connector listener functions
- #
- # inline void onSenderEmpty()
- def onSenderEmpty(self):
- if self._listeners is not None and self._profile is not None:
- self._listeners.connector_[OpenRTM_aist.ConnectorListenerType.ON_SENDER_EMPTY].notify(self._profile)
-
- return
-
-
- # inline void onSenderTimeout()
- def onSenderTimeout(self):
- if self._listeners is not None and self._profile is not None:
- self._listeners.connector_[OpenRTM_aist.ConnectorListenerType.ON_SENDER_TIMEOUT].notify(self._profile)
-
- return
-
-
- # inline void onSenderError()
- def onSenderError(self):
- if self._listeners is not None and self._profile is not None:
- self._listeners.connector_[OpenRTM_aist.ConnectorListenerType.ON_SENDER_ERROR].notify(self._profile)
-
- return
-
-
-def OutPortDirectConsumerInit():
- factory = OpenRTM_aist.OutPortConsumerFactory.instance()
- factory.addFactory("direct",
- OpenRTM_aist.OutPortDirectConsumer,
- OpenRTM_aist.Delete)
- return
Deleted: trunk/OpenRTM-aist-Python/OpenRTM_aist/OutPortDirectProvider.py
===================================================================
--- trunk/OpenRTM-aist-Python/OpenRTM_aist/OutPortDirectProvider.py 2016-02-01 05:29:04 UTC (rev 642)
+++ trunk/OpenRTM-aist-Python/OpenRTM_aist/OutPortDirectProvider.py 2016-02-01 08:37:55 UTC (rev 643)
@@ -1,175 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: euc-jp -*-
-
-##
-# @file OutPortDirectProvider.py
-# @brief OutPortDirectProvider class
-# @date $Date: 2016/01/08 $
-# @author Nobuhiko Miyamoto
-#
-
-import sys
-from omniORB import *
-from omniORB import any
-
-import OpenRTM_aist
-import OpenRTM__POA,OpenRTM
-
-##
-# @if jp
-# @class OutPortDirectProvider
-# @brief OutPortDirectProvider クラス
-#
-# データをダイレクトに書き込むpull型通信を実現するOutPortプロバイダクラス
-#
-# @param self
-#
-# @else
-# @class InPortDirectProvider
-# @brief InPortDirectProvider class
-#
-#
-# @param self
-#
-# @endif
-#
-class OutPortDirectProvider(OpenRTM_aist.OutPortProvider):
- ##
- # @if jp
- # @brief コンストラクタ
- #
- # コンストラクタ
- #
- # @param self
- #
- # @else
- # @brief Constructor
- #
- # @param self
- #
- # @endif
- #
- def __init__(self):
- OpenRTM_aist.OutPortProvider.__init__(self)
- self.setInterfaceType("direct")
-
-
-
- self._listeners = None
- self._buffer = None
- self._profile = None
- #self._connector = None
- return
-
-
- ##
- # @if jp
- # @brief デストラクタ
- #
- # デストラクタ
- #
- # @param self
- #
- # @else
- # @brief Destructor
- #
- # Destructor
- #
- # @param self
- #
- # @endif
- #
- def __del__(self):
-
- return
-
-
-
- # void init(coil::Properties& prop);
- def init(self, prop):
- pass
-
-
-
- # virtual void setBuffer(BufferBase<cdrMemoryStream>* buffer);
- def setBuffer(self, buffer):
- self._buffer = buffer
- return
-
-
-
- # virtual void setListener(ConnectorInfo& info,
- # ConnectorListeners* listeners);
- def setListener(self, info, listeners):
- self._profile = info
- self._listeners = listeners
- return
-
-
-
- # virtual void setConnector(OutPortConnector* connector);
- def setConnector(self, connector):
- self._connector = connector
- return
-
-
-
-
-
- # inline void onBufferRead(const cdrMemoryStream& data)
- def onBufferRead(self, data):
- if self._listeners and self._profile:
- self._listeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_BUFFER_READ].notify(self._profile, data)
- return
-
-
- # inline void onSend(const cdrMemoryStream& data)
- def onSend(self, data):
- if self._listeners and self._profile:
- self._listeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_SEND].notify(self._profile, data)
- return
-
-
- # inline void onBufferEmpty()
- def onBufferEmpty(self):
- if self._listeners and self._profile:
- self._listeners.connector_[OpenRTM_aist.ConnectorListenerType.ON_BUFFER_EMPTY].notify(self._profile)
- return
-
-
- # inline void onBufferReadTimeout()
- def onBufferReadTimeout(self):
- if self._listeners and self._profile:
- self._listeners.connector_[OpenRTM_aist.ConnectorListenerType.ON_BUFFER_READ_TIMEOUT].notify(self._profile)
- return
-
-
- # inline void onSenderEmpty()
- def onSenderEmpty(self):
- if self._listeners and self._profile:
- self._listeners.connector_[OpenRTM_aist.ConnectorListenerType.ON_SENDER_EMPTY].notify(self._profile)
- return
-
-
- # inline void onSenderTimeout()
- def onSenderTimeout(self):
- if self._listeners and self._profile:
- self._listeners.connector_[OpenRTM_aist.ConnectorListenerType.ON_SENDER_TIMEOUT].notify(self._profile)
- return
-
-
- # inline void onSenderError()
- def onSenderError(self):
- if self._listeners and self._profile:
- self._listeners.connector_[OpenRTM_aist.ConnectorListenerType.ON_SENDER_ERROR].notify(self._profile)
- return
-
-
-
-
-
-def OutPortDirectProviderInit():
- factory = OpenRTM_aist.OutPortProviderFactory.instance()
- factory.addFactory("direct",
- OpenRTM_aist.OutPortDirectProvider,
- OpenRTM_aist.Delete)
Modified: trunk/OpenRTM-aist-Python/OpenRTM_aist/OutPortPullConnector.py
===================================================================
--- trunk/OpenRTM-aist-Python/OpenRTM_aist/OutPortPullConnector.py 2016-02-01 05:29:04 UTC (rev 642)
+++ trunk/OpenRTM-aist-Python/OpenRTM_aist/OutPortPullConnector.py 2016-02-01 08:37:55 UTC (rev 643)
@@ -1,403 +1,319 @@
-#!/usr/bin/env python
-# -*- coding: euc-jp -*-
-
-
-##
-# @file OutPortPullConnector.py
-# @brief OutPortPull type connector class
-# @date $Date$
-# @author Noriaki Ando <n-ando at aist.go.jp> and Shinji Kurihara
-#
-# Copyright (C) 2009
-# Noriaki Ando
-# Task-intelligence Research Group,
-# Intelligent Systems Research Institute,
-# National Institute of
-# Advanced Industrial Science and Technology (AIST), Japan
-# All rights reserved.
-#
-
-from omniORB import *
-from omniORB import any
-
-import OpenRTM_aist
-
-
-##
-# @if jp
-# @class OutPortPullConnector
-# @brief OutPortPullConnector クラス
-#
-# OutPort の pull 型データフローのための Connector クラス。このオブ
-# ジェクトは、接続時に dataflow_type に pull が指定された場合、
-# OutPort によって生成・所有され、InPortPullConnector と対になって、
-# データポートの pull 型のデータフローを実現する。一つの接続に対して、
-# 一つのデータストリームを提供する唯一の Connector が対応する。
-# Connector は 接続時に生成される UUID 形式の ID により区別される。
-#
-# OutPortPullConnector は以下の三つのオブジェクトを所有し管理する。
-#
-# - InPortConsumer
-# - Buffer
-#
-# OutPort に書き込まれたデータは OutPortPullConnector::write() に渡
-# され Buffer に書き込まれる。InPortPullConnector が
-# OutPortPullConnector からデータを読み出すことで InPort にデータが
-# 転送される。
-#
-# @since 1.0.0
-#
-# @else
-# @class OutPortPullConnector
-# @brief OutPortPullConnector class
-#
-# Connector class of OutPort for pull type dataflow. When "pull" is
-# specified as dataflow_type at the time of establishing
-# connection, this object is generated and owned by the OutPort.
-# This connector and InPortPullConnector make a pair and realize
-# pull type dataflow of data ports. One connector corresponds to
-# one connection which provides a data stream. Connector is
-# distinguished by ID of the UUID that is generated at establishing
-# connection.
-#
-# OutPortPullConnector owns and manages the following objects.
-#
-# - InPortConsumer
-# - Buffer
-#
-# Data written into the OutPort is passed to
-# OutPortPullConnector::write(), and it is written into the buffer.
-# By reading data from OutPortPullConnector to InPortPullConnector,
-# data transfer is realized.
-#
-# @since 1.0.0
-#
-# @endif
-#
-class OutPortPullConnector(OpenRTM_aist.OutPortConnector):
- """
- """
-
- ##
- # @if jp
- # @brief コンストラクタ
- #
- # OutPortPullConnector のコンストラクタはオブジェクト生成時に下記
- # を引数にとる。ConnectorInfo は接続情報を含み、この情報に従いバッ
- # ファ等を生成する。OutPort インターフェースのプロバイダオブジェク
- # トへのポインタを取り、所有権を持つので、OutPortPullConnector は
- # OutPortProvider の解体責任を持つ。各種イベントに対するコールバッ
- # ク機構を提供する ConnectorListeners を持ち、適切なタイミングでコー
- # ルバックを呼び出す。データバッファがもし OutPortBase から提供さ
- # れる場合はそのポインタを取る。
- #
- # @param info ConnectorInfo
- # @param provider OutPortProvider
- # @param listeners ConnectorListeners 型のリスナオブジェクトリスト
- # @param buffer CdrBufferBase 型のバッファ
- #
- # @else
- # @brief Constructor
- #
- # OutPortPullConnector's constructor is given the following
- # arguments. According to ConnectorInfo which includes
- # connection information, a buffer is created. It is also given
- # a pointer to the provider object for the OutPort interface.
- # The owner-ship of the pointer is owned by this
- # OutPortPullConnector, it has responsibility to destruct the
- # OutPortProvider. OutPortPullConnector also has
- # ConnectorListeners to provide event callback mechanisms, and
- # they would be called at the proper timing. If data buffer is
- # given by OutPortBase, the pointer to the buffer is also given
- # as arguments.
- #
- # @param info ConnectorInfo
- # @param provider OutPortProvider
- # @param listeners ConnectorListeners type lsitener object list
- # @param buffer CdrBufferBase type buffer
- #
- # @endif
- #
- # OutPortPullConnector(ConnectorInfo info,
- # OutPortProvider* provider,
- # ConnectorListeners& listeners,
- # CdrBufferBase* buffer = 0);
- def __init__(self, info, provider, listeners, buffer = 0):
- OpenRTM_aist.OutPortConnector.__init__(self, info)
- self._provider = provider
- self._listeners = listeners
- self._buffer = buffer
-
- self._directInPort = None
- self._inPortListeners = None
-
- self._directNewData = False
- self._valueMutex = threading.RLock()
- self._value = None
-
- if not self._buffer:
- self._buffer = self.createBuffer(info)
-
- if not self._provider or not self._buffer:
- self._rtcout.RTC_ERROR("Exeption: in OutPortPullConnector.__init__().")
- raise
-
- self._buffer.init(info.properties.getNode("buffer"))
- self._provider.init(info.properties)
- self._provider.setBuffer(self._buffer)
- self._provider.setConnector(self)
- self._provider.setListener(info, self._listeners)
- self.onConnect()
- return
-
-
- ##
- # @if jp
- # @brief デストラクタ
- #
- # disconnect() が呼ばれ、provider, buffer が解体・削除される。
- #
- # @else
- #
- # @brief Destructor
- #
- # This operation calls disconnect(), which destructs and deletes
- # the consumer, the publisher and the buffer.
- #
- # @endif
- #
- def __del__(self):
- return
-
-
- ##
- # @if jp
- # @brief データの書き込み
- #
- # Publisherに対してデータを書き込み、これにより対応するInPortへ
- # データが転送される。
- #
- # @else
- #
- # @brief Writing data
- #
- # This operation writes data into publisher and then the data
- # will be transferred to correspondent InPort.
- #
- # @endif
- #
- # virtual ReturnCode write(const cdrMemoryStream& data);
- def write(self, data):
- if self._directInPort is not None:
- if self.isNew():
- #self._listeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_BUFFER_OVERWRITE].notify(self._profile, data)
- self._inPortListeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_BUFFER_OVERWRITE].notify(self._profile, data)
- #self._listeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_RECEIVER_FULL].notify(self._profile, data)
- self._inPortListeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_RECEIVER_FULL].notify(self._profile, data)
- self._rtcout.RTC_TRACE("ONBUFFER_OVERWRITE(InPort,OutPort), ")
- self._rtcout.RTC_TRACE("ON_RECEIVER_FULL(InPort,OutPort) ")
- self._rtcout.RTC_TRACE("callback called in direct mode.")
- #self._listeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_BUFFER_WRITE].notify(self._profile, data)
- self._inPortListeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_BUFFER_WRITE].notify(self._profile, data)
- self._rtcout.RTC_TRACE("ON_BUFFER_WRITE(InPort,OutPort), ")
- self._rtcout.RTC_TRACE("callback called in direct mode.")
- guard = OpenRTM_aist.ScopedLock(self._valueMutex)
- self._value = data
- self._directNewData = True
- del guard
- #self._listeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_RECEIVED].notify(self._profile, data)
- self._inPortListeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_RECEIVED].notify(self._profile, data)
- self._rtcout.RTC_TRACE("ON_RECEIVED(InPort,OutPort), ")
- self._rtcout.RTC_TRACE("callback called in direct mode.")
- return self.PORT_OK
- # data -> (conversion) -> CDR stream
- cdr_data = None
- if self._endian is not None:
- cdr_data = cdrMarshal(any.to_any(data).typecode(), data, self._endian)
- else:
- self._rtcout.RTC_ERROR("write(): endian %s is not support.",self._endian)
- return self.UNKNOWN_ERROR
-
- self._buffer.write(cdr_data)
- return self.PORT_OK
-
-
- ##
- # @if jp
- # @brief 接続解除
- #
- # consumer, publisher, buffer が解体・削除される。
- #
- # @else
- #
- # @brief disconnect
- #
- # This operation destruct and delete the consumer, the publisher
- # and the buffer.
- #
- # @endif
- #
- # virtual ReturnCode disconnect();
- def disconnect(self):
- self._rtcout.RTC_TRACE("disconnect()")
- self.onDisconnect()
- # delete provider
- if self._provider:
- OpenRTM_aist.OutPortProviderFactory.instance().deleteObject(self._provider)
- self._provider = 0
-
- # delete buffer
- if self._buffer:
- OpenRTM_aist.CdrBufferFactory.instance().deleteObject(self._buffer)
- self._buffer = 0
-
- if self._directInPort:
- self._directInPort.removeOutPortConnector(self)
- self._directInPort = None
-
- return self.PORT_OK
-
-
- ##
- # @if jp
- # @brief Buffer を取得する
- #
- # Connector が保持している Buffer を返す
- #
- # @else
- # @brief Getting Buffer
- #
- # This operation returns this connector's buffer
- #
- # @endif
- #
- # virtual CdrBufferBase* getBuffer();
- def getBuffer(self):
- return self._buffer
-
-
- ##
- # @if jp
- # @brief アクティブ化
- #
- # このコネクタをアクティブ化する
- #
- # @else
- #
- # @brief Connector activation
- #
- # This operation activates this connector
- #
- # @endif
- #
- # virtual void activate(){}; // do nothing
- def activate(self): # do nothing
- pass
-
-
- ##
- # @if jp
- # @brief 非アクティブ化
- #
- # このコネクタを非アクティブ化する
- #
- # @else
- #
- # @brief Connector deactivation
- #
- # This operation deactivates this connector
- #
- # @endif
- #
- # virtual void deactivate(){}; // do nothing
- def deactivate(self): # do nothing
- pass
-
-
- ##
- # @if jp
- # @brief Bufferの生成
- # @else
- # @brief create buffer
- # @endif
- #
- # CdrBufferBase* createBuffer(ConnectorInfo& info);
- def createBuffer(self, info):
- buf_type = info.properties.getProperty("buffer_type","ring_buffer")
- return OpenRTM_aist.CdrBufferFactory.instance().createObject(buf_type)
-
-
- ##
- # @if jp
- # @brief 接続確立時にコールバックを呼ぶ
- # @else
- # @brief Invoke callback when connection is established
- # @endif
- # void onConnect()
- def onConnect(self):
- if self._listeners and self._profile:
- self._listeners.connector_[OpenRTM_aist.ConnectorListenerType.ON_CONNECT].notify(self._profile)
- return
-
-
- ##
- # @if jp
- # @brief 接続切断時にコールバックを呼ぶ
- # @else
- # @brief Invoke callback when connection is destroied
- # @endif
- # void onDisconnect()
- def onDisconnect(self):
- if self._listeners and self._profile:
- self._listeners.connector_[OpenRTM_aist.ConnectorListenerType.ON_DISCONNECT].notify(self._profile)
- return
-
-
- ##
- # @if jp
- # @brief データをダイレクトに書き込むためのInPortのサーバントを設定する
- #
- # @param self
- # @param directInPort InPortのサーバント
- # @return True: 設定に成功 False: 既に設定済みのため失敗
- # @else
- # @brief
- #
- # @param self
- # @param directInPort
- # @return
- # @endif
- #
- # bool setInPort(InPortBase* directInPort);
- def setInPort(self, directInPort):
- if self._directInPort is not None:
- return False
- self._directInPort = directInPort
- self._inPortListeners = self._directInPort._listeners
- self._directInPort.addOutPortConnector(self)
- return True
-
- ##
- # @if jp
- #
- # @brief データをダイレクトに読み込む
- #
- # @param self
- # @return 読み込むデータ
- #
- # @else
- # @brief
- #
- # @param self
- # @param data
- # @endif
- # void write(const DataType& data)
- def read(self):
- guard = OpenRTM_aist.ScopedLock(self._valueMutex)
- data = self._value
- self._directNewData = False
- del guard
- return data
-
- def isNew(self):
- return self._directNewData
\ No newline at end of file
+#!/usr/bin/env python
+# -*- coding: euc-jp -*-
+
+
+##
+# @file OutPortPullConnector.py
+# @brief OutPortPull type connector class
+# @date $Date$
+# @author Noriaki Ando <n-ando at aist.go.jp> and Shinji Kurihara
+#
+# Copyright (C) 2009
+# Noriaki Ando
+# Task-intelligence Research Group,
+# Intelligent Systems Research Institute,
+# National Institute of
+# Advanced Industrial Science and Technology (AIST), Japan
+# All rights reserved.
+#
+
+from omniORB import *
+from omniORB import any
+
+import OpenRTM_aist
+
+
+##
+# @if jp
+# @class OutPortPullConnector
+# @brief OutPortPullConnector クラス
+#
+# OutPort の pull 型データフローのための Connector クラス。このオブ
+# ジェクトは、接続時に dataflow_type に pull が指定された場合、
+# OutPort によって生成・所有され、InPortPullConnector と対になって、
+# データポートの pull 型のデータフローを実現する。一つの接続に対して、
+# 一つのデータストリームを提供する唯一の Connector が対応する。
+# Connector は 接続時に生成される UUID 形式の ID により区別される。
+#
+# OutPortPullConnector は以下の三つのオブジェクトを所有し管理する。
+#
+# - InPortConsumer
+# - Buffer
+#
+# OutPort に書き込まれたデータは OutPortPullConnector::write() に渡
+# され Buffer に書き込まれる。InPortPullConnector が
+# OutPortPullConnector からデータを読み出すことで InPort にデータが
+# 転送される。
+#
+# @since 1.0.0
+#
+# @else
+# @class OutPortPullConnector
+# @brief OutPortPullConnector class
+#
+# Connector class of OutPort for pull type dataflow. When "pull" is
+# specified as dataflow_type at the time of establishing
+# connection, this object is generated and owned by the OutPort.
+# This connector and InPortPullConnector make a pair and realize
+# pull type dataflow of data ports. One connector corresponds to
+# one connection which provides a data stream. Connector is
+# distinguished by ID of the UUID that is generated at establishing
+# connection.
+#
+# OutPortPullConnector owns and manages the following objects.
+#
+# - InPortConsumer
+# - Buffer
+#
+# Data written into the OutPort is passed to
+# OutPortPullConnector::write(), and it is written into the buffer.
+# By reading data from OutPortPullConnector to InPortPullConnector,
+# data transfer is realized.
+#
+# @since 1.0.0
+#
+# @endif
+#
+class OutPortPullConnector(OpenRTM_aist.OutPortConnector):
+ """
+ """
+
+ ##
+ # @if jp
+ # @brief コンストラクタ
+ #
+ # OutPortPullConnector のコンストラクタはオブジェクト生成時に下記
+ # を引数にとる。ConnectorInfo は接続情報を含み、この情報に従いバッ
+ # ファ等を生成する。OutPort インターフェースのプロバイダオブジェク
+ # トへのポインタを取り、所有権を持つので、OutPortPullConnector は
+ # OutPortProvider の解体責任を持つ。各種イベントに対するコールバッ
+ # ク機構を提供する ConnectorListeners を持ち、適切なタイミングでコー
+ # ルバックを呼び出す。データバッファがもし OutPortBase から提供さ
+ # れる場合はそのポインタを取る。
+ #
+ # @param info ConnectorInfo
+ # @param provider OutPortProvider
+ # @param listeners ConnectorListeners 型のリスナオブジェクトリスト
+ # @param buffer CdrBufferBase 型のバッファ
+ #
+ # @else
+ # @brief Constructor
+ #
+ # OutPortPullConnector's constructor is given the following
+ # arguments. According to ConnectorInfo which includes
+ # connection information, a buffer is created. It is also given
+ # a pointer to the provider object for the OutPort interface.
+ # The owner-ship of the pointer is owned by this
+ # OutPortPullConnector, it has responsibility to destruct the
+ # OutPortProvider. OutPortPullConnector also has
+ # ConnectorListeners to provide event callback mechanisms, and
+ # they would be called at the proper timing. If data buffer is
+ # given by OutPortBase, the pointer to the buffer is also given
+ # as arguments.
+ #
+ # @param info ConnectorInfo
+ # @param provider OutPortProvider
+ # @param listeners ConnectorListeners type lsitener object list
+ # @param buffer CdrBufferBase type buffer
+ #
+ # @endif
+ #
+ # OutPortPullConnector(ConnectorInfo info,
+ # OutPortProvider* provider,
+ # ConnectorListeners& listeners,
+ # CdrBufferBase* buffer = 0);
+ def __init__(self, info, provider, listeners, buffer = 0):
+ OpenRTM_aist.OutPortConnector.__init__(self, info)
+ self._provider = provider
+ self._listeners = listeners
+ self._buffer = buffer
+
+ if not self._buffer:
+ self._buffer = self.createBuffer(info)
+
+ if not self._provider or not self._buffer:
+ self._rtcout.RTC_ERROR("Exeption: in OutPortPullConnector.__init__().")
+ raise
+
+ self._buffer.init(info.properties.getNode("buffer"))
+ self._provider.setBuffer(self._buffer)
+ self._provider.setConnector(self)
+ self._provider.setListener(info, self._listeners)
+ self.onConnect()
+ return
+
+
+ ##
+ # @if jp
+ # @brief デストラクタ
+ #
+ # disconnect() が呼ばれ、provider, buffer が解体・削除される。
+ #
+ # @else
+ #
+ # @brief Destructor
+ #
+ # This operation calls disconnect(), which destructs and deletes
+ # the consumer, the publisher and the buffer.
+ #
+ # @endif
+ #
+ def __del__(self):
+ return
+
+
+ ##
+ # @if jp
+ # @brief データの書き込み
+ #
+ # Publisherに対してデータを書き込み、これにより対応するInPortへ
+ # データが転送される。
+ #
+ # @else
+ #
+ # @brief Writing data
+ #
+ # This operation writes data into publisher and then the data
+ # will be transferred to correspondent InPort.
+ #
+ # @endif
+ #
+ # virtual ReturnCode write(const cdrMemoryStream& data);
+ def write(self, data):
+ # data -> (conversion) -> CDR stream
+ cdr_data = None
+ if self._endian is not None:
+ cdr_data = cdrMarshal(any.to_any(data).typecode(), data, self._endian)
+ else:
+ self._rtcout.RTC_ERROR("write(): endian %s is not support.",self._endian)
+ return self.UNKNOWN_ERROR
+
+ self._buffer.write(cdr_data)
+ return self.PORT_OK
+
+
+ ##
+ # @if jp
+ # @brief 接続解除
+ #
+ # consumer, publisher, buffer が解体・削除される。
+ #
+ # @else
+ #
+ # @brief disconnect
+ #
+ # This operation destruct and delete the consumer, the publisher
+ # and the buffer.
+ #
+ # @endif
+ #
+ # virtual ReturnCode disconnect();
+ def disconnect(self):
+ self._rtcout.RTC_TRACE("disconnect()")
+ self.onDisconnect()
+ # delete provider
+ if self._provider:
+ OpenRTM_aist.OutPortProviderFactory.instance().deleteObject(self._provider)
+ self._provider = 0
+
+ # delete buffer
+ if self._buffer:
+ OpenRTM_aist.CdrBufferFactory.instance().deleteObject(self._buffer)
+ self._buffer = 0
+
+ return self.PORT_OK
+
+
+ ##
+ # @if jp
+ # @brief Buffer を取得する
+ #
+ # Connector が保持している Buffer を返す
+ #
+ # @else
+ # @brief Getting Buffer
+ #
+ # This operation returns this connector's buffer
+ #
+ # @endif
+ #
+ # virtual CdrBufferBase* getBuffer();
+ def getBuffer(self):
+ return self._buffer
+
+
+ ##
+ # @if jp
+ # @brief アクティブ化
+ #
+ # このコネクタをアクティブ化する
+ #
+ # @else
+ #
+ # @brief Connector activation
+ #
+ # This operation activates this connector
+ #
+ # @endif
+ #
+ # virtual void activate(){}; // do nothing
+ def activate(self): # do nothing
+ pass
+
+
+ ##
+ # @if jp
+ # @brief 非アクティブ化
+ #
+ # このコネクタを非アクティブ化する
+ #
+ # @else
+ #
+ # @brief Connector deactivation
+ #
+ # This operation deactivates this connector
+ #
+ # @endif
+ #
+ # virtual void deactivate(){}; // do nothing
+ def deactivate(self): # do nothing
+ pass
+
+
+ ##
+ # @if jp
+ # @brief Bufferの生成
+ # @else
+ # @brief create buffer
+ # @endif
+ #
+ # CdrBufferBase* createBuffer(ConnectorInfo& info);
+ def createBuffer(self, info):
+ buf_type = info.properties.getProperty("buffer_type","ring_buffer")
+ return OpenRTM_aist.CdrBufferFactory.instance().createObject(buf_type)
+
+
+ ##
+ # @if jp
+ # @brief 接続確立時にコールバックを呼ぶ
+ # @else
+ # @brief Invoke callback when connection is established
+ # @endif
+ # void onConnect()
+ def onConnect(self):
+ if self._listeners and self._profile:
+ self._listeners.connector_[OpenRTM_aist.ConnectorListenerType.ON_CONNECT].notify(self._profile)
+ return
+
+
+ ##
+ # @if jp
+ # @brief 接続切断時にコールバックを呼ぶ
+ # @else
+ # @brief Invoke callback when connection is destroied
+ # @endif
+ # void onDisconnect()
+ def onDisconnect(self):
+ if self._listeners and self._profile:
+ self._listeners.connector_[OpenRTM_aist.ConnectorListenerType.ON_DISCONNECT].notify(self._profile)
+ return
Modified: trunk/OpenRTM-aist-Python/OpenRTM_aist/OutPortPushConnector.py
===================================================================
--- trunk/OpenRTM-aist-Python/OpenRTM_aist/OutPortPushConnector.py 2016-02-01 05:29:04 UTC (rev 642)
+++ trunk/OpenRTM-aist-Python/OpenRTM_aist/OutPortPushConnector.py 2016-02-01 08:37:55 UTC (rev 643)
@@ -1,473 +1,428 @@
-#!/usr/bin/env python
-# -*- coding: euc-jp -*-
-
-
-##
-# @file OutPortPushConnector.py
-# @brief Push type connector class
-# @date $Date$
-# @author Noriaki Ando <n-ando at aist.go.jp> and Shinji Kurihara
-#
-# Copyright (C) 2009
-# Noriaki Ando
-# Task-intelligence Research Group,
-# Intelligent Systems Research Institute,
-# National Institute of
-# Advanced Industrial Science and Technology (AIST), Japan
-# All rights reserved.
-#
-
-from omniORB import *
-from omniORB import any
-
-import OpenRTM_aist
-
-
-##
-# @if jp
-# @class OutPortPushConnector
-# @brief OutPortPushConnector クラス
-#
-# OutPort の push 型データフローのための Connector クラス。このオブ
-# ジェクトは、接続時に dataflow_type に push が指定された場合、
-# OutPort によって生成・所有され、InPortPushConnector と対になって、
-# データポートの push 型のデータフローを実現する。一つの接続に対して、
-# 一つのデータストリームを提供する唯一の Connector が対応する。
-# Connector は 接続時に生成される UUID 形式の ID により区別される。
-#
-# OutPortPushConnector は以下の三つのオブジェクトを所有し管理する。
-#
-# - InPortConsumer
-# - Buffer
-# - Publisher
-#
-# OutPort に書き込まれたデータは OutPortPushConnector::write() に渡
-# され、Connector は Publisher にデータを書き込む。Publisher はその
-# 特性に従ってデータを Buffer から取得し InPortConsumer に対して
-# push することで InPort にデータが転送される。
-#
-# @since 1.0.0
-#
-# @else
-# @class OutPortPushConnector
-# @brief OutPortPushConnector class
-#
-# Connector class of OutPort for push type dataflow. When "push"
-# is specified as dataflow_type at the time of establishing
-# connection, this object is generated and owned by the OutPort.
-# This connector and InPortPushConnector make a pair and realize
-# push type dataflow of data ports. One connector corresponds to
-# one connection which provides a data stream. Connector is
-# distinguished by ID of the UUID that is generated at establishing
-# connection.
-#
-# OutPortPushConnector owns and manages the following objects.
-#
-# - InPortConsumer
-# - Buffer
-# - Publisher
-#
-# @since 1.0.0
-#
-# Data written into the OutPort is passed to
-# OutPortPushConnector::write(), and the connector writes into the
-# publisher. The publisher gets data from the buffer based on the
-# policy and it is transferred to InPort by pushing it into the
-# InPortConsumer.
-#
-# @endif
-#
-class OutPortPushConnector(OpenRTM_aist.OutPortConnector):
- """
- """
-
- ##
- # @if jp
- # @brief コンストラクタ
- #
- # OutPortPushConnector のコンストラクタはオブジェクト生成時に下記
- # を引数にとる。ConnectorInfo は接続情報を含み、この情報に従いパブ
- # リッシャやバッファ等を生成する。InPort インターフェースに対する
- # コンシューマオブジェクトへのポインタを取り、所有権を持つので、
- # OutPortPushConnector は InPortConsumer の解体責任を持つ。各種イ
- # ベントに対するコールバック機構を提供する ConnectorListeners を持
- # ち、適切なタイミングでコールバックを呼び出す。データバッファがも
- # し OutPortBase から提供される場合はそのポインタを取る。
- #
- # @param info ConnectorInfo
- # @param consumer InPortConsumer
- # @param listeners ConnectorListeners 型のリスナオブジェクトリスト
- # @param buffer CdrBufferBase 型のバッファ
- #
- # @else
- # @brief Constructor
- #
- # OutPortPushConnector's constructor is given the following
- # arguments. According to ConnectorInfo which includes
- # connection information, a publisher and a buffer are created.
- # It is also given a pointer to the consumer object for the
- # InPort interface. The owner-ship of the pointer is owned by
- # this OutPortPushConnector, it has responsibility to destruct
- # the InPortConsumer. OutPortPushConnector also has
- # ConnectorListeners to provide event callback mechanisms, and
- # they would be called at the proper timing. If data buffer is
- # given by OutPortBase, the pointer to the buffer is also given
- # as arguments.
- #
- # @param info ConnectorInfo
- # @param consumer InPortConsumer
- # @param listeners ConnectorListeners type lsitener object list
- # @param buffer CdrBufferBase type buffer
- #
- # @endif
- #
- # OutPortPushConnector(ConnectorInfo info,
- # InPortConsumer* consumer,
- # ConnectorListeners& listeners,
- # CdrBufferBase* buffer = 0);
- def __init__(self, info, consumer, listeners, buffer = 0):
- OpenRTM_aist.OutPortConnector.__init__(self, info)
-
- self._buffer = buffer
- self._consumer = consumer
- self._listeners = listeners
-
- self._directInPort = None
- self._inPortListeners = None
-
- # publisher/buffer creation. This may throw std::bad_alloc;
- self._publisher = self.createPublisher(info)
- if not self._buffer:
- self._buffer = self.createBuffer(info)
-
-
- if not self._publisher or not self._buffer or not self._consumer:
- raise
-
- if self._publisher.init(info.properties) != self.PORT_OK:
- raise
-
- if self._profile.properties.hasKey("serializer"):
- endian = self._profile.properties.getProperty("serializer.cdr.endian")
- if not endian:
- self._rtcout.RTC_ERROR("write(): endian is not set.")
- raise
-
- endian = OpenRTM_aist.split(endian, ",") # Maybe endian is ["little","big"]
- endian = OpenRTM_aist.normalize(endian) # Maybe self._endian is "little" or "big"
- if endian == "little":
- self._endian = True
- elif endian == "big":
- self._endian = False
- else:
- self._endian = None
-
- else:
- self._endian = True # little endian
-
- self._buffer.init(info.properties.getNode("buffer"))
- self._consumer.init(info.properties)
- self._publisher.setConsumer(self._consumer)
- self._publisher.setBuffer(self._buffer)
- self._publisher.setListener(self._profile, self._listeners)
-
- self.onConnect()
- return
-
-
- ##
- # @if jp
- # @brief デストラクタ
- #
- # disconnect() が呼ばれ、consumer, publisher, buffer が解体・削除される。
- #
- # @else
- #
- # @brief Destructor
- #
- # This operation calls disconnect(), which destructs and deletes
- # the consumer, the publisher and the buffer.
- #
- # @endif
- #
- def __del__(self):
- return
-
- ##
- # @if jp
- # @brief データの書き込み
- #
- # Publisherに対してデータを書き込み、これにより対応するInPortへデー
- # タが転送される。正常終了した場合 PORT_OK が返される。それ以外の
- # 場合、エラー値として、CONNECTION_LOST, BUFFER_FULL,
- # BUFFER_ERROR, PORT_ERROR, BUFFER_TIMEOUT, PRECONDITION_NO_MET が
- # 返される。
- #
- # @return PORT_OK 正常終了
- # CONNECTION_LOST 接続がロストした
- # BUFFER_FULL バッファが一杯である
- # BUFFER_ERROR バッファエラー
- # BUFFER_TIMEOUT バッファへの書き込みがタイムアウトした
- # PRECONDITION_NOT_MET 事前条件を満たさない
- # PORT_ERROR その他のエラー
- #
- # @else
- #
- # @brief Writing data
- #
- # This operation writes data into publisher and then the data
- # will be transferred to correspondent InPort. If data is written
- # properly, this function will return PORT_OK return code. Except
- # normal return, CONNECTION_LOST, BUFFER_FULL, BUFFER_ERROR,
- # PORT_ERROR, BUFFER_TIMEOUT and PRECONDITION_NO_MET will be
- # returned as error codes.
- #
- # @return PORT_OK Normal return
- # CONNECTION_LOST Connectin lost
- # BUFFER_FULL Buffer full
- # BUFFER_ERROR Buffer error
- # BUFFER_TIMEOUT Timeout
- # PRECONDITION_NOT_MET Precondition not met
- # PORT_ERROR Other error
- #
- # @endif
- #
- # template<class DataType>
- # virtual ReturnCode write(const DataType& data);
- def write(self, data):
- self._rtcout.RTC_TRACE("write()")
-
- if self._directInPort is not None:
- if self._directInPort.isNew():
- self._listeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_BUFFER_OVERWRITE].notify(self._profile, data)
- self._inPortListeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_BUFFER_OVERWRITE].notify(self._profile, data)
- self._listeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_RECEIVER_FULL].notify(self._profile, data)
- self._inPortListeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_RECEIVER_FULL].notify(self._profile, data)
- self._rtcout.RTC_TRACE("ONBUFFER_OVERWRITE(InPort,OutPort), ")
- self._rtcout.RTC_TRACE("ON_RECEIVER_FULL(InPort,OutPort) ")
- self._rtcout.RTC_TRACE("callback called in direct mode.")
- self._listeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_BUFFER_WRITE].notify(self._profile, data)
- self._inPortListeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_BUFFER_WRITE].notify(self._profile, data)
- self._rtcout.RTC_TRACE("ON_BUFFER_WRITE(InPort,OutPort), ")
- self._rtcout.RTC_TRACE("callback called in direct mode.")
- self._directInPort.write(data)
- self._listeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_RECEIVED].notify(self._profile, data)
- self._inPortListeners.connectorData_[OpenRTM_aist.ConnectorDataListenerType.ON_RECEIVED].notify(self._profile, data)
- self._rtcout.RTC_TRACE("ON_RECEIVED(InPort,OutPort), ")
- self._rtcout.RTC_TRACE("callback called in direct mode.")
- return self.PORT_OK
- # data -> (conversion) -> CDR stream
- cdr_data = None
- if self._endian is not None:
- cdr_data = cdrMarshal(any.to_any(data).typecode(), data, self._endian)
- else:
- self._rtcout.RTC_ERROR("write(): endian %s is not support.",self._endian)
- return self.UNKNOWN_ERROR
-
- return self._publisher.write(cdr_data, 0, 0)
-
-
- ##
- # @if jp
- # @brief 接続解除
- #
- # consumer, publisher, buffer が解体・削除される。
- #
- # @else
- #
- # @brief disconnect
- #
- # This operation destruct and delete the consumer, the publisher
- # and the buffer.
- #
- # @endif
- #
- # virtual ReturnCode disconnect();
- def disconnect(self):
- self._rtcout.RTC_TRACE("disconnect()")
- self.onDisconnect()
- # delete publisher
- if self._publisher:
- self._rtcout.RTC_DEBUG("delete publisher")
- pfactory = OpenRTM_aist.PublisherFactory.instance()
- pfactory.deleteObject(self._publisher)
-
- self._publisher = 0
-
- # delete consumer
- if self._consumer:
- self._rtcout.RTC_DEBUG("delete consumer")
- cfactory = OpenRTM_aist.InPortConsumerFactory.instance()
- cfactory.deleteObject(self._consumer)
-
- self._consumer = 0
-
- # delete buffer
- if self._buffer:
- self._rtcout.RTC_DEBUG("delete buffer")
- bfactory = OpenRTM_aist.CdrBufferFactory.instance()
- bfactory.deleteObject(self._buffer)
-
- self._buffer = 0
- self._rtcout.RTC_TRACE("disconnect() done")
-
- return self.PORT_OK
-
-
- ##
- # @if jp
- # @brief アクティブ化
- #
- # このコネクタをアクティブ化する
- #
- # @else
- #
- # @brief Connector activation
- #
- # This operation activates this connector
- #
- # @endif
- #
- # virtual void activate();
- def activate(self):
- self._publisher.activate()
- return
-
-
- ##
- # @if jp
- # @brief 非アクティブ化
- #
- # このコネクタを非アクティブ化する
- #
- # @else
- #
- # @brief Connector deactivation
- #
- # This operation deactivates this connector
- #
- # @endif
- #
- # virtual void deactivate();
- def deactivate(self):
- self._publisher.deactivate()
- return
-
-
- ##
- # @if jp
- # @brief Buffer を取得する
- #
- # Connector が保持している Buffer を返す
- #
- # @else
- # @brief Getting Buffer
- #
- # This operation returns this connector's buffer
- #
- # @endif
- #
- # virtual CdrBufferBase* getBuffer();
- def getBuffer(self):
- return self._buffer
-
-
- ##
- # @if jp
- # @brief Publisherの生成
- #
- # 与えられた接続情報に基づきパブリッシャを生成する。
- #
- # @param info 接続情報
- # @return パブリッシャへのポインタ
- #
- # @else
- # @brief create buffer
- #
- # This function creates a publisher based on given information.
- #
- # @param info Connector information
- # @return The poitner to the publisher
- #
- # @endif
- #
- # virtual PublisherBase* createPublisher(ConnectorInfo& info);
- def createPublisher(self, info):
- pub_type = info.properties.getProperty("subscription_type","flush")
- pub_type = OpenRTM_aist.normalize([pub_type])
- return OpenRTM_aist.PublisherFactory.instance().createObject(pub_type)
-
-
- ##
- # @if jp
- # @brief Bufferの生成
- #
- # 与えられた接続情報に基づきバッファを生成する。
- #
- # @param info 接続情報
- # @return バッファへのポインタ
- #
- # @else
- # @brief create buffer
- #
- # This function creates a buffer based on given information.
- #
- # @param info Connector information
- # @return The poitner to the buffer
- #
- # @endif
- #
- # virtual CdrBufferBase* createBuffer(ConnectorInfo& info);
- def createBuffer(self, info):
- buf_type = info.properties.getProperty("buffer_type",
- "ring_buffer")
-
- return OpenRTM_aist.CdrBufferFactory.instance().createObject(buf_type)
-
-
- ##
- # @if jp
- # @brief 接続確立時にコールバックを呼ぶ
- # @else
- # @brief Invoke callback when connection is established
- # @endif
- # void onConnect()
- def onConnect(self):
- if self._listeners and self._profile:
- self._listeners.connector_[OpenRTM_aist.ConnectorListenerType.ON_CONNECT].notify(self._profile)
- return
-
- ##
- # @if jp
- # @brief 接続切断時にコールバックを呼ぶ
- # @else
- # @brief Invoke callback when connection is destroied
- # @endif
- # void onDisconnect()
- def onDisconnect(self):
- if self._listeners and self._profile:
- self._listeners.connector_[OpenRTM_aist.ConnectorListenerType.ON_DISCONNECT].notify(self._profile)
- return
-
- ##
- # @if jp
- # @brief データをダイレクトに書き込むためのInPortのサーバントを設定する
- #
- # @param self
- # @param directInPort InPortのサーバント
- # @return True: 設定に成功 False: 既に設定済みのため失敗
- # @else
- # @brief
- #
- # @param self
- # @param directInPort
- # @return
- # @endif
- #
- # bool setInPort(InPortBase* directInPort);
- def setInPort(self, directInPort):
- if self._directInPort is not None:
- return False
- self._directInPort = directInPort
- self._inPortListeners = self._directInPort._listeners
- return True
\ No newline at end of file
+#!/usr/bin/env python
+# -*- coding: euc-jp -*-
+
+
+##
+# @file OutPortPushConnector.py
+# @brief Push type connector class
+# @date $Date$
+# @author Noriaki Ando <n-ando at aist.go.jp> and Shinji Kurihara
+#
+# Copyright (C) 2009
+# Noriaki Ando
+# Task-intelligence Research Group,
+# Intelligent Systems Research Institute,
+# National Institute of
+# Advanced Industrial Science and Technology (AIST), Japan
+# All rights reserved.
+#
+
+from omniORB import *
+from omniORB import any
+
+import OpenRTM_aist
+
+
+##
+# @if jp
+# @class OutPortPushConnector
+# @brief OutPortPushConnector クラス
+#
+# OutPort の push 型データフローのための Connector クラス。このオブ
+# ジェクトは、接続時に dataflow_type に push が指定された場合、
+# OutPort によって生成・所有され、InPortPushConnector と対になって、
+# データポートの push 型のデータフローを実現する。一つの接続に対して、
+# 一つのデータストリームを提供する唯一の Connector が対応する。
+# Connector は 接続時に生成される UUID 形式の ID により区別される。
+#
+# OutPortPushConnector は以下の三つのオブジェクトを所有し管理する。
+#
+# - InPortConsumer
+# - Buffer
+# - Publisher
+#
+# OutPort に書き込まれたデータは OutPortPushConnector::write() に渡
+# され、Connector は Publisher にデータを書き込む。Publisher はその
+# 特性に従ってデータを Buffer から取得し InPortConsumer に対して
+# push することで InPort にデータが転送される。
+#
+# @since 1.0.0
+#
+# @else
+# @class OutPortPushConnector
+# @brief OutPortPushConnector class
+#
+# Connector class of OutPort for push type dataflow. When "push"
+# is specified as dataflow_type at the time of establishing
+# connection, this object is generated and owned by the OutPort.
+# This connector and InPortPushConnector make a pair and realize
+# push type dataflow of data ports. One connector corresponds to
+# one connection which provides a data stream. Connector is
+# distinguished by ID of the UUID that is generated at establishing
+# connection.
+#
+# OutPortPushConnector owns and manages the following objects.
+#
+# - InPortConsumer
+# - Buffer
+# - Publisher
+#
+# @since 1.0.0
+#
+# Data written into the OutPort is passed to
+# OutPortPushConnector::write(), and the connector writes into the
+# publisher. The publisher gets data from the buffer based on the
+# policy and it is transferred to InPort by pushing it into the
+# InPortConsumer.
+#
+# @endif
+#
+class OutPortPushConnector(OpenRTM_aist.OutPortConnector):
+ """
+ """
+
+ ##
+ # @if jp
+ # @brief コンストラクタ
+ #
+ # OutPortPushConnector のコンストラクタはオブジェクト生成時に下記
+ # を引数にとる。ConnectorInfo は接続情報を含み、この情報に従いパブ
+ # リッシャやバッファ等を生成する。InPort インターフェースに対する
+ # コンシューマオブジェクトへのポインタを取り、所有権を持つので、
+ # OutPortPushConnector は InPortConsumer の解体責任を持つ。各種イ
+ # ベントに対するコールバック機構を提供する ConnectorListeners を持
+ # ち、適切なタイミングでコールバックを呼び出す。データバッファがも
+ # し OutPortBase から提供される場合はそのポインタを取る。
+ #
+ # @param info ConnectorInfo
+ # @param consumer InPortConsumer
+ # @param listeners ConnectorListeners 型のリスナオブジェクトリスト
+ # @param buffer CdrBufferBase 型のバッファ
+ #
+ # @else
+ # @brief Constructor
+ #
+ # OutPortPushConnector's constructor is given the following
+ # arguments. According to ConnectorInfo which includes
+ # connection information, a publisher and a buffer are created.
+ # It is also given a pointer to the consumer object for the
+ # InPort interface. The owner-ship of the pointer is owned by
+ # this OutPortPushConnector, it has responsibility to destruct
+ # the InPortConsumer. OutPortPushConnector also has
+ # ConnectorListeners to provide event callback mechanisms, and
+ # they would be called at the proper timing. If data buffer is
+ # given by OutPortBase, the pointer to the buffer is also given
+ # as arguments.
+ #
+ # @param info ConnectorInfo
+ # @param consumer InPortConsumer
+ # @param listeners ConnectorListeners type lsitener object list
+ # @param buffer CdrBufferBase type buffer
+ #
+ # @endif
+ #
+ # OutPortPushConnector(ConnectorInfo info,
+ # InPortConsumer* consumer,
+ # ConnectorListeners& listeners,
+ # CdrBufferBase* buffer = 0);
+ def __init__(self, info, consumer, listeners, buffer = 0):
+ OpenRTM_aist.OutPortConnector.__init__(self, info)
+
+ self._buffer = buffer
+ self._consumer = consumer
+ self._listeners = listeners
+
+ # publisher/buffer creation. This may throw std::bad_alloc;
+ self._publisher = self.createPublisher(info)
+ if not self._buffer:
+ self._buffer = self.createBuffer(info)
+
+
+ if not self._publisher or not self._buffer or not self._consumer:
+ raise
+
+ if self._publisher.init(info.properties) != self.PORT_OK:
+ raise
+
+ if self._profile.properties.hasKey("serializer"):
+ endian = self._profile.properties.getProperty("serializer.cdr.endian")
+ if not endian:
+ self._rtcout.RTC_ERROR("write(): endian is not set.")
+ raise
+
+ endian = OpenRTM_aist.split(endian, ",") # Maybe endian is ["little","big"]
+ endian = OpenRTM_aist.normalize(endian) # Maybe self._endian is "little" or "big"
+ if endian == "little":
+ self._endian = True
+ elif endian == "big":
+ self._endian = False
+ else:
+ self._endian = None
+
+ else:
+ self._endian = True # little endian
+
+ self._buffer.init(info.properties.getNode("buffer"))
+ self._consumer.init(info.properties)
+ self._publisher.setConsumer(self._consumer)
+ self._publisher.setBuffer(self._buffer)
+ self._publisher.setListener(self._profile, self._listeners)
+
+ self.onConnect()
+ return
+
+
+ ##
+ # @if jp
+ # @brief デストラクタ
+ #
+ # disconnect() が呼ばれ、consumer, publisher, buffer が解体・削除される。
+ #
+ # @else
+ #
+ # @brief Destructor
+ #
+ # This operation calls disconnect(), which destructs and deletes
+ # the consumer, the publisher and the buffer.
+ #
+ # @endif
+ #
+ def __del__(self):
+ return
+
+ ##
+ # @if jp
+ # @brief データの書き込み
+ #
+ # Publisherに対してデータを書き込み、これにより対応するInPortへデー
+ # タが転送される。正常終了した場合 PORT_OK が返される。それ以外の
+ # 場合、エラー値として、CONNECTION_LOST, BUFFER_FULL,
+ # BUFFER_ERROR, PORT_ERROR, BUFFER_TIMEOUT, PRECONDITION_NO_MET が
+ # 返される。
+ #
+ # @return PORT_OK 正常終了
+ # CONNECTION_LOST 接続がロストした
+ # BUFFER_FULL バッファが一杯である
+ # BUFFER_ERROR バッファエラー
+ # BUFFER_TIMEOUT バッファへの書き込みがタイムアウトした
+ # PRECONDITION_NOT_MET 事前条件を満たさない
+ # PORT_ERROR その他のエラー
+ #
+ # @else
+ #
+ # @brief Writing data
+ #
+ # This operation writes data into publisher and then the data
+ # will be transferred to correspondent InPort. If data is written
+ # properly, this function will return PORT_OK return code. Except
+ # normal return, CONNECTION_LOST, BUFFER_FULL, BUFFER_ERROR,
+ # PORT_ERROR, BUFFER_TIMEOUT and PRECONDITION_NO_MET will be
+ # returned as error codes.
+ #
+ # @return PORT_OK Normal return
+ # CONNECTION_LOST Connectin lost
+ # BUFFER_FULL Buffer full
+ # BUFFER_ERROR Buffer error
+ # BUFFER_TIMEOUT Timeout
+ # PRECONDITION_NOT_MET Precondition not met
+ # PORT_ERROR Other error
+ #
+ # @endif
+ #
+ # template<class DataType>
+ # virtual ReturnCode write(const DataType& data);
+ def write(self, data):
+ self._rtcout.RTC_TRACE("write()")
+
+ # data -> (conversion) -> CDR stream
+ cdr_data = None
+ if self._endian is not None:
+ cdr_data = cdrMarshal(any.to_any(data).typecode(), data, self._endian)
+ else:
+ self._rtcout.RTC_ERROR("write(): endian %s is not support.",self._endian)
+ return self.UNKNOWN_ERROR
+
+ return self._publisher.write(cdr_data, 0, 0)
+
+
+ ##
+ # @if jp
+ # @brief 接続解除
+ #
+ # consumer, publisher, buffer が解体・削除される。
+ #
+ # @else
+ #
+ # @brief disconnect
+ #
+ # This operation destruct and delete the consumer, the publisher
+ # and the buffer.
+ #
+ # @endif
+ #
+ # virtual ReturnCode disconnect();
+ def disconnect(self):
+ self._rtcout.RTC_TRACE("disconnect()")
+ self.onDisconnect()
+ # delete publisher
+ if self._publisher:
+ self._rtcout.RTC_DEBUG("delete publisher")
+ pfactory = OpenRTM_aist.PublisherFactory.instance()
+ pfactory.deleteObject(self._publisher)
+
+ self._publisher = 0
+
+ # delete consumer
+ if self._consumer:
+ self._rtcout.RTC_DEBUG("delete consumer")
+ cfactory = OpenRTM_aist.InPortConsumerFactory.instance()
+ cfactory.deleteObject(self._consumer)
+
+ self._consumer = 0
+
+ # delete buffer
+ if self._buffer:
+ self._rtcout.RTC_DEBUG("delete buffer")
+ bfactory = OpenRTM_aist.CdrBufferFactory.instance()
+ bfactory.deleteObject(self._buffer)
+
+ self._buffer = 0
+ self._rtcout.RTC_TRACE("disconnect() done")
+
+ return self.PORT_OK
+
+
+ ##
+ # @if jp
+ # @brief アクティブ化
+ #
+ # このコネクタをアクティブ化する
+ #
+ # @else
+ #
+ # @brief Connector activation
+ #
+ # This operation activates this connector
+ #
+ # @endif
+ #
+ # virtual void activate();
+ def activate(self):
+ self._publisher.activate()
+ return
+
+
+ ##
+ # @if jp
+ # @brief 非アクティブ化
+ #
+ # このコネクタを非アクティブ化する
+ #
+ # @else
+ #
+ # @brief Connector deactivation
+ #
+ # This operation deactivates this connector
+ #
+ # @endif
+ #
+ # virtual void deactivate();
+ def deactivate(self):
+ self._publisher.deactivate()
+ return
+
+
+ ##
+ # @if jp
+ # @brief Buffer を取得する
+ #
+ # Connector が保持している Buffer を返す
+ #
+ # @else
+ # @brief Getting Buffer
+ #
+ # This operation returns this connector's buffer
+ #
+ # @endif
+ #
+ # virtual CdrBufferBase* getBuffer();
+ def getBuffer(self):
+ return self._buffer
+
+
+ ##
+ # @if jp
+ # @brief Publisherの生成
+ #
+ # 与えられた接続情報に基づきパブリッシャを生成する。
+ #
+ # @param info 接続情報
+ # @return パブリッシャへのポインタ
+ #
+ # @else
+ # @brief create buffer
+ #
+ # This function creates a publisher based on given information.
+ #
+ # @param info Connector information
+ # @return The poitner to the publisher
+ #
+ # @endif
+ #
+ # virtual PublisherBase* createPublisher(ConnectorInfo& info);
+ def createPublisher(self, info):
+ pub_type = info.properties.getProperty("subscription_type","flush")
+ pub_type = OpenRTM_aist.normalize([pub_type])
+ return OpenRTM_aist.PublisherFactory.instance().createObject(pub_type)
+
+
+ ##
+ # @if jp
+ # @brief Bufferの生成
+ #
+ # 与えられた接続情報に基づきバッファを生成する。
+ #
+ # @param info 接続情報
+ # @return バッファへのポインタ
+ #
+ # @else
+ # @brief create buffer
+ #
+ # This function creates a buffer based on given information.
+ #
+ # @param info Connector information
+ # @return The poitner to the buffer
+ #
+ # @endif
+ #
+ # virtual CdrBufferBase* createBuffer(ConnectorInfo& info);
+ def createBuffer(self, info):
+ buf_type = info.properties.getProperty("buffer_type",
+ "ring_buffer")
+
+ return OpenRTM_aist.CdrBufferFactory.instance().createObject(buf_type)
+
+
+ ##
+ # @if jp
+ # @brief 接続確立時にコールバックを呼ぶ
+ # @else
+ # @brief Invoke callback when connection is established
+ # @endif
+ # void onConnect()
+ def onConnect(self):
+ if self._listeners and self._profile:
+ self._listeners.connector_[OpenRTM_aist.ConnectorListenerType.ON_CONNECT].notify(self._profile)
+ return
+
+ ##
+ # @if jp
+ # @brief 接続切断時にコールバックを呼ぶ
+ # @else
+ # @brief Invoke callback when connection is destroied
+ # @endif
+ # void onDisconnect()
+ def onDisconnect(self):
+ if self._listeners and self._profile:
+ self._listeners.connector_[OpenRTM_aist.ConnectorListenerType.ON_DISCONNECT].notify(self._profile)
+ return
Deleted: trunk/OpenRTM-aist-Python/OpenRTM_aist/OutPortSHMConsumer.py
===================================================================
--- trunk/OpenRTM-aist-Python/OpenRTM_aist/OutPortSHMConsumer.py 2016-02-01 05:29:04 UTC (rev 642)
+++ trunk/OpenRTM-aist-Python/OpenRTM_aist/OutPortSHMConsumer.py 2016-02-01 08:37:55 UTC (rev 643)
@@ -1,183 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: euc-jp -*-
-
-
-##
-# @file OutPortSHMProvider.py
-# @brief OutPortSHMProvider class
-# @date $Date: 2016-01-12 $
-# @author Nobuhiko Miyamoto
-#
-#
-
-import sys
-from omniORB import any
-import OpenRTM_aist
-import OpenRTM
-
-import mmap
-from omniORB import cdrUnmarshal
-import CORBA
-
-##
-# @if jp
-# @class OutPortSHMConsumer
-#
-# @brief OutPortSHMConsumer クラス
-#
-# 通信手段に 共有メモリ を利用した出力ポートプロバイダーの実装クラス。
-#
-#
-# @else
-# @class OutPortSHMConsumer
-#
-# @brief OutPortSHMConsumer class
-#
-#
-# @endif
-#
-class OutPortSHMConsumer(OpenRTM_aist.OutPortCorbaCdrConsumer):
- """
- """
-
- ##
- # @if jp
- # @brief コンストラクタ
- #
- # コンストラクタ
- #
- # @else
- # @brief Constructor
- #
- # Constructor
- #
- # @endif
- #
- def __init__(self):
- OpenRTM_aist.OutPortCorbaCdrConsumer.__init__(self)
- self._rtcout = OpenRTM_aist.Manager.instance().getLogbuf("OutPortSHMConsumer")
-
- self._shmem = None
- return
-
- ##
- # @if jp
- # @brief デストラクタ
- #
- # デストラクタ
- #
- # @else
- # @brief Destructor
- #
- # Destructor
- #
- # @endif
- #
- def __del__(self, CorbaConsumer=OpenRTM_aist.CorbaConsumer):
- self._rtcout.RTC_PARANOID("~OutPortSHMConsumer()")
- CorbaConsumer.__del__(self)
-
- pass
-
-
- ##
- # @if jp
- # @brief 設定初期化
- #
- # OutPortConsumerの各種設定を行う
- #
- # @param self
- # @param prop コネクタプロパティ
- #
- # @else
- # @brief Initializing configuration
- #
- #
- # @endif
- #
- # virtual void init(coil::Properties& prop);
- def init(self, prop):
- self._rtcout.RTC_TRACE("init()")
-
- self._properties = prop
- self.shm_address = prop.getProperty("shared_memory.address")
-
- return
-
-
-
-
-
- ##
- # @if jp
- # @brief データを読み出す
- #
- # 設定されたデータを読み出す。
- #
- # CORBAでデータサイズだけ送受信して、データは共有メモリから読み込む
- #
- # @param data 読み出したデータを受け取るオブジェクト
- #
- # @return リターンコード
- #
- # @else
- # @brief Read data
- #
- # Read set data
- #
- # @param data Object to receive the read data
- #
- # @return Return Code
- #
- # @endif
- #
- # virtual ReturnCode get(cdrMemoryStream& data);
- def get(self, data):
- self._rtcout.RTC_PARANOID("get()")
-
- try:
- outportcdr = self.getObject()._narrow(OpenRTM.OutPortCdr)
- ret,cdr_data = outportcdr.get()
-
- if ret == OpenRTM.PORT_OK:
- self._rtcout.RTC_DEBUG("get() successful")
-
- data_size = cdrUnmarshal(CORBA.TC_ushort, cdr_data)
- self._shmem = mmap.mmap(0, data_size, self.shm_address, mmap.ACCESS_READ)
- shm_data = self._shmem.read(data_size)
-
-
- data[0] = shm_data
- self.onReceived(data[0])
- self.onBufferWrite(data[0])
-
- if self._buffer.full():
- self._rtcout.RTC_INFO("InPort buffer is full.")
- self.onBufferFull(data[0])
- self.onReceiverFull(data[0])
-
- self._buffer.put(data[0])
- self._buffer.advanceWptr()
- self._buffer.advanceRptr()
-
- return self.PORT_OK
- return self.convertReturn(ret,data[0])
-
- except:
- self._rtcout.RTC_WARN("Exception caught from OutPort.get().")
- self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
- return self.CONNECTION_LOST
-
- self._rtcout.RTC_ERROR("get(): Never comes here.")
- return self.UNKNOWN_ERROR
-
-
-
-
-
-def OutPortSHMConsumerInit():
- factory = OpenRTM_aist.OutPortConsumerFactory.instance()
- factory.addFactory("shared_memory",
- OpenRTM_aist.OutPortSHMConsumer,
- OpenRTM_aist.Delete)
- return
Deleted: trunk/OpenRTM-aist-Python/OpenRTM_aist/OutPortSHMProvider.py
===================================================================
--- trunk/OpenRTM-aist-Python/OpenRTM_aist/OutPortSHMProvider.py 2016-02-01 05:29:04 UTC (rev 642)
+++ trunk/OpenRTM-aist-Python/OpenRTM_aist/OutPortSHMProvider.py 2016-02-01 08:37:55 UTC (rev 643)
@@ -1,154 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: euc-jp -*-
-
-##
-# @file OutPortSHMProvider.py
-# @brief OutPortSHMProvider class
-# @date $Date: 2016-01-12 $
-# @author Nobuhiko Miyamoto
-#
-#
-
-import sys
-from omniORB import *
-from omniORB import any
-
-import OpenRTM_aist
-import OpenRTM__POA,OpenRTM
-import mmap, os
-from omniORB import cdrMarshal
-import CORBA
-
-##
-# @if jp
-# @class OutPortSHMProvider
-# @brief OutPortSHMProvider クラス
-#
-# OutPortProvider
-#
-# 通信手段に 共有メモリ を利用した出力ポートプロバイダの実装クラス。
-#
-#
-# @else
-# @class OutPortSHMProvider
-# @brief OutPortSHMProvider class
-#
-#
-#
-# @endif
-#
-class OutPortSHMProvider(OpenRTM_aist.OutPortCorbaCdrProvider):
- ##
- # @if jp
- # @brief コンストラクタ
- # 共有メモリの空間名はUUIDで作成し、コネクタプロファイルのdataport.shared_memory.addressに保存する
- #
- # コンストラクタ
- #
- # @else
- # @brief Constructor
- #
- # Constructor
- #
- # @endif
- #
- def __init__(self):
- OpenRTM_aist.OutPortCorbaCdrProvider.__init__(self)
- self.setInterfaceType("shared_memory")
-
- self.shm_address = str(OpenRTM_aist.uuid1())
-
- self._properties.append(OpenRTM_aist.NVUtil.newNV("dataport.shared_memory.address",self.shm_address))
-
- self._shmem = mmap.mmap(0, 256, self.shm_address, mmap.ACCESS_WRITE)
-
-
-
- return
-
-
- ##
- # @if jp
- # @brief デストラクタ
- #
- # デストラクタ
- #
- # @else
- # @brief Destructor
- #
- # Destructor
- #
- # @endif
- #
- def __del__(self):
- oid = self._default_POA().servant_to_id(self)
- self._default_POA().deactivate_object(oid)
-
- self._shmem.close()
- return
-
-
-
- # virtual void init(coil::Properties& prop);
- def init(self, prop):
- pass
-
-
-
- ##
- # @if jp
- # @brief バッファからデータを取得する
- #
- # @return (リターンコード、取得データ)
- #
- # @else
- # @brief Get data from the buffer
- #
- #
- # @return
- #
- # @endif
- #
- # virtual ::OpenRTM::PortStatus get(::OpenRTM::CdrData_out data);
- def get(self):
- self._rtcout.RTC_PARANOID("OutPortSHMProvider.get()")
- if not self._buffer:
- self.onSenderError()
- return (OpenRTM.UNKNOWN_ERROR, None)
-
- try:
- if self._buffer.empty():
- self._rtcout.RTC_ERROR("buffer is empty.")
- return (OpenRTM.BUFFER_EMPTY, None)
-
- cdr = [None]
- ret = self._buffer.read(cdr)
-
- if ret == OpenRTM_aist.BufferStatus.BUFFER_OK:
- if not cdr:
- self._rtcout.RTC_ERROR("buffer is empty.")
- return (OpenRTM.BUFFER_EMPTY, None)
-
- except:
- self._rtcout.RTC_TRACE(OpenRTM_aist.Logger.print_exception())
- return (OpenRTM.UNKNOWN_ERROR, None)
-
- self._shmem.seek(os.SEEK_SET)
- self._shmem.write(cdr[0])
-
-
- data_size = len(cdr[0])
- mar_data_size = cdrMarshal(CORBA.TC_ushort, data_size)
-
-
-
- return self.convertReturn(ret, mar_data_size)
-
-
-
-
-def OutPortSHMProviderInit():
- factory = OpenRTM_aist.OutPortProviderFactory.instance()
- factory.addFactory("shared_memory",
- OpenRTM_aist.OutPortSHMProvider,
- OpenRTM_aist.Delete)
Modified: trunk/OpenRTM-aist-Python/OpenRTM_aist/PortBase.py
===================================================================
--- trunk/OpenRTM-aist-Python/OpenRTM_aist/PortBase.py 2016-02-01 05:29:04 UTC (rev 642)
+++ trunk/OpenRTM-aist-Python/OpenRTM_aist/PortBase.py 2016-02-01 08:37:55 UTC (rev 643)
@@ -1,2516 +1,2515 @@
-#!/usr/bin/env python
-# -*- coding: euc-jp -*-
-
-##
-# @file PortBase.py
-# @brief RTC's Port base class
-# @date $Date: 2007/09/18 $
-# @author Noriaki Ando <n-ando at aist.go.jp> and Shinji Kurihara
-#
-# Copyright (C) 2006-2008
-# Task-intelligence Research Group,
-# Intelligent Systems Research Institute,
-# National Institute of
-# Advanced Industrial Science and Technology (AIST), Japan
-# All rights reserved.
-
-
-import threading
-import copy
-
-import OpenRTM_aist
-import RTC, RTC__POA
-
-
-
-##
-# @if jp
-# @class PortBase
-# @brief Port の基底クラス
-#
-# RTC::Port の基底となるクラス。
-# RTC::Port はほぼ UML Port の概念を継承しており、ほぼ同等のものとみなす
-# ことができる。RT コンポーネントのコンセプトにおいては、
-# Port はコンポーネントに付属し、コンポーネントが他のコンポーネントと相互作用
-# を行う接点であり、通常幾つかのインターフェースと関連付けられる。
-# コンポーネントは Port を通して外部に対しインターフェースを提供または要求
-# することができ、Portはその接続を管理する役割を担う。
-# <p>
-# Port の具象クラスは、通常 RT コンポーネントインスタンス生成時に同時に
-# 生成され、提供・要求インターフェースを登録した後、RT コンポーネントに
-# 登録され、外部からアクセス可能な Port として機能することを想定している。
-# <p>
-# RTC::Port は CORBA インターフェースとして以下のオペレーションを提供する。
-#
-# - get_port_profile()
-# - get_connector_profiles()
-# - get_connector_profile()
-# - connect()
-# - notify_connect()
-# - disconnect()
-# - notify_disconnect()
-# - disconnect_all()
-#
-# このクラスでは、これらのオペレーションの実装を提供する。
-# <p>
-# これらのオペレーションのうち、get_port_profile(), get_connector_profiles(),
-# get_connector_profile(), connect(), disconnect(), disconnect_all() は、
-# サブクラスにおいて特に振る舞いを変更する必要がないため、オーバーライド
-# することは推奨されない。
-# <p>
-# notify_connect(), notify_disconnect() については、サブクラスが提供・要求
-# するインターフェースの種類に応じて、振る舞いを変更する必要が生ずる
-# かもしれないが、これらを直接オーバーライドすることは推奨されず、
-# 後述の notify_connect(), notify_disconnect() の項においても述べられる通り
-# これらの関数に関連した 関数をオーバーライドすることにより振る舞いを変更する
-# ことが推奨される。
-#
-# @since 0.4.0
-#
-# @else
-# @class PortBase
-# @brief Port base class
-#
-# This class is a base class of RTC::Port.
-# RTC::Port inherits a concept of RT-Component, and can be regarded as almost
-# the same as it. In the concept of RT-Component, Port is attached to the
-# component, can mediate interaction between other components and usually is
-# associated with some interfaces.
-# Component can provide or require interface for outside via Port, and the
-# Port plays a role to manage the connection.
-# <p>
-# Concrete class of Port assumes to be usually created at the same time that
-# RT-Component's instance is created, be registerd to RT-Component after
-# provided and required interfaces are registerd, and function as accessible
-# Port from outside.
-# <p>
-# RTC::Port provides the following operations as CORBA interface:
-#
-# - get_port_profile()
-# - get_connector_profiles()
-# - get_connector_profile()
-# - connect()
-# - notify_connect()
-# - disconnect()
-# - notify_disconnect()
-# - disconnect_all()
-#
-# This class provides implementations of these operations.
-# <p>
-# In these operations, as for get_port_profile(), get_connector_profiles(),
-# get_connector_profile(), connect(), disconnect() and disconnect_all(),
-# since their behaviors especially need not to be change in subclass,
-# overriding is not recommended.
-# <p>
-# As for notify_connect() and notify_disconnect(), you may have to modify
-# behavior according to the kind of interfaces that subclass provides and
-# requires, however it is not recommended these are overriden directly.
-# In the section of notify_connect() and notify_disconnect() as described
-# below, it is recommended that you modify behavior by overriding the
-# protected function related to these functions.
-#
-# @since 0.4.0
-#
-# @endif
-class PortBase(RTC__POA.PortService):
- """
- """
-
-
-
- ##
- # @if jp
- # @brief コンストラクタ
- #
- # PortBase のコンストラクタは Port 名 name を引数に取り初期化を行う
- # と同時に、自分自身を CORBA Object として活性化し、自身の PortProfile
- # の port_ref に自身のオブジェクトリファレンスを格納する。
- # 名前には、"." 以外の文字列を使用することができる。
- #
- # @param self
- # @param name Port の名前(デフォルト値:None)
- #
- # @else
- #
- # @brief Constructor
- #
- # The constructor of the ProtBase class is given the name of this Port
- # and initialized. At the same time, the PortBase activates itself
- # as CORBA object and stores its object reference to the PortProfile's
- # port_ref member.
- # Characters except "." can be used for the name of the port.
- #
- # @param name The name of Port
- #
- # @endif
- def __init__(self, name=None):
- self._ownerInstanceName = "unknown"
- self._objref = self._this()
-
- self._profile = RTC.PortProfile("", [], RTC.PortService._nil, [], RTC.RTObject._nil,[])
- # Now Port name is <instance_name>.<port_name>. r1648
- if name is None:
- self._profile.name = "unknown.unknown"
- else:
- self._profile.name = self._ownerInstanceName+"."+name
-
- self._profile.port_ref = self._objref
- self._profile.owner = RTC.RTObject._nil
- self._profile_mutex = threading.RLock()
- self._connection_mutex = threading.RLock()
- self._rtcout = OpenRTM_aist.Manager.instance().getLogbuf(name)
- self._onPublishInterfaces = None
- self._onSubscribeInterfaces = None
- self._onConnected = None
- self._onUnsubscribeInterfaces = None
- self._onDisconnected = None
- self._onConnectionLost = None
- self._connectionLimit = -1
- self._portconnListeners = None
- return
-
-
- ##
- # @if jp
- #
- # @brief デストラクタ
- #
- # デストラクタでは、PortService CORBA オブジェクトの deactivate を
- # 行う。deactivateに際して例外を投げることはない。
- #
- # @else
- #
- # @brief Destructor
- #
- # In the destructor, PortService CORBA object is deactivated.
- # This function never throws exception.
- #
- # @endif
- #
- def __del__(self):
- self._rtcout.RTC_TRACE("PortBase.__del__()")
- try:
- mgr = OpenRTM_aist.Manager.instance().getPOA()
- oid = mgr.servant_to_id(self)
- mgr.deactivate_object(oid)
- except:
- self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
-
-
- ##
- # @if jp
- #
- # @brief [CORBA interface] PortProfileを取得する
- #
- # Portが保持するPortProfileを返す。
- # PortProfile 構造体は以下のメンバーを持つ。
- #
- # - name [string 型] Port の名前。
- # - interfaces [PortInterfaceProfileList 型] Port が保持する
- # PortInterfaceProfile のシーケンス
- # - port_ref [Port Object 型] Port 自身のオブジェクトリファレンス
- # - connector_profile [ConnectorProfileList 型] Port が現在保持する
- # ConnectorProfile のシーケンス
- # - owner [RTObject Object 型] この Port を所有する
- # RTObjectのリファレンス
- # - properties [NVList 型] その他のプロパティ。
- #
- # @param self
- #
- # @return PortProfile
- #
- # @else
- #
- # @brief [CORBA interface] Get the PortProfile of the Port
- #
- # This operation returns the PortProfile of the Port.
- # PortProfile struct has the following members,
- #
- # - name [string ] The name of the Port.
- # - interfaces [PortInterfaceProfileList] The sequence of
- # PortInterfaceProfile owned by the Port
- # - port_ref [Port Object] The object reference of the Port.
- # - connector_profile [ConnectorProfileList] The sequence of
- # ConnectorProfile owned by the Port.
- # - owner [RTObject Object] The object reference of
- # RTObject that is owner of the Port.
- # - properties [NVList] The other properties.
- #
- # @return the PortProfile of the Port
- #
- # @endif
- # PortProfile* get_port_profile()
- def get_port_profile(self):
- self._rtcout.RTC_TRACE("get_port_profile()")
-
- self.updateConnectors()
-
- guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
-
- prof = RTC.PortProfile(self._profile.name,
- self._profile.interfaces,
- self._profile.port_ref,
- self._profile.connector_profiles,
- self._profile.owner,
- self._profile.properties)
-
- return prof
-
-
- ##
- # @if jp
- #
- # @brief PortProfile を取得する。
- #
- # この関数は、オブジェクト内部に保持されている PortProfile の
- # const 参照を返す const 関数である。
- #
- # @post この関数を呼び出すことにより内部状態が変更されることはない。
- #
- # @return PortProfile
- #
- # @else
- #
- # @brief Get the PortProfile of the Port
- #
- # This function is a const function that returns a const
- # reference of the PortProfile stored in this Port.
- #
- # @post This function never changes the state of the object.
- #
- # @return PortProfile
- #
- # @endif
- # PortProfile& getPortProfile() const;
- def getPortProfile(self):
- self._rtcout.RTC_TRACE("getPortProfile()")
- return self._profile
-
-
- ##
- # @if jp
- #
- # @brief [CORBA interface] ConnectorProfileListを取得する
- #
- # Portが保持する ConnectorProfile の sequence を返す。
- # ConnectorProfile は Port 間の接続プロファイル情報を保持する構造体であり、
- # 接続時にPort間で情報交換を行い、関連するすべての Port で同一の値が
- # 保持される。
- # ConnectorProfile は以下のメンバーを保持している。
- #
- # - name [string 型] このコネクタの名前。
- # - connector_id [string 型] ユニークなID
- # - ports [Port sequnce] このコネクタに関連する Port のオブジェクト
- # リファレンスのシーケンス。
- # - properties [NVList 型] その他のプロパティ。
- #
- # @param self
- #
- # @return この Port が保持する ConnectorProfile
- #
- # @else
- #
- # @brief [CORBA interface] Get the ConnectorProfileList of the Port
- #
- # This operation returns a list of the ConnectorProfiles of the Port.
- # ConnectorProfile includes the connection information that describes
- # relation between (among) Ports, and Ports exchange the ConnectionProfile
- # on connection process and hold the same information in each Port.
- # ConnectionProfile has the following members,
- #
- # - name [string] The name of the connection.
- # - connector_id [string] Unique identifier.
- # - ports [Port sequnce] The sequence of Port's object reference
- # that are related the connection.
- # - properties [NVList] The other properties.
- #
- # @return the ConnectorProfileList of the Port
- #
- # @endif
- # virtual ConnectorProfileList* get_connector_profiles()
- def get_connector_profiles(self):
- self._rtcout.RTC_TRACE("get_connector_profiles()")
-
- self.updateConnectors()
-
- guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
- return self._profile.connector_profiles
-
-
- ##
- # @if jp
- #
- # @brief [CORBA interface] ConnectorProfile を取得する
- #
- # connector_id で指定された ConnectorProfile を返す。
- # 指定した connector_id を持つ ConnectorProfile を保持していない場合は、
- # 空の ConnectorProfile を返す。
- #
- # @param self
- # @param connector_id ConnectorProfile の ID
- #
- # @return connector_id で指定された ConnectorProfile
- #
- # @else
- #
- # @brief [CORBA interface] Get the ConnectorProfile
- #
- # This operation returns the ConnectorProfiles specified connector_id.
- #
- # @param connector_id ID of the ConnectorProfile
- #
- # @return the ConnectorProfile identified by the connector_id
- #
- # @endif
- # ConnectorProfile* get_connector_profile(const char* connector_id)
- def get_connector_profile(self, connector_id):
- self._rtcout.RTC_TRACE("get_connector_profile(%s)", connector_id)
-
- self.updateConnectors()
-
- guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
- index = OpenRTM_aist.CORBA_SeqUtil.find(self._profile.connector_profiles,
- self.find_conn_id(connector_id))
- if index < 0:
- conn_prof = RTC.ConnectorProfile("","",[],[])
- return conn_prof
-
- conn_prof = RTC.ConnectorProfile(self._profile.connector_profiles[index].name,
- self._profile.connector_profiles[index].connector_id,
- self._profile.connector_profiles[index].ports,
- self._profile.connector_profiles[index].properties)
- return conn_prof
-
-
- ##
- # @if jp
- #
- # @brief [CORBA interface] Port の接続を行う
- #
- # 与えられた ConnectoionProfile の情報に基づき、Port間の接続を確立
- # する。この関数は主にアプリケーションプログラムやツールから呼び出
- # すことを前提としている。
- #
- # @pre アプリケーションプログラムは、コンポーネント間の複数の
- # Port を接続するために、適切な値をセットした ConnectorProfile を
- # connect() の引数として与えて呼び出さなければならない。
- #
- # @pre connect() に与える ConnectorProfile のメンバーのうち、
- # name, ports, properties メンバーに対してデータをセットしなければ
- # ならない。connector_id には通常空文字を設定するか、適当なUUIDを
- # 文字列で設定する必要がある。
- #
- # @pre ConnectorProfile::name は接続につける名前で CORBA::string
- # 型に格納できる任意の文字列である必要がある。
- #
- # @pre ConnectorProfile::connector_id はすべての接続に対して一意な
- # ID (通常はUUID) が格納される。UUIDの設定は connect() 関数内で行
- # われるので、呼び出し側は空文字を設定する。既存の接続と同じUUIDを
- # 設定し connect() を呼び出した場合には PRECONDITION_NOT_MET エラー
- # を返す。ただし、将来の拡張で既存の接続プロファイルを更新するため
- # に既存の UUID を設定して呼び出す使用法が用いられる可能性がある。
- #
- # @pre ConnectorProfile::ports は RTC::PortService のシーケンスで、
- # 接続を構成する通常2つ以上のポートのオブジェクト参照を代入する必
- # 要がある。例外として、ポートのオブジェクト参照を1つだけ格納して
- # connect()を呼び出すことで、ポートのインターフェース情報を取得し
- # たり、特殊なポート(CORBAのRTC::PortService以外の相手)に対して接
- # 続を行う場合もある。
- #
- # @pre ConnectorProfile::properties はポートに関連付けられたインター
- # フェースに対するプロパティを与えるために使用する。プロパティは、
- # string 型をキー、Any 型を値としてもつペアのシーケンスであり、値
- # には任意のCORBAデータ型を格納できるが、可能な限り string 型とし
- # て格納されることが推奨される。
- #
- # @pre 以上 connect() 呼び出し時に設定する ConnectorProfile のメン
- # バをまとめると以下のようになる。
- #
- # - ConnectorProfile::name: 任意の接続名
- # - ConnectorProfile::connector_id: 空文字
- # - ConnectorProfile::ports: 1つ以上のポート
- # - ConnectorProfile::properties: インターフェースに対するプロパティ
- #
- # @post connect() 関数は、ConnectorProfile::portsに格納されたポー
- # トシーケンスの先頭のポートに対して notify_connect() を呼ぶ。
- #
- # @post notify_connect() は ConnectorProfile::ports に格納されたポー
- # ト順に notify_connect() をカスケード呼び出しする。このカスケード
- # 呼び出しは、途中のnotify_connect() でエラーが出てもポートのオブ
- # ジェクト参照が有効である限り、必ずすべてのポートに対して行われる
- # ことが保証される。有効でないオブジェクト参照がシーケンス中に存在
- # する場合、そのポートをスキップして、次のポートに対して
- # notify_connect() を呼び出す。
- #
- # @post connect() 関数は、notify_connect()の戻り値がRTC_OKであれば、
- # RTC_OK を返す。この時点で接続は完了する。RTC_OK以外
- # の場合は、この接続IDに対してdisconnect()を呼び出し接続を解除し、
- # notify_connect() が返したエラーリターンコードをそのまま返す。
- #
- # @post connect() の引数として渡した ConnectorProfile には、
- # ConnectorProfile::connector_id および、途中のポートが
- # publishInterfaces() で公開したポートインターフェースの各種情報が
- # 格納されている。connect() および途中の notify_connect() が
- # ConnectorProfile::{name, ports} を変更することはない。
- #
- # @param connector_profile ConnectorProfile
- # @return ReturnCode_t 型のリターンコード
- #
- # @else
- #
- # @brief [CORBA interface] Connect the Port
- #
- # This operation establishes connection according to the given
- # ConnectionProfile inforamtion. This function is premised on
- # calling from mainly application program or tools.
- #
- # @pre To establish the connection among Ports of RT-Components,
- # application programs must call this operation giving
- # ConnectorProfile with valid values as an argument.
- #
- # @pre Out of ConnectorProfile member variables, "name", "ports"
- # and "properties" members shall be set valid
- # data. "connector_id" shall be set as empty string value or
- # valid string UUID value.
- #
- # @pre ConnectorProfile::name that is connection identifier shall
- # be any valid CORBA::string.
- #
- #
- # @pre ConnectorProfile::connector_id shall be set unique
- # identifier (usually UUID is used) for all connections. Since
- # UUID string value is usually set in the connect() function,
- # caller should just set empty string. If the connect() is called
- # with the same UUID as existing connection, this function
- # returns PRECONDITION_NOT_MET error. However, in order to update
- # the existing connection profile, the "connect()" operation with
- # existing connector ID might be used as valid method by future
- # extension
- #
- # @pre ConnectorProfile::ports, which is sequence of
- # RTC::PortService references, shall store usually two or more
- # ports' references. As exceptions, the "connect()" operation
- # might be called with only one reference in ConnectorProfile, in
- # case of just getting interfaces information from the port, or
- # connecting a special port (i.e. the peer port except
- # RTC::PortService on CORBA).
- #
- # @pre ConnectorProfile::properties might be used to give certain
- # properties to the service interfaces associated with the port.
- # The properties is a sequence variable with a pair of key string
- # and Any type value. Although the A variable can store any type
- # of values, it is not recommended except string.
- #
- # @pre The following is the summary of the ConnectorProfile
- # member to be set when this operation is called.
- #
- # - ConnectorProfile::name: The any name of connection
- # - ConnectorProfile::connector_id: Empty string
- # - ConnectorProfile::ports: One or more port references
- # - ConnectorProfile::properties: Properties for the interfaces
- #
- # @post connect() operation will call the first port in the
- # sequence of the ConnectorProfile.
- #
- # @post "noify_connect()"s perform cascaded call to the ports
- # stored in the ConnectorProfile::ports by order. Even if errors
- # are raised by intermediate notify_connect() operation, as long
- # as ports' object references are valid, it is guaranteed that
- # this cascaded call is completed in all the ports. If invalid
- # or dead ports exist in the port's sequence, the ports are
- # skipped and notify_connect() is called for the next valid port.
- #
- # @post connect() function returns RTC_OK if all the
- # notify_connect() return RTC_OK. At this time the connection is
- # completed. If notify_connect()s return except RTC_OK,
- # connect() calls disconnect() operation with the connector_id to
- # destruct the connection, and then it returns error code from
- # notify_connect().
- #
- # @post The ConnectorProfile argument of the connect() operation
- # returns ConnectorProfile::connector_id and various information
- # about service interfaces that is published by
- # publishInterfaces() in the halfway ports. The connect() and
- # halfway notify_connect() functions never change
- # ConnectorProfile::{name, ports}.
- #
- # @param connector_profile The ConnectorProfile.
- # @return ReturnCode_t The return code of ReturnCode_t type.
- #
- # @endif
- #
- # virtual ReturnCode_t connect(ConnectorProfile& connector_profile)
- def connect(self, connector_profile):
- self._rtcout.RTC_TRACE("connect()")
- if self.isEmptyId(connector_profile):
- guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
- self.setUUID(connector_profile)
- assert(not self.isExistingConnId(connector_profile.connector_id))
- del guard
- else:
- guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
- if self.isExistingConnId(connector_profile.connector_id):
- self._rtcout.RTC_ERROR("Connection already exists.")
- return (RTC.PRECONDITION_NOT_MET,connector_profile)
- del guard
-
- try:
- retval,connector_profile = connector_profile.ports[0].notify_connect(connector_profile)
- if retval != RTC.RTC_OK:
- self._rtcout.RTC_ERROR("Connection failed. cleanup.")
- self.disconnect(connector_profile.connector_id)
-
- return (retval, connector_profile)
- #return connector_profile.ports[0].notify_connect(connector_profile)
- except:
- self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
- return (RTC.BAD_PARAMETER, connector_profile)
-
- return (RTC.RTC_ERROR, connector_profile)
-
-
- ##
- # @if jp
- #
- # @brief [CORBA interface] Port の接続通知を行う
- #
- # このオペレーションは、Port間の接続が行われる際に、Port間で内部的
- # に呼ばれるオペレーションであって、通常アプリケーションプログラム
- # や、Port以外のRTC関連オブジェクト等から呼び出されることは想定さ
- # れていない。
- #
- # notify_connect() 自体はテンプレートメソッドパターンとして、サブ
- # クラスで実装されることが前提の publishInterfaces(),
- # subscribeInterfaces() の2つの関数を内部で呼び出す。処理の手順は
- # 以下の通りである。
- #
- # - publishInterfaces(): インターフェース情報の公開
- # - connectNext(): 次の Port の notify_connect() の呼び出し
- # - subscribeInterfaces(): インターフェース情報の取得
- # - 接続情報の保存
- #
- # notify_connect() は ConnectorProfile::ports に格納されている
- # Port の順序に従って、カスケード状に呼び出しを行うことにより、イ
- # ンターフェース情報の公開と取得を関連すすべてのポートに対して行う。
- # このカスケード呼び出しは途中で中断されることはなく、必ず
- # ConnectorProfile::ports に格納されている全ポートに対して行われる。
- #
- # @pre notify_connect() は ConnectorProfile::ports 内に格納されて
- # いる Port 参照リストのうち、当該 Port 自身の参照の次に格納されて
- # いる Port に対して notify_connect() を呼び出す。したがって
- # ConnectorProfile::ports には当該 Port の参照が格納されている必要
- # がある。もし、自身の参照が格納されていない場合、その他の処理によ
- # りエラーが上書きされなければ、BAD_PARAMETER エラーが返される。
- #
- # @pre 呼び出し時に ConnectorProfile::connector_id には一意なIDと
- # して UUID が保持されている必要がある。通常 connector_id は
- # connect() 関数により与えられ、空文字の場合は動作は未定義である。
- #
- # @post ConnectorProfile::name, ConnectorProfile::connector_id,
- # ConnectorProfile::ports は notify_connect() の呼び出しにより
- # 書き換えられることはなく不変である。
- #
- # @post ConnectorProfile::properties は notify_connect() の内部で、
- # 当該 Port が持つサービスインターフェースに関する情報を他の Port
- # に伝えるために、プロパティ情報が書き込まれる。
- #
- # @post なお、ConnectorProfile::ports のリストの最初 Port の
- # notify_connet() が終了した時点では、すべての関連する Port の
- # notify_connect() の呼び出しが完了する。publishInterfaces(),
- # connectNext(), subscribeInterfaces() および接続情報の保存のいず
- # れかの段階でエラーが発生した場合でも、エラーコードは内部的に保持
- # されており、最初に生じたエラーのエラーコードが返される。
- #
- # @param connector_profile ConnectorProfile
- # @return ReturnCode_t 型のリターンコード
- #
- # @else
- #
- # @brief [CORBA interface] Notify the Ports connection
- #
- # This operation is usually called from other ports' connect() or
- # notify_connect() operations when connection between ports is
- # established. This function is not premised on calling from
- # other functions or application programs.
- #
- # According to the template method pattern, the notify_connect()
- # calls "publishInterfaces()" and "subsctiveInterfaces()"
- # functions, which are premised on implementing in the
- # subclasses. The processing sequence is as follows.
- #
- # - publishInterfaces(): Publishing interface information
- # - connectNext(): Calling notify_connect() of the next port
- # - subscribeInterfaces(): Subscribing interface information
- # - Storing connection profile
- #
- # According to the order of port's references stored in the
- # ConnectorProfile::ports, publishing interface information to
- # all the ports and subscription interface information from all
- # the ports is performed by "notify_connect()"s. This cascaded
- # call never aborts in the halfway operations, and calling
- # sequence shall be completed for all the ports.
- #
- # @pre notify_connect() calls notify_connect() for the port's
- # reference that is stored in next of this port's reference in
- # the sequence of the ConnectorProfile::ports. Therefore the
- # reference of this port shall be stored in the
- # ConnectorProfile::ports. If this port's reference is not stored
- # in the sequence, BAD_PARAMETER error will be returned, except
- # the return code is overwritten by other operations.
- #
- # @pre UUID shall be set to ConnectorProfile::connector_id as a
- # unique identifier when this operation is called. Usually,
- # connector_id is given by a connect() function and, the behavior
- # is undefined in the case of a null character.
- #
- # @post ConnectorProfile::name, ConnectorProfile::connector_id,
- # ConnectorProfile::ports are invariant, and they are never
- # rewritten by notify_connect() operations.
- #
- # @post In order to transfer interface information to other
- # ports, interface property information is stored into the
- # ConnectorProfile::properties.
- #
- # @post At the end of notify_connect() operation for the first
- # port stored in the ConnectorProfile::ports sequence, the
- # related ports' notify_connect() invocations complete. Even if
- # errors are raised at the halfway of publishInterfaces(),
- # connectNext(), subscribeInterfaces() and storing process of
- # ConnectorProfile, error codes are saved and the first error is
- # returned.
- #
- # @param connector_profile The ConnectorProfile.
- # @return ReturnCode_t The return code of ReturnCode_t type.
- #
- # @endif
- #
- # virtual ReturnCode_t notify_connect(ConnectorProfile& connector_profile)
- def notify_connect(self, connector_profile):
- self._rtcout.RTC_TRACE("notify_connect()")
-
- guard_connection = OpenRTM_aist.ScopedLock(self._connection_mutex)
-
- # publish owned interface information to the ConnectorProfile
- retval = [RTC.RTC_OK for i in range(3)]
-
- self.onNotifyConnect(self.getName(),connector_profile)
- retval[0] = self.publishInterfaces(connector_profile)
- if retval[0] != RTC.RTC_OK:
- self._rtcout.RTC_ERROR("publishInterfaces() in notify_connect() failed.")
-
- self.onPublishInterfaces(self.getName(), connector_profile, retval[0])
- if self._onPublishInterfaces:
- self._onPublishInterfaces(connector_profile)
-
- # call notify_connect() of the next Port
- retval[1], connector_profile = self.connectNext(connector_profile)
- if retval[1] != RTC.RTC_OK:
- self._rtcout.RTC_ERROR("connectNext() in notify_connect() failed.")
-
- self.onConnectNextport(self.getName(), connector_profile, retval[1])
- # subscribe interface from the ConnectorProfile's information
- if self._onSubscribeInterfaces:
- self._onSubscribeInterfaces(connector_profile)
-
- retval[2] = self.subscribeInterfaces(connector_profile)
- if retval[2] != RTC.RTC_OK:
- self._rtcout.RTC_ERROR("subscribeInterfaces() in notify_connect() failed.")
- #self.notify_disconnect(connector_profile.connector_id)
-
- self.onSubscribeInterfaces(self.getName(), connector_profile, retval[2])
-
- self._rtcout.RTC_PARANOID("%d connectors are existing",
- len(self._profile.connector_profiles))
-
- guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
- # update ConnectorProfile
- index = self.findConnProfileIndex(connector_profile.connector_id)
- if index < 0:
- OpenRTM_aist.CORBA_SeqUtil.push_back(self._profile.connector_profiles,
- connector_profile)
- self._rtcout.RTC_PARANOID("New connector_id. Push backed.")
-
- else:
- self._profile.connector_profiles[index] = connector_profile
- self._rtcout.RTC_PARANOID("Existing connector_id. Updated.")
-
- for ret in retval:
- if ret != RTC.RTC_OK:
- self.onConnected(self.getName(), connector_profile, ret)
- return (ret, connector_profile)
-
- # connection established without errors
- if self._onConnected:
- self._onConnected(connector_profile)
- self.onConnected(self.getName(), connector_profile, RTC.RTC_OK)
- return (RTC.RTC_OK, connector_profile)
-
-
- ##
- # @if jp
- #
- # @brief [CORBA interface] Port の接続を解除する
- #
- # このオペレーションは与えられた connector_id に対応する接続を解除
- # する。connector_id は通常、システム全体において一意な UUID の文
- # 字列であり、事前に connect()/notify_connect() の呼び出しにより確
- # 立された接続プロファイル ConnectorProfile::connector_id に対応す
- # る。
- #
- # @pre connector_id は Port が保持する ConnectorProfile の少なくと
- # も一つの ID に一致する文字列でなければならない。当該 Port が持つ
- # ConnectorProfile のリスト内に connector_id と同一の ID を持つ
- # ConnectorProfile が存在しなければこの関数は BAD_PARAMETER エラー
- # を返す。
- #
- # @pre connector_id と同じ ID を持つ ConnectorProfile::ports には
- # 有効な Port の参照が含まれていなければならない。
- #
- # @post disconnect() 関数は、ConnectorProfile::ports の Port の参
- # 照リストの先頭に対して、notify_disconnect() を呼び出す。参照が無
- # 効であるなど、notify_disconnect() の呼び出しに失敗した場合には、
- # 参照リストの先頭から順番に成功するまで notify_disconnect() の呼
- # び出しを試す。notify_disconnect() の呼び出しに一つでも成功すれば、
- # notify_disconnect() の返却値をそのまま返し、一つも成功しなかった
- # 場合には RTC_ERROR エラーを返す。
- #
- # @param connector_id ConnectorProfile の ID
- # @return ReturnCode_t 型のリターンコード
- #
- # @else
- #
- # @brief [CORBA interface] Disconnect the Port
- #
- # This operation destroys connection between this port and the
- # peer port according to given connector_id. Usually connector_id
- # should be a UUID string that is unique in the system. And the
- # connection, which is established by connect()/notify_connect()
- # functions, is identified by the ConnectorProfile::connector_id.
- #
- # @pre connector_id shall be a character string which is same
- # with ID of at least one of the ConnectorProfiles stored in this
- # port. If ConnectorProfile that has same ID with the given
- # connector_id does not exist in the list of ConnectorProfile,
- # this operation returns BAD_PARAMTER error.
- #
- # @pre ConnectorProfile::ports that is same ID with given
- # connector_id shall store the valid ports' references.
- #
- # @post disconnect() function invokes the notify_disconnect() for
- # the port that is stored in the first of the
- # ConnectorProfile::ports. If notify_disconnect() call fails for
- # the first port, It tries on calling "notify_disconnect()" in
- # order for ports stored in ConnectorProfile::ports until the
- # operation call is succeeded. If notify_disconnect() succeeded
- # for at least one port, it returns return code from
- # notify_disconnect(). If none of notify_connect() call
- # succeeded, it returns RTC_ERROR error.
- #
- # @param connector_id The ID of the ConnectorProfile.
- # @return ReturnCode_t The return code of ReturnCode_t type.
- #
- # @endif
- #
- # virtual ReturnCode_t disconnect(const char* connector_id)
- def disconnect(self, connector_id):
- self._rtcout.RTC_TRACE("disconnect(%s)", connector_id)
-
- index = self.findConnProfileIndex(connector_id)
-
- if index < 0:
- self._rtcout.RTC_ERROR("Invalid connector id: %s", connector_id)
- return RTC.BAD_PARAMETER
-
- guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
- if index < len(self._profile.connector_profiles):
- prof = self._profile.connector_profiles[index]
- del guard
-
- if len(prof.ports) < 1:
- self._rtcout.RTC_FATAL("ConnectorProfile has empty port list.")
- return RTC.PRECONDITION_NOT_MET
-
- for i in range(len(prof.ports)):
- p = prof.ports[i]
- try:
- return p.notify_disconnect(connector_id)
- except:
- self._rtcout.RTC_WARN(OpenRTM_aist.Logger.print_exception())
- continue
-
- self._rtcout.RTC_ERROR("notify_disconnect() for all ports failed.")
- return RTC.RTC_ERROR
-
-
- ##
- # @if jp
- #
- # @brief [CORBA interface] Port の接続解除通知を行う
- #
- # このオペレーションは、Port間の接続解除が行われる際に、Port間で内
- # 部的に呼ばれるオペレーションであり、通常アプリケーションプログラ
- # ムや、 Port 以外の RTC 関連オブジェクト等から呼び出されることは
- # 想定されていない。
- #
- # notify_disconnect() 自体はテンプレートメソッドパターンとして、サ
- # ブクラスで実装されることが前提の unsubscribeInterfaces() 関数を
- # 内部で呼び出す。処理の手順は以下の通りである。
- #
- # - ConnectorProfile の検索
- # - 次の Port の notify_disconnect() 呼び出し
- # - unsubscribeInterfaces()
- # - ConnectorProfile の削除
- #
- # notify_disconnect() は ConnectorProfile::ports に格納されている
- # Port の順序に従って、カスケード状に呼び出しを行うことにより、接
- # 続の解除をすべての Port に通知する。
- #
- # @pre Port は与えられた connector_id に対応する ConnectorProfile
- # を保持していなければならない。
- #
- # @post connector_id に対応する ConnectorProfile が見つからない場
- # 合はBAD_PARAMETER エラーを返す。
- #
- # @post カスケード呼び出しを行う際には ConnectorProfile::ports に
- # 保持されている Port の参照リストのうち、自身の参照の次の参照に対
- # して notify_disconnect() を呼び出すが、その呼び出しで例外が発生
- # した場合には、呼び出しをスキップしリストの次の参照に対して
- # notify_disconnect() を呼び出す。一つも呼び出しに成功しない場合、
- # RTC_ERROR エラーコードを返す。
- #
- # @post なお、ConnectorProfile::ports のリストの最初 Port の
- # notify_disconnet() が終了した時点では、すべての関連する Port の
- # notify_disconnect() の呼び出しが完了する。
- #
- # @param connector_id ConnectorProfile の ID
- # @return ReturnCode_t 型のリターンコード
- #
- # @else
- #
- # @brief [CORBA interface] Notify the Ports disconnection
- #
- # This operation is invoked between Ports internally when the
- # connection is destroied. Generally it is not premised on
- # calling from application programs or RTC objects except Port
- # object.
- #
- # According to the template method pattern, the
- # notify_disconnect() calls unsubsctiveInterfaces() function,
- # which are premised on implementing in the subclasses. The
- # processing sequence is as follows.
- #
- # - Searching ConnectorProfile
- # - Calling notify_disconnect() for the next port
- # - Unsubscribing interfaces
- # - Deleting ConnectorProfile
- #
- # notify_disconnect() notifies disconnection to all the ports by
- # cascaded call to the stored ports in the
- # ConnectorProfile::ports in order.
- #
- # @pre The port shall store the ConnectorProfile having same id
- # with connector_id.
- #
- # @post If ConnectorProfile of same ID with connector_id does not
- # exist, it returns BAD_PARAMETER error.
- #
- # @post For the cascaded call, this operation calls
- # noify_disconnect() for the port that is stored in the next of
- # this port in the ConnectorProfile::ports. If the operation
- # call raises exception for some failure, it tries to call
- # notify_disconnect() and skips until the operation succeeded.
- # If none of operation call succeeded, it returns RTC_ERROR.
- #
- # @post At the end of notify_disconnect() operation for the first
- # port stored in the ConnectorProfile::ports sequence, the
- # related ports' notify_disconnect() invocations complete.
- #
- # @param connector_id The ID of the ConnectorProfile.
- # @return ReturnCode_t The return code of ReturnCode_t type.
- #
- # @endif
- #
- # virtual ReturnCode_t notify_disconnect(const char* connector_id)
- def notify_disconnect(self, connector_id):
- self._rtcout.RTC_TRACE("notify_disconnect(%s)", connector_id)
-
- guard_connection = OpenRTM_aist.ScopedLock(self._connection_mutex)
- # The Port of which the reference is stored in the beginning of
- # connectorProfile's PortServiceList is master Port.
- # The master Port has the responsibility of disconnecting all Ports.
- # The slave Ports have only responsibility of deleting its own
- # ConnectorProfile.
-
- guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
-
- index = self.findConnProfileIndex(connector_id)
-
- if index < 0:
- self._rtcout.RTC_ERROR("Invalid connector id: %s", connector_id)
- return RTC.BAD_PARAMETER
-
- prof = RTC.ConnectorProfile(self._profile.connector_profiles[index].name,
- self._profile.connector_profiles[index].connector_id,
- self._profile.connector_profiles[index].ports,
- self._profile.connector_profiles[index].properties)
- self.onNotifyDisconnect(self.getName(), prof)
-
- retval = self.disconnectNext(prof)
- self.onDisconnectNextport(self.getName(), prof, retval)
-
- if self._onUnsubscribeInterfaces:
- self._onUnsubscribeInterfaces(prof)
- self.onUnsubscribeInterfaces(self.getName(), prof)
- self.unsubscribeInterfaces(prof)
-
- if self._onDisconnected:
- self._onDisconnected(prof)
-
- OpenRTM_aist.CORBA_SeqUtil.erase(self._profile.connector_profiles, index)
-
- self.onDisconnected(self.getName(), prof, retval)
- return retval
-
-
- ##
- # @if jp
- #
- # @brief [CORBA interface] Port の全接続を解除する
- #
- # このオペレーションはこの Port に関連した全ての接続を解除する。
- #
- # @param self
- #
- # @return ReturnCode_t 型のリターンコード
- #
- # @else
- #
- # @brief [CORBA interface] Connect the Port
- #
- # This operation destroys all connection channels owned by the Port.
- #
- # @return ReturnCode_t The return code of this operation.
- #
- # @endif
- # virtual ReturnCode_t disconnect_all()
- def disconnect_all(self):
- self._rtcout.RTC_TRACE("disconnect_all()")
- guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
- plist = copy.deepcopy(self._profile.connector_profiles)
- del guard
-
- retcode = RTC.RTC_OK
- len_ = len(plist)
- self._rtcout.RTC_DEBUG("disconnecting %d connections.", len_)
-
- # disconnect all connections
- # Call disconnect() for each ConnectorProfile.
- for i in range(len_):
- tmpret = self.disconnect(plist[i].connector_id)
- if tmpret != RTC.RTC_OK:
- retcode = tmpret
-
- return retcode
-
-
- #============================================================
- # Local operations
- #============================================================
-
- ##
- # @if jp
- # @brief Port の名前を設定する
- #
- # Port の名前を設定する。この名前は Port が保持する PortProfile.name
- # に反映される。
- #
- # @param self
- # @param name Port の名前
- #
- # @else
- # @brief Set the name of this Port
- #
- # This operation sets the name of this Port. The given Port's name is
- # applied to Port's PortProfile.name.
- #
- # @param name The name of this Port.
- #
- # @endif
- # void setName(const char* name);
- def setName(self, name):
- self._rtcout.RTC_TRACE("setName(%s)", name)
- guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
- self._profile.name = name
- return
-
- ##
- # @if jp
- # @brief Port の名前を取得する
- # @else
- # @brief Get the name of this Port
- # @return The name of this Port.
- # @endif
- #
- # const char* PortBase::getName() const
- def getName(self):
- self._rtcout.RTC_TRACE("getName() = %s", self._profile.name)
- return self._profile.name
-
-
- ##
- # @if jp
- # @brief PortProfileを取得する
- #
- # Portが保持する PortProfile の const 参照を返す。
- #
- # @param self
- #
- # @return この Port の PortProfile
- #
- # @else
- # @brief Get the PortProfile of the Port
- #
- # This operation returns const reference of the PortProfile.
- #
- # @return the PortProfile of the Port
- #
- # @endif
- # const PortProfile& getProfile() const;
- def getProfile(self):
- self._rtcout.RTC_TRACE("getProfile()")
- guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
- return self._profile
-
-
- ##
- # @if jp
- #
- # @brief Port のオブジェクト参照を設定する
- #
- # このオペレーションは Port の PortProfile にこの Port 自身の
- # オブジェクト参照を設定する。
- #
- # @param self
- # @param port_ref この Port のオブジェクト参照
- #
- # @else
- #
- # @brief Set the object reference of this Port
- #
- # This operation sets the object reference itself
- # to the Port's PortProfile.
- #
- # @param The object reference of this Port.
- #
- # @endif
- # void setPortRef(PortService_ptr port_ref);
- def setPortRef(self, port_ref):
- self._rtcout.RTC_TRACE("setPortRef()")
- guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
- self._profile.port_ref = port_ref
-
-
- ##
- # @if jp
- #
- # @brief Port のオブジェクト参照を取得する
- #
- # このオペレーションは Port の PortProfile が保持している
- # この Port 自身のオブジェクト参照を取得する。
- #
- # @param self
- #
- # @return この Port のオブジェクト参照
- #
- # @else
- #
- # @brief Get the object reference of this Port
- #
- # This operation returns the object reference
- # that is stored in the Port's PortProfile.
- #
- # @return The object reference of this Port.
- #
- # @endif
- # PortService_ptr getPortRef();
- def getPortRef(self):
- self._rtcout.RTC_TRACE("getPortRef()")
- guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
- return self._profile.port_ref
-
-
- ##
- # @if jp
- #
- # @brief Port の owner の RTObject を指定する
- #
- # このオペレーションは Port の PortProfile.owner を設定する。
- #
- # @param self
- # @param owner この Port を所有する RTObject の参照
- #
- # @else
- #
- # @brief Set the owner RTObject of the Port
- #
- # This operation sets the owner RTObject of this Port.
- #
- # @param owner The owner RTObject's reference of this Port
- #
- # @endif
- # void setOwner(RTObject_ptr owner);
- def setOwner(self, owner):
- prof = owner.get_component_profile()
- self._ownerInstanceName = prof.instance_name
- self._rtcout.RTC_TRACE("setOwner(%s)", self._ownerInstanceName)
-
- guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
- plist = self._profile.name.split(".")
- if not self._ownerInstanceName:
- self._rtcout.RTC_ERROR("Owner is not set.")
- self._rtcout.RTC_ERROR("addXXXPort() should be called in onInitialize().")
- portname = self._ownerInstanceName+"."+plist[-1]
-
- self._profile.owner = owner
- self._profile.name = portname
-
-
- #============================================================
- # callbacks
- #============================================================
-
- ##
- # @if jp
- #
- # @brief インターフェースを公開する際に呼ばれるコールバックをセットする
- #
- # このオペレーションは、このポートが接続時に、ポート自身が持つサー
- # ビスインターフェース情報を公開するタイミングで呼ばれるコールバッ
- # クファンクタをセットする。
- #
- # コールバックファンクタの所有権は、呼び出し側にあり、オブジェクト
- # が必要なくなった時に解体するのは呼び出し側の責任である。
- #
- # このコールバックファンクタは、PortBaseクラスの仮想関数である
- # publishInterfaces() が呼ばれたあとに、同じ引数 ConnectorProfile と
- # ともに呼び出される。このコールバックを利用して、
- # publishInterfaces() が公開した ConnectorProfile を変更することが可
- # 能であるが、接続関係の不整合を招かないよう、ConnectorProfile の
- # 変更には注意を要する。
- #
- # @param on_publish ConnectionCallback のサブクラスオブジェクトのポインタ
- #
- # @else
- #
- # @brief Setting callback called on publish interfaces
- #
- # This operation sets a functor that is called after publishing
- # interfaces process when connecting between ports.
- #
- # Since the ownership of the callback functor object is owned by
- # the caller, it has the responsibility of object destruction.
- #
- # The callback functor is called after calling
- # publishInterfaces() that is virtual member function of the
- # PortBase class with an argument of ConnectorProfile type that
- # is same as the argument of publishInterfaces() function.
- # Although by using this functor, you can modify the ConnectorProfile
- # published by publishInterfaces() function, the modification
- # should be done carefully for fear of causing connection
- # inconsistency.
- #
- # @param on_publish a pointer to ConnectionCallback's subclasses
- #
- # @endif
- #
- # void setOnPublishInterfaces(ConnectionCallback* on_publish);
- def setOnPublishInterfaces(self, on_publish):
- self._onPublishInterfaces = on_publish
- return
-
-
- ##
- # @if jp
- #
- # @brief インターフェースを取得する際に呼ばれるコールバックをセットする
- #
- # このオペレーションは、このポートが接続時に、相手のポートが持つサー
- # ビスインターフェース情報を取得するタイミングで呼ばれるコールバッ
- # クファンクタをセットする。
- #
- # コールバックファンクタの所有権は、呼び出し側にあり、オブジェクト
- # が必要なくなった時に解体するのは呼び出し側の責任である。
- #
- # このコールバックファンクタは、PortBaseクラスの仮想関数である
- # subscribeInterfaces() が呼ばれる前に、同じ引数 ConnectorProfile と
- # ともに呼び出される。このコールバックを利用して、
- # subscribeInterfaces() に与える ConnectorProfile を変更することが可
- # 能であるが、接続関係の不整合を招かないよう、ConnectorProfile の
- # 変更には注意を要する。
- #
- # @param on_subscribe ConnectionCallback のサブクラスオブジェクトのポインタ
- #
- # @else
- #
- # @brief Setting callback called on publish interfaces
- #
- # This operation sets a functor that is called before subscribing
- # interfaces process when connecting between ports.
- #
- # Since the ownership of the callback functor object is owned by
- # the caller, it has the responsibility of object destruction.
- #
- # The callback functor is called before calling
- # subscribeInterfaces() that is virtual member function of the
- # PortBase class with an argument of ConnectorProfile type that
- # is same as the argument of subscribeInterfaces() function.
- # Although by using this functor, you can modify ConnectorProfile
- # argument for subscribeInterfaces() function, the modification
- # should be done carefully for fear of causing connection
- # inconsistency.
- #
- # @param on_subscribe a pointer to ConnectionCallback's subclasses
- #
- # @endif
- #
- #void setOnSubscribeInterfaces(ConnectionCallback* on_subscribe);
- def setOnSubscribeInterfaces(self, on_subscribe):
- self._onSubscribeInterfaces = on_subscribe
- return
-
-
- ##
- # @if jp
- #
- # @brief 接続完了時に呼ばれるコールバックをセットする
- #
- # このオペレーションは、このポートが接続完了時に呼ばれる、コールバッ
- # クファンクタをセットする。
- #
- # コールバックファンクタの所有権は、呼び出し側にあり、オブジェクト
- # が必要なくなった時に解体するのは呼び出し側の責任である。
- #
- # このコールバックファンクタは、ポートの接続実行関数である
- # notify_connect() の終了直前に、接続処理が正常終了する際に限って
- # 呼び出されるコールバックである。接続処理の過程でエラーが発生した
- # 場合には呼び出されない。
- #
- # このコールバックファンクタは notify_connect() が out パラメータ
- # として返すのと同じ引数 ConnectorProfile とともに呼び出されるので、
- # この接続において公開されたすべてのインターフェース情報を得ること
- # ができる。このコールバックを利用して、notify_connect() が返す
- # ConnectorProfile を変更することが可能であるが、接続関係の不整合
- # を招かないよう、ConnectorProfile の変更には注意を要する。
- #
- # @param on_subscribe ConnectionCallback のサブクラスオブジェクトのポインタ
- #
- # @else
- #
- # @brief Setting callback called on connection established
- #
- # This operation sets a functor that is called when connection
- # between ports established.
- #
- # Since the ownership of the callback functor object is owned by
- # the caller, it has the responsibility of object destruction.
- #
- # The callback functor is called only when notify_connect()
- # function successfully returns. In case of error, the functor
- # will not be called.
- #
- # Since this functor is called with ConnectorProfile argument
- # that is same as out-parameter of notify_connect() function, you
- # can get all the information of published interfaces of related
- # ports in the connection. Although by using this functor, you
- # can modify ConnectorProfile argument for out-paramter of
- # notify_connect(), the modification should be done carefully for
- # fear of causing connection inconsistency.
- #
- # @param on_subscribe a pointer to ConnectionCallback's subclasses
- #
- # @endif
- #
- # void setOnConnected(ConnectionCallback* on_connected);
- def setOnConnected(self, on_connected):
- self._onConnected = on_connected
- return
-
-
- ##
- # @if jp
- #
- # @brief インターフェースを解放する際に呼ばれるコールバックをセットする
- #
- # このオペレーションは、このポートが接続時に、相手のポートが持つサー
- # ビスインターフェース情報を解放するタイミングで呼ばれるコールバッ
- # クファンクタをセットする。
- #
- # コールバックファンクタの所有権は、呼び出し側にあり、オブジェクト
- # が必要なくなった時に解体するのは呼び出し側の責任である。
- #
- # このコールバックファンクタは、PortBaseクラスの仮想関数である
- # unsubscribeInterfaces() が呼ばれる前に、同じ引数 ConnectorProfile と
- # ともに呼び出される。このコールバックを利用して、
- # unsubscribeInterfaces() に与える ConnectorProfile を変更することが可
- # 能であるが、接続関係の不整合を招かないよう、ConnectorProfile の
- # 変更には注意を要する。
- #
- # @param on_unsubscribe ConnectionCallback のサブクラスオブジェク
- # トのポインタ
- #
- # @else
- #
- # @brief Setting callback called on unsubscribe interfaces
- #
- # This operation sets a functor that is called before unsubscribing
- # interfaces process when disconnecting between ports.
- #
- # Since the ownership of the callback functor object is owned by
- # the caller, it has the responsibility of object destruction.
- #
- # The callback functor is called before calling
- # unsubscribeInterfaces() that is virtual member function of the
- # PortBase class with an argument of ConnectorProfile type that
- # is same as the argument of unsubscribeInterfaces() function.
- # Although by using this functor, you can modify ConnectorProfile
- # argument for unsubscribeInterfaces() function, the modification
- # should be done carefully for fear of causing connection
- # inconsistency.
- #
- # @param on_unsubscribe a pointer to ConnectionCallback's subclasses
- #
- # @endif
- #
- # void setOnUnsubscribeInterfaces(ConnectionCallback* on_subscribe);
- def setOnUnsubscribeInterfaces(self, on_subscribe):
- self._onUnsubscribeInterfaces = on_subscribe
- return
-
-
- ##
- # @if jp
- #
- # @brief 接続解除に呼ばれるコールバックをセットする
- #
- # このオペレーションは、このポートの接続解除時に呼ばれる、コールバッ
- # クファンクタをセットする。
- #
- # コールバックファンクタの所有権は、呼び出し側にあり、オブジェクト
- # が必要なくなった時に解体するのは呼び出し側の責任である。
- #
- # このコールバックファンクタは、ポートの接続解除実行関数である
- # notify_disconnect() の終了直前に、呼び出されるコールバックである。
- #
- # このコールバックファンクタは接続に対応する ConnectorProfile とと
- # もに呼び出される。この ConnectorProfile はこのファンクタ呼出し後
- # に破棄されるので、変更がほかに影響を与えることはない。
- #
- # @param on_disconnected ConnectionCallback のサブクラスオブジェク
- # トのポインタ
- #
- # @else
- #
- # @brief Setting callback called on disconnected
- #
- # This operation sets a functor that is called when connection
- # between ports is destructed.
- #
- # Since the ownership of the callback functor object is owned by
- # the caller, it has the responsibility of object destruction.
- #
- # The callback functor is called just before notify_disconnect()
- # that is disconnection execution function returns.
- #
- # This functor is called with argument of corresponding
- # ConnectorProfile. Since this ConnectorProfile will be
- # destructed after calling this functor, modifications never
- # affect others.
- #
- # @param on_disconnected a pointer to ConnectionCallback's subclasses
- #
- # @endif
- #
- # void setOnDisconnected(ConnectionCallback* on_disconnected);
- def setOnDisconnected(self, on_disconnected):
- self._onDisconnected = on_disconnected
- return
-
- # void setOnConnectionLost(ConnectionCallback* on_connection_lost);
- def setOnConnectionLost(self, on_connection_lost):
- self._onConnectionLost = on_connection_lost
- return
-
-
- ##
- # @if jp
- # @brief PortConnectListeners のホルダをセットする
- #
- # ポートの接続に関するリスナ群を保持するホルダクラスへのポインタを
- # セットする。この関数は通常親のRTObjectから呼ばれ、RTObjectが持つ
- # ホルダクラスへのポインタがセットされる。
- #
- # @param portconnListeners PortConnectListeners オブジェクトのポインタ
- #
- # @else
- # @brief Setting PortConnectListener holder
- #
- # This operation sets a functor that is called when connection
- # of this port does lost.
- #
- # @param on_connection_lost a pointer to ConnectionCallback's subclasses
- #
- # @endif
- #
- # void setPortConnectListenerHolder(PortConnectListeners* portconnListeners);
- def setPortConnectListenerHolder(self, portconnListeners):
- self._portconnListeners = portconnListeners
- return
-
-
- ##
- # @if jp
- #
- # @brief Interface 情報を公開する(サブクラス実装用)
- #
- # このオペレーションは、notify_connect() 処理シーケンスの始めにコール
- # される関数である。
- # notify_connect() では、
- #
- # - publishInterfaces()
- # - connectNext()
- # - subscribeInterfaces()
- # - updateConnectorProfile()
- #
- # の順に protected 関数がコールされ接続処理が行われる。
- # <br>
- # 具象 Port ではこのオペレーションをオーバーライドし、引数として
- # 与えられた ConnectorProfile に従い処理を行い、パラメータが不適切
- # であれば、RteurnCode_t 型のエラーコードを返す。
- # 通常 publishInterafaces() 内においては、この Port に属する
- # インターフェースに関する情報を ConnectorProfile に対して適切に設定し
- # 他の Port に通知しなければならない。
- # <br>
- # また、この関数がコールされる段階では、他の Port の Interface に関する
- # 情報はすべて含まれていないので、他の Port の Interface を取得する処理
- # は subscribeInterfaces() 内で行われるべきである。
- # <br>
- # このオペレーションは、新規の connector_id に対しては接続の生成、
- # 既存の connector_id に対しては更新が適切に行われる必要がある。<BR>
- # ※サブクラスでの実装参照用
- #
- # @param self
- # @param connector_profile 接続に関するプロファイル情報
- #
- # @return ReturnCode_t 型のリターンコード
- #
- # @else
- #
- # @brief Publish interface information
- #
- # This operation is pure virutal method that would be called at the
- # beginning of the notify_connect() process sequence.
- # In the notify_connect(), the following methods would be called in order.
- #
- # - publishInterfaces()
- # - connectNext()
- # - subscribeInterfaces()
- # - updateConnectorProfile()
- #
- # In the concrete Port, this method should be overridden. This method
- # processes the given ConnectorProfile argument and if the given parameter
- # is invalid, it would return error code of ReturnCode_t.
- # Usually, publishInterfaces() method should set interfaces information
- # owned by this Port, and publish it to the other Ports.
- # <br>
- # When this method is called, other Ports' interfaces information may not
- # be completed. Therefore, the process to obtain other Port's interfaces
- # information should be done in the subscribeInterfaces() method.
- # <br>
- # This operation should create the new connection for the new
- # connector_id, and should update the connection for the existing
- # connection_id.
- #
- # @param connector_profile The connection profile information
- # @return The return code of ReturnCode_t type.
- #
- #@endif
- def publishInterfaces(self, connector_profile):
- pass
-
-
- ##
- # @if jp
- #
- # @brief 次の Port に対して notify_connect() をコールする
- #
- # ConnectorProfile の port_ref 内に格納されている Port のオブジェクト
- # リファレンスのシーケンスの中から、自身の Port の次の Port に対して
- # notify_connect() をコールする。
- #
- # @param self
- # @param connector_profile 接続に関するプロファイル情報
- #
- # @return ReturnCode_t 型のリターンコード
- #
- # @else
- #
- # @brief Call notify_connect() of the next Port
- #
- # This operation calls the notify_connect() of the next Port's
- # that stored in ConnectorProfile's port_ref sequence.
- #
- # @param connector_profile The connection profile information
- #
- # @return The return code of ReturnCode_t type.
- #
- # @endif
- # virtual ReturnCode_t connectNext(ConnectorProfile& connector_profile);
- def connectNext(self, connector_profile):
- index = OpenRTM_aist.CORBA_SeqUtil.find(connector_profile.ports,
- self.find_port_ref(self._profile.port_ref))
- if index < 0:
- return (RTC.BAD_PARAMETER, connector_profile)
-
- index += 1
- if index < len(connector_profile.ports):
- p = connector_profile.ports[index]
- return p.notify_connect(connector_profile)
-
- return (RTC.RTC_OK, connector_profile)
-
-
- ##
- # @if jp
- #
- # @brief 次の Port に対して notify_disconnect() をコールする
- #
- # ConnectorProfile の port_ref 内に格納されている Port のオブジェクト
- # リファレンスのシーケンスの中から、自身の Port の次の Port に対して
- # notify_disconnect() をコールする。
- #
- # @param self
- # @param connector_profile 接続に関するプロファイル情報
- #
- # @return ReturnCode_t 型のリターンコード
- #
- # @else
- #
- # @brief Call notify_disconnect() of the next Port
- #
- # This operation calls the notify_disconnect() of the next Port's
- # that stored in ConnectorProfile's port_ref sequence.
- #
- # @param connector_profile The connection profile information
- #
- # @return The return code of ReturnCode_t type.
- #
- # @endif
- # virtual ReturnCode_t disconnectNext(ConnectorProfile& connector_profile);
- def disconnectNext(self, connector_profile):
- index = OpenRTM_aist.CORBA_SeqUtil.find(connector_profile.ports,
- self.find_port_ref(self._profile.port_ref))
- if index < 0:
- return RTC.BAD_PARAMETER
-
- if index == (len(connector_profile.ports) - 1):
- return RTC.RTC_OK
-
- index += 1
-
- while index < len(connector_profile.ports):
- p = connector_profile.ports[index]
- index += 1
- try:
- return p.notify_disconnect(connector_profile.connector_id)
- except:
- self._rtcout.RTC_WARN(OpenRTM_aist.Logger.print_exception())
- continue
-
- return RTC.RTC_ERROR
-
-
- ##
- # @if jp
- #
- # @brief Interface 情報を取得する(サブクラス実装用)
- #
- # このオペレーションは、notify_connect() 処理シーケンスの中間にコール
- # される関数である。
- # notify_connect() では、
- #
- # - publishInterfaces()
- # - connectNext()
- # - subscribeInterfaces()
- # - updateConnectorProfile()
- #
- # の順に protected 関数がコールされ接続処理が行われる。
- # <br>
- # 具象 Port ではこのオペレーションをオーバーライドし、引数として
- # 与えられた ConnectorProfile に従い処理を行い、パラメータが不適切
- # であれば、RteurnCode_t 型のエラーコードを返す。
- # 引数 ConnectorProfile には他の Port の Interface に関する情報が
- # 全て含まれている。
- # 通常 subscribeInterafaces() 内においては、この Port が使用する
- # Interface に関する情報を取得し、要求側のインターフェースに対して
- # 情報を設定しなければならない。
- # <br>
- # このオペレーションは、新規の connector_id に対しては接続の生成、
- # 既存の connector_id に対しては更新が適切に行われる必要がある。<BR>
- # ※サブクラスでの実装参照用
- #
- # @param self
- # @param connector_profile 接続に関するプロファイル情報
- #
- # @return ReturnCode_t 型のリターンコード
- #
- # @else
- #
- # @brief Publish interface information
- #
- # This operation is pure virutal method that would be called at the
- # mid-flow of the notify_connect() process sequence.
- # In the notify_connect(), the following methods would be called in order.
- #
- # - publishInterfaces()
- # - connectNext()
- # - subscribeInterfaces()
- # - updateConnectorProfile()
- #
- # In the concrete Port, this method should be overridden. This method
- # processes the given ConnectorProfile argument and if the given parameter
- # is invalid, it would return error code of ReturnCode_t.
- # The given argument ConnectorProfile includes all the interfaces
- # information in it.
- # Usually, subscribeInterafaces() method obtains information of interfaces
- # from ConnectorProfile, and should set it to the interfaces that require
- # them.
- # <br>
- # This operation should create the new connection for the new
- # connector_id, and should update the connection for the existing
- # connection_id.
- #
- # @param connector_profile The connection profile information
- #
- # @return The return code of ReturnCode_t type.
- #
- #@endif
- def subscribeInterfaces(self, connector_profile):
- pass
-
-
- ##
- # @if jp
- #
- # @brief Interface の接続を解除する(サブクラス実装用)
- #
- # このオペレーションは、notify_disconnect() 処理シーケンスの終わりにコール
- # される関数である。
- # notify_disconnect() では、
- # - disconnectNext()
- # - unsubscribeInterfaces()
- # - eraseConnectorProfile()
- # の順に protected 関数がコールされ接続解除処理が行われる。
- # <br>
- # 具象 Port ではこのオペレーションをオーバーライドし、引数として
- # 与えられた ConnectorProfile に従い接続解除処理を行う。<BR>
- # ※サブクラスでの実装参照用
- #
- # @param self
- # @param connector_profile 接続に関するプロファイル情報
- #
- # @else
- #
- # @brief Disconnect interface connection
- #
- # This operation is pure virutal method that would be called at the
- # end of the notify_disconnect() process sequence.
- # In the notify_disconnect(), the following methods would be called.
- # - disconnectNext()
- # - unsubscribeInterfaces()
- # - eraseConnectorProfile()
- # <br>
- # In the concrete Port, this method should be overridden. This method
- # processes the given ConnectorProfile argument and disconnect interface
- # connection.
- #
- # @param connector_profile The connection profile information
- #
- # @endif
- def unsubscribeInterfaces(self, connector_profile):
- pass
-
-
- ##
- # @if jp
- #
- # @brief 接続の最大数を設定する。
- #
- # @param limit_value 最大数
- #
- # @else
- #
- # @brief Set the maximum number of connections
- #
- #
- # @param limit_value The maximum number of connections
- #
- # @endif
- #
- # virtual void setConnectionLimit(int limit_value);
- def setConnectionLimit(self, limit_value):
- self._connectionLimit = limit_value
- return
-
-
- ##
- # @if jp
- # @brief Interface情報を公開する
- #
- # Interface情報を公開する。
- #
- # dataport.dataflow_type
- #
- # @return ReturnCode_t 型のリターンコード
- #
- # @else
- # @brief Publish interface information
- #
- # Publish interface information.
- #
- #
- # @return The return code of ReturnCode_t type
- #
- # @endif
- #
- # virtual ReturnCode_t _publishInterfaces(void);
- def _publishInterfaces(self):
- if not (self._connectionLimit < 0) :
- if self._connectionLimit <= len(self._profile.connector_profiles):
- self._rtcout.RTC_PARANOID("Connected number has reached the limitation.")
- self._rtcout.RTC_PARANOID("Can connect the port up to %d ports.",
- self._connectionLimit)
- self._rtcout.RTC_PARANOID("%d connectors are existing",
- len(self._profile.connector_profiles))
- return RTC.RTC_ERROR
-
- return RTC.RTC_OK
-
-
- ##
- # @if jp
- #
- # @brief ConnectorProfile の connector_id フィールドが空かどうか判定
- #
- # 指定された ConnectorProfile の connector_id が空であるかどうかの判定を
- # 行う。
- #
- # @param self
- # @param connector_profile 判定対象コネクタプロファイル
- #
- # @return 引数で与えられた ConnectorProfile の connector_id が空であれば、
- # true、そうでなければ false を返す。
- #
- # @else
- #
- # @brief Whether connector_id of ConnectorProfile is empty
- #
- # @return If the given ConnectorProfile's connector_id is empty string,
- # it returns true.
- #
- # @endif
- # bool isEmptyId(const ConnectorProfile& connector_profile) const;
- def isEmptyId(self, connector_profile):
- return connector_profile.connector_id == ""
-
-
- ##
- # @if jp
- #
- # @brief UUIDを生成する
- #
- # このオペレーションは UUID を生成する。
- #
- # @param self
- #
- # @return uuid
- #
- # @else
- #
- # @brief Get the UUID
- #
- # This operation generates UUID.
- #
- # @return uuid
- #
- # @endif
- # const std::string getUUID() const;
- def getUUID(self):
- return str(OpenRTM_aist.uuid1())
-
-
- ##
- # @if jp
- #
- # @brief UUIDを生成し ConnectorProfile にセットする
- #
- # このオペレーションは UUID を生成し、ConnectorProfile にセットする。
- #
- # @param self
- # @param connector_profile connector_id をセットする ConnectorProfile
- #
- # @else
- #
- # @brief Create and set the UUID to the ConnectorProfile
- #
- # This operation generates and set UUID to the ConnectorProfile.
- #
- # @param connector_profile ConnectorProfile to be set connector_id
- #
- # @endif
- # void setUUID(ConnectorProfile& connector_profile) const;
- def setUUID(self, connector_profile):
- connector_profile.connector_id = self.getUUID()
- assert(connector_profile.connector_id != "")
-
-
- ##
- # @if jp
- #
- # @brief id が既存の ConnectorProfile のものかどうか判定する
- #
- # このオペレーションは与えられた ID が既存の ConnectorProfile のリスト中に
- # 存在するかどうか判定する。
- #
- # @param self
- # @param id_ 判定する connector_id
- #
- # @return id の存在判定結果
- #
- # @else
- #
- # @brief Whether the given id exists in stored ConnectorProfiles
- #
- # This operation returns boolean whether the given id exists in
- # the Port's ConnectorProfiles.
- #
- # @param id connector_id to be find in Port's ConnectorProfiles
- #
- # @endif
- # bool isExistingConnId(const char* id);
- def isExistingConnId(self, id_):
- return OpenRTM_aist.CORBA_SeqUtil.find(self._profile.connector_profiles,
- self.find_conn_id(id_)) >= 0
-
-
- ##
- # @if jp
- #
- # @brief id を持つ ConnectorProfile を探す
- #
- # このオペレーションは与えられた ID を持つ ConnectorProfile を Port が
- # もつ ConnectorProfile のリスト中から探す。
- # もし、同一の id を持つ ConnectorProfile がなければ、空の ConnectorProfile
- # が返される。
- #
- # @param self
- # @param id_ 検索する connector_id
- #
- # @return connector_id を持つ ConnectorProfile
- #
- # @else
- #
- # @brief Find ConnectorProfile with id
- #
- # This operation returns ConnectorProfile with the given id from Port's
- # ConnectorProfiles' list.
- # If the ConnectorProfile with connector id that is identical with the
- # given id does not exist, empty ConnectorProfile is returned.
- #
- # @param id the connector_id to be searched in Port's ConnectorProfiles
- #
- # @return CoonectorProfile with connector_id
- #
- # @endif
- # ConnectorProfile findConnProfile(const char* id);
- def findConnProfile(self, id_):
- index = OpenRTM_aist.CORBA_SeqUtil.find(self._profile.connector_profiles,
- self.find_conn_id(id_))
- if index < 0 or index >= len(self._profile.connector_profiles):
- return RTC.ConnectorProfile("","",[],[])
-
- return self._profile.connector_profiles[index]
-
-
- ##
- # @if jp
- #
- # @brief id を持つ ConnectorProfile を探す
- #
- # このオペレーションは与えられた ID を持つ ConnectorProfile を Port が
- # もつ ConnectorProfile のリスト中から探しインデックスを返す。
- # もし、同一の id を持つ ConnectorProfile がなければ、-1 を返す。
- #
- # @param self
- # @param id_ 検索する connector_id
- #
- # @return Port の ConnectorProfile リストのインデックス
- #
- # @else
- #
- # @brief Find ConnectorProfile with id
- #
- # This operation returns ConnectorProfile with the given id from Port's
- # ConnectorProfiles' list.
- # If the ConnectorProfile with connector id that is identical with the
- # given id does not exist, empty ConnectorProfile is returned.
- #
- # @param id the connector_id to be searched in Port's ConnectorProfiles
- #
- # @return The index of ConnectorProfile of the Port
- #
- # @endif
- # CORBA::Long findConnProfileIndex(const char* id);
- def findConnProfileIndex(self, id_):
- return OpenRTM_aist.CORBA_SeqUtil.find(self._profile.connector_profiles,
- self.find_conn_id(id_))
-
-
- ##
- # @if jp
- #
- # @brief ConnectorProfile の追加もしくは更新
- #
- # このオペレーションは与えられた与えられた ConnectorProfile を
- # Port に追加もしくは更新保存する。
- # 与えられた ConnectorProfile の connector_id と同じ ID を持つ
- # ConnectorProfile がリストになければ、リストに追加し、
- # 同じ ID が存在すれば ConnectorProfile を上書き保存する。
- #
- # @param self
- # @param connector_profile 追加もしくは更新する ConnectorProfile
- #
- # @else
- #
- # @brief Append or update the ConnectorProfile list
- #
- # This operation appends or updates ConnectorProfile of the Port
- # by the given ConnectorProfile.
- # If the connector_id of the given ConnectorProfile does not exist
- # in the Port's ConnectorProfile list, the given ConnectorProfile would be
- # append to the list. If the same id exists, the list would be updated.
- #
- # @param connector_profile the ConnectorProfile to be appended or updated
- #
- # @endif
- # void updateConnectorProfile(const ConnectorProfile& connector_profile);
- def updateConnectorProfile(self, connector_profile):
- index = OpenRTM_aist.CORBA_SeqUtil.find(self._profile.connector_profiles,
- self.find_conn_id(connector_profile.connector_id))
-
- if index < 0:
- OpenRTM_aist.CORBA_SeqUtil.push_back(self._profile.connector_profiles,
- connector_profile)
- else:
- self._profile.connector_profiles[index] = connector_profile
-
-
- ##
- # @if jp
- #
- # @brief ConnectorProfile を削除する
- #
- # このオペレーションは Port の PortProfile が保持している
- # ConnectorProfileList のうち与えられた id を持つ ConnectorProfile
- # を削除する。
- #
- # @param self
- # @param id_ 削除する ConnectorProfile の id
- #
- # @return 正常に削除できた場合は true、
- # 指定した ConnectorProfile が見つからない場合は false を返す
- #
- # @else
- #
- # @brief Delete the ConnectorProfile
- #
- # This operation deletes a ConnectorProfile specified by id from
- # ConnectorProfileList owned by PortProfile of this Port.
- #
- # @param id The id of the ConnectorProfile to be deleted.
- #
- # @endif
- # bool eraseConnectorProfile(const char* id);
- def eraseConnectorProfile(self, id_):
- guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
-
- index = OpenRTM_aist.CORBA_SeqUtil.find(self._profile.connector_profiles,
- self.find_conn_id(id_))
-
- if index < 0:
- return False
-
- OpenRTM_aist.CORBA_SeqUtil.erase(self._profile.connector_profiles, index)
-
- return True
-
-
- ##
- # @if jp
- #
- # @brief PortInterfaceProfile に インターフェースを登録する
- #
- # このオペレーションは Port が持つ PortProfile の、PortInterfaceProfile
- # にインターフェースの情報を追加する。
- # この情報は、get_port_profile() 似よって得られる PortProfile のうち
- # PortInterfaceProfile の値を変更するのみであり、実際にインターフェースを
- # 提供したり要求したりする場合には、サブクラスで、 publishInterface() ,
- # subscribeInterface() 等の関数を適切にオーバーライドしインターフェースの
- # 提供、要求処理を行わなければならない。
- #
- # インターフェース(のインスタンス)名は Port 内で一意でなければならない。
- # 同名のインターフェースがすでに登録されている場合、この関数は false を
- # 返す。
- #
- # @param self
- # @param instance_name インターフェースのインスタンスの名前
- # @param type_name インターフェースの型の名前
- # @param pol インターフェースの属性 (RTC::PROVIDED もしくは RTC:REQUIRED)
- #
- # @return インターフェース登録処理結果。
- # 同名のインターフェースが既に登録されていれば false を返す。
- #
- # @else
- #
- # @brief Append an interface to the PortInterfaceProfile
- #
- # This operation appends interface information to the PortInterfaceProfile
- # that is owned by the Port.
- # The given interfaces information only updates PortInterfaceProfile of
- # PortProfile that is obtained through get_port_profile().
- # In order to provide and require interfaces, proper functions (for
- # example publishInterface(), subscribeInterface() and so on) should be
- # overridden in subclasses, and these functions provide concrete interface
- # connection and disconnection functionality.
- #
- # The interface (instance) name have to be unique in the Port.
- # If the given interface name is identical with stored interface name,
- # this function returns false.
- #
- # @param name The instance name of the interface.
- # @param type_name The type name of the interface.
- # @param pol The interface's polarity (RTC::PROVIDED or RTC:REQUIRED)
- #
- # @return false would be returned if the same name is already registered.
- #
- # @endif
- # bool appendInterface(const char* name, const char* type_name,
- # PortInterfacePolarity pol);
- def appendInterface(self, instance_name, type_name, pol):
- index = OpenRTM_aist.CORBA_SeqUtil.find(self._profile.interfaces,
- self.find_interface(instance_name, pol))
-
- if index >= 0:
- return False
-
- # setup PortInterfaceProfile
- prof = RTC.PortInterfaceProfile(instance_name, type_name, pol)
- OpenRTM_aist.CORBA_SeqUtil.push_back(self._profile.interfaces, prof)
-
- return True
-
-
- ##
- # @if jp
- #
- # @brief PortInterfaceProfile からインターフェース登録を削除する
- #
- # このオペレーションは Port が持つ PortProfile の、PortInterfaceProfile
- # からインターフェースの情報を削除する。
- #
- # @param self
- # @param name インターフェースのインスタンスの名前
- # @param pol インターフェースの属性 (RTC::PROVIDED もしくは RTC:REQUIRED)
- #
- # @return インターフェース削除処理結果。
- # インターフェースが登録されていなければ false を返す。
- #
- # @else
- #
- # @brief Delete an interface from the PortInterfaceProfile
- #
- # This operation deletes interface information from the
- # PortInterfaceProfile that is owned by the Port.
- #
- # @param name The instance name of the interface.
- # @param pol The interface's polarity (RTC::PROVIDED or RTC:REQUIRED)
- #
- # @return false would be returned if the given name is not registered.
- #
- # @endif
- # bool deleteInterface(const char* name, PortInterfacePolarity pol);
- def deleteInterface(self, name, pol):
- index = OpenRTM_aist.CORBA_SeqUtil.find(self._profile.interfaces,
- self.find_interface(name, pol))
-
- if index < 0:
- return False
-
- OpenRTM_aist.CORBA_SeqUtil.erase(self._profile.interfaces, index)
- return True
-
-
- ##
- # @if jp
- #
- # @brief PortProfile の properties に NameValue 値を追加する
- #
- # PortProfile の properties に NameValue 値を追加する。
- # 追加するデータの型をValueTypeで指定する。
- #
- # @param self
- # @param key properties の name
- # @param value properties の value
- #
- # @else
- #
- # @brief Add NameValue data to PortProfile's properties
- #
- # @param key The name of properties
- # @param value The value of properties
- #
- # @endif
- # template <class ValueType>
- # void addProperty(const char* key, ValueType value)
- def addProperty(self, key, value):
- OpenRTM_aist.CORBA_SeqUtil.push_back(self._profile.properties,
- OpenRTM_aist.NVUtil.newNV(key, value))
-
- ##
- # @if jp
- #
- # @brief PortProfile の properties に NameValue 値を要素に追加する
- #
- # PortProfile の properties に NameValue 値を要素に追加する。
- #
- # @param key properties の name
- # @param value properties の value
- #
- # @else
- #
- # @brief Append NameValue data to PortProfile's properties
- #
- # Append NameValue data to PortProfile's properties.
- #
- # @param key The name of properties
- # @param value The value of properties
- #
- # @endif
- # void appendProperty(const char* key, const char* value)
- def appendProperty(self, key, value):
- OpenRTM_aist.NVUtil.appendStringValue(self._profile.properties, key, value)
-
-
-
- ##
- # @if jp
- #
- # @brief 存在しないポートをdisconnectする。
- #
- # @else
- #
- # @brief Disconnect ports that doesn't exist.
- #
- # @endif
- # void updateConnectors()
- def updateConnectors(self):
- guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
-
- connector_ids = []
- clist = self._profile.connector_profiles
-
- for cprof in clist:
- if not self.checkPorts(cprof.ports):
- connector_ids.append(cprof.connector_id)
- self._rtcout.RTC_WARN("Dead connection: %s", cprof.connector_id)
-
- for cid in connector_ids:
- self.disconnect(cid)
-
- return
-
-
- ##
- # @if jp
- #
- # @brief ポートの存在を確認する。
- #
- # @param ports 確認するポート
- # @return true:存在する,false:存在しない
- #
- # @else
- #
- # @brief Existence of ports
- #
- # @param ports Checked ports
- # @return true:existent,false:non existent
- #
- # @endif
- # bool checkPorts(::RTC::PortServiceList& ports)
- def checkPorts(self, ports):
- for port in ports:
- try:
- if port._non_existent():
- self._rtcout.RTC_WARN("Dead Port reference detected.")
- return False
- except:
- self._rtcout.RTC_WARN(OpenRTM_aist.Logger.print_exception())
- return False
-
- return True
-
-
- #inline void onNotifyConnect(const char* portname,
- # RTC::ConnectorProfile& profile)
- def onNotifyConnect(self, portname, profile):
- if self._portconnListeners != None:
- type = OpenRTM_aist.PortConnectListenerType.ON_NOTIFY_CONNECT
- self._portconnListeners.portconnect_[type].notify(portname, profile)
- return
-
-
- #inline void onNotifyDisconnect(const char* portname,
- # RTC::ConnectorProfile& profile)
- def onNotifyDisconnect(self, portname, profile):
- if self._portconnListeners != None:
- type = OpenRTM_aist.PortConnectListenerType.ON_NOTIFY_DISCONNECT
- self._portconnListeners.portconnect_[type].notify(portname, profile)
- return
-
-
- #inline void onUnsubscribeInterfaces(const char* portname,
- # RTC::ConnectorProfile& profile)
- def onUnsubscribeInterfaces(self, portname, profile):
- if self._portconnListeners != None:
- type = OpenRTM_aist.PortConnectListenerType.ON_UNSUBSCRIBE_INTERFACES
- self._portconnListeners.portconnect_[type].notify(portname, profile)
- return
-
-
- #inline void onPublishInterfaces(const char* portname,
- # RTC::ConnectorProfile& profile,
- # ReturnCode_t ret)
- def onPublishInterfaces(self, portname, profile, ret):
- if self._portconnListeners != None:
- type = OpenRTM_aist.PortConnectRetListenerType.ON_PUBLISH_INTERFACES
- self._portconnListeners.portconnret_[type].notify(portname, profile, ret)
- return
-
-
- #inline void onConnectNextport(const char* portname,
- # RTC::ConnectorProfile& profile,
- # ReturnCode_t ret)
- def onConnectNextport(self, portname, profile, ret):
- if self._portconnListeners != None:
- type = OpenRTM_aist.PortConnectRetListenerType.ON_CONNECT_NEXTPORT
- self._portconnListeners.portconnret_[type].notify(portname, profile, ret)
- return
-
-
- #inline void onSubscribeInterfaces(const char* portname,
- # RTC::ConnectorProfile& profile,
- # ReturnCode_t ret)
- def onSubscribeInterfaces(self, portname, profile, ret):
- if self._portconnListeners != None:
- type = OpenRTM_aist.PortConnectRetListenerType.ON_SUBSCRIBE_INTERFACES
- self._portconnListeners.portconnret_[type].notify(portname, profile, ret)
- return
-
-
- #inline void onConnected(const char* portname,
- # RTC::ConnectorProfile& profile,
- # ReturnCode_t ret)
- def onConnected(self, portname, profile, ret):
- if self._portconnListeners != None:
- type = OpenRTM_aist.PortConnectRetListenerType.ON_CONNECTED
- self._portconnListeners.portconnret_[type].notify(portname, profile, ret)
- return
-
-
- #inline void onDisconnectNextport(const char* portname,
- # RTC::ConnectorProfile& profile,
- # ReturnCode_t ret)
- def onDisconnectNextport(self, portname, profile, ret):
- if self._portconnListeners != None:
- type = OpenRTM_aist.PortConnectRetListenerType.ON_DISCONNECT_NEXT
- self._portconnListeners.portconnret_[type].notify(portname, profile, ret)
- return
-
-
- #inline void onDisconnected(const char* portname,
- # RTC::ConnectorProfile& profile,
- # ReturnCode_t ret)
- def onDisconnected(self, portname, profile, ret):
- if self._portconnListeners != None:
- type = OpenRTM_aist.PortConnectRetListenerType.ON_DISCONNECTED
- self._portconnListeners.portconnret_[type].notify(portname, profile, ret)
- return
-
-
-
-
- #============================================================
- # Functor
- #============================================================
-
- ##
- # @if jp
- # @class if_name
- # @brief instance_name を持つ PortInterfaceProfile を探す Functor
- # @else
- # @brief A functor to find a PortInterfaceProfile named instance_name
- # @endif
- class if_name:
- def __init__(self, name):
- self._name = name
-
- def __call__(self, prof):
- return str(self._name) == str(prof.instance_name)
-
-
- ##
- # @if jp
- # @class find_conn_id
- # @brief id を持つ ConnectorProfile を探す Functor
- # @else
- # @brief A functor to find a ConnectorProfile named id
- # @endif
- class find_conn_id:
- def __init__(self, id_):
- """
- \param id_(string)
- """
- self._id = id_
-
- def __call__(self, cprof):
- """
- \param cprof(RTC.ConnectorProfile)
- """
- return str(self._id) == str(cprof.connector_id)
-
- ##
- # @if jp
- # @class find_port_ref
- # @brief コンストラクタ引数 port_ref と同じオブジェクト参照を探す Functor
- # @else
- # @brief A functor to find the object reference that is identical port_ref
- # @endif
- class find_port_ref:
- def __init__(self, port_ref):
- """
- \param port_ref(RTC.PortService)
- """
- self._port_ref = port_ref
-
- def __call__(self, port_ref):
- """
- \param port_ref(RTC.PortService)
- """
- return self._port_ref._is_equivalent(port_ref)
-
- ##
- # @if jp
- # @class connect_func
- # @brief Port の接続を行う Functor
- # @else
- # @brief A functor to connect Ports
- # @endif
- class connect_func:
- def __init__(self, p, prof):
- """
- \param p(RTC.PortService)
- \param prof(RTC.ConnectorProfile)
- """
- self._port_ref = p
- self._connector_profile = prof
- self.return_code = RTC.RTC_OK
-
- def __call__(self, p):
- """
- \param p(RTC.PortService)
- """
- if not self._port_ref._is_equivalent(p):
- retval = p.notify_connect(self._connector_profile)
- if retval != RTC.RTC_OK:
- self.return_code = retval
-
- ##
- # @if jp
- # @class disconnect_func
- # @brief Port の接続解除を行う Functor
- # @else
- # @brief A functor to disconnect Ports
- # @endif
- class disconnect_func:
- def __init__(self, p, prof):
- """
- \param p(RTC.PortService)
- \param prof(RTC.ConnectorProfile)
- """
- self._port_ref = p
- self._connector_profile = prof
- self.return_code = RTC.RTC_OK
-
- def __call__(self, p):
- """
- \param p(RTC.PortService)
- """
- if not self._port_ref._is_equivalent(p):
- retval = p.disconnect(self._connector_profile.connector_id)
- if retval != RTC.RTC_OK:
- self.return_code = retval
-
- ##
- # @if jp
- # @class disconnect_all_func
- # @brief Port の全接続解除を行う Functor
- # @else
- # @brief A functor to disconnect all Ports
- # @endif
- class disconnect_all_func:
- def __init__(self, p):
- """
- \param p(OpenRTM_aist.PortBase)
- """
- self.return_code = RTC.RTC_OK
- self._port = p
-
- def __call__(self, p):
- """
- \param p(RTC.ConnectorProfile)
- """
- retval = self._port.disconnect(p.connector_id)
- if retval != RTC.RTC_OK:
- self.return_code = retval
-
- ##
- # @if jp
- # @class find_interface
- # @brief name と polarity から interface を探す Functor
- # @else
- # @brief A functor to find interface from name and polarity
- # @endif
- class find_interface:
- def __init__(self, name, pol):
- """
- \param name(string)
- \param pol(RTC.PortInterfacePolarity)
- """
- self._name = name
- self._pol = pol
-
- def __call__(self, prof):
- """
- \param prof(RTC.PortInterfaceProfile)
- """
- name = prof.instance_name
- return (str(self._name) == str(name)) and (self._pol == prof.polarity)
+#!/usr/bin/env python
+# -*- coding: euc-jp -*-
+
+##
+# @file PortBase.py
+# @brief RTC's Port base class
+# @date $Date: 2007/09/18 $
+# @author Noriaki Ando <n-ando at aist.go.jp> and Shinji Kurihara
+#
+# Copyright (C) 2006-2008
+# Task-intelligence Research Group,
+# Intelligent Systems Research Institute,
+# National Institute of
+# Advanced Industrial Science and Technology (AIST), Japan
+# All rights reserved.
+
+
+import threading
+import copy
+
+import OpenRTM_aist
+import RTC, RTC__POA
+
+
+
+##
+# @if jp
+# @class PortBase
+# @brief Port の基底クラス
+#
+# RTC::Port の基底となるクラス。
+# RTC::Port はほぼ UML Port の概念を継承しており、ほぼ同等のものとみなす
+# ことができる。RT コンポーネントのコンセプトにおいては、
+# Port はコンポーネントに付属し、コンポーネントが他のコンポーネントと相互作用
+# を行う接点であり、通常幾つかのインターフェースと関連付けられる。
+# コンポーネントは Port を通して外部に対しインターフェースを提供または要求
+# することができ、Portはその接続を管理する役割を担う。
+# <p>
+# Port の具象クラスは、通常 RT コンポーネントインスタンス生成時に同時に
+# 生成され、提供・要求インターフェースを登録した後、RT コンポーネントに
+# 登録され、外部からアクセス可能な Port として機能することを想定している。
+# <p>
+# RTC::Port は CORBA インターフェースとして以下のオペレーションを提供する。
+#
+# - get_port_profile()
+# - get_connector_profiles()
+# - get_connector_profile()
+# - connect()
+# - notify_connect()
+# - disconnect()
+# - notify_disconnect()
+# - disconnect_all()
+#
+# このクラスでは、これらのオペレーションの実装を提供する。
+# <p>
+# これらのオペレーションのうち、get_port_profile(), get_connector_profiles(),
+# get_connector_profile(), connect(), disconnect(), disconnect_all() は、
+# サブクラスにおいて特に振る舞いを変更する必要がないため、オーバーライド
+# することは推奨されない。
+# <p>
+# notify_connect(), notify_disconnect() については、サブクラスが提供・要求
+# するインターフェースの種類に応じて、振る舞いを変更する必要が生ずる
+# かもしれないが、これらを直接オーバーライドすることは推奨されず、
+# 後述の notify_connect(), notify_disconnect() の項においても述べられる通り
+# これらの関数に関連した 関数をオーバーライドすることにより振る舞いを変更する
+# ことが推奨される。
+#
+# @since 0.4.0
+#
+# @else
+# @class PortBase
+# @brief Port base class
+#
+# This class is a base class of RTC::Port.
+# RTC::Port inherits a concept of RT-Component, and can be regarded as almost
+# the same as it. In the concept of RT-Component, Port is attached to the
+# component, can mediate interaction between other components and usually is
+# associated with some interfaces.
+# Component can provide or require interface for outside via Port, and the
+# Port plays a role to manage the connection.
+# <p>
+# Concrete class of Port assumes to be usually created at the same time that
+# RT-Component's instance is created, be registerd to RT-Component after
+# provided and required interfaces are registerd, and function as accessible
+# Port from outside.
+# <p>
+# RTC::Port provides the following operations as CORBA interface:
+#
+# - get_port_profile()
+# - get_connector_profiles()
+# - get_connector_profile()
+# - connect()
+# - notify_connect()
+# - disconnect()
+# - notify_disconnect()
+# - disconnect_all()
+#
+# This class provides implementations of these operations.
+# <p>
+# In these operations, as for get_port_profile(), get_connector_profiles(),
+# get_connector_profile(), connect(), disconnect() and disconnect_all(),
+# since their behaviors especially need not to be change in subclass,
+# overriding is not recommended.
+# <p>
+# As for notify_connect() and notify_disconnect(), you may have to modify
+# behavior according to the kind of interfaces that subclass provides and
+# requires, however it is not recommended these are overriden directly.
+# In the section of notify_connect() and notify_disconnect() as described
+# below, it is recommended that you modify behavior by overriding the
+# protected function related to these functions.
+#
+# @since 0.4.0
+#
+# @endif
+class PortBase(RTC__POA.PortService):
+ """
+ """
+
+
+
+ ##
+ # @if jp
+ # @brief コンストラクタ
+ #
+ # PortBase のコンストラクタは Port 名 name を引数に取り初期化を行う
+ # と同時に、自分自身を CORBA Object として活性化し、自身の PortProfile
+ # の port_ref に自身のオブジェクトリファレンスを格納する。
+ # 名前には、"." 以外の文字列を使用することができる。
+ #
+ # @param self
+ # @param name Port の名前(デフォルト値:None)
+ #
+ # @else
+ #
+ # @brief Constructor
+ #
+ # The constructor of the ProtBase class is given the name of this Port
+ # and initialized. At the same time, the PortBase activates itself
+ # as CORBA object and stores its object reference to the PortProfile's
+ # port_ref member.
+ # Characters except "." can be used for the name of the port.
+ #
+ # @param name The name of Port
+ #
+ # @endif
+ def __init__(self, name=None):
+ self._ownerInstanceName = "unknown"
+ self._objref = self._this()
+
+ self._profile = RTC.PortProfile("", [], RTC.PortService._nil, [], RTC.RTObject._nil,[])
+ # Now Port name is <instance_name>.<port_name>. r1648
+ if name is None:
+ self._profile.name = "unknown.unknown"
+ else:
+ self._profile.name = self._ownerInstanceName+"."+name
+
+ self._profile.port_ref = self._objref
+ self._profile.owner = RTC.RTObject._nil
+ self._profile_mutex = threading.RLock()
+ self._connection_mutex = threading.RLock()
+ self._rtcout = OpenRTM_aist.Manager.instance().getLogbuf(name)
+ self._onPublishInterfaces = None
+ self._onSubscribeInterfaces = None
+ self._onConnected = None
+ self._onUnsubscribeInterfaces = None
+ self._onDisconnected = None
+ self._onConnectionLost = None
+ self._connectionLimit = -1
+ self._portconnListeners = None
+ return
+
+
+ ##
+ # @if jp
+ #
+ # @brief デストラクタ
+ #
+ # デストラクタでは、PortService CORBA オブジェクトの deactivate を
+ # 行う。deactivateに際して例外を投げることはない。
+ #
+ # @else
+ #
+ # @brief Destructor
+ #
+ # In the destructor, PortService CORBA object is deactivated.
+ # This function never throws exception.
+ #
+ # @endif
+ #
+ def __del__(self):
+ self._rtcout.RTC_TRACE("PortBase.__del__()")
+ try:
+ mgr = OpenRTM_aist.Manager.instance().getPOA()
+ oid = mgr.servant_to_id(self)
+ mgr.deactivate_object(oid)
+ except:
+ self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
+
+
+ ##
+ # @if jp
+ #
+ # @brief [CORBA interface] PortProfileを取得する
+ #
+ # Portが保持するPortProfileを返す。
+ # PortProfile 構造体は以下のメンバーを持つ。
+ #
+ # - name [string 型] Port の名前。
+ # - interfaces [PortInterfaceProfileList 型] Port が保持する
+ # PortInterfaceProfile のシーケンス
+ # - port_ref [Port Object 型] Port 自身のオブジェクトリファレンス
+ # - connector_profile [ConnectorProfileList 型] Port が現在保持する
+ # ConnectorProfile のシーケンス
+ # - owner [RTObject Object 型] この Port を所有する
+ # RTObjectのリファレンス
+ # - properties [NVList 型] その他のプロパティ。
+ #
+ # @param self
+ #
+ # @return PortProfile
+ #
+ # @else
+ #
+ # @brief [CORBA interface] Get the PortProfile of the Port
+ #
+ # This operation returns the PortProfile of the Port.
+ # PortProfile struct has the following members,
+ #
+ # - name [string ] The name of the Port.
+ # - interfaces [PortInterfaceProfileList] The sequence of
+ # PortInterfaceProfile owned by the Port
+ # - port_ref [Port Object] The object reference of the Port.
+ # - connector_profile [ConnectorProfileList] The sequence of
+ # ConnectorProfile owned by the Port.
+ # - owner [RTObject Object] The object reference of
+ # RTObject that is owner of the Port.
+ # - properties [NVList] The other properties.
+ #
+ # @return the PortProfile of the Port
+ #
+ # @endif
+ # PortProfile* get_port_profile()
+ def get_port_profile(self):
+ self._rtcout.RTC_TRACE("get_port_profile()")
+
+ self.updateConnectors()
+
+ guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
+
+ prof = RTC.PortProfile(self._profile.name,
+ self._profile.interfaces,
+ self._profile.port_ref,
+ self._profile.connector_profiles,
+ self._profile.owner,
+ self._profile.properties)
+
+ return prof
+
+
+ ##
+ # @if jp
+ #
+ # @brief PortProfile を取得する。
+ #
+ # この関数は、オブジェクト内部に保持されている PortProfile の
+ # const 参照を返す const 関数である。
+ #
+ # @post この関数を呼び出すことにより内部状態が変更されることはない。
+ #
+ # @return PortProfile
+ #
+ # @else
+ #
+ # @brief Get the PortProfile of the Port
+ #
+ # This function is a const function that returns a const
+ # reference of the PortProfile stored in this Port.
+ #
+ # @post This function never changes the state of the object.
+ #
+ # @return PortProfile
+ #
+ # @endif
+ # PortProfile& getPortProfile() const;
+ def getPortProfile(self):
+ self._rtcout.RTC_TRACE("getPortProfile()")
+ return self._profile
+
+
+ ##
+ # @if jp
+ #
+ # @brief [CORBA interface] ConnectorProfileListを取得する
+ #
+ # Portが保持する ConnectorProfile の sequence を返す。
+ # ConnectorProfile は Port 間の接続プロファイル情報を保持する構造体であり、
+ # 接続時にPort間で情報交換を行い、関連するすべての Port で同一の値が
+ # 保持される。
+ # ConnectorProfile は以下のメンバーを保持している。
+ #
+ # - name [string 型] このコネクタの名前。
+ # - connector_id [string 型] ユニークなID
+ # - ports [Port sequnce] このコネクタに関連する Port のオブジェクト
+ # リファレンスのシーケンス。
+ # - properties [NVList 型] その他のプロパティ。
+ #
+ # @param self
+ #
+ # @return この Port が保持する ConnectorProfile
+ #
+ # @else
+ #
+ # @brief [CORBA interface] Get the ConnectorProfileList of the Port
+ #
+ # This operation returns a list of the ConnectorProfiles of the Port.
+ # ConnectorProfile includes the connection information that describes
+ # relation between (among) Ports, and Ports exchange the ConnectionProfile
+ # on connection process and hold the same information in each Port.
+ # ConnectionProfile has the following members,
+ #
+ # - name [string] The name of the connection.
+ # - connector_id [string] Unique identifier.
+ # - ports [Port sequnce] The sequence of Port's object reference
+ # that are related the connection.
+ # - properties [NVList] The other properties.
+ #
+ # @return the ConnectorProfileList of the Port
+ #
+ # @endif
+ # virtual ConnectorProfileList* get_connector_profiles()
+ def get_connector_profiles(self):
+ self._rtcout.RTC_TRACE("get_connector_profiles()")
+
+ self.updateConnectors()
+
+ guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
+ return self._profile.connector_profiles
+
+
+ ##
+ # @if jp
+ #
+ # @brief [CORBA interface] ConnectorProfile を取得する
+ #
+ # connector_id で指定された ConnectorProfile を返す。
+ # 指定した connector_id を持つ ConnectorProfile を保持していない場合は、
+ # 空の ConnectorProfile を返す。
+ #
+ # @param self
+ # @param connector_id ConnectorProfile の ID
+ #
+ # @return connector_id で指定された ConnectorProfile
+ #
+ # @else
+ #
+ # @brief [CORBA interface] Get the ConnectorProfile
+ #
+ # This operation returns the ConnectorProfiles specified connector_id.
+ #
+ # @param connector_id ID of the ConnectorProfile
+ #
+ # @return the ConnectorProfile identified by the connector_id
+ #
+ # @endif
+ # ConnectorProfile* get_connector_profile(const char* connector_id)
+ def get_connector_profile(self, connector_id):
+ self._rtcout.RTC_TRACE("get_connector_profile(%s)", connector_id)
+
+ self.updateConnectors()
+
+ guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
+ index = OpenRTM_aist.CORBA_SeqUtil.find(self._profile.connector_profiles,
+ self.find_conn_id(connector_id))
+ if index < 0:
+ conn_prof = RTC.ConnectorProfile("","",[],[])
+ return conn_prof
+
+ conn_prof = RTC.ConnectorProfile(self._profile.connector_profiles[index].name,
+ self._profile.connector_profiles[index].connector_id,
+ self._profile.connector_profiles[index].ports,
+ self._profile.connector_profiles[index].properties)
+ return conn_prof
+
+
+ ##
+ # @if jp
+ #
+ # @brief [CORBA interface] Port の接続を行う
+ #
+ # 与えられた ConnectoionProfile の情報に基づき、Port間の接続を確立
+ # する。この関数は主にアプリケーションプログラムやツールから呼び出
+ # すことを前提としている。
+ #
+ # @pre アプリケーションプログラムは、コンポーネント間の複数の
+ # Port を接続するために、適切な値をセットした ConnectorProfile を
+ # connect() の引数として与えて呼び出さなければならない。
+ #
+ # @pre connect() に与える ConnectorProfile のメンバーのうち、
+ # name, ports, properties メンバーに対してデータをセットしなければ
+ # ならない。connector_id には通常空文字を設定するか、適当なUUIDを
+ # 文字列で設定する必要がある。
+ #
+ # @pre ConnectorProfile::name は接続につける名前で CORBA::string
+ # 型に格納できる任意の文字列である必要がある。
+ #
+ # @pre ConnectorProfile::connector_id はすべての接続に対して一意な
+ # ID (通常はUUID) が格納される。UUIDの設定は connect() 関数内で行
+ # われるので、呼び出し側は空文字を設定する。既存の接続と同じUUIDを
+ # 設定し connect() を呼び出した場合には PRECONDITION_NOT_MET エラー
+ # を返す。ただし、将来の拡張で既存の接続プロファイルを更新するため
+ # に既存の UUID を設定して呼び出す使用法が用いられる可能性がある。
+ #
+ # @pre ConnectorProfile::ports は RTC::PortService のシーケンスで、
+ # 接続を構成する通常2つ以上のポートのオブジェクト参照を代入する必
+ # 要がある。例外として、ポートのオブジェクト参照を1つだけ格納して
+ # connect()を呼び出すことで、ポートのインターフェース情報を取得し
+ # たり、特殊なポート(CORBAのRTC::PortService以外の相手)に対して接
+ # 続を行う場合もある。
+ #
+ # @pre ConnectorProfile::properties はポートに関連付けられたインター
+ # フェースに対するプロパティを与えるために使用する。プロパティは、
+ # string 型をキー、Any 型を値としてもつペアのシーケンスであり、値
+ # には任意のCORBAデータ型を格納できるが、可能な限り string 型とし
+ # て格納されることが推奨される。
+ #
+ # @pre 以上 connect() 呼び出し時に設定する ConnectorProfile のメン
+ # バをまとめると以下のようになる。
+ #
+ # - ConnectorProfile::name: 任意の接続名
+ # - ConnectorProfile::connector_id: 空文字
+ # - ConnectorProfile::ports: 1つ以上のポート
+ # - ConnectorProfile::properties: インターフェースに対するプロパティ
+ #
+ # @post connect() 関数は、ConnectorProfile::portsに格納されたポー
+ # トシーケンスの先頭のポートに対して notify_connect() を呼ぶ。
+ #
+ # @post notify_connect() は ConnectorProfile::ports に格納されたポー
+ # ト順に notify_connect() をカスケード呼び出しする。このカスケード
+ # 呼び出しは、途中のnotify_connect() でエラーが出てもポートのオブ
+ # ジェクト参照が有効である限り、必ずすべてのポートに対して行われる
+ # ことが保証される。有効でないオブジェクト参照がシーケンス中に存在
+ # する場合、そのポートをスキップして、次のポートに対して
+ # notify_connect() を呼び出す。
+ #
+ # @post connect() 関数は、notify_connect()の戻り値がRTC_OKであれば、
+ # RTC_OK を返す。この時点で接続は完了する。RTC_OK以外
+ # の場合は、この接続IDに対してdisconnect()を呼び出し接続を解除し、
+ # notify_connect() が返したエラーリターンコードをそのまま返す。
+ #
+ # @post connect() の引数として渡した ConnectorProfile には、
+ # ConnectorProfile::connector_id および、途中のポートが
+ # publishInterfaces() で公開したポートインターフェースの各種情報が
+ # 格納されている。connect() および途中の notify_connect() が
+ # ConnectorProfile::{name, ports} を変更することはない。
+ #
+ # @param connector_profile ConnectorProfile
+ # @return ReturnCode_t 型のリターンコード
+ #
+ # @else
+ #
+ # @brief [CORBA interface] Connect the Port
+ #
+ # This operation establishes connection according to the given
+ # ConnectionProfile inforamtion. This function is premised on
+ # calling from mainly application program or tools.
+ #
+ # @pre To establish the connection among Ports of RT-Components,
+ # application programs must call this operation giving
+ # ConnectorProfile with valid values as an argument.
+ #
+ # @pre Out of ConnectorProfile member variables, "name", "ports"
+ # and "properties" members shall be set valid
+ # data. "connector_id" shall be set as empty string value or
+ # valid string UUID value.
+ #
+ # @pre ConnectorProfile::name that is connection identifier shall
+ # be any valid CORBA::string.
+ #
+ #
+ # @pre ConnectorProfile::connector_id shall be set unique
+ # identifier (usually UUID is used) for all connections. Since
+ # UUID string value is usually set in the connect() function,
+ # caller should just set empty string. If the connect() is called
+ # with the same UUID as existing connection, this function
+ # returns PRECONDITION_NOT_MET error. However, in order to update
+ # the existing connection profile, the "connect()" operation with
+ # existing connector ID might be used as valid method by future
+ # extension
+ #
+ # @pre ConnectorProfile::ports, which is sequence of
+ # RTC::PortService references, shall store usually two or more
+ # ports' references. As exceptions, the "connect()" operation
+ # might be called with only one reference in ConnectorProfile, in
+ # case of just getting interfaces information from the port, or
+ # connecting a special port (i.e. the peer port except
+ # RTC::PortService on CORBA).
+ #
+ # @pre ConnectorProfile::properties might be used to give certain
+ # properties to the service interfaces associated with the port.
+ # The properties is a sequence variable with a pair of key string
+ # and Any type value. Although the A variable can store any type
+ # of values, it is not recommended except string.
+ #
+ # @pre The following is the summary of the ConnectorProfile
+ # member to be set when this operation is called.
+ #
+ # - ConnectorProfile::name: The any name of connection
+ # - ConnectorProfile::connector_id: Empty string
+ # - ConnectorProfile::ports: One or more port references
+ # - ConnectorProfile::properties: Properties for the interfaces
+ #
+ # @post connect() operation will call the first port in the
+ # sequence of the ConnectorProfile.
+ #
+ # @post "noify_connect()"s perform cascaded call to the ports
+ # stored in the ConnectorProfile::ports by order. Even if errors
+ # are raised by intermediate notify_connect() operation, as long
+ # as ports' object references are valid, it is guaranteed that
+ # this cascaded call is completed in all the ports. If invalid
+ # or dead ports exist in the port's sequence, the ports are
+ # skipped and notify_connect() is called for the next valid port.
+ #
+ # @post connect() function returns RTC_OK if all the
+ # notify_connect() return RTC_OK. At this time the connection is
+ # completed. If notify_connect()s return except RTC_OK,
+ # connect() calls disconnect() operation with the connector_id to
+ # destruct the connection, and then it returns error code from
+ # notify_connect().
+ #
+ # @post The ConnectorProfile argument of the connect() operation
+ # returns ConnectorProfile::connector_id and various information
+ # about service interfaces that is published by
+ # publishInterfaces() in the halfway ports. The connect() and
+ # halfway notify_connect() functions never change
+ # ConnectorProfile::{name, ports}.
+ #
+ # @param connector_profile The ConnectorProfile.
+ # @return ReturnCode_t The return code of ReturnCode_t type.
+ #
+ # @endif
+ #
+ # virtual ReturnCode_t connect(ConnectorProfile& connector_profile)
+ def connect(self, connector_profile):
+ self._rtcout.RTC_TRACE("connect()")
+ if self.isEmptyId(connector_profile):
+ guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
+ self.setUUID(connector_profile)
+ assert(not self.isExistingConnId(connector_profile.connector_id))
+ del guard
+ else:
+ guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
+ if self.isExistingConnId(connector_profile.connector_id):
+ self._rtcout.RTC_ERROR("Connection already exists.")
+ return (RTC.PRECONDITION_NOT_MET,connector_profile)
+ del guard
+
+ try:
+ retval,connector_profile = connector_profile.ports[0].notify_connect(connector_profile)
+ if retval != RTC.RTC_OK:
+ self._rtcout.RTC_ERROR("Connection failed. cleanup.")
+ self.disconnect(connector_profile.connector_id)
+
+ return (retval, connector_profile)
+ #return connector_profile.ports[0].notify_connect(connector_profile)
+ except:
+ self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
+ return (RTC.BAD_PARAMETER, connector_profile)
+
+ return (RTC.RTC_ERROR, connector_profile)
+
+
+ ##
+ # @if jp
+ #
+ # @brief [CORBA interface] Port の接続通知を行う
+ #
+ # このオペレーションは、Port間の接続が行われる際に、Port間で内部的
+ # に呼ばれるオペレーションであって、通常アプリケーションプログラム
+ # や、Port以外のRTC関連オブジェクト等から呼び出されることは想定さ
+ # れていない。
+ #
+ # notify_connect() 自体はテンプレートメソッドパターンとして、サブ
+ # クラスで実装されることが前提の publishInterfaces(),
+ # subscribeInterfaces() の2つの関数を内部で呼び出す。処理の手順は
+ # 以下の通りである。
+ #
+ # - publishInterfaces(): インターフェース情報の公開
+ # - connectNext(): 次の Port の notify_connect() の呼び出し
+ # - subscribeInterfaces(): インターフェース情報の取得
+ # - 接続情報の保存
+ #
+ # notify_connect() は ConnectorProfile::ports に格納されている
+ # Port の順序に従って、カスケード状に呼び出しを行うことにより、イ
+ # ンターフェース情報の公開と取得を関連すすべてのポートに対して行う。
+ # このカスケード呼び出しは途中で中断されることはなく、必ず
+ # ConnectorProfile::ports に格納されている全ポートに対して行われる。
+ #
+ # @pre notify_connect() は ConnectorProfile::ports 内に格納されて
+ # いる Port 参照リストのうち、当該 Port 自身の参照の次に格納されて
+ # いる Port に対して notify_connect() を呼び出す。したがって
+ # ConnectorProfile::ports には当該 Port の参照が格納されている必要
+ # がある。もし、自身の参照が格納されていない場合、その他の処理によ
+ # りエラーが上書きされなければ、BAD_PARAMETER エラーが返される。
+ #
+ # @pre 呼び出し時に ConnectorProfile::connector_id には一意なIDと
+ # して UUID が保持されている必要がある。通常 connector_id は
+ # connect() 関数により与えられ、空文字の場合は動作は未定義である。
+ #
+ # @post ConnectorProfile::name, ConnectorProfile::connector_id,
+ # ConnectorProfile::ports は notify_connect() の呼び出しにより
+ # 書き換えられることはなく不変である。
+ #
+ # @post ConnectorProfile::properties は notify_connect() の内部で、
+ # 当該 Port が持つサービスインターフェースに関する情報を他の Port
+ # に伝えるために、プロパティ情報が書き込まれる。
+ #
+ # @post なお、ConnectorProfile::ports のリストの最初 Port の
+ # notify_connet() が終了した時点では、すべての関連する Port の
+ # notify_connect() の呼び出しが完了する。publishInterfaces(),
+ # connectNext(), subscribeInterfaces() および接続情報の保存のいず
+ # れかの段階でエラーが発生した場合でも、エラーコードは内部的に保持
+ # されており、最初に生じたエラーのエラーコードが返される。
+ #
+ # @param connector_profile ConnectorProfile
+ # @return ReturnCode_t 型のリターンコード
+ #
+ # @else
+ #
+ # @brief [CORBA interface] Notify the Ports connection
+ #
+ # This operation is usually called from other ports' connect() or
+ # notify_connect() operations when connection between ports is
+ # established. This function is not premised on calling from
+ # other functions or application programs.
+ #
+ # According to the template method pattern, the notify_connect()
+ # calls "publishInterfaces()" and "subsctiveInterfaces()"
+ # functions, which are premised on implementing in the
+ # subclasses. The processing sequence is as follows.
+ #
+ # - publishInterfaces(): Publishing interface information
+ # - connectNext(): Calling notify_connect() of the next port
+ # - subscribeInterfaces(): Subscribing interface information
+ # - Storing connection profile
+ #
+ # According to the order of port's references stored in the
+ # ConnectorProfile::ports, publishing interface information to
+ # all the ports and subscription interface information from all
+ # the ports is performed by "notify_connect()"s. This cascaded
+ # call never aborts in the halfway operations, and calling
+ # sequence shall be completed for all the ports.
+ #
+ # @pre notify_connect() calls notify_connect() for the port's
+ # reference that is stored in next of this port's reference in
+ # the sequence of the ConnectorProfile::ports. Therefore the
+ # reference of this port shall be stored in the
+ # ConnectorProfile::ports. If this port's reference is not stored
+ # in the sequence, BAD_PARAMETER error will be returned, except
+ # the return code is overwritten by other operations.
+ #
+ # @pre UUID shall be set to ConnectorProfile::connector_id as a
+ # unique identifier when this operation is called. Usually,
+ # connector_id is given by a connect() function and, the behavior
+ # is undefined in the case of a null character.
+ #
+ # @post ConnectorProfile::name, ConnectorProfile::connector_id,
+ # ConnectorProfile::ports are invariant, and they are never
+ # rewritten by notify_connect() operations.
+ #
+ # @post In order to transfer interface information to other
+ # ports, interface property information is stored into the
+ # ConnectorProfile::properties.
+ #
+ # @post At the end of notify_connect() operation for the first
+ # port stored in the ConnectorProfile::ports sequence, the
+ # related ports' notify_connect() invocations complete. Even if
+ # errors are raised at the halfway of publishInterfaces(),
+ # connectNext(), subscribeInterfaces() and storing process of
+ # ConnectorProfile, error codes are saved and the first error is
+ # returned.
+ #
+ # @param connector_profile The ConnectorProfile.
+ # @return ReturnCode_t The return code of ReturnCode_t type.
+ #
+ # @endif
+ #
+ # virtual ReturnCode_t notify_connect(ConnectorProfile& connector_profile)
+ def notify_connect(self, connector_profile):
+ self._rtcout.RTC_TRACE("notify_connect()")
+
+ guard_connection = OpenRTM_aist.ScopedLock(self._connection_mutex)
+
+ # publish owned interface information to the ConnectorProfile
+ retval = [RTC.RTC_OK for i in range(3)]
+
+ self.onNotifyConnect(self.getName(),connector_profile)
+ retval[0] = self.publishInterfaces(connector_profile)
+ if retval[0] != RTC.RTC_OK:
+ self._rtcout.RTC_ERROR("publishInterfaces() in notify_connect() failed.")
+
+ self.onPublishInterfaces(self.getName(), connector_profile, retval[0])
+ if self._onPublishInterfaces:
+ self._onPublishInterfaces(connector_profile)
+
+ # call notify_connect() of the next Port
+ retval[1], connector_profile = self.connectNext(connector_profile)
+ if retval[1] != RTC.RTC_OK:
+ self._rtcout.RTC_ERROR("connectNext() in notify_connect() failed.")
+
+ self.onConnectNextport(self.getName(), connector_profile, retval[1])
+ # subscribe interface from the ConnectorProfile's information
+ if self._onSubscribeInterfaces:
+ self._onSubscribeInterfaces(connector_profile)
+
+ retval[2] = self.subscribeInterfaces(connector_profile)
+ if retval[2] != RTC.RTC_OK:
+ self._rtcout.RTC_ERROR("subscribeInterfaces() in notify_connect() failed.")
+ #self.notify_disconnect(connector_profile.connector_id)
+
+ self.onSubscribeInterfaces(self.getName(), connector_profile, retval[2])
+
+ self._rtcout.RTC_PARANOID("%d connectors are existing",
+ len(self._profile.connector_profiles))
+
+ guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
+ # update ConnectorProfile
+ index = self.findConnProfileIndex(connector_profile.connector_id)
+ if index < 0:
+ OpenRTM_aist.CORBA_SeqUtil.push_back(self._profile.connector_profiles,
+ connector_profile)
+ self._rtcout.RTC_PARANOID("New connector_id. Push backed.")
+
+ else:
+ self._profile.connector_profiles[index] = connector_profile
+ self._rtcout.RTC_PARANOID("Existing connector_id. Updated.")
+
+ for ret in retval:
+ if ret != RTC.RTC_OK:
+ self.onConnected(self.getName(), connector_profile, ret)
+ return (ret, connector_profile)
+
+ # connection established without errors
+ if self._onConnected:
+ self._onConnected(connector_profile)
+ self.onConnected(self.getName(), connector_profile, RTC.RTC_OK)
+ return (RTC.RTC_OK, connector_profile)
+
+
+ ##
+ # @if jp
+ #
+ # @brief [CORBA interface] Port の接続を解除する
+ #
+ # このオペレーションは与えられた connector_id に対応する接続を解除
+ # する。connector_id は通常、システム全体において一意な UUID の文
+ # 字列であり、事前に connect()/notify_connect() の呼び出しにより確
+ # 立された接続プロファイル ConnectorProfile::connector_id に対応す
+ # る。
+ #
+ # @pre connector_id は Port が保持する ConnectorProfile の少なくと
+ # も一つの ID に一致する文字列でなければならない。当該 Port が持つ
+ # ConnectorProfile のリスト内に connector_id と同一の ID を持つ
+ # ConnectorProfile が存在しなければこの関数は BAD_PARAMETER エラー
+ # を返す。
+ #
+ # @pre connector_id と同じ ID を持つ ConnectorProfile::ports には
+ # 有効な Port の参照が含まれていなければならない。
+ #
+ # @post disconnect() 関数は、ConnectorProfile::ports の Port の参
+ # 照リストの先頭に対して、notify_disconnect() を呼び出す。参照が無
+ # 効であるなど、notify_disconnect() の呼び出しに失敗した場合には、
+ # 参照リストの先頭から順番に成功するまで notify_disconnect() の呼
+ # び出しを試す。notify_disconnect() の呼び出しに一つでも成功すれば、
+ # notify_disconnect() の返却値をそのまま返し、一つも成功しなかった
+ # 場合には RTC_ERROR エラーを返す。
+ #
+ # @param connector_id ConnectorProfile の ID
+ # @return ReturnCode_t 型のリターンコード
+ #
+ # @else
+ #
+ # @brief [CORBA interface] Disconnect the Port
+ #
+ # This operation destroys connection between this port and the
+ # peer port according to given connector_id. Usually connector_id
+ # should be a UUID string that is unique in the system. And the
+ # connection, which is established by connect()/notify_connect()
+ # functions, is identified by the ConnectorProfile::connector_id.
+ #
+ # @pre connector_id shall be a character string which is same
+ # with ID of at least one of the ConnectorProfiles stored in this
+ # port. If ConnectorProfile that has same ID with the given
+ # connector_id does not exist in the list of ConnectorProfile,
+ # this operation returns BAD_PARAMTER error.
+ #
+ # @pre ConnectorProfile::ports that is same ID with given
+ # connector_id shall store the valid ports' references.
+ #
+ # @post disconnect() function invokes the notify_disconnect() for
+ # the port that is stored in the first of the
+ # ConnectorProfile::ports. If notify_disconnect() call fails for
+ # the first port, It tries on calling "notify_disconnect()" in
+ # order for ports stored in ConnectorProfile::ports until the
+ # operation call is succeeded. If notify_disconnect() succeeded
+ # for at least one port, it returns return code from
+ # notify_disconnect(). If none of notify_connect() call
+ # succeeded, it returns RTC_ERROR error.
+ #
+ # @param connector_id The ID of the ConnectorProfile.
+ # @return ReturnCode_t The return code of ReturnCode_t type.
+ #
+ # @endif
+ #
+ # virtual ReturnCode_t disconnect(const char* connector_id)
+ def disconnect(self, connector_id):
+ self._rtcout.RTC_TRACE("disconnect(%s)", connector_id)
+
+ index = self.findConnProfileIndex(connector_id)
+
+ if index < 0:
+ self._rtcout.RTC_ERROR("Invalid connector id: %s", connector_id)
+ return RTC.BAD_PARAMETER
+
+ guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
+ if index < len(self._profile.connector_profiles):
+ prof = self._profile.connector_profiles[index]
+ del guard
+
+ if len(prof.ports) < 1:
+ self._rtcout.RTC_FATAL("ConnectorProfile has empty port list.")
+ return RTC.PRECONDITION_NOT_MET
+
+ for i in range(len(prof.ports)):
+ p = prof.ports[i]
+ try:
+ return p.notify_disconnect(connector_id)
+ except:
+ self._rtcout.RTC_WARN(OpenRTM_aist.Logger.print_exception())
+ continue
+
+ self._rtcout.RTC_ERROR("notify_disconnect() for all ports failed.")
+ return RTC.RTC_ERROR
+
+
+ ##
+ # @if jp
+ #
+ # @brief [CORBA interface] Port の接続解除通知を行う
+ #
+ # このオペレーションは、Port間の接続解除が行われる際に、Port間で内
+ # 部的に呼ばれるオペレーションであり、通常アプリケーションプログラ
+ # ムや、 Port 以外の RTC 関連オブジェクト等から呼び出されることは
+ # 想定されていない。
+ #
+ # notify_disconnect() 自体はテンプレートメソッドパターンとして、サ
+ # ブクラスで実装されることが前提の unsubscribeInterfaces() 関数を
+ # 内部で呼び出す。処理の手順は以下の通りである。
+ #
+ # - ConnectorProfile の検索
+ # - 次の Port の notify_disconnect() 呼び出し
+ # - unsubscribeInterfaces()
+ # - ConnectorProfile の削除
+ #
+ # notify_disconnect() は ConnectorProfile::ports に格納されている
+ # Port の順序に従って、カスケード状に呼び出しを行うことにより、接
+ # 続の解除をすべての Port に通知する。
+ #
+ # @pre Port は与えられた connector_id に対応する ConnectorProfile
+ # を保持していなければならない。
+ #
+ # @post connector_id に対応する ConnectorProfile が見つからない場
+ # 合はBAD_PARAMETER エラーを返す。
+ #
+ # @post カスケード呼び出しを行う際には ConnectorProfile::ports に
+ # 保持されている Port の参照リストのうち、自身の参照の次の参照に対
+ # して notify_disconnect() を呼び出すが、その呼び出しで例外が発生
+ # した場合には、呼び出しをスキップしリストの次の参照に対して
+ # notify_disconnect() を呼び出す。一つも呼び出しに成功しない場合、
+ # RTC_ERROR エラーコードを返す。
+ #
+ # @post なお、ConnectorProfile::ports のリストの最初 Port の
+ # notify_disconnet() が終了した時点では、すべての関連する Port の
+ # notify_disconnect() の呼び出しが完了する。
+ #
+ # @param connector_id ConnectorProfile の ID
+ # @return ReturnCode_t 型のリターンコード
+ #
+ # @else
+ #
+ # @brief [CORBA interface] Notify the Ports disconnection
+ #
+ # This operation is invoked between Ports internally when the
+ # connection is destroied. Generally it is not premised on
+ # calling from application programs or RTC objects except Port
+ # object.
+ #
+ # According to the template method pattern, the
+ # notify_disconnect() calls unsubsctiveInterfaces() function,
+ # which are premised on implementing in the subclasses. The
+ # processing sequence is as follows.
+ #
+ # - Searching ConnectorProfile
+ # - Calling notify_disconnect() for the next port
+ # - Unsubscribing interfaces
+ # - Deleting ConnectorProfile
+ #
+ # notify_disconnect() notifies disconnection to all the ports by
+ # cascaded call to the stored ports in the
+ # ConnectorProfile::ports in order.
+ #
+ # @pre The port shall store the ConnectorProfile having same id
+ # with connector_id.
+ #
+ # @post If ConnectorProfile of same ID with connector_id does not
+ # exist, it returns BAD_PARAMETER error.
+ #
+ # @post For the cascaded call, this operation calls
+ # noify_disconnect() for the port that is stored in the next of
+ # this port in the ConnectorProfile::ports. If the operation
+ # call raises exception for some failure, it tries to call
+ # notify_disconnect() and skips until the operation succeeded.
+ # If none of operation call succeeded, it returns RTC_ERROR.
+ #
+ # @post At the end of notify_disconnect() operation for the first
+ # port stored in the ConnectorProfile::ports sequence, the
+ # related ports' notify_disconnect() invocations complete.
+ #
+ # @param connector_id The ID of the ConnectorProfile.
+ # @return ReturnCode_t The return code of ReturnCode_t type.
+ #
+ # @endif
+ #
+ # virtual ReturnCode_t notify_disconnect(const char* connector_id)
+ def notify_disconnect(self, connector_id):
+ self._rtcout.RTC_TRACE("notify_disconnect(%s)", connector_id)
+
+ guard_connection = OpenRTM_aist.ScopedLock(self._connection_mutex)
+ # The Port of which the reference is stored in the beginning of
+ # connectorProfile's PortServiceList is master Port.
+ # The master Port has the responsibility of disconnecting all Ports.
+ # The slave Ports have only responsibility of deleting its own
+ # ConnectorProfile.
+
+ guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
+
+ index = self.findConnProfileIndex(connector_id)
+
+ if index < 0:
+ self._rtcout.RTC_ERROR("Invalid connector id: %s", connector_id)
+ return RTC.BAD_PARAMETER
+
+ prof = RTC.ConnectorProfile(self._profile.connector_profiles[index].name,
+ self._profile.connector_profiles[index].connector_id,
+ self._profile.connector_profiles[index].ports,
+ self._profile.connector_profiles[index].properties)
+ self.onNotifyDisconnect(self.getName(), prof)
+
+ retval = self.disconnectNext(prof)
+ self.onDisconnectNextport(self.getName(), prof, retval)
+
+ if self._onUnsubscribeInterfaces:
+ self._onUnsubscribeInterfaces(prof)
+ self.onUnsubscribeInterfaces(self.getName(), prof)
+ self.unsubscribeInterfaces(prof)
+
+ if self._onDisconnected:
+ self._onDisconnected(prof)
+
+ OpenRTM_aist.CORBA_SeqUtil.erase(self._profile.connector_profiles, index)
+
+ self.onDisconnected(self.getName(), prof, retval)
+ return retval
+
+
+ ##
+ # @if jp
+ #
+ # @brief [CORBA interface] Port の全接続を解除する
+ #
+ # このオペレーションはこの Port に関連した全ての接続を解除する。
+ #
+ # @param self
+ #
+ # @return ReturnCode_t 型のリターンコード
+ #
+ # @else
+ #
+ # @brief [CORBA interface] Connect the Port
+ #
+ # This operation destroys all connection channels owned by the Port.
+ #
+ # @return ReturnCode_t The return code of this operation.
+ #
+ # @endif
+ # virtual ReturnCode_t disconnect_all()
+ def disconnect_all(self):
+ self._rtcout.RTC_TRACE("disconnect_all()")
+ guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
+ plist = copy.deepcopy(self._profile.connector_profiles)
+ del guard
+
+ retcode = RTC.RTC_OK
+ len_ = len(plist)
+ self._rtcout.RTC_DEBUG("disconnecting %d connections.", len_)
+
+ # disconnect all connections
+ # Call disconnect() for each ConnectorProfile.
+ for i in range(len_):
+ tmpret = self.disconnect(plist[i].connector_id)
+ if tmpret != RTC.RTC_OK:
+ retcode = tmpret
+
+ return retcode
+
+
+ #============================================================
+ # Local operations
+ #============================================================
+
+ ##
+ # @if jp
+ # @brief Port の名前を設定する
+ #
+ # Port の名前を設定する。この名前は Port が保持する PortProfile.name
+ # に反映される。
+ #
+ # @param self
+ # @param name Port の名前
+ #
+ # @else
+ # @brief Set the name of this Port
+ #
+ # This operation sets the name of this Port. The given Port's name is
+ # applied to Port's PortProfile.name.
+ #
+ # @param name The name of this Port.
+ #
+ # @endif
+ # void setName(const char* name);
+ def setName(self, name):
+ self._rtcout.RTC_TRACE("setName(%s)", name)
+ guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
+ self._profile.name = name
+ return
+
+ ##
+ # @if jp
+ # @brief Port の名前を取得する
+ # @else
+ # @brief Get the name of this Port
+ # @return The name of this Port.
+ # @endif
+ #
+ # const char* PortBase::getName() const
+ def getName(self):
+ self._rtcout.RTC_TRACE("getName() = %s", self._profile.name)
+ return self._profile.name
+
+
+ ##
+ # @if jp
+ # @brief PortProfileを取得する
+ #
+ # Portが保持する PortProfile の const 参照を返す。
+ #
+ # @param self
+ #
+ # @return この Port の PortProfile
+ #
+ # @else
+ # @brief Get the PortProfile of the Port
+ #
+ # This operation returns const reference of the PortProfile.
+ #
+ # @return the PortProfile of the Port
+ #
+ # @endif
+ # const PortProfile& getProfile() const;
+ def getProfile(self):
+ self._rtcout.RTC_TRACE("getProfile()")
+ guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
+ return self._profile
+
+
+ ##
+ # @if jp
+ #
+ # @brief Port のオブジェクト参照を設定する
+ #
+ # このオペレーションは Port の PortProfile にこの Port 自身の
+ # オブジェクト参照を設定する。
+ #
+ # @param self
+ # @param port_ref この Port のオブジェクト参照
+ #
+ # @else
+ #
+ # @brief Set the object reference of this Port
+ #
+ # This operation sets the object reference itself
+ # to the Port's PortProfile.
+ #
+ # @param The object reference of this Port.
+ #
+ # @endif
+ # void setPortRef(PortService_ptr port_ref);
+ def setPortRef(self, port_ref):
+ self._rtcout.RTC_TRACE("setPortRef()")
+ guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
+ self._profile.port_ref = port_ref
+
+
+ ##
+ # @if jp
+ #
+ # @brief Port のオブジェクト参照を取得する
+ #
+ # このオペレーションは Port の PortProfile が保持している
+ # この Port 自身のオブジェクト参照を取得する。
+ #
+ # @param self
+ #
+ # @return この Port のオブジェクト参照
+ #
+ # @else
+ #
+ # @brief Get the object reference of this Port
+ #
+ # This operation returns the object reference
+ # that is stored in the Port's PortProfile.
+ #
+ # @return The object reference of this Port.
+ #
+ # @endif
+ # PortService_ptr getPortRef();
+ def getPortRef(self):
+ self._rtcout.RTC_TRACE("getPortRef()")
+ guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
+ return self._profile.port_ref
+
+
+ ##
+ # @if jp
+ #
+ # @brief Port の owner の RTObject を指定する
+ #
+ # このオペレーションは Port の PortProfile.owner を設定する。
+ #
+ # @param self
+ # @param owner この Port を所有する RTObject の参照
+ #
+ # @else
+ #
+ # @brief Set the owner RTObject of the Port
+ #
+ # This operation sets the owner RTObject of this Port.
+ #
+ # @param owner The owner RTObject's reference of this Port
+ #
+ # @endif
+ # void setOwner(RTObject_ptr owner);
+ def setOwner(self, owner):
+ prof = owner.get_component_profile()
+ self._ownerInstanceName = prof.instance_name
+ self._rtcout.RTC_TRACE("setOwner(%s)", self._ownerInstanceName)
+
+ guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
+ plist = self._profile.name.split(".")
+ if not self._ownerInstanceName:
+ self._rtcout.RTC_ERROR("Owner is not set.")
+ self._rtcout.RTC_ERROR("addXXXPort() should be called in onInitialize().")
+ portname = self._ownerInstanceName+"."+plist[-1]
+
+ self._profile.owner = owner
+ self._profile.name = portname
+
+
+ #============================================================
+ # callbacks
+ #============================================================
+
+ ##
+ # @if jp
+ #
+ # @brief インターフェースを公開する際に呼ばれるコールバックをセットする
+ #
+ # このオペレーションは、このポートが接続時に、ポート自身が持つサー
+ # ビスインターフェース情報を公開するタイミングで呼ばれるコールバッ
+ # クファンクタをセットする。
+ #
+ # コールバックファンクタの所有権は、呼び出し側にあり、オブジェクト
+ # が必要なくなった時に解体するのは呼び出し側の責任である。
+ #
+ # このコールバックファンクタは、PortBaseクラスの仮想関数である
+ # publishInterfaces() が呼ばれたあとに、同じ引数 ConnectorProfile と
+ # ともに呼び出される。このコールバックを利用して、
+ # publishInterfaces() が公開した ConnectorProfile を変更することが可
+ # 能であるが、接続関係の不整合を招かないよう、ConnectorProfile の
+ # 変更には注意を要する。
+ #
+ # @param on_publish ConnectionCallback のサブクラスオブジェクトのポインタ
+ #
+ # @else
+ #
+ # @brief Setting callback called on publish interfaces
+ #
+ # This operation sets a functor that is called after publishing
+ # interfaces process when connecting between ports.
+ #
+ # Since the ownership of the callback functor object is owned by
+ # the caller, it has the responsibility of object destruction.
+ #
+ # The callback functor is called after calling
+ # publishInterfaces() that is virtual member function of the
+ # PortBase class with an argument of ConnectorProfile type that
+ # is same as the argument of publishInterfaces() function.
+ # Although by using this functor, you can modify the ConnectorProfile
+ # published by publishInterfaces() function, the modification
+ # should be done carefully for fear of causing connection
+ # inconsistency.
+ #
+ # @param on_publish a pointer to ConnectionCallback's subclasses
+ #
+ # @endif
+ #
+ # void setOnPublishInterfaces(ConnectionCallback* on_publish);
+ def setOnPublishInterfaces(self, on_publish):
+ self._onPublishInterfaces = on_publish
+ return
+
+
+ ##
+ # @if jp
+ #
+ # @brief インターフェースを取得する際に呼ばれるコールバックをセットする
+ #
+ # このオペレーションは、このポートが接続時に、相手のポートが持つサー
+ # ビスインターフェース情報を取得するタイミングで呼ばれるコールバッ
+ # クファンクタをセットする。
+ #
+ # コールバックファンクタの所有権は、呼び出し側にあり、オブジェクト
+ # が必要なくなった時に解体するのは呼び出し側の責任である。
+ #
+ # このコールバックファンクタは、PortBaseクラスの仮想関数である
+ # subscribeInterfaces() が呼ばれる前に、同じ引数 ConnectorProfile と
+ # ともに呼び出される。このコールバックを利用して、
+ # subscribeInterfaces() に与える ConnectorProfile を変更することが可
+ # 能であるが、接続関係の不整合を招かないよう、ConnectorProfile の
+ # 変更には注意を要する。
+ #
+ # @param on_subscribe ConnectionCallback のサブクラスオブジェクトのポインタ
+ #
+ # @else
+ #
+ # @brief Setting callback called on publish interfaces
+ #
+ # This operation sets a functor that is called before subscribing
+ # interfaces process when connecting between ports.
+ #
+ # Since the ownership of the callback functor object is owned by
+ # the caller, it has the responsibility of object destruction.
+ #
+ # The callback functor is called before calling
+ # subscribeInterfaces() that is virtual member function of the
+ # PortBase class with an argument of ConnectorProfile type that
+ # is same as the argument of subscribeInterfaces() function.
+ # Although by using this functor, you can modify ConnectorProfile
+ # argument for subscribeInterfaces() function, the modification
+ # should be done carefully for fear of causing connection
+ # inconsistency.
+ #
+ # @param on_subscribe a pointer to ConnectionCallback's subclasses
+ #
+ # @endif
+ #
+ #void setOnSubscribeInterfaces(ConnectionCallback* on_subscribe);
+ def setOnSubscribeInterfaces(self, on_subscribe):
+ self._onSubscribeInterfaces = on_subscribe
+ return
+
+
+ ##
+ # @if jp
+ #
+ # @brief 接続完了時に呼ばれるコールバックをセットする
+ #
+ # このオペレーションは、このポートが接続完了時に呼ばれる、コールバッ
+ # クファンクタをセットする。
+ #
+ # コールバックファンクタの所有権は、呼び出し側にあり、オブジェクト
+ # が必要なくなった時に解体するのは呼び出し側の責任である。
+ #
+ # このコールバックファンクタは、ポートの接続実行関数である
+ # notify_connect() の終了直前に、接続処理が正常終了する際に限って
+ # 呼び出されるコールバックである。接続処理の過程でエラーが発生した
+ # 場合には呼び出されない。
+ #
+ # このコールバックファンクタは notify_connect() が out パラメータ
+ # として返すのと同じ引数 ConnectorProfile とともに呼び出されるので、
+ # この接続において公開されたすべてのインターフェース情報を得ること
+ # ができる。このコールバックを利用して、notify_connect() が返す
+ # ConnectorProfile を変更することが可能であるが、接続関係の不整合
+ # を招かないよう、ConnectorProfile の変更には注意を要する。
+ #
+ # @param on_subscribe ConnectionCallback のサブクラスオブジェクトのポインタ
+ #
+ # @else
+ #
+ # @brief Setting callback called on connection established
+ #
+ # This operation sets a functor that is called when connection
+ # between ports established.
+ #
+ # Since the ownership of the callback functor object is owned by
+ # the caller, it has the responsibility of object destruction.
+ #
+ # The callback functor is called only when notify_connect()
+ # function successfully returns. In case of error, the functor
+ # will not be called.
+ #
+ # Since this functor is called with ConnectorProfile argument
+ # that is same as out-parameter of notify_connect() function, you
+ # can get all the information of published interfaces of related
+ # ports in the connection. Although by using this functor, you
+ # can modify ConnectorProfile argument for out-paramter of
+ # notify_connect(), the modification should be done carefully for
+ # fear of causing connection inconsistency.
+ #
+ # @param on_subscribe a pointer to ConnectionCallback's subclasses
+ #
+ # @endif
+ #
+ # void setOnConnected(ConnectionCallback* on_connected);
+ def setOnConnected(self, on_connected):
+ self._onConnected = on_connected
+ return
+
+
+ ##
+ # @if jp
+ #
+ # @brief インターフェースを解放する際に呼ばれるコールバックをセットする
+ #
+ # このオペレーションは、このポートが接続時に、相手のポートが持つサー
+ # ビスインターフェース情報を解放するタイミングで呼ばれるコールバッ
+ # クファンクタをセットする。
+ #
+ # コールバックファンクタの所有権は、呼び出し側にあり、オブジェクト
+ # が必要なくなった時に解体するのは呼び出し側の責任である。
+ #
+ # このコールバックファンクタは、PortBaseクラスの仮想関数である
+ # unsubscribeInterfaces() が呼ばれる前に、同じ引数 ConnectorProfile と
+ # ともに呼び出される。このコールバックを利用して、
+ # unsubscribeInterfaces() に与える ConnectorProfile を変更することが可
+ # 能であるが、接続関係の不整合を招かないよう、ConnectorProfile の
+ # 変更には注意を要する。
+ #
+ # @param on_unsubscribe ConnectionCallback のサブクラスオブジェク
+ # トのポインタ
+ #
+ # @else
+ #
+ # @brief Setting callback called on unsubscribe interfaces
+ #
+ # This operation sets a functor that is called before unsubscribing
+ # interfaces process when disconnecting between ports.
+ #
+ # Since the ownership of the callback functor object is owned by
+ # the caller, it has the responsibility of object destruction.
+ #
+ # The callback functor is called before calling
+ # unsubscribeInterfaces() that is virtual member function of the
+ # PortBase class with an argument of ConnectorProfile type that
+ # is same as the argument of unsubscribeInterfaces() function.
+ # Although by using this functor, you can modify ConnectorProfile
+ # argument for unsubscribeInterfaces() function, the modification
+ # should be done carefully for fear of causing connection
+ # inconsistency.
+ #
+ # @param on_unsubscribe a pointer to ConnectionCallback's subclasses
+ #
+ # @endif
+ #
+ # void setOnUnsubscribeInterfaces(ConnectionCallback* on_subscribe);
+ def setOnUnsubscribeInterfaces(self, on_subscribe):
+ self._onUnsubscribeInterfaces = on_subscribe
+ return
+
+
+ ##
+ # @if jp
+ #
+ # @brief 接続解除に呼ばれるコールバックをセットする
+ #
+ # このオペレーションは、このポートの接続解除時に呼ばれる、コールバッ
+ # クファンクタをセットする。
+ #
+ # コールバックファンクタの所有権は、呼び出し側にあり、オブジェクト
+ # が必要なくなった時に解体するのは呼び出し側の責任である。
+ #
+ # このコールバックファンクタは、ポートの接続解除実行関数である
+ # notify_disconnect() の終了直前に、呼び出されるコールバックである。
+ #
+ # このコールバックファンクタは接続に対応する ConnectorProfile とと
+ # もに呼び出される。この ConnectorProfile はこのファンクタ呼出し後
+ # に破棄されるので、変更がほかに影響を与えることはない。
+ #
+ # @param on_disconnected ConnectionCallback のサブクラスオブジェク
+ # トのポインタ
+ #
+ # @else
+ #
+ # @brief Setting callback called on disconnected
+ #
+ # This operation sets a functor that is called when connection
+ # between ports is destructed.
+ #
+ # Since the ownership of the callback functor object is owned by
+ # the caller, it has the responsibility of object destruction.
+ #
+ # The callback functor is called just before notify_disconnect()
+ # that is disconnection execution function returns.
+ #
+ # This functor is called with argument of corresponding
+ # ConnectorProfile. Since this ConnectorProfile will be
+ # destructed after calling this functor, modifications never
+ # affect others.
+ #
+ # @param on_disconnected a pointer to ConnectionCallback's subclasses
+ #
+ # @endif
+ #
+ # void setOnDisconnected(ConnectionCallback* on_disconnected);
+ def setOnDisconnected(self, on_disconnected):
+ self._onDisconnected = on_disconnected
+ return
+
+ # void setOnConnectionLost(ConnectionCallback* on_connection_lost);
+ def setOnConnectionLost(self, on_connection_lost):
+ self._onConnectionLost = on_connection_lost
+ return
+
+
+ ##
+ # @if jp
+ # @brief PortConnectListeners のホルダをセットする
+ #
+ # ポートの接続に関するリスナ群を保持するホルダクラスへのポインタを
+ # セットする。この関数は通常親のRTObjectから呼ばれ、RTObjectが持つ
+ # ホルダクラスへのポインタがセットされる。
+ #
+ # @param portconnListeners PortConnectListeners オブジェクトのポインタ
+ #
+ # @else
+ # @brief Setting PortConnectListener holder
+ #
+ # This operation sets a functor that is called when connection
+ # of this port does lost.
+ #
+ # @param on_connection_lost a pointer to ConnectionCallback's subclasses
+ #
+ # @endif
+ #
+ # void setPortConnectListenerHolder(PortConnectListeners* portconnListeners);
+ def setPortConnectListenerHolder(self, portconnListeners):
+ self._portconnListeners = portconnListeners
+ return
+
+
+ ##
+ # @if jp
+ #
+ # @brief Interface 情報を公開する(サブクラス実装用)
+ #
+ # このオペレーションは、notify_connect() 処理シーケンスの始めにコール
+ # される関数である。
+ # notify_connect() では、
+ #
+ # - publishInterfaces()
+ # - connectNext()
+ # - subscribeInterfaces()
+ # - updateConnectorProfile()
+ #
+ # の順に protected 関数がコールされ接続処理が行われる。
+ # <br>
+ # 具象 Port ではこのオペレーションをオーバーライドし、引数として
+ # 与えられた ConnectorProfile に従い処理を行い、パラメータが不適切
+ # であれば、RteurnCode_t 型のエラーコードを返す。
+ # 通常 publishInterafaces() 内においては、この Port に属する
+ # インターフェースに関する情報を ConnectorProfile に対して適切に設定し
+ # 他の Port に通知しなければならない。
+ # <br>
+ # また、この関数がコールされる段階では、他の Port の Interface に関する
+ # 情報はすべて含まれていないので、他の Port の Interface を取得する処理
+ # は subscribeInterfaces() 内で行われるべきである。
+ # <br>
+ # このオペレーションは、新規の connector_id に対しては接続の生成、
+ # 既存の connector_id に対しては更新が適切に行われる必要がある。<BR>
+ # ※サブクラスでの実装参照用
+ #
+ # @param self
+ # @param connector_profile 接続に関するプロファイル情報
+ #
+ # @return ReturnCode_t 型のリターンコード
+ #
+ # @else
+ #
+ # @brief Publish interface information
+ #
+ # This operation is pure virutal method that would be called at the
+ # beginning of the notify_connect() process sequence.
+ # In the notify_connect(), the following methods would be called in order.
+ #
+ # - publishInterfaces()
+ # - connectNext()
+ # - subscribeInterfaces()
+ # - updateConnectorProfile()
+ #
+ # In the concrete Port, this method should be overridden. This method
+ # processes the given ConnectorProfile argument and if the given parameter
+ # is invalid, it would return error code of ReturnCode_t.
+ # Usually, publishInterfaces() method should set interfaces information
+ # owned by this Port, and publish it to the other Ports.
+ # <br>
+ # When this method is called, other Ports' interfaces information may not
+ # be completed. Therefore, the process to obtain other Port's interfaces
+ # information should be done in the subscribeInterfaces() method.
+ # <br>
+ # This operation should create the new connection for the new
+ # connector_id, and should update the connection for the existing
+ # connection_id.
+ #
+ # @param connector_profile The connection profile information
+ # @return The return code of ReturnCode_t type.
+ #
+ #@endif
+ def publishInterfaces(self, connector_profile):
+ pass
+
+
+ ##
+ # @if jp
+ #
+ # @brief 次の Port に対して notify_connect() をコールする
+ #
+ # ConnectorProfile の port_ref 内に格納されている Port のオブジェクト
+ # リファレンスのシーケンスの中から、自身の Port の次の Port に対して
+ # notify_connect() をコールする。
+ #
+ # @param self
+ # @param connector_profile 接続に関するプロファイル情報
+ #
+ # @return ReturnCode_t 型のリターンコード
+ #
+ # @else
+ #
+ # @brief Call notify_connect() of the next Port
+ #
+ # This operation calls the notify_connect() of the next Port's
+ # that stored in ConnectorProfile's port_ref sequence.
+ #
+ # @param connector_profile The connection profile information
+ #
+ # @return The return code of ReturnCode_t type.
+ #
+ # @endif
+ # virtual ReturnCode_t connectNext(ConnectorProfile& connector_profile);
+ def connectNext(self, connector_profile):
+ index = OpenRTM_aist.CORBA_SeqUtil.find(connector_profile.ports,
+ self.find_port_ref(self._profile.port_ref))
+ if index < 0:
+ return (RTC.BAD_PARAMETER, connector_profile)
+
+ index += 1
+ if index < len(connector_profile.ports):
+ p = connector_profile.ports[index]
+ return p.notify_connect(connector_profile)
+
+ return (RTC.RTC_OK, connector_profile)
+
+
+ ##
+ # @if jp
+ #
+ # @brief 次の Port に対して notify_disconnect() をコールする
+ #
+ # ConnectorProfile の port_ref 内に格納されている Port のオブジェクト
+ # リファレンスのシーケンスの中から、自身の Port の次の Port に対して
+ # notify_disconnect() をコールする。
+ #
+ # @param self
+ # @param connector_profile 接続に関するプロファイル情報
+ #
+ # @return ReturnCode_t 型のリターンコード
+ #
+ # @else
+ #
+ # @brief Call notify_disconnect() of the next Port
+ #
+ # This operation calls the notify_disconnect() of the next Port's
+ # that stored in ConnectorProfile's port_ref sequence.
+ #
+ # @param connector_profile The connection profile information
+ #
+ # @return The return code of ReturnCode_t type.
+ #
+ # @endif
+ # virtual ReturnCode_t disconnectNext(ConnectorProfile& connector_profile);
+ def disconnectNext(self, connector_profile):
+ index = OpenRTM_aist.CORBA_SeqUtil.find(connector_profile.ports,
+ self.find_port_ref(self._profile.port_ref))
+ if index < 0:
+ return RTC.BAD_PARAMETER
+
+ if index == (len(connector_profile.ports) - 1):
+ return RTC.RTC_OK
+
+ index += 1
+
+ while index < len(connector_profile.ports):
+ p = connector_profile.ports[index]
+ index += 1
+ try:
+ return p.notify_disconnect(connector_profile.connector_id)
+ except:
+ self._rtcout.RTC_WARN(OpenRTM_aist.Logger.print_exception())
+ continue
+
+ return RTC.RTC_ERROR
+
+
+ ##
+ # @if jp
+ #
+ # @brief Interface 情報を取得する(サブクラス実装用)
+ #
+ # このオペレーションは、notify_connect() 処理シーケンスの中間にコール
+ # される関数である。
+ # notify_connect() では、
+ #
+ # - publishInterfaces()
+ # - connectNext()
+ # - subscribeInterfaces()
+ # - updateConnectorProfile()
+ #
+ # の順に protected 関数がコールされ接続処理が行われる。
+ # <br>
+ # 具象 Port ではこのオペレーションをオーバーライドし、引数として
+ # 与えられた ConnectorProfile に従い処理を行い、パラメータが不適切
+ # であれば、RteurnCode_t 型のエラーコードを返す。
+ # 引数 ConnectorProfile には他の Port の Interface に関する情報が
+ # 全て含まれている。
+ # 通常 subscribeInterafaces() 内においては、この Port が使用する
+ # Interface に関する情報を取得し、要求側のインターフェースに対して
+ # 情報を設定しなければならない。
+ # <br>
+ # このオペレーションは、新規の connector_id に対しては接続の生成、
+ # 既存の connector_id に対しては更新が適切に行われる必要がある。<BR>
+ # ※サブクラスでの実装参照用
+ #
+ # @param self
+ # @param connector_profile 接続に関するプロファイル情報
+ #
+ # @return ReturnCode_t 型のリターンコード
+ #
+ # @else
+ #
+ # @brief Publish interface information
+ #
+ # This operation is pure virutal method that would be called at the
+ # mid-flow of the notify_connect() process sequence.
+ # In the notify_connect(), the following methods would be called in order.
+ #
+ # - publishInterfaces()
+ # - connectNext()
+ # - subscribeInterfaces()
+ # - updateConnectorProfile()
+ #
+ # In the concrete Port, this method should be overridden. This method
+ # processes the given ConnectorProfile argument and if the given parameter
+ # is invalid, it would return error code of ReturnCode_t.
+ # The given argument ConnectorProfile includes all the interfaces
+ # information in it.
+ # Usually, subscribeInterafaces() method obtains information of interfaces
+ # from ConnectorProfile, and should set it to the interfaces that require
+ # them.
+ # <br>
+ # This operation should create the new connection for the new
+ # connector_id, and should update the connection for the existing
+ # connection_id.
+ #
+ # @param connector_profile The connection profile information
+ #
+ # @return The return code of ReturnCode_t type.
+ #
+ #@endif
+ def subscribeInterfaces(self, connector_profile):
+ pass
+
+
+ ##
+ # @if jp
+ #
+ # @brief Interface の接続を解除する(サブクラス実装用)
+ #
+ # このオペレーションは、notify_disconnect() 処理シーケンスの終わりにコール
+ # される関数である。
+ # notify_disconnect() では、
+ # - disconnectNext()
+ # - unsubscribeInterfaces()
+ # - eraseConnectorProfile()
+ # の順に protected 関数がコールされ接続解除処理が行われる。
+ # <br>
+ # 具象 Port ではこのオペレーションをオーバーライドし、引数として
+ # 与えられた ConnectorProfile に従い接続解除処理を行う。<BR>
+ # ※サブクラスでの実装参照用
+ #
+ # @param self
+ # @param connector_profile 接続に関するプロファイル情報
+ #
+ # @else
+ #
+ # @brief Disconnect interface connection
+ #
+ # This operation is pure virutal method that would be called at the
+ # end of the notify_disconnect() process sequence.
+ # In the notify_disconnect(), the following methods would be called.
+ # - disconnectNext()
+ # - unsubscribeInterfaces()
+ # - eraseConnectorProfile()
+ # <br>
+ # In the concrete Port, this method should be overridden. This method
+ # processes the given ConnectorProfile argument and disconnect interface
+ # connection.
+ #
+ # @param connector_profile The connection profile information
+ #
+ # @endif
+ def unsubscribeInterfaces(self, connector_profile):
+ pass
+
+
+ ##
+ # @if jp
+ #
+ # @brief 接続の最大数を設定する。
+ #
+ # @param limit_value 最大数
+ #
+ # @else
+ #
+ # @brief Set the maximum number of connections
+ #
+ #
+ # @param limit_value The maximum number of connections
+ #
+ # @endif
+ #
+ # virtual void setConnectionLimit(int limit_value);
+ def setConnectionLimit(self, limit_value):
+ self._connectionLimit = limit_value
+ return
+
+
+ ##
+ # @if jp
+ # @brief Interface情報を公開する
+ #
+ # Interface情報を公開する。
+ #
+ # dataport.dataflow_type
+ #
+ # @return ReturnCode_t 型のリターンコード
+ #
+ # @else
+ # @brief Publish interface information
+ #
+ # Publish interface information.
+ #
+ #
+ # @return The return code of ReturnCode_t type
+ #
+ # @endif
+ #
+ # virtual ReturnCode_t _publishInterfaces(void);
+ def _publishInterfaces(self):
+ if not (self._connectionLimit < 0) :
+ if self._connectionLimit <= len(self._profile.connector_profiles):
+ self._rtcout.RTC_PARANOID("Connected number has reached the limitation.")
+ self._rtcout.RTC_PARANOID("Can connect the port up to %d ports.",
+ self._connectionLimit)
+ self._rtcout.RTC_PARANOID("%d connectors are existing",
+ len(self._profile.connector_profiles))
+ return RTC.RTC_ERROR
+
+ return RTC.RTC_OK
+
+
+ ##
+ # @if jp
+ #
+ # @brief ConnectorProfile の connector_id フィールドが空かどうか判定
+ #
+ # 指定された ConnectorProfile の connector_id が空であるかどうかの判定を
+ # 行う。
+ #
+ # @param self
+ # @param connector_profile 判定対象コネクタプロファイル
+ #
+ # @return 引数で与えられた ConnectorProfile の connector_id が空であれば、
+ # true、そうでなければ false を返す。
+ #
+ # @else
+ #
+ # @brief Whether connector_id of ConnectorProfile is empty
+ #
+ # @return If the given ConnectorProfile's connector_id is empty string,
+ # it returns true.
+ #
+ # @endif
+ # bool isEmptyId(const ConnectorProfile& connector_profile) const;
+ def isEmptyId(self, connector_profile):
+ return connector_profile.connector_id == ""
+
+
+ ##
+ # @if jp
+ #
+ # @brief UUIDを生成する
+ #
+ # このオペレーションは UUID を生成する。
+ #
+ # @param self
+ #
+ # @return uuid
+ #
+ # @else
+ #
+ # @brief Get the UUID
+ #
+ # This operation generates UUID.
+ #
+ # @return uuid
+ #
+ # @endif
+ # const std::string getUUID() const;
+ def getUUID(self):
+ return str(OpenRTM_aist.uuid1())
+
+
+ ##
+ # @if jp
+ #
+ # @brief UUIDを生成し ConnectorProfile にセットする
+ #
+ # このオペレーションは UUID を生成し、ConnectorProfile にセットする。
+ #
+ # @param self
+ # @param connector_profile connector_id をセットする ConnectorProfile
+ #
+ # @else
+ #
+ # @brief Create and set the UUID to the ConnectorProfile
+ #
+ # This operation generates and set UUID to the ConnectorProfile.
+ #
+ # @param connector_profile ConnectorProfile to be set connector_id
+ #
+ # @endif
+ # void setUUID(ConnectorProfile& connector_profile) const;
+ def setUUID(self, connector_profile):
+ connector_profile.connector_id = self.getUUID()
+ assert(connector_profile.connector_id != "")
+
+
+ ##
+ # @if jp
+ #
+ # @brief id が既存の ConnectorProfile のものかどうか判定する
+ #
+ # このオペレーションは与えられた ID が既存の ConnectorProfile のリスト中に
+ # 存在するかどうか判定する。
+ #
+ # @param self
+ # @param id_ 判定する connector_id
+ #
+ # @return id の存在判定結果
+ #
+ # @else
+ #
+ # @brief Whether the given id exists in stored ConnectorProfiles
+ #
+ # This operation returns boolean whether the given id exists in
+ # the Port's ConnectorProfiles.
+ #
+ # @param id connector_id to be find in Port's ConnectorProfiles
+ #
+ # @endif
+ # bool isExistingConnId(const char* id);
+ def isExistingConnId(self, id_):
+ return OpenRTM_aist.CORBA_SeqUtil.find(self._profile.connector_profiles,
+ self.find_conn_id(id_)) >= 0
+
+
+ ##
+ # @if jp
+ #
+ # @brief id を持つ ConnectorProfile を探す
+ #
+ # このオペレーションは与えられた ID を持つ ConnectorProfile を Port が
+ # もつ ConnectorProfile のリスト中から探す。
+ # もし、同一の id を持つ ConnectorProfile がなければ、空の ConnectorProfile
+ # が返される。
+ #
+ # @param self
+ # @param id_ 検索する connector_id
+ #
+ # @return connector_id を持つ ConnectorProfile
+ #
+ # @else
+ #
+ # @brief Find ConnectorProfile with id
+ #
+ # This operation returns ConnectorProfile with the given id from Port's
+ # ConnectorProfiles' list.
+ # If the ConnectorProfile with connector id that is identical with the
+ # given id does not exist, empty ConnectorProfile is returned.
+ #
+ # @param id the connector_id to be searched in Port's ConnectorProfiles
+ #
+ # @return CoonectorProfile with connector_id
+ #
+ # @endif
+ # ConnectorProfile findConnProfile(const char* id);
+ def findConnProfile(self, id_):
+ index = OpenRTM_aist.CORBA_SeqUtil.find(self._profile.connector_profiles,
+ self.find_conn_id(id_))
+ if index < 0 or index >= len(self._profile.connector_profiles):
+ return RTC.ConnectorProfile("","",[],[])
+
+ return self._profile.connector_profiles[index]
+
+
+ ##
+ # @if jp
+ #
+ # @brief id を持つ ConnectorProfile を探す
+ #
+ # このオペレーションは与えられた ID を持つ ConnectorProfile を Port が
+ # もつ ConnectorProfile のリスト中から探しインデックスを返す。
+ # もし、同一の id を持つ ConnectorProfile がなければ、-1 を返す。
+ #
+ # @param self
+ # @param id_ 検索する connector_id
+ #
+ # @return Port の ConnectorProfile リストのインデックス
+ #
+ # @else
+ #
+ # @brief Find ConnectorProfile with id
+ #
+ # This operation returns ConnectorProfile with the given id from Port's
+ # ConnectorProfiles' list.
+ # If the ConnectorProfile with connector id that is identical with the
+ # given id does not exist, empty ConnectorProfile is returned.
+ #
+ # @param id the connector_id to be searched in Port's ConnectorProfiles
+ #
+ # @return The index of ConnectorProfile of the Port
+ #
+ # @endif
+ # CORBA::Long findConnProfileIndex(const char* id);
+ def findConnProfileIndex(self, id_):
+ return OpenRTM_aist.CORBA_SeqUtil.find(self._profile.connector_profiles,
+ self.find_conn_id(id_))
+
+
+ ##
+ # @if jp
+ #
+ # @brief ConnectorProfile の追加もしくは更新
+ #
+ # このオペレーションは与えられた与えられた ConnectorProfile を
+ # Port に追加もしくは更新保存する。
+ # 与えられた ConnectorProfile の connector_id と同じ ID を持つ
+ # ConnectorProfile がリストになければ、リストに追加し、
+ # 同じ ID が存在すれば ConnectorProfile を上書き保存する。
+ #
+ # @param self
+ # @param connector_profile 追加もしくは更新する ConnectorProfile
+ #
+ # @else
+ #
+ # @brief Append or update the ConnectorProfile list
+ #
+ # This operation appends or updates ConnectorProfile of the Port
+ # by the given ConnectorProfile.
+ # If the connector_id of the given ConnectorProfile does not exist
+ # in the Port's ConnectorProfile list, the given ConnectorProfile would be
+ # append to the list. If the same id exists, the list would be updated.
+ #
+ # @param connector_profile the ConnectorProfile to be appended or updated
+ #
+ # @endif
+ # void updateConnectorProfile(const ConnectorProfile& connector_profile);
+ def updateConnectorProfile(self, connector_profile):
+ index = OpenRTM_aist.CORBA_SeqUtil.find(self._profile.connector_profiles,
+ self.find_conn_id(connector_profile.connector_id))
+
+ if index < 0:
+ OpenRTM_aist.CORBA_SeqUtil.push_back(self._profile.connector_profiles,
+ connector_profile)
+ else:
+ self._profile.connector_profiles[index] = connector_profile
+
+
+ ##
+ # @if jp
+ #
+ # @brief ConnectorProfile を削除する
+ #
+ # このオペレーションは Port の PortProfile が保持している
+ # ConnectorProfileList のうち与えられた id を持つ ConnectorProfile
+ # を削除する。
+ #
+ # @param self
+ # @param id_ 削除する ConnectorProfile の id
+ #
+ # @return 正常に削除できた場合は true、
+ # 指定した ConnectorProfile が見つからない場合は false を返す
+ #
+ # @else
+ #
+ # @brief Delete the ConnectorProfile
+ #
+ # This operation deletes a ConnectorProfile specified by id from
+ # ConnectorProfileList owned by PortProfile of this Port.
+ #
+ # @param id The id of the ConnectorProfile to be deleted.
+ #
+ # @endif
+ # bool eraseConnectorProfile(const char* id);
+ def eraseConnectorProfile(self, id_):
+ guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
+
+ index = OpenRTM_aist.CORBA_SeqUtil.find(self._profile.connector_profiles,
+ self.find_conn_id(id_))
+
+ if index < 0:
+ return False
+
+ OpenRTM_aist.CORBA_SeqUtil.erase(self._profile.connector_profiles, index)
+
+ return True
+
+
+ ##
+ # @if jp
+ #
+ # @brief PortInterfaceProfile に インターフェースを登録する
+ #
+ # このオペレーションは Port が持つ PortProfile の、PortInterfaceProfile
+ # にインターフェースの情報を追加する。
+ # この情報は、get_port_profile() 似よって得られる PortProfile のうち
+ # PortInterfaceProfile の値を変更するのみであり、実際にインターフェースを
+ # 提供したり要求したりする場合には、サブクラスで、 publishInterface() ,
+ # subscribeInterface() 等の関数を適切にオーバーライドしインターフェースの
+ # 提供、要求処理を行わなければならない。
+ #
+ # インターフェース(のインスタンス)名は Port 内で一意でなければならない。
+ # 同名のインターフェースがすでに登録されている場合、この関数は false を
+ # 返す。
+ #
+ # @param self
+ # @param instance_name インターフェースのインスタンスの名前
+ # @param type_name インターフェースの型の名前
+ # @param pol インターフェースの属性 (RTC::PROVIDED もしくは RTC:REQUIRED)
+ #
+ # @return インターフェース登録処理結果。
+ # 同名のインターフェースが既に登録されていれば false を返す。
+ #
+ # @else
+ #
+ # @brief Append an interface to the PortInterfaceProfile
+ #
+ # This operation appends interface information to the PortInterfaceProfile
+ # that is owned by the Port.
+ # The given interfaces information only updates PortInterfaceProfile of
+ # PortProfile that is obtained through get_port_profile().
+ # In order to provide and require interfaces, proper functions (for
+ # example publishInterface(), subscribeInterface() and so on) should be
+ # overridden in subclasses, and these functions provide concrete interface
+ # connection and disconnection functionality.
+ #
+ # The interface (instance) name have to be unique in the Port.
+ # If the given interface name is identical with stored interface name,
+ # this function returns false.
+ #
+ # @param name The instance name of the interface.
+ # @param type_name The type name of the interface.
+ # @param pol The interface's polarity (RTC::PROVIDED or RTC:REQUIRED)
+ #
+ # @return false would be returned if the same name is already registered.
+ #
+ # @endif
+ # bool appendInterface(const char* name, const char* type_name,
+ # PortInterfacePolarity pol);
+ def appendInterface(self, instance_name, type_name, pol):
+ index = OpenRTM_aist.CORBA_SeqUtil.find(self._profile.interfaces,
+ self.find_interface(instance_name, pol))
+
+ if index >= 0:
+ return False
+
+ # setup PortInterfaceProfile
+ prof = RTC.PortInterfaceProfile(instance_name, type_name, pol)
+ OpenRTM_aist.CORBA_SeqUtil.push_back(self._profile.interfaces, prof)
+
+ return True
+
+
+ ##
+ # @if jp
+ #
+ # @brief PortInterfaceProfile からインターフェース登録を削除する
+ #
+ # このオペレーションは Port が持つ PortProfile の、PortInterfaceProfile
+ # からインターフェースの情報を削除する。
+ #
+ # @param self
+ # @param name インターフェースのインスタンスの名前
+ # @param pol インターフェースの属性 (RTC::PROVIDED もしくは RTC:REQUIRED)
+ #
+ # @return インターフェース削除処理結果。
+ # インターフェースが登録されていなければ false を返す。
+ #
+ # @else
+ #
+ # @brief Delete an interface from the PortInterfaceProfile
+ #
+ # This operation deletes interface information from the
+ # PortInterfaceProfile that is owned by the Port.
+ #
+ # @param name The instance name of the interface.
+ # @param pol The interface's polarity (RTC::PROVIDED or RTC:REQUIRED)
+ #
+ # @return false would be returned if the given name is not registered.
+ #
+ # @endif
+ # bool deleteInterface(const char* name, PortInterfacePolarity pol);
+ def deleteInterface(self, name, pol):
+ index = OpenRTM_aist.CORBA_SeqUtil.find(self._profile.interfaces,
+ self.find_interface(name, pol))
+
+ if index < 0:
+ return False
+
+ OpenRTM_aist.CORBA_SeqUtil.erase(self._profile.interfaces, index)
+ return True
+
+
+ ##
+ # @if jp
+ #
+ # @brief PortProfile の properties に NameValue 値を追加する
+ #
+ # PortProfile の properties に NameValue 値を追加する。
+ # 追加するデータの型をValueTypeで指定する。
+ #
+ # @param self
+ # @param key properties の name
+ # @param value properties の value
+ #
+ # @else
+ #
+ # @brief Add NameValue data to PortProfile's properties
+ #
+ # @param key The name of properties
+ # @param value The value of properties
+ #
+ # @endif
+ # template <class ValueType>
+ # void addProperty(const char* key, ValueType value)
+ def addProperty(self, key, value):
+ OpenRTM_aist.CORBA_SeqUtil.push_back(self._profile.properties,
+ OpenRTM_aist.NVUtil.newNV(key, value))
+
+ ##
+ # @if jp
+ #
+ # @brief PortProfile の properties に NameValue 値を要素に追加する
+ #
+ # PortProfile の properties に NameValue 値を要素に追加する。
+ #
+ # @param key properties の name
+ # @param value properties の value
+ #
+ # @else
+ #
+ # @brief Append NameValue data to PortProfile's properties
+ #
+ # Append NameValue data to PortProfile's properties.
+ #
+ # @param key The name of properties
+ # @param value The value of properties
+ #
+ # @endif
+ # void appendProperty(const char* key, const char* value)
+ def appendProperty(self, key, value):
+ OpenRTM_aist.NVUtil.appendStringValue(self._profile.properties, key, value)
+
+
+
+ ##
+ # @if jp
+ #
+ # @brief 存在しないポートをdisconnectする。
+ #
+ # @else
+ #
+ # @brief Disconnect ports that doesn't exist.
+ #
+ # @endif
+ # void updateConnectors()
+ def updateConnectors(self):
+ guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
+
+ connector_ids = []
+ clist = self._profile.connector_profiles
+
+ for cprof in clist:
+ if not self.checkPorts(cprof.ports):
+ connector_ids.append(cprof.connector_id)
+ self._rtcout.RTC_WARN("Dead connection: %s", cprof.connector_id)
+
+ for cid in connector_ids:
+ self.disconnect(cid)
+
+ return
+
+
+ ##
+ # @if jp
+ #
+ # @brief ポートの存在を確認する。
+ #
+ # @param ports 確認するポート
+ # @return true:存在する,false:存在しない
+ #
+ # @else
+ #
+ # @brief Existence of ports
+ #
+ # @param ports Checked ports
+ # @return true:existent,false:non existent
+ #
+ # @endif
+ # bool checkPorts(::RTC::PortServiceList& ports)
+ def checkPorts(self, ports):
+ for port in ports:
+ try:
+ if port._non_existent():
+ self._rtcout.RTC_WARN("Dead Port reference detected.")
+ return False
+ except:
+ self._rtcout.RTC_WARN(OpenRTM_aist.Logger.print_exception())
+ return False
+
+ return True
+
+
+ #inline void onNotifyConnect(const char* portname,
+ # RTC::ConnectorProfile& profile)
+ def onNotifyConnect(self, portname, profile):
+ if self._portconnListeners != None:
+ type = OpenRTM_aist.PortConnectListenerType.ON_NOTIFY_CONNECT
+ self._portconnListeners.portconnect_[type].notify(portname, profile)
+ return
+
+
+ #inline void onNotifyDisconnect(const char* portname,
+ # RTC::ConnectorProfile& profile)
+ def onNotifyDisconnect(self, portname, profile):
+ if self._portconnListeners != None:
+ type = OpenRTM_aist.PortConnectListenerType.ON_NOTIFY_DISCONNECT
+ self._portconnListeners.portconnect_[type].notify(portname, profile)
+ return
+
+
+ #inline void onUnsubscribeInterfaces(const char* portname,
+ # RTC::ConnectorProfile& profile)
+ def onUnsubscribeInterfaces(self, portname, profile):
+ if self._portconnListeners != None:
+ type = OpenRTM_aist.PortConnectListenerType.ON_UNSUBSCRIBE_INTERFACES
+ self._portconnListeners.portconnect_[type].notify(portname, profile)
+ return
+
+
+ #inline void onPublishInterfaces(const char* portname,
+ # RTC::ConnectorProfile& profile,
+ # ReturnCode_t ret)
+ def onPublishInterfaces(self, portname, profile, ret):
+ if self._portconnListeners != None:
+ type = OpenRTM_aist.PortConnectRetListenerType.ON_PUBLISH_INTERFACES
+ self._portconnListeners.portconnret_[type].notify(portname, profile, ret)
+ return
+
+
+ #inline void onConnectNextport(const char* portname,
+ # RTC::ConnectorProfile& profile,
+ # ReturnCode_t ret)
+ def onConnectNextport(self, portname, profile, ret):
+ if self._portconnListeners != None:
+ type = OpenRTM_aist.PortConnectRetListenerType.ON_CONNECT_NEXTPORT
+ self._portconnListeners.portconnret_[type].notify(portname, profile, ret)
+ return
+
+
+ #inline void onSubscribeInterfaces(const char* portname,
+ # RTC::ConnectorProfile& profile,
+ # ReturnCode_t ret)
+ def onSubscribeInterfaces(self, portname, profile, ret):
+ if self._portconnListeners != None:
+ type = OpenRTM_aist.PortConnectRetListenerType.ON_SUBSCRIBE_INTERFACES
+ self._portconnListeners.portconnret_[type].notify(portname, profile, ret)
+ return
+
+
+ #inline void onConnected(const char* portname,
+ # RTC::ConnectorProfile& profile,
+ # ReturnCode_t ret)
+ def onConnected(self, portname, profile, ret):
+ if self._portconnListeners != None:
+ type = OpenRTM_aist.PortConnectRetListenerType.ON_CONNECTED
+ self._portconnListeners.portconnret_[type].notify(portname, profile, ret)
+ return
+
+
+ #inline void onDisconnectNextport(const char* portname,
+ # RTC::ConnectorProfile& profile,
+ # ReturnCode_t ret)
+ def onDisconnectNextport(self, portname, profile, ret):
+ if self._portconnListeners != None:
+ type = OpenRTM_aist.PortConnectRetListenerType.ON_DISCONNECT_NEXT
+ self._portconnListeners.portconnret_[type].notify(portname, profile, ret)
+ return
+
+
+ #inline void onDisconnected(const char* portname,
+ # RTC::ConnectorProfile& profile,
+ # ReturnCode_t ret)
+ def onDisconnected(self, portname, profile, ret):
+ if self._portconnListeners != None:
+ type = OpenRTM_aist.PortConnectRetListenerType.ON_DISCONNECTED
+ self._portconnListeners.portconnret_[type].notify(portname, profile, ret)
+ return
+
+
+
+ #============================================================
+ # Functor
+ #============================================================
+
+ ##
+ # @if jp
+ # @class if_name
+ # @brief instance_name を持つ PortInterfaceProfile を探す Functor
+ # @else
+ # @brief A functor to find a PortInterfaceProfile named instance_name
+ # @endif
+ class if_name:
+ def __init__(self, name):
+ self._name = name
+
+ def __call__(self, prof):
+ return str(self._name) == str(prof.instance_name)
+
+
+ ##
+ # @if jp
+ # @class find_conn_id
+ # @brief id を持つ ConnectorProfile を探す Functor
+ # @else
+ # @brief A functor to find a ConnectorProfile named id
+ # @endif
+ class find_conn_id:
+ def __init__(self, id_):
+ """
+ \param id_(string)
+ """
+ self._id = id_
+
+ def __call__(self, cprof):
+ """
+ \param cprof(RTC.ConnectorProfile)
+ """
+ return str(self._id) == str(cprof.connector_id)
+
+ ##
+ # @if jp
+ # @class find_port_ref
+ # @brief コンストラクタ引数 port_ref と同じオブジェクト参照を探す Functor
+ # @else
+ # @brief A functor to find the object reference that is identical port_ref
+ # @endif
+ class find_port_ref:
+ def __init__(self, port_ref):
+ """
+ \param port_ref(RTC.PortService)
+ """
+ self._port_ref = port_ref
+
+ def __call__(self, port_ref):
+ """
+ \param port_ref(RTC.PortService)
+ """
+ return self._port_ref._is_equivalent(port_ref)
+
+ ##
+ # @if jp
+ # @class connect_func
+ # @brief Port の接続を行う Functor
+ # @else
+ # @brief A functor to connect Ports
+ # @endif
+ class connect_func:
+ def __init__(self, p, prof):
+ """
+ \param p(RTC.PortService)
+ \param prof(RTC.ConnectorProfile)
+ """
+ self._port_ref = p
+ self._connector_profile = prof
+ self.return_code = RTC.RTC_OK
+
+ def __call__(self, p):
+ """
+ \param p(RTC.PortService)
+ """
+ if not self._port_ref._is_equivalent(p):
+ retval = p.notify_connect(self._connector_profile)
+ if retval != RTC.RTC_OK:
+ self.return_code = retval
+
+ ##
+ # @if jp
+ # @class disconnect_func
+ # @brief Port の接続解除を行う Functor
+ # @else
+ # @brief A functor to disconnect Ports
+ # @endif
+ class disconnect_func:
+ def __init__(self, p, prof):
+ """
+ \param p(RTC.PortService)
+ \param prof(RTC.ConnectorProfile)
+ """
+ self._port_ref = p
+ self._connector_profile = prof
+ self.return_code = RTC.RTC_OK
+
+ def __call__(self, p):
+ """
+ \param p(RTC.PortService)
+ """
+ if not self._port_ref._is_equivalent(p):
+ retval = p.disconnect(self._connector_profile.connector_id)
+ if retval != RTC.RTC_OK:
+ self.return_code = retval
+
+ ##
+ # @if jp
+ # @class disconnect_all_func
+ # @brief Port の全接続解除を行う Functor
+ # @else
+ # @brief A functor to disconnect all Ports
+ # @endif
+ class disconnect_all_func:
+ def __init__(self, p):
+ """
+ \param p(OpenRTM_aist.PortBase)
+ """
+ self.return_code = RTC.RTC_OK
+ self._port = p
+
+ def __call__(self, p):
+ """
+ \param p(RTC.ConnectorProfile)
+ """
+ retval = self._port.disconnect(p.connector_id)
+ if retval != RTC.RTC_OK:
+ self.return_code = retval
+
+ ##
+ # @if jp
+ # @class find_interface
+ # @brief name と polarity から interface を探す Functor
+ # @else
+ # @brief A functor to find interface from name and polarity
+ # @endif
+ class find_interface:
+ def __init__(self, name, pol):
+ """
+ \param name(string)
+ \param pol(RTC.PortInterfacePolarity)
+ """
+ self._name = name
+ self._pol = pol
+
+ def __call__(self, prof):
+ """
+ \param prof(RTC.PortInterfaceProfile)
+ """
+ name = prof.instance_name
+ return (str(self._name) == str(name)) and (self._pol == prof.polarity)
Modified: trunk/OpenRTM-aist-Python/OpenRTM_aist/__init__.py
===================================================================
--- trunk/OpenRTM-aist-Python/OpenRTM_aist/__init__.py 2016-02-01 05:29:04 UTC (rev 642)
+++ trunk/OpenRTM-aist-Python/OpenRTM_aist/__init__.py 2016-02-01 08:37:55 UTC (rev 643)
@@ -100,12 +100,3 @@
from PublisherNew import *
from PublisherPeriodic import *
from FactoryInit import *
-from InPortDirectConsumer import *
-from InPortDirectProvider import *
-from OutPortDirectConsumer import *
-from OutPortDirectProvider import *
-from InPortSHMConsumer import *
-from InPortSHMProvider import *
-from OutPortSHMConsumer import *
-from OutPortSHMProvider import *
-from CORBA_RTCUtil import *
More information about the openrtm-commit
mailing list