gbiggs / rtshell

Shell commands for managing RT-Middleware running on OpenRTM-aist.
http://openrtm.org
GNU Lesser General Public License v3.0
10 stars 17 forks source link

rtcryo の副作用に起因する rtresurrect の問題 #24

Closed gbiggs closed 9 years ago

gbiggs commented 9 years ago

From 東京都立産業技術研究センター 佐々木さん

rtresurrect ends up with the following error message and doesn't restore configuration parameters specified in a system profile saved with rtcryo.

rtresurrect: No such configuration set: default

Workaround: A. Execute rtresurrect 3 times with the same system profile. B. Alternatively, make all the RT components composing the system have some `conf.default' properties at initialization even if the configuration parameters are not used

Test environment:

How to reproduce the problem:

# 設定 & 保存, Config. and save
  [00]$ rtcwd /localhost/foo.host_cxt
  [01]$ cd /usr/share/openrtm-1.1/example
  [02]$ ./ConsoleInComp &  # --> job spec %1
  [03]$ ./ConsoleOutComp & # --> job spec %2
  [04]$ cd ~/test/
  [05]$ python DoodleDoo.py # --> job spec %3,
   # --> DoodleDoo は 2個の config set を持つ (default と mode1) RTC
   #     ( DoodleDoo is an RTC that has 2 config sets, default and mode1. )

  [06]$ rtcon ConsoleIn0.rtc:out DoodleDoo0.rtc:in
  [07]$ rtcon rtcon DoodleDoo0.rtc:out ConsoleOut0.rtc:in
  [08]$ rtcat -ll ConsoleInComp |grep conf
   # --> この時点では conf.default なし
   #     (No `conf.default' at this point)

  [09]$ rtcryo -x -o test_sys.xml localhost
   # --> test_sys.xml に ConsoleIn につき rts:activeConfigurationSet="default" 指定なし
   #    (`rts:activeConfigurationSet="default"' not specified for ConsoleIn in test_sys.xml)

  [10]$ rtcat -ll ConsoleInComp |grep conf
   # --> この時点では conf.default あり (rtcryo の副作用による)
   #      (`conf.default' added at this point because of side effects of rtcryo)

  [11]$ rtconf DoodleDoo0.rtc -s mode1 act
  [12]$ rtconf DoodleDoo0.rtc
      +default
      +mode1*

  [14]$ rtcryo -x -o test_sys2.xml localhost
   # --> test_sys2.xml に ConsoleIn につき rts:activeConfigurationSet="default" 指定あり
   #    (`rts:activeConfigurationSet="default"' specified for ConsoleIn in test_sys.xml)

  # 復元, resurrection
  [15]$ kill -9 %1 %2 %3
  [16]$ cd /usr/share/openrtm-1.1/example
  [17]$ ./ConsoleInComp &  
  [18]$ ./ConsoleOutComp & 
  [19]$ cd ~/test/
  [20]$ python DoodleDoo.py
  [21]$ rtresurrect test_sys2.xml 
      rtresurrect: No such configuration set: default
   # --> NoConfSetError 例外が発生する,
   #     (NoConfSetError exception was raised)
   #     at /usr/local/lib/python2.7/dist-packages/rtshell/actions.py, Line 318

  [22]$ rtconf DoodleDoo0.rtc 
      +default
      +mode1
   # --> どちらの config set も active でない
   #     (no active config set)

  [23]$ rtresurrect test_sys2.xml 
      rtresurrect: No such configuration set: default
  [24]$ rtconf DoodleDoo0.rtc 
      +default
      +mode1*
   # --> NoConfSetError 例外は発生するが DoodleDoo の設定は 復元される
   #     ( NoConfSetError exception was raised, but the config set 
   #      for DoodleDoo was restored.)

  [25]$ rtresurrect test_sys2.xml
   # --> もう一度実行すると エラーメッセージがでない (No error message)

Causes: ConsoleIn doesn't have the conf.default' property at start [02]. But rtcryo has side effects to add theconf.default' property to the component [08]-[10]. On executing rtcryo after changing config parameters in DoodleDoo, it saves the active config set specification for ConsoleIn in test_sys2.xml [14].

Because ConsoleIn doesn't have the `conf.default' property at restart [17], executing rtresurrect with test_sys2.xml will raise NoConfSetError [21].

NoConfSetError exception raised for ConsoleIn keeps DoodleDoo away from configuration restoration since "DoodleDoo" is after "ConsoleIn" in order of actions taken by rtresurrect [22]. see /usr/local/lib/python2.7/dist-packages/rtshell/rtresurrect.py, Line 236.

DoodleDoo.py (test component):

#!/usr/bin/env python
# -*- coding: utf-8 -*- 
# -*- Python -*-

import sys
sys.path.append(".")

import RTC
import OpenRTM_aist

module_spec = [
  "implementation_id", "DoodleDoo", 
  "type_name",         "DoodleDoo", 
  "description",       "DoodleDoo", 
  "version",           "0.1", 
  "vendor",            "xxxx", 
  "category",          "test", 
  "activity_type",     "DataFlowComponent", 
  "max_instance",      "10", 
  "language",          "Python", 
  "lang_type",         "SCRIPT",
  "conf.default.coeff", "10",
  "conf.mode1.coeff",  "5",
  ""]

# //////////////////////////////////////////////////////////////////////////////
#!
#
class DoodleDoo(OpenRTM_aist.DataFlowComponentBase):
  def __init__(self, manager):
      OpenRTM_aist.DataFlowComponentBase.__init__(self, manager)
      self._coeff = [5]

  def makeInPort(self, name, data):
      port = OpenRTM_aist.InPort(name, data)
      self.addInPort(name, port)      
      return port

  def makeOutPort(self, name, data):
      port = OpenRTM_aist.OutPort(name, data)
      self.addOutPort(name, port)      
      return port

  def onInitialize(self):
      self._d_in = RTC.TimedLong(RTC.Time(0,0), 0)
      self._inIn = self.makeInPort("in", self._d_in)
      self._d_out = RTC.TimedLong(RTC.Time(0,0), 0)
      self._outOut = self.makeOutPort("out", self._d_out)

      self.bindParameter("coeff", self._coeff, str(self._coeff[0]))

      return RTC.RTC_OK

  def onActivated(self, ec_id):
      return RTC.RTC_OK

  def onDeactivated(self, ec_id):
      return RTC.RTC_OK

  def onExecute(self, ec_id):
      if self._inIn.isNew():
          self._inIn.read()
          self._d_out.data = self._coeff[0] * self._d_in.data
          OpenRTM_aist.setTimestamp(self._d_out)
          self._outOut.write()
      return RTC.RTC_OK

def DoodleDooInit(manager):
    profile = OpenRTM_aist.Properties(defaults_str=module_spec)
    manager.registerFactory(profile,
                            DoodleDoo,
                            OpenRTM_aist.Delete)

def MyModuleInit(manager):
    DoodleDooInit(manager)
    comp = manager.createComponent("DoodleDoo")

def main():
    mgr = OpenRTM_aist.Manager.init(sys.argv)
    mgr.setModuleInitProc(MyModuleInit)
    mgr.activateManager()
    mgr.runManager()

if __name__ == '__main__':
    main()
gbiggs commented 9 years ago

This problem is due to a bug in OpenRTM. The default configuration set is supposed to exist at all times, but it does not get created until the first call asking for a list of all configuration sets. rtcryo makes that call several times (rtconf makes it, too), causing the "default" set to get created before rtcryo gets the list of sets to save in the XML file.