This is Unofficial EPICS BASE Doxygen Site
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 
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  ControlSupportPtr support(new ControlSupport(pvRecord));
50  return support;
51 }
52 
53 ControlSupport::ControlSupport(PVRecordPtr const & pvRecord)
54  : pvRecord(pvRecord)
55 {}
56 
57 bool ControlSupport::init(PVFieldPtr const & pv,PVFieldPtr const & pvsup)
58 {
59  if(pv) {
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);
64  }
65  }
66  }
67  if(!pvValue) {
68  cout << "ControlSupport for record " << pvRecord->getRecordName()
69  << " failed because not numeric scalar\n";
70  return false;
71  }
72  pvControl = static_pointer_cast<PVStructure>(pvsup);
73  if(pvControl) {
74  pvLimitLow = pvControl->getSubField<PVDouble>("limitLow");
75  pvLimitHigh = pvControl->getSubField<PVDouble>("limitHigh");
76  pvMinStep = pvControl->getSubField<PVDouble>("minStep");
77  pvOutputValue = pvControl->getSubField<PVScalar>("outputValue");
78  }
79  if(!pvControl || !pvLimitLow || !pvLimitHigh || !pvMinStep || !pvOutputValue) {
80  cout << "ControlSupport for record " << pvRecord->getRecordName()
81  << " failed because pvSupport not a valid control structure\n";
82  return false;
83  }
84  ConvertPtr convert = getConvert();
85  currentValue = convert->toDouble(pvValue);
86  isMinStep = false;
87  return true;
88 }
89 
90 bool ControlSupport::process()
91 {
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;}
102  }
103  if(setValue) convert->fromDouble(pvValue,value);
104  double diff = value - currentValue;
105  double outputValue = value;
106  if(minStep>0.0) {
107  if(diff<0.0) {
108  outputValue = currentValue - minStep;
109  if(limitHigh>limitLow && outputValue<=limitLow) outputValue = limitLow;
110  isMinStep = true;
111  if(outputValue<value) {
112  outputValue = value;
113  isMinStep = false;
114  }
115  } else {
116  outputValue = currentValue + minStep;
117  if(limitHigh>limitLow && outputValue>=limitHigh) outputValue = limitHigh;
118  isMinStep = true;
119  if(outputValue>value) {
120  outputValue = value;
121  isMinStep = false;
122  }
123  }
124  }
125  if(outputValue==currentValue) return false;
126  currentValue = outputValue;
127  convert->fromDouble(pvOutputValue,outputValue);
128  return true;
129 }
130 
131 void ControlSupport::reset()
132 {
133  isMinStep = false;
134 }
135 
136 
137 }}
FORCE_INLINE std::tr1::shared_ptr< PVField > getSubField(A a)
Definition: pvData.h:744
This class implements introspection object for Scalar.
Definition: pvIntrospect.h:397
Definition: link.h:174
PVScalar is the base class for each scalar field.
Definition: pvData.h:272
Definition: tool_lib.h:67
shared_ptr< T > static_pointer_cast(shared_ptr< U > const &r) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:788
Definition: memory.hpp:41
TODO only here because of the Lockable.
Definition: ntaggregate.cpp:16
std::tr1::shared_ptr< const Structure > StructureConstPtr
Definition: pvIntrospect.h:162
std::tr1::shared_ptr< const Scalar > ScalarConstPtr
Definition: pvIntrospect.h:150
Holds all PVA related.
Definition: pvif.h:34
pvData
Definition: monitor.h:428
bool isNumeric(ScalarType type)
Definition: TypeFunc.cpp:53
Data interface for a structure,.
Definition: pvData.h:712
std::tr1::shared_ptr< PVRecord > PVRecordPtr
Definition: pvDatabase.h:21
Class that holds the data for each possible scalar type.
Definition: pvData.h:54
std::tr1::shared_ptr< PVField > PVFieldPtr
Definition: pvData.h:66
Base interface for a ControlSupport.
std::tr1::shared_ptr< ControlSupport > ControlSupportPtr
std::tr1::shared_ptr< Convert > ConvertPtr
Definition: convert.h:23
static FieldBuilderPtr begin()