Skip to content
Snippets Groups Projects
Commit b52cb560 authored by Martin Christoph Hierholzer's avatar Martin Christoph Hierholzer
Browse files

- fixed a bug in the FanOut which did not wait for the trigger (since...

- fixed a bug in the FanOut which did not wait for the trigger (since ProcessScalar::receive() does not wait)
- fixed a bug in Application::feedDeviceRegisterToControlSystem() not handling the last arugment (trigger) properly
- improved the output produced with VariableNetwork::dump()
parent 0478c9bf
No related branches found
No related tags found
No related merge requests found
......@@ -46,6 +46,9 @@ class ControlLoopModule : public ctk::ApplicationModule {
void mainLoop() {
actuator = 0;
actuator.write();
while(true) {
readback.read();
setpoint.read();
......
......@@ -43,8 +43,11 @@ namespace ChimeraTK {
* function only. */
Application(const std::string& name);
/** Destructor */
virtual ~Application() {}
/** The destructor will remove the global pointer to the instance and allows creating another instance
* afterwards. This is mostly useful for writing tests, as it allows to run several applications sequentially
* in the same executable. Note that any ApplicationModules etc. owned by this Application are no longer
* valid after destroying the Application and must be destroyed as well (or at least no longer used). */
virtual ~Application();
/** Set the process variable manager. This will be called by the control system adapter initialisation code. */
void setPVManager(boost::shared_ptr<mtca4u::DevicePVManager> const &processVariableManager) {
......
......@@ -77,7 +77,8 @@ namespace ChimeraTK {
assert(hasExternalTrigger);
while(true) {
// wait for external trigger
externalTrigger->receive();
/// @todo TODO replace with proper blocking implementation when supported by the CSA
while(externalTrigger->receive() == false) std::this_thread::yield();
// receive data
impl->receive();
for(auto &slave : slaves) { // send out copies to slaves
......
......@@ -140,8 +140,8 @@ namespace ChimeraTK {
/** Return list of consuming nodes */
const std::list<Node>& getConsumingNodes() const { return consumerList; }
/** Dump the network structure to std::cout */
void dump() const;
/** Dump the network structure to std::cout. The optional linePrefix will be prepended to all lines. */
void dump(const std::string& linePrefix="") const;
/** Compare two networks */
bool operator==(const VariableNetwork &other) const {
......@@ -156,7 +156,7 @@ namespace ChimeraTK {
/** Return the trigger type. This function will also do some checking if the network confguration is valid under
* the aspect of the trigger type. */
TriggerType getTriggerType();
TriggerType getTriggerType() const;
/** Return the enginerring unit */
const std::string& getUnit() { return engineeringUnit; }
......
......@@ -39,6 +39,13 @@ Application::Application(const std::string& name)
/*********************************************************************************************************************/
Application::~Application() {
std::lock_guard<std::mutex> lock(instance_mutex);
instance = nullptr;
}
/*********************************************************************************************************************/
void Application::run() {
// call the user-defined initialise() function which describes the structure of the application
initialise();
......@@ -458,7 +465,7 @@ void Application::feedDeviceRegisterToControlSystem(const std::string &deviceAli
networkList.emplace_back();
VariableNetwork& network = networkList.back();
UpdateMode mode = UpdateMode::push;
if(dynamic_cast<InvalidAccessor*>(&trigger) != nullptr) {
if(dynamic_cast<InvalidAccessor*>(&trigger) == nullptr) {
mode = UpdateMode::poll;
network.addTrigger(trigger);
}
......
......@@ -22,11 +22,15 @@ namespace ChimeraTK {
/*********************************************************************************************************************/
void VariableNetwork::Node::dump() const {
if(type == NodeType::Application) std::cout << " type = Application" << std::endl;
if(type == NodeType::ControlSystem) std::cout << " type = ControlSystem ('" << publicName << "')" << std::endl;
if(type == NodeType::Device) std::cout << " type = Device (" << deviceAlias << ": "
<< registerName << ")" << std::endl;
}
if(type == NodeType::Application) std::cout << " type = Application";
if(type == NodeType::ControlSystem) std::cout << " type = ControlSystem ('" << publicName << "')";
if(type == NodeType::Device) std::cout << " type = Device (" << deviceAlias << ": " << registerName << ")";
if(type == NodeType::TriggerReceiver) std::cout << " type = TriggerReceiver";
if(type == NodeType::invalid) std::cout << " type = **invalid**";
if(mode == UpdateMode::push) std::cout << " pushing" << std::endl;
if(mode == UpdateMode::poll) std::cout << " polling" << std::endl;
}
/*********************************************************************************************************************/
......@@ -262,17 +266,34 @@ namespace ChimeraTK {
/*********************************************************************************************************************/
void VariableNetwork::dump() const {
std::cout << "VariableNetwork {" << std::endl;
std::cout << " feeder";
void VariableNetwork::dump(const std::string& linePrefix) const {
std::cout << linePrefix << "VariableNetwork {" << std::endl;
std::cout << linePrefix << " value type = " << valueType->name() << ", engineering unit = " << engineeringUnit << std::endl;
std::cout << linePrefix << " trigger type = ";
try {
TriggerType tt = getTriggerType();
if(tt == TriggerType::feeder) std::cout << "feeder" << std::endl;
if(tt == TriggerType::pollingConsumer) std::cout << "pollingConsumer" << std::endl;
if(tt == TriggerType::external) std::cout << "external" << std::endl;
if(tt == TriggerType::none) std::cout << "none" << std::endl;
}
catch(ApplicationExceptionWithID<ApplicationExceptionID::illegalVariableNetwork> &e) {
std::cout << "**error**" << std::endl;
}
std::cout << linePrefix << " feeder";
feeder.dump();
std::cout << " number of consumers: " << consumerList.size() << std::endl;
std::cout << linePrefix << " consumers: " << consumerList.size() << std::endl;
size_t count = 0;
for(auto &consumer : consumerList) {
std::cout << " consumer " << ++count << ":";
std::cout << linePrefix << " # " << ++count << ":";
consumer.dump();
}
std::cout << "}" << std::endl;
if(hasExternalTrigger) {
std::cout << linePrefix << " external trigger network:" << std::endl;;
assert(externalTrigger != nullptr);
externalTrigger->dump(" ");
}
std::cout << linePrefix << "}" << std::endl;
}
/*********************************************************************************************************************/
......@@ -310,7 +331,7 @@ namespace ChimeraTK {
/*********************************************************************************************************************/
VariableNetwork::TriggerType VariableNetwork::getTriggerType() {
VariableNetwork::TriggerType VariableNetwork::getTriggerType() const {
// network has an external trigger
if(hasExternalTrigger) {
if(feeder.mode == UpdateMode::push) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment