Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F332145
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Size
13 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/examples/deluxe-interface/deluxe-interface.cpp b/examples/deluxe-interface/deluxe-interface.cpp
index f465933..82621ac 100755
--- a/examples/deluxe-interface/deluxe-interface.cpp
+++ b/examples/deluxe-interface/deluxe-interface.cpp
@@ -1,178 +1,272 @@
//===-- examples/deluxe-interface/deluxe-interface.cpp ----------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file examples/deluxe-interface/deluxe-interface.cpp
///
/// \author David Juhasz (david.juhasz@tuwien.ac.at)
///
/// \date 2017-2019
///
/// \brief A simple example on the \c rosa::deluxe::DeluxeContext and related
/// classes.
//===----------------------------------------------------------------------===//
#include "rosa/config/version.h"
#include "rosa/deluxe/DeluxeContext.hpp"
#include <algorithm>
#include <cmath>
#include <vector>
using namespace rosa;
using namespace rosa::deluxe;
using namespace rosa::terminal;
/// How many cycles of simulation to perform.
const size_t NumberOfSimulationCycles = 16;
-/// Helper function creating a deluxe agent for logging and forwarding values.
-///
-/// Received values are dumped to \c LOG_INFO_STREAM and then returned as
-/// result.
-///
-/// \tparam T type of values to handle
-///
-/// \param C the deluxe context to create the agent in
-/// \param Name name of the new agent
-///
-/// \return handle for the new agent
-template <typename T>
-AgentHandle createLowLevelAgent(std::unique_ptr<DeluxeContext> &C,
- const std::string &Name) {
- using handler = std::function<Optional<T>(std::pair<T, bool>)>;
- using result = Optional<T>;
- return C->createAgent(
- Name, handler([&, Name](std::pair<T, bool> I) -> result {
- LOG_INFO_STREAM << "\n******\n"
- << Name << " " << (I.second ? "<New>" : "<Old>")
- << " value: " << I.first << "\n******\n";
- return {I.first};
- }));
-}
-
int main(void) {
LOG_INFO_STREAM << '\n'
<< library_string() << " -- " << Color::Red
<< "deluxe-interface example" << Color::Default << '\n';
std::unique_ptr<DeluxeContext> C = DeluxeContext::create("Deluxe");
//
// Create deluxe sensors.
//
LOG_INFO("Creating sensors.");
// All sensors are created without defining a normal generator function, but
- // with the default value of the second argument. That, however, requires the
+ // with the default value of the last argument. That, however, requires the
// data type to be explicitly defined. This is good for simulation only.
+
+ // The first and second sensors do not receive master-input.
+ AgentHandle BoolSensor = C->createSensor<bool>("BoolSensor");
AgentHandle IntSensor = C->createSensor<int32_t>("IntSensor");
- AgentHandle FloatSensor = C->createSensor<float>("FloatSensor");
+
+ // This sensor receives master-input and dumps it to \c LOG_INFO_STREAM.
+ const std::string FloatSensorName = "FloatSensor";
+ AgentHandle FloatSensor = C->createSensor<uint32_t, float>(
+ FloatSensorName, [&FloatSensorName](std::pair<uint32_t, bool> I) {
+ LOG_INFO_STREAM << "\n******\n"
+ << FloatSensorName
+ << " master-input " << (I.second ? "<New>" : "<Old>")
+ << " value: " << I.first << "\n******\n";
+ });
//
// Create low-level deluxe agents with \c createLowLevelAgent.
//
LOG_INFO("Creating low-level agents.");
- AgentHandle IntAgent = createLowLevelAgent<int32_t>(C, "IntAgent");
- AgentHandle FloatAgent = createLowLevelAgent<float>(C, "FloatAgent");
+ // All agents below dump their received values to \c LOG_INFO_STREAM on each
+ // triggering.
+
+ // This agent does not receive master-input and does not produce
+ // master-output. It results in the value it received.
+ const std::string BoolAgentName = "BoolAgent";
+ using BoolResult = Optional<bool>;
+ using BoolHandler = std::function<BoolResult(std::pair<bool, bool>)>;
+ AgentHandle BoolAgent = C->createAgent(
+ BoolAgentName,
+ BoolHandler([&BoolAgentName](std::pair<bool, bool> I) -> BoolResult {
+ LOG_INFO_STREAM << "\n******\n"
+ << BoolAgentName << " "
+ << (I.second ? "<New>" : "<Old>")
+ << " value: " << I.first << "\n******\n";
+ return {I.first};
+ }));
+
+ // This agent receives master-input but does not produce master-output. The
+ // agent maintains a state in \c IntAgentOffset. The master-input handler
+ // updates \c IntAgentOffset according to each received (new) value from its
+ // master. The slave-input handler results in the sum of the received value
+ // and the actual value of \c IntAgentOffset.
+ const std::string IntAgentName = "IntAgent";
+ using IntMasterHandler = std::function<void(std::pair<uint32_t, bool>)>;
+ using IntResult = Optional<int32_t>;
+ using IntHandler = std::function<IntResult(std::pair<int32_t, bool>)>;
+ uint32_t IntAgentOffset = 0;
+ AgentHandle IntAgent = C->createAgent(
+ IntAgentName,
+ // Master-input handler.
+ IntMasterHandler([&IntAgentName,
+ &IntAgentOffset](std::pair<uint32_t, bool> I) {
+ LOG_INFO_STREAM << "\n******\n"
+ << IntAgentName
+ << " master-input " << (I.second ? "<New>" : "<Old>")
+ << " value: " << I.first << "\n******\n";
+ if (I.second) {
+ IntAgentOffset = I.first;
+ }
+ }),
+ // Slave-input handler.
+ IntHandler([&IntAgentName,
+ &IntAgentOffset](std::pair<int32_t, bool> I) -> IntResult {
+ LOG_INFO_STREAM << "\n******\n"
+ << IntAgentName << " " << (I.second ? "<New>" : "<Old>")
+ << " value: " << I.first << "\n******\n";
+ return {I.first + IntAgentOffset};
+ }));
+
+ // This agent receives master-input and produces master-output. The
+ // master-input handler propagaates each received (new) value to its slave as
+ // master-output. The slave-input handler results in the value it received and
+ // produces no actual master-output.
+ const std::string FloatAgentName = "FloatAgent";
+ using FloatMasterResult = std::tuple<Optional<uint32_t>>;
+ using FloatMasterHandler =
+ std::function<FloatMasterResult(std::pair<uint32_t, bool>)>;
+ using FloatResult = std::tuple<Optional<float>, Optional<uint32_t>>;
+ using FloatHandler = std::function<FloatResult(std::pair<float, bool>)>;
+ AgentHandle FloatAgent = C->createAgent(
+ FloatAgentName,
+ // Master-input handler.
+ FloatMasterHandler([&FloatAgentName](
+ std::pair<uint32_t, bool> I) -> FloatMasterResult {
+ LOG_INFO_STREAM << "\n******\n"
+ << FloatAgentName
+ << " master-input " << (I.second ? "<New>" : "<Old>")
+ << " value: " << I.first << "\n******\n";
+ const auto Output =
+ I.second ? Optional<uint32_t>(I.first) : Optional<uint32_t>();
+ return {Output};
+ }),
+ // Slave-input handler.
+ FloatHandler([&FloatAgentName](std::pair<float, bool> I) -> FloatResult {
+ LOG_INFO_STREAM << "\n******\n"
+ << FloatAgentName << " "
+ << (I.second ? "<New>" : "<Old>")
+ << " value: " << I.first << "\n******\n";
+ return {{I.first}, {}};
+ }));
//
// Connect sensors to low-level agents.
//
LOG_INFO("Connect sensors to their corresponding low-level agents.");
+ C->connectSensor(BoolAgent, 0, BoolSensor, "Bool Sensor Channel");
C->connectSensor(IntAgent, 0, IntSensor, "Int Sensor Channel");
C->connectSensor(FloatAgent, 0, FloatSensor, "Float Sensor Channel");
//
// Create a high-level deluxe agent.
//
LOG_INFO("Create high-level agent.");
- // The new agent logs its input values and results in the the sum of them.
+ // This agent does not receive master-input but produces master-output for its
+ // slaves at positions `1` and `2` but not for that at position `0`. The agent
+ // maintains a state in \c SumAgentState. The handler increments \c
+ // SumAgentState upon each received (new) `true` value from its slave at
+ // position `0`. Whenever \c SumAgentState has been updated, it is sent to the
+ // slaves at positions `1` and `2`. The handler results in the sum of the
+ // values received from slaves at positions `1` and `2`.
+ using SumResult = std::tuple<Optional<double>, Optional<unit_t>,
+ Optional<uint32_t>, Optional<uint32_t>>;
+ using SumHandler = std::function<SumResult(
+ std::pair<bool, bool>, std::pair<int32_t, bool>, std::pair<float, bool>)>;
+ uint32_t SumAgentState = 0;
AgentHandle SumAgent = C->createAgent(
- "Sum Agent", std::function<Optional<double>(std::pair<int32_t, bool>,
- std::pair<float, bool>)>(
- [](std::pair<int32_t, bool> I1,
- std::pair<float, bool> I2) -> Optional<double> {
- LOG_INFO_STREAM
- << "\n*******\nSum Agent triggered with values:\n"
- << (I1.second ? "<New>" : "<Old>")
- << " int value: " << I1.first << "\n"
- << (I2.second ? "<New>" : "<Old>")
- << " float value: " << I2.first << "\n******\n";
- return {I1.first + I2.first};
- }));
+ "Sum Agent",
+ SumHandler([&SumAgentState](std::pair<bool, bool> I0,
+ std::pair<int32_t, bool> I1,
+ std::pair<float, bool> I2) -> SumResult {
+ LOG_INFO_STREAM << "\n*******\nSum Agent triggered with values:\n"
+ << (I0.second ? "<New>" : "<Old>")
+ << " bool value: " << I0.first << "\n"
+ << (I1.second ? "<New>" : "<Old>")
+ << " int value: " << I1.first << "\n"
+ << (I2.second ? "<New>" : "<Old>")
+ << " float value: " << I2.first << "\n******\n";
+ if (I0.second && I0.first) {
+ ++SumAgentState;
+ }
+ const auto MasterOutput = I0.second && I0.first
+ ? Optional<uint32_t>(SumAgentState)
+ : Optional<uint32_t>();
+ const auto Output = I1.first + I2.first;
+ return {{Output}, {}, {MasterOutput}, {MasterOutput}};
+ }));
//
// Connect low-level agents to the high-level agent.
//
LOG_INFO("Connect low-level agents to the high-level agent.");
- C->connectAgents(SumAgent, 0, IntAgent, "Int Agent Channel");
- C->connectAgents(SumAgent, 1, FloatAgent, "Float Agent Channel");
+ C->connectAgents(SumAgent, 0, BoolAgent, "Bool Agent Channel");
+ C->connectAgents(SumAgent, 1, IntAgent, "Int Agent Channel");
+ C->connectAgents(SumAgent, 2, FloatAgent, "Float Agent Channel");
//
// For simulation output, create a logger agent writing the output of the
// high-level agent into a log stream.
//
LOG_INFO("Create a logger agent.");
- // The agent logs each new input value and produces nothing.
+ // The agent dumps each received (new) value to \c LOG_INFO_STREAM and
+ // produces nothing; does not receive mater-input and does not produce
+ // master-output.
AgentHandle LoggerAgent =
C->createAgent("Logger Agent",
std::function<Optional<unit_t>(std::pair<double, bool>)>(
[](std::pair<double, bool> Sum) -> Optional<unit_t> {
if (Sum.second) {
LOG_INFO_STREAM << "Result: " << Sum.first << "\n";
}
return {};
}));
//
// Connect the high-level agent to the logger agent.
//
LOG_INFO("Connect the high-level agent to the logger agent.");
C->connectAgents(LoggerAgent, 0, SumAgent, "Sum Agent Channel");
//
// Do simulation.
//
LOG_INFO("Setting up and performing simulation.");
//
// Initialize deluxe context for simulation.
//
C->initializeSimulation();
//
// Create some vectors and register them for their corresponding sensors.
//
+ std::vector<bool> BoolValues(NumberOfSimulationCycles);
+ std::generate(BoolValues.begin(), BoolValues.end(),
+ [i = 0](void) mutable -> bool { return (++i % 4) == 0; });
+ C->registerSensorValues(BoolSensor, BoolValues.begin(), BoolValues.end());
+
std::vector<int32_t> IntValues(NumberOfSimulationCycles);
std::generate(IntValues.begin(), IntValues.end(),
[i = 0](void) mutable { return ++i; });
C->registerSensorValues(IntSensor, IntValues.begin(), IntValues.end());
std::vector<float> FloatValues(NumberOfSimulationCycles);
std::generate(FloatValues.begin(), FloatValues.end(),
[f = 0.5f](void) mutable {
f += 0.3f;
return std::floor(f) + 0.5f;
});
C->registerSensorValues(FloatSensor, FloatValues.begin(), FloatValues.end());
//
// Simulate.
//
C->simulate(NumberOfSimulationCycles);
return 0;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Mar 15, 7:49 PM (15 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
129097
Default Alt Text
(13 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment