Skip to content
GitLab
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
d152c2bb
Commit
d152c2bb
authored
Jun 24, 2020
by
Gauthier Quesnel
Browse files
core: add qss2 integrator
parent
2c2caa73
Pipeline
#14778
passed with stage
in 53 seconds
Changes
5
Pipelines
2
Hide whitespace changes
Inline
Side-by-side
app/gui/gui.hpp
View file @
d152c2bb
...
...
@@ -26,70 +26,6 @@ load_file_dialog(std::filesystem::path& out);
bool
save_file_dialog
(
std
::
filesystem
::
path
&
out
);
static
inline
const
char
*
simulation_status_string
[]
=
{
"success"
,
"running"
,
"uninitialized"
,
"internal_error"
,
};
static
inline
const
char
*
status_string
[]
=
{
"success"
,
"unknown_dynamics"
,
"block_allocator_bad_capacity"
,
"block_allocator_not_enough_memory"
,
"head_allocator_bad_capacity"
,
"head_allocator_not_enough_memory"
,
"simulation_not_enough_model"
,
"simulation_not_enough_memory_message_list_allocator"
,
"simulation_not_enough_memory_input_port_list_allocator"
,
"simulation_not_enough_memory_output_port_list_allocator"
,
"data_array_init_capacity_error"
,
"data_array_not_enough_memory"
,
"data_array_archive_init_capacity_error"
,
"data_array_archive_not_enough_memory"
,
"array_init_capacity_zero"
,
"array_init_capacity_too_big"
,
"array_init_not_enough_memory"
,
"vector_init_capacity_zero"
,
"vector_init_capacity_too_big"
,
"vector_init_not_enough_memory"
,
"dynamics_unknown_id"
,
"dynamics_unknown_port_id"
,
"dynamics_not_enough_memory"
,
"model_connect_output_port_unknown"
,
"model_connect_input_port_unknown"
,
"model_connect_already_exist"
,
"model_connect_bad_dynamics"
,
"model_adder_empty_init_message"
,
"model_adder_bad_init_message"
,
"model_adder_bad_external_message"
,
"model_mult_empty_init_message"
,
"model_mult_bad_init_message"
,
"model_mult_bad_external_message"
,
"model_integrator_internal_error"
,
"model_integrator_output_error"
,
"model_integrator_running_without_x_dot"
,
"model_integrator_ta_with_bad_x_dot"
,
"model_integrator_bad_external_message"
,
"model_quantifier_bad_quantum_parameter"
,
"model_quantifier_bad_archive_length_parameter"
,
"model_quantifier_shifting_value_neg"
,
"model_quantifier_shifting_value_less_1"
,
"model_quantifier_bad_external_message"
,
"model_cross_bad_external_message"
,
"model_time_func_bad_init_message"
,
"model_accumulator_bad_external_message"
,
"gui_not_enough_memory"
,
"io_file_format_error"
,
"io_file_format_model_error"
,
"io_file_format_model_number_error"
,
"io_file_format_model_unknown"
,
"io_file_format_dynamics_unknown"
,
"io_file_format_dynamics_limit_reach"
,
"io_file_format_dynamics_init_error"
};
}
// namespace irt
#endif
app/gui/node-editor.cpp
View file @
d152c2bb
...
...
@@ -38,8 +38,7 @@ static auto automatic_layout_y_distance = 350.f;
static
auto
grid_layout_x_distance
=
250.
f
;
static
auto
grid_layout_y_distance
=
250.
f
;
static
ImVec4
operator
*
(
const
ImVec4
&
lhs
,
const
float
rhs
)
noexcept
static
ImVec4
operator
*
(
const
ImVec4
&
lhs
,
const
float
rhs
)
noexcept
{
return
ImVec4
(
lhs
.
x
*
rhs
,
lhs
.
y
*
rhs
,
lhs
.
z
*
rhs
,
lhs
.
w
*
rhs
);
}
...
...
@@ -206,16 +205,14 @@ run_simulation(simulation& sim,
if
(
auto
ret
=
sim
.
initialize
(
current
);
irt
::
is_bad
(
ret
))
{
log_w
.
log
(
3
,
"Simulation initialization failure (%s)
\n
"
,
irt
::
status_string
[
static_cast
<
int
>
(
ret
)
]
);
irt
::
status_string
(
ret
));
st
=
simulation_status
::
internal_error
;
return
;
}
do
{
if
(
auto
ret
=
sim
.
run
(
current
);
irt
::
is_bad
(
ret
))
{
log_w
.
log
(
3
,
"Simulation failure (%s)
\n
"
,
irt
::
status_string
[
static_cast
<
int
>
(
ret
)]);
log_w
.
log
(
3
,
"Simulation failure (%s)
\n
"
,
irt
::
status_string
(
ret
));
st
=
simulation_status
::
internal_error
;
return
;
...
...
@@ -665,48 +662,49 @@ struct copier
auto
ret
=
sim
.
dispatch
(
mdl
->
type
,
[
this
,
&
sim
,
mdl
,
&
mdl_id_dst
]
<
typename
DynamicsM
>
(
DynamicsM
&
dynamics_models
)
->
status
{
using
Dynamics
=
typename
DynamicsM
::
value_type
;
[
this
,
&
sim
,
mdl
,
&
mdl_id_dst
]
<
typename
DynamicsM
>
(
DynamicsM
&
dynamics_models
)
->
status
{
using
Dynamics
=
typename
DynamicsM
::
value_type
;
irt_return_if_fail
(
dynamics_models
.
can_alloc
(
1
),
status
::
dynamics_not_enough_memory
);
irt_return_if_fail
(
dynamics_models
.
can_alloc
(
1
),
status
::
dynamics_not_enough_memory
);
auto
*
dyn_ptr
=
dynamics_models
.
try_to_get
(
mdl
->
id
);
irt_return_if_fail
(
dyn_ptr
,
status
::
dynamics_unknown_id
);
auto
*
dyn_ptr
=
dynamics_models
.
try_to_get
(
mdl
->
id
);
irt_return_if_fail
(
dyn_ptr
,
status
::
dynamics_unknown_id
);
auto
&
new_dyn
=
dynamics_models
.
alloc
(
*
dyn_ptr
);
auto
new_dyn_id
=
dynamics_models
.
get_id
(
new_dyn
);
auto
&
new_dyn
=
dynamics_models
.
alloc
(
*
dyn_ptr
);
auto
new_dyn_id
=
dynamics_models
.
get_id
(
new_dyn
);
if
constexpr
(
is_detected_v
<
has_input_port_t
,
Dynamics
>
)
std
::
fill_n
(
new_dyn
.
x
,
std
::
size
(
new_dyn
.
x
),
static_cast
<
input_port_id
>
(
0
));
if
constexpr
(
is_detected_v
<
has_input_port_t
,
Dynamics
>
)
std
::
fill_n
(
new_dyn
.
x
,
std
::
size
(
new_dyn
.
x
),
static_cast
<
input_port_id
>
(
0
));
if
constexpr
(
is_detected_v
<
has_output_port_t
,
Dynamics
>
)
std
::
fill_n
(
new_dyn
.
y
,
std
::
size
(
new_dyn
.
y
),
static_cast
<
output_port_id
>
(
0
));
if
constexpr
(
is_detected_v
<
has_output_port_t
,
Dynamics
>
)
std
::
fill_n
(
new_dyn
.
y
,
std
::
size
(
new_dyn
.
y
),
static_cast
<
output_port_id
>
(
0
));
irt_return_if_bad
(
sim
.
alloc
(
new_dyn
,
new_dyn_id
,
mdl
->
name
.
c_str
()));
irt_return_if_bad
(
sim
.
alloc
(
new_dyn
,
new_dyn_id
,
mdl
->
name
.
c_str
()));
*
mdl_id_dst
=
new_dyn
.
id
;
*
mdl_id_dst
=
new_dyn
.
id
;
if
constexpr
(
is_detected_v
<
has_input_port_t
,
Dynamics
>
)
for
(
size_t
j
=
0
,
ej
=
std
::
size
(
new_dyn
.
x
);
j
!=
ej
;
++
j
)
this
->
c_input_ports
.
emplace_back
(
dyn_ptr
->
x
[
j
],
new_dyn
.
x
[
j
]);
if
constexpr
(
is_detected_v
<
has_input_port_t
,
Dynamics
>
)
for
(
size_t
j
=
0
,
ej
=
std
::
size
(
new_dyn
.
x
);
j
!=
ej
;
++
j
)
this
->
c_input_ports
.
emplace_back
(
dyn_ptr
->
x
[
j
],
new_dyn
.
x
[
j
]);
if
constexpr
(
is_detected_v
<
has_output_port_t
,
Dynamics
>
)
for
(
size_t
j
=
0
,
ej
=
std
::
size
(
new_dyn
.
y
);
j
!=
ej
;
++
j
)
this
->
c_output_ports
.
emplace_back
(
dyn_ptr
->
y
[
j
],
new_dyn
.
y
[
j
]);
if
constexpr
(
is_detected_v
<
has_output_port_t
,
Dynamics
>
)
for
(
size_t
j
=
0
,
ej
=
std
::
size
(
new_dyn
.
y
);
j
!=
ej
;
++
j
)
this
->
c_output_ports
.
emplace_back
(
dyn_ptr
->
y
[
j
],
new_dyn
.
y
[
j
]);
return
status
::
success
;
});
return
status
::
success
;
});
irt_return_if_bad
(
ret
);
}
...
...
@@ -1398,621 +1396,561 @@ editor::show_model_cluster(cluster& mdl) noexcept
}
}
void
editor
::
show_model_dynamics
(
model
&
mdl
)
noexcept
static
const
char
*
str_empty
[]
=
{
""
};
static
const
char
*
str_integrator
[]
=
{
"x-dot"
,
"reset"
};
static
const
char
*
str_adaptative_integrator
[]
=
{
"quanta"
,
"x-dot"
,
"reset"
};
static
const
char
*
str_in_1
[]
=
{
"in"
};
static
const
char
*
str_in_2
[]
=
{
"in-1"
,
"in-2"
};
static
const
char
*
str_in_3
[]
=
{
"in-1"
,
"in-2"
,
"in-3"
};
static
const
char
*
str_in_4
[]
=
{
"in-1"
,
"in-2"
,
"in-3"
,
"in-4"
};
static
const
char
*
str_value_if_else
[]
=
{
"value"
,
"if"
,
"else"
};
static
const
char
*
str_in_2_nb_2
[]
=
{
"in-1"
,
"in-2"
,
"nb-1"
,
"nb-2"
};
static
const
char
*
str_out_1
[]
=
{
"out"
};
static
const
char
*
str_out_2
[]
=
{
"out-1"
,
"out-2"
};
template
<
typename
Dynamics
>
static
constexpr
const
char
**
get_input_port_names
()
{
ImGui
::
PushItemWidth
(
100.0
f
);
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
none
>
)
return
str_empty
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
qss1_integrator
>
)
return
str_integrator
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
qss2_integrator
>
)
return
str_integrator
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
qss2_multiplier
>
)
return
str_in_2
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
qss2_sum_2
>
)
return
str_in_2
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
qss2_sum_3
>
)
return
str_in_3
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
qss2_sum_4
>
)
return
str_in_4
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
qss2_wsum_2
>
)
return
str_in_2
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
qss2_wsum_3
>
)
return
str_in_3
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
qss2_wsum_4
>
)
return
str_in_4
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
integrator
>
)
return
str_adaptative_integrator
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
quantifier
>
)
return
str_in_1
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
adder_2
>
)
return
str_in_2
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
adder_3
>
)
return
str_in_3
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
adder_4
>
)
return
str_in_4
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
mult_2
>
)
return
str_in_2
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
mult_3
>
)
return
str_in_3
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
mult_4
>
)
return
str_in_4
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
counter
>
)
return
str_in_1
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
generator
>
)
return
str_empty
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
constant
>
)
return
str_empty
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
cross
>
)
return
str_value_if_else
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
accumulator_2
>
)
return
str_in_2_nb_2
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
time_func
>
)
return
str_empty
;
}
{
const
char
*
items
[]
=
{
"none"
,
"plot"
,
"file"
,
"both"
};
int
current_item
=
0
;
/* Default show none */
auto
*
obs
=
sim
.
observers
.
try_to_get
(
mdl
.
obs_id
);
template
<
typename
Dynamics
>
static
constexpr
const
char
**
get_output_port_names
()
{
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
none
>
)
return
str_empty
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
qss1_integrator
>
)
return
str_out_1
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
qss2_integrator
>
)
return
str_out_1
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
qss2_multiplier
>
)
return
str_out_1
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
qss2_sum_2
>
)
return
str_out_1
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
qss2_sum_3
>
)
return
str_out_1
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
qss2_sum_4
>
)
return
str_out_1
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
qss2_wsum_2
>
)
return
str_out_1
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
qss2_wsum_3
>
)
return
str_out_1
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
qss2_wsum_4
>
)
return
str_out_1
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
integrator
>
)
return
str_out_1
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
quantifier
>
)
return
str_out_1
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
adder_2
>
)
return
str_out_1
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
adder_3
>
)
return
str_out_1
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
adder_4
>
)
return
str_out_1
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
mult_2
>
)
return
str_out_1
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
mult_3
>
)
return
str_out_1
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
mult_4
>
)
return
str_out_1
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
counter
>
)
return
str_out_1
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
generator
>
)
return
str_out_1
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
constant
>
)
return
str_out_1
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
cross
>
)
return
str_out_2
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
accumulator_2
>
)
return
str_empty
;
else
if
constexpr
(
std
::
is_same_v
<
Dynamics
,
time_func
>
)
return
str_out_1
;
}
if
(
obs
)
current_item
=
static_cast
<
int
>
(
observation_types
[
get_index
(
mdl
.
obs_id
)]);
template
<
typename
Dynamics
>
static
void
add_input_attribute
(
editor
&
ed
,
const
Dynamics
&
dyn
)
noexcept
{
if
constexpr
(
is_detected_v
<
has_input_port_t
,
Dynamics
>
)
{
const
auto
**
names
=
get_input_port_names
<
Dynamics
>
();
if
(
ImGui
::
Combo
(
"observation"
,
&
current_item
,
items
,
IM_ARRAYSIZE
(
items
)))
{
if
(
current_item
==
0
)
{
if
(
obs
)
{
observation_types
[
get_index
(
mdl
.
obs_id
)]
=
observation_output
::
type
::
none
;
sim
.
observers
.
free
(
*
obs
);
mdl
.
obs_id
=
static_cast
<
observer_id
>
(
0
);
}
}
else
{
if
(
!
obs
)
{
auto
&
o
=
sim
.
observers
.
alloc
(
0.01
,
mdl
.
name
.
c_str
(),
nullptr
);
sim
.
observe
(
mdl
,
o
);
}
for
(
size_t
i
=
0
,
e
=
std
::
size
(
dyn
.
x
);
i
!=
e
;
++
i
)
{
imnodes
::
BeginInputAttribute
(
ed
.
get_in
(
dyn
.
x
[
i
]));
ImGui
::
TextUnformatted
(
names
[
i
]);
imnodes
::
EndAttribute
();
}
}
}
observation_types
[
get_index
(
mdl
.
obs_id
)]
=
current_item
==
1
?
observation_output
::
type
::
plo
t
:
current_item
==
2
?
observation_output
::
type
::
file
:
observation_output
::
type
::
both
;
}
template
<
typename
Dynamics
>
static
void
add_output_attribute
(
editor
&
ed
,
const
Dynamics
&
dyn
)
noexcep
t
{
if
constexpr
(
is_detected_v
<
has_output_port_t
,
Dynamics
>
)
{
const
auto
**
names
=
get_output_port_names
<
Dynamics
>
();
if
(
auto
*
o
=
sim
.
observers
.
try_to_get
(
mdl
.
obs_id
);
o
)
{
float
v
=
static_cast
<
float
>
(
o
->
time_step
);
if
(
ImGui
::
InputFloat
(
"freq."
,
&
v
,
0.001
f
,
0.1
f
,
"%.3f"
,
0
))
o
->
time_step
=
static_cast
<
double
>
(
v
);
}
for
(
size_t
i
=
0
,
e
=
std
::
size
(
dyn
.
y
);
i
!=
e
;
++
i
)
{
imnodes
::
BeginOutputAttribute
(
ed
.
get_out
(
dyn
.
y
[
i
]));
ImGui
::
TextUnformatted
(
names
[
i
]);
imnodes
::
EndAttribute
();
}
}
}
ImGui
::
PopItemWidth
();
static
void
show_dynamics_values
(
const
none
&
/*dyn*/
)
{}
if
(
simulation_show_value
&&
match
(
st
,
simulation_status
::
success
,
simulation_status
::
running
))
{
switch
(
mdl
.
type
)
{
case
dynamics_type
::
none
:
/* none does not have input port. */
break
;
case
dynamics_type
::
integrator
:
{
auto
&
dyn
=
sim
.
integrator_models
.
get
(
mdl
.
id
);
imnodes
::
BeginInputAttribute
(
get_in
(
dyn
.
x
[
0
]));
ImGui
::
TextUnformatted
(
"quanta"
);
imnodes
::
EndAttribute
();
imnodes
::
BeginInputAttribute
(
get_in
(
dyn
.
x
[
1
]));
ImGui
::
TextUnformatted
(
"x_dot"
);
imnodes
::
EndAttribute
();
imnodes
::
BeginInputAttribute
(
get_in
(
dyn
.
x
[
2
]));
ImGui
::
TextUnformatted
(
"reset"
);
imnodes
::
EndAttribute
();
static
void
show_dynamics_values
(
const
qss1_integrator
&
dyn
)
{
ImGui
::
Text
(
"X %.3f"
,
dyn
.
X
);
ImGui
::
Text
(
"dQ %.3f"
,
dyn
.
dQ
);
}
ImGui
::
PushItemWidth
(
120.0
f
);
ImGui
::
Text
(
"value %.3f"
,
dyn
.
current_value
);
ImGui
::
PopItemWidth
();
static
void
show_dynamics_values
(
const
qss2_integrator
&
dyn
)
{
ImGui
::
Text
(
"X %.3f"
,
dyn
.
X
);
ImGui
::
Text
(
"dQ %.3f"
,
dyn
.
dQ
);
}
imnodes
::
BeginOutputAttribute
(
get_out
(
dyn
.
y
[
0
]));
const
float
text_width
=
ImGui
::
CalcTextSize
(
"x"
).
x
;
ImGui
::
Indent
(
120.
f
+
ImGui
::
CalcTextSize
(
"quanta"
).
x
-
text_width
);
ImGui
::
TextUnformatted
(
"x"
);
imnodes
::
EndAttribute
();
}
break
;
case
dynamics_type
::
quantifier
:
{
auto
&
dyn
=
sim
.
quantifier_models
.
get
(
mdl
.
id
);
imnodes
::
BeginInputAttribute
(
get_in
(
dyn
.
x
[
0
]));
ImGui
::
TextUnformatted
(
"x_dot"
);
imnodes
::
EndAttribute
();
static
void
show_dynamics_values
(
const
qss2_sum_2
&
dyn
)
{
ImGui
::
Text
(
"%.3f %.3f"
,
dyn
.
values
[
0
],
dyn
.
slopes
[
0
]);
ImGui
::
Text
(
"%.3f %.3f"
,
dyn
.
values
[
1
],
dyn
.
slopes
[
1
]);
}
ImGui
::
PushItemWidth
(
120.0
f
);
ImGui
::
Text
(
"up threshold %.3f"
,
dyn
.
m_upthreshold
);
ImGui
::
Text
(
"down threshold %.3f"
,
dyn
.
m_downthreshold
);
ImGui
::
PopItemWidth
();
static
void
show_dynamics_values
(
const
qss2_sum_3
&
dyn
)
{
ImGui
::
Text
(
"%.3f %.3f"
,
dyn
.
values
[
0
],
dyn
.
slopes
[
0
]);
ImGui
::
Text
(
"%.3f %.3f"
,
dyn
.
values
[
1
],
dyn
.
slopes
[
1
]);
ImGui
::
Text
(
"%.3f %.3f"
,
dyn
.
values
[
2
],
dyn
.
slopes
[
2
]);
}
imnodes
::
BeginOutputAttribute
(
get_out
(
dyn
.
y
[
0
]));
ImGui
::
TextUnformatted
(
"quanta"
);
imnodes
::
EndAttribute
();
}
break
;
case
dynamics_type
::
adder_2
:
{
auto
&
dyn
=
sim
.
adder_2_models
.
get
(
mdl
.
id
);
imnodes
::
BeginInputAttribute
(
get_in
(
dyn
.
x
[
0
]));
ImGui
::
TextUnformatted
(
"x0"
);
imnodes
::
EndAttribute
();
imnodes
::
BeginInputAttribute
(
get_in
(
dyn
.
x
[
1
]));
ImGui
::
TextUnformatted
(
"x1"
);
imnodes
::
EndAttribute
();
static
void
show_dynamics_values
(
const
qss2_sum_4
&
dyn
)
{
ImGui
::
Text
(
"%.3f %.3f"
,
dyn
.
values
[
0
],
dyn
.
slopes
[
0
]);
ImGui
::
Text
(
"%.3f %.3f"
,
dyn
.
values
[
1
],
dyn
.
slopes
[
1
]);
ImGui
::
Text
(
"%.3f %.3f"
,
dyn
.
values
[
2
],
dyn
.
slopes
[
2
]);
ImGui
::
Text
(
"%.3f %.3f"
,
dyn
.
values
[
3
],
dyn
.
slopes
[
3
]);
}
ImGui
::
PushItemWidth
(
120.0
f
);
ImGui
::
Text
(
"%.3f * %.3f"
,
dyn
.
values
[
0
],
dyn
.
input_coeffs
[
0
]);
ImGui
::
Text
(
"%.3f * %.3f"
,
dyn
.
values
[
1
],
dyn
.
input_coeffs
[
1
]);
ImGui
::
PopItemWidth
();
static
void
show_dynamics_values
(
const
qss2_multiplier
&
dyn
)
{
ImGui
::
Text
(
"%.3f %.3f"
,
dyn
.
values
[
0
],
dyn
.
slopes
[
0
]);
ImGui
::
Text
(
"%.3f %.3f"
,
dyn
.
values
[
1
],
dyn
.
slopes
[
1
]);
}
imnodes
::
BeginOutputAttribute
(
get_out
(
dyn
.
y
[
0
]));
const
float
text_width
=
ImGui
::
CalcTextSize
(
"sum"
).
x
;
ImGui
::
Indent
(
120.
f
+
ImGui
::
CalcTextSize
(
"coeff-0"
).
x
-
text_width
);
ImGui
::
TextUnformatted
(
"sum"
);
imnodes
::
EndAttribute
();
}
break
;
case
dynamics_type
::
adder_3
:
{
auto
&
dyn
=
sim
.
adder_3_models
.
get
(
mdl
.
id
);
imnodes
::
BeginInputAttribute
(
get_in
(
dyn
.
x
[
0
]));
ImGui
::
TextUnformatted
(
"x0"
);
imnodes
::
EndAttribute
();
imnodes
::
BeginInputAttribute
(
get_in
(
dyn
.
x
[
1
]));
ImGui
::
TextUnformatted
(
"x1"
);
imnodes
::
EndAttribute
();
imnodes
::
BeginInputAttribute
(
get_in
(
dyn
.
x
[
2
]));
ImGui
::
TextUnformatted
(
"x2"
);
imnodes
::
EndAttribute
();
static
void
show_dynamics_values
(
const
qss2_wsum_2
&
dyn
)
{
ImGui
::
Text
(
"%.3f %.3f"
,
dyn
.
values
[
0
],
dyn
.
slopes
[
0
]);
ImGui
::
Text
(
"%.3f %.3f"
,
dyn
.
values
[
1
],
dyn
.
slopes
[
1
]);
}
ImGui
::
PushItemWidth
(
120.0
f
);
ImGui
::
Text
(
"%.3f * %.3f"
,
dyn
.
values
[
0
],
dyn
.
input_coeffs
[
0
]);
ImGui
::
Text
(
"%.3f * %.3f"
,
dyn
.
values
[
1
],
dyn
.
input_coeffs
[
1
]);
ImGui
::
Text
(
"%.3f * %.3f"
,
dyn
.
values
[
2
],
dyn
.
input_coeffs
[
2
]);
ImGui
::
PopItemWidth
();
static
void
show_dynamics_values
(
const
qss2_wsum_3
&
dyn
)
{
ImGui
::
Text
(
"%.3f %.3f"
,
dyn
.
values
[
0
],
dyn
.
slopes
[
0
]);
ImGui
::
Text
(
"%.3f %.3f"
,
dyn
.
values
[
1
],
dyn
.
slopes
[
1
]);
ImGui
::
Text
(
"%.3f %.3f"
,
dyn
.
values
[
2
],
dyn
.
slopes
[
2
]);
}
imnodes
::
BeginOutputAttribute
(
get_out
(
dyn
.
y
[
0
]));
const
float
text_width
=
ImGui
::
CalcTextSize
(
"sum"
).
x
;
ImGui
::
Indent
(
120.
f
+
ImGui
::
CalcTextSize
(
"coeff-0"
).
x
-
text_width
);
ImGui
::
TextUnformatted
(
"sum"
);
imnodes
::
EndAttribute
();
}
break
;
case
dynamics_type
::
adder_4
:
{
auto
&
dyn
=
sim
.
adder_4_models
.
get
(
mdl
.
id
);
imnodes
::
BeginInputAttribute
(
get_in
(
dyn
.
x
[
0
]));
ImGui
::
TextUnformatted
(
"x0"
);
imnodes
::
EndAttribute
();
imnodes
::
BeginInputAttribute
(
get_in
(
dyn
.
x
[
1
]));
ImGui
::
TextUnformatted
(
"x1"
);
imnodes
::
EndAttribute
();
imnodes
::
BeginInputAttribute
(
get_in
(
dyn
.
x
[
2
]));
ImGui
::
TextUnformatted
(
"x2"
);
imnodes
::
EndAttribute
();
imnodes
::
BeginInputAttribute
(
get_in
(
dyn
.
x
[
3
]));
ImGui
::
TextUnformatted
(
"x3"
);
imnodes
::
EndAttribute
();
static
void
show_dynamics_values
(
const
qss2_wsum_4
&
dyn
)
{
ImGui
::
Text
(
"%.3f %.3f"
,
dyn
.
values
[
0
],
dyn
.
slopes
[
0
]);
ImGui
::
Text
(
"%.3f %.3f"
,
dyn
.
values
[
1
],
dyn
.
slopes
[
1
]);
ImGui
::
Text
(
"%.3f %.3f"
,
dyn
.
values
[
2
],
dyn
.
slopes
[
2
]);
ImGui
::
Text
(
"%.3f %.3f"
,
dyn
.
values
[
3
],
dyn
.
slopes
[
3
]);
}
ImGui
::
PushItemWidth
(
120.0
f
);
ImGui
::
Text
(
"%.3f * %.3f"
,
dyn
.
values
[
0
],
dyn
.
input_coeffs
[
0
]);
ImGui
::
Text
(
"%.3f * %.3f"
,
dyn
.
values
[
1
],
dyn
.
input_coeffs
[
1
]);
ImGui
::
Text
(
"%.3f * %.3f"
,
dyn
.
values
[
2
],
dyn
.
input_coeffs
[
2
]);
ImGui
::
Text
(
"%.3f * %.3f"
,
dyn
.
values
[
3
],
dyn
.
input_coeffs
[
3
]);
ImGui
::
PopItemWidth
();
static
void
show_dynamics_values
(
const
integrator
&
dyn
)
{
ImGui
::
Text
(
"value %.3f"
,
dyn
.
current_value
);
}
imnodes
::
BeginOutputAttribute
(
get_out
(
dyn
.
y
[
0
]));
const
float
text_width
=
ImGui
::
CalcTextSize
(
"sum"
).
x
;
ImGui
::
Indent
(
120.
f
+
ImGui
::
CalcTextSize
(
"coeff-0"
).
x
-
text_width
);
ImGui
::
TextUnformatted
(
"sum"
);
imnodes
::
EndAttribute
();
}
break
;
case
dynamics_type
::
mult_2
:
{
auto
&
dyn
=
sim
.
mult_2_models
.
get
(
mdl
.
id
);
imnodes
::
BeginInputAttribute
(
get_in
(
dyn
.
x
[
0
]));
ImGui
::
TextUnformatted
(
"x0"
);
imnodes
::
EndAttribute
();
imnodes
::
BeginInputAttribute
(
get_in
(
dyn
.
x
[
1
]));
ImGui
::
TextUnformatted
(
"x1"
);
imnodes
::
EndAttribute
();
static
void
show_dynamics_values
(
const
quantifier
&
dyn
)
{
ImGui
::
Text
(
"up threshold %.3f"
,
dyn
.
m_upthreshold
);
ImGui
::
Text
(
"down threshold %.3f"
,
dyn
.
m_downthreshold
);
}
ImGui
::
PushItemWidth
(
120.0
f
);
ImGui
::
Text
(
"%.3f * %.3f"
,
dyn
.
values
[
0
],
dyn
.
input_coeffs
[
0
]);
ImGui
::
Text
(
"%.3f * %.3f"
,
dyn
.
values
[
1
],
dyn
.
input_coeffs
[
1
]);
ImGui
::
PopItemWidth
();
static
void
show_dynamics_values
(
const
adder_2
&
dyn
)
{
ImGui
::
Text
(
"%.3f * %.3f"
,
dyn
.
values
[
0
],
dyn
.
input_coeffs
[
0
]);
ImGui
::
Text
(
"%.3f * %.3f"
,
dyn
.
values
[
1
],
dyn
.
input_coeffs
[
1
]);
}