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

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

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

あらゆるものをWindows上で動かさないと気がすまない筆者なので、頑張ってExperimental Physics and Industrial Control System (EPICS) R3.15をWindows上で動かすことにする。7.0用の記事もあるが、Windowsで動かすには色々バグがあるかもしれない。

ビルドに必要なアイテムは4つ

  • Windows用のmake (PATHを通す必要がある)
  • Windows用のperl
  • Visual Studio 2022 Community等
  • Windows用のGit

当環境の各バージョンは以下の通り

>make --version
GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
これはフリーソフトウェアです. 利用許諾についてはソースを
ご覧ください.
商業性や特定の目的への適合性の如何に関わらず, 無保証です.
This program built for i386-pc-mingw32

>perl --version
This is perl 5, version 32, subversion 1 (v5.32.1) built for MSWin32-x64-multi-thread
Copyright 1987-2021, Larry Wall
Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.

>cl
Microsoft(R) C/C++ Optimizing Compiler Version 19.29.30151 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.
使い方: cl [ オプション... ] ファイル名... [ /link リンク オプション... ]

>git --version
git version 2.37.2.windows.2

上記4つの準備が終わったら、Visual Studio 2022 Community 等の x64 Native Tools Command Prompt を開き、Gitで epics-base3.15 をcloneする。

>git clone --recursive -b 3.15 https://github.com/epics-base/epics-base.git ./epics-base_v3.15

このまま

> cd epics-base_v3.15
> make

とすると、bin/windows-x64 にビルドされた exe がインストールされる。

C:\Users\Masahiro\epics-base_v3.15 でmakeした場合、以下のように環境変数を設定する。

EPICS_BASE=C:\Users\Masahiro\epics-base_v3.15
EPICS_HOST_ARCH=windows-x64
PATH=C:\Users\Masahiro\epics-base_v3.15\bin\windows-x64

EPICSのbaseがインストールできたか確認する。新しいコマンドプロンプトを立ち上げてsoftIoc というコマンドを実行すると、

> softIoc
epics>

「このアプリの機能のいくつかが Windows Defender ファイアウォールでブロックされています」という「Windows セキュリティの重要な警告」が出てくるはずである。他のプログラムでも同様に、各自の判断で、「アクセスを許可する」すること。

epics> と出ればインストールは成功している。Ctrl+Cでプログラムを終了させる。

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

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

例は水の温度である。

コマンドプロンプトで、test.dbを作成したディレクトリに移動し、softIoc を実行すると、このdbファイルの値を管理するプロセスが立ち上がる。

>softIoc -d test.db
Starting iocInit
############################################################################
## EPICS R3.15.9.1-DEV
## EPICS Base built Nov  1 2023
############################################################################
iocRun: All initialization complete

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

epics> dbl
temperature:water
epics>

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

※ WSL版だと caputではなく caset である。

> caget temperature:water
>caput temperature:water 20
Old : temperature:water              0
New : temperature:water              20

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

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

> camonitor temperature:water

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

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

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

当 Windows 環境で以下のエラーが出たのでその解決方法について書いておく。

>caget temperature:water
temperature:water              0
CA.Client.Exception...............................................
    Warning: "Identical process variable names on multiple servers"
    Context: "Channel: "temperature:water", Connecting to: XXX.XXX.XXX.XXX:5064, Ignored: hostname.mshome.net:5064"
    Source File: C:\Users\Masahiro\epics-base_v3.15\src\ca\client\cac.cpp line 1308
    Current Time: Wed Nov 01 2023 20:28:41.805707200
..................................................................

これは、複数のサーバー上で同じプロセス変数名 と言う警告であるが、チャンネルアクセス(CA) を管理しているホストに名前がついていて、IPアドレスと名前でアクセス出来る場合等に起こる現象のようである。

CHAPTER 1 Configuration

を参考に、CAのアドレスに対する環境変数を設定する。例えば、

EPICS_CA_ADDR_LIST=127.0.0.1
EPICS_CA_AUTO_ADDR_LIST=NO

とするとよい。

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

あらゆるものをWindows上で動かさないと気がすまない筆者なので、頑張ってExperimental Physics and Industrial Control System (EPICS) 7.0をWindows上で動かすことにする。

必要なアイテムは4つ

  • Windows用のmake (PATHを通す必要がある)
  • Windows用のperl
  • Visual Studio 2022 Community等
  • Windows用のGit

上記4つの準備が終わったら、Visual Studio 2022 Community 等の x64 Native Tools Command Prompt を開き、Gitで epics-base の最新版をcloneする。

