[openrtm-users 00035] HelloRTWorldについて&デバイスとの通信について

3 個の投稿 / 0 new
最終投稿
root
オフライン
Last seen: 1日 8時間 前
登録日: 2009-06-23 14:31
[openrtm-users 00035] HelloRTWorldについて&デバイスとの通信について

はじめまして。
船戸@未来大学です。

はじめに安藤さん、7月のRTミドルウェア講習会ではお世話になりました。
また他のメーリングメンバーのみなさまの書き込みも、有難く拝見させて頂いております。

まだLinux、ロボット制御、更にはC++も学習中の身ではありますが、質問させてください。

<質問1>
rtc-linkを含む、SimpleIOのサンプルは動作させることができました。しかし、
HelloRTWorldCompを実行しようとすると、

#]./HelloRTWorldComp -f rtc.conf
Unknown exception.
omniORB: ERROR -- the application attempted to invoke an operation on a nil refrence.
zsh: abort ./HelloRTWorldComp -f rtc.conf

とアボートしてしまいます。
この原因について、アドバイスをお願いします。
OSは、VineLinux3.1 です。

<質問2>
コンポーネントを用いて、制御対象(モータ)を制御するために踏まなければならない
プロセスが分かりません。コンポーネントから直接モータを制御するCPU等との通信を
確立させるための方法が分からないと言った方がいいでしょうか。

現在CPUはH8/3069を用いており、PC側はWindowsXPのハイパーターミナルを用いて、
PC-H8間のUSBによるシリアル通信でモータをドライブさせていますが、
ハイパーターミナルがやってくれている事をコンポーネントで行わせるためには
どうしたら良いのかが分かりません。
もちろん、コンポーネントで動作させる場合は、LAN経由での通信を想定しております。

例えば、HPのRTコンポーネントプログラミング2にある、Manupilator.cpp や
Manupilator.cpp 内の Manipulator::XXX()関数の中身はどうなっているのでしょうか?

以上、ご鞭撻の程、宜しくお願い致します。

未定義
root
オフライン
Last seen: 1日 8時間 前
登録日: 2009-06-23 14:31
[openrtm-users 00036] HelloRTWorldについて&デバイスとの通信について

船戸様

あんどう@産総研です

> はじめに安藤さん、7月のRTミドルウェア講習会ではお世話になりました。
> また他のメーリングメンバーのみなさまの書き込みも、有難く拝見させて頂いております。
>
> まだLinux、ロボット制御、更にはC++も学習中の身ではありますが、質問させてください。

講習会ではわざわざ遠くからありがとうございました。

> <質問1>
> rtc-linkを含む、SimpleIOのサンプルは動作させることができました。しかし、
> HelloRTWorldCompを実行しようとすると、
>
> #]./HelloRTWorldComp -f rtc.conf
> Unknown exception.
> omniORB: ERROR -- the application attempted to invoke an operation on a nil refrence.
> zsh: abort ./HelloRTWorldComp -f rtc.conf
>
> とアボートしてしまいます。
> この原因について、アドバイスをお願いします。
> OSは、VineLinux3.1 です。

ネームサーバは動いていますか?
rtc.conf に書いたネームサーバのホスト名(or IP アドレス)とポート番号は
起動させたネームサーバと合致していますか?

> <質問2>
> コンポーネントを用いて、制御対象(モータ)を制御するために踏まなければならない
> プロセスが分かりません。コンポーネントから直接モータを制御するCPU等との通信を
> 確立させるための方法が分からないと言った方がいいでしょうか。

まぁ、この辺はRTミドルウエアと関係ないことなので、
ハードウエアに応じてコンポーネント開発者がよしなにやってください
というのが本当のところですが。

> 現在CPUはH8/3069を用いており、PC側はWindowsXPのハイパーターミナルを用いて、
> PC-H8間のUSBによるシリアル通信でモータをドライブさせていますが、
> ハイパーターミナルがやってくれている事をコンポーネントで行わせるためには
> どうしたら良いのかが分かりません。
> もちろん、コンポーネントで動作させる場合は、LAN経由での通信を想定しております。

そのモータにどのようなコマンドを送って制御しているのかわからないので、
なんともいえませんが、ハイパーターミナルということは、
コマンドは文字列で送るようなシステムになっているのでしょうね。

ならば、そのモータを制御するための一連の関数群(もしくはC++ならクラス)
をつくって、そのプログラムをつかってモータを制御できるようにしてください。

以下のページが役に立つと思います。
http://www.linux.or.jp/JF/JFdocs/Serial-Programming-HOWTO.html

