Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
3-Add-simulated-motors.md 13.72 KiB

IOC Deployment and Troubleshooting

[previous section] [next section]

3 Add simulated motors to the IOC

IOCs based on xxx already include support for simulated motors by default, so only the IOC's run-time config needs to be modified to add simulated motors.

3.1 Make a copy of the motors.iocsh example

$ cd ${IOC_DIR}/xxx/iocBoot/iocxxx
$ mkdir iocsh
$ cp -p examples/motors.iocsh iocsh

3.2 Customize the simulated motor config

3.2.1 Edit iocsh/motor.iocsh

$ gedit iocsh/motors.iocsh &

Make the following changes:

  • comment out motor.substitutions
  • uncomment motorSim.iocsh
  • reduce the number of axes to 8
hint

The comment character is #. Lines that start with the comment character are ignored.

solution
diff --git a/iocBoot/iocxxx/iocsh/motors.iocsh b/iocBoot/iocxxx/iocsh/motors.iocsh
index 34998d9..273bea4 100644
--- a/iocBoot/iocxxx/iocsh/motors.iocsh
+++ b/iocBoot/iocxxx/iocsh/motors.iocsh
@@ -1,9 +1,9 @@
 # Motors
-dbLoadTemplate("substitutions/motor.substitutions", "P=$(PREFIX)")
+#dbLoadTemplate("substitutions/motor.substitutions", "P=$(PREFIX)")
 #dbLoadTemplate("substitutions/softMotor.substitutions", "P=$(PREFIX)")
 #dbLoadTemplate("substitutions/pseudoMotor.substitutions", "P=$(PREFIX)")
 
-#iocshLoad("$(MOTOR)/iocsh/motorSim.iocsh", "INSTANCE=motorSim, HOME_POS=0, NUM_AXES=16, HIGH_LIM=32000, LOW_LIM=-32000, SUB=substitutions/motorSim.substitutions")
+iocshLoad("$(MOTOR)/iocsh/motorSim.iocsh", "INSTANCE=motorSim, HOME_POS=0, NUM_AXES=8, HIGH_LIM=32000, LOW_LIM=-32000, SUB=substitutions/motorSim.substitutions")
 
 # Allstop, alldone
 iocshLoad("$(MOTOR)/iocsh/allstop.iocsh", "P=$(PREFIX)")
what does this mean?

The motorSim.iocsh script will be loaded when the motors.iocsh script is run, and the controller instance defined in the motorSim.iocsh script will be set up with the specified parameters (instance name, home position, number of axes, high and low limits, and substitution definitions). This is useful for running a simulation of your motor system for testing or development purposes.

3.2.2 Edit substitutions/motorSim.substitutions

$ gedit substitutions/motorSim.substitutions &

Make the following change:

  • comment out motors 9-16
hint

The comment character is #. Lines that start with the comment character are ignored.

An old BCDA convention is to use #! to comment out lines that can be uncommented and # for actual comments. It is not necessary to follow this convention.

solution
diff --git a/iocBoot/iocxxx/substitutions/motorSim.substitutions b/iocBoot/iocxxx/substitutions/motorSim.substitutions
index 909c067..3d17e23 100644
--- a/iocBoot/iocxxx/substitutions/motorSim.substitutions
+++ b/iocBoot/iocxxx/substitutions/motorSim.substitutions
@@ -10,12 +10,12 @@ pattern
 {6,  "m$(N)",  5,  "motor $(N)",  degrees,  Pos,  1,     .1,    .2,    0,     1,     .2,    0.01,  5, ""}
 {7,  "m$(N)",  6,  "motor $(N)",  degrees,  Pos,  1,     .1,    .2,    0,     1,     .2,    0.01,  5, ""}
 {8,  "m$(N)",  7,  "motor $(N)",  degrees,  Pos,  1,     .1,    .2,    0,     1,     .2,    0.01,  5, ""}
