状態機械によるモーション実行

前のページ
目次
次のページ


このページの内容


状態機械(State Machines)

 ロボットに複雑な動きをさせるときに使う、最も一般的な方法は状態機械(state machine)を定義する方法です。
 状態機械は、いくつかの「状態」と「状態間の遷移」で構成されます。
 状態(State)は、あるアクションを実行します。
 遷移(Transition)は、ある状態から別の状態への移動のことで、センサーからのイベントなどに応じて遷移します(下図)。

  

 Tekkotsu は状態機械を実現するために、StateNode(状態ノード)Transition(遷移) という2つのクラスを用意しています。これらクラスは BehaviorBaseのサブクラスです。

 状態機械のプログラムは次の順番で動きます。

  1. 1つの状態は、その状態の DoStart()関数により呼び出されて起動する。
  2. 起動した DoStart()関数の中で StateNode::DoStart() を呼ぶ。
  3. StateNode::DoStart() が、その状態につながる全ての遷移の DoStart()関数を呼ぶ。
  4. それぞれの遷移は、あらかじめ決められたイベントが発生すると起動する。
  5. 遷移は、前の状態の DoStop()関数を呼ぶことにより、前の状態の活動を止め、次の状態の DoStart()関数を呼ぶことにより、次の状態を起動する。
  6. 前の状態が止まると、その状態から出ている遷移も、それらの DoStop()関数により全て止まり、それらが持つリスナーが削除される。
 この順番を表したのが下図です。

  


状態機械によるモーション実行

 状態機械を使用してモーションを実行することができます。
 例えば、「伏せ → 座り → 立ち → 座り」 のような複数のモーションを連続して実行することが可能です(下図)。

  

 上図の状態遷移「伏せ → 座り → 立ち → 座り」を実行するプログラムについて説明します。

状態機械のプログラムを作成する一般的な手順は次の通りです。

 例えば MyStateMotion のような名前を付けて1つの StateNode を作ります。
 この親ノードで、setup()関数を提供し、この関数内で状態機械に必要な全ての状態ノードと遷移を作ります。
 次に、MyStateMotionDoStart()関数を呼び、状態機械のスタート・ノードを起動します。そして、スタート・ノードは出力遷移を起動します。

 重要なのは、setup()DoStart()の違いを理解することです。
 setup() はノードと遷移を作るための関数です。
 DoStart() はノードと遷移の活動をスタートするための関数です。状態機械が動くとき、いろいろなノードと遷移の活動が DoStart()で始まり DoStop()で停止します。しかし、ノードや遷移の活動が止まっても、ノードと遷移は消えません。それらは存在し、再び活動を始めることができます。
 このため、状態機械を捨てたいときには、親ノードの teardown()関数を呼びます。 teardownは全てのノードと遷移を削除してくれるのです。


 例: 状態機械による連続モーション実行

 最初に、このファイル自体が定義されていない場合には定義するために、次の2行を記述します。

#ifndef INCLUDED_MyStateMotion_h_	// このファイル INCLUDED_MyStateMotion_h_ が定義されていなければ
#define INCLUDED_MyStateMotion_h_	// このファイル INCLUDED_MyStateMotion_h_ を定義する

 次に必要な部品ファイルをインクルードします。

#include "Shared/ERS7Info.h"	// AIBOの機種(ERS7)に関する部品ファイル
#include "Shared/WorldState.h"	// 状態を監視するための部品ファイル
#include "StateHeader.h"		// 状態と遷移に必要な部品ファイル

 さて、StateNode の子クラスとして、MyStateMotion を作成します。
   class MyStateMotion : public StateNode

 スタート・ノードへのポインタを作るために、protected変数 start_node を使用します。

 コンストラクタ MyStateMotion() は、クラス開始時に自動的に起動する関数で、クラス開始の準備をします。
 コンストラクタ起動時に、start_node を初期化するために、start_node(NULL) を記述します。
 デコンストラクタ ~MyStateMotion() は、クラス終了時に自動的に起動する関数で、クラス終了の後片付けをします。
 そして、setup() が実行されているか判断して、teardown()を実行する処理をデコンストラクタ内に記述します。

// クラス MyStateMotion
class MyStateMotion : public StateNode {
protected:
	StateNode * start_node; // start_nodeは、クラス全体で使用するのでココに定義する

public:
	// コンストラクタ
	MyStateMotion() : StateNode("MyStateMotion"), start_node(NULL) {}

	// デコンストラクタ
	~MyStateMotion() {
		if(issetup)
			teardown();
	}

 setup()関数は、状態機械を構築します。この関数は、MyStateMotionDoStart()関数が最初に呼ばれるときに自動的に呼ばれます。

 StateNode::setup() は、親クラスStateNodesetup() を呼ぶ処理です。この処理は決まりごとです。

 次に必要なノードを順番に作成して、追加していきます。

 例えば、伏せ姿勢を実行するための lie_node を作成する場合には、次のように記述します。

   // 伏せ姿勢を実行するためのlie_node を作成する
   StateNode * lie_node = new SmallMotionSequenceNode("Lie","lielie.mot");


 【構文】 モーション・ノードを作成する
StateNode * NodeName = new XxxxxMotionSequenceNode("StateName","FileName");
NodeName状態ノード名
StateName状態名
FileNameモーションファイル名(.mot)
 XxxxxMotionSequenceNode の部分は、モーションのポスチャ数に応じて使い分けてください。
 MotionEditorで作成したモーションのポスチャ数は、キーフレームファイル(.kfm)の1行目に記されています。
ポスチャ数に応じて関数を使い分ける
関数ポスチャ数
TinyMotionSequenceNode4
SmallMotionSequenceNode7
MediumMotionSequenceNode14
LargeMotionSequenceNode25
XLargeMotionSequenceNode60
 60ポスチャを超える場合はモーションを分割し、1モーションのポスチャ数が60以下になるようにしてください。

 作成したノードを追加する場合、次のように記述します。

  // lie_node を追加する
  addNode(lie_node);


 【構文】 ノードを追加する  
addNode(NodeName);
NodeName状態ノード名
 状態から状態への遷移のうち、最も単純な遷移は、前の状態が終了したら、すぐに次の状態へ遷移させることです。
 そのような単純な遷移は次のようにして追加します。

  // 単純な遷移(lie_node → sit_node)を追加する
  lie_node->addTransition(new CompletionTrans(sit_node));