それができたら、そのプログラムをコンポーネントに組み込んでください。

まぁ、C++で書くとしたら、
(そちらのシステムの情報がないので想像で書くしかないのですが)

------------------------------------------------------------
class MotorControl
{
MotorControl(){};
MotorContorl(char* port_name)
{
シリアルポートをオープンする。
};
~MotorContorl(){};

bool open(char* port_name)
{
シリアルポートをオープンする。
}

void setMode(Mode mode)
{
モードをセットするコマンドをシリアルに送信
}

void setPos(int pos)
{
位置指令をセットするコマンドを送信
}

void setVelocity(int vel)
{
速度指令をセットするコマンドを送信
}

int getPos()
{
現在位置を取得するコマンドを送信し現在位置を受信
}

int getVelocity()
{
現在速度を取得するコマンドを送信し現在速度を受信
}
:
そのほか必要な機能を実装
:
};
------------------------------------------------------------

このクラスがちゃんと動くか、単一の(コンポーネントでない)プログラムで
テストをします。

------------------------------------------------------------
inlcude
include "MotorContorl.h"

int main(void)
{
MotorControl mot("/dev/ttyS0");

// 位置制御モードのテスト
mot.setMode(MotorContro::POSCTRL_MODE);
mot.setPos(266);
for (int i = 0; i < 1000; i++)
{
std::cout << "Position: " << getPos() << std::endl;
usleep(10000); // 10ms休む
}

// 速度制御モードのテスト
:

}
------------------------------------------------------------

これでちゃんと動くようになったら、コンポーネントに組み込みます。

InPort -> 位置入力
OutPort -> 位置出力

というコンポーネントを考えると、rtc_active_do なんかは

m_PosRefIn : InPortのインスタンス
m_PosRef : InPort にバインドされた変数
m_mot : MotorControl のインスタンス
m_PosCurOut : OutPortのインスタンス
m_PosCur : OutPort にバインドされた変数

とすると

RtmRes rtc_active_do()
{
m_PosRefIn.read();
m_mot.setPos(m_PosRef.data);

m_PosCur.data = getPos();
m_PosCurOut.write();

return RTM_OK;
}

こんな感じで書けるのではないでしょうか?

root
オフライン
Last seen: 1日 8時間 前
登録日: 2009-06-23 14:31
[openrtm-users 00037] HelloRTWorldについて&デバイスとの通信について

船戸@未来大学です。

ご回答ありがとうございます。
いろいろと試行錯誤を繰り返している内に返信がすっかり遅くなってしまいました。
申し訳ありません。

> > <質問1>
> > rtc-linkを含む、SimpleIOのサンプルは動作させることができました。しかし、
> > HelloRTWorldCompを実行しようとすると、
> >
> > #]./HelloRTWorldComp -f rtc.conf
> > Unknown exception.
> > omniORB: ERROR -- the application attempted to invoke an operation on a nil refrence.
> > zsh: abort ./HelloRTWorldComp -f rtc.conf
> >
> > とアボートしてしまいます。
> > この原因について、アドバイスをお願いします。
> > OSは、VineLinux3.1 です。
>
> ネームサーバは動いていますか?
> rtc.conf に書いたネームサーバのホスト名(or IP アドレス)とポート番号は
> 起動させたネームサーバと合致していますか?

ネームサーバが正しく動作していなかったようです。
指摘していただいた点を改善した所、上記のようなエラーは出なくなりましたが、

#]./HelloRTWorldComp -f rtc.conf
zsh: abort ./HelloRTWorldComp -f rtc.conf

と、単純にアボートしてしまいます。

