概要ここでは、歩行パターンファイルに基づいてPD制御でロボットを歩行させるコントローラをOpenRTMコンポーネントとして作成する方法を説明します。 ファイルの作成
まず、作業フォルダーとして新しいフォルダーを作成します。(例えば "mySamplePD" としましょう。)
※ テスト用のファイルが "OpenHRP3/sample/controller/SamplePD/etc/" フォルダー内に
置いてありますので、それらの3つのファイルを "mySamplePD/etc/" 内にコピーして使ってもらって
も構いません。
ファイル内容はいずれの場合も同じです。 歩行パターンファイル歩行パターンファイル(angle.dat,vel.dat)のフォーマットについて説明します。 時刻 <JointID=0 の関節のデータ> <JointID=1 の関節のデータ> … <JointID=nの関節のデータ>
一行が1フレームに相当し、デリミッタはtabです。時刻は開始時刻からの相対時間、関節のデータはangle.datの場合角度、vel.datの場合角速度に相当します。例えばサンプルの場合、14秒間6701フレームの29個の関節データが表現されています。 ゲインファイルPD制御のゲインを記録します。そのフォーマットはJointID行にPゲイン、Dゲインの任意個をスペースでわけて書くこととし、具体的には以下のとおりとします。Pゲイン Dゲイン (<= JointID = 0) Pゲイン Dゲイン (<= JointID = 1) ... Pゲイン Dゲイン (<= JointID = n) スケルトン作成コンポーネントのスケルトンを作成します。angleという名前のInPort、torqueという名前のOutPortを備えたSamplePDコンポーネントです。 RTC Builderを使用する方法とrtc-templateを使用する方法があります。 RTC BUilderを使用する
RTC Builderを起動します。RTC Builderに関する詳しい説明は、OpenRTM マニュアルの
RTCBuilder-1.1.0とは
で確認してください。
アクティビティページを開いて図2のように設定します。
データポートページを開いて図3のように設定します。
言語・環境ページを開いて図4のように設定します。
基本プロファイル入力ページに戻って、コード生成ボタンを押すと、コンポーネントのスケルトンが作成されます。 プログラミングSamplePD.h生成されたソースSamplePD.hを編集します。 コントローラが使用する種々のメンバを追加します。 private: int dummy; std::ifstream angle, vel; // 関節角度, 関節角速度 double *Pgain; // Pゲインの配列 double *Dgain; // Dゲインの配列 std::vector<double> qold; // ひとつ前の関節角度を保持 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" namespace { const bool CONTROLLER_BRIDGE_DEBUG = false; } SamplePD.hで宣言したメソッドを実装します。 SamplePD::SamplePDでコンストラクタを追加します。 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) { SamplePD::onInitialize()で歩行パターンファイルを開き、ゲインファイルからPDゲイン値を変数に取り込みます。 RTC::ReturnCode_t SamplePD::onInitialize() { // Registration: InPort/OutPort/Service // <rtc-template block="registration"> // Set InPort buffers addInPort("angle", m_angleIn); // Set OutPort buffer addOutPort("torque", m_torqueOut); // Set service provider to Ports // Set service consumers to Ports // Set CORBA Service Ports // </rtc-template> // <rtc-template block="bind_config"> // Bind variables and configuration variable Pgain = new double[DOF]; Dgain = new double[DOF]; // 関節角度ファイルを開く angle.open(ANGLE_FILE); if (!angle.is_open()){ std::cerr << ANGLE_FILE << " not found" << std::endl; } // 関節角速度ファイルを開く vel.open(VEL_FILE); if (!vel.is_open()){ std::cerr << VEL_FILE << " not found" << std::endl; } // ゲインファイルを開き配列に代入 std::ifstream gain; gain.open(GAIN_FILE); if (gain.is_open()){ for (int i=0; i<DOF; i++){ gain >> Pgain[i]; gain >> Dgain[i]; } gain.close(); }else{ std::cerr << GAIN_FILE << " not found" << std::endl; } // トルク, 関節角度ポートの長さをロボットの自由度分確保 m_torque.data.length(DOF); m_angle.data.length(DOF); // </rtc-template> return RTC::RTC_OK; } 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の値をアップデート if(m_angleIn.isNew()){ m_angleIn.read(); } // 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) { if( CONTROLLER_BRIDGE_DEBUG ) { std::cout << "onExecute" << std::endl; } // 関節角度InPortの値をアップデート if(m_angleIn.isNew()){ m_angleIn.read(); } double q_ref, dq_ref; angle >> q_ref; vel >> dq_ref;// skip time // 各関節のtorque値を決定 for (int i=0; i<DOF; i++){ angle >> q_ref; vel >> dq_ref; double q = m_angle.data[i]; double dq = (q - qold[i]) / TIMESTEP; qold[i] = q; m_torque.data[i] = -(q - q_ref) * Pgain[i] - (dq - dq_ref) * Dgain[i]; } //トルクを出力 m_torqueOut.write(); return RTC::RTC_OK; } コンパイルLinuxの場合Makefileが自動的に生成されます。そのMakefileを使用してコンパイルします。 make -f Makefile.SamplePD Windowsの場合
CMake用のCMakeList.txtが自動的に生成されます。 # check doxygen installed #find_package(Doxygen) #if(DOXYGEN_FOUND STREQUAL "NO") # message(FATAL_ERROR "Doxygen not found.") #endif()
CMakeのGUIを起動して、必要な内容を設定し、VC++のバージョンを選択してソリューションファイルを生成してください。 |