Commit 29ac9ea1 authored by yannick legoc's avatar yannick legoc
Browse files

added special Frequency controller for in16

parent dc09c830
/*
* 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 <InstrumentManager/InstrumentManager.h>
#include <boost/lexical_cast.hpp>
#include <fstream>
#include <iostream>
#include <common/base/ServerProperties.h>
#include "FrequencyRemoteMatlabReq.h"
#include "FrequencyRequestMessages.pb.h"
#include "controllers/common/family/Families.h"
namespace in16 {
using namespace std;
using namespace common;
using namespace boost;
using namespace cameo;
const std::string FrequencyRemoteMatlabReq::TYPE = "in16_remote_matlab";
const std::string FrequencyRemoteMatlabReq::MATLAB_APPLICATION = "in16-matlab";
const std::string FrequencyRemoteMatlabReq::RESPONDER_NAME = "in16_frequency_controller";
const std::string FrequencyRemoteMatlabReq::RUN_SPECTRUMS_TEST = "Run Spectrums Test";
const std::string FrequencyRemoteMatlabReq::RUN_SPECTRUMS = "Run Spectrums";
const std::string FrequencyRemoteMatlabReq::RUN_SPECTRUMS_TIME = "Run Spectrums Time";
const std::string FrequencyRemoteMatlabReq::RUN_SINGLE_FREQUENCY = "Run Single Frequency";
FrequencyRemoteMatlabReq::FrequencyRemoteMatlabReq(const std::string& name) :
ExperimentController(name), controller::Stoppable(this) {
serverEndpoint.init(this, SAVE, "cameo_server");
initialized.init(this, NOSAVE, "initialized");
requestTypeValues.init(this, NOSAVE, "request_type_values");
requestTypeValues.resize(4);
requestTypeValues.set(0, RUN_SPECTRUMS_TEST);
requestTypeValues.set(1, RUN_SPECTRUMS);
requestTypeValues.set(2, RUN_SPECTRUMS_TIME);
requestTypeValues.set(3, RUN_SINGLE_FREQUENCY);
requestType.init(this, NOSAVE, "request_type", "Request");
requestType.setEnumeratedLabels(requestTypeValues);
requestType.setEnumeratedValues(requestTypeValues);
requestType = requestTypeValues.get(0);
fr.init(this, NOSAVE, "fr");
frMin.init(this, NOSAVE, "frMin");
frMax.init(this, NOSAVE, "frMax");
nMax.init(this, NOSAVE, "nMax");
time.init(this, NOSAVE, "time");
comment.init(this, NOSAVE, "comment");
fr = 0;
frMin = 1E1;
frMax = 1E6;
nMax = 5;
time = 0;
comment = "a comment";
}
FrequencyRemoteMatlabReq::FrequencyRemoteMatlabReq(const FrequencyRemoteMatlabReq& controller) :
ExperimentController(controller), controller::Stoppable(this) {
}
FrequencyRemoteMatlabReq::~FrequencyRemoteMatlabReq() {
// Stop the remote application.
m_matlabApplication->stop();
// Wait for the termination
application::State state = m_matlabApplication->waitFor();
cout << "Matlab application terminated with state " << application::toString(state) << endl;
}
void FrequencyRemoteMatlabReq::postConfiguration() {
if (serverEndpoint() == "") {
m_server.reset(new Server(application::This::getServer().getEndpoint()));
} else {
m_server.reset(new Server(serverEndpoint()));
}
initialized = initApplication();
}
bool FrequencyRemoteMatlabReq::initApplication() {
// Do not initialize if it is already done
if (initialized()) {
return true;
}
try {
// Start the Matlab server
if (!m_server->isAvailable(10000)) {
cout << "Matlab server is not available" << endl;
return false;
}
cout << "Matlab server is connected to " << getName() << endl;
m_matlabApplication = m_server->connect(MATLAB_APPLICATION);
if (m_matlabApplication->exists()) {
// The application exists from a previous server session
m_matlabApplication->stop();
application::State state = m_matlabApplication->waitFor();
cout << "Terminated matlab application " << state << endl;
}
m_matlabApplication = m_server->start(MATLAB_APPLICATION);
if (!m_matlabApplication->exists()) {
cout << "No matlab application" << endl;
return false;
}
// Create the requester.
m_requester = application::Requester::create(*m_matlabApplication, RESPONDER_NAME);
if (m_requester.get() == 0) {
cout << "requester error" << endl;
return false;
}
// Application initialized.
initialized = true;
return true;
} catch (...) {
// Currently an exception can occur during isAvailable.
cout << "Unexpected exception during matlab connection" << endl;
}
return false;
}
void FrequencyRemoteMatlabReq::start() {
// Serialize the request.
proto::RunSpectrumsRequest request;
request.set_fr(fr());
request.set_frmin(frMin());
request.set_frmax(frMax());
request.set_nmax(nMax());
request.set_time(time());
request.set_comment(comment());
if (requestType() == RUN_SPECTRUMS) {
request.set_type(proto::RunSpectrumsRequest_Type_RUN);
}
else if (requestType() == RUN_SPECTRUMS_TIME) {
request.set_type(proto::RunSpectrumsRequest_Type_RUN_TIME);
}
else if (requestType() == RUN_SINGLE_FREQUENCY) {
request.set_type(proto::RunSpectrumsRequest_Type_RUN_SINGLE);
}
else if (requestType() == RUN_SPECTRUMS_TEST) {
request.set_type(proto::RunSpectrumsRequest_Type_TEST);
}
// Send the message.
m_requester->sendBinary(request.SerializeAsString());
cout << getName() << " sent run request " << requestType() << endl;
// Wait for the response synchronously.
// Note that responses can be processed asynchronously if the server is able to.
string data;
m_requester->receiveBinary(data);
proto::FrequencyResponse response;
response.ParseFromString(data);
cout << "received response " << response.responseid() << endl;
sleep(1);
}
void FrequencyRemoteMatlabReq::stop() {
// Serialize the request.
proto::RunSpectrumsRequest request;
request.set_type(proto::RunSpectrumsRequest_Type_STOP);
request.set_fr(0);
request.set_frmin(0);
request.set_frmax(0);
request.set_nmax(0);
request.set_time(0);
request.set_comment("");
// Send the message.
m_requester->sendBinary(request.SerializeAsString());
cout << getName() << " sent run request " << endl;
// Wait for the response synchronously.
// Note that responses can be processed asynchronously if the server is able to.
string data;
m_requester->receiveBinary(data);
proto::FrequencyResponse response;
response.ParseFromString(data);
cout << "received response " << response.responseid() << endl;
}
}
/*
* 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 IN16_REMOTEMATLABREQ_H
#define IN16_REMOTEMATLABREQ_H
#include <Controller.h>
#include <cameo/cameo.h>
namespace in16 {
class FrequencyRemoteMatlabReq : public ExperimentController,
public controller::Stoppable {
public:
//! Type of controller
static const std::string TYPE;
FrequencyRemoteMatlabReq(const std::string& name);
FrequencyRemoteMatlabReq(const FrequencyRemoteMatlabReq& controller);
virtual ~FrequencyRemoteMatlabReq();
virtual void postConfiguration();
virtual void start();
virtual void stop();
static const std::string RUN_SPECTRUMS_TEST;
static const std::string RUN_SPECTRUMS;
static const std::string RUN_SPECTRUMS_TIME;
static const std::string RUN_SINGLE_FREQUENCY;
DynamicProperty<std::string> requestTypeValues;
Property<std::string> requestType;
Property<double> fr;
Property<double> frMin;
Property<double> frMax;
Property<int32> nMax;
Property<double> time;
Property<std::string> comment;
private:
bool initApplication();
static const std::string MATLAB_APPLICATION;
static const std::string RESPONDER_NAME;
Property<std::string> serverEndpoint;
Property<bool> initialized;
std::auto_ptr<cameo::Server> m_server;
std::auto_ptr<cameo::application::Instance> m_matlabApplication;
std::auto_ptr<cameo::application::Requester> m_requester;
};
}
#endif
This diff is collapsed.
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: FrequencyRequestMessages.proto
#ifndef PROTOBUF_FrequencyRequestMessages_2eproto__INCLUDED
#define PROTOBUF_FrequencyRequestMessages_2eproto__INCLUDED
#include <string>
#include <google/protobuf/stubs/common.h>
#if GOOGLE_PROTOBUF_VERSION < 2006000
#error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update
#error your headers.
#endif
#if 2006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc.
#endif
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/extension_set.h>
// @@protoc_insertion_point(includes)
namespace proto {
// Internal implementation detail -- do not call these.
void protobuf_AddDesc_FrequencyRequestMessages_2eproto();
void protobuf_AssignDesc_FrequencyRequestMessages_2eproto();
void protobuf_ShutdownFile_FrequencyRequestMessages_2eproto();
class RunSpectrumsRequest;
class FrequencyResponse;
enum RunSpectrumsRequest_Type {
RunSpectrumsRequest_Type_START = 1,
RunSpectrumsRequest_Type_STOP = 2,
RunSpectrumsRequest_Type_RUN = 3,
RunSpectrumsRequest_Type_RUN_TIME = 4,
RunSpectrumsRequest_Type_RUN_SINGLE = 5,
RunSpectrumsRequest_Type_TEST = 6
};
bool RunSpectrumsRequest_Type_IsValid(int value);
const RunSpectrumsRequest_Type RunSpectrumsRequest_Type_Type_MIN = RunSpectrumsRequest_Type_START;
const RunSpectrumsRequest_Type RunSpectrumsRequest_Type_Type_MAX = RunSpectrumsRequest_Type_TEST;
const int RunSpectrumsRequest_Type_Type_ARRAYSIZE = RunSpectrumsRequest_Type_Type_MAX + 1;
// ===================================================================
class RunSpectrumsRequest : public ::google::protobuf::MessageLite {
public:
RunSpectrumsRequest();
virtual ~RunSpectrumsRequest();
RunSpectrumsRequest(const RunSpectrumsRequest& from);
inline RunSpectrumsRequest& operator=(const RunSpectrumsRequest& from) {
CopyFrom(from);
return *this;
}
inline const ::std::string& unknown_fields() const {
return _unknown_fields_;
}
inline ::std::string* mutable_unknown_fields() {
return &_unknown_fields_;
}
static const RunSpectrumsRequest& default_instance();
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
// Returns the internal default instance pointer. This function can
// return NULL thus should not be used by the user. This is intended
// for Protobuf internal code. Please use default_instance() declared
// above instead.
static inline const RunSpectrumsRequest* internal_default_instance() {
return default_instance_;
}
#endif
void Swap(RunSpectrumsRequest* other);
// implements Message ----------------------------------------------
RunSpectrumsRequest* New() const;
void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
void CopyFrom(const RunSpectrumsRequest& from);
void MergeFrom(const RunSpectrumsRequest& from);
void Clear();
bool IsInitialized() const;
int ByteSize() const;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
void DiscardUnknownFields();
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const;
public:
::std::string GetTypeName() const;
// nested types ----------------------------------------------------
typedef RunSpectrumsRequest_Type Type;
static const Type START = RunSpectrumsRequest_Type_START;
static const Type STOP = RunSpectrumsRequest_Type_STOP;
static const Type RUN = RunSpectrumsRequest_Type_RUN;
static const Type RUN_TIME = RunSpectrumsRequest_Type_RUN_TIME;
static const Type RUN_SINGLE = RunSpectrumsRequest_Type_RUN_SINGLE;
static const Type TEST = RunSpectrumsRequest_Type_TEST;
static inline bool Type_IsValid(int value) {
return RunSpectrumsRequest_Type_IsValid(value);
}
static const Type Type_MIN =
RunSpectrumsRequest_Type_Type_MIN;
static const Type Type_MAX =
RunSpectrumsRequest_Type_Type_MAX;
static const int Type_ARRAYSIZE =
RunSpectrumsRequest_Type_Type_ARRAYSIZE;
// accessors -------------------------------------------------------
// required .proto.RunSpectrumsRequest.Type type = 1;
inline bool has_type() const;
inline void clear_type();
static const int kTypeFieldNumber = 1;
inline ::proto::RunSpectrumsRequest_Type type() const;
inline void set_type(::proto::RunSpectrumsRequest_Type value);
// required double fr = 2;
inline bool has_fr() const;
inline void clear_fr();
static const int kFrFieldNumber = 2;
inline double fr() const;
inline void set_fr(double value);
// required double frMin = 3;
inline bool has_frmin() const;
inline void clear_frmin();
static const int kFrMinFieldNumber = 3;
inline double frmin() const;
inline void set_frmin(double value);
// required double frMax = 4;
inline bool has_frmax() const;
inline void clear_frmax();
static const int kFrMaxFieldNumber = 4;
inline double frmax() const;
inline void set_frmax(double value);
// required int32 nMax = 5;
inline bool has_nmax() const;
inline void clear_nmax();
static const int kNMaxFieldNumber = 5;
inline ::google::protobuf::int32 nmax() const;
inline void set_nmax(::google::protobuf::int32 value);
// required double time = 6;
inline bool has_time() const;
inline void clear_time();
static const int kTimeFieldNumber = 6;
inline double time() const;
inline void set_time(double value);
// required string comment = 7;
inline bool has_comment() const;
inline void clear_comment();
static const int kCommentFieldNumber = 7;
inline const ::std::string& comment() const;
inline void set_comment(const ::std::string& value);
inline void set_comment(const char* value);
inline void set_comment(const char* value, size_t size);
inline ::std::string* mutable_comment();
inline ::std::string* release_comment();
inline void set_allocated_comment(::std::string* comment);
// @@protoc_insertion_point(class_scope:proto.RunSpectrumsRequest)
private:
inline void set_has_type();
inline void clear_has_type();
inline void set_has_fr();
inline void clear_has_fr();
inline void set_has_frmin();
inline void clear_has_frmin();
inline void set_has_frmax();
inline void clear_has_frmax();
inline void set_has_nmax();
inline void clear_has_nmax();
inline void set_has_time();
inline void clear_has_time();
inline void set_has_comment();
inline void clear_has_comment();
::std::string _unknown_fields_;
::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
double fr_;
double frmin_;
int type_;
::google::protobuf::int32 nmax_;
double frmax_;
double time_;
::std::string* comment_;
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
friend void protobuf_AddDesc_FrequencyRequestMessages_2eproto_impl();
#else
friend void protobuf_AddDesc_FrequencyRequestMessages_2eproto();
#endif
friend void protobuf_AssignDesc_FrequencyRequestMessages_2eproto();
friend void protobuf_ShutdownFile_FrequencyRequestMessages_2eproto();
void InitAsDefaultInstance();
static RunSpectrumsRequest* default_instance_;
};
// -------------------------------------------------------------------
class FrequencyResponse : public ::google::protobuf::MessageLite {
public:
FrequencyResponse();
virtual ~FrequencyResponse();
FrequencyResponse(const FrequencyResponse& from);
inline FrequencyResponse& operator=(const FrequencyResponse& from) {
CopyFrom(from);
return *this;
}
inline const ::std::string& unknown_fields() const {
return _unknown_fields_;
}
inline ::std::string* mutable_unknown_fields() {
return &_unknown_fields_;
}
static const FrequencyResponse& default_instance();
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
// Returns the internal default instance pointer. This function can
// return NULL thus should not be used by the user. This is intended
// for Protobuf internal code. Please use default_instance() declared
// above instead.
static inline const FrequencyResponse* internal_default_instance() {
return default_instance_;
}
#endif
void Swap(FrequencyResponse* other);
// implements Message ----------------------------------------------
FrequencyResponse* New() const;
void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
void CopyFrom(const FrequencyResponse& from);
void MergeFrom(const FrequencyResponse& from);
void Clear();
bool IsInitialized() const;
int ByteSize() const;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
void DiscardUnknownFields();
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const;
public:
::std::string GetTypeName() const;
// nested types ----------------------------------------------------
// accessors -------------------------------------------------------