RTCのコンフィグを変更するソフトウエア


ここではコンポーネントのコンフィグレーションを変更するプログラムについて解説します.

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”コンフィグレーションセットを取得して変更する方法について.

プログラムの流れは,

  1. CORBAオブジェクトを作成して,ネームサーバーを取得.
  2. ネームサーバーから起動しているコンポーネントの中からPeriodicConsoleOutコンポーネントのインスタンスを取得.
  3. コンポーネントのインスタンスからコンフィグレーションオブジェクトを取得
  4. コンフィグレーションオブジェクトからdefaultコンフィグレーションセットを受け取る
  5. defaultコンフィグレーションに新しいプロパティを追加し,元のコンフィグレーションオブジェクトに追加.
  6. defaultコンフィグレーションをアクティブ化する
  7. PeriodicConsoleOutコンポーネントのインスタンスをアクティブ化.
  8. 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-&gt;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-&gt;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に上書きします.

2.3.4 各自の変更点

プロパティはkeyとvalueによって管理されていますから,これを各自のコンフィグレーション名に合わせて変更する必要があります.

2.4 コンパイル

コンパイルするとたくさんwarningが出ます.何でなのかは今検討中.でもコンパイルは出来ます.

2.5 実行

ネームサーバーを起動してから,PeriodicConsoleOutコンポーネントを起動してください.RT System Editorを使っているなら,ネームサーバーにPeriodicConsoleOut0.rtcというコンポーネントが登録されいてることがわかるでしょう.

次に,RTCActivate2を実行すると,コンソールの文字列が変更されます.

3. まとめ

これを使えば,プログラムを若干変更することでRTSystem
Editorを使わずにコンフィグレーションを変更したり,RTCをアクティブ化できます.Eclipse,重いですよね.