Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F386819
deluxe-interface.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Size
10 KB
Referenced Files
None
Subscribers
None
deluxe-interface.cpp
View Options
//===-- 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
;
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 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"
);
// 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."
);
// 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."
);
// 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"
,
SumHandler
([
&
SumAgentState
](
std
::
pair
<
bool
,
bool
>
I0
,
std
::
pair
<
int32_t
,
bool
>
I1
,
std
::
pair
<
float
,
bool
>
I2
)
->
SumResult
{
LOG_INFO_STREAM
<<
"
\n
*******
\n
Sum 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
,
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 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-c
Expires
Fri, Jul 4, 8:29 AM (1 h, 33 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
157559
Default Alt Text
deluxe-interface.cpp (10 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment