|
|
|
このページの内容
例: 状態機械による歩行プログラム MyStateWalk.h 状態機械を使用してアイボに歩行させる方法は簡単です。
歩行ノードは次のように作成します。// 歩行ノードを作成する例
WalkNode * move_node = new WalkNode("Move",150,0,0);あとは、普通のノードと同じように、歩行ノードを追加して、遷移させればOKです。
【構文】 歩行ノードを作成する
WalkNode * WalkNodeName = new WalkNode( "StateName", dx, dy, da);
WalkNodeName 歩行ノード名 StateName 状態名 dx 前向き速度(ミリ/秒)マイナスでバック。範囲(−100〜+150) dy 左向き速度(ミリ/秒)マイナスで右向き。範囲(-50〜+50) da 回転速度(ラジアン/秒)マイナスで時計回り。範囲(-1〜+1) 秀丸を開き、上記プログラム(背景が黄色)をコピー&貼り付け、次の通り保存してください。
#ifndef INCLUDED_MyStateWalk_h_ #define INCLUDED_MyStateWalk_h_ #include "Shared/ERS7Info.h" #include "Shared/WorldState.h" #include "StateHeader.h" // Walkノードを使用したサンプルプログラム class MyStateWalk : public StateNode { protected: StateNode * start_node; // start_nodeは、クラス全体で使用するのでココに定義する public: // コンストラクタ MyStateWalk() : StateNode("MyStateWalk"), start_node(NULL) {} // デコンストラクタ ~MyStateWalk() { if(issetup) teardown(); } virtual void setup() { StateNode::setup(); // 伏せノード作成 StateNode * lie_node = new SmallMotionSequenceNode("Lie","lielie.mot"); addNode(lie_node); // 座り姿勢ノード StateNode * sit_node = new SmallMotionSequenceNode("Sit","sitsit.mot"); addNode(sit_node); // 立ち姿勢ノード StateNode * stand_node = new MediumMotionSequenceNode("Stand","sitwalk.mot"); addNode(stand_node); // 頭ニュートラル_ノード StateNode * headneutral_node = new SmallMotionSequenceNode("HeadNeutral","headneut.mot"); addNode(headneutral_node); // 前進歩行ノード WalkNode * move_node = new WalkNode("Move",150,0,0); addNode(move_node); // スタートは伏せ姿勢 start_node = lie_node; // 遷移(伏せ→座り→立ち→頭正面) lie_node->addTransition(new CompletionTrans(sit_node)); sit_node->addTransition(new CompletionTrans(stand_node)); stand_node->addTransition(new CompletionTrans(headneutral_node)); // 頭正面の状態で1秒経過したら前進歩行を開始 headneutral_node->addTransition(new TimeOutTrans(move_node,1000)); } virtual void DoStart() { StateNode::DoStart(); start_node->DoStart(); } virtual void DoStop() { erouter->removeListener(this); StateNode::DoStop(); } virtual void teardown() { StateNode::teardown(); } private: // コンパイル時の警告を避けるためのダミー関数 MyStateWalk(const MyStateWalk&); MyStateWalk operator=(const MyStateWalk&); }; #endif保 存 先 : マイドキュメント → usXX → project
ファイル名 : MyStateWalk.h
ファイル種類: C言語ヘッダーファイル(*.h)ファイルを保存したら、次の手順で実行してください。
実行するとアイボは前進し続けます。
アイボの前に障害物を置かないでください。
例: 追跡プログラム MyStateTarget.h 状態機械を使用してアイボに物体を追跡させる方法は簡単です。
追跡ノードは次のように作成します。// 追跡ノードの作成例
WalkToTargetNode * chase_node = new WalkToTargetNode("Chase", ProjectInterface::visPinkBallSID);あとは、普通のノードと同じように、追跡ノードを追加して、遷移させればOKです。
【構文】 追跡ノードを作成する
WalkToTargetNode * ChaseNodeName = new WalkToTargetNode( "StateName", SourceID);
ChaseNodeName 追跡ノード名 StateName 状態名 SourceID ターゲットのソースID 秀丸を開き、上記プログラム(背景が黄色)をコピー&貼り付け、次の通り保存してください。
#ifndef INCLUDED_MyStateTarget_h_ #define INCLUDED_MyStateTarget_h_ #include "Shared/ERS7Info.h" #include "Shared/WorldState.h" #include "StateHeader.h" class MyStateTarget : public StateNode { protected: StateNode * start_node; // start_nodeは、クラス全体で使用するのでココに定義する public: // コンストラクタ MyStateTarget() : StateNode("MyStateTarget"), start_node(NULL) {} // デコンストラクタ ~MyStateTarget() { if(issetup) teardown(); } virtual void setup() { StateNode::setup(); // 伏せノード作成 StateNode * lie_node = new SmallMotionSequenceNode("Lie","lielie.mot"); addNode(lie_node); // 座り姿勢ノード StateNode * sit_node = new SmallMotionSequenceNode("Sit","sitsit.mot"); addNode(sit_node); // 立ち姿勢ノード StateNode * stand_node = new MediumMotionSequenceNode("Stand","sitwalk.mot"); addNode(stand_node); // 頭ニュートラル_ノード StateNode * headneutral_node = new SmallMotionSequenceNode("HeadNeutral","headneut.mot"); addNode(headneutral_node); // ボール追跡 WalkToTargetNode * chase_node = new WalkToTargetNode("Chase", ProjectInterface::visPinkBallSID); addNode(chase_node); // 停止 WalkNode * stop_node = new WalkNode("Stop", 0,0,0); addNode(stop_node); // スタートは伏せ姿勢 start_node = lie_node; // 遷移(伏せ→座り→立ち→頭正面) lie_node->addTransition(new CompletionTrans(sit_node)); sit_node->addTransition(new CompletionTrans(stand_node)); stand_node->addTransition(new CompletionTrans(headneutral_node)); // 何度も使う遷移はこのようにNULLで初期化して定義する Transition * tmptrans=NULL; // 頭正面の状態でピンクボールを見たら追跡開始 headneutral_node->addTransition(tmptrans=new VisualTargetTrans(chase_node,ProjectInterface::visPinkBallSID)); tmptrans->setSound("cutey.wav"); // 見失ったら停止 chase_node->addTransition(tmptrans=chase_node->newDefaultLostTrans(stop_node)); tmptrans->setSound("whimper.wav"); // 再びピンクボールを見たら追跡開始 stop_node->addTransition(tmptrans=new VisualTargetTrans(chase_node,ProjectInterface::visPinkBallSID)); tmptrans->setSound("cutey.wav"); // 音声ファイルを読み込む sndman->LoadFile("cutey.wav"); sndman->LoadFile("whimper.wav"); } virtual void DoStart() { StateNode::DoStart(); start_node->DoStart(); } // 音声ファイルをLoadFileで読み込んだときは teardown()で解放する virtual void teardown() { // 音声ファイルを解放する sndman->ReleaseFile("cutey.wav"); sndman->ReleaseFile("whimper.wav"); StateNode::teardown(); } private: // コンパイル時の警告を避けるためのダミー関数 MyStateTarget(const MyStateTarget&); MyStateTarget operator=(const MyStateTarget&); }; #endif保 存 先 : マイドキュメント → usXX → project
ファイル名 : MyStateTarget.h
ファイル種類: C言語ヘッダーファイル(*.h)ファイルを保存したら、次の手順で実行してください。
例: 状態機械による徘徊プログラム MyStateExplore.h
秀丸を開き、上記プログラム(背景が黄色)をコピー&貼り付け、次の通り保存してください。
#ifndef INCLUDED_MyStateExplore_h_ #define INCLUDED_MyStateExplore_h_ #include "Shared/ERS7Info.h" #include "Shared/WorldState.h" #include "StateHeader.h" // Walkノードを使用したサンプルプログラム class MyStateExplore : public StateNode { protected: StateNode * start_node; // start_nodeは、クラス全体で使用するのでココに定義する WalkNode * turn_node; // turn_nodeは、クラス全体で使用するのでココに定義する public: // コンストラクタ MyStateExplore() : StateNode("MyStateExplore"), start_node(NULL), turn_node(NULL) {} // デコンストラクタ ~MyStateExplore() { if(issetup) teardown(); } virtual void setup() { StateNode::setup(); // 赤外線センサ設定 unsigned int IRDistOffset; IRDistOffset=ERS7Info::NearIRDistOffset; // 伏せノード作成 StateNode * lie_node = new SmallMotionSequenceNode("Lie","lielie.mot"); addNode(lie_node); // 座り姿勢ノード StateNode * sit_node = new SmallMotionSequenceNode("Sit","sitsit.mot"); addNode(sit_node); // 立ち姿勢ノード StateNode * stand_node = new MediumMotionSequenceNode("Stand","sitwalk.mot"); addNode(stand_node); // 頭ニュートラル_ノード StateNode * headneutral_node = new SmallMotionSequenceNode("HeadNeutral","headneut.mot"); addNode(headneutral_node); // 前進歩行ノード WalkNode * move_node = new WalkNode("Move",150,0,0); addNode(move_node); // 旋回ノード追加 addNode(turn_node = new WalkNode("Turn",0,0,0.5f)); // スタートは伏せ姿勢 start_node = lie_node; // 遷移(伏せ→座り→立ち→頭正面) lie_node->addTransition(new CompletionTrans(sit_node)); sit_node->addTransition(new CompletionTrans(stand_node)); stand_node->addTransition(new CompletionTrans(headneutral_node)); // 頭正面の状態で1秒経過したら前進歩行を開始 headneutral_node->addTransition(new TimeOutTrans(move_node,1000)); /* 障害物までの距離が350ミリ以下になったら遷移(前進→旋回) */ move_node->addTransition(new SmoothCompareTrans<float>( turn_node, &state->sensors[IRDistOffset], CompareTrans<float>::LT, 350, EventBase(EventBase::sensorEGID,SensorSourceID::UpdatedSID,EventBase::statusETID), .7)); /* 旋回の状態で2秒経過したら遷移(旋回→前進) */ turn_node->addTransition(new TimeOutTrans(move_node,2000)); } virtual void DoStart() { StateNode::DoStart(); start_node->DoStart(); erouter->addListener(this,EventBase::stateMachineEGID,(size_t)turn_node,EventBase::activateETID); } virtual void DoStop() { erouter->removeListener(this); StateNode::DoStop(); } virtual void teardown() { StateNode::teardown(); } // turnノードが呼ばれるたびに、旋回速度をランダムに変更する virtual void processEvent(const EventBase& /*e*/) { float vel=rand()/(float)RAND_MAX*2.0f-1; if(vel<0) vel-=.25; if(vel>0) vel+=.25; turn_node->setAVelocity(vel); } private: // コンパイル時の警告を避けるためのダミー関数 MyStateExplore(const MyStateExplore&); MyStateExplore operator=(const MyStateExplore&); }; #endif保 存 先 : マイドキュメント → usXX → project
ファイル名 : MyStateExplore.h
ファイル種類: C言語ヘッダーファイル(*.h)ファイルを保存したら、次の手順で実行してください。
【構文】 状態をスムースに遷移させる SmoothCompareTrans
SmoothCompareTrans (
DestinationNode,
Monitor,
SmoothCompareTrans( <type>::enumerator),
value,
event,
speed
);比較条件:
DestinationNode 次ノード名 Monitor モニタ対象のセンサ type データ型 enumerator 比較条件 value センサ値 event イベント speed 遷移速度
LT less than (<) GT greater than (>) LTE less than or equal (≦) GTE greater than or equal (≧) EQ equal (=) NE not equal (≠)
|
|
|