pvDatabaseCPP  4.7.1-dev
controlSupport.cpp
Go to the documentation of this file.
1 /* controlSupport.cpp */
12 #include <pv/pvData.h>
13 #include <pv/pvTimeStamp.h>
14 #include <pv/rpcService.h>
15 #include <pv/convert.h>
16 #include <pv/standardField.h>
17 #define epicsExportSharedSymbols
18 #include "pv/pvStructureCopy.h"
19 #include <pv/pvSupport.h>
20 #include "pv/pvDatabase.h"
21 #include "pv/controlSupport.h"
22 
23 using std::tr1::static_pointer_cast;
24 using namespace epics::pvData;
25 using namespace epics::pvAccess;
26 using namespace std;
27 
28 namespace epics { namespace pvDatabase {
29 
30 ControlSupport::~ControlSupport()
31 {
32 //cout << "ControlSupport::~ControlSupport()\n";
33 }
34 
35 epics::pvData::StructureConstPtr ControlSupport::controlField(ScalarType scalarType)
36 {
37  return FieldBuilder::begin()
38  ->setId("control_t")
39  ->add("limitLow", pvDouble)
40  ->add("limitHigh", pvDouble)
41  ->add("minStep", pvDouble)
42  ->add("outputValue", scalarType)
43  ->createStructure();
44 }
45 
46 
47 ControlSupportPtr ControlSupport::create(PVRecordPtr const & pvRecord)
48 {
49  cerr << "ControlSupport IS DEPRECATED\n";
50  ControlSupportPtr support(new ControlSupport(pvRecord));
51  return support;
52 }
53 
54 ControlSupport::ControlSupport(PVRecordPtr const & pvRecord)
55  : pvRecord(pvRecord)
56 {}
57 
58 bool ControlSupport::init(PVFieldPtr const & pv,PVFieldPtr const & pvsup)
59 {
60  if(pv) {
61  if(pv->getField()->getType()==epics::pvData::scalar) {
62  ScalarConstPtr s = static_pointer_cast<const Scalar>(pv->getField());
63  if(ScalarTypeFunc::isNumeric(s->getScalarType())) {
64  pvValue = static_pointer_cast<PVScalar>(pv);
65  }
66  }
67  }
68  if(!pvValue) {
69  cout << "ControlSupport for record " << pvRecord->getRecordName()
70  << " failed because not numeric scalar\n";
71  return false;
72  }
73  pvControl = static_pointer_cast<PVStructure>(pvsup);
74  if(pvControl) {
75  pvLimitLow = pvControl->getSubField<PVDouble>("limitLow");
76  pvLimitHigh = pvControl->getSubField<PVDouble>("limitHigh");
77  pvMinStep = pvControl->getSubField<PVDouble>("minStep");
78  pvOutputValue = pvControl->getSubField<PVScalar>("outputValue");
79  }
80  if(!pvControl || !pvLimitLow || !pvLimitHigh || !pvMinStep || !pvOutputValue) {
81  cout << "ControlSupport for record " << pvRecord->getRecordName()
82  << " failed because pvSupport not a valid control structure\n";
83  return false;
84  }
85  ConvertPtr convert = getConvert();
86  currentValue = convert->toDouble(pvValue);
87  isMinStep = false;
88  return true;
89 }
90 
91 bool ControlSupport::process()
92 {
93  ConvertPtr convert = getConvert();
94  double value = convert->toDouble(pvValue);
95  if(!isMinStep && value==currentValue) return false;
96  double limitLow = pvLimitLow->get();
97  double limitHigh = pvLimitHigh->get();
98  double minStep = pvMinStep->get();
99  bool setValue = false;
100  if(limitHigh>limitLow) {
101  if(value>limitHigh) {value = limitHigh;setValue=true;}
102  if(value<limitLow) {value = limitLow;setValue=true;}
103  }
104  if(setValue) convert->fromDouble(pvValue,value);
105  double diff = value - currentValue;
106  double outputValue = value;
107  if(minStep>0.0) {
108  if(diff<0.0) {
109  outputValue = currentValue - minStep;
110  if(limitHigh>limitLow && outputValue<=limitLow) outputValue = limitLow;
111  isMinStep = true;
112  if(outputValue<value) {
113  outputValue = value;
114  isMinStep = false;
115  }
116  } else {
117  outputValue = currentValue + minStep;
118  if(limitHigh>limitLow && outputValue>=limitHigh) outputValue = limitHigh;
119  isMinStep = true;
120  if(outputValue>value) {
121  outputValue = value;
122  isMinStep = false;
123  }
124  }
125  }
126  if(outputValue==currentValue) return false;
127  currentValue = outputValue;
128  convert->fromDouble(pvOutputValue,outputValue);
129  return true;
130 }
131 
132 void ControlSupport::reset()
133 {
134  isMinStep = false;
135 }
136 
137 
138 }}
STL namespace.
std::tr1::shared_ptr< PVRecord > PVRecordPtr
Definition: pvDatabase.h:21
Base interface for a ControlSupport.
std::tr1::shared_ptr< ControlSupport > ControlSupportPtr