models.hpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. /**
  2. * @file tests/pdevs/models.hpp
  3. * @author The ARTIS Development Team
  4. * See the AUTHORS or Authors.txt file
  5. */
  6. /*
  7. * ARTIS - the multimodeling and simulation environment
  8. * This file is a part of the ARTIS environment
  9. *
  10. * Copyright (C) 2013-2019 ULCO http://www.univ-littoral.fr
  11. *
  12. * This program is free software: you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License as published by
  14. * the Free Software Foundation, either version 3 of the License, or
  15. * (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  24. */
  25. #ifndef TESTS_PDEVS_MODELS_HPP
  26. #define TESTS_PDEVS_MODELS_HPP
  27. #include <artis-star/common/time/DoubleTime.hpp>
  28. #include <artis-star/common/utils/Trace.hpp>
  29. #include <artis-star/kernel/pdevs/Dynamics.hpp>
  30. #include <chrono>
  31. #include <iostream>
  32. #define DELAY 100
  33. namespace artis {
  34. namespace tests {
  35. namespace pdevs {
  36. struct data {
  37. double x;
  38. double y;
  39. data()
  40. : x(0), y(0) {}
  41. data(double _x, double _y)
  42. : x(_x), y(_y) {}
  43. };
  44. class Inactive : public artis::pdevs::Dynamics<common::DoubleTime, Inactive> {
  45. public:
  46. Inactive(const std::string &name,
  47. const artis::pdevs::Context<common::DoubleTime, Inactive> &context)
  48. :
  49. artis::pdevs::Dynamics<common::DoubleTime, Inactive>(name, context) {}
  50. ~Inactive() override = default;
  51. };
  52. class A : public artis::pdevs::Dynamics<common::DoubleTime, A> {
  53. public:
  54. enum inputs {
  55. IN
  56. };
  57. enum outputs {
  58. OUT
  59. };
  60. A(const std::string &name,
  61. const artis::pdevs::Context<common::DoubleTime, A, artis::common::NoParameters> &context)
  62. :
  63. artis::pdevs::Dynamics<common::DoubleTime, A>(name, context) {
  64. input_ports({{IN, "in"}});
  65. output_ports({{OUT, "out"}});
  66. }
  67. ~A() override = default;
  68. void dint(const typename common::DoubleTime::type &t) override {
  69. #ifndef WITH_TRACE
  70. (void)t;
  71. #endif
  72. #ifdef WITH_TRACE
  73. common::Trace<common::DoubleTime>::trace()
  74. << common::TraceElement<common::DoubleTime>(get_name(), t,
  75. common::FormalismType::PDEVS,
  76. common::FunctionType::DELTA_INT,
  77. common::LevelType::USER);
  78. common::Trace<common::DoubleTime>::trace().flush();
  79. #endif
  80. if (_phase == WAIT) {
  81. ++_value.x;
  82. --_value.y;
  83. _phase = SEND;
  84. } else if (_phase == SEND) {
  85. _phase = WAIT;
  86. }
  87. }
  88. void
  89. dext(const typename common::DoubleTime::type &t,
  90. const typename common::DoubleTime::type & /* e */,
  91. const common::Bag <common::DoubleTime> &msgs) override {
  92. #ifndef WITH_TRACE
  93. (void)t;
  94. (void)msgs;
  95. #endif
  96. #ifdef WITH_TRACE
  97. common::Trace<common::DoubleTime>::trace()
  98. << common::TraceElement<common::DoubleTime>(get_name(), t,
  99. common::FormalismType::PDEVS,
  100. common::FunctionType::DELTA_EXT,
  101. common::LevelType::USER)
  102. << "messages = " << msgs.to_string();
  103. common::Trace<common::DoubleTime>::trace().flush();
  104. #endif
  105. _phase = SEND;
  106. }
  107. void dconf(const typename common::DoubleTime::type &t,
  108. const typename common::DoubleTime::type & /* e */,
  109. const common::Bag <common::DoubleTime> &msgs) override {
  110. #ifndef WITH_TRACE
  111. (void)t;
  112. (void)msgs;
  113. #endif
  114. #ifdef WITH_TRACE
  115. common::Trace<common::DoubleTime>::trace()
  116. << common::TraceElement<common::DoubleTime>(get_name(), t,
  117. common::FormalismType::PDEVS,
  118. common::FunctionType::DELTA_CONF,
  119. common::LevelType::USER)
  120. << "messages = " << msgs.to_string();
  121. common::Trace<common::DoubleTime>::trace().flush();
  122. #endif
  123. }
  124. void start(const typename common::DoubleTime::type &t) override {
  125. #ifndef WITH_TRACE
  126. (void)t;
  127. #endif
  128. #ifdef WITH_TRACE
  129. common::Trace<common::DoubleTime>::trace()
  130. << common::TraceElement<common::DoubleTime>(get_name(), t,
  131. common::FormalismType::PDEVS,
  132. common::FunctionType::START,
  133. common::LevelType::USER);
  134. common::Trace<common::DoubleTime>::trace().flush();
  135. #endif
  136. _phase = SEND;
  137. }
  138. typename common::DoubleTime::type
  139. ta(const typename common::DoubleTime::type &t) const override {
  140. #ifndef WITH_TRACE
  141. (void)t;
  142. #endif
  143. #ifdef WITH_TRACE
  144. common::Trace<common::DoubleTime>::trace()
  145. << common::TraceElement<common::DoubleTime>(get_name(), t,
  146. common::FormalismType::PDEVS,
  147. common::FunctionType::TA,
  148. common::LevelType::USER);
  149. common::Trace<common::DoubleTime>::trace().flush();
  150. #endif
  151. if (_phase == WAIT) {
  152. return 1;
  153. } else {
  154. return 0;
  155. }
  156. }
  157. common::Bag <common::DoubleTime>
  158. lambda(const typename common::DoubleTime::type &t) const override {
  159. #ifndef WITH_TRACE
  160. (void)t;
  161. #endif
  162. common::Bag<common::DoubleTime> msgs;
  163. if (_phase == SEND) {
  164. msgs.push_back(
  165. artis::common::ExternalEvent<common::DoubleTime>(OUT, _value));
  166. }
  167. #ifdef WITH_TRACE
  168. common::Trace<common::DoubleTime>::trace()
  169. << common::TraceElement<common::DoubleTime>(get_name(), t,
  170. common::FormalismType::PDEVS,
  171. common::FunctionType::LAMBDA,
  172. common::LevelType::USER)
  173. << "messages = " << msgs.to_string();
  174. common::Trace<common::DoubleTime>::trace().flush();
  175. #endif
  176. return msgs;
  177. }
  178. private:
  179. enum Phase {
  180. WAIT, SEND
  181. };
  182. Phase _phase;
  183. data _value;
  184. };
  185. class B : public artis::pdevs::Dynamics<common::DoubleTime, B> {
  186. public:
  187. enum inputs {
  188. IN
  189. };
  190. enum outputs {
  191. OUT
  192. };
  193. B(const std::string &name,
  194. const artis::pdevs::Context<common::DoubleTime, B, artis::common::NoParameters> &context)
  195. :
  196. artis::pdevs::Dynamics<common::DoubleTime, B>(name, context),
  197. _value(0) {
  198. input_ports({{IN, "in"}});
  199. output_ports({{OUT, "out"}});
  200. }
  201. ~B() override = default;
  202. void dint(const typename common::DoubleTime::type &t) override {
  203. #ifndef WITH_TRACE
  204. (void)t;
  205. #endif
  206. #ifdef WITH_TRACE
  207. common::Trace<common::DoubleTime>::trace()
  208. << common::TraceElement<common::DoubleTime>(get_name(), t,
  209. common::FormalismType::PDEVS,
  210. common::FunctionType::DELTA_INT,
  211. common::LevelType::USER);
  212. common::Trace<common::DoubleTime>::trace().flush();
  213. #endif
  214. if (_phase == SEND) {
  215. _phase = WAIT;
  216. }
  217. }
  218. void
  219. dext(const typename common::DoubleTime::type &t,
  220. const typename common::DoubleTime::type & /* e */,
  221. const common::Bag <common::DoubleTime> &msgs) override {
  222. #ifndef WITH_TRACE
  223. (void)t;
  224. (void)msgs;
  225. #endif
  226. #ifdef WITH_TRACE
  227. common::Trace<common::DoubleTime>::trace()
  228. << common::TraceElement<common::DoubleTime>(get_name(), t,
  229. common::FormalismType::PDEVS,
  230. common::FunctionType::DELTA_EXT,
  231. common::LevelType::USER)
  232. << "messages = " << msgs.to_string();
  233. common::Trace<common::DoubleTime>::trace().flush();
  234. #endif
  235. _phase = SEND;
  236. }
  237. void dconf(const typename common::DoubleTime::type &t,
  238. const typename common::DoubleTime::type &e,
  239. const common::Bag <common::DoubleTime> &msgs) override {
  240. #ifndef WITH_TRACE
  241. (void)t;
  242. (void)msgs;
  243. #endif
  244. dext(t, e, msgs);
  245. #ifdef WITH_TRACE
  246. common::Trace<common::DoubleTime>::trace()
  247. << common::TraceElement<common::DoubleTime>(get_name(), t,
  248. common::FormalismType::PDEVS,
  249. common::FunctionType::DELTA_CONF,
  250. common::LevelType::USER)
  251. << "messages = " << msgs.to_string();
  252. common::Trace<common::DoubleTime>::trace().flush();
  253. #endif
  254. }
  255. void start(const typename common::DoubleTime::type &t) override {
  256. #ifndef WITH_TRACE
  257. (void)t;
  258. #endif
  259. #ifdef WITH_TRACE
  260. common::Trace<common::DoubleTime>::trace()
  261. << common::TraceElement<common::DoubleTime>(get_name(), t,
  262. common::FormalismType::PDEVS,
  263. common::FunctionType::START,
  264. common::LevelType::USER);
  265. common::Trace<common::DoubleTime>::trace().flush();
  266. #endif
  267. _phase = WAIT;
  268. }
  269. typename common::DoubleTime::type ta(
  270. const typename common::DoubleTime::type &t) const override {
  271. #ifndef WITH_TRACE
  272. (void)t;
  273. #endif
  274. #ifdef WITH_TRACE
  275. common::Trace<common::DoubleTime>::trace()
  276. << common::TraceElement<common::DoubleTime>(get_name(), t,
  277. common::FormalismType::PDEVS,
  278. common::FunctionType::TA,
  279. common::LevelType::USER);
  280. common::Trace<common::DoubleTime>::trace().flush();
  281. #endif
  282. if (_phase == WAIT) {
  283. return common::DoubleTime::infinity;
  284. } else {
  285. return 0;
  286. }
  287. }
  288. common::Bag <common::DoubleTime> lambda(
  289. const typename common::DoubleTime::type &t) const override {
  290. #ifndef WITH_TRACE
  291. (void)t;
  292. #endif
  293. common::Bag<common::DoubleTime> msgs;
  294. if (_phase == SEND) {
  295. msgs.push_back(
  296. artis::common::ExternalEvent<common::DoubleTime>(OUT, _value));
  297. }
  298. #ifdef WITH_TRACE
  299. common::Trace<common::DoubleTime>::trace()
  300. << common::TraceElement<common::DoubleTime>(get_name(), t,
  301. common::FormalismType::PDEVS,
  302. common::FunctionType::LAMBDA,
  303. common::LevelType::USER)
  304. << "messages = " << msgs.to_string();
  305. common::Trace<common::DoubleTime>::trace().flush();
  306. #endif
  307. return msgs;
  308. }
  309. private:
  310. enum Phase {
  311. WAIT, SEND
  312. };
  313. Phase _phase;
  314. double _value;
  315. };
  316. class TwoStateModel : public artis::pdevs::Dynamics<common::DoubleTime, TwoStateModel> {
  317. public:
  318. TwoStateModel(const std::string &name,
  319. const artis::pdevs::Context<common::DoubleTime,
  320. TwoStateModel,
  321. artis::common::NoParameters> &context)
  322. :
  323. artis::pdevs::Dynamics<common::DoubleTime, TwoStateModel>(name, context) {}
  324. ~TwoStateModel() override = default;
  325. void dint(const typename common::DoubleTime::type &t) override {
  326. if (_phase == S1) {
  327. _phase = S2;
  328. } else if (_phase == S2) {
  329. _phase = S1;
  330. }
  331. _last_time = t;
  332. }
  333. void start(const typename common::DoubleTime::type &t) override {
  334. _phase = S1;
  335. _last_time = t;
  336. }
  337. typename common::DoubleTime::type
  338. ta(const typename common::DoubleTime::type & /* t */) const override {
  339. if (_phase == S1) {
  340. return 5;
  341. } else {
  342. return 6;
  343. }
  344. }
  345. common::Bag <common::DoubleTime>
  346. lambda(const typename common::DoubleTime::type &t) const override {
  347. std::cout << (t - _last_time) << std::endl;
  348. return common::Bag<common::DoubleTime>();
  349. }
  350. private:
  351. enum Phase {
  352. S1, S2
  353. };
  354. Phase _phase;
  355. typename common::DoubleTime::type _last_time;
  356. };
  357. class ThreeStateModel
  358. : public artis::pdevs::Dynamics<common::DoubleTime, ThreeStateModel> {
  359. public:
  360. enum outputs {
  361. OUT
  362. };
  363. enum states {
  364. HEIGHTS, SPEEDS, SCALES, N, INDEX, SIGMA, LAST_TIME
  365. };
  366. ThreeStateModel(const std::string &name,
  367. const artis::pdevs::Context<common::DoubleTime,
  368. ThreeStateModel,
  369. artis::common::NoParameters> &context)
  370. :
  371. artis::pdevs::Dynamics<common::DoubleTime, ThreeStateModel>(name, context) {
  372. DECLARE_STATES(std::vector<double>,
  373. ((HEIGHTS, &ThreeStateModel::heights), (SPEEDS, &ThreeStateModel::speeds), (SCALES, &ThreeStateModel::scales)));
  374. DECLARE_STATES(unsigned int,
  375. ((N, &ThreeStateModel::n), (INDEX, &ThreeStateModel::index)));
  376. DECLARE_STATES(typename common::DoubleTime::type,
  377. ((SIGMA, &ThreeStateModel::sigma), (LAST_TIME, &ThreeStateModel::_last_time)));
  378. output_ports({{OUT, "out"}});
  379. }
  380. ~ThreeStateModel() override = default;
  381. void dconf(const typename common::DoubleTime::type &t,
  382. const typename common::DoubleTime::type &e,
  383. const common::Bag <common::DoubleTime> &msgs) override {
  384. dext(t, e, msgs);
  385. }
  386. void dext(const typename common::DoubleTime::type & /* t */,
  387. const typename common::DoubleTime::type & /* e */,
  388. const common::Bag <common::DoubleTime> &msgs) override {
  389. for (common::Bag<common::DoubleTime>::const_iterator it = msgs.begin();
  390. it != msgs.end();
  391. ++it) {
  392. ++n;
  393. }
  394. if (sigma == 1) {
  395. if (n > 3) {
  396. ++index;
  397. if (index == scales.size()) {
  398. index = 0;
  399. }
  400. sigma = common::DoubleTime::infinity;
  401. if (scales[index] == 1) {
  402. scales[index] = 2;
  403. } else {
  404. scales[index] = 1;
  405. }
  406. n = 0;
  407. }
  408. } else {
  409. sigma = 1;
  410. n = 0;
  411. }
  412. }
  413. void dint(const typename common::DoubleTime::type &t) override {
  414. mark_full(t);
  415. if (full_N()) {
  416. raz();
  417. }
  418. compute();
  419. }
  420. void start(const typename common::DoubleTime::type &t) override {
  421. heights = {0, 0, 0, 0, 0};
  422. speeds = {0.21, 0.3, 0.7, 0.56, 0.14};
  423. scales = {1, 1, 1, 1, 1};
  424. index = 0;
  425. n = 0;
  426. sigma = 0;
  427. _last_time = t;
  428. }
  429. typename common::DoubleTime::type
  430. ta(const typename common::DoubleTime::type & /* t */) const override { return sigma; }
  431. common::Bag <common::DoubleTime>
  432. lambda(const typename common::DoubleTime::type & /* t */) const override {
  433. common::Bag<common::DoubleTime> msgs;
  434. if (full()) {
  435. msgs.push_back(artis::common::ExternalEvent<common::DoubleTime>(OUT, 0));
  436. }
  437. return msgs;
  438. }
  439. private:
  440. void compute() {
  441. for (unsigned int i = 0; i < heights.size(); ++i) {
  442. if (heights[i] != -1 and heights[i] < 10) {
  443. heights[i] += speeds[i] * scales[i];
  444. }
  445. }
  446. }
  447. void display() const {
  448. for (std::vector<double>::const_iterator it = heights.begin();
  449. it != heights.end(); ++it) {
  450. std::cout << *it << " ";
  451. }
  452. std::cout << std::endl;
  453. }
  454. void display_full() const {
  455. unsigned int i = 1;
  456. for (std::vector<double>::const_iterator it = heights.begin();
  457. it != heights.end(); ++it, ++i) {
  458. if (*it > 10) {
  459. std::cout << "S" << i;
  460. }
  461. }
  462. std::cout << std::endl;
  463. }
  464. bool full() const {
  465. unsigned int n = 0;
  466. for (std::vector<double>::const_iterator it = heights.begin();
  467. it != heights.end(); ++it) {
  468. if (*it > 10) {
  469. ++n;
  470. }
  471. }
  472. return n > 0;
  473. }
  474. bool full_N() const {
  475. unsigned int n = 0;
  476. for (std::vector<double>::const_iterator it = heights.begin();
  477. it != heights.end(); ++it) {
  478. if (*it == -1) {
  479. ++n;
  480. }
  481. }
  482. return n >= 2;
  483. }
  484. void mark_full(const typename common::DoubleTime::type &t) {
  485. for (std::vector<double>::iterator it = heights.begin();
  486. it != heights.end(); ++it) {
  487. if (*it > 10) {
  488. *it = -1;
  489. _last_time = t;
  490. }
  491. }
  492. }
  493. void raz() {
  494. for (std::vector<double>::iterator it = heights.begin();
  495. it != heights.end(); ++it) {
  496. if (*it == -1) {
  497. *it = 0;
  498. }
  499. }
  500. }
  501. // state
  502. std::vector<double> heights;
  503. std::vector<double> speeds;
  504. std::vector<double> scales;
  505. unsigned int index;
  506. unsigned int n;
  507. typename common::DoubleTime::type sigma;
  508. typename common::DoubleTime::type _last_time;
  509. };
  510. }
  511. }
  512. } // namespace artis tests pdevs
  513. #endif