-{9,  "m$(N)",  8,  "motor $(N)",  degrees,  Pos,  1,     .1,    .2,    0,     1,     .2,    0.01,  5, ""}
-{10,  "m$(N)",  9,  "motor $(N)",  degrees,  Pos,  1,     .1,    .2,    0,     1,     .2,    0.01,  5, ""}
-{11,  "m$(N)",  10,  "motor $(N)",  degrees,  Pos,  1,     .1,    .2,    0,     1,     .2,    0.01,  5, ""}
-{12,  "m$(N)",  11,  "motor $(N)",  degrees,  Pos,  1,     .1,    .2,    0,     1,     .2,    0.01,  5, ""}
-{13,  "m$(N)",  12,  "motor $(N)",  degrees,  Pos,  1,     .1,    .2,    0,     1,     .2,    0.01,  5, ""}
-{14,  "m$(N)",  13,  "motor $(N)",  degrees,  Pos,  1,     .1,    .2,    0,     1,     .2,    0.01,  5, ""}
-{15,  "m$(N)",  14,  "motor $(N)",  degrees,  Pos,  1,     .1,    .2,    0,     1,     .2,    0.01,  5, ""}
-{16,  "m$(N)",  15,  "motor $(N)",  degrees,  Pos,  1,     .1,    .2,    0,     1,     .2,    0.01,  5, ""}
+#!{9,  "m$(N)",  8,  "motor $(N)",  degrees,  Pos,  1,     .1,    .2,    0,     1,     .2,    0.01,  5, ""}
+#!{10,  "m$(N)",  9,  "motor $(N)",  degrees,  Pos,  1,     .1,    .2,    0,     1,     .2,    0.01,  5, ""}
+#!{11,  "m$(N)",  10,  "motor $(N)",  degrees,  Pos,  1,     .1,    .2,    0,     1,     .2,    0.01,  5, ""}
+#!{12,  "m$(N)",  11,  "motor $(N)",  degrees,  Pos,  1,     .1,    .2,    0,     1,     .2,    0.01,  5, ""}
+#!{13,  "m$(N)",  12,  "motor $(N)",  degrees,  Pos,  1,     .1,    .2,    0,     1,     .2,    0.01,  5, ""}
+#!{14,  "m$(N)",  13,  "motor $(N)",  degrees,  Pos,  1,     .1,    .2,    0,     1,     .2,    0.01,  5, ""}
+#!{15,  "m$(N)",  14,  "motor $(N)",  degrees,  Pos,  1,     .1,    .2,    0,     1,     .2,    0.01,  5, ""}
+#!{16,  "m$(N)",  15,  "motor $(N)",  degrees,  Pos,  1,     .1,    .2,    0,     1,     .2,    0.01,  5, ""}
 }

3.2.3 Edit st.cmd.Linux:

$ gedit st.cmd.Linux &

Make the following change:

  • source iocsh/motors.iocsh
hint

st.cmd.Linux already sources settings.iocsh, override.iocsh, and common.iocsh, all of which reside in the startup directory.

solution
diff --git a/iocBoot/iocxxx/st.cmd.Linux b/iocBoot/iocxxx/st.cmd.Linux
index 588dda7..8fddfc1 100644
--- a/iocBoot/iocxxx/st.cmd.Linux
+++ b/iocBoot/iocxxx/st.cmd.Linux
@@ -15,6 +15,8 @@ iocxxxLinux_registerRecordDeviceDriver(pdbbase)
 < override.iocsh
 < common.iocsh
 
+< iocsh/motors.iocsh
+
 #- devIocStats
 dbLoadRecords("$(DEVIOCSTATS)/db/iocAdminSoft.db","IOC=$(PREFIX)")
 #- PV aliases change :: into :
what does this mean?

The st.cmd.Linux file is the IOC startup script which is responsible for initializing the EPICS environment, loading database definitions, and starting the IOC. The command < iocsh/motors.iocsh is used to execute the motors.iocsh script in the current shell environment. After you make this modification and run the startup script, it will execute the commands in motors.iocsh as part of the IOC startup process, setting up the motor instance as specified in the motors.iocsh file.

3.3 Run the IOC

Start the IOC in a screen session:

$ ./softioc/xxx.sh start
output
Starting xxx

