[openrtm-commit:00657] r2302 - in trunk/OpenRTM-aist: etc src/lib/rtm
openrtm @ openrtm.org
openrtm @ openrtm.org
2012年 2月 4日 (土) 03:57:45 JST
Author: n-ando
Date: 2012-02-04 03:57:44 +0900 (Sat, 04 Feb 2012)
New Revision: 2302
Modified:
trunk/OpenRTM-aist/etc/component.conf
trunk/OpenRTM-aist/etc/rtc.conf.sample
trunk/OpenRTM-aist/src/lib/rtm/RTObject.cpp
trunk/OpenRTM-aist/src/lib/rtm/RTObject.h
Log:
[incompat,header/imple,func] The method to create EC has been changed. Now zero or more EC can be attached to RTC. Configuration options for EC have been changed changed. refs #2349
Modified: trunk/OpenRTM-aist/etc/component.conf
===================================================================
--- trunk/OpenRTM-aist/etc/component.conf 2012-02-03 17:45:45 UTC (rev 2301)
+++ trunk/OpenRTM-aist/etc/component.conf 2012-02-03 18:57:44 UTC (rev 2302)
@@ -44,6 +44,99 @@
# exec_cxt.event_driven.type: [specify event driven type EC]
#
+#
+# State transition mode settings YES/NO
+#
+# Default: YES (efault setting is recommended.)
+#
+# Activating, deactivating and resetting of RTC performs state
+# transition. Some execution contexts might execute main logic in
+# different thread. If these flags are set to YES, activation,
+# deactivation and resetting will be performed synchronously. In other
+# words, if these flags are YES,
+# activation/deactivation/resetting-operations must be returned after
+# state transition completed.
+#
+# "sync_transition" will set synchronous transition flags to all other
+# synchronous transition flags sync_activation/deactivation/reset.
+#
+# exec_cxt.sync_transition: YES
+# exec_cxt.sync_activation: YES
+# exec_cxt.sync_deactivation: YES
+# exec_cxt.sync_reset: YES
+
+#
+# Timeout of synchronous state transition [s]
+#
+# Default: 0.5 [s]
+#
+# When synchronous transition flags are set to YES, the following
+# timeout settings are valid. If "transition_timeout" is set, the
+# value will be set to all other timeout of activation/deactivation
+# and resetting
+#
+# exec_cxt.transition_timeout: 0.5
+# exec_cxt.activation_timeout: 0.5
+# exec_cxt.deactivation_timeout: 0.5
+# exec_cxt.reset_timeout: 0.5
+
+#
+# Specifying Execution Contexts
+#
+# Default: No default
+#
+# execution_contexts: None or <EC0>,<EC1>,...
+# <EC?>: ECtype(ECname)
+#
+# RTC can be attached with zero or more Execution
+# Contexts. "execution_contexts" option specifies RTC-specific
+# attached ECs and its name. If the option is not specified, the
+# internal global options or rtc.conf options related to EC will be
+# used. If None is specified, no EC will be created.
+#
+# Availabilities in OpenRTM-aist
+#
+# - ExtTrigExecutionContext: External triggered EC. It is embedded in
+# OpenRTM library.
+# - OpenHRPExecutionContext: External triggred paralell execution
+# EC. It is embedded in OpenRTM
+# library. This is usually used with
+# OpenHRP3.
+# - RTPreemptEC: Real-time execution context for Linux
+# RT-preemptive pathed kernel.
+# - ArtExecutionContext: Real-time execution context for ARTLinux
+# (http://sourceforge.net/projects/art-linux/)
+#
+# execution_contexts: PeriodicExecutionContext(pec1000Hz), \
+# PeriodicExecutionContext(pec500Hz)
+
+#
+# EC specific configurations
+#
+# Default: No default
+#
+# Each EC can have its own configuration. Individual configuration can
+# be specified by using EC type name or EC instance name. Attached ECs
+# would be specified in execution_context option like <EC type
+# name>(<EC instance name>), ... EC specific option can be specified
+# as follows.
+#
+# ec.<EC type name>.<option>
+# ec.<EC instance name>.<option>
+#
+# Example:
+# ec.PeriodicExecutionContext.sync_transition: NO
+# ec.pec1000Hz.rate: 1000
+# ec.pec1000Hz.synch_transition: YES
+# ec.pec1000Hz.transition_timeout: 0.5
+# ec.pec500Hz.rate: 500
+# ec.pec500Hz.synch_activation: YES
+# ec.pec500Hz.synch_deactivation: NO
+# ec.pec500Hz.synch_reset: YES
+# ec.pec500Hz.activation_timeout: 0.5
+# ec.pec500Hz.reset_timeout: 0.5
+
+
#============================================================
# port configurations
#
Modified: trunk/OpenRTM-aist/etc/rtc.conf.sample
===================================================================
--- trunk/OpenRTM-aist/etc/rtc.conf.sample 2012-02-03 17:45:45 UTC (rev 2301)
+++ trunk/OpenRTM-aist/etc/rtc.conf.sample 2012-02-03 18:57:44 UTC (rev 2302)
@@ -383,12 +383,51 @@
# (http://sourceforge.net/projects/art-linux/)
#
exec_cxt.periodic.type: PeriodicExecutionContext
+# exec_cxt.event_driven_type: to be implemented
#
# The execution cycle of ExecutionContext
#
exec_cxt.periodic.rate: 1000
+#
+# State transition mode settings YES/NO
+#
+# Default: YES (efault setting is recommended.)
+#
+# Activating, deactivating and resetting of RTC makes state
+# transition. Some execution contexts execute main logic in different
+# thread. If these flags set to YES, activation, deactivation and
+# resetting will be performed synchronously. In other words, if these
+# flags are YES, activation/deactivation/resetting-operations must be
+# returned after state transition completed.
+#
+# "synchronous_transition" will set synchronous transition flags to
+# all other synchronous transition flags
+# (synchronous_activation/deactivation/resetting.
+#
+exec_cxt.sync_transition: YES
+exec_cxt.sync_activation: YES
+exec_cxt.sync_deactivation: YES
+exec_cxt.sync_reset: YES
+
+#
+# Timeout of synchronous state transition [s]
+#
+# Default: 1.0 [s]
+#
+# When synchronous transition flags are set to YES, the following
+# timeout settings are valid. If "transition_timeout" is set, the
+# value will be set to all other timeout of activation/deactivation
+# and resetting
+#
+exec_cxt.transition_timeout: 0.5
+exec_cxt.activation_timeout: 0.5
+exec_cxt.deactivation_timeout: 0.5
+exec_cxt.reset_timeout: 0.5
+
+
+
#============================================================
# SDO service settings
#============================================================
Modified: trunk/OpenRTM-aist/src/lib/rtm/RTObject.cpp
===================================================================
--- trunk/OpenRTM-aist/src/lib/rtm/RTObject.cpp 2012-02-03 17:45:45 UTC (rev 2301)
+++ trunk/OpenRTM-aist/src/lib/rtm/RTObject.cpp 2012-02-03 18:57:44 UTC (rev 2302)
@@ -311,61 +311,40 @@
throw (CORBA::SystemException)
{
RTC_TRACE(("initialize()"));
- std::string ec_type;
- std::string ec_args;
- ec_type = m_properties["exec_cxt.periodic.type"];
- ec_args += m_properties["exec_cxt.periodic.type"];
- ec_args += "?";
- ec_args += "rate=" + m_properties["exec_cxt.periodic.rate"];
-
- RTC::ExecutionContextBase* ec;
- ec = RTC::ExecutionContextFactory::instance().createObject(ec_type.c_str());
- if (ec == NULL)
+ // EC creation
+ std::vector<coil::Properties> ec_args;
+ if (getContextOptions(ec_args) != RTC::RTC_OK)
{
- RTC_ERROR(("EC (%s) creation failed.", ec_type.c_str()));
- coil::vstring ecs;
- ecs = RTC::ExecutionContextFactory::instance().getIdentifiers();
- RTC_DEBUG(("Available EC list: %s",
- coil::flatten(ecs).c_str()));
- return RTC::RTC_ERROR;
+ RTC_ERROR(("Valid EC options are not available. Aborting"));
+ return RTC::BAD_PARAMETER;
}
- RTC_DEBUG(("EC (%s) created.", ec_type.c_str()));
-
- m_eclist.push_back(ec);
- ExecutionContextService_var ecv;
- ecv = RTC::ExecutionContextService::_duplicate(ec->getObjRef());
- if (CORBA::is_nil(ecv))
+ if (createContexts(ec_args) != RTC::RTC_OK)
{
- RTC_ERROR(("Getting object reference of ec failed."));
- return RTC::RTC_ERROR;
+ RTC_ERROR(("EC creation failed. Maybe out of resources. Aborting."));
+ return RTC::OUT_OF_RESOURCES;
}
- double ec_rate;
- coil::stringTo(ec_rate, m_properties["exec_cxt.periodic.rate"].c_str());
- ecv->set_rate(ec_rate);
- RTC_DEBUG(("Execution context rate is set to %f.", ec_rate));
- ec->bindComponent(this);
// -- entering alive state --
- // at least one EC must be attached
- if (m_ecMine.length() == 0)
- {
- RTC_ERROR(("No EC of this RTC."));
- return RTC::PRECONDITION_NOT_MET;
- }
-
+ RTC_INFO(("%d execution context%s created.",
+ m_ecMine.length(),
+ (m_ecMine.length() == 1) ? " was" : "s were"));
ReturnCode_t ret;
ret = on_initialize();
m_created = false;
- if (ret != RTC::RTC_OK) return ret;
-
+ if (ret != RTC::RTC_OK)
+ {
+ RTC_ERROR(("on_initialize() failed."));
+ return ret;
+ }
+ RTC_DEBUG(("on_initialize() was properly done."));
for (::CORBA::ULong i(0), len(m_ecMine.length()); i < len; ++i)
{
RTC_DEBUG(("EC[%d] starting.", i));
m_ecMine[i]->start();
}
-
// ret must be RTC_OK
+ assert(ret == RTC::RTC_OK);
return ret;
}
@@ -907,11 +886,11 @@
try
{
preOnShutdown(ec_id);
- ret = onShutdown(ec_id);
+ ret = onShutdown(ec_id);
}
catch (...)
{
- ret = RTC::RTC_ERROR;
+ ret = RTC::RTC_ERROR;
}
postOnShutdown(ec_id, ret);
return ret;
@@ -932,13 +911,13 @@
try
{
preOnActivated(ec_id);
- m_configsets.update();
- ret = onActivated(ec_id);
+ m_configsets.update();
+ ret = onActivated(ec_id);
m_portAdmin.activatePorts();
}
catch (...)
{
- ret = RTC::RTC_ERROR;
+ ret = RTC::RTC_ERROR;
}
postOnActivated(ec_id, ret);
return ret;
@@ -960,7 +939,7 @@
{
preOnDeactivated(ec_id);
m_portAdmin.deactivatePorts();
- ret = onDeactivated(ec_id);
+ ret = onDeactivated(ec_id);
}
catch (...)
{
@@ -2440,7 +2419,7 @@
{
m_configsets.addConfigurationSetListener(type, listener, autoclean);
}
-
+
/*!
* @if jp
* @brief ConfigurationSetListener を削除する
@@ -2454,7 +2433,7 @@
{
m_configsets.removeConfigurationSetListener(type, listener);
}
-
+
/*!
* @if jp
* @brief ConfigurationSetNameListener を追加する
@@ -2469,7 +2448,7 @@
{
m_configsets.addConfigurationSetNameListener(type, listener, autoclean);
}
-
+
/*!
* @if jp
* @brief ConfigurationSetNameListener を削除する
@@ -2497,14 +2476,14 @@
RTC_TRACE(("shutdown()"));
try
{
- finalizePorts();
+ finalizePorts();
finalizeContexts();
PortableServer::ObjectId_var oid1;
oid1 = m_pPOA->servant_to_id(m_pSdoConfigImpl);
PortableServer::ObjectId_var oid2;
oid2 = m_pPOA->servant_to_id(this);
- m_pPOA->deactivate_object(oid1);
- m_pPOA->deactivate_object(oid2);
+ m_pPOA->deactivate_object(oid1);
+ m_pPOA->deactivate_object(oid2);
}
catch (PortableServer::POA::ServantNotActive &e)
{
@@ -2519,7 +2498,7 @@
// never throws exception
RTC_ERROR(("Unknown exception caught."));
}
-
+
if (m_pManager != NULL)
{
RTC_DEBUG(("Cleanup on Manager"));
@@ -2527,6 +2506,231 @@
}
}
+ ReturnCode_t RTObject_impl::
+ getInheritedECOptions(coil::Properties& default_opts)
+ {
+ const char* inherited_opts[] =
+ {
+ "sync_transition",
+ "sync_activation",
+ "sync_deactivation",
+ "sync_reset",
+ "transition_timeout",
+ "activation_timeout",
+ "deactivation_timeout",
+ "reset_timeout",
+ ""
+ };
+ coil::Properties* p = m_properties.findNode("exec_cxt");
+ if (p == NULL)
+ {
+ RTC_WARN(("No exec_cxt option found."));
+ return RTC::RTC_ERROR;
+ }
+ RTC_DEBUG(("Copying inherited EC options."));
+ for (size_t i(0); inherited_opts[i][0] != '\0'; ++i)
+ {
+ if ((*p).findNode(inherited_opts[i]) != NULL)
+ {
+ RTC_PARANOID(("Option %s exists.", inherited_opts[i]));
+ default_opts[inherited_opts[i]] = (*p)[inherited_opts[i]];
+ }
+ }
+ return RTC::RTC_OK;
+ }
+ /*!
+ * @brief getting individual EC options from RTC's configuration file
+ */
+ ReturnCode_t RTObject_impl::
+ getPrivateContextOptions(std::vector<coil::Properties>& ec_args)
+ {
+ RTC_TRACE(("getPrivateContextOptions()"));
+ // Component specific multiple EC option available
+ if (m_properties.findNode("execution_contexts") == NULL)
+ {
+ RTC_DEBUG(("No component specific EC specified."));
+ return RTC::RTC_ERROR;
+ }
+ std::string& args(m_properties["execution_contexts"]);
+ coil::vstring ecs_tmp = coil::split(args, ",", true);
+ if (ecs_tmp.empty()) { return RTC::RTC_ERROR; }
+ RTC_DEBUG(("Component specific e EC option available,"));
+ RTC_DEBUG(("%s", args.c_str()));
+ coil::Properties default_opts;
+ getInheritedECOptions(default_opts);
+ for (size_t i(0); i < ecs_tmp.size(); ++i)
+ {
+ if (coil::normalize(ecs_tmp[i]) == "none")
+ {
+ RTC_INFO(("EC none. EC will not be bound to the RTC."));
+ ec_args.clear();
+ return RTC::RTC_OK;
+ }
+ coil::vstring type_and_name = coil::split(ecs_tmp[i], "(", true);
+ if (type_and_name.size() > 2)
+ {
+ RTC_DEBUG(("Invalid EC type specified: %s", ecs_tmp[i].c_str()));
+ continue;
+ }
+ coil::Properties p = default_opts;
+ // create EC's properties
+ p["type"] = type_and_name[0];
+ RTC_DEBUG(("p_type: %s", p["type"].c_str()));
+ coil::Properties* p_type = m_properties.findNode("ec." + p["type"]);
+ if (p_type != NULL)
+ {
+ RTC_DEBUG(("p_type props:"));
+ RTC_DEBUG_STR((*p_type));
+ p << *p_type;
+ }
+ else { RTC_DEBUG(("p_type none")); }
+
+ // EC name specified
+ RTC_DEBUG(("size: %d, name: %s", type_and_name.size(),
+ type_and_name[1].c_str()))
+ if (type_and_name.size() == 2 &&
+ type_and_name[1].at(type_and_name[1].size() - 1) == ')')
+ {
+ type_and_name[1].erase(type_and_name[1].size() - 1);
+ p["name"] = type_and_name[1];
+ coil::Properties* p_name = m_properties.findNode("ec." + p["name"]);
+ if (p_name != NULL)
+ {
+ RTC_DEBUG(("p_name props:"));
+ RTC_DEBUG_STR((*p_name));
+ p << *p_name;
+ }
+ else { RTC_DEBUG(("p_name none")); }
+ }
+ ec_args.push_back(p);
+ RTC_DEBUG(("New EC properties stored:"));
+ RTC_DEBUG_STR((p));
+ }
+ return RTC::RTC_OK;
+ }
+
+ /*!
+ * @brief getting global EC options from rtc.conf
+ */
+ ReturnCode_t RTObject_impl::
+ getGlobalContextOptions(coil::Properties& global_ec_props)
+ {
+ // exec_cxt option is obsolete
+ RTC_TRACE(("getGlobalContextOptions()"));
+
+ coil::Properties* prop = m_properties.findNode("exec_cxt.periodic");
+ if (prop == NULL)
+ {
+ RTC_WARN(("No global EC options found."));
+ return RTC::RTC_ERROR;
+ }
+ RTC_DEBUG(("Global EC options are specified."));
+ RTC_DEBUG_STR((*prop));
+ getInheritedECOptions(global_ec_props);
+ global_ec_props << *prop;
+ return RTC::RTC_OK;
+ }
+
+ /*!
+ * @brief getting EC options
+ */
+ ReturnCode_t RTObject_impl::
+ getContextOptions(std::vector<coil::Properties>& ec_args)
+ {
+ RTC_DEBUG(("getContextOptions()"));
+ coil::Properties global_props;
+ ReturnCode_t ret_global = getGlobalContextOptions(global_props);
+ ReturnCode_t ret_private = getPrivateContextOptions(ec_args);
+
+ // private(X), global(X) -> error
+ // private(O), global(O) -> private
+ // private(X), global(O) -> global
+ // private(O), global(X) -> private
+ if (ret_global != RTC::RTC_OK && ret_private != RTC::RTC_OK)
+ {
+ return RTC::RTC_ERROR;
+ }
+ if (ret_global == RTC::RTC_OK && ret_private != RTC::RTC_OK)
+ {
+ ec_args.push_back(global_props);
+ }
+ return RTC::RTC_OK;
+ }
+
+ /*!
+ * @brief finding existing EC from the factory
+ */
+ ReturnCode_t RTObject_impl::
+ findExistingEC(coil::Properties& ec_arg,
+ RTC::ExecutionContextBase*& ec)
+ {
+ std::vector<RTC::ExecutionContextBase*> eclist;
+ eclist = RTC::ExecutionContextFactory::instance().createdObjects();
+ for (size_t i(0); i < eclist.size(); ++i)
+ {
+ if (eclist[i]->getProperties()["type"] == ec_arg["type"] &&
+ eclist[i]->getProperties()["name"] == ec_arg["name"])
+ {
+ ec = eclist[i];
+ return RTC::RTC_OK;
+ }
+ }
+ return RTC::RTC_ERROR;
+ }
+
+ /*!
+ * @brief creating, initializing and binding context
+ */
+ ReturnCode_t RTObject_impl::
+ createContexts(std::vector<coil::Properties>& ec_args)
+ {
+ ReturnCode_t ret(RTC::RTC_OK);
+ coil::vstring avail_ec
+ = RTC::ExecutionContextFactory::instance().getIdentifiers();
+
+ for (size_t i(0); i < ec_args.size(); ++i)
+ {
+ std::string& ec_type(ec_args[i]["type"]);
+ std::string& ec_name(ec_args[i]["name"]);
+ RTC::ExecutionContextBase* ec;
+ if (!ec_name.empty() &&
+ findExistingEC(ec_args[i], ec) == RTC::RTC_OK)
+ { // if EC's name exists, find existing EC in the factory.
+ RTC_DEBUG(("EC: type=%s, name=%s already exists.",
+ ec_type.c_str(), ec_name.c_str()));
+ }
+ else
+ { // If EC's name is empty or no existing EC, create new EC.
+ if (std::find(avail_ec.begin(), avail_ec.end(), ec_type)
+ == avail_ec.end())
+ {
+ RTC_WARN(("EC %s is not available.", ec_type.c_str()));
+ RTC_DEBUG(("Available ECs: %s",
+ coil::flatten(avail_ec).c_str()));
+ continue;
+ }
+ ec = RTC::ExecutionContextFactory::
+ instance().createObject(ec_type.c_str());
+ }
+
+ if (ec == NULL)
+ { // EC factory available but creation failed. Resource full?
+ RTC_ERROR(("EC (%s) creation failed.", ec_type.c_str()));
+ RTC_DEBUG(("Available EC list: %s",
+ coil::flatten(avail_ec).c_str()));
+ ret = RTC::RTC_ERROR;
+ continue;
+ }
+ RTC_DEBUG(("EC (%s) created.", ec_type.c_str()));
+
+ ec->init(ec_args[i]);
+ m_eclist.push_back(ec);
+ ec->bindComponent(this);
+ }
+ return ret;
+ }
+
+
}
Modified: trunk/OpenRTM-aist/src/lib/rtm/RTObject.h
===================================================================
--- trunk/OpenRTM-aist/src/lib/rtm/RTObject.h 2012-02-03 17:45:45 UTC (rev 2301)
+++ trunk/OpenRTM-aist/src/lib/rtm/RTObject.h 2012-02-03 18:57:44 UTC (rev 2302)
@@ -4542,7 +4542,38 @@
{
m_actionListeners.ecaction_[EC_DETACHED].notify(ec_id);
}
+
+ ReturnCode_t getInheritedECOptions(coil::Properties& default_opts);
+
+ /*!
+ * @brief getting individual EC options from RTC's configuration file
+ */
+ ReturnCode_t
+ getPrivateContextOptions(std::vector<coil::Properties>& ec_args);
+
+ /*!
+ * @brief getting global EC options from rtc.conf
+ */
+ ReturnCode_t
+ getGlobalContextOptions(coil::Properties& global_ec_props);
+
+ /*!
+ * @brief getting EC options
+ */
+ ReturnCode_t
+ getContextOptions(std::vector<coil::Properties>& ec_args);
+
+ /*!
+ * @brief fiding existing EC from the factory
+ */
+ ReturnCode_t findExistingEC(coil::Properties& ec_arg,
+ RTC::ExecutionContextBase*& ec);
+ /*!
+ * @brief creating, initializing and binding context
+ */
+ ReturnCode_t createContexts(std::vector<coil::Properties>& ec_args);
+
protected:
/*!
* @if jp
openrtm-commit メーリングリストの案内