忍者ブログ
ロボット、千葉ロッテマリーンズについていいかげんなことを書きます。
[28]  [29]  [30]  [31]  [32]  [33]  [34]  [35]  [36]  [37
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

OpenRTM-aist-Python-1.0.1のManagerConfig.pyで


config_file_path = ["./rtc.conf",
                      "/etc/rtc.conf",
                      "/etc/rtc/rtc.conf",
                      "/usr/local/etc/rtc.conf",
                      "/usr/local/etc/rtc/rtc.conf",
                      None]



とWindowsでもこうなってるのが仕様なのかどうかわからない・・・

Linuxならこれで良いかもしれないけど.




それはさておき,今回はcoil(Common Operating System Infrastructure Layer)で遊んでみます.

今回のサンプルはここからダウンロードできます.


今回のサンプルは単に別のタスクをwhile文の中で待たせておいて,1秒ごとに外からのシグナルで再開させるだけのプログラムです.


ソースを見ていきます.

まず,


#include <coil/Mutex.h>
#include <coil/Condition.h>
#include <coil/Task.h>



としてcoilをインクルードします.


あとは,


class task : public virtual coil::Task
{
    public:
        task(){};
        virtual int svc();
};


int task::svc()
{
    static int count = 0;  //タスクを待たせた回数
   
    m_worker.mutex_.lock(); //排他処理

    while(!m_worker.running_)
    {
        count += 1;
        printf("task1の回数\t%d\n",count);  //回数表示
       
        m_worker.cond_.wait();  //待たせる
       
    }

    if(m_worker.running_)
    {
        printf("task1が終了しました\n");
    }
    m_worker.mutex_.unlock();  //排他処理
       
    return 0;

}



のようなTaskにしておきます.


そして,main文では


    task *task1 = new task();  //タスクの生成
    m_worker.running_ = false;  //falseの時にwhile文が回る,trueの時は終了
    task1->activate();  //タスクを実行
   
       
    for(int i=0;i < 5;i++)
    {
        Sleep(1*1000);
        m_worker.mutex_.lock();  //排他処理
        m_worker.cond_.signal();  //
待ち状態から起こす
        m_worker.mutex_.unlock();  //排他処理

    }

    Sleep(2*1000);
   
    //while文終了

    m_worker.running_ = true;
    m_worker.mutex_.lock();
    m_worker.cond_.signal();
    m_worker.mutex_.unlock();
    Sleep(1*1000);



こんな感じで.

説明不足ですが,今日のところはこのぐらいにしときます.


次回は何をやるかは未定です.













にほんブログ村 科学ブログ ロボットへ
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・

人気ブログランキングへ
PR
Wubiで入れたUbuntuでOpenRTM-aistの動作ができた人っていますかね?

いや、最近RTM関連っぽい人が少し来るようなので。





それはさておき、今回はARTExecutionContextを使ってみます。

OpenRTM-aistのARTLinux用実行コンテキストのページから入手できます。

・・・というより、今回はOpenRTM-aistのページを見ながらやってみたに近いので別にこの記事を読まなくても良いと思います。

ちなみにARTLinuxはここから。


あとは、ダウンロードしたフォルダを解凍して、フォルダに移動した後makeすればArtExecutionContext.soが作成されます。

ArtExecutionContext.soをrtc.confのあるフォルダにコピーした後、


manager.modules.load_path: ./
manager.modules.abs_path_allowed: no
manager.modules.preload: ArtExecutionContext.so
exec_cxt.periodic.type: ArtExecutionContext



をrtc.confに追加することでArtExecutionContext.soを読み込んで、ArtExecutionContextを実行コンテキストに設定。



今回は簡単な時間計測を行います。

今回作成した時間計測のサンプルRTCはここからダウンロードできます。

ArtExecutionContext.soをコピーしてからRTCを立ち上げてください。

ArtExecutionContextを使った場合と使わなかった場合を比較しました。


まずはArtExecutionContextを使わなかった場合です。

実行周期は0.1sとなってます。


0.103991
0.103993
0.104
0.103999
0.103993
0.103993
0.104002
0.103996
0.103997
0.103998
0.103996
0.104001
0.103998
0.103993
0.103998
0.104018
0.10398
0.103996
0.103999
0.103995
0.103998
0.103999
0.103995
0.103999
0.103996
0.103998
0.103996
0.104
0.103996
0.103997
0.103999
0.103999
0.103996





・・・・なんできれいに4msだけずれるんだ?

追記
(どうやらPeriodicExecutionContextについて誤解があったみたいで、OpenRTM-aist-1.0.0では
RTCのコアロジックの処理→設定した実行周期だけ待つ
だったみたいです。1.1.0からは、
設定した実行周期 - RTCのコアロジックの処理時間
だけsleepで待つように変更されたみたいです。最初からこういう仕様なのかと思ってましたよ。なんでそんな誰得な仕様だったのでしょうね?)

ちなみに、実行周期を1msとかにしたら、


0.00404382
0.00397801
0.00396514
0.00400805
0.00398803
0.00401998
0.00401092
0.00396895
0.00414109
0.00393701
0.00401497
0.00391006
0.00407791
0.00405908



こんな事態になってしまいました。


とりあえず、リアルタイムではないのは理解できるのですが、きれいに4msだけずれるのは何か原因があるような気がする。

なにかわからんけど。



続いて、ArtExecutionContextを使った場合です。



0.0999839
0.0999939
0.0999951
0.100003
0.0999949
0.1
0.0999949
0.100004
0.0999911
0.099997
0.099998
0.0999968
0.0999961
0.099999
0.099997
0.0999999
0.0999951
0.099998
0.099997
0.099998
0.099997
0.099998
0.099998
0.0999968
0.099997
0.099998



こちらはリアルタイムになっているようですね。

ちなみに、実行周期1msでは、


0.000984192
0.00100088
0.000998974
0.00100803
0.00099206
0.000998974
0.00100088
0.00100708
0.000993013
0.000999928
0.00100017
0.00100994
0.000989914
0.00100017
0.000999928
0.00100803



こんな感じでリアルタイム化されてます。




今日はこのぐらいにしといてあげます。

次回なにをやるかは未定です.





にほんブログ村 科学ブログ ロボットへ
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・

人気ブログランキングへ
・・・そろそろ書くネタがなくなりそう.

多分,あと3回ぐらいでこの企画も終わりです.

さすがに毎日更新はきつい.毎日更新してないけど.

とりあえず,記事の数が20を越えたのでこれで勘弁して欲しい.



それはさておき,今回はデータポート追加RTC実行コンテキストデータポートコールバックをPythonで作成します.

OpenRTM-aist-Python-1.0.1がひっそりと公開されてるので,まだインストールしてない人はそちらを入れた方が良いかも.


まずはデータポート追加RTCから.

サンプルはここからダウンロード出来ます.


とは言ってもC++とほぼ同じで,

データポートの追加は,


self._inIn = OpenRTM_aist.InPort("in", self._d_in)
self.registerInPort("in",self._inIn)

self._outOut = OpenRTM_aist.OutPort("out", self._d_out)
self.registerOutPort("out",self._outOut)



のような感じです.

削除は,


self.removePort(self._inIn)
self.removePort(self._outOut)




とするだけ.
若干Pythonの方が簡単です.



続いて,実行コンテキストを作成します.

サンプルはここからダウンロード出来ます.


rtc.confでDLLの替わりに,


manager.modules.preload: TestExecutionContext.py


とPythonソースファイルを読み込みます.


肝心のソースですが,特にC++と違う所はないため省略します.



続いて,データポートコールバックをPythonで実装します.

サンプルはここからダウンロード出来ます.


コネクタ・バッファのコールバックはOpenRTM-aist-Python-1.0.1のサンプルそのままなので手抜き省略します.


インポートのコールバックは,


class MyOnRead(OpenRTM_aist.OnRead):
   def __init__(self):
           pass
   def __call__(self):
     print u"read() 関数が呼ばれました。"

class MyOnReadConvert(OpenRTM_aist.OnReadConvert):
   def __init__(self):
           pass
   def __call__(self, value):
     tmp = RTC.TimedLong(RTC.Time(0,0),0)
     tmp.data = 2*value.data
     return tmp

・・・

self._inIn.setOnRead(MyOnRead())
self._inIn.setOnReadConvert(MyOnReadConvert())



という感じ.

__call__というメソッドが呼び出されるみたいですね.


アウトポートのコールバックは


class MyOnWrite(OpenRTM_aist.OnWrite):
   def __init__(self):
           pass
   def __call__(self, value):
     print u"write() 関数が呼ばれました。"

class MyOnWriteConvert(OpenRTM_aist.OnWriteConvert):
   def __init__(self):
           pass
   def __call__(self, value):
     tmp = RTC.TimedLong(RTC.Time(0,0),0)
     tmp.data = value.data * value.data
     return tmp

・・・

self._outOut.setOnWrite(MyOnWrite())
self._outOut.setOnWriteConvert(MyOnWriteConvert())



となります.



今日はこの辺にしといてやります.

次回はARTExecutionContextを使ってみます.






にほんブログ村 科学ブログ ロボットへ
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・

人気ブログランキングへ

最近人は来るのに何故か全くコメントがつかない・・・

もしかして,ブログ記事から僕の暗黒臭が滲み出てるとかでしょうか・・・・

最近割と本気で運が悪いんで.




それはさておき,今回はデータポートのコールバックをやります.

とは言っても,OpenRTM-aistの公式サイトに説明,OpenRTM-aist-1.0.0-RELEASEにサンプルがあるので別にやる意味なかったり.

今回作成したサンプルはここからダウンロード出来ます.


まず,インポートのコールバックはOpenRTM-aistの公式サイトの実装例をヘッダーファイルにコピペして,


std::ofstream ofs("MyOnRead.txt");

m_inIn.setOnRead(new MyOnRead<TimedLong>(ofs));
m_inIn.setOnReadConvert(new MyOnReadConvert<TimedLong>);



といった感じ.

MyOnReadの引数にstd::ofstreamを設定することでファイルに出力をしています.

これで,読み込んだデータが入力されたデータの2乗となるはずです.

公式サイトの説明以上の説明ができないので意味とかは省略します.


アウトポートのコールバックもOpenRTM-aistの公式サイトの実装例をヘッダーファイルにコピペして,

std::ofstream ofs("MyOnWrite.txt");

m_outOut.setOnWrite(new MyOnWrite<TimedLong>(ofs));
m_outOut.setOnWriteConvert(new MyOnWriteConvert<TimedLong>);



だけ.

出力するデータがm_out.dataで設定したデータの2倍となるはずです.


・・・ただ,1つだけ疑問があって


virtual void operator()()

virtual void operator()(const T& value)


ではないかなと.
上でアウトポートのコールバックのプログラム作ってコンパイルが通った人っていますかね?





続いて,コネクタ・バッファのコールバックです.

OpenRTM-aist-1.0.0-RELEASEのサンプルの通りと言ってしまえばそれまでなんですが,

まず,ヘッダーファイルに


class DataListener
  : public ConnectorDataListenerT<RTC::TimedLong>
{
public:
  DataListener(const char* name) : m_name(name) {}
  virtual ~DataListener(){}

  virtual void operator()(const ConnectorInfo& info,
                          const TimedLong& data)
  {
    std::cout << "Data:          " << data.data    << std::endl;
  };
  std::string m_name;
};



と記述して,onInitializeで,


m_inIn.addConnectorDataListener(ON_BUFFER_WRITE, new DataListener("ON_BUFFER_WRITE"));



とするだけでバッファ書き込み時にデータが表示されます.

addConnectorDataListenerの1つめの引数はどの時に呼び出すかであり,他にON_BUFFER_OVERWRITE,ON_SEND等があります.





ちょっと今回は手抜きですが,今回はこれで勘弁してください.

次回は・・・・特に思いつかないなぁ.

今回手抜きなのも正直ネタ切れな気配がするからですからね.


次回はいままでこのカテゴリでやったプログラムをPythonで実装してみようかと思います.










にほんブログ村 科学ブログ ロボットへ
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・

人気ブログランキングへ

1日1回更新宣言はどこへやらといった感じです.

へたれなので許してください.



それはさておき,今回はomniORBで他のPCとの通信をやります.

とは言っても,前回のサンプルのサーバーかクライアントを


TestCORBAserver -ORBInitRef NameService=corbaloc:iiop:1.0@(IPアドレス):2809/NameService



とコマンドから入力して起ち上げるだけです.



普通なソケット通信と比較してみます.


単純なデータの送受信なら普通のソケット通信の方が良さそうです.

omniORBはちょっと日本語の資料が少なすぎるのが難点かも.

同じCORBAでもJAVAなら資料が見つかりますけど.

ただ,IDLで簡単にインターフェースを定義できるのでちょっと複雑になったらCORBAの方が良いと思います.


完全に主観ですけど,使ってみた感じこんな感想.

まあ,RTMだったらさらに簡単にできるわけだから,別にomniORB単体でつかう必要を感じなかったりしてるところです.








にほんブログ村 科学ブログ ロボットへ
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・

人気ブログランキングへ

カレンダー
12 2025/01 02
S M T W T F S
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
フリーエリア
最新CM
[08/31 ysuga]
[08/31 Nobu]
[08/31 ysuga]
[12/11 Nobu]
[12/11 Kanamura]
最新TB
プロフィール
HN:
Nobu
年齢:
36
性別:
男性
誕生日:
1988/09/22
職業:
あれ
趣味:
妄想、自堕落
バーコード
ブログ内検索
P R
カウンター
忍者ブログ [PR]