ARCS on Raspberry Pi 2
FRONT PAGE

コレは何?/What is this?

Raspberry Pi 2 Model B でARCSが動くことを確認し、リアルタイム性について検証した。



動 機

ちょっとした制御をやりたいのに、そのためにデカイ制御用PCを用意するのはバカバカしい上に、なによりPCのお値段高い。 さらに、PCIのボードも応答性あんまり良くない上に高い。 あと、普通のPCを移動ロボットに積もうと思ったら結構面倒だし。 ってことで、ラズベリーパイ2で ARCS Ver.5.1-SF が動いて制御ができれば嬉しいというのが動機。

ソースコード

ARCSのControlFunctions.ccの制御用周期実行関数を以下のように作成。 やってることは、GPIO21を制御周期毎にON、OFFするだけ。つまり方形波が出るはず。 制御周期は200μsに設定。

     1 :	void ControlFunctions::ControlFunction1(ControlFunctions* pCF){
     2 :	    // 制御用周期実行関数1
     3 :	    
     4 :	    // 制御用定数設定
     5 :	    const float Ts = ConstParams::SAMPLING_TIME[0]*1e-9;    // [s]        制御周期
     6 :	    
     7 :	    // 制御用変数宣言
     8 :	    static bool loopflag = true;
     9 :	    
    10 :	    // 制御器等々
    11 :	    static RPi2GPIO* gpio;
    12 :	    
    13 :	    if(pCF->CmdFlag==CTRL_INIT){
    14 :	        // 初期化モード (ここは制御開始時に1度だけ呼び出される(非実時間空間なので重い処理もOK))
    15 :	        gpio = new RPi2GPIO();
    16 :	    }
    17 :	    if(pCF->CmdFlag==CTRL_LOOP){
    18 :	        // 周期モード (ここは制御周期 SAMPLING_TIME[0] 毎に呼び出される(実時間空間なので処理は制御周期内に収めること))
    19 :	        pCF->count++;        // ループカウンタを進める
    20 :	        t=pCF->count*Ts;    // 時刻の計算
    21 :	        
    22 :	        // 制御ここから
    23 :	        pCF->pIF->GetTorque(TorqueRes);        // [Nm] トルク応答値の取得
    24 :	        pCF->pIF->GetPosition(PositionRes);    // [rad] 位置応答値の取得
    25 :	        
    26 :	        // ここにやりたい制御を書くがよい!!
    27 :	        if(loopflag == true){
    28 :	            gpio->BitSet(21);    // GPIO21を1にする
    29 :	            loopflag = false;
    30 :	        }else{
    31 :	            gpio->BitClear(21);    // GPIO21を0にする
    32 :	            loopflag = true;
    33 :	        }
    34 :	        
    35 :	        pCF->pIF->SetCurrent(CurrentRef);    // [A] 電流指令値の出力
    36 :	        // 制御ここまで
    37 :	        
    38 :	        // 任意変数値表示用
    39 :	        pCF->IndicVars[0] = 0;    // 表示変数
    40 :	        pCF->IndicVars[1] = 0;    // 表示変数
    41 :	        pCF->IndicVars[2] = 0;    // 表示変数
    42 :	        pCF->IndicVars[3] = 0;    // 表示変数
    43 :	        pCF->IndicVars[4] = 0;    // 表示変数
    44 :	        pCF->IndicVars[5] = 0;    // 表示変数
    45 :	        pCF->IndicVars[6] = 0;    // 表示変数
    46 :	        pCF->IndicVars[7] = 0;    // 表示変数
    47 :	        
    48 :	        // 任意変数プロット
    49 :	        pCF->PlotVars[0] = 0;
    50 :	        pCF->PlotVars[1] = 0;
    51 :	        
    52 :	        // データの保存
    53 :	        pCF->Data[0] = t;    // [s]    時刻の保存
    54 :	        pCF->Data[1] = 0;    // 保存変数
    55 :	        pCF->Data[2] = 0;    // 保存変数
    56 :	        pCF->Data[3] = 0;    // 保存変数
    57 :	        pCF->ExpData->PutData(pCF->Data,ConstParams::DATA_NUM);    // データ格納
    58 :	    }
    59 :	    if(pCF->CmdFlag==CTRL_EXIT){
    60 :	        // 終了処理モード (ここは制御終了時に1度だけ呼び出される(非実時間空間なので重い処理もOK))
    61 :	        delete gpio;
    62 :	    }
    63 :	}

実 験

GPIO21の出力をオシロで観測。その結果が以下の図である。パルス幅ピッタリ200μs。いけるでこれ。



GPIO21の出力波形

もうちょっと長い時間ではどうなんでしょう?というのが気になるので、時間スパンを広げて観測。



GPIO21の出力波形をもっと長い時間で観測

といってもこれじゃよく分からんので、オシロからCSVデータを出力して、MATLABでそれを読み込み、パルス幅を計測する。



パルス幅をMATLABに読み込んでジッタを計測

これなら行けそうだわ。 ただ、本当ならもっと長時間のジッタを計測したいが、オシロの時間分解能とタイムスパンとのトレードオフがあるので、そこは課題。



ちゃんといごいてるで~ 秋月の10.1inディスプレイに表示。(このときは制御周期100μsに設定)

結 論

Raspberry Pi 2 でも問題なく制御できそう。 ただし、実際にモータ制御をしたわけではないので、そこは要確認。





- 97661 -

研究室の横の倉庫 - Side Warehouse of Laboratory
Copyright(C), Side Warehouse, All rights reserved.