/* controlSupport.cpp */ /** * Copyright - See the COPYRIGHT that is included with this distribution. * EPICS pvData is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. */ /** * @author mrk * @date 2019.06.01 */ #include #include #include #include #include #define epicsExportSharedSymbols #include "pv/pvStructureCopy.h" #include #include "pv/pvDatabase.h" #include "pv/controlSupport.h" using std::tr1::static_pointer_cast; using namespace epics::pvData; using namespace epics::pvAccess; using namespace std; namespace epics { namespace pvDatabase { ControlSupport::~ControlSupport() { //cout << "ControlSupport::~ControlSupport()\n"; } epics::pvData::StructureConstPtr ControlSupport::controlField(ScalarType scalarType) { return FieldBuilder::begin() ->setId("control_t") ->add("limitLow", pvDouble) ->add("limitHigh", pvDouble) ->add("minStep", pvDouble) ->add("outputValue", scalarType) ->createStructure(); } ControlSupportPtr ControlSupport::create(PVRecordPtr const & pvRecord) { ControlSupportPtr support(new ControlSupport(pvRecord)); return support; } ControlSupport::ControlSupport(PVRecordPtr const & pvRecord) : pvRecord(pvRecord) {} bool ControlSupport::init(PVFieldPtr const & pv,PVFieldPtr const & pvsup) { if(pv) { if(pv->getField()->getType()==epics::pvData::scalar) { ScalarConstPtr s = static_pointer_cast(pv->getField()); if(ScalarTypeFunc::isNumeric(s->getScalarType())) { pvValue = static_pointer_cast(pv); } } } if(!pvValue) { cout << "ControlSupport for record " << pvRecord->getRecordName() << " failed because not numeric scalar\n"; return false; } pvControl = static_pointer_cast(pvsup); if(pvControl) { pvLimitLow = pvControl->getSubField("limitLow"); pvLimitHigh = pvControl->getSubField("limitHigh"); pvMinStep = pvControl->getSubField("minStep"); pvOutputValue = pvControl->getSubField("outputValue"); } if(!pvControl || !pvLimitLow || !pvLimitHigh || !pvMinStep || !pvOutputValue) { cout << "ControlSupport for record " << pvRecord->getRecordName() << " failed because pvSupport not a valid control structure\n"; return false; } ConvertPtr convert = getConvert(); currentValue = convert->toDouble(pvValue); isMinStep = false; return true; } bool ControlSupport::process() { ConvertPtr convert = getConvert(); double value = convert->toDouble(pvValue); if(!isMinStep && value==currentValue) return false; double limitLow = pvLimitLow->get(); double limitHigh = pvLimitHigh->get(); double minStep = pvMinStep->get(); bool setValue = false; if(limitHigh>limitLow) { if(value>limitHigh) {value = limitHigh;setValue=true;} if(valuefromDouble(pvValue,value); double diff = value - currentValue; double outputValue = value; if(minStep>0.0) { if(diff<0.0) { outputValue = currentValue - minStep; if(limitHigh>limitLow && outputValue<=limitLow) outputValue = limitLow; isMinStep = true; if(outputValuelimitLow && outputValue>=limitHigh) outputValue = limitHigh; isMinStep = true; if(outputValue>value) { outputValue = value; isMinStep = false; } } } if(outputValue==currentValue) return false; currentValue = outputValue; convert->fromDouble(pvOutputValue,outputValue); return true; } void ControlSupport::reset() { isMinStep = false; } }}