Browse Source

QSS: add reset mecanisms

Eric Ramat 1 year ago
parent
commit
63d1dacd57

+ 37 - 25
src/artis-star/kernel/pdevs/qss/Derivative.hpp

@@ -42,7 +42,7 @@ namespace artis {
 
             public:
                 enum inputs {
-                    IN = 0
+                    RESET = 0, IN
                 };
 
                 enum outputs {
@@ -68,7 +68,8 @@ namespace artis {
                             ((OUTPUT_VALUE, &type::_output_value),
                                     (LAST_OUTPUT, &type::_output_value)));
 
-                    this->input_port({IN, "in"});
+                    this->input_ports({{RESET, "reset"},
+                                       {IN,    "in"}});
                     this->output_port({OUT, "out"});
                 }
 
@@ -112,28 +113,39 @@ namespace artis {
                 {
                     std::for_each(bag.begin(), bag.end(),
                             [this, t, e](const common::ExternalEvent<Time>& event) {
-                                IntegratorData data;
-
-                                event.data()(data);
-                                this->get(event.port_index() + LAST_OUTPUT + 1).put(
-                                        dynamic_cast<Dyn*>(this),
-                                        data.value);
-                                switch (_state) {
-                                case INIT:
-                                    if (_input_number == this->state_number() - (LAST_OUTPUT + 1)) {
-                                        _output_value = compute();
-                                        _state = RESPONSE;
-                                    }
-                                    break;
-                                case WAIT:
-                                case RESPONSE:
-                                    double value = compute();
-
-                                    if (value != _last_output) {
-                                        _output_value = value;
-                                        _state = RESPONSE;
-                                    } else {
-                                        _state = WAIT;
+                                if (event.on_port(RESET)) {
+                                    IntegratorData data;
+
+                                    event.data()(data);
+                                    this->get(LAST_OUTPUT + 1).put(dynamic_cast<Dyn*>(this),
+                                            data.value);
+                                    _output_value = compute();
+                                    _state = RESPONSE;
+                                } else {
+                                    IntegratorData data;
+
+                                    event.data()(data);
+                                    this->get((event.port_index() - 1) + LAST_OUTPUT + 1).put(
+                                            dynamic_cast<Dyn*>(this),
+                                            data.value);
+                                    switch (_state) {
+                                    case INIT:
+                                        if (_input_number
+                                                == this->state_number() - (LAST_OUTPUT + 1)) {
+                                            _output_value = compute();
+                                            _state = RESPONSE;
+                                        }
+                                        break;
+                                    case WAIT:
+                                    case RESPONSE:
+                                        double value = compute();
+
+                                        if (value != _last_output) {
+                                            _output_value = value;
+                                            _state = RESPONSE;
+                                        } else {
+                                            _state = WAIT;
+                                        }
                                     }
                                 }
                             });
@@ -141,7 +153,7 @@ namespace artis {
 
                 virtual void start(typename Time::type /* time */)
                 {
-                    _input_number = this->input_port_number();
+                    _input_number = this->input_port_number() - 1;
                     if (_input_number == 0) {
                         _output_value = compute();
                         _state = RESPONSE;

+ 15 - 3
src/artis-star/kernel/pdevs/qss/GraphManager.hpp

@@ -35,7 +35,7 @@ namespace artis {
     namespace pdevs {
         namespace qss {
 
-            template <class DerivativeParameters>
+            template<class DerivativeParameters>
             struct QSSParameters {
                 IntegratorParameters integrator;
                 QuantifierParameters quantifier;
@@ -52,6 +52,10 @@ namespace artis {
                     S_Derivative, S_Integrator, S_Quantifier
                 };
 
+                enum inputs {
+                    RESET
+                };
+
                 enum outputs {
                     OUT
                 };
@@ -73,8 +77,16 @@ namespace artis {
                     this->add_child(S_Integrator, &_integrator);
                     this->add_child(S_Quantifier, &_quantifier);
 
+                    coordinator->input_port({RESET, "reset"});
                     coordinator->output_port({OUT, "out"});
 
+                    this->in({coordinator, RESET})
+                            >> this->in({&_derivative, Derivative::RESET});
+                    this->in({coordinator, RESET})
+                            >> this->in({&_integrator, Integrator<Time>::RESET});
+                    this->in({coordinator, RESET})
+                            >> this->in({&_quantifier, Quantifier<Time>::RESET});
+
                     this->out({&_derivative, Derivative::OUT})
                             >> this->in({&_integrator, Integrator<Time>::X_DOT});
                     this->out({&_integrator, Integrator<Time>::OUT})
@@ -89,8 +101,8 @@ namespace artis {
 
                 ~GraphManager() override = default;
 
-                artis::pdevs::Simulator<Time, Derivative, DerivativeParameters>* derivative()
-                { return &_derivative; }
+                artis::pdevs::Simulator<Time, Derivative, DerivativeParameters>*
+                derivative() { return &_derivative; }
 
             private:
                 artis::pdevs::Simulator<Time, Derivative, DerivativeParameters> _derivative;

+ 11 - 5
src/artis-star/kernel/pdevs/qss/Integrator.hpp

@@ -52,11 +52,11 @@ namespace artis {
 
             public:
                 enum inputs {
-                    QUANTA = 1, X_DOT
+                    QUANTA, X_DOT, RESET
                 };
 
                 enum outputs {
-                    OUT = 1
+                    OUT
                 };
 
                 typedef enum vars {
@@ -98,7 +98,8 @@ namespace artis {
 
                     this->input_ports({
                             {QUANTA, "quanta"},
-                            {X_DOT,  "x_dot"}});
+                            {X_DOT,  "x_dot"},
+                            {RESET,  "reset"}});
                     this->output_port({OUT, "out"});
                     this->observable({VALUE, "value"});
 
@@ -158,8 +159,7 @@ namespace artis {
                                     if (_state == WAIT_FOR_BOTH) {
                                         _state = WAIT_FOR_X_DOT;
                                     }
-                                }
-                                if (event.on_port(X_DOT)) {
+                                } else if (event.on_port(X_DOT)) {
                                     DerivativeData data;
 
                                     event.data()(data);
@@ -171,6 +171,12 @@ namespace artis {
                                     if (_state == WAIT_FOR_BOTH) {
                                         _state = WAIT_FOR_QUANTA;
                                     }
+                                } else if (event.on_port(RESET)) {
+                                    IntegratorData data;
+
+                                    event.data()(data);
+                                    _current_value = data.value;
+                                    _state = INIT;
                                 }
                             });
                     if (_state == RUNNING) {

+ 54 - 48
src/artis-star/kernel/pdevs/qss/Quantifier.hpp

@@ -48,11 +48,11 @@ namespace artis {
                     : public artis::pdevs::Dynamics<Time, Quantifier<Time>, QuantifierParameters> {
             public:
                 enum inputs {
-                    IN = 1
+                    IN, RESET
                 };
 
                 enum outputs {
-                    OUT = 1
+                    OUT
                 };
 
                 enum states {
@@ -72,7 +72,8 @@ namespace artis {
                     DECLARE_STATES(double,
                             ((OFFSET, &Quantifier<Time>::_offset), (UP_THRESHOLD, &Quantifier<Time>::_up_threshold), (DOWN_THRESHOLD, &Quantifier<Time>::_down_threshold)));
 
-                    this->input_port({IN, "in"});
+                    this->input_ports({{IN,    "in"},
+                                       {RESET, "reset"}});
                     this->output_port({OUT, "out"});
                     this->observables({{UP,    "up"},
                                        {DOWN,  "down"},
@@ -117,61 +118,66 @@ namespace artis {
                 {
                     std::for_each(bag.begin(), bag.end(),
                             [this, t, e](const common::ExternalEvent<Time>& event) {
-                                IntegratorData data;
-                                double shifting_factor;
-                                double value;
-                                int cnt;
-
-                                event.data()(data);
-                                value = data.value;
-                                if (_state == INIT) {
-                                    init_step_number_and_offset(value);
-                                    update_thresholds();
-                                    _state = RESPONSE;
-                                } else {
-                                    cnt = 0;
-                                    while (value >= _up_threshold or value <= _down_threshold) {
-                                        cnt++;
-                                        if (value >= _up_threshold) {
-                                            _step_number++;
-                                        } else {
-                                            _step_number--;
-                                        }
-                                        switch (_adaptive_state) {
-                                        case IMPOSSIBLE:
-                                            update_thresholds();
-                                            break;
-                                        case POSSIBLE:
+                                if (event.on_port(IN)) {
+                                    IntegratorData data;
+                                    double shifting_factor;
+                                    double value;
+                                    int cnt;
+
+                                    event.data()(data);
+                                    value = data.value;
+                                    if (_state == INIT) {
+                                        init_step_number_and_offset(value);
+                                        update_thresholds();
+                                        _state = RESPONSE;
+                                    } else {
+                                        cnt = 0;
+                                        while (value >= _up_threshold or value <= _down_threshold) {
+                                            cnt++;
                                             if (value >= _up_threshold) {
-                                                store_change(_step_size, t);
+                                                _step_number++;
                                             } else {
-                                                store_change(-_step_size, t);
+                                                _step_number--;
                                             }
-                                            shifting_factor = shift_quanta();
-
-                                            assert(shifting_factor >= 0
-                                                    and shifting_factor <= 1);
-
-                                            if (shifting_factor != 0 and shifting_factor != 1) {
+                                            switch (_adaptive_state) {
+                                            case IMPOSSIBLE:
+                                                update_thresholds();
+                                                break;
+                                            case POSSIBLE:
                                                 if (value >= _up_threshold) {
-                                                    update_thresholds(shifting_factor,
-                                                            DIRECTION_DOWN);
+                                                    store_change(_step_size, t);
                                                 } else {
-                                                    update_thresholds(shifting_factor,
-                                                            DIRECTION_UP);
+                                                    store_change(-_step_size, t);
                                                 }
-                                                _adaptive_state = DONE;
-                                            } else {
+                                                shifting_factor = shift_quanta();
+
+                                                assert(shifting_factor >= 0
+                                                        and shifting_factor <= 1);
+
+                                                if (shifting_factor != 0 and shifting_factor != 1) {
+                                                    if (value >= _up_threshold) {
+                                                        update_thresholds(shifting_factor,
+                                                                DIRECTION_DOWN);
+                                                    } else {
+                                                        update_thresholds(shifting_factor,
+                                                                DIRECTION_UP);
+                                                    }
+                                                    _adaptive_state = DONE;
+                                                } else {
+                                                    update_thresholds();
+                                                }
+                                                break;
+                                            case DONE:
+                                                init_step_number_and_offset(value);
+                                                _adaptive_state = POSSIBLE;
                                                 update_thresholds();
+                                                break;
                                             }
-                                            break;
-                                        case DONE:
-                                            init_step_number_and_offset(value);
-                                            _adaptive_state = POSSIBLE;
-                                            update_thresholds();
-                                            break;
                                         }
                                     }
+                                } else if (event.on_port(RESET)) {
+                                    _offset = 0;
+                                    _state = INIT;
                                 }
                             });
                     _state = RESPONSE;