Open12

ロボット制御フレームワーク ARCS6 に入門してみる

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

コンパイル環境

コンパイルするには下記 3 つの選択肢がある

  • 物理マシン
  • 仮想マシン
  • Docker コンテナ

実際にロボットを制御する場合は物理マシンを使う必要があるが、とりあえずコンパイルや実行してみるだけなら仮想マシンや Docker コンテナでも良さそう

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

ワークスペースの準備

コマンド
mkdir hello-arcs6
cd hello-arcs6
mkdir src

Docker コンテナを起動する時に -v オプションを使って src ディレクトリを /root/src に紐付ける

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

ビルドツールのインストール

コマンド
yum install -y make gcc gcc-c++
gcc のバージョン確認
$ gcc --version
gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-16)
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
g++ のバージョン確認
# g++ --version
g++ (GCC) 8.5.0 20210514 (Red Hat 8.5.0-16)
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

gcc と g++ のバージョンは 7.3 以上が必要、両方とも 8.5 なので大丈夫そう

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

ソースコードの入手

コマンド(ホスト側)
cd src
git clone https://github.com/sidewarehouse/ARCS-PUBLIC arcs6
動作確認(コンテナ側)
# ls /root/src/arcs6
ARCS6  README.md  README_cmake.md  archive
薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

サンプルのコンパイル

コマンド
cd /root/src/arcs6/ARCS6/robot/sample/00_空の基本コード/
make

一発でコンパイルが通った、さすが横倉先生のプロダクトだ

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

ControlFunctions.cc を眺めてみる

arcs6/ARCS6/robot/sample/00_空の基本コード/ControlFunctions.cc(一部抜粋)
//! @brief 制御用周期実行関数1
//! @param[in]	t		時刻 [s]
//! @param[in]	Tact	計測周期 [s]
//! @param[in]	Tcmp	消費時間 [s]
//! @return		クロックオーバーライドフラグ (true = リアルタイムループ, false = 非リアルタイムループ)
bool ControlFunctions::ControlFunction1(double t, double Tact, double Tcmp){
	// 制御用定数設定
	[[maybe_unused]] constexpr double Ts = ConstParams::SAMPLING_TIME[0]*1e-9;	// [s]	制御周期
	
	// 制御用変数宣言
	
	if(CmdFlag == CTRL_INIT){
		// 初期化モード (ここは制御開始時/再開時に1度だけ呼び出される(非リアルタイム空間なので重い処理もOK))
		Initializing = true;		// 初期化中ランプ点灯
		Screen.InitOnlineSetVar();	// オンライン設定変数の初期値の設定
		Interface.ServoON();		// サーボON指令の送出
		Initializing = false;		// 初期化中ランプ消灯
	}
	if(CmdFlag == CTRL_LOOP){
		// 周期モード (ここは制御周期 SAMPLING_TIME[0] 毎に呼び出される(リアルタイム空間なので処理は制御周期内に収めること))
		// リアルタイム制御ここから
		Interface.GetPosition(PositionRes);	// [rad] 位置応答の取得
		Screen.GetOnlineSetVar();			// オンライン設定変数の読み込み
		
		// ここに制御アルゴリズムを記述する
		
		Interface.SetCurrent(CurrentRef);	// [A] 電流指令の出力
		Screen.SetVarIndicator(0, 0, 0, 0, 0, 0, 0, 0, 0, 0);	// 任意変数インジケータ(変数0, ..., 変数9)
		Graph.SetTime(Tact, t);									// [s] グラフ描画用の周期と時刻のセット
		Graph.SetVars(0, 0, 0, 0, 0, 0, 0, 0, 0);	// グラフプロット0 (グラフ番号, 変数0, ..., 変数7)
		Graph.SetVars(1, 0, 0, 0, 0, 0, 0, 0, 0);	// グラフプロット1 (グラフ番号, 変数0, ..., 変数7)
		Graph.SetVars(2, 0, 0, 0, 0, 0, 0, 0, 0);	// グラフプロット2 (グラフ番号, 変数0, ..., 変数7)
		Graph.SetVars(3, 0, 0, 0, 0, 0, 0, 0, 0);	// グラフプロット3 (グラフ番号, 変数0, ..., 変数7)
		Memory.SetData(Tact, t, 0, 0, 0, 0, 0, 0, 0, 0, 0);		// CSVデータ保存変数 (周期, A列, B列, ..., J列)
		// リアルタイム制御ここまで
	}
	if(CmdFlag == CTRL_EXIT){
		// 終了処理モード (ここは制御終了時に1度だけ呼び出される(非リアルタイム空間なので重い処理もOK))
		Interface.SetZeroCurrent();	// 電流指令を零に設定
		Interface.ServoOFF();		// サーボOFF信号の送出
	}
	return true;	// クロックオーバーライドフラグ(falseにすると次の周期時刻を待たずにスレッドが即刻動作する)
}

現状の理解

  • CmdFlag が CTRL_LOOP ならば実際に制御が行われている状態
  • Interface.GetPosition() 関数を呼び出すとモーター等の位置応答を取得できる
  • Screen.GetOnlineSetVar() 関数を呼び出すとスクリーン上で入力された変数を取得できる
  • Interface.SetCurrent() 関数を呼び出すと電流指令値を設定できる
  • Graph.SetTime() 関数を呼び出すとグラフの時間を設定できる
  • Graph.SetVars() 関数を呼び出すとグラフにプロットできる
  • Memory.SetData() 関数を呼び出すと CSV 出力に書き込める

わからないこと

  • 制御よう周期実行関数 1〜3 まで複数ある、3 が最大?
  • どのように制御周期を設定できるか?
薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

グラフが表示されない理由

Docker コンテナだからかな?次は少し手間がかかるけど仮想マシンでやってみようと思う