Confirm that the IOC is running:

$ ./softioc/xxx.sh status
output
xxx is running (pid=1914250) in a screen session (pid=1914249)

Connect to the IOC's console:

$ ./softioc/xxx.sh console

Confirm that motor records are loaded:

kmp> dbl "motor"
output
kmp> dbl "motor"
kmp:m1
kmp:m2
kmp:m3
kmp:m4
kmp:m5
kmp:m6
kmp:m7
kmp:m8
kmp> 

Disconnect from the IOC's shell by typing ctrl+a, ctrl+d

Confirm that motor settings are being saved

$ grep motor autosave/built_*.req
what does grep mean?

The command grep motor autosave/built_*.req searches for the string "motor" within the contents of files that match the pattern autosave/built_*.req.

output
autosave/built_positions.req:file asyn_motor_positions.req P=kmp:,N=1,M="m1",DTYP="asynMotor",PORT=VMC1,ADDR=0,DESC="motor 1",EGU=mm,DIR=Pos,VELO=1,VBAS=.1,ACCL=.2,BDST=0,BVEL=1,BACC=.2,MRES=0.0025,PREC=4,DHLM=100,DLLM=-100,INIT=""
autosave/built_positions.req:file asyn_motor_positions.req P=kmp:,N=2,M="m2",DTYP="asynMotor",PORT=VMC1,ADDR=1,DESC="motor 2",EGU=mm,DIR=Pos,VELO=1,VBAS=.1,ACCL=.2,BDST=0,BVEL=1,BACC=.2,MRES=0.0025,PREC=4,DHLM=100,DLLM=-100,INIT=""
autosave/built_positions.req:file asyn_motor_positions.req P=kmp:,N=3,M="m3",DTYP="asynMotor",PORT=VMC1,ADDR=2,DESC="motor 3",EGU=mm,DIR=Pos,VELO=1,VBAS=.1,ACCL=.2,BDST=0,BVEL=1,BACC=.2,MRES=0.0025,PREC=4,DHLM=100,DLLM=-100,INIT=""
autosave/built_positions.req:file asyn_motor_positions.req P=kmp:,N=4,M="m4",DTYP="asynMotor",PORT=VMC1,ADDR=3,DESC="motor 4",EGU=deg,DIR=Pos,VELO=1,VBAS=.1,ACCL=.2,BDST=0,BVEL=1,BACC=.2,MRES=0.01,PREC=4,DHLM=100,DLLM=-100,INIT=""
autosave/built_positions.req:file asyn_motor_positions.req P=kmp:,N=5,M="m5",DTYP="asynMotor",PORT=VMC1,ADDR=4,DESC="motor 5",EGU=deg,DIR=Pos,VELO=1,VBAS=.1,ACCL=.2,BDST=0,BVEL=1,BACC=.2,MRES=0.01,PREC=4,DHLM=100,DLLM=-100,INIT=""
autosave/built_positions.req:file asyn_motor_positions.req P=kmp:,N=6,M="m6",DTYP="asynMotor",PORT=VMC1,ADDR=5,DESC="motor 6",EGU=deg,DIR=Pos,VELO=1,VBAS=.1,ACCL=.2,BDST=0,BVEL=1,BACC=.2,MRES=0.01,PREC=4,DHLM=100,DLLM=-100,INIT=""
autosave/built_positions.req:file asyn_motor_positions.req P=kmp:,N=7,M="m7",DTYP="asynMotor",PORT=VMC1,ADDR=6,DESC="motor 7",EGU=deg,DIR=Pos,VELO=1,VBAS=.1,ACCL=.2,BDST=0,BVEL=1,BACC=.2,MRES=0.01,PREC=4,DHLM=100,DLLM=-100,INIT=""
autosave/built_positions.req:file asyn_motor_positions.req P=kmp:,N=8,M="m8",DTYP="asynMotor",PORT=VMC1,ADDR=7,DESC="motor 8",EGU=deg,DIR=Pos,VELO=1,VBAS=.1,ACCL=.2,BDST=0,BVEL=1,BACC=.2,MRES=0.01,PREC=4,DHLM=100,DLLM=-100,INIT=""
autosave/built_settings.req:file asyn_motor_settings.req P=kmp:,N=1,M="m1",DTYP="asynMotor",PORT=VMC1,ADDR=0,DESC="motor 1",EGU=mm,DIR=Pos,VELO=1,VBAS=.1,ACCL=.2,BDST=0,BVEL=1,BACC=.2,MRES=0.0025,PREC=4,DHLM=100,DLLM=-100,INIT=""
autosave/built_settings.req:file asyn_motor_settings.req P=kmp:,N=2,M="m2",DTYP="asynMotor",PORT=VMC1,ADDR=1,DESC="motor 2",EGU=mm,DIR=Pos,VELO=1,VBAS=.1,ACCL=.2,BDST=0,BVEL=1,BACC=.2,MRES=0.0025,PREC=4,DHLM=100,DLLM=-100,INIT=""
autosave/built_settings.req:file asyn_motor_settings.req P=kmp:,N=3,M="m3",DTYP="asynMotor",PORT=VMC1,ADDR=2,DESC="motor 3",EGU=mm,DIR=Pos,VELO=1,VBAS=.1,ACCL=.2,BDST=0,BVEL=1,BACC=.2,MRES=0.0025,PREC=4,DHLM=100,DLLM=-100,INIT=""
autosave/built_settings.req:file asyn_motor_settings.req P=kmp:,N=4,M="m4",DTYP="asynMotor",PORT=VMC1,ADDR=3,DESC="motor 4",EGU=deg,DIR=Pos,VELO=1,VBAS=.1,ACCL=.2,BDST=0,BVEL=1,BACC=.2,MRES=0.01,PREC=4,DHLM=100,DLLM=-100,INIT=""
autosave/built_settings.req:file asyn_motor_settings.req P=kmp:,N=5,M="m5",DTYP="asynMotor",PORT=VMC1,ADDR=4,DESC="motor 5",EGU=deg,DIR=Pos,VELO=1,VBAS=.1,ACCL=.2,BDST=0,BVEL=1,BACC=.2,MRES=0.01,PREC=4,DHLM=100,DLLM=-100,INIT=""
autosave/built_settings.req:file asyn_motor_settings.req P=kmp:,N=6,M="m6",DTYP="asynMotor",PORT=VMC1,ADDR=5,DESC="motor 6",EGU=deg,DIR=Pos,VELO=1,VBAS=.1,ACCL=.2,BDST=0,BVEL=1,BACC=.2,MRES=0.01,PREC=4,DHLM=100,DLLM=-100,INIT=""
autosave/built_settings.req:file asyn_motor_settings.req P=kmp:,N=7,M="m7",DTYP="asynMotor",PORT=VMC1,ADDR=6,DESC="motor 7",EGU=deg,DIR=Pos,VELO=1,VBAS=.1,ACCL=.2,BDST=0,BVEL=1,BACC=.2,MRES=0.01,PREC=4,DHLM=100,DLLM=-100,INIT=""
autosave/built_settings.req:file asyn_motor_settings.req P=kmp:,N=8,M="m8",DTYP="asynMotor",PORT=VMC1,ADDR=7,DESC="motor 8",EGU=deg,DIR=Pos,VELO=1,VBAS=.1,ACCL=.2,BDST=0,BVEL=1,BACC=.2,MRES=0.01,PREC=4,DHLM=100,DLLM=-100,INIT=""

3.4 Launch motor screen

Do the following:

  1. Launch caQtDM if it isn't already running
$ ./softioc/xxx.sh caqtdm

If the EPICS_HOST_ARCH is rhel9-x86_64 and caQtDM is not found, then do the following:

workaround

bash

$ sed -i.bak -e 's/APSshare\/bin\/caQtDM/APSshare\/caqtdm\/caqtdm-4.4.0-APS\/caQtDM_Binaries\/rhel9-x86_64\/caQtDM/g' ../../start_caQtDM_xxx

And then restart caqtdm:

$ ./softioc/xxx.sh caqtdm