Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.

IOC Deployment and Troubleshooting

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)")

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 :

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
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

This launches my-xxx.ui:

screenshot of my-xxx.ui showing the default Motors section

  1. Click the Motors 1-8 button on my-xxx.ui

This launches topMotors8.ui:

screenshot of topMotors8.ui

  1. From the m1 menu of topMotors8.ui, choose m1 (Debug)

This launches motorx_all.ui:

screenshot of motorx_all.ui

3.5 Move motors

Move motors using the caQtDM screens.

3.6 Remove simulated motors

Simulated motors behave like real motors, but they don't misbehave like real motors, so we'll remove them for now.

3.6.1 Stop the IOC

$ ./softioc/xxx.sh stop
output
Stopping xxx (pid=1914250)

3.6.2 Edit iocsh/motor.iocsh

$ gedit iocsh/motors.iocsh &

Make the following change:

  • comment out motorSim.iocsh
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 273bea4..ce924c3 100644
--- a/iocBoot/iocxxx/iocsh/motors.iocsh
+++ b/iocBoot/iocxxx/iocsh/motors.iocsh
@@ -3,7 +3,7 @@
 #dbLoadTemplate("substitutions/softMotor.substitutions", "P=$(PREFIX)")
 #dbLoadTemplate("substitutions/pseudoMotor.substitutions", "P=$(PREFIX)")
 
-iocshLoad("$(MOTOR)/iocsh/motorSim.iocsh", "INSTANCE=motorSim, HOME_POS=0, NUM_AXES=8, 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)")

3.6.3 Run the IOC

We run the IOC at this point to confirm the simulated motors have been removed.

$ ./softioc/xxx.sh run

Things to do:

  • see dbFindRecord messages at init

3.6.4 Stop the IOC

Exit the IOC from the IOC shell:

kmp> exit

Note: typing ctrl+c will also stop the IOC.

Things to do:

  • see no motor references in autosave/built_*.req

4 Deploy the motorVMC (Virtual Motor Controller) module