139 lines
4.1 KiB
C++
139 lines
4.1 KiB
C++
/* 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 <pv/pvData.h>
|
|
#include <pv/pvTimeStamp.h>
|
|
#include <pv/rpcService.h>
|
|
#include <pv/convert.h>
|
|
#include <pv/standardField.h>
|
|
#define epicsExportSharedSymbols
|
|
#include "pv/pvStructureCopy.h"
|
|
#include <pv/pvSupport.h>
|
|
#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<const Scalar>(pv->getField());
|
|
if(ScalarTypeFunc::isNumeric(s->getScalarType())) {
|
|
pvValue = static_pointer_cast<PVScalar>(pv);
|
|
}
|
|
}
|
|
}
|
|
if(!pvValue) {
|
|
cout << "ControlSupport for record " << pvRecord->getRecordName()
|
|
<< " failed because not numeric scalar\n";
|
|
return false;
|
|
}
|
|
pvControl = static_pointer_cast<PVStructure>(pvsup);
|
|
if(pvControl) {
|
|
pvLimitLow = pvControl->getSubField<PVDouble>("limitLow");
|
|
pvLimitHigh = pvControl->getSubField<PVDouble>("limitHigh");
|
|
pvMinStep = pvControl->getSubField<PVDouble>("minStep");
|
|
pvOutputValue = pvControl->getSubField<PVScalar>("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(value<limitLow) {value = limitLow;setValue=true;}
|
|
}
|
|
if(setValue) convert->fromDouble(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(outputValue<value) {
|
|
outputValue = value;
|
|
isMinStep = false;
|
|
}
|
|
} else {
|
|
outputValue = currentValue + minStep;
|
|
if(limitHigh>limitLow && 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;
|
|
}
|
|
|
|
|
|
}}
|
|
|