123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616 |
- /**
- * @file tests/pdevs/models.hpp
- * @author The ARTIS Development Team
- * See the AUTHORS or Authors.txt file
- */
- /*
- * ARTIS - the multimodeling and simulation environment
- * This file is a part of the ARTIS environment
- *
- * Copyright (C) 2013-2019 ULCO http://www.univ-littoral.fr
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- #ifndef TESTS_PDEVS_MODELS_HPP
- #define TESTS_PDEVS_MODELS_HPP 1
- #include <artis-star/common/time/DoubleTime.hpp>
- #include <artis-star/common/utils/Trace.hpp>
- #include <artis-star/kernel/pdevs/Dynamics.hpp>
- #include <chrono>
- #include <iostream>
- #define DELAY 100
- namespace artis {
- namespace tests {
- namespace pdevs {
- struct data {
- double x;
- double y;
- data()
- :x(0), y(0) { }
- data(double _x, double _y)
- :x(_x), y(_y) { }
- };
- class A : public artis::pdevs::Dynamics<common::DoubleTime, A> {
- public:
- enum inputs {
- IN
- };
- enum outputs {
- OUT
- };
- A(const std::string& name,
- const artis::pdevs::Context<common::DoubleTime, A, artis::common::NoParameters>& context)
- :
- artis::pdevs::Dynamics<common::DoubleTime, A>(name, context)
- {
- input_ports({{IN, "in"}});
- output_ports({{OUT, "out"}});
- }
- ~A() override = default;
- void dint(typename common::DoubleTime::type t) override
- {
- #ifndef WITH_TRACE
- (void)t;
- #endif
- #ifdef WITH_TRACE
- common::Trace<common::DoubleTime>::trace()
- << common::TraceElement<common::DoubleTime>(get_name(), t,
- common::TraceType::DELTA_INT);
- common::Trace<common::DoubleTime>::trace().flush();
- #endif
- if (_phase == WAIT) {
- ++_value.x;
- --_value.y;
- _phase = SEND;
- } else if (_phase == SEND) {
- _phase = WAIT;
- }
- }
- void
- dext(typename common::DoubleTime::type t, typename common::DoubleTime::type /* e */,
- const common::Bag<common::DoubleTime>& msgs) override
- {
- #ifndef WITH_TRACE
- (void)t;
- (void)msgs;
- #endif
- #ifdef WITH_TRACE
- common::Trace<common::DoubleTime>::trace()
- << common::TraceElement<common::DoubleTime>(get_name(), t,
- common::TraceType::DELTA_EXT)
- << "messages = " << msgs.to_string();
- common::Trace<common::DoubleTime>::trace().flush();
- #endif
- _phase = SEND;
- }
- void dconf(typename common::DoubleTime::type t,
- typename common::DoubleTime::type /* e */,
- const common::Bag<common::DoubleTime>& msgs) override
- {
- #ifndef WITH_TRACE
- (void)t;
- (void)msgs;
- #endif
- #ifdef WITH_TRACE
- common::Trace<common::DoubleTime>::trace()
- << common::TraceElement<common::DoubleTime>(get_name(), t,
- common::TraceType::DELTA_CONF)
- << "messages = " << msgs.to_string();
- common::Trace<common::DoubleTime>::trace().flush();
- #endif
- }
- typename common::DoubleTime::type
- start(typename common::DoubleTime::type t) override
- {
- #ifndef WITH_TRACE
- (void)t;
- #endif
- #ifdef WITH_TRACE
- common::Trace<common::DoubleTime>::trace()
- << common::TraceElement<common::DoubleTime>(get_name(), t,
- common::TraceType::START);
- common::Trace<common::DoubleTime>::trace().flush();
- #endif
- _phase = WAIT;
- return 0;
- }
- typename common::DoubleTime::type
- ta(typename common::DoubleTime::type t) const override
- {
- #ifndef WITH_TRACE
- (void)t;
- #endif
- #ifdef WITH_TRACE
- common::Trace<common::DoubleTime>::trace()
- << common::TraceElement<common::DoubleTime>(get_name(), t, common::TraceType::TA);
- common::Trace<common::DoubleTime>::trace().flush();
- #endif
- if (_phase == WAIT) {
- return 1;
- } else {
- return 0;
- }
- }
- common::Bag<common::DoubleTime>
- lambda(typename common::DoubleTime::type t) const override
- {
- #ifndef WITH_TRACE
- (void)t;
- #endif
- common::Bag<common::DoubleTime> msgs;
- if (_phase == SEND) {
- msgs.push_back(
- artis::common::ExternalEvent<common::DoubleTime>(OUT, _value));
- }
- #ifdef WITH_TRACE
- common::Trace<common::DoubleTime>::trace()
- << common::TraceElement<common::DoubleTime>(get_name(), t,
- common::TraceType::LAMBDA)
- << "messages = " << msgs.to_string();
- common::Trace<common::DoubleTime>::trace().flush();
- #endif
- return msgs;
- }
- private:
- enum Phase {
- WAIT, SEND
- };
- Phase _phase;
- data _value;
- };
- class B : public artis::pdevs::Dynamics<common::DoubleTime, B> {
- public:
- enum inputs {
- IN
- };
- enum outputs {
- OUT
- };
- B(const std::string& name,
- const artis::pdevs::Context<common::DoubleTime, B, artis::common::NoParameters>& context)
- :
- artis::pdevs::Dynamics<common::DoubleTime, B>(name, context),
- _value(0)
- {
- input_ports({{IN, "in"}});
- output_ports({{OUT, "out"}});
- }
- ~B() override = default;
- void dint(typename common::DoubleTime::type t) override
- {
- #ifndef WITH_TRACE
- (void)t;
- #endif
- #ifdef WITH_TRACE
- common::Trace<common::DoubleTime>::trace()
- << common::TraceElement<common::DoubleTime>(get_name(), t,
- common::TraceType::DELTA_INT);
- common::Trace<common::DoubleTime>::trace().flush();
- #endif
- if (_phase == SEND) {
- _phase = WAIT;
- }
- }
- void
- dext(typename common::DoubleTime::type t, typename common::DoubleTime::type /* e */,
- const common::Bag<common::DoubleTime>& msgs) override
- {
- #ifndef WITH_TRACE
- (void)t;
- (void)msgs;
- #endif
- #ifdef WITH_TRACE
- common::Trace<common::DoubleTime>::trace()
- << common::TraceElement<common::DoubleTime>(get_name(), t,
- common::TraceType::DELTA_EXT)
- << "messages = " << msgs.to_string();
- common::Trace<common::DoubleTime>::trace().flush();
- #endif
- _phase = SEND;
- }
- void dconf(typename common::DoubleTime::type t,
- typename common::DoubleTime::type e,
- const common::Bag<common::DoubleTime>& msgs) override
- {
- #ifndef WITH_TRACE
- (void)t;
- (void)msgs;
- #endif
- dext(t, e, msgs);
- #ifdef WITH_TRACE
- common::Trace<common::DoubleTime>::trace()
- << common::TraceElement<common::DoubleTime>(get_name(), t,
- common::TraceType::DELTA_CONF)
- << "messages = " << msgs.to_string();
- common::Trace<common::DoubleTime>::trace().flush();
- #endif
- }
- typename common::DoubleTime::type
- start(typename common::DoubleTime::type t) override
- {
- #ifndef WITH_TRACE
- (void)t;
- #endif
- #ifdef WITH_TRACE
- common::Trace<common::DoubleTime>::trace()
- << common::TraceElement<common::DoubleTime>(get_name(), t,
- common::TraceType::START);
- common::Trace<common::DoubleTime>::trace().flush();
- #endif
- _phase = WAIT;
- return common::DoubleTime::infinity;
- }
- typename common::DoubleTime::type ta(
- typename common::DoubleTime::type t) const override
- {
- #ifndef WITH_TRACE
- (void)t;
- #endif
- #ifdef WITH_TRACE
- common::Trace<common::DoubleTime>::trace()
- << common::TraceElement<common::DoubleTime>(get_name(), t, common::TraceType::TA);
- common::Trace<common::DoubleTime>::trace().flush();
- #endif
- if (_phase == WAIT) {
- return common::DoubleTime::infinity;
- } else {
- return 0;
- }
- }
- common::Bag<common::DoubleTime> lambda(
- typename common::DoubleTime::type t) const override
- {
- #ifndef WITH_TRACE
- (void)t;
- #endif
- common::Bag<common::DoubleTime> msgs;
- if (_phase == SEND) {
- msgs.push_back(
- artis::common::ExternalEvent<common::DoubleTime>(OUT, _value));
- }
- #ifdef WITH_TRACE
- common::Trace<common::DoubleTime>::trace()
- << common::TraceElement<common::DoubleTime>(get_name(), t,
- common::TraceType::LAMBDA)
- << "messages = " << msgs.to_string();
- common::Trace<common::DoubleTime>::trace().flush();
- #endif
- return msgs;
- }
- private:
- enum Phase {
- WAIT, SEND
- };
- Phase _phase;
- double _value;
- };
- class TwoStateModel : public artis::pdevs::Dynamics<common::DoubleTime, TwoStateModel> {
- public:
- TwoStateModel(const std::string& name,
- const artis::pdevs::Context<common::DoubleTime, TwoStateModel, artis::common::NoParameters>& context)
- :
- artis::pdevs::Dynamics<common::DoubleTime, TwoStateModel>(name, context) { }
- ~TwoStateModel() override = default;
- void dint(typename common::DoubleTime::type t) override
- {
- if (_phase == S1) {
- _phase = S2;
- } else if (_phase == S2) {
- _phase = S1;
- }
- _last_time = t;
- }
- typename common::DoubleTime::type
- start(typename common::DoubleTime::type t) override
- {
- _phase = S1;
- _last_time = t;
- return ta(t);
- }
- typename common::DoubleTime::type
- ta(typename common::DoubleTime::type /* t */) const override
- {
- if (_phase == S1) {
- return 5;
- } else {
- return 6;
- }
- }
- common::Bag<common::DoubleTime>
- lambda(typename common::DoubleTime::type t) const override
- {
- std::cout << (t - _last_time) << std::endl;
- return common::Bag<common::DoubleTime>();
- }
- private:
- enum Phase {
- S1, S2
- };
- Phase _phase;
- typename common::DoubleTime::type _last_time;
- };
- class ThreeStateModel
- : public artis::pdevs::Dynamics<common::DoubleTime, ThreeStateModel> {
- public:
- enum outputs {
- OUT
- };
- enum states {
- HEIGHTS, SPEEDS, SCALES, N, INDEX, SIGMA, LAST_TIME
- };
- ThreeStateModel(const std::string& name,
- const artis::pdevs::Context<common::DoubleTime, ThreeStateModel, artis::common::NoParameters>& context)
- :
- artis::pdevs::Dynamics<common::DoubleTime, ThreeStateModel>(name, context)
- {
- DECLARE_STATES(std::vector<double>,
- ((HEIGHTS, &ThreeStateModel::heights), (SPEEDS, &ThreeStateModel::speeds), (SCALES, &ThreeStateModel::scales)));
- DECLARE_STATES(unsigned int,
- ((N, &ThreeStateModel::n), (INDEX, &ThreeStateModel::index)));
- DECLARE_STATES(typename common::DoubleTime::type,
- ((SIGMA, &ThreeStateModel::sigma), (LAST_TIME, &ThreeStateModel::_last_time)));
- output_ports({{OUT, "out"}});
- }
- ~ThreeStateModel() override = default;
- void dconf(typename common::DoubleTime::type t,
- typename common::DoubleTime::type e,
- const common::Bag<common::DoubleTime>& msgs) override
- {
- dext(t, e, msgs);
- }
- void dext(typename common::DoubleTime::type /* t */,
- typename common::DoubleTime::type /* e */,
- const common::Bag<common::DoubleTime>& msgs) override
- {
- for (common::Bag<common::DoubleTime>::const_iterator it = msgs.begin();
- it != msgs.end();
- ++it) {
- ++n;
- }
- if (sigma == 1) {
- if (n > 3) {
- ++index;
- if (index == scales.size()) {
- index = 0;
- }
- sigma = common::DoubleTime::infinity;
- if (scales[index] == 1) {
- scales[index] = 2;
- } else {
- scales[index] = 1;
- }
- n = 0;
- }
- } else {
- sigma = 1;
- n = 0;
- }
- }
- void dint(typename common::DoubleTime::type t) override
- {
- mark_full(t);
- if (full_N()) {
- raz();
- }
- compute();
- }
- typename common::DoubleTime::type
- start(typename common::DoubleTime::type t) override
- {
- heights = {0, 0, 0, 0, 0};
- speeds = {0.21, 0.3, 0.7, 0.56, 0.14};
- scales = {1, 1, 1, 1, 1};
- index = 0;
- n = 0;
- sigma = 1;
- _last_time = t;
- return 0;
- }
- typename common::DoubleTime::type
- ta(typename common::DoubleTime::type /* t */) const override { return sigma; }
- common::Bag<common::DoubleTime>
- lambda(typename common::DoubleTime::type /* t */) const override
- {
- common::Bag<common::DoubleTime> msgs;
- if (full()) {
- msgs.push_back(artis::common::ExternalEvent<common::DoubleTime>(OUT, 0));
- }
- return msgs;
- }
- private:
- void compute()
- {
- for (unsigned int i = 0; i < heights.size(); ++i) {
- if (heights[i] != -1 and heights[i] < 10) {
- heights[i] += speeds[i] * scales[i];
- }
- }
- }
- void display() const
- {
- for (std::vector<double>::const_iterator it = heights.begin();
- it != heights.end(); ++it) {
- std::cout << *it << " ";
- }
- std::cout << std::endl;
- }
- void display_full() const
- {
- unsigned int i = 1;
- for (std::vector<double>::const_iterator it = heights.begin();
- it != heights.end(); ++it, ++i) {
- if (*it > 10) {
- std::cout << "S" << i;
- }
- }
- std::cout << std::endl;
- }
- bool full() const
- {
- unsigned int n = 0;
- for (std::vector<double>::const_iterator it = heights.begin();
- it != heights.end(); ++it) {
- if (*it > 10) {
- ++n;
- }
- }
- return n > 0;
- }
- bool full_N() const
- {
- unsigned int n = 0;
- for (std::vector<double>::const_iterator it = heights.begin();
- it != heights.end(); ++it) {
- if (*it == -1) {
- ++n;
- }
- }
- return n >= 2;
- }
- void mark_full(typename common::DoubleTime::type t)
- {
- for (std::vector<double>::iterator it = heights.begin();
- it != heights.end(); ++it) {
- if (*it > 10) {
- *it = -1;
- _last_time = t;
- }
- }
- }
- void raz()
- {
- for (std::vector<double>::iterator it = heights.begin();
- it != heights.end(); ++it) {
- if (*it == -1) {
- *it = 0;
- }
- }
- }
- // state
- std::vector<double> heights;
- std::vector<double> speeds;
- std::vector<double> scales;
- unsigned int index;
- unsigned int n;
- typename common::DoubleTime::type sigma;
- typename common::DoubleTime::type _last_time;
- };
- }
- }
- } // namespace artis tests pdevs
- #endif
|