概要
歩行パターンファイルに基づきPD制御によってロボットを歩行させるSamplePDを例にして、OpenRTMコンポーネントとしてコントローラを作成する方法を説明します。 コード解説SamplePD.hController/rtc/SamplePD/SamplePD.h をご覧ください。 SamplePD::onActivated と SamplePD::onExecute が宣言されていることを確認してください。 雛形作成時には SamplePD::onInitialize 以外の仮想関数がコメントアウトされています。 これらの仮想関数をオーバーライドすることでコントローラ特有の振る舞いを定義することができます。 コントローラが使用する種々のメンバが追加されています。 private: int dummy; std::ifstream angle, vel, gain; // 関節角度、 関節角速度、ゲイン値 double *Pgain; // Pゲインの配列 double *Dgain; // Dゲインの配列 std::vector<double> qold; // ひとつ前の関節角度を保持 Windows環境でも実行する場合は、DLL版のビルドに対応するためSamplePDInitメソッドをOpenRTMで定義されたDLL_EXPORTマクロで修飾します。
extern "C"
{
DLL_EXPORT void SamplePDInit(RTC::Manager* manager);
};
SamplePD.cppヘッダファイルのインクルードとマクロの定義を行います。 #include <iostream> #define DOF (29) // 自由度 #define TIMESTEP 0.002 // シミュレーションのステップ // 各種ファイル群 #define ANGLE_FILE "etc/angle.dat" // 関節角度 #define VEL_FILE "etc/vel.dat" // 関節角速度 #define GAIN_FILE "etc/PDgain.dat" // PDゲイン値 SamplePD.hで宣言したメソッドを実装します。 SamplePD::SamplePDでコンストラクタを呼んだ後、歩行パターンファイルを開き、ゲインファイルからPDゲイン値を変数に取り込みます。
SamplePD::SamplePD(RTC::Manager* manager)
: RTC::DataFlowComponentBase(manager),
// <rtc-template block="initializer">
m_angleIn("angle", m_angle),
m_torqueOut("torque", m_torque),
// </rtc-template>
dummy(0),
qold(DOF)
{
...
Pgain = new double[DOF];
Dgain = new double[DOF];
// 関節角度ファイルを開く
if (access(ANGLE_FILE, 0)){
std::cerr << ANGLE_FILE << " not found" << std::endl;
}else{
angle.open(ANGLE_FILE);
}
// 関節角速度ファイルを開く
if (access(VEL_FILE, 0)){
std::cerr << VEL_FILE << " not found" << std::endl;
}else{
vel.open(VEL_FILE);
}
// ゲインファイルを開き配列に代入
if (access(GAIN_FILE, 0)){
std::cerr << GAIN_FILE << " not found" << std::endl;
}else{
gain.open(GAIN_FILE);
for (int i=0; i<DOF; i++){
gain >> Pgain[i];
gain >> Dgain[i];
}
gain.close();
}
// トルク, 関節角度ポートの長さをロボットの自由度分確保
m_torque.data.length(DOF);
m_angle.data.length(DOF);
}
SamplePD::~SamplePDでファイルのクローズと配列の解放を行います。 if (angle.is_open()) angle.close(); if (vel.is_open()) vel.close(); delete [] Pgain; delete [] Dgain; RTC::ReturnCode_t SamplePD::onActivatedでは初期化処理を行います。
RTC::ReturnCode_t SamplePD::onActivated(RTC::UniqueId ec_id)
{
std::cout << "on Activated" << std::endl;
angle.seekg(0);
vel.seekg(0);
// 関節角度InPortの値をアップデート
m_angleIn.update();
// 1フレーム前の値を保持する
for(int i=0; i < DOF; ++i){
qold[i] = m_angle.data[i];
}
return RTC::RTC_OK;
}
RTC::ReturnCode_t SamplePD::onExecuteメソッドでシミュレーションのステップ毎の振る舞いを処理します。
RTC::ReturnCode_t SamplePD::onExecute(RTC::UniqueId ec_id)
{
// 関節角度InPortの値をアップデート
m_angleIn.update();
// 各関節の角度と角速度を更新
static double q_ref[DOF], dq_ref[DOF];
if(!angle.eof()){
angle >> q_ref[0]; vel >> dq_ref[0];// skip time
for (int i=0; i<DOF; i++){
angle >> q_ref[i];
vel >> dq_ref[i];
}
}
// 各関節のtorque値を決定
for(int i=0; i<DOF; i++){
double q = m_angle.data[i];
double dq = (q - qold[i]) / TIMESTEP;
qold[i] = q;
m_torque.data[i] = -(q - q_ref[i]) * Pgain[i] - (dq - dq_ref[i]) * Dgain[i];
}
//トルクを出力
m_torqueOut.write();
return RTC::RTC_OK;
}
ファイルController/rtc/SamplePD/以下のパターンファイルと設定ファイルについて説明します。歩行パターンファイル
コードでいうところのANGLE_FILEマクロ、VEL_FILEマクロに相当するファイルです。 時刻 <JointID=0 の関節のデータ> <JointID=1 の関節のデータ> … <JointID=nの関節のデータ>
一行が1フレームに相当し、デリミッタはtabです。 ゲインファイルコードでいうところのGAIN_FILEマクロに相当するファイルです。PD制御のゲインを記録します。 そのフォーマットはJointID行にPゲイン、Dゲインの任意個をスペースでわけて書くこととし、具体的には以下のとおりとします。 Pゲイン Dゲイン (<= JointID = 0) Pゲイン Dゲイン (<= JointID = 1) ... Pゲイン Dゲイン (<= JointID = n) rtc.conf
設定ファイル Controller/rtc/SamplePD/rtc.conf をご覧ください。 環境に合わせてネームサーバの場所を記述します。 corba.nameservers: localhost:2809特に,
OpenHRP.vsprops, bin/dos/config.bat (Windows 環境) ログファイル作りの有無を設定します。
logger.enable:YES
ログファイルの作り先(パス)と名前形式を設定します。 logger.file_name: D:\\Temp\\rtc%p.log ログレベルの設定です。 logger.log_level: TRACE 以下の内容は基本的には変更しないでください。 naming.formats: %n.rtc manager.modules.load_path: . exec_cxt.periodic.rate: 1000000 manager.modules.abs_path_allowed: yes exec_cxt.periodic.type: SynchExtTriggerEC RTコンポーネントの設定オプションに関する詳しい説明は、OpenRTM マニュアルの コンフィギュレーション で確認してください。 コントローラブリッジの設定と起動
各コンポーネント毎に実装を分離する目的は、開発における保守性・可搬性の向上です。 Linuxの場合
起動スクリプトController/rtc/SamplePD/SamplePD.shをご覧ください。
#!/bin/sh
CONTROLLER_BRIDGE_DIR=../../bridge
if [ -z $NS_HOST ]; then
if [ -z $NS_PORT ]; then
. $CONTROLLER_BRIDGE_DIR/../../bin/unix/config.sh
fi
fi
$CONTROLLER_BRIDGE_DIR/ControllerBridge \
--config-file bridge.conf \
--name-server $NS_HOST:$NS_PORT
Controller/bridgeディレクトリとController/SamplePDディレクトリの相対位置が変わった場合、
CONTROLLER_BRIDGE_DIRを適宜に変更することでControllerBridgeへの参照が対応するように
なっています。環境変数 NS_HOST、NS_PORTが定義されていない場合、bin/unix/config.shより取得するようになっています。 Windowsの場合
起動スクリプトController/rtc/SamplePD/SamplePD.batをご覧ください。
SET CONTROLLER_BRIDGE_DIR=..\..\bridge
@echo off
if "%NS_HOST%" == "" (
if "%NS_PORT%" == "" (
call %CONTROLLER_BRIDGE_DIR%\..\..\bin\dos\config.bat
)
)
@echo on
%CONTROLLER_BRIDGE_DIR%\ControllerBridge ^
--config-file bridge.conf ^
--name-server %NS_HOST%:%NS_PORT%
SamplePD.shと同様にController/bridgeディレクトリとController/SamplePDディレクトリの相対位置が変わった場合、
ControllerBridgeが参照できるようにCONTROLLER_BRIDGE_DIRの変更によって対応するようになっております。パス名にスペースが入る際はダブルクォテーションで囲ってください。 環境変数 NS_HOST、NS_PORTが定義されていない場合、bin/dos/config.batより取得できるようにします。 Windows環境における当バッチファイルの実行において注意点があります。 それは、Linux環境と違いomninamesサーバをサービスとして登録しない場合が多いので、そのようなときは事前にomninamesサーバを起動しておく必要があります。 マニュアルによるomninamesサーバの起動方法はRTコンポーネント作成(VC++版)「ネームサーバの起動」項目を参照してください。 もしくは、事前にGrxUIを起動していただければGrxUI動作中は、omninamesサーバが動作します。 ただしGrxUIによるomninamesサーバの起動は、GrxUIを終了するとomninamesサーバも終了しますので注意が必要です。 起動オプションについて
config-file
name-server 起動オプションの詳細、その他の起動オプションについては「コントローラーブリッジ使用マニュアル」をご覧ください。 プロジェクトファイルの読み込みと実行GrxUIからSamplePD.xmlを読み込み動作を確認します。
GrxUIの詳細については「GrxUI」をご覧ください。 スケルトンの作成コンポーネントのスケルトン作成について説明します。 コマンドライン上でも作成できますが設定項目が多いので、スクリプト用いた作成手法を環境毎に説明します。このスクリプトの実行によってangleという名前のInPort、torqueという名前のOutPortを備えたSamplePDコンポーネントのスケルトンを生成します。 Linuxの場合以下のようなシェルスクリプトを用意します。 #!/bin/sh rtc-template -bcxx \ --module-name=SamplePD --module-desc="SamplePD component" \ --module-version=0.1 --module-vendor=AIST --module-category=Generic \ --module-comp-type=DataFlowComponent --module-act-type=SPORADIC \ --module-max-inst=1 \ --inport=angle:TimedDoubleSeq \ --outport=torque:TimedDoubleSeq rtc-template(Linux C++版)に関する詳しい説明は、OpenRTM マニュアルの RTコンポーネント作成 で確認してください。 Windowsの場合以下のようなバッチを用意します。 "C:\Program Files\OpenRTM-aist\0.4\utils\rtc-template\rtc-template.py" -bcxx ^ --module-name=SamplePD --module-desc="SamplePD component" ^ --module-version=0.1 --module-vendor=AIST --module-category=Generic ^ --module-comp-type=DataFlowComponent --module-act-type=SPORADIC ^ --module-max-inst=1 ^ --inport=angle:TimedDoubleSeq ^ --outport=torque:TimedDoubleSeq バッチの実行によって、VC++用のソリューションファイル、VC++ 2008用のプロジェクトファイルを生成します。 実行後、rtc-templateが自動生成した copyprops.bat を実行してください。 rtc-template(Windows VC++版)に関する詳しい説明は、OpenRTM マニュアルの RTコンポーネント作成(VC++版) で確認してください。 |