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
Pour information : coupure de la forge ce matin entre 6h45 et 7h05 pour une mise à jour de sécurité
Open sidebar
Gauthier Quesnel
irritator
Commits
33b0e646
Commit
33b0e646
authored
Apr 08, 2021
by
Gauthier Quesnel
Browse files
core: add buffer and update generator with external sources
parent
b5cdce84
Changes
6
Hide whitespace changes
Inline
Side-by-side
app/gui/node-editor.cpp
View file @
33b0e646
...
...
@@ -1591,10 +1591,18 @@ show_dynamics_values(const counter& dyn)
ImGui
::
Text
(
"number %ld"
,
static_cast
<
long
>
(
dyn
.
number
));
}
static
void
show_dynamics_values
(
const
buffer
&
dyn
)
{
ImGui
::
Text
(
"next %.3f"
,
dyn
.
sigma
);
ImGui
::
Text
(
"value %.3f"
,
dyn
.
value
);
}
static
void
show_dynamics_values
(
const
generator
&
dyn
)
{
ImGui
::
Text
(
"next %.3f"
,
dyn
.
sigma
);
ImGui
::
Text
(
"value %.3f"
,
dyn
.
value
);
}
static
void
...
...
@@ -1897,11 +1905,17 @@ static void
show_dynamics_inputs
(
counter
&
/*dyn*/
)
{}
static
void
show_dynamics_inputs
(
buffer
&
dyn
)
{
ImGui
::
InputDouble
(
"value"
,
&
dyn
.
default_value
);
ImGui
::
InputDouble
(
"offset"
,
&
dyn
.
default_offset
);
}
static
void
show_dynamics_inputs
(
generator
&
dyn
)
{
ImGui
::
InputDouble
(
"value"
,
&
dyn
.
default_value
);
ImGui
::
InputDouble
(
"period"
,
&
dyn
.
default_period
);
ImGui
::
InputDouble
(
"offset"
,
&
dyn
.
default_offset
);
}
...
...
@@ -2582,6 +2596,7 @@ editor::show_editor() noexcept
}
add_popup_menuitem
(
*
this
,
dynamics_type
::
counter
,
&
new_model
);
add_popup_menuitem
(
*
this
,
dynamics_type
::
buffer
,
&
new_model
);
add_popup_menuitem
(
*
this
,
dynamics_type
::
generator
,
&
new_model
);
add_popup_menuitem
(
*
this
,
dynamics_type
::
constant
,
&
new_model
);
add_popup_menuitem
(
*
this
,
dynamics_type
::
time_func
,
&
new_model
);
...
...
app/gui/node-editor.hpp
View file @
33b0e646
...
...
@@ -49,12 +49,18 @@ status_string(const status s) noexcept
"model_connect_input_port_unknown"
,
"model_connect_already_exist"
,
"model_connect_bad_dynamics"
,
"model_buffer_null_ta_source"
,
"model_buffer_empty_ta_source"
,
"model_integrator_dq_error"
,
"model_integrator_X_error"
,
"model_integrator_internal_error"
,
"model_integrator_output_error"
,
"model_integrator_running_without_x_dot"
,
"model_integrator_ta_with_bad_x_dot"
,
"model_generator_null_ta_source"
,
"model_generator_empty_ta_source"
,
"model_generator_null_value_source"
,
"model_generator_empty_value_source"
,
"model_quantifier_bad_quantum_parameter"
,
"model_quantifier_bad_archive_length_parameter"
,
"model_quantifier_shifting_value_neg"
,
...
...
lib/include/irritator/core.hpp
View file @
33b0e646
...
...
@@ -173,12 +173,22 @@ enum class status
model_connect_input_port_unknown
,
model_connect_already_exist
,
model_connect_bad_dynamics
,
model_buffer_null_ta_source
,
model_buffer_empty_ta_source
,
model_integrator_dq_error
,
model_integrator_X_error
,
model_integrator_internal_error
,
model_integrator_output_error
,
model_integrator_running_without_x_dot
,
model_integrator_ta_with_bad_x_dot
,
model_generator_null_ta_source
,
model_generator_empty_ta_source
,
model_generator_null_value_source
,
model_generator_empty_value_source
,
model_quantifier_bad_quantum_parameter
,
model_quantifier_bad_archive_length_parameter
,
model_quantifier_shifting_value_neg
,
...
...
@@ -2433,6 +2443,7 @@ enum class dynamics_type : i8
mult_4
,
counter
,
buffer
,
generator
,
constant
,
cross
,
...
...
@@ -2476,9 +2487,11 @@ struct observer
finalize
};
using
update_fn
=
function_ref
<
void
(
const
observer
&
,
const
dynamics_type
,
const
time
,
const
time
,
const
observer
::
status
)
>
;
using
update_fn
=
function_ref
<
void
(
const
observer
&
,
const
dynamics_type
,
const
time
,
const
time
,
const
observer
::
status
)
>
;
observer
(
const
char
*
name_
,
update_fn
cb_
)
noexcept
:
cb
(
cb_
)
...
...
@@ -2558,6 +2571,9 @@ using has_output_port_t = decltype(&T::y);
template
<
typename
T
>
using
has_init_port_t
=
decltype
(
&
T
::
init
);
template
<
typename
T
>
using
has_sim_attribute_t
=
decltype
(
&
T
::
sim
);
struct
simulation
;
struct
none
...
...
@@ -4584,37 +4600,99 @@ struct counter
}
};
struct
generator
struct
external_source
{
double
*
data
=
nullptr
;
// @todo use a std::span<double> instead
sz
index
=
0
;
// of data and size.
sz
size
=
0
;
u64
id
=
0
;
function_ref
<
bool
(
external_source
&
src
)
>
expand
;
bool
next
(
double
&
value
)
noexcept
{
irt_assert
(
data
);
if
(
index
>=
size
)
{
if
(
expand
.
empty
()
||
!
expand
(
*
this
))
return
false
;
}
value
=
data
[
index
++
];
return
true
;
}
};
enum
class
external_source_id
:
u64
;
struct
buffer
{
model_id
id
;
input_port_id
x
[
1
];
output_port_id
y
[
1
];
time
sigma
;
external_source_id
default_lambda_source_id
=
external_source_id
{
0
};
simulation
*
sim
=
nullptr
;
double
default_offset
=
0.0
;
double
default_value
=
0.0
;
double
default_period
=
1.0
;
double
default_offset
=
1.0
;
double
value
=
0.0
;
double
period
=
1.0
;
double
offset
=
1.0
;
double
value
;
status
initialize
()
noexcept
{
sigma
=
default_offset
;
value
=
default_value
;
period
=
default_period
;
offset
=
default_offset
;
sigma
=
offset
;
return
status
::
success
;
}
status
transition
(
data_array
<
input_port
,
input_port_id
>&
/*input_ports*/
,
status
transition
(
data_array
<
input_port
,
input_port_id
>&
input_ports
,
time
/*t*/
,
time
/*e*/
,
time
/*r*/
)
noexcept
time
r
)
noexcept
;
status
lambda
(
data_array
<
output_port
,
output_port_id
>&
output_ports
)
noexcept
{
sigma
=
period
;
output_ports
.
get
(
y
[
0
]).
messages
.
emplace_front
(
value
);
return
status
::
success
;
}
message
observation
(
const
time
/*e*/
)
const
noexcept
{
return
{
value
};
}
};
struct
generator
{
model_id
id
;
output_port_id
y
[
1
];
time
sigma
;
external_source_id
default_lambda_source_id
=
external_source_id
{
0
};
external_source_id
default_value_source_id
=
external_source_id
{
0
};
simulation
*
sim
=
nullptr
;
double
default_offset
=
1.0
;
double
default_value
=
0.0
;
double
value
;
status
initialize
()
noexcept
{
sigma
=
default_offset
;
value
=
default_value
;
return
status
::
success
;
}
status
transition
(
data_array
<
input_port
,
input_port_id
>&
/*input_ports*/
,
time
/*t*/
,
time
/*e*/
,
time
/*r*/
)
noexcept
;
status
lambda
(
data_array
<
output_port
,
output_port_id
>&
output_ports
)
noexcept
{
...
...
@@ -5414,6 +5492,8 @@ dynamics_typeof() noexcept
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
counter
>
)
return
dynamics_type
::
counter
;
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
buffer
>
)
return
dynamics_type
::
buffer
;
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
generator
>
)
return
dynamics_type
::
generator
;
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
constant
>
)
...
...
@@ -5492,6 +5572,7 @@ struct simulation
data_array
<
mult_3
,
dynamics_id
>
mult_3_models
;
data_array
<
mult_4
,
dynamics_id
>
mult_4_models
;
data_array
<
counter
,
dynamics_id
>
counter_models
;
data_array
<
buffer
,
dynamics_id
>
buffer_models
;
data_array
<
generator
,
dynamics_id
>
generator_models
;
data_array
<
constant
,
dynamics_id
>
constant_models
;
data_array
<
cross
,
dynamics_id
>
cross_models
;
...
...
@@ -5501,6 +5582,8 @@ struct simulation
data_array
<
observer
,
observer_id
>
observers
;
data_array
<
external_source
,
external_source_id
>
external_sources
;
scheduller
sched
;
time
begin
=
time_domain
<
time
>::
zero
;
...
...
@@ -5615,6 +5698,8 @@ struct simulation
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
counter
>
)
return
counter_models
;
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
buffer
>
)
return
buffer_models
;
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
generator
>
)
return
generator_models
;
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
constant
>
)
...
...
@@ -5732,6 +5817,8 @@ struct simulation
return
f
(
mult_4_models
,
args
...);
case
dynamics_type
::
counter
:
return
f
(
counter_models
,
args
...);
case
dynamics_type
::
buffer
:
return
f
(
buffer_models
,
args
...);
case
dynamics_type
::
generator
:
return
f
(
generator_models
,
args
...);
case
dynamics_type
::
constant
:
...
...
@@ -5845,6 +5932,8 @@ struct simulation
return
f
(
mult_4_models
,
args
...);
case
dynamics_type
::
counter
:
return
f
(
counter_models
,
args
...);
case
dynamics_type
::
buffer
:
return
f
(
buffer_models
,
args
...);
case
dynamics_type
::
generator
:
return
f
(
generator_models
,
args
...);
case
dynamics_type
::
constant
:
...
...
@@ -6068,6 +6157,7 @@ public:
irt_return_if_bad
(
mult_3_models
.
init
(
model_capacity
));
irt_return_if_bad
(
mult_4_models
.
init
(
model_capacity
));
irt_return_if_bad
(
counter_models
.
init
(
model_capacity
));
irt_return_if_bad
(
buffer_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
(
cross_models
.
init
(
model_capacity
));
...
...
@@ -6077,6 +6167,8 @@ public:
irt_return_if_bad
(
observers
.
init
(
model_capacity
));
irt_return_if_bad
(
external_sources
.
init
(
ten
*
ten
));
irt_return_if_bad
(
flat_double_list_shared_allocator
.
init
(
integrator_models
.
capacity
()
*
ten
));
...
...
@@ -6371,6 +6463,7 @@ public:
case
dynamics_type
::
mult_3
:
case
dynamics_type
::
mult_4
:
case
dynamics_type
::
counter
:
case
dynamics_type
::
buffer
:
case
dynamics_type
::
generator
:
case
dynamics_type
::
constant
:
case
dynamics_type
::
cross
:
...
...
@@ -6477,7 +6570,8 @@ public:
while
(
observers
.
next
(
obs
))
{
if
(
auto
*
mdl
=
models
.
try_to_get
(
obs
->
model
);
mdl
)
{
obs
->
msg
.
reset
();
obs
->
cb
(
*
obs
,
mdl
->
type
,
mdl
->
tl
,
t
,
observer
::
status
::
initialize
);
obs
->
cb
(
*
obs
,
mdl
->
type
,
mdl
->
tl
,
t
,
observer
::
status
::
initialize
);
}
}
...
...
@@ -6532,6 +6626,9 @@ public:
if
constexpr
(
is_detected_v
<
initialize_function_t
,
Dynamics
>
)
irt_return_if_bad
(
dyn
.
initialize
());
if
constexpr
(
is_detected_v
<
has_sim_attribute_t
,
Dynamics
>
)
dyn
.
sim
=
this
;
mdl
.
tl
=
t
;
mdl
.
tn
=
t
+
dyn
.
sigma
;
mdl
.
handle
=
nullptr
;
...
...
@@ -6657,6 +6754,61 @@ public:
}
};
inline
status
buffer
::
transition
(
data_array
<
input_port
,
input_port_id
>&
input_ports
,
time
/*t*/
,
time
/*e*/
,
time
r
)
noexcept
{
irt_assert
(
sim
);
bool
have_message
=
false
;
auto
&
port
=
input_ports
.
get
(
x
[
0
]);
for
(
const
auto
&
msg
:
port
.
messages
)
{
value
=
msg
[
0
];
have_message
=
true
;
}
if
(
time_domain
<
time
>::
is_zero
(
r
))
{
auto
*
src_v
=
sim
->
external_sources
.
try_to_get
(
default_lambda_source_id
);
if
(
!
src_v
)
irt_bad_return
(
status
::
model_buffer_null_ta_source
);
if
(
!
src_v
->
next
(
sigma
))
irt_bad_return
(
status
::
model_buffer_empty_ta_source
);
}
else
{
sigma
=
r
;
}
return
status
::
success
;
}
inline
status
generator
::
transition
(
data_array
<
input_port
,
input_port_id
>&
/*input_ports*/
,
time
/*t*/
,
time
/*e*/
,
time
/*r*/
)
noexcept
{
irt_assert
(
sim
);
auto
*
src_l
=
sim
->
external_sources
.
try_to_get
(
default_lambda_source_id
);
if
(
!
src_l
)
irt_bad_return
(
status
::
model_generator_null_ta_source
);
if
(
!
src_l
->
next
(
sigma
))
irt_bad_return
(
status
::
model_generator_empty_ta_source
);
auto
*
src_v
=
sim
->
external_sources
.
try_to_get
(
default_value_source_id
);
if
(
!
src_v
)
irt_bad_return
(
status
::
model_generator_null_value_source
);
if
(
!
src_v
->
next
(
value
))
irt_bad_return
(
status
::
model_generator_empty_value_source
);
return
status
::
success
;
}
}
// namespace irt
#endif
lib/include/irritator/external_source.hpp
0 → 100644
View file @
33b0e646
// Copyright (c) 2020 INRA Distributed under the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef ORG_VLEPROJECT_IRRITATOR_EXTERNAL_SOURCE_2021
#define ORG_VLEPROJECT_IRRITATOR_EXTERNAL_SOURCE_2021
#include <irritator/core.hpp>
#include <array>
#include <filesystem>
#include <fstream>
namespace
irt
::
source
{
struct
binary_file
{
std
::
array
<
char
,
1024
*
1024
>
buffer
;
std
::
ifstream
ifs
;
sz
buffer_size
=
0
;
bool
use_rewind
=
false
;
binary_file
()
=
default
;
bool
init
(
external_source
&
src
)
{
if
(
!
read
(
src
))
return
false
;
}
bool
operator
()(
external_source
&
src
)
{
if
(
!
ifs
.
good
()
&&
!
use_rewind
)
return
false
;
if
(
!
ifs
.
good
())
ifs
.
seekg
(
0
);
if
(
!
read
(
src
))
return
false
;
return
true
;
}
private:
bool
read
(
external_source
&
src
)
{
ifs
.
read
(
buffer
.
data
(),
std
::
size
(
buffer
));
buffer_size
=
ifs
.
gcount
();
if
(
buffer_size
%
8
!=
0
)
return
false
;
src
.
data
=
reinterpret_cast
<
double
*>
(
buffer
.
data
());
src
.
index
=
0
;
src
.
size
=
buffer_size
/
8
;
return
true
;
}
};
struct
text_file
{
std
::
array
<
double
,
1024
*
1024
/
8
>
buffer
;
std
::
ifstream
ifs
;
bool
use_rewind
=
false
;
text_file
()
=
default
;
bool
init
(
external_source
&
src
)
{
if
(
!
read
(
src
))
return
false
;
}
bool
operator
()(
external_source
&
src
)
{
if
(
!
ifs
.
good
()
&&
!
use_rewind
)
return
false
;
if
(
!
ifs
.
good
())
ifs
.
seekg
(
0
);
if
(
!
read
(
src
))
return
false
;
return
true
;
}
private:
bool
read
(
external_source
&
src
)
{
size_t
i
=
0
;
for
(;
i
<
std
::
size
(
buffer
)
&&
ifs
.
good
();
++
i
)
{
if
(
!
(
ifs
>>
buffer
[
i
]))
break
;
}
src
.
data
=
buffer
.
data
();
src
.
index
=
0
;
src
.
size
=
i
;
return
true
;
}
};
struct
random_source
{
double
*
buffer
=
nullptr
;
sz
size
=
0
;
bool
use_rewind
;
random_source
()
=
default
;
~
random_source
()
noexcept
{
if
(
buffer
)
g_free_fn
(
buffer
);
}
template
<
typename
RandomGenerator
,
typename
Distribution
>
bool
init
(
const
sz
size_
,
RandomGenerator
&
gen
,
Distribution
&
dist
)
noexcept
{
if
(
!
size_
)
return
false
;
if
(
buffer
)
g_free_fn
(
buffer
);
size
=
0
;
buffer
=
g_alloc_fn
(
sizeof
(
double
)
*
size_
);
if
(
buffer
)
{
std
::
generate_n
(
buffer
,
size
,
(
*
dist
)(
*
gen
));
size
=
size_
;
return
true
;
}
return
false
;
}
bool
operator
()(
external_source
&
src
)
{
if
(
!
use_rewind
)
return
false
;
size
=
0
;
return
true
;
}
};
enum
class
random_file_type
{
binary
,
text
,
};
template
<
typename
RandomGenerator
,
typename
Distribution
>
inline
int
generate_random_file
(
std
::
ostream
&
os
,
RandomGenerator
&
gen
,
Distribution
&
dist
,
const
std
::
size_t
size
,
const
random_file_type
type
)
noexcept
{
switch
(
type
)
{
case
random_file_type
::
text
:
{
if
(
!
os
)
return
-
1
;
for
(
std
::
size_t
sz
=
0
;
sz
<
size
;
++
sz
)
if
(
!
(
os
<<
dist
(
gen
)
<<
'\n'
))
return
-
2
;
}
break
;
case
random_file_type
::
binary
:
{
if
(
!
os
)
return
-
1
;
for
(
std
::
size_t
sz
=
0
;
sz
<
size
;
++
sz
)
{
const
double
value
=
dist
(
gen
);
os
.
write
(
reinterpret_cast
<
const
char
*>
(
&
value
),
sizeof
(
value
));
}
}
break
;
}
return
0
;
}
}
// namespace irt::source
#endif
lib/include/irritator/io.hpp
View file @
33b0e646
...
...
@@ -58,6 +58,7 @@ static inline const char* dynamics_type_names[] = { "none",
"mult_3"
,
"mult_4"
,
"counter"
,
"buffer"
,
"generator"
,
"constant"
,
"cross"
,
...
...
@@ -133,6 +134,7 @@ get_input_port_names() noexcept
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
quantifier
>
||
std
::
is_same_v
<
Dynamics
,
counter
>
||
std
::
is_same_v
<
Dynamics
,
buffer
>
||
std
::
is_same_v
<
Dynamics
,
qss1_power
>
||
std
::
is_same_v
<
Dynamics
,
qss2_power
>
||
std
::
is_same_v
<
Dynamics
,
qss3_power
>
||
...
...
@@ -287,6 +289,7 @@ get_output_port_names() noexcept
std
::
is_same_v
<
Dynamics
,
mult_3
>
||
std
::
is_same_v
<
Dynamics
,
mult_4
>
||
std
::
is_same_v
<
Dynamics
,
counter
>
||
std
::
is_same_v
<
Dynamics
,
buffer
>
||
std
::
is_same_v
<
Dynamics
,
generator
>
||
std
::
is_same_v
<
Dynamics
,
constant
>
||
std
::
is_same_v
<
Dynamics
,
time_func
>
||
...
...
@@ -351,6 +354,7 @@ get_output_port_names(const dynamics_type type) noexcept
case
dynamics_type
::
mult_3
:
case
dynamics_type
::
mult_4
:
case
dynamics_type
::
counter
:
case
dynamics_type
::
buffer
:
case
dynamics_type
::
generator
:
case
dynamics_type
::
constant
:
case
dynamics_type
::
time_func
:
...
...
@@ -619,6 +623,7 @@ private:
{
"adder_2"
,
dynamics_type
::
adder_2
},
{
"adder_3"
,
dynamics_type
::
adder_3
},