|
@@ -41,6 +41,15 @@ namespace artis {
|
|
|
template<class Time>
|
|
|
class Integrator
|
|
|
: public artis::pdevs::Dynamics<Time, Integrator<Time>, IntegratorParameters> {
|
|
|
+
|
|
|
+ typedef enum {
|
|
|
+ INIT,
|
|
|
+ WAIT_FOR_QUANTA,
|
|
|
+ WAIT_FOR_X_DOT,
|
|
|
+ WAIT_FOR_BOTH,
|
|
|
+ RUNNING
|
|
|
+ } State;
|
|
|
+
|
|
|
public:
|
|
|
enum inputs {
|
|
|
QUANTA = 1, X_DOT
|
|
@@ -54,14 +63,40 @@ namespace artis {
|
|
|
VALUE
|
|
|
} Observable;
|
|
|
|
|
|
+ enum states {
|
|
|
+ STATE,
|
|
|
+ LAST_OUT_DATE,
|
|
|
+ UP_THRESHOLD,
|
|
|
+ DOWN_THRESHOLD,
|
|
|
+ LAST_OUT_VALUE,
|
|
|
+ INIT_VALUE,
|
|
|
+ CURRENT_VALUE,
|
|
|
+ EXPECTED_VALUE,
|
|
|
+ ARCHIVE_X_DOT,
|
|
|
+ ARCHIVE_DATE
|
|
|
+ };
|
|
|
+
|
|
|
Integrator(const std::string& name,
|
|
|
const Context<Time, Integrator<Time>, IntegratorParameters>& context)
|
|
|
:
|
|
|
artis::pdevs::Dynamics<Time, Integrator<Time>, IntegratorParameters>(name,
|
|
|
context)
|
|
|
{
|
|
|
- this->input_ports({{QUANTA, "quanta"},
|
|
|
- {X_DOT, "x_dot"}});
|
|
|
+ DECLARE_STATES(int, ((STATE, &Integrator<Time>::_state)));
|
|
|
+ DECLARE_STATES(typename Time::type,
|
|
|
+ ((LAST_OUT_DATE, &Integrator<Time>::_last_output_date)));
|
|
|
+ DECLARE_STATES(double, ((UP_THRESHOLD, &Integrator<Time>::_up_threshold),
|
|
|
+ (DOWN_THRESHOLD, &Integrator<Time>::_down_threshold),
|
|
|
+ (LAST_OUT_VALUE, &Integrator<Time>::_last_output_value),
|
|
|
+ (INIT_VALUE, &Integrator<Time>::_init_value),
|
|
|
+ (CURRENT_VALUE, &Integrator<Time>::_current_value),
|
|
|
+ (EXPECTED_VALUE, &Integrator<Time>::_expected_value)));
|
|
|
+ DECLARE_STATES(std::vector < double >, ((ARCHIVE_X_DOT, &Integrator<Time>::_archive_x_dot)));
|
|
|
+ DECLARE_STATES(std::vector <typename Time::type >, ((ARCHIVE_DATE, &Integrator<Time>::_archive_date)));
|
|
|
+
|
|
|
+ this->input_ports({
|
|
|
+ {QUANTA, "quanta"},
|
|
|
+ {X_DOT, "x_dot"}});
|
|
|
this->output_port({OUT, "out"});
|
|
|
this->observable({VALUE, "value"});
|
|
|
|
|
@@ -81,15 +116,14 @@ namespace artis {
|
|
|
{
|
|
|
switch (_state) {
|
|
|
case RUNNING: {
|
|
|
- record_t record;
|
|
|
- double last_derivative_value = _archive.back().x_dot;
|
|
|
+ double last_derivative_value = _archive_x_dot.back();
|
|
|
|
|
|
_last_output_value = _expected_value;
|
|
|
_last_output_date = time;
|
|
|
- _archive.clear();
|
|
|
- record.date = time;
|
|
|
- record.x_dot = last_derivative_value;
|
|
|
- _archive.push_back(record);
|
|
|
+ _archive_x_dot.clear();
|
|
|
+ _archive_date.clear();
|
|
|
+ _archive_x_dot.push_back(last_derivative_value);
|
|
|
+ _archive_date.push_back(time);
|
|
|
_current_value = _expected_value;
|
|
|
_state = WAIT_FOR_QUANTA;
|
|
|
break;
|
|
@@ -125,12 +159,10 @@ namespace artis {
|
|
|
}
|
|
|
if (event.on_port(X_DOT)) {
|
|
|
DerivativeData data;
|
|
|
- record_t record;
|
|
|
|
|
|
event.data()(data);
|
|
|
- record.date = t;
|
|
|
- record.x_dot = data.x_dot;
|
|
|
- _archive.push_back(record);
|
|
|
+ _archive_x_dot.push_back(data.x_dot);
|
|
|
+ _archive_date.push_back(t);
|
|
|
if (_state == WAIT_FOR_X_DOT) {
|
|
|
_state = RUNNING;
|
|
|
}
|
|
@@ -159,9 +191,9 @@ namespace artis {
|
|
|
switch (_state) {
|
|
|
case RUNNING:
|
|
|
|
|
|
- assert(_archive.size() > 0);
|
|
|
+ assert(_archive_date.size() > 0);
|
|
|
|
|
|
- current_derivative = _archive.back().x_dot;
|
|
|
+ current_derivative = _archive_x_dot.back();
|
|
|
if (current_derivative == 0) {
|
|
|
return Time::infinity;
|
|
|
}
|
|
@@ -220,19 +252,19 @@ namespace artis {
|
|
|
{
|
|
|
double val = _last_output_value;
|
|
|
|
|
|
- if (_archive.size() > 0) {
|
|
|
- for (size_t i = 0; i < _archive.size() - 1; i++) {
|
|
|
+ if (_archive_date.size() > 0) {
|
|
|
+ for (size_t i = 0; i < _archive_date.size() - 1; i++) {
|
|
|
val +=
|
|
|
- (_archive[i + 1].date - _archive[i].date) * _archive[i].x_dot;
|
|
|
+ (_archive_date[i + 1] - _archive_date[i]) * _archive_x_dot[i];
|
|
|
}
|
|
|
- val += (time - _archive.back().date) * _archive.back().x_dot;
|
|
|
+ val += (time - _archive_date.back()) * _archive_x_dot.back();
|
|
|
}
|
|
|
return val;
|
|
|
}
|
|
|
|
|
|
double expected_value(const typename Time::type& /* time */) const
|
|
|
{
|
|
|
- double current_derivative = _archive.back().x_dot;
|
|
|
+ double current_derivative = _archive_x_dot.back();
|
|
|
|
|
|
if (current_derivative == 0) {
|
|
|
return _current_value;
|
|
@@ -242,20 +274,7 @@ namespace artis {
|
|
|
return _down_threshold;
|
|
|
}
|
|
|
|
|
|
- typedef enum {
|
|
|
- INIT,
|
|
|
- WAIT_FOR_QUANTA,
|
|
|
- WAIT_FOR_X_DOT,
|
|
|
- WAIT_FOR_BOTH,
|
|
|
- RUNNING
|
|
|
- } State;
|
|
|
-
|
|
|
- struct record_t {
|
|
|
- double x_dot;
|
|
|
- typename Time::type date;
|
|
|
- };
|
|
|
-
|
|
|
- State _state;
|
|
|
+ int _state;
|
|
|
|
|
|
typename Time::type _last_output_date;
|
|
|
|
|
@@ -267,7 +286,8 @@ namespace artis {
|
|
|
double _current_value;
|
|
|
double _expected_value;
|
|
|
|
|
|
- std::deque<record_t> _archive;
|
|
|
+ std::vector<double> _archive_x_dot;
|
|
|
+ std::vector<typename Time::type> _archive_date;
|
|
|
};
|
|
|
|
|
|
}
|