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 23 using std::tr1::static_pointer_cast;
28 namespace epics {
namespace pvDatabase {
30 ControlSupport::~ControlSupport()
35 epics::pvData::StructureConstPtr ControlSupport::controlField(ScalarType scalarType)
37 return FieldBuilder::begin()
39 ->add(
"limitLow", pvDouble)
40 ->add(
"limitHigh", pvDouble)
41 ->add(
"minStep", pvDouble)
42 ->add(
"outputValue", scalarType)
53 ControlSupport::ControlSupport(
PVRecordPtr const & pvRecord)
57 bool ControlSupport::init(PVFieldPtr
const & pv,PVFieldPtr
const & pvsup)
60 if(pv->getField()->getType()==epics::pvData::scalar) {
61 ScalarConstPtr s = static_pointer_cast<
const Scalar>(pv->getField());
62 if(ScalarTypeFunc::isNumeric(s->getScalarType())) {
63 pvValue = static_pointer_cast<PVScalar>(pv);
68 cout <<
"ControlSupport for record " << pvRecord->getRecordName()
69 <<
" failed because not numeric scalar\n";
72 pvControl = static_pointer_cast<PVStructure>(pvsup);
74 pvLimitLow = pvControl->getSubField<PVDouble>(
"limitLow");
75 pvLimitHigh = pvControl->getSubField<PVDouble>(
"limitHigh");
76 pvMinStep = pvControl->getSubField<PVDouble>(
"minStep");
77 pvOutputValue = pvControl->getSubField<PVScalar>(
"outputValue");
79 if(!pvControl || !pvLimitLow || !pvLimitHigh || !pvMinStep || !pvOutputValue) {
80 cout <<
"ControlSupport for record " << pvRecord->getRecordName()
81 <<
" failed because pvSupport not a valid control structure\n";
84 ConvertPtr convert = getConvert();
85 currentValue = convert->toDouble(pvValue);
90 bool ControlSupport::process()
92 ConvertPtr convert = getConvert();
93 double value = convert->toDouble(pvValue);
94 if(!isMinStep && value==currentValue)
return false;
95 double limitLow = pvLimitLow->get();
96 double limitHigh = pvLimitHigh->get();
97 double minStep = pvMinStep->get();
98 bool setValue =
false;
99 if(limitHigh>limitLow) {
100 if(value>limitHigh) {value = limitHigh;setValue=
true;}
101 if(value<limitLow) {value = limitLow;setValue=
true;}
103 if(setValue) convert->fromDouble(pvValue,value);
104 double diff = value - currentValue;
105 double outputValue = value;
108 outputValue = currentValue - minStep;
109 if(limitHigh>limitLow && outputValue<=limitLow) outputValue = limitLow;
111 if(outputValue<value) {
116 outputValue = currentValue + minStep;
117 if(limitHigh>limitLow && outputValue>=limitHigh) outputValue = limitHigh;
119 if(outputValue>value) {
125 if(outputValue==currentValue)
return false;
126 currentValue = outputValue;
127 convert->fromDouble(pvOutputValue,outputValue);
131 void ControlSupport::reset()
std::tr1::shared_ptr< PVRecord > PVRecordPtr
Base interface for a ControlSupport.
std::tr1::shared_ptr< ControlSupport > ControlSupportPtr