models.hpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642
  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 1
  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 A : public artis::pdevs::Dynamics<common::DoubleTime, A> {
  45. public:
  46. enum inputs {
  47. IN
  48. };
  49. enum outputs {
  50. OUT
  51. };
  52. A(const std::string& name,
  53. const artis::pdevs::Context<common::DoubleTime, A, artis::common::NoParameters>& context)
  54. :
  55. artis::pdevs::Dynamics<common::DoubleTime, A>(name, context)
  56. {
  57. input_ports({{IN, "in"}});
  58. output_ports({{OUT, "out"}});
  59. }
  60. ~A() override = default;
  61. void dint(typename common::DoubleTime::type t) override
  62. {
  63. #ifndef WITH_TRACE
  64. (void)t;
  65. #endif
  66. #ifdef WITH_TRACE
  67. common::Trace<common::DoubleTime>::trace()
  68. << common::TraceElement<common::DoubleTime>(get_name(), t,
  69. common::FormalismType::PDEVS,
  70. common::FunctionType::DELTA_INT,
  71. common::LevelType::USER);
  72. common::Trace<common::DoubleTime>::trace().flush();
  73. #endif
  74. if (_phase == WAIT) {
  75. ++_value.x;
  76. --_value.y;
  77. _phase = SEND;
  78. } else if (_phase == SEND) {
  79. _phase = WAIT;
  80. }
  81. }
  82. void
  83. dext(typename common::DoubleTime::type t, typename common::DoubleTime::type /* e */,
  84. const common::Bag<common::DoubleTime>& msgs) override
  85. {
  86. #ifndef WITH_TRACE
  87. (void)t;
  88. (void)msgs;
  89. #endif
  90. #ifdef WITH_TRACE
  91. common::Trace<common::DoubleTime>::trace()
  92. << common::TraceElement<common::DoubleTime>(get_name(), t,
  93. common::FormalismType::PDEVS,
  94. common::FunctionType::DELTA_EXT,
  95. common::LevelType::USER)
  96. << "messages = " << msgs.to_string();
  97. common::Trace<common::DoubleTime>::trace().flush();
  98. #endif
  99. _phase = SEND;
  100. }
  101. void dconf(typename common::DoubleTime::type t,
  102. typename common::DoubleTime::type /* e */,
  103. const common::Bag<common::DoubleTime>& msgs) override
  104. {
  105. #ifndef WITH_TRACE
  106. (void)t;
  107. (void)msgs;
  108. #endif
  109. #ifdef WITH_TRACE
  110. common::Trace<common::DoubleTime>::trace()
  111. << common::TraceElement<common::DoubleTime>(get_name(), t,
  112. common::FormalismType::PDEVS,
  113. common::FunctionType::DELTA_CONF,
  114. common::LevelType::USER)
  115. << "messages = " << msgs.to_string();
  116. common::Trace<common::DoubleTime>::trace().flush();
  117. #endif
  118. }
  119. typename common::DoubleTime::type
  120. start(typename common::DoubleTime::type t) override
  121. {
  122. #ifndef WITH_TRACE
  123. (void)t;
  124. #endif
  125. #ifdef WITH_TRACE
  126. common::Trace<common::DoubleTime>::trace()
  127. << common::TraceElement<common::DoubleTime>(get_name(), t,
  128. common::FormalismType::PDEVS,
  129. common::FunctionType::START,
  130. common::LevelType::USER);
  131. common::Trace<common::DoubleTime>::trace().flush();
  132. #endif
  133. _phase = WAIT;
  134. return 0;
  135. }
  136. typename common::DoubleTime::type
  137. ta(typename common::DoubleTime::type t) const override
  138. {
  139. #ifndef WITH_TRACE
  140. (void)t;
  141. #endif
  142. #ifdef WITH_TRACE
  143. common::Trace<common::DoubleTime>::trace()
  144. << common::TraceElement<common::DoubleTime>(get_name(), t,
  145. common::FormalismType::PDEVS,
  146. common::FunctionType::TA,
  147. common::LevelType::USER);
  148. common::Trace<common::DoubleTime>::trace().flush();
  149. #endif
  150. if (_phase == WAIT) {
  151. return 1;
  152. } else {
  153. return 0;
  154. }
  155. }
  156. common::Bag<common::DoubleTime>
  157. lambda(typename common::DoubleTime::type t) const override
  158. {
  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. {
  199. input_ports({{IN, "in"}});
  200. output_ports({{OUT, "out"}});
  201. }
  202. ~B() override = default;
  203. void dint(typename common::DoubleTime::type t) override
  204. {
  205. #ifndef WITH_TRACE
  206. (void)t;
  207. #endif
  208. #ifdef WITH_TRACE
  209. common::Trace<common::DoubleTime>::trace()
  210. << common::TraceElement<common::DoubleTime>(get_name(), t,
  211. common::FormalismType::PDEVS,
  212. common::FunctionType::DELTA_INT,
  213. common::LevelType::USER);
  214. common::Trace<common::DoubleTime>::trace().flush();
  215. #endif
  216. if (_phase == SEND) {
  217. _phase = WAIT;
  218. }
  219. }
  220. void
  221. dext(typename common::DoubleTime::type t, typename common::DoubleTime::type /* e */,
  222. const common::Bag<common::DoubleTime>& msgs) override
  223. {
  224. #ifndef WITH_TRACE
  225. (void)t;
  226. (void)msgs;
  227. #endif
  228. #ifdef WITH_TRACE
  229. common::Trace<common::DoubleTime>::trace()
  230. << common::TraceElement<common::DoubleTime>(get_name(), t,
  231. common::FormalismType::PDEVS,
  232. common::FunctionType::DELTA_EXT,
  233. common::LevelType::USER)
  234. << "messages = " << msgs.to_string();
  235. common::Trace<common::DoubleTime>::trace().flush();
  236. #endif
  237. _phase = SEND;
  238. }
  239. void dconf(typename common::DoubleTime::type t,
  240. typename common::DoubleTime::type e,
  241. const common::Bag<common::DoubleTime>& msgs) override
  242. {
  243. #ifndef WITH_TRACE
  244. (void)t;
  245. (void)msgs;
  246. #endif
  247. dext(t, e, msgs);
  248. #ifdef WITH_TRACE
  249. common::Trace<common::DoubleTime>::trace()
  250. << common::TraceElement<common::DoubleTime>(get_name(), t,
  251. common::FormalismType::PDEVS,
  252. common::FunctionType::DELTA_CONF,
  253. common::LevelType::USER)
  254. << "messages = " << msgs.to_string();
  255. common::Trace<common::DoubleTime>::trace().flush();
  256. #endif
  257. }
  258. typename common::DoubleTime::type
  259. start(typename common::DoubleTime::type t) override
  260. {
  261. #ifndef WITH_TRACE
  262. (void)t;
  263. #endif
  264. #ifdef WITH_TRACE
  265. common::Trace<common::DoubleTime>::trace()
  266. << common::TraceElement<common::DoubleTime>(get_name(), t,
  267. common::FormalismType::PDEVS,
  268. common::FunctionType::START,
  269. common::LevelType::USER);
  270. common::Trace<common::DoubleTime>::trace().flush();
  271. #endif
  272. _phase = WAIT;
  273. return common::DoubleTime::infinity;
  274. }
  275. typename common::DoubleTime::type ta(
  276. typename common::DoubleTime::type t) const override
  277. {
  278. #ifndef WITH_TRACE
  279. (void)t;
  280. #endif
  281. #ifdef WITH_TRACE
  282. common::Trace<common::DoubleTime>::trace()
  283. << common::TraceElement<common::DoubleTime>(get_name(), t,
  284. common::FormalismType::PDEVS,
  285. common::FunctionType::TA,
  286. common::LevelType::USER);
  287. common::Trace<common::DoubleTime>::trace().flush();
  288. #endif
  289. if (_phase == WAIT) {
  290. return common::DoubleTime::infinity;
  291. } else {
  292. return 0;
  293. }
  294. }
  295. common::Bag<common::DoubleTime> lambda(
  296. typename common::DoubleTime::type t) const override
  297. {
  298. #ifndef WITH_TRACE
  299. (void)t;
  300. #endif
  301. common::Bag<common::DoubleTime> msgs;
  302. if (_phase == SEND) {
  303. msgs.push_back(
  304. artis::common::ExternalEvent<common::DoubleTime>(OUT, _value));
  305. }
  306. #ifdef WITH_TRACE
  307. common::Trace<common::DoubleTime>::trace()
  308. << common::TraceElement<common::DoubleTime>(get_name(), t,
  309. common::FormalismType::PDEVS,
  310. common::FunctionType::LAMBDA,
  311. common::LevelType::USER)
  312. << "messages = " << msgs.to_string();
  313. common::Trace<common::DoubleTime>::trace().flush();
  314. #endif
  315. return msgs;
  316. }
  317. private:
  318. enum Phase {
  319. WAIT, SEND
  320. };
  321. Phase _phase;
  322. double _value;
  323. };
  324. class TwoStateModel : public artis::pdevs::Dynamics<common::DoubleTime, TwoStateModel> {
  325. public:
  326. TwoStateModel(const std::string& name,
  327. const artis::pdevs::Context<common::DoubleTime, TwoStateModel, artis::common::NoParameters>& context)
  328. :
  329. artis::pdevs::Dynamics<common::DoubleTime, TwoStateModel>(name, context) { }
  330. ~TwoStateModel() override = default;
  331. void dint(typename common::DoubleTime::type t) override
  332. {
  333. if (_phase == S1) {
  334. _phase = S2;
  335. } else if (_phase == S2) {
  336. _phase = S1;
  337. }
  338. _last_time = t;
  339. }
  340. typename common::DoubleTime::type
  341. start(typename common::DoubleTime::type t) override
  342. {
  343. _phase = S1;
  344. _last_time = t;
  345. return ta(t);
  346. }
  347. typename common::DoubleTime::type
  348. ta(typename common::DoubleTime::type /* t */) const override
  349. {
  350. if (_phase == S1) {
  351. return 5;
  352. } else {
  353. return 6;
  354. }
  355. }
  356. common::Bag<common::DoubleTime>
  357. lambda(typename common::DoubleTime::type t) const override
  358. {
  359. std::cout << (t - _last_time) << std::endl;
  360. return common::Bag<common::DoubleTime>();
  361. }
  362. private:
  363. enum Phase {
  364. S1, S2
  365. };
  366. Phase _phase;
  367. typename common::DoubleTime::type _last_time;
  368. };
  369. class ThreeStateModel
  370. : public artis::pdevs::Dynamics<common::DoubleTime, ThreeStateModel> {
  371. public:
  372. enum outputs {
  373. OUT
  374. };
  375. enum states {
  376. HEIGHTS, SPEEDS, SCALES, N, INDEX, SIGMA, LAST_TIME
  377. };
  378. ThreeStateModel(const std::string& name,
  379. const artis::pdevs::Context<common::DoubleTime, ThreeStateModel, artis::common::NoParameters>& context)
  380. :
  381. artis::pdevs::Dynamics<common::DoubleTime, ThreeStateModel>(name, context)
  382. {
  383. DECLARE_STATES(std::vector<double>,
  384. ((HEIGHTS, &ThreeStateModel::heights), (SPEEDS, &ThreeStateModel::speeds), (SCALES, &ThreeStateModel::scales)));
  385. DECLARE_STATES(unsigned int,
  386. ((N, &ThreeStateModel::n), (INDEX, &ThreeStateModel::index)));
  387. DECLARE_STATES(typename common::DoubleTime::type,
  388. ((SIGMA, &ThreeStateModel::sigma), (LAST_TIME, &ThreeStateModel::_last_time)));
  389. output_ports({{OUT, "out"}});
  390. }
  391. ~ThreeStateModel() override = default;
  392. void dconf(typename common::DoubleTime::type t,
  393. typename common::DoubleTime::type e,
  394. const common::Bag<common::DoubleTime>& msgs) override
  395. {
  396. dext(t, e, msgs);
  397. }
  398. void dext(typename common::DoubleTime::type /* t */,
  399. typename common::DoubleTime::type /* e */,
  400. const common::Bag<common::DoubleTime>& msgs) override
  401. {
  402. for (common::Bag<common::DoubleTime>::const_iterator it = msgs.begin();
  403. it != msgs.end();
  404. ++it) {
  405. ++n;
  406. }
  407. if (sigma == 1) {
  408. if (n > 3) {
  409. ++index;
  410. if (index == scales.size()) {
  411. index = 0;
  412. }
  413. sigma = common::DoubleTime::infinity;
  414. if (scales[index] == 1) {
  415. scales[index] = 2;
  416. } else {
  417. scales[index] = 1;
  418. }
  419. n = 0;
  420. }
  421. } else {
  422. sigma = 1;
  423. n = 0;
  424. }
  425. }
  426. void dint(typename common::DoubleTime::type t) override
  427. {
  428. mark_full(t);
  429. if (full_N()) {
  430. raz();
  431. }
  432. compute();
  433. }
  434. typename common::DoubleTime::type
  435. start(typename common::DoubleTime::type t) override
  436. {
  437. heights = {0, 0, 0, 0, 0};
  438. speeds = {0.21, 0.3, 0.7, 0.56, 0.14};
  439. scales = {1, 1, 1, 1, 1};
  440. index = 0;
  441. n = 0;
  442. sigma = 1;
  443. _last_time = t;
  444. return 0;
  445. }
  446. typename common::DoubleTime::type
  447. ta(typename common::DoubleTime::type /* t */) const override { return sigma; }
  448. common::Bag<common::DoubleTime>
  449. lambda(typename common::DoubleTime::type /* t */) const override
  450. {
  451. common::Bag<common::DoubleTime> msgs;
  452. if (full()) {
  453. msgs.push_back(artis::common::ExternalEvent<common::DoubleTime>(OUT, 0));
  454. }
  455. return msgs;
  456. }
  457. private:
  458. void compute()
  459. {
  460. for (unsigned int i = 0; i < heights.size(); ++i) {
  461. if (heights[i] != -1 and heights[i] < 10) {
  462. heights[i] += speeds[i] * scales[i];
  463. }
  464. }
  465. }
  466. void display() const
  467. {
  468. for (std::vector<double>::const_iterator it = heights.begin();
  469. it != heights.end(); ++it) {
  470. std::cout << *it << " ";
  471. }
  472. std::cout << std::endl;
  473. }
  474. void display_full() const
  475. {
  476. unsigned int i = 1;
  477. for (std::vector<double>::const_iterator it = heights.begin();
  478. it != heights.end(); ++it, ++i) {
  479. if (*it > 10) {
  480. std::cout << "S" << i;
  481. }
  482. }
  483. std::cout << std::endl;
  484. }
  485. bool full() const
  486. {
  487. unsigned int n = 0;
  488. for (std::vector<double>::const_iterator it = heights.begin();
  489. it != heights.end(); ++it) {
  490. if (*it > 10) {
  491. ++n;
  492. }
  493. }
  494. return n > 0;
  495. }
  496. bool full_N() const
  497. {
  498. unsigned int n = 0;
  499. for (std::vector<double>::const_iterator it = heights.begin();
  500. it != heights.end(); ++it) {
  501. if (*it == -1) {
  502. ++n;
  503. }
  504. }
  505. return n >= 2;
  506. }
  507. void mark_full(typename common::DoubleTime::type t)
  508. {
  509. for (std::vector<double>::iterator it = heights.begin();
  510. it != heights.end(); ++it) {
  511. if (*it > 10) {
  512. *it = -1;
  513. _last_time = t;
  514. }
  515. }
  516. }
  517. void raz()
  518. {
  519. for (std::vector<double>::iterator it = heights.begin();
  520. it != heights.end(); ++it) {
  521. if (*it == -1) {
  522. *it = 0;
  523. }
  524. }
  525. }
  526. // state
  527. std::vector<double> heights;
  528. std::vector<double> speeds;
  529. std::vector<double> scales;
  530. unsigned int index;
  531. unsigned int n;
  532. typename common::DoubleTime::type sigma;
  533. typename common::DoubleTime::type _last_time;
  534. };
  535. }
  536. }
  537. } // namespace artis tests pdevs
  538. #endif