ここではコンポーネントのコンフィグレーションを変更するプログラムについて解説します.
1. 概要
コンフィグレーションは実は「コンフィグレーションセット」という単位で管理されています.
このセットの概念を使えば,RTCの動作を場面に合わせてガラリと変化させることが出来ます.
たとえば,複数のセンサから構成されるセンサアレイを考えてみましょう.
屋外/屋内など,ロボットが動作する場面に合わせて複数のセンサのコンフィグレーションをいくつか同時に変更します.
ここで,コンフィグレーションセットとして「屋外」と「屋内」を与えておき,場面に合わせてセットごと変更すれば手間が省けます.
ここでは,デフォルトで追加されているコンフィグレーションセット「default」を読みだして更新する方法と,新しいコンフィグレーションセットを追加して,そちらをアクティブ化するプログラムの作成方法をお教えします.
2. プロジェクト生成
前回の記事のようにRTCビルダーで生成してから不要な部分を削除。
これでプロジェクトの設定は終了です.
2.3 プログラミング
- RTCActivate2.cpp
- stdafx.h
- stdafx.cpp
- targetver.h
2.3.1 stdafx.h
これはプリコンパイルヘッダーの設定がされていて,変更が少ないヘッダーファイルのみをコンパイル単位として保存しておき,再コンパイル時に,いちいち再コンパイルされずに作業を効率化するのが目的です.この部分にRTC.hやManager.hなどのコンパイルに時間がかかるファイルを置いておくと,作業がはかどります.
#pragma once #include "targetver.h" #include <stdio.h> #include <tchar.h> #include <iostream> #include <rtm/CorbaNaming.h> #include <rtm/RTObject.h> #include <rtm/CorbaConsumer.h> #include <assert.h> |
2.3.2 RTCActivate2.cpp
まずは”default”コンフィグレーションセットを取得して変更する方法について.
プログラムの流れは,
- CORBAオブジェクトを作成して,ネームサーバーを取得.
- ネームサーバーから起動しているコンポーネントの中からPeriodicConsoleOutコンポーネントのインスタンスを取得.
- コンポーネントのインスタンスからコンフィグレーションオブジェクトを取得
- コンフィグレーションオブジェクトからdefaultコンフィグレーションセットを受け取る
- defaultコンフィグレーションに新しいプロパティを追加し,元のコンフィグレーションオブジェクトに追加.
- defaultコンフィグレーションをアクティブ化する
- PeriodicConsoleOutコンポーネントのインスタンスをアクティブ化.
- CORBAオブジェクトを破棄.
となります.一応,RTCActivate2.cppファイルの中身すべては以下の通りです.
// RTCActivate2.cpp : コンソール アプリケーションのエントリ ポイントを定義します。 // #include "stdafx.h" using namespace RTC; int _tmain(int argc, _TCHAR* argv[]) { //CORBA ORBオブジェクトを生成 CORBA::ORB_var corbaORB = CORBA::ORB_init(argc, (char**)argv); //ネームサービスオブジェクト生成 CorbaNaming corbaNaming(corbaORB, "localhost:2809"); //ネームサーバーからPeriodicConsoleOutコンポーネントのインスタンスを検索 CorbaConsumer periodicConsoleOut0; CORBA::Object_ptr object = corbaNaming.resolve("agni.host_cxt/PeriodicConsoleOut0.rtc"); periodicConsoleOut0.setObject(object); // コンフィグレーションを変更します. std::string key = "value"; // コンフィグレーション名 std::string value = "10"; // コンフィグレーションの値 RTC::Properties properties; RTC::NVList list; // コンフィグレーションオブジェクトを取得 SDOPackage::Configuration_ptr conf = periodicConsoleOut0->get_configuration(); // defaultコンフィグレーションセットを取得 SDOPackage::ConfigurationSet *confSet = conf->get_configuration_set("default"); // コンフィグレーションセットからコンフィグレーションデータを引き出し, NVUtil::copyToProperties(properties, confSet->configuration_data); // 引き出したプロパティに新しいコンフィグレーションを追加 properties.setProperty(key, value); // コンフィグレーションをListに加えてコンフィグレーションセットに上書き NVUtil::copyFromProperties(list, properties); confSet->configuration_data = list; conf->set_configuration_set_values(*confSet); // コンフィグレーションをアクティブ化 conf->activate_configuration_set("default"); //PeriodicConsoleOutコンポーネントのインスタンスをアクティブ化 ExecutionContextList_var ExecutionContextList = periodicConsoleOut0->get_owned_contexts(); ExecutionContextList[0]->activate_component(RTObject::_duplicate(periodicConsoleOut0._ptr())); //CORBA ORBオブジェクトの破壊 corbaORB->destroy(); return 0; } |
次に,新しいコンフィグレーションセット”new_set”を追加する方法について.
流れが若干かわりますが,大筋は一緒.
// RTCActivate2.cpp : コンソール アプリケーションのエントリ ポイントを定義します。 // #include "stdafx.h" using namespace RTC; int _tmain(int argc, _TCHAR* argv[]) { //CORBA ORBオブジェクトを生成 CORBA::ORB_var corbaORB = CORBA::ORB_init(argc, (char**)argv); //ネームサービスオブジェクト生成 CorbaNaming corbaNaming(corbaORB, "localhost:2809"); //ネームサーバーからPeriodicConsoleOutコンポーネントのインスタンスを検索 CorbaConsumer periodicConsoleOut0; CORBA::Object_ptr object = corbaNaming.resolve("agni.host_cxt/PeriodicConsoleOut0.rtc"); periodicConsoleOut0.setObject(object); // コンフィグレーションを変更します. std::string key = "value"; // コンフィグレーション名 std::string value = "10"; // コンフィグレーションの値 RTC::Properties properties; RTC::NVList list; SDOPackage::ConfigurationSet confSet; // コンフィグレーションオブジェクトを取得 SDOPackage::Configuration_ptr conf = periodicConsoleOut0->get_configuration(); // defaultコンフィグレーションセットを設定 confSet.id = "new_config"; confSet.description = "New Configuration Set."; // プロパティを設定し,Listに加える properties.setProperty(key, value); // コンフィグレーションをListに加えてコンフィグレーションセットに追加 NVUtil::copyFromProperties(list, properties); confSet.configuration_data = list; conf->set_configuration_set_values(confSet); //PeriodicConsoleOutコンポーネントのインスタンスをアクティブ化 ExecutionContextList_var ExecutionContextList = periodicConsoleOut0->get_owned_contexts(); ExecutionContextList[0]->activate_component(RTObject::_duplicate(periodicConsoleOut0._ptr())); //CORBA ORBオブジェクトの破壊 corbaORB->destroy(); return 0; } |
2.3.3 ポイントまとめ
- RTC::CorbaConsumer::get_configuration()でコンフィグレーション全体(SDOPackage::Configuration型へのポインタ)を取得できます.
- コンフィグレーションに対して,
- SDOPackage::Configuration::get_configuration_set(CORBA::string_member id)でID(コンフィグレーションセットの名前)を使ってコンフィグレーションセットを取得できます.
- SDOPackage::Configuration::set_configuration_set_values(SDOPackage::ConfigurationSet
set)でコンフィグレーションセットを追加できます. - activate_configuration_set(string_member id)でidで指定されるコンフィグレーションセットをアクティブ化できます.
- struct SDOPackage::ConfigurationSetでは
- id (CORBA::string_member)はコンフィグレーションセットのID(識別名)です.
- description (CORBA::string_member) はコンフィグレーションの説明というところでしょうか.
- SDOPackage::ConfigurationSet::configuration_dataメンバがコンフィグレーション本体(NVList型)です.
- configuration_dataを変更していく方法ですが
- RTC::PropertiesオブジェクトのsetProperties(CORBA::string_member key, COBA::string_member
value)を使います.- keyはコンフィグレーション名
- valueはコンフィグレーションの値
- NVUtil::copyFromProperties(NVList list, Properties prop)を使って,NVListにプロパティをコピーします.
- configuration_dataに上書きします.
- RTC::PropertiesオブジェクトのsetProperties(CORBA::string_member key, COBA::string_member
2.3.4 各自の変更点
プロパティはkeyとvalueによって管理されていますから,これを各自のコンフィグレーション名に合わせて変更する必要があります.
2.4 コンパイル
コンパイルするとたくさんwarningが出ます.何でなのかは今検討中.でもコンパイルは出来ます.
2.5 実行
ネームサーバーを起動してから,PeriodicConsoleOutコンポーネントを起動してください.RT System Editorを使っているなら,ネームサーバーにPeriodicConsoleOut0.rtcというコンポーネントが登録されいてることがわかるでしょう.
次に,RTCActivate2を実行すると,コンソールの文字列が変更されます.
3. まとめ
これを使えば,プログラムを若干変更することでRTSystem
Editorを使わずにコンフィグレーションを変更したり,RTCをアクティブ化できます.Eclipse,重いですよね.