物理の駅 Physics station by 現役研究者

テクノロジーは共有されてこそ栄える

WSL上でEPICSを使う: プロセス間でリアルタイム通信する

Experimental Physics and Industrial Control System (EPICS) とは何か?

Wikipediaには

EPICS(Experimental Physics and Industrial Control System)は、加速器、望遠鏡、その他の大規模は実験用機器を運用する分散制御システムを開発・実装するのに使われるソフトウェア環境である。EPICS は SCADA の機能も提供する。このツールは、多数のコンピュータからなるネットワークで制御とフィードバックを行うシステムの開発の補助となるよう設計されている。アルゴンヌ国立研究所が2004年に開発したもので、独自のオープンソースライセンスでリリースされている。

EPICS は、コンピュータ間の通信モデルとしてクライアントサーバモデルと出版-購読型モデルを採用している。コンピュータ群(サーバまたは Input Output Controller)が、付随する測定機器を使って実験データと制御データを収集する。この情報を Channel Access (CA) というプロトコルで別のコンピュータ群(クライアント)に送る。CA は広帯域のネットワークプロトコルであり、科学実験のようなリアルタイム性を要する応用に適している。

と書かれているが、全く分からない。その他、日本語での解説もあるが、EPICSを使いこなした玄人が正確を期して書いた文章すぎて本当に訳が分からない。

この投稿では「コンピュータ内のプロセス間でリアルタイム通信する機能」を確認するところまでやる。

docs.epics-controls.org

上記とおりやればよいわけだが、一つ一つ説明しておこう。まずはWSLのUbuntuをインストール。

wsl --install

wsl で起動し、バージョンを確認する。執筆時はUbuntu22.04だった。

$ cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.2 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.2 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy

パッケージのアップデートとビルド用ツールをインストールする。

$ sudo apt update
$ sudo apt install build-essential

EPICSの基本部分をコンパイルする。$HOME (~と同じ)にEPICSディレクトリを作り、そこに最新のソースコードを git でダウンロードし、 EPICSの 通称base をコンパイルするため、epics-baseディレクトリに移動し、 make する。

$ mkdir $HOME/EPICS
$ cd $HOME/EPICS
$ git clone --recursive https://github.com/epics-base/epics-base.git
$ cd epics-base
$ make

かなりの時間を要するので make -j8 等と並列化(私のPCは8コアなので例は8並列)してもよい。

終わったら、~/.bashrc に以下のように書いておこう。

export EPICS_BASE=${HOME}/EPICS/epics-base
export EPICS_HOST_ARCH=$(${EPICS_BASE}/startup/EpicsHostArch)
export PATH=${EPICS_BASE}/bin/${EPICS_HOST_ARCH}:${PATH}

source ~/.bashrc で環境を再読み込みする。

EPICSのbaseがインストールできたか確認する。softIoc というコマンドを実行すると、

$ softIoc
epics>

となるはずである。これでインストールは成功している。Ctrl+Cでプログラムを終了させる。

管理する値を定義する。適当なディレクトリを作成し、そこにcdで移動して、次の内容の test.db ファイルを作る。

record(ai, "temperature:water")
{
    field(DESC, "Water temperature in the fish tank")
}

例は水の温度である。

softIoc を実行すると、このdbファイルの値を管理するプロセスが立ち上がる。

$ softIoc -d test.db

この中で、値をリスト化するコマンドdblを実行すると、水の温度があることがわかる。

epics> dbl
temperature:water
epics>

別のプロセスから、水の温度の確認、追加をしてみよう。別のターミナル(2番)を開き、値を確認するコマンド caget、値をセットするコマンド caset を実行する。

$ caget temperature:water
$ caset temperature:water 20

ともあれ、これだけではリアルタイムで値が管理されているか分からない。

別プロセスから値をリアルタイムでモニターしよう。さらに別のターミナル(3番)を開き、モニターするコマンド camonitor を実行する。

$ camonitor temperature:water

このままターミナル2番から caset で値をセットすると、セットしたタイミングで以下のように表示されるはずである。

temperature:water              2023-10-13 21:45:09.551818 24
temperature:water              2023-10-13 21:45:43.071098 21

以上で「コンピュータ内のプロセス間でリアルタイム通信する機能」を確認できた。

反応する値の精度を変える説明は、以下の英語のドキュメントを参照してほしい。

docs.epics-controls.org