Commit 4af22a43 authored by ics's avatar ics

implement in1 displex sample changer controller

parent 7eb46205
<module name="in1">
<controller class="in1::IN1MonoCurves"/>
<controller class="in1::IN1Settings"/>
<controller class="in1::SampleChanger"/>
</module>
/*
* 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.
*/
/*!
* \brief Class described the flipper coils control
* \author J. Locatelli
* \date 01-12-2012
*/
#include <controllers/tas/in1/SampleChanger.h>
#include "controllers/common/family/Families.h"
using namespace std;
namespace in1 {
const string SampleChanger::TYPE = "in1_sample_changer";
const char SampleChanger::LOAD_STATE[] = "1";
const char SampleChanger::UNLOAD_STATE[] = "2";
const char SampleChanger::LOAD_STATE_STR[] = "load";
const char SampleChanger::UNLOAD_STATE_STR[] = "unload";
const int32 SampleChanger::NB_SAMPLES = 6;
const float64 SampleChanger::SAMPLE_ANGLE_STEP = 60.;
/*
* Constructor
*/
SampleChanger::SampleChanger(const string& name) :
ExperimentController(name), controller::Stoppable(this), controller::Read(this) {
setFamily(family::SAMPLE_ENVIRONMENT);
sample.init(this, SAVE | SPY | SCAN, "actual_sample", "wanted_sample", "Sample");
registerFunction(TYPE);
m_Rotation.init(this, "rotation");
m_Valves.init(this, "valves");
m_LastPosition = 0;
m_DoComplete = false;
}
/*
* Constructor
*/
SampleChanger::SampleChanger(const SampleChanger& controller) :
ExperimentController(controller), controller::Stoppable(this), controller::Read(this) {
sample.copy(this, controller.sample);
m_Rotation.copy(controller.m_Rotation);
m_Valves.copy(controller.m_Valves);
m_LastPosition = 0;
m_DoComplete = false;
}
/*
* Destructor
*/
SampleChanger::~SampleChanger() {
}
/*
* postConfiguration
*/
void SampleChanger::postConfiguration() {
registerRefresher(sample.setpoint, &SampleChanger::refreshSampleProperty, this);
registerUpdater(m_Rotation->position, &SampleChanger::updateChanger, this);
registerUpdater(m_Valves->state, &SampleChanger::updateChanger, this);
registerStatus(m_Rotation, &SampleChanger::updateStatus, this);
registerStatus(m_Valves, &SampleChanger::updateStatus, this);
registerProgression(m_Rotation, &SampleChanger::updateProgression, this);
registerProgression(m_Valves, &SampleChanger::updateProgression, this);
updateChanger();
updateStatus();
}
/*
* refreshChangerProperty
*/
void SampleChanger::refreshSampleProperty(int32 value) throw (CannotSetValue) {
if (value > NB_SAMPLES) {
throw CannotSetValue();
}
}
/*
* start
*/
void SampleChanger::start() {
commandProgression = 0;
try {
commandStatus.setRunning();
log(Level::s_Debug) << "Sample index " << sample.setpoint << endlog;
// Unload sample
if (isStopped() == false) {
m_Valves->state.setpoint = LOAD_STATE;
m_Valves->startCommand(false);
}
if (sample.setpoint() != 0) {
if (isStopped() == false) {
// Move on selected changer pos
m_Rotation->position.setpoint = SAMPLE_ANGLE_STEP * (sample.setpoint() - 1);
if (m_Rotation->position.setpoint() >= m_Rotation->position()) {
// Go directly
m_Rotation->startCommand(false);
}
else {
m_DoComplete = true;
unique_lock<mutex> lock(m_ConditionMutex);
// pass to zero first
m_Rotation->moveToHighSwitchParallel();
// wait zero
cout << "wait..." << endl;
m_Condition.wait(lock);
cout << "wait OK" << endl;
if (isStopped() == false) {
// Go to final setpoint
m_Rotation->startCommand(false);
}
}
}
if (isStopped() == false) {
m_Valves->state.setpoint = UNLOAD_STATE;
m_Valves->startCommand(false);
}
}
checkStatus();
if (sample() == 0) {
log(Level::s_Debug) << "No Sample" << endlog;
} else {
log(Level::s_Debug) << "Sample index " << sample << endlog;
}
} catch (...) {
commandStatus.setError();
}
commandProgression = 100;
sendProgressEvent(100);
}
/*
* stop
*/
void SampleChanger::stop() {
log(Level::s_Info) << "stopped" << endlog;
m_Rotation->stopParallel();
m_Valves->stopParallel();
m_Condition.notify_one();
}
/*
* read
*/
void SampleChanger::read() {
m_Rotation->readParallel();
m_Valves->readParallel();
}
/*
* pause
*/
void SampleChanger::pause() {
log(Level::s_Info) << "pause" << endlog;
m_Rotation->pauseParallel();
m_Valves->stopParallel();
}
/*
* resume
*/
void SampleChanger::resume() {
if (isStarted() == true) {
log(Level::s_Info) << "continue" << endlog;
m_Rotation->resumeParallel();
m_Valves->startParallel();
}
}
/*
* updateFlipperState
*/
void SampleChanger::updateChanger() {
float64 rotationpos = m_Rotation->position();
if (rotationpos < m_LastPosition) {
unique_lock<mutex> lock(m_ConditionMutex);
cout << "notify >>> " << endl;
m_Condition.notify_one();
}
m_LastPosition = rotationpos;
string valvesstate = m_Valves->state();
// cout << "valvesstate = " << valvesstate << endl;
// find index;
int32 index = 0;
if (valvesstate.compare(LOAD_STATE_STR) == 0) {
for (int32 i = 0; i < NB_SAMPLES; ++i) {
if (fabs(rotationpos - i * SAMPLE_ANGLE_STEP) < 0.1) {
index = i + 1;
break;
}
}
}
sample.update(index);
}
/*
* checkStatus
*/
void SampleChanger::checkStatus() {
if (m_Rotation->commandStatus.isError() || m_Valves->commandStatus.isError()) {
commandStatus.setError();
} else if (m_Rotation->commandStatus.isWarning() || m_Valves->commandStatus.isWarning()) {
commandStatus.setWarning();
} else if (m_Rotation->commandStatus.isIdle() || m_Valves->commandStatus.isIdle()) {
commandStatus.setIdle();
} else {
commandStatus.setUnknown();
}
}
/*
* updateStatus
*/
void SampleChanger::updateStatus() {
if (isStarted() == false) {
checkStatus();
}
}
/*
* updateProgression
*/
void SampleChanger::updateProgression() {
if (isStarted() == true) {
int32 progression = (m_Rotation->commandProgression() + m_Valves->commandProgression()) / 2;
if (progression >= 100) {
progression = 99;
}
commandProgression = progression;
}
}
/*
* test
*/
void SampleChanger::test() {
using namespace utilities;
// UnitTest test(this);
}
}
/*
* 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.
*/
/*!
* \brief Class described the new sample changer of IN1 displex
* \author J. Locatelli
* \date 28-06-2019
*/
#ifndef SAMPLECHANGER_H
#define SAMPLECHANGER_H
#include <Controller.h>
#include "controllers/common/axis/AxisController.h"
#include "controllers/common/state/stateio/StateIOController.h"
#include <mutex>
#include <condition_variable>
namespace in1 {
/*!
* \class SampleChanger
* \brief Class described the new sample in1 displex changer
*
* \par
* This class is the class which describing the new sample in1 displex changer control
*/
class SampleChanger: public ExperimentController,
public controller::Stoppable,
public controller::Pausable,
public controller::Read {
public:
//! Type of controller
static const std::string TYPE;
/*!
* \brief Constructor
* \param[in] name the name of the experiment controller
*/
SampleChanger(const std::string& name);
SampleChanger(const SampleChanger& controller);
/*!
* \brief Destructor
*/
~SampleChanger();
//! Properties name
Property<int32, SETPOINT> sample;
/*!
* \brief implement unitary test
*/
virtual void test();
protected:
/*!
* \brief Method called before changing the property value
*
* This method is called after setting configuration during the creation of controller.
*/
virtual void postConfiguration();
private:
/*!
* \brief Start command
*
* This command implementation applies chosen voltage and current to the power supply.
*/
virtual void start();
/*!
* \brief Stop command
*
* This command implementation stops.
*/
virtual void stop();
/*!
* \brief Pause command
*
* This command implementation pause.
*/
virtual void pause();
/*!
* \brief resume command
*
* This command implementation continu.
*/
virtual void resume();
/*!
* \brief Read command
*
* This command implementation reads.
*/
virtual void read();
/*!
* \brief This method registers imps controllers
*/
void refreshSampleProperty(int32 value) throw (CannotSetValue);
/*!
* \brief Update methods
*/
void updateChanger();
/*!
* \brief Update status of sample changer
*/
void updateStatus();
void checkStatus();
/*!
* \brief Update progression
*/
void updateProgression();
ControllerPtr<axis::AxisController> m_Rotation; //!
ControllerPtr<stateio::StateIOController> m_Valves; //!
std::mutex m_ConditionMutex;
std::condition_variable m_Condition;
bool m_DoComplete;
float64 m_LastPosition;
static const int32 NB_SAMPLES;
static const float64 SAMPLE_ANGLE_STEP;
static const char LOAD_STATE[];
static const char UNLOAD_STATE[];
static const char LOAD_STATE_STR[];
static const char UNLOAD_STATE_STR[];
};
}
#endif //SAMPLECHANGER_H
# Labels
in1_sample_changer.wantedSamplePrefix=Wanted Sample Index
in1_sample_changer.actualSamplePrefix=Actual Sample Index
in1_sample_changer.0Label=Unload
in1_sample_changer.1Label=1
in1_sample_changer.2Label=2
in1_sample_changer.3Label=3
in1_sample_changer.4Label=4
in1_sample_changer.5Label=5
in1_sample_changer.6Label=6
in1_sample_changer.0Value=0
in1_sample_changer.1Value=1
in1_sample_changer.2Value=2
in1_sample_changer.3Value=3
in1_sample_changer.4Value=4
in1_sample_changer.5Value=5
in1_sample_changer.6Value=6
<plugin>
<controller type="state_io" role="state_io1"/>
<number_of_lines nb_lines="1"/>
<combo role="in1_sample_changer1" property="wanted_sample" prefix="in1_sample_changer.wantedSamplePrefix" valuesAndLabels="in1_sample_changer.0,in1_sample_changer.1,in1_sample_changer.2,in1_sample_changer.3,in1_sample_changer.4,in1_sample_changer.5,in1_sample_changer.6"/>
<text role="in1_sample_changer1" property="wanted_sample" prefix="in1_sample_changer.wantedSamplePrefix" />
<label role="in1_sample_changer1" property="actual_sample" prefix="in1_sample_changer.actualSamplePrefix" valuesAndLabels="in1_sample_changer.0,in1_sample_changer.1,in1_sample_changer.2,in1_sample_changer.3,in1_sample_changer.4,in1_sample_changer.5,in1_sample_changer.6"/>
</plugin>
<controller_plugin_config type="in1_sample_changer">
<image key="SAMPLE_CHANGER"/>
<settings view="in1_sample_changerView.xml"/>
<command view="in1_sample_changerCommandView.xml"/>
</controller_plugin_config>
<?xml version="1.0" encoding="ISO-8859-1" ?>
<controller type="in1_sample_changer">
<property name="wanted_sample" type="int32">
<!-- <range min="0" max="6"/> -->
</property>
<property name="actual_sample" type="int32" max_length="1">
</property>
<property name="commandStatus" type="int32">
</property>
</controller>
<plugin>
<controller type="in1_sample_changer" role="in1_sample_changer1"/>
<label role="in1_sample_changer1" property="actual_sample" prefix="in1_sample_changer.actualSamplePrefix" valuesAndLabels="in1_sample_changer.0,in1_sample_changer.1,in1_sample_changer.2,in1_sample_changer.3,in1_sample_changer.4,in1_sample_changer.5,in1_sample_changer.6"/>
<newLine/>
<combo role="in1_sample_changer1" property="wanted_sample" prefix="in1_sample_changer.wantedSamplePrefix" valuesAndLabels="in1_sample_changer.0,in1_sample_changer.1,in1_sample_changer.2,in1_sample_changer.3,in1_sample_changer.4,in1_sample_changer.5,in1_sample_changer.6"/>
<newLine/>
<status role="in1_sample_changer1" property="commandStatus" valuesImagesAndLabels="commandStatusUnknown,commandStatusIdle,commandStatusRunning,commandStatusWarning,commandStatusError"/>
</plugin>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment