Petoi Bittle 入門 (6) - スキル
「Petoi Bittle」の「スキル」についてまとめました。
前回
1. スキル
「スキル」には、「Instinct」と「Newbility」があります。
・Instinct (本能) : 調整済みの固定スキル
・Newbility (新スキル) : 調整前でまだ多くのテストを必要とするスキル
これらのアドレスは、ルックアップテーブルを「EEPROM」に保存し、実際のデータは「I2C EEPROM」と「Flash」に保存します。
・EEPROM (1KB) : ルックアップテーブルを保存
・I2C EEPROM (8KB) : 「WriteInstinct.ino」の実行時に「Instinct」を保存
・Flash (32KB) : スケッチアップロード時に「Newbility」を保存
EEPROMとFlashの違いは、以下が参考になります。
・FAQ 1008915 : EEPROMとFlashメモリの違い
2. スキルの定義
スキルの定義は、「InstinctBittle.h」で行います。
以下は、「InstinctBittle.h」のショートバージョンになります。
#define BITTLE
#define NUM_SKILLS 4
#define I2C_EEPROM
const char rest[] PROGMEM = {
1, 0, 0, 1,
-30, -80, -45, 0, -3, -3, 3, 3, 75, 75, 75, 75, -55, -55, -55, -55,};
const char zero[] PROGMEM = {
1, 0, 0, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,};
const char crF[] PROGMEM = {
36, 0, -3, 1,
61, 68, 54, 61, -26, -39, -13, -26,
66, 61, 58, 55, -26, -39, -13, -26,
...
51, 81, 45, 72, -25, -37, -12, -25,
55, 76, 49, 68, -26, -38, -13, -26,
60, 70, 53, 62, -26, -39, -13, -26,
};
const char pu[] PROGMEM = {
-8, 0, -15, 1,
6, 7, 3,
0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30, 30, 30, 30, 5, 0,
15, 0, 0, 0, 0, 0, 0, 0, 30, 35, 40, 29, 50, 15, 15, 15, 5, 0,
30, 0, 0, 0, 0, 0, 0, 0, 27, 35, 40, 60, 50, 15, 20, 45, 5, 0,
15, 0, 0, 0, 0, 0, 0, 0, 45, 35, 40, 60, 25, 20, 20, 60, 5, 0,
0, 0, 0, 0, 0, 0, 0, 0, 50, 35, 75, 60, 20, 30, 20, 60, 6, 0,
-15, 0, 0, 0, 0, 0, 0, 0, 60, 60, 70, 70, 15, 15, 60, 60, 6, 0,
0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 95, 95, 60, 60, 60, 60, 6, 1,
30, 0, 0, 0, 0, 0, 0, 0, 75, 70, 80, 80, -50, -50, 60, 60, 8, 0,
};
#if !defined(MAIN_SKETCH) || !defined(I2C_EEPROM)
const char* skillNameWithType[] = {"crI", "puI", "restI", "zeroN",};
const char* progmemPointer[] = {cr, pu, rest, zero, };
#else
const char* progmemPointer[] = {zero};
#endif
2-1. define定義
「InstinctBittle.h」には、次の3つのdefine定義があります。
#define BITTLE
Bittle用のInstinctであることを示す。
#define NUM_SKILLS 4
スキル数を示す。skillNameWithType[]の要素数と同じにする。
#define I2C_EEPROM
Instinctの保存先が「I2C EEPROM」であることを示す。
2-2. スキルのデータ構造
スキルのデータ構造には、「Posture」と「Gait」と「Behavior」があります。
・Posture (姿勢) : 関節パラメータの単一フレーム
・Gait (歩行) : 関節パラメータの周期的な複数フレーム
・Behavior (動作) : XXXXX
【Postureの例】
「reset」は「ふせ」の姿勢をとる「Posture」の例です。
const char rest[] PROGMEM = {
1, 0, 0, 1,
-30, -80, -45, 0, -3, -3, 3, 3, 75, 75, 75, 75, -55, -55, -55, -55,};
配列の意味は、次のとおりです。
16関節角度を1フレームを保持します。
「Expected Body Orientation」は、スキル実行時の体の角度です。角度が傾いている場合は、バランシングアルゴリズムはいくつかの調整を行います。
「Angle Ratio」は、-128〜127の範囲よりも大きい角度を表現する場合に使います。比率を2に変更して、2で除算することで、大きな角度を表現できるようにします。
【Gaitの例】
「crF」(crawlforward)は「ほふく前進」の歩行を行う「Gait」の例です。
const char crF[] PROGMEM = {
36, 0, -3, 1,
61, 68, 54, 61, -26, -39, -13, -26,
66, 61, 58, 55, -26, -39, -13, -26,
...
51, 81, 45, 72, -25, -37, -12, -25,
55, 76, 49, 68, -26, -38, -13, -26,
60, 70, 53, 62, -26, -39, -13, -26,
};
配列の意味は、次のとおりです。
8関節角度の36フレームを保持し、ループします。
【Behaviorの例】
「pu」(push up)は「腕立て伏せ」の動作を行う「Behavior」の例です。
const char pu[] PROGMEM = {
-8, 0, -15, 1,
6, 7, 3,
0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30, 30, 30, 30, 5, 0,
15, 0, 0, 0, 0, 0, 0, 0, 30, 35, 40, 29, 50, 15, 15, 15, 5, 0,
30, 0, 0, 0, 0, 0, 0, 0, 27, 35, 40, 60, 50, 15, 20, 45, 5, 0,
15, 0, 0, 0, 0, 0, 0, 0, 45, 35, 40, 60, 25, 20, 20, 60, 5, 0,
0, 0, 0, 0, 0, 0, 0, 0, 50, 35, 75, 60, 20, 30, 20, 60, 6, 0,
-15, 0, 0, 0, 0, 0, 0, 0, 60, 60, 70, 70, 15, 15, 60, 60, 6, 0,
0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 95, 95, 60, 60, 60, 60, 6, 1,
30, 0, 0, 0, 0, 0, 0, 0, 75, 70, 80, 80, -50, -50, 60, 60, 8, 0,
};
最初の4要素は、「Behavior」であることを示すためにフレーム数が負の値になっていることを除いて、「Posture」「Gait」と同様です。
次の3要素では、シーケンス内のフレームの繰り返しを設定します。
開始フレーム, 終了フレーム, ループサイクル,
例の「6, 7, 3」は、「Behavior」が0〜6フレーム目を再生後、7〜8フレーム目までを3回ループすることを意味します。「Gait」と違い、「Behavior」は配列全体が1回だけ実行されます。
各フレームには16関節角度が含まれており、フレーム最後の4要素では、「遷移速度」と「遅延条件」を設定します。
...16関節角度, 遷移層度, 遅延時間, トリガー軸, トリガー角度,
「遷移速度」は初期値4、値範囲は1(遅い)〜127(速い)、単位は 1 ステップあたりの度数です。0を設定すると、サーボの最大速度(約0.07秒/60度)で回転します。10 以上は推奨しません。
「遅延時間」は初期値0、値範囲は0~127、単位は50msです。
「トリガー軸」は0でない場合、遅延時間は無視されます。次のフレームのトリガーは、対応する軸のボディの角度に依存します。ピッチ軸は「1」、ロール軸は「2」を指定します。数字の符号は閾値の方向(現在の角度がトリガーの角度よりも小さいか大きいか)を設定します。
「トリガー角度」の値範囲は128〜127度になります。
2-3. スキル配列
スキルをEEPROMに書き込むには、最初に「WriteInstinct.ino」をアップロードします。「WriteInstinct.ino」は、以下のスキル名とポインタの配列の情報を使用します。
const char* skillNameWithType[] = {"crI", "puI", "restI", "zeroN",};
const char* progmemPointer[] = {cr, pu, rest, zero, };
「skillNameWithType」の文字列の接尾語(「I」:Instinct, 「N」:Newbility)は、スキルをどこに保存するか、どのタイミングで保存するかを伝えるものです。
その後にアップロードされたスケッチが「OpenCat.ino」であり、「I2C EEPROM」を搭載した「NyBoard」を使用している場合、「OpenCat.ino」はNewbilityのポインタのみを必要とします。
const char* progmemPointer[] = {zero};
3. スキルの追加
3-1. 既存のスキルの更新
「InstinctBittle.h」には既に「zeroN」と呼ばれるスキルがあります。これは新しい定義を待っているゼロ状態の姿勢になります。
最初にコマンド「mIndex Offset」を使用して、個々の関節をターゲット位置に移動し、次に配列内の関節角度の値を置き換えます。
const char zero[] PROGMEM = {
1, 0, 0, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,};
「Newbility」として定義されており、「I2C EEPROM」に書き込む必要がないため、配列を変更する毎に「OpenCat.ino」をアップロードするだけで(WriteInstinct.inoのアップロードなしに)更新できます。
IRリモコンの「7」を押すか、シリアルモニタで「kzero」と入力することで、新しい姿勢を実行することができます。スキル名を変更することもできますが、IRリモコンを使うには、IRリモコンのキーマップの更新も必要になります。
3-2. 新規スキルの追加
新規スキルを追加するには、「InstinctBittle.h」の「NUM_SKILLS」でスキル数を増やし、スキル配列にスキル名とポインタを追加する必要があります。
スキルはシリアルモニタからトークンの「k」コマンドで呼び出すことができます。例えば、「ksit」は姿勢「sit」を実行します。また、新しいスケッチをアップロードしなくても、「m」「i」「l」トークンを使ってシリアルポートから姿勢フレームを送ることで、新しいスキルをチューニングすることができます。スキルを微調整した後、「InstinctBittle.h」に保存し、それを「Instinct」または「Newbility」としてボードにアップロードすることができます。
使用可能なスキル名については、必ず実際のコードを確認してください。ソフトウェアを開発する中で、スキルセットを変更する場合があります。
このリポジトリは、カスタマイズされた歩行を開発したい場合の良い出発点となります。逆運動学の計算を行う場合は、以下の主要なディメンションを使用してモデルを構築することができます。
4. 参考
次回
この記事が気に入ったらサポートをしてみませんか?