EPICSPVAInput
Warning
The EPICSPVAInput DataSource is only available in distributions where EPICS Channel Access is installed.
The EPICSPVAInput DataSource can be used to receive application data using the EPICS pvAccess protocol. This allows interfacing the application with any EPICS-based monitoring or control application (e.g. EPICS Control System Studio).
This DataSource reads from the PVA records asynchronously on a separate thread (which may be allocated to a different CPU core). This means that it is not intended to be used for real-time control, but rather for live parameter configuration.
The names of the PVs need to be defined for every signal in the DataSource configuration.
Given that the PVA record names need to be unique, in order to avoid name clashes, the configuration file ../Configurations/MassSpring/RTApp-MassSpring-36.cfg will be automatically updated from a Makefile.cfg. The names of the PV records are based on the username.
The PV records are hosted using a MARTe2 EPICSPVADatabase, which in this example is instantiated in the same configuration file as the application.
Makefile.cfg. 1+EPICSPVADatabase = {
2 Class = EPICSPVA::EPICSPVADatabase
3 StackSize = 1048576
4 CPUs = 0x1
5 AutoStart = 1
6 +AppControlMonitor = {
7 Class = EPICSPVA::EPICSPVARecord
8 +AppControlInput = {
9 Class = EPICSPVA::EPICSPVARecord
10 Alias = XSTR(MARTE2-TUTORIAL-USERNAME-MASS-SPRING-CONTROL-INPUT)
11 Structure = {
12 value = {
13 Type = ControlInput
14 NumberOfElements = 1
15 }
16 }
17 }
In this example, the ReferencePosition signal is read from a PVA record and used as the reference for the control of the mass-spring system.
Alias field to access the signal directly from the DataSource without the need to copy the full structure. 1 +GAMReference = {
2 Class = IOGAM
3 InputSignals = {
4 ReferencePosition = {
5 DataSource = EPICSPVAReader
6 Type = float64
7 Alias = "ControlIn.ReferencePosition"
8 }
9 }
10 OutputSignals = {
11 ReferencePosition = {
12 DataSource = DDB1
13 Type = float64
14 }
15 }
16 }
Makefile.cfg. 1 +EPICSPVAReader = {
2 Class = EPICSPVADataSource::EPICSPVAInput
3 CPUMask = 0x1
4 StackSize = 10000000
5 Signals = {
6 ControlIn = {
7 Alias = XSTR(MARTE2-TUTORIAL-USERNAME-MASS-SPRING-CONTROL-INPUT)
8 Field = "value"
9 Type = ControlInput
10 }
11 }
12 }
Running the application
make -C ../Configurations/MassSpring/ -f Makefile.cfg
./MARTeApp.sh -f ../Configurations/MassSpring/RTApp-MassSpring-38_Gen.cfg -l RealTimeLoader -s State1
Once the application is running, inspect the screen output and verify that it is running without any issues. The log should show entries similar to the following:
...
$ [Debug - EPICSPVAChannelWrapper.cpp:362]: Resolving scalar (or array of) [value.Control.Thread1.GAMsExecutionTime]
$ [Debug - EPICSPVAChannelWrapper.cpp:373]: Assigned PV to signal with name [value.Control.Thread1.GAMsExecutionTime]
$ [Information - LoggerBroker.cpp:152]: Time [0:0]:1000000
$ [Information - LoggerBroker.cpp:152]: Time [0:0]:2000000
...
Open another terminal and check that the PVA records are being updated with the application data using the command:
pvget -m MARTE2-TUTORIAL-USERNAME-MASS-SPRING-CONTROL # Replace with your username in capital letters
The output should be similar to the following:
$ MARTE2-TUTORIAL-USERNAME-MASS-SPRING-CONTROL structure
$ MonitorControl value
$ uint Time 38650000
$ ControlParameters Control
$ double ReferencePosition 0
$ double Position 3.15283e-14
$ double PositionDisturbed 5.46623e-14
$ double PositionFiltered 2.90153e-13
$ double PositionM 3.99788e-09
$ double Velocity -2.95341e-12
$ double VelocityM 1.85333e-09
$ double PositionErr 2.90153e-13
$ double Force -6.71745e-11
$ double ForceAverage -6.60828e-17
$ double ForceStdDev 2.22174e-08
$ double ForceMax 2.23554e-10
$ double ForceMin -2.23302e-10
...
Open another terminal and modify the value of the ReferencePosition PVA record using the command:
pvput MARTE2-TUTORIAL-USERNAME-MASS-SPRING-CONTROL-INPUT value='{"ReferencePosition":1.0}' #Replace with your username in capital letters
Open another terminal and check that the PVA record is being updated with the application data using the command:
pvget -m MARTE2-TUTORIAL-USERNAME-MASS-SPRING-CONTROL #Replace with your username in capital letters
The output should be similar to the following:
$ MARTE2-TUTORIAL-USERNAME-MASS-SPRING-CONTROL structure
$ MonitorControl value
$ uint Time 177230000
$ ControlParameters Control
$ double ReferencePosition 1
$ double Position 0.996746
$ double PositionDisturbed 1.00621
$ double PositionFiltered 0.996685
$ double PositionM 0.993831
$ double Velocity 0.00478432
$ double VelocityM 0.0349763
$ double PositionErr -0.00331458
$ double Force 9.9693
$ double ForceAverage 10.0853
$ double ForceStdDev 0.152168
$ double ForceMax 10.489
$ double ForceMin 9.96202
Exercises
Ex. 1: Switch on/off
The objective of this exercise is to use the EPICSPVAInput DataSource to switch the force output of the mass-spring system on and off.
Edit the file
../Configurations/MassSpring/RTApp-MassSpring-39.cfgand add a MuxGAM that selects between the signalsForceZeroandForceFromControllerto produce an output signal namedForceinDDB1. Name this GAMGAMMuxSwitchOn.Modify the
ControllerGAMto output the signal namedForceFromControllerinstead ofForce.Modify the
ReferenceGAMto read the full structure from the EPICSCAInput DataSource and copy both theReferencePositionand theSwitchOnsignal toDDB1.Add the MuxGAM to the execution list.
Execute the application:
make -C ../Configurations/MassSpring/ -f Makefile.cfg
./MARTeApp.sh -f ../Configurations/MassSpring/RTApp-MassSpring-39_Gen.cfg -l RealTimeLoader -s State1
Set a new target
ReferencePositionusing thepvputcommand.
pvput MARTE2-TUTORIAL-USERNAME-MASS-SPRING-CONTROL-INPUT value='{"ReferencePosition":1.0}' #Replace with your username in capital letters
Observe that the
Positionis not changing and that the system is not responding to the new targetReferencePosition.
pvget -m MARTE2-TUTORIAL-USERNAME-MASS-SPRING-CONTROL #Replace with your username in capital letters
Switch on the system by setting the switch on-off PV to 1 using the command:
pvput MARTE2-TUTORIAL-USERNAME-MASS-SPRING-CONTROL-INPUT value='{"SwitchOn":1}' #Replace with your username in capital letters
Observe that the
Positionis now changing and that the system is responding to the new targetReferencePosition.
pvget -m MARTE2-TUTORIAL-USERNAME-MASS-SPRING-CONTROL #Replace with your username in capital letters
Solution
The solution is to add a MuxGAM as specified above.
1 +GAMMuxSwitchOn = {
2 Class = MuxGAM
3 InputSignals = {
4 SwitchOn = {
5 DataSource = DDB1
6 Type = uint32
7 NumberOfDimensions = 1
8 NumberOfElements = 1
9 }
10 ForceZero = {
11 DataSource = DDB1
12 Type = float64
13 NumberOfDimensions = 1
14 NumberOfElements = 1
15 }
16 ForceFromController = {
17 DataSource = DDB1
18 Type = float64
19 NumberOfDimensions = 1
20 NumberOfElements = 1
21 }
22 }
23 OutputSignals = {
24 Force = {
25 DataSource = DDB1
26 Type = float64
27 NumberOfDimensions = 1
28 NumberOfElements = 1
29 }
30 }
31 }
Update the GAMReference to read both signals from the DataSource.
1 +GAMReference = {
2 Class = IOGAM
3 InputSignals = {
4 ControlIn = {
5 DataSource = EPICSPVAReader
6 Type = ControlInput
7 }
8 }
9 OutputSignals = {
10 ReferencePosition = {
11 DataSource = DDB1
12 Type = float64
13 }
14 SwitchOn = {
15 DataSource = DDB1
16 Type = uint32
17 }
18 }
19 }
Note
The Alias could also have been used to access the signals directly from the DataSource in the MuxGAM without copying the full structure in ReferenceGAM.
However, the MuxGAM requires the signal to have NumberOfDimensions=1, while the structured signal read from the DataSource has NumberOfDimensions=0, and even if they are binary compatible (array of one element and scalar), another GAM to covert between them would be needed, which would make the configuration more complex.
Add the GAM to the execution list.
1 +States = {
2 Class = ReferenceContainer
3 +State1 = {
4 Class = RealTimeState
5 +Threads = {
6 Class = ReferenceContainer
7 +Thread1 = {
8 Class = RealTimeThread
9 CPUs = 0x1
10 Functions = {GAMPerfMonitor GAMTimer GAMReference GAMDisturbanceWaveform GAMMathDisturbance GAMFilterDisturbance GAMController GAMConstantZero GAMMuxSwitchOn GAMSpringMass GAMMathModel GAMMathPositionErr GAMStats GAMPatchForceDims GAMForceStats GAMHist GAMMathExpr GAMConversion GAMFilterMovingAvg GAMMathTrigger GAMMathTriggerSecond GAMDisplay GAMWriter}
11 }
12 }
13 }
14 }