 【構文】 単純な遷移を追加する  
PreNodeName->addTransition(new CompletionTrans(DestinationNodeName);
PreNodeName遷移前の状態ノード名
DestinationNodeName遷移後の状態ノード名
 このプログラムでは、もう1つ別の遷移を使用しています。
 それは、前の状態が開始してから「ある時間」が経過したら、次の状態へ遷移させる方法です。
 そのような時間経過による遷移は次のようにして追加します。

  // 時間経過による遷移(headneutral_node → standsit_node)を追加する
  headneutral_node->addTransition(new TimeOutTrans(standsit_node,1000));


 【構文】 時間経過による遷移を追加する  
PreNodeName->addTransition(new TimeOutTrans(DestinationNodeName, delay);
PreNodeName遷移前の状態ノード名
DestinationNodeName遷移後の状態ノード名
delay経過時間(ミリ秒)(1秒=1000ミリ秒)
virtual void setup() {

	// 親クラスStateNodeの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);

	// 立ち→座りモーション_ノード
	StateNode * standsit_node = new MediumMotionSequenceNode("StandSit","standsit.mot");
	addNode(standsit_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(standsit_node,1000));

}

 DoStart() は状態機械を起動したいときに呼ばれます。
 そして、DoStart() は最初に StateNode::DoStart() を呼びます。
 それから、その子ノード start_nodeDoStart() を呼んで状態機械をスタートします。

 DoSop() は同様に StateNode::DoStop() を呼びます。

 teardown() は後処理の関数です。下記の例では、StateNode::teardown() を呼ぶだけですが、サウンドファイルを使用した場合は、それをメモリから捨てる処理を記述してください。

 下の方の privateセクションは、コンパイラのwarning(警告)を避けるために必要なダミーのコードです。クラスがポインターデータの変数を持つときに書きます。ここでのポインターデータ変数は、start_node です。

virtual void DoStart() {
	StateNode::DoStart();
	start_node->DoStart();
}

virtual void DoStop() {
	StateNode::DoStop();
}

virtual void teardown() {
	StateNode::teardown();
}

private:  // コンパイル時の警告を避けるためのダミー関数
	MyStateMotion(const MyStateMotion&);
	MyStateMotion operator=(const MyStateMotion&);
};

#endif

秀丸を開き、上記プログラム(背景が黄色の5つの部分)をコピー&貼り付け、次の通り保存してください。

    保 存 先 : マイドキュメント → usXX → project
    ファイル名 : MyStateMotion.h
    ファイル種類: C言語ヘッダーファイル(*.h)

ファイルを保存したら、次の手順で実行してください。


Event Logging

 プログラムが思い通りに動いているか確認するには、どのようにすれば良いでしょうか?
 状態が正しく遷移していることを確認するには、Event Logger を使用します。
 Event Logger を使用すると、状態遷移や発生イベントをパソコンのTelnet画面で観察できます。
 ここでは、Event Logger の使い方を説明します。

Event Logger の使用

  1. 上記の状態機械のプログラムをコンパイルして、AIBOに入れてください。
    すでに入っていれば再びコンパイルする必要はありません。

  2. AIBOを起動してください。

  3. Cygwin画面を開き、下記のように打ち込んで、AIBOに無線接続してください。

    us0X@xxxxx ~
    
    $ telnet AIBOのIPアドレス 59000      
    
  4. コントローラ画面のメニューから次の順に選んでください。
       Root Control → Status Reports → Event Logger
       次の2つを探してダブルクリックしてください。
         [ ] stateMachineEGID
         [ ] stateTransitionEGID
       それらの左にチェックマーク X が表示されます。

  5. Backボタンを押して Root Control に戻り、0. Mode Switch に進んでください。
       MyStateMotion をダブルクリックして起動してください。
       Telnet画面に一連のイベントが表示されるでしょう。
       最初のイベントは、MyStateMotion が起動したことによるものです。
       次は、lie_node の状態が発生したことが表示されるでしょう。

  6. あとは AIBOの動きに合わせて状態遷移が表示されます。

 Telnet画面に表示されるイベントの例を示します。白字が表示されます。カラーの字は表示されません。

EVENT: (stateMachineEGID,MyStateMotion,A)                        MyStateMotion開始
Loading: /ms/data/motion/lielie.mot                              ファイル lielie.mot 読み込み
Loading: /ms/data/motion/liedown.pos                             ファイル liedown.pos 読み込み
EVENT: (stateMachineEGID,Lie,A)                                  状態 Lie 開始
Removing expired 4 (autoprune)
EVENT: (stateTransitionEGID,{Lie}--CompletionTrans-->{Sit},S)    遷移 Lie-->Sit 開始
EVENT: (stateMachineEGID,Lie,D)                                  状態 Lie 終了
Loading: /ms/data/motion/sitsit.mot                              ファイル sitsit.mot 読み込み
Loading: /ms/data/motion/situp.pos                               ファイル situp.pos 読み込み
EVENT: (stateMachineEGID,Sit,A)                                  状態 Sit 開始
EVENT: (stateMachineEGID,Lie,S)
Removing expired 5 (autoprune)
EVENT: (stateTransitionEGID,{Sit}--CompletionTrans-->{Stand},S)  遷移 Lie-->Sit 開始

複数の状態への遷移(GroupNode)

 ある状態から、複数の状態へ遷移させたいことがあるでしょう。
 例えば、次図のような場合です。

  

 上図では、「伏せ」から「座り」に遷移すると同時に、「遠吠え」の音ファイルを再生します。
 また、「座り」から「立ち」に遷移すると同時に、LEDを点滅させます。

 このように、動作と同時に音ファイルを再生したり、動作と同時にLEDを光らせたりするには、グループノード(GroupNode)を使用します。

 下に示すのは、グループノードを使用したプログラム例です。


 例: グループノードによる複数状態への遷移

 グループノードの方法は、複数のノードを1つのグループにまとめる、ということです。
 具体的には、次の手順になります。

  1. グループノードを作成する。
  2. グループノードに所属させたいノードを作成する。
  3. 個々のノードをグループノードに加える。
 1. グループノードを作成する。

   // グループノード sit_group を作成する例
   GroupNode * sit_group = new GroupNode("SitGroup");


 【構文】 グループノードを作成する
GroupNode * GroupNodeName = new GroupNode("GroupName");
GroupNodeNameグループノード名
GroupNameグループ名
 2. グループノードに所属させたいノードを作成する。
   このノードの作成方法は、上の MyStateMotion.h で示した通りなので説明を省略します。

 3. 個々のノードをグループノードに加える。

   // sit_group に sit_node と howl_node を加える例
   sit_group->addNode(sit_node);
   sit_group->addNode(howl_node);


 【構文】 個々のノードをグループノードに加える
GroupNodeName->addNode("NodeName");
GroupNodeNameグループノード名
NodeName追加したいノード名
 ノードからグループノードへ遷移するには、普通のノードへ遷移する場合と同様です。
 次行は、ノード lie_node からグループノード sit_group へ遷移する例です。
   lie_node->addTransition(new CompletionTrans(sit_group));

 グループノードから次のノードへ遷移するには、グループのすべてのノードが完了してから次のノードへ遷移させます。
 その手順は次の通りです。

  1. 次ノードへの遷移を作る。
  2. グループに所属する個々のノードに、1で作った遷移を追加する。
 1. 次ノードへの遷移を作る。

   // 次ノード headneutral_node への遷移 ctrans を作る例
   CompletionTrans * ctrans = new CompletionTrans(headneutral_node,1);


 【構文】 次ノードへの遷移を作る(グループからの遷移)
CompletionTrans * TransName = new CompletionTrans(DestinationNodeName,n);
TransName遷移名
DestinationNodeName遷移後の状態ノード名
n完了を検知する状態の数(0=すべての状態)
 2. グループに所属する個々のノードに、1で作った遷移を追加する。

   // 個々のノード(stand_nodeface_node)に 遷移 ctrans を追加する例
   stand_node->addTransition(ctrans);
   face_node->addTransition(ctrans);


 【構文】 ノードに作成した遷移を追加する
PreNodeName->addTransition(TransName);
PreNodeName遷移前の状態ノード名
TransName遷移名
#ifndef INCLUDED_MyStateGroup_h_
#define INCLUDED_MyStateGroup_h_

#include "Shared/ERS7Info.h"
#include "Shared/WorldState.h"

#include "StateHeader.h"

// GroupNodeを使用したサンプルプログラム
class MyStateGroup : public StateNode {
protected:
	StateNode * start_node; // start_nodeは、クラス全体で使用するのでココに定義する

public:
	// コンストラクタ
	MyStateGroup() : StateNode("MyStateGroup"), start_node(NULL) {}

	// デコンストラクタ
	~MyStateGroup() {
		if(issetup)
			teardown();
	}

virtual void setup() {

	StateNode::setup();

	// 伏せノード作成
	StateNode * lie_node = new SmallMotionSequenceNode("Lie","lielie.mot");
	addNode(lie_node);

	// sit_group = グループノード(座り+遠吠え)
	GroupNode * sit_group = new GroupNode("SitGroup");
	addNode(sit_group);

		// 座り姿勢ノード
		StateNode * sit_node = new SmallMotionSequenceNode("Sit","sitsit.mot");
		sit_group->addNode(sit_node);

		// サウンドノード(遠吠え)
		SoundNode * howl_node = new SoundNode("Howl","howl.wav");
		sit_group->addNode(howl_node);

	// stand_group = グループノード(立ち+LED顔)
	GroupNode * stand_group = new GroupNode("StandGroup");
	addNode(stand_group);

		// 立ち姿勢ノード
		StateNode * stand_node = new MediumMotionSequenceNode("Stand","sitwalk.mot");
		stand_group->addNode(stand_node);

		// LEDノード(顔)
		LedNode * face_node = new LedNode("Face");
		face_node->getMC()->cycle(RobotInfo::FaceLEDMask,1500,1.0);
		stand_group->addNode(face_node);

	// 頭ニュートラル_ノード
	StateNode * headneutral_node = new SmallMotionSequenceNode("HeadNeutral","headneut.mot");
	addNode(headneutral_node);

	// 立ち→座りモーション_ノード
	StateNode * standsit_node = new MediumMotionSequenceNode("StandSit","standsit.mot");
	addNode(standsit_node);

	// スタートは伏せ姿勢
	start_node = lie_node;

	// 遷移(伏せ→座り→立ち)
	lie_node->addTransition(new CompletionTrans(sit_group));
	sit_node->addTransition(new CompletionTrans(stand_group));

	// 遷移(→頭ニュートラル)
	CompletionTrans *ctrans = new CompletionTrans(headneutral_node,1);

	// 遷移(立ち→頭ニュートラル)
	stand_node->addTransition(ctrans);

	// 遷移(LED顔→頭ニュートラル)
	face_node->addTransition(ctrans);

	// 頭正面の状態で1秒経過したら立ち→座り
	headneutral_node->addTransition(new TimeOutTrans(standsit_node,1000));

}

virtual void DoStart() {
	StateNode::DoStart();
	start_node->DoStart();
}

virtual void DoStop() {
	StateNode::DoStop();
}

virtual void teardown() {
	StateNode::teardown();
}

private:  // コンパイル時の警告を避けるためのダミー関数
	MyStateGroup(const MyStateGroup&);
	MyStateGroup operator=(const MyStateGroup&);
};

#endif

秀丸を開き、上記プログラム(背景が黄色)をコピー&貼り付け、次の通り保存してください。

    保 存 先 : マイドキュメント → usXX → project
    ファイル名 : MyStateGroup.h
    ファイル種類: C言語ヘッダーファイル(*.h)

ファイルを保存したら、次の手順で実行してください。


イベントによる遷移

 イベントとはAIBOが検知する情報のことです。
 イベントに応じて状態を遷移させることができます。
 つまり、イベントに応じてAIBOをコントロールできます。
 主なイベントには次のものがあります。
イベント名Event Generator ID(EGID)説明
 タイマーイベント timerEGID タイマーが設定時間に到達したら発生する
 テキストメッセージイベント textmsgEGID パソコン等からテキストメッセージが届いたら発生する
 ボタンイベント buttonEGID AIBOのボタンが押されたら発生する
 ビジョンオブジェクトイベント visObjEGID AIBOが物体を見たら発生する
 モーションマネージャイベント motmanEGID AIBOが特定の動きをしたとき、または動きを終了したとき発生する
 下に示すのは、イベントによる遷移を含むプログラム例です。

 例: イベントによる遷移

 このプログラムは、上記 MyStateMotion.h と MyStationGroup.h をもとに書き換えたものです。
 次のように書き換えました。

  • 「伏せ」のときに、テキストメッセージイベントで「座り」に遷移
  • 「座り」のときに、ボタンイベントで「立ち」に遷移
  • 「立ち」のときに、ビジョンオブジェクトイベントで「頭正面」に遷移
 この遷移を図で示すと、次のようになります。

  

 イベント遷移プログラムは、イベントの種類によって書き方が異なります。
 それらを次に示します。


 【構文】 TextMessageEventによる遷移を作成する
EventTrans * TransName = new EventTrans(DestinationNodeName,EventBase::textmsgEGID);
TransName遷移名
DestinationNodeName遷移後の状態ノード名

 【構文】 ButtonEventによる遷移を作成する
EventTrans * TransName = new EventTrans (DestinationNodeName,EventBase::buttonEGID, SourceID, TypeID);
TransName遷移名
DestinationNodeName遷移後の状態ノード名
SourceIDボタンの場所
TypeIDボタンの状態
     ボタンの状態は次の通り
        押された  EventBase::activateETID
        離された  EventBase::deactivateETID

 【構文】 VisionObjectEventによる遷移を作成する
EventTrans * TransName = new EventTrans (DestinationNodeName,EventBase::visObjEGID, SourceID);
TransName遷移名
DestinationNodeName遷移後の状態ノード名
SourceID
     色は次の通り
        ピンク  ProjectInterface::visBluePinkSID
        ブルー  ProjectInterface::visBlueBallSID
        アイボが色をうまく認識できないときは調整してください。
#ifndef INCLUDED_MyStateEvent_h_
#define INCLUDED_MyStateEvent_h_

#include "Shared/ERS7Info.h"
#include "Shared/WorldState.h"

#include "StateHeader.h"

// イベントによる状態遷移のサンプルプログラム
class MyStateEvent : public StateNode {
protected:
	StateNode * start_node; // start_nodeは、クラス全体で使用するのでココに定義する

public:
	// コンストラクタ
	MyStateEvent() : StateNode("MyStateEvent"), start_node(NULL) {}

	// デコンストラクタ, check if we need to call our teardown
	~MyStateEvent() {
		if(issetup)
			teardown();
	}

virtual void setup() {

	StateNode::setup();

	// 伏せノード作成
	StateNode * lie_node = new SmallMotionSequenceNode("Lie","lielie.mot");
	addNode(lie_node);

	// sit_group = グループノード(座り+遠吠え)
	GroupNode * sit_group = new GroupNode("SitGroup");
	addNode(sit_group);

		// 座り姿勢ノード
		StateNode * sit_node = new SmallMotionSequenceNode("Sit","sitsit.mot");
		sit_group->addNode(sit_node);

		// サウンドノード(遠吠え)
		SoundNode * howl_node = new SoundNode("Howl","howl.wav");
		sit_group->addNode(howl_node);

	// 立ち姿勢ノード
	StateNode * stand_node = new MediumMotionSequenceNode("Stand","sitwalk.mot");
	addNode(stand_node);

	// 頭ニュートラル_ノード
	StateNode * headneutral_node = new SmallMotionSequenceNode("HeadNeutral","headneut.mot");
	addNode(headneutral_node);

	// 立ち→座り姿勢ノード
	StateNode * standsit_node = new MediumMotionSequenceNode("StandSit","standsit.mot");
	addNode(standsit_node);

	// スタートは伏せ姿勢
	start_node = lie_node;

	// TextMessageEventによる遷移(伏せ→座り)
	EventTrans * textTrans = new EventTrans(sit_group,EventBase::textmsgEGID);
	lie_node->addTransition(textTrans);

	// ButtonEventによる遷移(座り→立ち)
	EventTrans * buttonTrans = new EventTrans(stand_node,EventBase::buttonEGID,
			RobotInfo::HeadButOffset,EventBase::activateETID);
	sit_node->addTransition(buttonTrans);

	// VisionObjectEventによる遷移(立ち→頭ニュートラル)
	EventTrans * visTrans = new EventTrans(headneutral_node,EventBase::visObjEGID,ProjectInterface::visBlueBallSID);
	stand_node->addTransition(visTrans);

	// 頭正面の状態で1秒経過したら立ち→座り
	headneutral_node->addTransition(new TimeOutTrans(standsit_node,1000));

}

virtual void DoStart() {
	StateNode::DoStart();
	start_node->DoStart();
}

virtual void DoStop() {
	StateNode::DoStop();
}

virtual void teardown() {
	StateNode::teardown();
}

private:  // コンパイル時の警告を避けるためのダミー関数
	MyStateEvent(const MyStateEvent&);
	MyStateEvent operator=(const MyStateEvent&);
};

#endif

秀丸を開き、上記プログラム(背景が黄色)をコピー&貼り付け、次の通り保存してください。

    保 存 先 : マイドキュメント → usXX → project
    ファイル名 : MyStateEvent.h
    ファイル種類: C言語ヘッダーファイル(*.h)

ファイルを保存したら、次の手順で実行してください。


構文まとめ


基本姿勢のモーションファイル

 アイボには次に示す4つの基本姿勢があります。
 それぞれの基本姿勢を実行するモーションファイルは次の通りです。
基本姿勢のモーションファイル
姿勢ファイル名関数
伏せ → 伏せlielie.motSmallMotionSequenceNode
座り → 座りsitsit.motSmallMotionSequenceNode
座り → 伏せsitlie.motMediumMotionSequenceNode
座り → 立ちsitstand.motMediumMotionSequenceNode
座り → 歩行準備sitwalk.motMediumMotionSequenceNode
立ち → 座りstandsit.motMediumMotionSequenceNode
 基本姿勢以外のモーションは、MotionEditorで自作してください。
 自作したモーションのサイズには注意してください(下表)
 MotionEditorで作成したモーションのポスチャ数は、キーフレームファイル(.kfm)の1行目に記されています。
ポスチャ数に応じて関数を使い分ける
関数ポスチャ数
TinyMotionSequenceNode〜 2
SmallMotionSequenceNode〜 6
MediumMotionSequenceNode〜 12
LargeMotionSequenceNode〜 24
XLargeMotionSequenceNode〜 60
 60ポスチャを超える場合はモーションを分割し、1モーションのポスチャ数が60以下になるようにしてください。
前のページ
目次
次のページ