> > <質問2>
> > コンポーネントを用いて、制御対象(モータ)を制御するために踏まなければならない
> > プロセスが分かりません。コンポーネントから直接モータを制御するCPU等との通信を
> > 確立させるための方法が分からないと言った方がいいでしょうか。
>
> まぁ、この辺はRTミドルウエアと関係ないことなので、
> ハードウエアに応じてコンポーネント開発者がよしなにやってください
> というのが本当のところですが。
>
> > 現在CPUはH8/3069を用いており、PC側はWindowsXPのハイパーターミナルを用いて、
> > PC-H8間のUSBによるシリアル通信でモータをドライブさせていますが、
> > ハイパーターミナルがやってくれている事をコンポーネントで行わせるためには
> > どうしたら良いのかが分かりません。
> > もちろん、コンポーネントで動作させる場合は、LAN経由での通信を想定しております。
>
> そのモータにどのようなコマンドを送って制御しているのかわからないので、
> なんともいえませんが、ハイパーターミナルということは、
> コマンドは文字列で送るようなシステムになっているのでしょうね。
>
> ならば、そのモータを制御するための一連の関数群(もしくはC++ならクラス)
> をつくって、そのプログラムをつかってモータを制御できるようにしてください。
>
> 以下のページが役に立つと思います。
> http://www.linux.or.jp/JF/JFdocs/Serial-Programming-HOWTO.html
>
> それができたら、そのプログラムをコンポーネントに組み込んでください。
>
>
> まぁ、C++で書くとしたら、
> (そちらのシステムの情報がないので想像で書くしかないのですが)
>
>
> ------------------------------------------------------------
> class MotorControl
> {
> MotorControl(){};
> MotorContorl(char* port_name)
> {
> シリアルポートをオープンする。
> };
> ~MotorContorl(){};
>
> bool open(char* port_name)
> {
> シリアルポートをオープンする。
> }
>
> void setMode(Mode mode)
> {
> モードをセットするコマンドをシリアルに送信
> }
>
> void setPos(int pos)
> {
> 位置指令をセットするコマンドを送信
> }
>
> void setVelocity(int vel)
> {
> 速度指令をセットするコマンドを送信
> }
>
> int getPos()
> {
> 現在位置を取得するコマンドを送信し現在位置を受信
> }
>
> int getVelocity()
> {
> 現在速度を取得するコマンドを送信し現在速度を受信
> }
> :
> そのほか必要な機能を実装
> :
> };
> ------------------------------------------------------------
>
> このクラスがちゃんと動くか、単一の(コンポーネントでない)プログラムで
> テストをします。
>
> ------------------------------------------------------------
> inlcude
> include "MotorContorl.h"
>
> int main(void)
> {
> MotorControl mot("/dev/ttyS0");
>
> // 位置制御モードのテスト
> mot.setMode(MotorContro::POSCTRL_MODE);
> mot.setPos(266);
> for (int i = 0; i < 1000; i++)
> {
> std::cout << "Position: " << getPos() << std::endl;
> usleep(10000); // 10ms休む
> }
>
> // 速度制御モードのテスト
> :
>
> }
> ------------------------------------------------------------
>
> これでちゃんと動くようになったら、コンポーネントに組み込みます。
>
> InPort -> 位置入力
> OutPort -> 位置出力
>
> というコンポーネントを考えると、rtc_active_do なんかは
>
> m_PosRefIn : InPortのインスタンス
> m_PosRef : InPort にバインドされた変数
> m_mot : MotorControl のインスタンス
> m_PosCurOut : OutPortのインスタンス
> m_PosCur : OutPort にバインドされた変数
>
> とすると
>
> RtmRes rtc_active_do()
> {
> m_PosRefIn.read();
> m_mot.setPos(m_PosRef.data);
>
> m_PosCur.data = getPos();
> m_PosCurOut.write();
>
> return RTM_OK;
> }
>
> こんな感じで書けるのではないでしょうか?

参考ページに加えてコードサンプルまで・・・
ありがとうございます!

自分の中でC++とコンポーネントの切り分けがきちんとできていなかったようです。
というか、デバイス関連のプログラミングはまるで別世界が広がっているのですね・・・
RTMの本題では無かったにも関わらず、丁寧なご回答、ありがとうございます。

○○デバイス用のクラスライブラリを上記のような方法などを用いて用意し、
rtc-template で作成したコンポーネントの雛形に組み込んでいく、ということなのですね。
webにある、RTコンポーネントプログラミング2のぼやけていた部分が
大分すっきりしてきました。ありがとうございます。

シリアル通信やクラスライブラリなどについては、
たくさんのヒントや入り口を提示して頂いたので、自習させて頂きます。

ありがとうございました。

コメントを投稿するにはログインまたはユーザー登録を行ってください

ダウンロード

最新バージョン : 2.0.1-RELESE

統計

Webサイト統計
ユーザ数:2209
プロジェクト統計
RTコンポーネント307
RTミドルウエア35
ツール22
文書・仕様書2

Choreonoid

モーションエディタ/シミュレータ

OpenHRP3

動力学シミュレータ

OpenRTP

統合開発プラットフォーム

産総研RTC集

産総研が提供するRTC集

TORK

東京オープンソースロボティクス協会

DAQ-Middleware

ネットワーク分散環境でデータ収集用ソフトウェアを容易に構築するためのソフトウェア・フレームワーク