Open12
ロボット制御フレームワーク ARCS6 に入門してみる
コンパイル環境
コンパイルするには下記 3 つの選択肢がある
- 物理マシン
- 仮想マシン
- Docker コンテナ
実際にロボットを制御する場合は物理マシンを使う必要があるが、とりあえずコンパイルや実行してみるだけなら仮想マシンや Docker コンテナでも良さそう
ワークスペースの準備
コマンド
mkdir hello-arcs6
cd hello-arcs6
mkdir src
Docker コンテナを起動する時に -v
オプションを使って src ディレクトリを /root/src に紐付ける
Docker コンテナの起動
コマンド
docker run -it --name arcs6 -v `pwd`/src:/root/src almalinux /bin/bash
ビルドツールのインストール
コマンド
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 なので大丈夫そう
依存関係のインストール
コマンド
yum install -y ncurses* libncurses* libpng* kernel-devel
kernel-devel はいらないかも知れない
ソースコードの入手
コマンド(ホスト側)
cd src
git clone https://github.com/sidewarehouse/ARCS-PUBLIC arcs6
動作確認(コンテナ側)
# ls /root/src/arcs6
ARCS6 README.md README_cmake.md archive
VSCode で Shift_JIS が文字化けする場合
設定で Auto Guess Encoding にチェックを入れれば良い
サンプルのコンパイル
コマンド
cd /root/src/arcs6/ARCS6/robot/sample/00_空の基本コード/
make
一発でコンパイルが通った、さすが横倉先生のプロダクトだ
サンプルの実行
コマンド
./ARCS
無事に起動できたが PLOT/PRINT AREA が空白なのが気になる
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 が最大?
- どのように制御周期を設定できるか?
グラフが表示されない理由
Docker コンテナだからかな?次は少し手間がかかるけど仮想マシンでやってみようと思う