Motion interpreter モジュールのコードです。サーボモータ制御のアプリケーション・インタフェースの役割を持ちます。
◀ この記事の前に: Motion interpreter( 操作説明 )
▶ この記事の次に: Motion sequencer( 概要 )
概 要
Qumcum Lab.の主要機能( アプリケーション )から呼ばれる関数で構成しています。概要は以下のとおりです。
モジュールの構造
アプリーションからの指示の種類別に関数があります。その関数を統合している関数が setMIinstruction()です。
各関数はおもにアプリケーションからの指示を受け付ける APIになります。指示は文字列( instruction )です。文字列の最初の文字が Motion interpreterへの指示(命令)になります。
関数の概要
関数は以下のとおりです。
外部関数
他のジュールやファイルの外部からアクセス可能な関数です。
setInstructionMI( String szInput )
引 数:
String szInput: インストラクション( ASCII文字列 )
tcX: 詳細は以下のとおり
・ t: 対象は音声で “m”( motion )
・ c: コマンドで以下のとおり
・ X: コマンドの引数で以下のとおり
コマンド | 命 令 | 引 数 |
---|---|---|
e | シーケンス動作の開始 | N:シーケンス番号 |
●f | シーケンス動作の開始( 即時 ) | N:シーケンス番号 |
m | サーボモータの個別動作( 即時 ) | CA:動作コマンド |
s | 発声速度の設定 | L:基底速度 ・1 ~ 100の間で指定( 初期値:10 ) |
q | 動作の停止と基本姿勢 | ( なし ) |
w | シーケンスの書き込み | XXX%:シーケンス ・終了記号は % |
e | 機能の開始/終了 | S:開始または終了 ・1:開始 / 0:終了 |
分 類:
API( 対象はアプリケーション、他 )
機 能:
指示されたインストラクションを解析してサーボモータを動かす。( 各内部関数に振り分ける。)
デバッグ用の USB入力で使用している。
関係する関数:
上位関数: アプリケーション
下位関数: procMIexecSq(), procMIwriteSq(), procMImoveSv(), procMIsetSpeedSV()
この関数のコードはこちらです。
procMIexecSq / ● execSqMI( String szInput / ● int nSqNo )
引 数:
String szInput: シーケンス番号
分 類:
API、内部関数
機 能:
シーケンスを開始する。もし、シーケンスが実行中の場合はそのシーケンスが終了してから開始する。
関係する関数:
上位関数: setMIinstruction()、アプリケーション、他
下位関数: startSqMS()
この関数のコードはこちらです。
procMImoveSv / ● moveSvMI( String szInput )
引 数:
String szInput: サーボモータの操作コマンド
分 類:
API、内部関数
機 能:
指定したサーボモータを操作する。
関係する関数:
上位関数: setMIinstruction()、アプリケーション、他
下位関数: setSVposition()
この関数のコードはこちらです。
procMIsetSpeedSv / ● setSpeedMI( String szInput / ●int nSpeed )
引 数:
String szInput: 設定する基底速度
分 類:
API、内部関数
機 能:
基底速度を設定(変更)する。
関係する関数:
上位関数: setMIinstruction()、アプリケーション、他
下位関数: setSpeedSV()
この関数のコードはこちらです。
procMIwriteSq / ● writeSqMI( String szInput )
引 数:
String szInput: シーケンスデータ / フォーマットは書き込み用( 内部設定用とは異なる。)
分 類:
API、内部関数
機 能:
書き込み用シーケンスデータを書き込む。
保存できるシーケンスデータは1つで、このインストラクションを使用すると上書き保存する。
関係する関数:
上位関数: setMIinstruction()、アプリケーション、他
下位関数: ( なし )
この関数のコードはこちらです。
内部関数
外部から直接アクセスできずモジュール( 特定のスコープ内 )で使用する関数です。
Motion interpreter( コード )では内部関数はありません。
データの構造
データの構造は以下のとおりです。
グローバル定義
Motion interpreter( コード )ではグローバル定義はありません。
コード
コードは以下のとおりです。
関数間の関係
関数の関係は以下のとおりです。
setMIinstruction( String szInput )
procMIexecSq( String szInput )
シーケンスを開始する。
//**** command : Execute sequence ****
// eN[enter]
// e : command / Execute
// N : Sequence No.
void procMIexecSq( String szInput )
{
int lenBuf = szInput.length();
String azArg1 = szInput.substring(1, lenBuf); // sequence numbern
int seqNo = azArg1.toInt();
startSqMS( seqNo ); // subfunction
}
引数は開始するシーケンスで、文字列として受け取ります。下位関数には数字で渡すため変換を行います。
procMImoveSv( String szInput )
書き込み用シーケンスデータを書き込む。
//**** command : Move servomotor ****
// mCA[enter]
// m : command / Move
// C : extremities abbreviation
// HD, AR, AL, LR, LL, FR, FL
// A : position / expressive angle
// -x - +x, 0 - 180
void procMImoveSv( String szInput )
{
struct MI_M_EXTERMITIES {
String abbr;
int svNo;
};
struct MI_M_EXTERMITIES miTable[] = {
{ "hd", SV_HD }, // Head
{ "ar", SV_AR }, // Arm Right
{ "al", SV_AL }, // Arm Left
{ "lr", SV_LR }, // Leg Right
{ "ll", SV_LL }, // Leg Left
{ "fr", SV_FR }, // Foot Right
{ "fl", SV_FL } // Foot Left
};
int lenBuf = szInput.length();
String azArg1 = szInput.substring(1, 3); // extremities abbreviation
String azArg2 = szInput.substring(3, lenBuf); // position / expressive angle
int nPos = azArg2.toInt();
int svNo = 0;
for ( int i = 0; i < 8; i++ ){
if( azArg1.compareTo( miTable[i].abbr ) == 0 ){
svNo = miTable[i].svNo;
}
}
if( svNo != 0 ){
setSVposition( svNo, nPos );
}
}
miTable[] は、サーボモータの指定が小文字なので内部表現に変換するテーブルです。書き込み用の表現と内部の表現を対応付けている部分です。ここを変更することにより書き込み用の表現を変えることができます。
procMIsetSpeedSv( String szInput )
基底速度を設定(変更)する。
//**** command : Set speed servomotor ****
// sL[enter]
// s : command / Set angle speed
// M : speed
// 1 - 10
void procMIsetSpeedSV( String szInput )
{
int lenBuf = szInput.length();
String azArg1 = szInput.substring(1, lenBuf); // sequence numbern
float speedDev = azArg1.toInt();
setSpeedSV( speedDev );
}
procMIwriteSq( String szInput )
書き込み用シーケンスデータを書き込む。
//**** command : Write sequence ****
// wXXX[enter]
// w : command / Write sequence
// X : Element of motions ( unique )
// CAAW
// C : extremities abbreviation ( char )
// HD, AR, AL, LR, LL, FR, FL
// AA : position / expressive angle ( hex. )
// -x - +x, 0 - 180
// W : wait time by next execute ( hex. )
// retun : TRUE = success / FALSE = error <<<add***
int procMIwriteSq( String szInput )
{
char buf[SV_SQ_WRITABLE_CMDMAX]; <<<add***
char tmp[3];
int nPos;
// Elements of extermities and commands
int miTableSq[] = {
0, // 0 : Dummy
SV_AR, // 1 : Arm Right
SV_FR, // 2 : Foot Right
SV_LR, // 3 : Leg Right
SV_HD, // 4 : Head
SV_LL, // 5 : Leg Left
SV_FL, // 6 : Foot Left
SV_AL // 7 : Arm Left
};
struct MI_W_COMMAND {
char com; // command for communication
int mi; // command for motion interpreter
};
struct MI_W_COMMAND miTableSqCom[] = {
{ 'F', SV_CMD_FINISH }, // F : End of sequence
{ 'L', SV_CMD_LOOP }, // L : Loop next
{ 'N', SV_CMD_NEXT }, // N : Execute next command
{ 'S', SV_CMD_SET_SPEED } // S : Set speed
};
int lenBuf = szInput.length();
szInput.toCharArray ( buf, lenBuf );
int nNumChar = ( szInput.indexOf('/') - 1 ) / 4;
if( nNumChar > SV_SQ_WRITABLE_CMDMAX ) return FALSE; <<<add***
int j = 1;
for( int i = 0; i < nNumChar; ++i ){
//.... Target Servomotor ....
if( buf[j] < '8' ){
svSqWritable[i].svNo = buf[j] - '0';
} else {
for ( int k = 0; k < 4; ++k ){
if( miTableSqCom[k].com == buf[j] ){
svSqWritable[i].svNo = miTableSqCom[k].mi;
}
}
}
//.... Target Position ....
int c1, c2, c;
if( buf[j+1] <= '9' ){
c1 = buf[j+1] - '0';
} else {
c1 = buf[j+1] - 55;
}
if( buf[j+2] <= '9' ){
c2 = buf[j+2] - '0';
} else {
c2 = buf[j+2] - 55;
}
nPos = c1 * 16 + c2;
if( !( svSqWritable[i].svNo == SV_AR ||
svSqWritable[i].svNo == SV_AL ||
svSqWritable[i].svNo == SV_CMD_SET_SPEED
)) {
nPos -= 90;
}
svSqWritable[i].svPos = nPos;
//.... Period by next motion ....
if( buf[j+3] <= '9' ){
svSqWritable[i].period = buf[j+3] - '0';
} else {
svSqWritable[i].period = buf[j+3] - 'F';
}
j+=4;
}
return TRUE; <<<add***
}
line. 18: miTableSq [ ]: 対象とするサーボモータの指定( 変換 )
line. 34: miTableSqCom [ ]: シーケンス制御コマンドの内部表記への変換
line. 60: 角度または時間の 16進数表記から 10進数への変換
line. 77: 90度のオフセットを元に戻す
line.86: 次のコマンドへの間隔の 16進数表記から 10進数への変換

