ysuga.net

This page is my hobby page! Robots, Inline skates, Rugby, and more!!

RTCを接続するソフトウエアの開発

ここでは2つのデータポートを持つコンポーネントを接続するためのプログラムについて紹介します.

ここでは前節で作ったConsoleInコンポーネントとConsoleOutコンポーネントを接続してみましょう.

バージョン1.0になって,この辺のツール類のプログラムが様変わりしています.細かい変更です…

プロジェクトの追加

あらたにRTCConnectorというWin32コンソールプロジェクトを追加します.

次に,プロジェクトのプロパティの変更が必要です.このあたりはRTCActivateの章で行った操作と同じです.

プログラム

とりあえずこれまでと同様にプリコンパイルヘッダーにRTC系のヘッダーを集めちゃいます.このほうが再コンパイルが早いので.


// stdafx.h : 標準のシステム インクルード ファイルのインクルード ファイル、または
// 参照回数が多く、かつあまり変更されない、プロジェクト専用のインクルード ファイル
// を記述します。
//

#pragma once

#include "targetver.h"

#include
#include 

#include
#include
#include
#include
#include

次にプロジェクトにCPPファイルを編集します.RTCConnector.cppがありますよね.

プログラムの流れは,

  1. CORBAオブジェクトを作成して,ネームサーバーを取得.
  2. ネームサーバーから起動しているコンポーネントの中からConsoleInコンポーネントのインスタンスを取得.同時に入力データポートを取得.コンポーネントをアクティブ化.
  3. ConnectorProfileオブジェクトを利用して,これから生成する接続のプロファイルを設定しています.
  4. connector0による接続.
  5. ネームサーバーから起動しているコンポーネントの中からConsoleOutコンポーネントのインスタンスを取得.同時に出力データポートを取得.コンポーネントのアクティブ化.
  6. CORBAオブジェクトを破棄.

となります.一応,RTCConnector.cppファイルの中身すべては以下の通りです.


// RTCConnector.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"

int main(int argc, char* argv[])
{
	// ORBを取得
	CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
	RTC::CorbaNaming naming(orb, "localhost:2809");

	// それぞれのコンポーネントを取得
	RTC::CorbaConsumer consoleIn0, consoleOut0;
	consoleIn0.setObject(naming.resolve("ConsoleIn0.rtc"));
	consoleOut0.setObject(naming.resolve("ConsoleOut0.rtc"));

	// それぞれのコンポーネントからポートのリストを取得
	RTC::PortServiceList *portIn, *portOut;
	portIn = consoleIn0->get_ports();
	portOut = consoleOut0->get_ports();
	assert(portIn->length() > 0);
	assert(portOut->length() > 0);

	// とりあえず全部切断
	(*portIn)[0]->disconnect_all();
	(*portOut)[0]->disconnect_all();

	// 接続のためのコネクションプロファイルを作成
	RTC::ConnectorProfile prof;
	prof.connector_id = "cn0";
	prof.name = CORBA::string_dup("connector0");
	prof.ports.length(2);
	prof.ports[0] = (*portIn)[0];
	prof.ports[1] = (*portOut)[0];

	// 接続のプロパティを追加
	CORBA_SeqUtil::push_back(prof.properties,
		   NVUtil::newNV("dataport.interface_type",
				 "corba_cdr"));
	CORBA_SeqUtil::push_back(prof.properties,
		   NVUtil::newNV("dataport.dataflow_type",
				 "push"));
	CORBA_SeqUtil::push_back(prof.properties,
		   NVUtil::newNV("dataport.subscription_type",
				 "new"));

	// 接続を確立
	RTC::ReturnCode_t ret;
	ret = (*portIn)[0]->connect(prof);
	assert(ret == RTC::RTC_OK);
	std::cout << "Connector ID: " << prof.connector_id << std::endl;
     NVUtil::dump(prof.properties);
        //Console**コンポーネントのインスタンスをアクティブ化
        RTC::ExecutionContextList_var ExecutionContextListOut = consoleOut0->get_owned_contexts();
	ExecutionContextListOut[0]->activate_component(RTC::RTObject::_duplicate(consoleOut0._ptr()));
	RTC::ExecutionContextList_var ExecutionContextListIn = consoleIn0->get_owned_contexts();
	ExecutionContextListIn[0]->activate_component(RTC::RTObject::_duplicate(consoleIn0._ptr()));

	orb->destroy();
	return 0;
}

rtc.confの設定

実行前にrtc.confファイルの変更が必要です.今回もnamingサービスの設定が必要になります.コンポーネントをネームサーバーから検索するときにコンポーネントの名前を使うので,この設定は絶対必要です.気をつけましょう.

RTCがネームサーバーに登録される際の名前付けの規則を変更します.新しいrtc.confに”naming.formats:
%n.rtc”の行を追加します.これによって,ConsoleOutコンポーネントが作成された場合,名前はConsoleOut0.rtcとなります.同様にConsoleInの場合はConsoleIn0.rtcになります.

この名前を使って,ネームサーバーからインスタンスを検索&取得するのです.

実行

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

次に,ComponentConnectorを実行すると,ConsoleIn0コンソールに”input
number”文字列が出力されます.ここで数字を入力してEnterを押すと,ConsoleOut0のコンソールに入力した数字が出力されますので,二つのコンポーネントが接続されたことが確認できます.

まとめ

いかがでしたか?簡単でしょ?

RTCConnector.zip

ここまででRTミドルウェアのプログラミングの一連の流れが分かったといえます.次は単純なLong型のデータの受け渡しを超えて,画像や文字列などの大きく,洗練されたデータの流れを作る方法をやりましょう♪


Get Adobe Flash playerPlugin by wpburn.com wordpress themes