Commit 6ded7af6 authored by ics's avatar ics

Add IN5 Cryogenic magnetic field driver

parent 5b42a19d
......@@ -40,6 +40,7 @@ const string MagneticFieldCommon::HOUR_UNIT = "h";
const string MagneticFieldCommon::IPS120_TYPE = "ips120";
const string MagneticFieldCommon::MERCURY_TYPE = "mercury";
const string MagneticFieldCommon::SMS_TYPE = "sms";
/*
* Constructor
......
......@@ -128,6 +128,7 @@ public:
//! driver type
static const std::string IPS120_TYPE;
static const std::string MERCURY_TYPE;
static const std::string SMS_TYPE;
private:
......
......@@ -75,6 +75,7 @@ MagneticFieldController::MagneticFieldController(const string& name) :
m_OldDriver.init(this, "driver");
m_NewDriver.init(this, "new_driver");
m_SmsDriver.init(this, "sms_driver");
registerFunction(TYPE);
......@@ -411,10 +412,17 @@ void MagneticFieldController::setEnabledForLoading(bool all, bool postconf) {
if (driverType() == MagneticFieldCommon::MERCURY_TYPE) {
m_Driver.assign(dynamic_cast<TestController*>(*m_NewDriver.getControllerPointer()));
addExcludeSetEnableController(m_OldDriver.getRole());
addExcludeSetEnableController(m_SmsDriver.getRole());
}
else if (driverType() == MagneticFieldCommon::SMS_TYPE) {
m_Driver.assign(dynamic_cast<TestController*>(*m_SmsDriver.getControllerPointer()));
addExcludeSetEnableController(m_OldDriver.getRole());
addExcludeSetEnableController(m_NewDriver.getRole());
}
else {
m_Driver.assign(dynamic_cast<TestController*>(*m_OldDriver.getControllerPointer()));
addExcludeSetEnableController(m_NewDriver.getRole());
addExcludeSetEnableController(m_SmsDriver.getRole());
}
ExperimentController::setEnabledForLoading(all, postconf);
}
......
......@@ -90,6 +90,7 @@ private:
DriverPtr<MagneticFieldCommon> m_OldDriver; //! Old IPS120 driver link
DriverPtr<MagneticFieldCommon> m_NewDriver; //! New mercury driver link
DriverPtr<MagneticFieldCommon> m_SmsDriver; //! New sms cryogenic driver
DriverPtr<MagneticFieldCommon> m_Driver; //! current driver link
/*!
......
/*
* Nomad Instrument Control Software
*
* Copyright 2011 Institut Laue-Langevin
*
* Licensed under the EUPL, Version 1.1 only (the "License");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
#ifndef CRYOGENICSMSDEF_H
#define CRYOGENICSMSDEF_H
namespace cryogenic_sms {
/*
* Locat status
*/
static const int32 NO_STATUS = 0x0;
static const int32 HOLDING_ON_STATUS = 0x1;
static const int32 RAMPING_ON_STATUS = 0x2;
static const int32 HEATER_ON_STATUS = 0x4;
static const int32 QUENCH_TRIP_STATUS = 0x8;
static const int32 EXTERNAL_TRIP_STATUS = 0x10;
/*
* Commands
*/
static const char UPDATE_COMMAND[] = "UPDATE";
static const char RAMP_COMMAND[] = "RAMP";
static const char PAUSE_COMMAND[] = "PAUSE";
static const char HEATER_COMMAND[] = "HEATER";
static const char TESLA_COMMAND[] = "TESLA";
static const char LOCK_COMMAND[] = "LOCK";
static const char SET_COMMAND[] = "SET";
static const char DIRECTION_COMMAND[] = "DIRECTION";
static const char GET_OUTPUT_COMMAND[] = "GET OUTPUT";
static const char ON[] = "ON";
static const char OFF[] = "OFF";
static const char RATE[] = "RATE";
static const char RAMP[] = "RAMP";
static const char MID[] = "MID";
static const char OUTPUT[] = "OUTPUT";
static const char PLUS[] = "+";
static const char MINUS[] = "-";
static const char ZERO[] = "ZERO";
static const char STATUS[] = "STATUS";
static const char QUENCH[] = "STATUS";
static const char HOLDING[] = "HOLDING";
static const char RAMPING[] = "RAMPING";
static const char EXTERNAL[] = "EXTERNAL";
static const char TERMINATOR[] = "\r\n";
/*
* Properties
*/
enum ProcessStep {
DUMMY, INIT, HEATER_ON, FIELD_CHANGING, STABILISATION, HEATER_OFF, AUTO_POWERED, HOLD
};
}
#endif //CRYOGENICSMSDEF_H
/*
* Nomad Instrument Control Software
*
* Copyright 2011 Institut Laue-Langevin
*
* Licensed under the EUPL, Version 1.1 only (the "License");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
#include "CryogenicSmsDriver.h"
#include "CryogenicSmsDef.h"
#include "RealCryogenicSmsDriver.h"
#include "PerfectCryogenicSmsDriver.h"
using namespace std;
namespace cryogenic_sms {
const std::string CryogenicSmsDriver::TYPE = "CryogenicSms";
/*
* Constructor
*/
CryogenicSmsDriver::CryogenicSmsDriver(const std::string& name) :
magneticfield::MagneticFieldCommon(name) {
driver::RS232::init(name);
persistentField.init(this, NOSAVE, "persistent_field");
registerStates(new RealCryogenicSmsDriver(this), new PerfectCryogenicSmsDriver(this), new PerfectCryogenicSmsDriver(this));
// Init command list
initCommand(driver::INIT_COMMAND);
initCommand(driver::READ_COMMAND);
initCommand(driver::START_COMMAND);
initCommand(driver::STOP_COMMAND);
initCommand(driver::STATUS_COMMAND);
initCommand(driver::READ_INFOS_COMMAND);
// Init functions
registerFunction(NONE_FUNCTION);
m_DoRegenrise = false;
m_WantedCurrent = 0;
m_OutputCurrent = 0;
m_PersistentCurrent = 0;
deviceType = LEAF_DEVICE_TYPE_DEVICE_CONTAINER;
/*
* Register the Spy and Observer commands necessary to do the updates.
*/
registerSpyCommand(driver::STATUS_COMMAND, 1);
registerObserverCommand(driver::STATUS_COMMAND, 100);
}
/*
* Destructor
*/
CryogenicSmsDriver::~CryogenicSmsDriver() {
}
/*
* execute
*/
void CryogenicSmsDriver::execute(const std::string& aCommand) {
if ((aCommand != driver::STOP_COMMAND) && (aCommand != driver::STATUS_COMMAND) && (aCommand != driver::READ_COMMAND)) {
commandProgression = PROGRESSION_UNKNOWNSTATE_DEVICE_CONTAINER;
}
CryogenicSmsState* currentState = dynamic_cast<CryogenicSmsState *>(getCurrentState());
// Check command
if (aCommand == driver::READ_INFOS_COMMAND) {
// Info command
currentState->readInfos();
} else if (aCommand == driver::START_COMMAND) {
m_DoRegenrise = true;
startActivated = true;
currentState->start();
currentState->readStatus();
} else if (aCommand == driver::INIT_COMMAND) {
m_DoRegenrise = true;
m_RegeneriseCounter.clear();
currentState->init();
} else if (aCommand == driver::READ_COMMAND) {
currentState->read();
} else if (aCommand == driver::STOP_COMMAND) {
m_DoRegenrise = false;
startActivated = false;
currentState->stop();
} else if (aCommand == driver::STATUS_COMMAND) {
currentState->readStatus();
}
}
/*
* refreshWantedFieldProperty
*/
void CryogenicSmsDriver::refreshWantedFieldProperty(float64 value) throw (CannotSetValue) {
if (value > maxField()) {
stringstream maxStream;
maxStream << maxField();
string smax;
maxStream >> smax;
sendErrorEvent(ABOVE_HIGH_LIMIT_ERROR, "Field must be <= " + smax + " Tesla");
throw CannotSetValue();
} else if (value < minField()) {
stringstream minStream;
minStream << minField();
string smin;
minStream >> smin;
sendErrorEvent(BELOW_LOW_LIMIT_ERROR, "Field must be => " + smin + " Tesla");
throw CannotSetValue();
}
m_WantedCurrent = value / maxField() * maxCurrent();
}
/*
* computeFieldStatus
*/
void CryogenicSmsDriver::computeFieldStatus(int32 value) {
int32 valueout = 0;
if (value & QUENCH_TRIP_STATUS) {
valueout |= MagneticFieldCommon::QUENCH;
} else if (value & EXTERNAL_TRIP_STATUS) {
valueout |= MagneticFieldCommon::FAULT;
} else if (value & RAMPING_ON_STATUS) {
valueout |= MagneticFieldCommon::CHANGING;
}
if (valueout == 0) {
// In precision flag setting
float64 delta = wantedField() - actualField();
if (delta <= tolerance()) {
valueout |= MagneticFieldCommon::IN_TOLERANCE;
} else {
valueout &= ~(MagneticFieldCommon::IN_TOLERANCE);
}
}
status = value;
fieldStatus = valueout;
}
}
/*
* Nomad Instrument Control Software
*
* Copyright 2011 Institut Laue-Langevin
*
* Licensed under the EUPL, Version 1.1 only (the "License");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
#ifndef CRYOGENICSMSDRIVER_H
#define CRYOGENICSMSDRIVER_H
#include <time.h>
#include <Driver.h>
#include "drivers/global/RS232.h"
#include "controllers/common/sample_environment/magneticfield/MagneticFieldCommon.h"
#include "Utilities/Counter.h"
namespace cryogenic_sms {
/*!
* The CryogenicSmsDriver class contains the hardware operation on Oxford CryogenicSms controller
*/
class CryogenicSmsDriver: public magneticfield::MagneticFieldCommon, public driver::RS232 {
friend class RealCryogenicSmsDriver;
friend class PerfectCryogenicSmsDriver;
friend class SimulatedCryogenicSmsDriver;
public:
//! Driver type value
static const std::string TYPE;
/*!
* \brief Constructor
* \param[in] name the name of the device driver
*/
CryogenicSmsDriver(const std::string& name);
/*!
* \brief Destructor
*/
virtual ~CryogenicSmsDriver();
/*!
* \brief Method called for executing a command
*
* \param[in] command the command to apply on the controller
*/
virtual void execute(const std::string& aCommand);
/*!
* Properties
*/
Property<float64> persistentField; //! Persistent field in the controller
private:
/*!
* \brief Method called before changing the wanted position property value
* \param[in] value the property value
* \throws CannotSetValue the value isn't corrected, or property couldn't be changed
*/
virtual void refreshWantedFieldProperty(float64 value) throw (CannotSetValue);
/*!
* \brief compute global axis status
* \param[in] value the driver status
*/
virtual void computeFieldStatus(int32 value);
/*!
* Local values
*/
float64 m_WantedCurrent;
float64 m_OutputCurrent;
float64 m_PersistentCurrent;
Counter m_RegeneriseCounter;
bool m_DoRegenrise;
};
}
#endif //CRYOGENICSMSDRIVER_H
/*
* Nomad Instrument Control Software
*
* Copyright 2011 Institut Laue-Langevin
*
* Licensed under the EUPL, Version 1.1 only (the "License");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
#ifndef CRYOGENICSMSSTATE_H
#define CRYOGENICSMSSTATE_H
#include <Driver.h>
#include "CryogenicSmsDriver.h"
namespace cryogenic_sms {
/*!
* \class CryogenicSmsState
* \brief Virtual class for implement State pattern
*
* Define all methods that perfect, simulated and real classes have to implement
*/
class CryogenicSmsState: public DriverState<CryogenicSmsDriver> {
public:
/*!
* \brief Constructor
* \param[in] owner The device driver main class link
*/
CryogenicSmsState(CryogenicSmsDriver* owner) :
DriverState<CryogenicSmsDriver>(owner) {
}
/*!
* \brief Destructor
*/
virtual ~CryogenicSmsState() {
}
/*!
* \brief start command implementation
*/
virtual void start() = 0;
/*!
* \brief Read command implementation
*/
virtual void read() = 0;
/*!
* \brief stop command implementation
*/
virtual void stop() = 0;
/*!
* \brief Read Status command implementation
*/
virtual void readStatus() = 0;
/*!
* \brief Read Infos command implementation
*/
virtual void readInfos() = 0;
};
}
#endif //CryogenicSmsSTATE_H
<module name="cryogenic_sms">
<driver class="cryogenic_sms::CryogenicSmsDriver"/>
</module>
\ No newline at end of file
/*
* Nomad Instrument Control Software
*
* Copyright 2011 Institut Laue-Langevin
*
* Licensed under the EUPL, Version 1.1 only (the "License");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
#include "PerfectCryogenicSmsDriver.h"
#include "CryogenicSmsDef.h"
namespace cryogenic_sms {
/*
* Constructor
*/
PerfectCryogenicSmsDriver::PerfectCryogenicSmsDriver(CryogenicSmsDriver* owner) :
CryogenicSmsState(owner) {
/* Empty */
}
/*
* Destructor
*/
PerfectCryogenicSmsDriver::~PerfectCryogenicSmsDriver() {
/* Empty */
}
/*
* init
*/
void PerfectCryogenicSmsDriver::init() {
}
/*
* readStatus
*/
void PerfectCryogenicSmsDriver::readStatus() {
if ((owner()->useRegenerise() == true) && (owner()->m_DoRegenrise == true) && (owner()->persistentField() != 0)){
// check time
if (owner()->m_RegeneriseCounter.getTime() >= (owner()->regeneriseTime() * 3600)) {
owner()->m_RegeneriseCounter.clear();
owner()->regenerise = true;
start();
owner()->regenerise = false;
}
}
owner()->status = NO_STATUS;
owner()->computeFieldStatus(NO_STATUS);
owner()->startActivated = false;
owner()->commandProgression = PROGRESSION_END_DEVICE_CONTAINER;
}
/*
* stop
*/
void PerfectCryogenicSmsDriver::stop() {
}
/*
* readInfos
*/
void PerfectCryogenicSmsDriver::readInfos() {
}
/*
* read
*/
void PerfectCryogenicSmsDriver::read() {
}
/*
* start
*/
void PerfectCryogenicSmsDriver::start() {
float64 setpoint = owner()->wantedField();
owner()->m_OutputCurrent = setpoint / owner()->maxField() * owner()->maxCurrent();
owner()->m_PersistentCurrent = setpoint / owner()->maxField() * owner()->maxCurrent();
owner()->actualField = setpoint;
owner()->persistentField = setpoint;
owner()->m_RegeneriseCounter.clear();
}
}
/*
* Nomad Instrument Control Software
*
* Copyright 2011 Institut Laue-Langevin
*
* Licensed under the EUPL, Version 1.1 only (the "License");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
#ifndef PERFECTCRYOGENICSMSDRIVER_H
#define PERFECTCRYOGENICSMSDRIVER_H
#include "CryogenicSmsState.h"
namespace cryogenic_sms {
/*!
* \class PerfectLakeshore211Driver
* \brief Perfect implementation class for the cryogenic_sms device driver
*
* This class is a perfect implementation of cryogenic_sms device driver.
* On start command, all actual values become target's ones.
*/
class PerfectCryogenicSmsDriver: public CryogenicSmsState {
public:
/*!
* \brief Constructor
* \param[in] owner The device driver main class link
*/
PerfectCryogenicSmsDriver(CryogenicSmsDriver* owner);
/*!
* \brief Destructor
*/
virtual ~PerfectCryogenicSmsDriver();
/*!
* \brief init command implementation
*/
virtual void init();
/*!
* \brief start command implementation
*/
virtual void start();
/*!
* \brief Read command implementation
*/
virtual void read();
/*!
* \brief stop command implementation
*/
virtual void stop();
/*!
* \brief Read status command implementation
*/
virtual void readStatus();
/*!
* \brief Read Infos command implementation
*/
virtual void readInfos();
};
}
#endif //PERFECTCRYOGENICSMSDRIVER_H