|
|
|
このページの内容
これらはコントローラ画面の Walk Remote Control で試せます(下記)。
CMPack は滑らかな歩調なので、歩きながら物を探す場合に有利です。
注意: 安全のため、AIBOを広い床に置き、進行方向に障害物を置かないで下さい。 Walk Remote Control を試す
- AIBOを起動する。
- コントローラ画面でAIBOに接続後、●Stopモードから●Runningモードにする。
- コントローラ画面 Root Control メニューから、TekkotsuMon を選ぶ。
- TekkotsuMon メニューから、Walk Remote Control または UPenn Walk Remote Control を選ぶ。
- 座標画面の中心点が赤色になったら、マウスで赤い点をドラッグして操作する。
- Walk Remote Control と UPenn Walk Remote Control を切り替えるには、使いたい方だけを赤字にしてください。
上記コード内で、getClassDescriptionを定義しています。この関数は、コントローラ画面でBallChaserにマウスを近づけたときに、文字列を表示します。 紫色のコードは、AIBOを立たせるためのコードです。このコードはAIBOを立たせるときの基本になるので参考にしてください。 下記の processEvent() について説明します。 deactivateETIDはボールを見失ったときに起こるイベントです。また、visev.getObjectArea() は視野におけるボールの面積(%)です。ボールを見失ったり、ボール面積が1%未満になると、歩行を停止します(MMAccessor<WalkMC>(walker_id)->setTargetVelocity(0, 0, 0);)。
#ifndef INCLUDED_BallChaser_h_ #define INCLUDED_BallChaser_h_ #include "Behaviors/BehaviorBase.h" #include "Events/EventRouter.h" #include "Events/VisionObjectEvent.h" #include "Motion/HeadPointerMC.h" #include "Motion/MMAccessor.h" #include "Motion/MotionManager.h" #include "Motion/MotionSequenceMC.h" #include "Motion/WalkMC.h" #include "Shared/ProjectInterface.h" #include "Shared/WorldState.h" #define PI acos(-1.) // PI(3.14)の定義 class BallChaser : public BehaviorBase { protected: MotionManager::MC_ID stand_id; // 立たせるモーションのidを宣言 MotionManager::MC_ID headpointer_id; // 頭部モーションのidを宣言 MotionManager::MC_ID walker_id; // 歩行モーションのidを宣言 public: BallChaser() : BehaviorBase("BallChaser"), // 各idを初期化 stand_id(MotionManager::invalid_MC_ID), headpointer_id(MotionManager::invalid_MC_ID), walker_id(MotionManager::invalid_MC_ID) {} virtual void DoStart() { BehaviorBase::DoStart(); // 座位から歩行体勢に移行するためのモーションコマンド SharedObject<MediumMotionSequenceMC> stand_mc("sitwalk.mot"); stand_id = motman->addPrunableMotion(stand_mc); // 頭の向きを制御するモーションコマンド SharedObject<HeadPointerMC> head_mc; headpointer_id = motman->addPersistentMotion(head_mc); // 歩行モーションコマンド SharedObject<WalkMC> walk_mc; walker_id = motman->addPersistentMotion(walk_mc); // ビジョンリスナーを追加 erouter->addListener(this,EventBase::visObjEGID,ProjectInterface::visPinkBallSID); } virtual void DoStop() { motman->removeMotion(headpointer_id); motman->removeMotion(walker_id); BehaviorBase::DoStop(); } static std::string getClassDescription() { return "Follows ball with head and walks whereever the head is pointing"; } virtual std::string getDescription() const { return getClassDescription(); }
上記2つのプログラムを合体させて、次のように保存してください。
virtual void processEvent(const EventBase& event) { const VisionObjectEvent &visev = *reinterpret_cast<const VisionObjectEvent*>(&event); float const minBallArea = 0.01; // 画像の1% // ボールを見失う、または、画像の1%未満なら停止 if ( visev.getTypeID() == EventBase::deactivateETID || visev.getObjectArea() < minBallArea ) { MMAccessor<WalkMC>(walker_id)->setTargetVelocity(0, 0, 0); return; }; float const ball_horiz_angle = visev.getCenterX() * CameraFOV/2; float const ball_vert_angle = visev.getCenterY() * CameraFOV/2; double const head_pan_angle = state->outputs[HeadOffset+PanOffset]; double const head_tilt_angle = state->outputs[HeadOffset+TiltOffset]; double const new_pan = min(80.0*PI/180.0, max((-80.0)*PI/180.0, head_pan_angle - ball_horiz_angle)); double const new_tilt = min(40.0*PI/180.0, max((-20.0)*PI/180.0, head_tilt_angle - ball_vert_angle)); // 頭をボールの方角に向ける MMAccessor<HeadPointerMC>(headpointer_id)->setJoints(new_tilt, new_pan, 0); // 頭を向けている方角に歩く MMAccessor<WalkMC> walker_acc(walker_id); if ( fabs(new_pan) < 0.05 ) walker_acc->setTargetVelocity(160, 0, 0); // 全速力で前進 else walker_acc->setTargetVelocity(100, 0, new_pan); // ボールの方向へ旋回 } }; #endif
保存する場所 : マイドキュメント → usXX → project
ファイル名 : BallChaser.h
ファイルの種類: C言語ヘッダーファイル(*.h)
発展:
補足(読み飛ばして構いません)画像の計算について、もう少し詳しく説明します。
定数 RobotInfo::CameraFOV (ERS7Infoで定義) は、カメラの視野をラジアンで与えます。
関数 getCenterX() と getCenterY()は、座標を -1と+1の間にした値を返します。
カメラ中心座標は[0,0]です。
実際のAIBOのカメラは、横長に写ります。
X座標は-1と+1の間ですが、Y座標は-0.76と+0.76の間です。
ERS-7の場合は、56.9度ですから0.99ラジアンです。
水平視野はカメラ座標で-1と+1の範囲なので、画像中心からの距離getCenterX()を計算するために、CameraFOVを2で割ります。
例えば、getCenterX()が1というのは、中心から右28度の位置に相当します。
垂直視野は45.2度しかありません。
これはY座標で0.76になるように調整されます。 角度の計算は厳密ではありません。
AIBOの頭がまっすぐ立っていれば、カメラのレンズ面が地面と垂直になるのでボールの方向は水平角になります。
しかし、頭が下を向いていれば、カメラの「水平」は実際の水平線とは異なります。
厳密さに欠けますが、ボールを追いかけるには充分です。
なぜなら、AIBOは画像を逐次取り込んでモーションを調整するからです。
厳密に計算するには「順方向運動学」という知識を使わなければなりませんが難しいので省略します。
|
|
|