> git clone --recursive https://github.com/epics-base/epics-base.git

このまま

> cd epics-base
> make

とすると途中で止まってしまう。Windows用の makeの abspath コマンドは、WindowsのC:\等を含むPATHに対するバグ(仕様)があるので、それを使ってる configure\CONFIG_BASE を修正する。

# TOOLS = $(abspath $(EPICS_BASE_HOST_BIN))
TOOLS = $(EPICS_BASE_HOST_BIN)

修正後、epics-base ディレクトリで

> make

とすると、で最後までビルド・インストールできるはずである。

C:\Users\Masahiro\epics-base でmakeした場合、以下のように環境変数を設定する。

EPICS_BASE=C:\Users\Masahiro\epics-base
EPICS_HOST_ARCH=windows-x64
PATH=C:\Users\Masahiro\epics-base\bin\windows-x64

EPICSのbaseがインストールできたか確認する。新しいコマンドプロンプトを立ち上げてsoftIoc というコマンドを実行すると、

> softIoc
epics>

「このアプリの機能のいくつかが Windows Defender ファイアウォールでブロックされています」という「Windows セキュリティの重要な警告」が出てくるはずである。他のプログラムでも同様に、各自の判断で、「アクセスを許可する」すること。

epics> と出ればインストールは成功している。Ctrl+Cでプログラムを終了させる。

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

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

例は水の温度である。

コマンドプロンプトで、test.dbを作成したディレクトリに移動し、softIoc を実行すると、このdbファイルの値を管理するプロセスが立ち上がる。

>softIoc -d test.db
Starting iocInit
############################################################################
## EPICS R7.0.7.1-DEV
## Rev. R7.0.7-183-gb41787b6bf8093caaf00-dirty
## Rev. Date Git: 2023-10-22 17:42:36 -0700
############################################################################
iocRun: All initialization complete
epics>

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

epics> dbl
temperature:water
epics>

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

※ WSL版だと caputではなく caset である。

> caget temperature:water
> caput temperature:water 20

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

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

> camonitor temperature:water

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

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

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

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

docs.epics-controls.org

Windows の インストール済み UWP アプリを表示・アンインストールする

インストール済み UWP (ユニバーサル Windows プラットフォーム) アプリ表示するPowerShell コマンド

Get-AppxPackage | Sort-Object Name | Select Name,PackageFullName

Microsoft StoreからはアンインストールできないUWPアプリをアンインストールするコマンド。 ここでは、Microsoft.Xbox.TCUIMicrosoft.XboxIdentityProviderを削除してみる。

Get-AppxPackage -Name Microsoft.Xbox.TCUI | Remove-AppxPackage
Get-AppxPackage -Name Microsoft.XboxIdentityProvider | Remove-AppxPackage

これらのアプリは一度アンインストールするとMicrosoft Storeからインストールできない。 再インストールするには、管理者権限でPowerShellを開いて以下のコマンドを実行する。

Get-AppxPackage -AllUsers | where-object { $_.name -eq 'Microsoft.XboxIdentityProvider' } | Foreach {Add-AppxPackage -DisableDevelopmentMode -Register "$($_.InstallLocation)\AppXManifest.xml"}

Get-AppxPackage -AllUsers | where-object { $_.name -eq 'Microsoft.Xbox.TCUI' } | Foreach {Add-AppxPackage -DisableDevelopmentMode -Register "$($_.InstallLocation)\AppXManifest.xml"}

なくても困りそうにないアプリ

Microsoft.MicrosoftSolitaireCollection
Microsoft.BingNews
Microsoft.BingWeather

JavaScript: 元素記号

const periodicTable = [
    "H", "He",
    "Li", "Be", "B", "C", "N", "O", "F", "Ne",
    "Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar",
    "K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr",
    "Rb", "Sr", "Y", "Zr", "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn", "Sb", "Te", "I", "Xe",
    "Cs", "Ba",
    "La", "Ce", "Pr", "Nd", "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb", "Lu",
    "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn",
    "Fr", "Ra",
    "Ac", "Th", "Pa", "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es", "Fm", "Md", "No", "Lr",
    "Rf", "Db", "Sg", "Bh", "Hs", "Mt", "Ds", "Rg", "Cn", "Nh", "Fl", "Mc", "Lv", "Ts", "Og"
];

const z2symbol = {};
const symbol2z = {};

for (let z = 1; z <= periodicTable.length; z++) {
    const symbol = periodicTable[z - 1];
    z2symbol[z] = symbol;
    symbol2z[symbol] = z;
}

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