忍者ブログ
ロボット、千葉ロッテマリーンズについていいかげんなことを書きます。
[50]  [51]  [52]  [53]  [54]  [55]  [56]  [57]  [58]  [59]  [60
×

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

なんか最近RTCのプログラミングの話ばかりしてるなあ。
マニュアルも最近修正とかしてないですからね。


今回は実行コンテキストのコールバックを設定します。
簡単なプログラムを作ってみました。


重要なところはコンストラクタの、


self.addExecutionContextActionListener(OpenRTM_aist.ExecutionContextActionListenerType.EC_ATTACHED, self.ECListener.onAttached)
    self.addExecutionContextActionListener(OpenRTM_aist.ExecutionContextActionListenerType.EC_DETACHED,self.ECListener.onDetached)
    


の2つです。

実行コンテキストに関連付け、関連付け解除のリスナを設定しています。


・・・あまり言うこともないなあ。

ついでにComponentActionの直前、直後に発生するイベントリスナの設定もやっておきます。
とりあえず一部だけ抜粋します。

まず直後のイベントリスナの設定は以下のように書けます。

self.addPostComponentActionListener(OpenRTM_aist.PostComponentActionListenerType.POST_ON_INITIALIZE, self.POST_CAListener.onInitialize)

次に直前のイベントリスナです。

self.addPreComponentActionListener(OpenRTM_aist.PreComponentActionListenerType.PRE_ON_INITIALIZE, self.PRE_CAListener.onInitialize)


設定できるComponentActionは12種類あります。詳しくはこのページに書いてあるようです。




今日はこれぐらいにしておきます。
ネタがもうほとんどない。あと1週間が限界です。
次はコンフィギュレーションコールバックを少しやります。






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

人気ブログランキングへ
PR
今回も書くことなし。
ひょっとしたら10月中旬ぐらいまで誰も投稿しないのではないかと思い始めました。
そもそも10月31日締め切りが早いですし。



今回はコンポーネントオブザーバについて書いておきます。
コンポーネントオブザーバは外部からRTCの状態を監視する際に使用します。
別に周期的に外部ツールでRTCの状態を取得する方法を取ることもできますが、コンポーネントオブザーバを使用した場合RTC側から状態が変化したときにオブザーバに通知します。


コンポーネントオブザーバに関してはほとんど情報がなく、このサイトで取り上げているぐらいしか見つかりませんでした。


とりあえずPython版のサンプルで実験してみようかと思いますが、

C:\Python26\Lib\site-packages\OpenRTM_aist\ext\sdo\observer

にサンプルがあるはずなのですがComponentObserverConsumer.pyはあるのに何故かComponentObserverProvider.pyは存在しません。皆さんの環境ではどうなっているでしょうか?

とりあえずOpenRTM-aistのサイトからダウンロードできるソースコードには含まれていますのでそれをダウンロードしてください。

そして解凍したフォルダの、

OpenRTM-aist-Python-1.1.0\OpenRTM_aist\ext\sdo\observer
OpenRTM-aist-Python-1.1.0\OpenRTM_aist\ext\sdo\observer\test

のsetup.batを実行してください。



次にCOCTestRTC.pyを実行します。
するとCOCTestRTCというRTCが起動するのでこのRTCの監視を行います。


次にtestフォルダのComponentObserverProvider.pyを起動するわけですがConsoleIn0という名前のRTCを監視するようになっているので、43行目のConsoleIn0をCOCTestRTC0に変更してください。変更後ComponentObserverProvider.pyを実行してください。


その後COCTestRTCをActiveにしてみたりDeactiveにしてみたり、あるいは数値を入力せずにエンターキーを押す等してError状態にしてみたりいろいろやってみてください。



heartbeatはRTCが生存していると周期的に送信されるようです。

次にどのように使用するかを見てみます。
まずはrtc.confを見てみます。


manager.modules.load_path:  .
manager.modules.preload: ComponentObserverConsumer



ComponentObserverConsumer.pyをあらかじめ読み込んでおきます。
するとComponentObserverConsumer.pyのComponentObserverConsumerInitが実行されます。ComponentObserverConsumerのinit関数でself._rtobjにRTCオブジェクトを入力して、self._rtobj.addPostComponentActionListenerで状態変化のリスナを設定していると思いますがよくわかりません。
多分、ComponentObserverConsumerのupdateStatus関数で

self._observer._ptr().update_status(statuskind, msg)

とすることでComponentObserverProviderのComponentObserver_iのupdate_status関数の処理が実行されて状態を取得できるのだとは思います。
とりあえずインターフェースComponentObserverを使って状態を通知しているみたいです。

次にComponentObserverProvider.pyを見てみます。
ComponentObserver_iのupdate_status関数で状態変化時の処理を行っています。

以下でheartbeatの通知の有無、heartbeatの周期、監視する状態の指定は以下のコードで記述しているようです。

properties = [OpenRTM_aist.NVUtil.newNV("heartbeat.enable","YES"),
                OpenRTM_aist.NVUtil.newNV("heartbeat.interval","10"),
                OpenRTM_aist.NVUtil.newNV("observed_status","ALL")]





とりあえず、どのように使用するかをまとめると、
  1. rtc.confの変更する
  2. ComponentObserverProvider.pyのComponentObserver_iのように状態変化時の処理を実装する
  3. 必要な数だけComponentObserver_iを生成して各RTCと接続する
という感じなのかなあ?
詳しい資料が見つからないので詳しい人は教えてください。




RTCのプログラミングに関してもあまり書くことがなくなってきたなあ。
今回のサンプルプログラムを見ていてそういえば実行コンテキストのコールバックに関してまだ書いたことなかったなと思ったので明日はそれを書きます。
その次からは、
  • manager
  • サービスポート
  • omniORB
に関する事で埋めたいとは思いますがネタ切れが近いです。







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

人気ブログランキングへ
もうコメントくれくれなんて乞食みたいなことは言わないので、プロジェクトページ下の評価(星が5つ並んでいるところです)を付けてもらえませんか?
好きな星の数を選ぶだけなので気が向いた人はよろしくおねがいします。


今回も書くことがないので共有メモリによる通信を行うRTCを調べてみました。
以下の2つがあるようです。
  1. 共有メモリを用いたRTコンポーネント間の大容量データ通信
  2. クァッドロータを制御するRTコンポーネント群
他にもあるとは思いますが、ソースコードを読む気力がないのでこれぐらいにしておきます。


まず1について想像半分ですが説明します。
TimedString型のOutPortを持つRTC_AとInPortを持つRTC_Bがあるとします。
RTC_Aで共有メモリの領域の作成、書き込みを行いOutPortから共有メモリの空間名を送信します。そしてRTC_BのInPortで読み込んだ名前で共有メモリを開いてデータの読み込みを行います。多分こんなかんじの動作です。

次に2ですがこのプログラムを書いた人はかなり高度な技術を持っているらしく、ソースコードを読んで動作を理解するのは苦労しました。
まず、自分のRTCで2の共有メモリのポートを利用するためには以下のような記述をします。

宣言
ShmOutPort<long> m_shmOutPort;

初期化
m_shmOutPort("shmOut")

サービスポートの追加
m_shmOutPort.attachTo(*this);

データの書きこみ
m_shmOutPort.write(10);


多分、こんな感じで書けます。
ShmOutPortクラス、ShmInPortクラスはサービスポートm_servicePortを変数として持っています。
ちなみにShmOutPortがコンシュマー、ShmInPortクラスがプロバイダのインターフェースを持つサービスポートになります。

ShmOutPort側のサービスポートのsetShmSegmentID関数で空間名を書き込んで、ShmInPort側でshmSegmentID関数で空間名を取得して共有メモリ空間からデータを読み込むという方法みたいなので、大雑把にいえば1の方法とやりかたは同じです。

ただ1はWindowsAPI、2はBoostのライブラリで共有メモリに関する処理をしているようなので2の方がいろいろなOSで使用できそうですし、1は画像データだけみたいですが2はいろいろなデータを扱える点では汎用性はありそうです。

ただ、2のソフトウェアのプロジェクトページを見たところクァッドロータの制御がメインみたいなのに何故か特徴は共有メモリという風に書いてあります。
ソフトウェア自体のクオリティは高いのだから、せめてクァッドロータで共有メモリによるデータ送信がどのように役立つかを書いておけば良くなるかなあと思わなくもないです。偉そうなことを言ってしまって申し訳ないです。


今年投稿される作品もこんな感じでソースコードを解析するかもしれないので、作った側からしたら不快に思う人もいるかもしれません。
その場合、コメント欄にそう書いてくれたら記事は消しますのでそうしてください。





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

人気ブログランキングへ
なんであんなに早く作品投稿してしまったんだろうか?
ずっと一人なのでそろそろ恥ずかしくなってきたのですが。
もしかしてまだ作品投稿してはいけなかったとか?
いやそれならメールを送ったときに指摘されると思うので違うか。



まだ先の話なのですが、発表当日は賞金の振り込みのために通帳の口座番号を控えておいてください。後でFAXを送る羽目になります。僕も一応準備はして行きます。ビギナー限定賞とかもらえるかもしれないので。






今回も特に書くことがありません。
とりあえずInPortでread関数を使わずにコネクタ取得→Buffer取得からのデータ取得をするプログラムを書いてみたので今回はこれで埋めます。


#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import OpenRTM_aist
import RTC
 
bufftest_spec = ["implementation_id", "BuffTest",
                  "type_name",         "BuffTest",
                  "description",       "Console input component",
                  "version",           "1.0",
                  "vendor",            "sample",
                  "category",          "example",
                  "activity_type",     "DataFlowComponent",
                  "max_instance",      "10",
                  "language",          "Python",
                  "lang_type",         "script",
                  ""]
 
class BuffTest(OpenRTM_aist.DataFlowComponentBase):
    def __init__(self, manager):
        OpenRTM_aist.DataFlowComponentBase.__init__(self, manager)
        self._data = RTC.TimedLong(RTC.Time(0,0),0)
        self._inport = OpenRTM_aist.InPort("in", self._data)
       
 
    def onInitialize(self):
        self.registerInPort("in", self._inport)
        return RTC.RTC_OK
 
    def onExecute(self, ec_id):
        sys.stdin.readline()
        print self._inport.connectors()[0].getBuffer().length()
        print self._inport.connectors()[0].getBuffer().get()
        self._inport.connectors()[0].getBuffer().advanceRptr(1)
        
        #self._inport.connectors()[0].getBuffer().put(RTC.TimedLong(RTC.Time(0,0),34))
        
        #value = [0]
        #self._inport.connectors()[0].getBuffer().read(value)
        #print value[0]
        
        return RTC.RTC_OK
 
def MyModuleInit(manager):
    profile = OpenRTM_aist.Properties(defaults_str=bufftest_spec)
    manager.registerFactory(profile,
                            BuffTest,
                            OpenRTM_aist.Delete)
    comp = manager.createComponent("BuffTest")
 
def main():
    mgr = OpenRTM_aist.Manager.init(sys.argv)
    mgr.setModuleInitProc(MyModuleInit)
    mgr.activateManager()
    mgr.runManager()
 
if __name__ == "__main__":
    main()


このRTCはTimedLong型のInPortを持っています。

onExecuteで、
  1. Buffer長の表示(self._inport.connectors()[0].getBuffer().length())
  2. Bufferからデータを読みだして表示(self._inport.connectors()[0].getBuffer().get())
  3. Bufferの読み出し位置のポインタを1進める(self._inport.connectors()[0].getBuffer().advanceRptr(1))
という動作をするようにプログラムを書いています。
関数の詳しい説明はC:\Python2X\Lib\site-packages\OpenRTM_aist\BufferBase.pyに書いてあるのでそちらを参考にしたほうが良いと思います。


まあでもデータは読みだしたいけど位置は進めたくないなんて状況はあまりなさそうなのでマメ知識ぐらいな感じで覚えておくぐらいで良いかもしれません。







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

人気ブログランキングへ
そういえばID通知のメールが来てから一カ月ぐらい経つのですが未だに他の作品が投稿されてません。
前参加したときこんなんだったけ?


何故か最近プロジェクトページへのアクセスがそれなりに好調です。
実のところOpenRTM-aistの公式サイトRTMコンテストのページには作品一覧のページへのリンクが存在しないので、僕のプロジェクトページを見るにはこのブログかTwitterかあるいは検索してたまたま辿り着くかしかありません。
このブログにはほとんど人は来ませんし、Twitterで#openrtmで検索した場合でもかなり下の方に来るぐらい時間も経ってるので、入口がないのに何故か人が来るという不可思議な現象に困惑しています。なおコメントも評価も付かない模様。人間が来ているとは限らないですからね。



今回は前々から気になっていたのでRTシステムエディタ on the Webがどのような処理をしているか調べてみました。

ただし、僕はWebプログラミングは素人なのであまり参考にしない事をお勧めします。



そのためにはXMLHTTPRequestについて知っておく必要があります。
XMLHTTPRequestとはJavaScript等でHTTP通信するためのAPIらしいです。
このサイトに詳しく書いてあるので参考になります。

通常CGIを利用する場合にボタンを押すなどしてCGIの処理を行いたい場合ページが遷移するわけですが、JavaScriptでXMLHTTPRequestを利用するとページを読み込むことなくCGIの処理を行い結果を取得できます。


簡単なプログラムで実験してみます。
ボタンを押すとJavaScriptの関数を実行するようにHTMLファイルに記述してください。

<html>
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript" src="js/test.js"></script>
</head>
<body>
<input type="button" name="test" value="test" onClick="test();">
</body>
</html>
これでtest.jsファイルのtest()という関数が実行されます。

次にtest.jsの編集をします。

function test(){
  
  var obj=new XMLHttpRequest();
  obj.onreadystatechange = function(){
    if (obj.readyState == 4 && obj.status == 200){
      alert(obj.responseText);
      
    }
  }
  obj.open("POST", "/cgi-bin/test.py", true);
  obj.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
  obj.send(null);
  
  
  
}



見ての通りtest.pyというCGIと通信します。

正直全然見たことない関数だらけなので一応メモ程度に説明を書いておきます。
onreadystatechange

XHR通信の状態が変化するたびに実行される関数を指定

readyState

XHR通信の状態
4は通信完了
200はリクエスト完了

open

アクセス先のURLの設定
引数はHTTPメソッド、アクセス先のURL、非同期実行か

setRequestHeader

HTTP要求ヘッダの指定

send

送信開始
引数は送信データ




最後にtest.pyの編集をやります。
if __name__ == '__main__':
  print "Content-type: text/html;charset=utf-8"
  print ""
  print "test"
とりあえずこのように適当な文字列を送信します。


それからCGIを使うにはWebサーバーを立ち上げる必要があるのでtestserver.pyというファイルを作成して以下を記述してください。

import CGIHTTPServer
 
if __name__ == "__main__":
    CGIHTTPServer.test()



そして適当にフォルダを作成して以下の配置にしてください。

test.html
testserver.py
js
- test.js
cgi-bin
- test.py


実験してみます。
まずはtestserver.pyを実行してサーバーを起動します。

次にWebブラウザから以下のURLを入力して移動してください。


http://localhost:8000/test.html 


そして表示されたボタンを押して"test"と表示されれば成功です。





ページの読み込みがないのは便利ですね。簡単にCGIを利用できます。


後はrtctree等を使ってRTCを操作するプログラムを書けば良いと思います。












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

人気ブログランキングへ
&lt;&lt; 前のページ 次のページ &gt;&gt;
カレンダー
10 2024/11 12
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
フリーエリア
最新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]