C( サーボモータの指定またはシーケンス制御コマンド )により、参照するテーブルが異なる。サーボモータの指定でもシーケンス制御コマンドの場合でも内部表現に変換した結果を、メモリ内のシーケンスデータに保存します。
参考情報
参考になる情報は以下のとおりです。
このホームページ内
- Motion Interpreter( 概要 ): サーボモータ制御の最上位、Motion Interrupter の概要です。
- Motion Interpreter( 操作説明 ): アプリケーションからの操作方法です。( API )
- Motion Interpreter( コード ): コードの詳細を説明します。
- Motion sequencer( 概要 ): サーボモータの協調運動制御の概要です。
- Motion sequencer( 操作説明 ): シーケンスの開始・停止等の操作方法です。( API )
- Motion sequencer( コード ): コードの詳細を説明します。
- シーケンスデータ: シーケンスデータの仕様と作成方法です。
- Servomotor Driver( 概要 ): サーボモータそのものの制御です。( API )
- Servomotor Driver( 操作説明 ): 個々のサーボモータを制御する方法です。
- Servomotor Driver( コード ): コードの詳細を説明します。
- サーボモータの制御( コード詳説 ): バックグラウンド処理の分散化の実現方法です。
- サーボモータ: サーボモータの回路です。ハードウエアの説明です。