OpenRTM / OpenRTM-aist

OpenRTM-aist: RT-Middleware and OMG RTC implementation in C++ implemented by AIST
https://openrtm.org/
Other
19 stars 12 forks source link

コンポーネントのインスタンス名の変更 #475

Closed y-masutani closed 5 years ago

y-masutani commented 5 years ago

コンポーネントのインスタンス名を変更する簡単な方法はないでしょうか?起動時にコマンドラインに以下のようなオプションを付ければいいことは知っていますが,面倒です.

 -o カテゴリ名.RTC名.instance_name:新しい名前
n-ando commented 5 years ago

今のところ、ご提示の方法か、rtc.confに同等のオプションを記載するくらいしか方法はありません。

ZZZComp.exe --rtcname RTC名:インスタンス名 とか YYYComp.exe --RTC名 インスタンス名 くらいなら簡単といえるでしょうか?

y-masutani commented 5 years ago

返信ありがとうございます. カテゴリ名やRTC名をわざわざ指定しないといけないのが,不思議ですし,面倒です.

XXXComp.exe --instance_name:インスタンス名

という様にはできないものでしょうか?

n-ando commented 5 years ago

ご存じとは思いますが、スタンドアロンコンポーネントも実際には複数のインスタンスを起動することができ、また、他のRTCのモジュールもロードしてインスタンス化することも可能です。(ConsoleInのrtc.confのサンプルをご覧ください。)したがって、カテゴリ名やRTC名を指定しないと特定のRTCに対してインスタンス名を指定できません。

ただ、ご要望の方法に関して、以下のようにすることで、RTCのインスタンス化時のフックを利用して、インスタンス名を指定する方法を考えました。

./ConsoleInComp --instance_name=MyConsoleIn1000

→ ConsoleIn0 が MyConsoleIn1000 にrenameされる。

# rtc.conf に manager.components.precreate: ConsoleIn, ConsoleIn, ConsoleInを指定し、4つのインスタンスを起動
./ConsoleInComp --instance_name=MyConsoleIn1000 --instance_name2=MyConsoleIn1002 --instance_name3=MyConsoleIn1003

→ ConsoleIn0~3がそれぞれ、MyConsoleIn1000, ConsoleIn1, MySConsoleIn1002, MyConsoleIn1003 にrenameされる。

コードは、XXXComp.cpp内に以下のクラスを定義。

class OverwriteInstanceName
  : public RTM::RtcLifecycleActionListener
{
public:
  OverwriteInstanceName(int argc, char** argv)
    : m_names(0), m_count(0)
  {
    for (size_t i = 0; i < argc; ++i)
      {
        coil::vstring opt = coil::split(argv[i], "=");
        if (opt.size() != 2) { continue; }
        if (opt[0].find("--instance_name") != std::string::npos)
          {
            coil::replaceString(opt[0], "--instance_name", "");
            if (opt[0].empty()) { opt[0] += "0"; }
            size_t n;
            coil::stringTo(n, opt[0].c_str());
            if (m_names.size() < (n + 1)) { m_names.resize(n + 1); }
            m_names.at(n) = opt[1];
          }
      }
  }
  virtual ~OverwriteInstanceName() {}
  virtual void preCreate(std::string& args)
  {
    if (!(m_count < m_names.size()) || m_names[m_count].empty()) { ++m_count; return; }
    args = args + "?instance_name=" + m_names[m_count];
    ++m_count;
  };
  virtual void postCreate(RTC::RTObject_impl*) {};
  virtual void preConfigure(coil::Properties&) {};
  virtual void postConfigure(coil::Properties&) {};
  virtual void preInitialize() {};
  virtual void postInitialize() {};
private:
  coil::vstring m_names;
  int32_t m_count;
};

main関数内で、addRtcLifecycleActionListener にてリスナを追加、

int main (int argc, char** argv)
{
  RTC::Manager* manager;
  manager = RTC::Manager::init(argc, argv);
  manager->addRtcLifecycleActionListener(new OverwriteInstanceName(argc, argv),
                                         true);

こんな感じでよければ、RTCBuilderの生成コードにこれを反映させます。

y-masutani commented 5 years ago

ご存じとは思いますが、スタンドアロンコンポーネントも実際には複数のインスタンスを起動することができ、また、他のRTCのモジュールもロードしてインスタンス化することも可能です。(ConsoleInのrtc.confのサンプルをご覧ください。)したがって、カテゴリ名やRTC名を指定しないと特定のRTCに対してインスタンス名を指定できません。

本件,よくわかっていませんでした.モジュールをロードするのはrtcdでやるのだと思っていました.

ご提示いただいた「--instance_name=」というオプションがあると,大変ありがたいです.

一方で,「--instance_name2=」「--instance_name3=」は美しくないように思います.これを使うには,rtc.confに記述が必要ですよね.であれば,インスタンス名もrtc.confに書く方がすっきりするのではないでしょうか.

n-ando commented 5 years ago

そうですね、ではinstance_nameオプションのみにします。

n-ando commented 5 years ago

OpenRTPのissueにあげなおしましたのでクローズします。 https://github.com/OpenRTM/OpenRTP-aist/issues/109