Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Gauthier Quesnel
irritator
Commits
f5d22912
Commit
f5d22912
authored
Apr 01, 2020
by
K-H-Ismail
Committed by
Gauthier Quesnel
Apr 03, 2020
Browse files
core: add cross model and integrator reset
parent
c4a413e7
Changes
1
Hide whitespace changes
Inline
Side-by-side
lib/include/irritator/core.hpp
View file @
f5d22912
...
@@ -13,7 +13,7 @@
...
@@ -13,7 +13,7 @@
#include <cmath>
#include <cmath>
#include <cstdint>
#include <cstdint>
#include <cstring>
#include <cstring>
//#include <iostream>
namespace
irt
{
namespace
irt
{
using
i8
=
int8_t
;
using
i8
=
int8_t
;
...
@@ -93,6 +93,10 @@ enum class status
...
@@ -93,6 +93,10 @@ enum class status
model_constant_empty_init_message
,
model_constant_empty_init_message
,
model_constant_bad_init_message
,
model_constant_bad_init_message
,
model_cross_empty_init_message
,
model_cross_bad_init_message
,
model_cross_bad_external_message
,
};
};
constexpr
bool
constexpr
bool
...
@@ -2467,7 +2471,8 @@ enum class dynamics_type : i8
...
@@ -2467,7 +2471,8 @@ enum class dynamics_type : i8
mult_4
,
mult_4
,
counter
,
counter
,
generator
,
generator
,
constant
constant
,
cross
};
};
struct
model
struct
model
...
@@ -2797,6 +2802,98 @@ struct constant
...
@@ -2797,6 +2802,98 @@ struct constant
return
status
::
success
;
return
status
::
success
;
}
}
};
};
struct
cross
{
model_id
id
;
input_port_id
x
[
3
];
output_port_id
y
[
1
];
time
sigma
;
double
threshold
;
double
value
=
threshold
-
1.0
;
double
if_value
=
0.0
;
double
else_value
=
0.0
;
enum
port_name
{
port_value
,
port_if_value
,
port_else_value
};
status
initialize
(
data_array
<
message
,
message_id
>&
init_messages
)
noexcept
{
sigma
=
time_domain
<
time
>::
zero
;
return
status
::
success
;
}
status
transition
(
data_array
<
input_port
,
input_port_id
>&
input_ports
,
time
/*t*/
,
time
/*e*/
,
time
/*r*/
)
noexcept
{
bool
have_message
=
false
;
if
(
auto
*
port
=
input_ports
.
try_to_get
(
x
[
port_value
]);
port
)
{
for
(
const
auto
&
msg
:
port
->
messages
)
{
irt_return_if_fail
(
msg
.
type
==
value_type
::
real_64
,
status
::
model_cross_bad_external_message
);
irt_return_if_fail
(
msg
.
size
()
==
1
,
status
::
model_cross_bad_external_message
);
value
=
msg
.
to_real_64
(
0
)
;
have_message
=
true
;
}
}
if
(
auto
*
port
=
input_ports
.
try_to_get
(
x
[
port_if_value
]);
port
)
{
for
(
const
auto
&
msg
:
port
->
messages
)
{
irt_return_if_fail
(
msg
.
type
==
value_type
::
real_64
,
status
::
model_cross_bad_external_message
);
irt_return_if_fail
(
msg
.
size
()
==
1
,
status
::
model_cross_bad_external_message
);
if_value
=
msg
.
to_real_64
(
0
);
}
}
if
(
auto
*
port
=
input_ports
.
try_to_get
(
x
[
port_else_value
]);
port
)
{
for
(
const
auto
&
msg
:
port
->
messages
)
{
irt_return_if_fail
(
msg
.
type
==
value_type
::
real_64
,
status
::
model_cross_bad_external_message
);
irt_return_if_fail
(
msg
.
size
()
==
1
,
status
::
model_cross_bad_external_message
);
else_value
=
msg
.
to_real_64
(
0
);
}
}
sigma
=
have_message
?
time_domain
<
time
>::
zero
:
time_domain
<
time
>::
infinity
;
return
status
::
success
;
}
status
lambda
(
data_array
<
output_port
,
output_port_id
>&
output_ports
)
noexcept
{
double
output_value
=
0.0
;
if
(
auto
*
port
=
output_ports
.
try_to_get
(
y
[
0
]);
port
)
{
output_value
=
value
>=
threshold
?
if_value
:
else_value
;
port
->
messages
.
emplace_front
(
output_value
);
}
return
status
::
success
;
}
};
struct
none
struct
none
{
{
...
@@ -2808,13 +2905,14 @@ struct integrator
...
@@ -2808,13 +2905,14 @@ struct integrator
{
{
model_id
id
;
model_id
id
;
time
sigma
=
time_domain
<
time
>::
zero
;
time
sigma
=
time_domain
<
time
>::
zero
;
input_port_id
x
[
2
];
input_port_id
x
[
3
];
output_port_id
y
[
1
];
output_port_id
y
[
1
];
enum
port_name
enum
port_name
{
{
port_quanta
,
port_quanta
,
port_x_dot
port_x_dot
,
port_reset
};
};
enum
class
state
enum
class
state
...
@@ -2830,7 +2928,9 @@ struct integrator
...
@@ -2830,7 +2928,9 @@ struct integrator
double
down_threshold
=
0.0
;
double
down_threshold
=
0.0
;
double
last_output_value
=
0.0
;
double
last_output_value
=
0.0
;
double
current_value
=
0.0
;
double
current_value
=
0.0
;
double
expected_value
=
0.0
;
double
expected_value
=
0.0
;
bool
reset
=
false
;
double
reset_value
;
flat_double_list
<
record
>
archive
;
flat_double_list
<
record
>
archive
;
state
st
=
state
::
init
;
state
st
=
state
::
init
;
...
@@ -2844,6 +2944,7 @@ struct integrator
...
@@ -2844,6 +2944,7 @@ struct integrator
status
external
(
input_port
&
port_quanta
,
status
external
(
input_port
&
port_quanta
,
input_port
&
port_x_dot
,
input_port
&
port_x_dot
,
input_port
&
port_reset
,
time
t
)
noexcept
time
t
)
noexcept
{
{
for
(
const
auto
&
msg
:
port_quanta
.
messages
)
{
for
(
const
auto
&
msg
:
port_quanta
.
messages
)
{
...
@@ -2875,6 +2976,15 @@ struct integrator
...
@@ -2875,6 +2976,15 @@ struct integrator
st
=
state
::
wait_for_quanta
;
st
=
state
::
wait_for_quanta
;
}
}
for
(
const
auto
&
msg
:
port_reset
.
messages
)
{
irt_return_if_fail
(
msg
.
type
==
value_type
::
real_64
&&
msg
.
size
()
==
1
,
status
::
model_integrator_bad_external_message
);
reset_value
=
msg
.
to_real_64
(
0
);
reset
=
true
;
}
if
(
st
==
state
::
running
)
{
if
(
st
==
state
::
running
)
{
current_value
=
compute_current_value
(
t
);
current_value
=
compute_current_value
(
t
);
expected_value
=
compute_expected_value
();
expected_value
=
compute_expected_value
();
...
@@ -2912,14 +3022,15 @@ struct integrator
...
@@ -2912,14 +3022,15 @@ struct integrator
{
{
auto
*
port_1
=
input_ports
.
try_to_get
(
x
[
port_quanta
]);
auto
*
port_1
=
input_ports
.
try_to_get
(
x
[
port_quanta
]);
auto
*
port_2
=
input_ports
.
try_to_get
(
x
[
port_x_dot
]);
auto
*
port_2
=
input_ports
.
try_to_get
(
x
[
port_x_dot
]);
auto
*
port_3
=
input_ports
.
try_to_get
(
x
[
port_reset
]);
if
(
port_1
->
messages
.
empty
()
&&
port_2
->
messages
.
empty
()
)
{
if
(
port_1
->
messages
.
empty
()
&&
port_2
->
messages
.
empty
()
&&
port_3
->
messages
.
empty
())
{
irt_return_if_bad
(
internal
(
t
));
irt_return_if_bad
(
internal
(
t
));
}
else
{
}
else
{
if
(
time_domain
<
time
>::
is_zero
(
r
))
if
(
time_domain
<
time
>::
is_zero
(
r
))
irt_return_if_bad
(
internal
(
t
));
irt_return_if_bad
(
internal
(
t
));
irt_return_if_bad
(
external
(
*
port_1
,
*
port_2
,
t
));
irt_return_if_bad
(
external
(
*
port_1
,
*
port_2
,
*
port_3
,
t
));
}
}
return
ta
();
return
ta
();
...
@@ -2982,7 +3093,7 @@ private:
...
@@ -2982,7 +3093,7 @@ private:
if
(
archive
.
empty
())
if
(
archive
.
empty
())
return
last_output_value
;
return
last_output_value
;
auto
val
=
last_output_value
;
auto
val
=
reset
?
reset_value
:
last_output_value
;
auto
end
=
archive
.
end
();
auto
end
=
archive
.
end
();
auto
it
=
archive
.
begin
();
auto
it
=
archive
.
begin
();
auto
next
=
archive
.
begin
();
auto
next
=
archive
.
begin
();
...
@@ -3445,6 +3556,7 @@ struct simulation
...
@@ -3445,6 +3556,7 @@ struct simulation
data_array
<
counter
,
dynamics_id
>
counter_models
;
data_array
<
counter
,
dynamics_id
>
counter_models
;
data_array
<
generator
,
dynamics_id
>
generator_models
;
data_array
<
generator
,
dynamics_id
>
generator_models
;
data_array
<
constant
,
dynamics_id
>
constant_models
;
data_array
<
constant
,
dynamics_id
>
constant_models
;
data_array
<
cross
,
dynamics_id
>
cross_models
;
scheduller
sched
;
scheduller
sched
;
...
@@ -3483,6 +3595,7 @@ struct simulation
...
@@ -3483,6 +3595,7 @@ struct simulation
irt_return_if_bad
(
counter_models
.
init
(
model_capacity
));
irt_return_if_bad
(
counter_models
.
init
(
model_capacity
));
irt_return_if_bad
(
generator_models
.
init
(
model_capacity
));
irt_return_if_bad
(
generator_models
.
init
(
model_capacity
));
irt_return_if_bad
(
constant_models
.
init
(
model_capacity
));
irt_return_if_bad
(
constant_models
.
init
(
model_capacity
));
irt_return_if_bad
(
cross_models
.
init
(
model_capacity
));
return
status
::
success
;
return
status
::
success
;
}
}
...
@@ -3530,8 +3643,10 @@ struct simulation
...
@@ -3530,8 +3643,10 @@ struct simulation
mdl
.
type
=
dynamics_type
::
counter
;
mdl
.
type
=
dynamics_type
::
counter
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
generator
>
)
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
generator
>
)
mdl
.
type
=
dynamics_type
::
generator
;
mdl
.
type
=
dynamics_type
::
generator
;
else
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
constant
>
)
mdl
.
type
=
dynamics_type
::
constant
;
mdl
.
type
=
dynamics_type
::
constant
;
else
mdl
.
type
=
dynamics_type
::
cross
;
if
constexpr
(
is_detected_v
<
initialize_function_t
,
Dynamics
>
)
{
if
constexpr
(
is_detected_v
<
initialize_function_t
,
Dynamics
>
)
{
//if constexpr (is_detected_v<has_init_port_t, Dynamics>) {
//if constexpr (is_detected_v<has_init_port_t, Dynamics>) {
...
@@ -3716,6 +3831,8 @@ struct simulation
...
@@ -3716,6 +3831,8 @@ struct simulation
return
make_transition
(
mdl
,
generator_models
.
get
(
mdl
.
id
),
t
,
o
);
return
make_transition
(
mdl
,
generator_models
.
get
(
mdl
.
id
),
t
,
o
);
case
dynamics_type
::
constant
:
case
dynamics_type
::
constant
:
return
make_transition
(
mdl
,
constant_models
.
get
(
mdl
.
id
),
t
,
o
);
return
make_transition
(
mdl
,
constant_models
.
get
(
mdl
.
id
),
t
,
o
);
case
dynamics_type
::
cross
:
return
make_transition
(
mdl
,
cross_models
.
get
(
mdl
.
id
),
t
,
o
);
}
}
return
make_transition
(
mdl
,
none_models
.
get
(
mdl
.
id
),
t
,
o
);
return
make_transition
(
mdl
,
none_models
.
get
(
mdl
.
id
),
t
,
o
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment