No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

messages.cpp 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712
  1. /*
  2. * Copyright (C) 2018 dimercur
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include "messages.h"
  18. #include <exception>
  19. #include <stdexcept>
  20. #include <string>
  21. /*
  22. * @brief Constants used with ToString method, for printing message id
  23. */
  24. const string MESSAGE_ID_STRING[] = {
  25. "Empty",
  26. "Log",
  27. "Answer",
  28. "Monitor connection lost",
  29. "Open serial com",
  30. "Close serial com",
  31. "Open camera",
  32. "Close camera",
  33. "Ask for arena",
  34. "Arena confirmed",
  35. "Arena infirmed",
  36. "Compute position",
  37. "Stop compute position",
  38. "Position",
  39. "Image",
  40. "Robot ping",
  41. "Robot reset",
  42. "Robot start with wtachdog",
  43. "Robot start without wtachdog",
  44. "Robot reload watchdog",
  45. "Robot move",
  46. "Robot turn",
  47. "Robot go forward",
  48. "Robot go backward",
  49. "Robot go left",
  50. "Robot go right",
  51. "Robot stop",
  52. "Robot poweroff",
  53. "Robot get battery",
  54. "Robot battery level",
  55. "Robot get state",
  56. "Robot current state"
  57. };
  58. /*
  59. * @brief Constants used with ToString method, for printing answer id
  60. */
  61. const string ANSWER_ID_STRING[] = {
  62. "Acknowledge",
  63. "Not Acknowledge",
  64. "Robot lost",
  65. "Timeout error",
  66. "Unknown command",
  67. "Invalid or refused command",
  68. "Checksum error"
  69. };
  70. /**
  71. * Create a new, empty message
  72. */
  73. Message::Message() {
  74. this->messageID = MESSAGE_EMPTY;
  75. }
  76. /**
  77. * Create a new, empty message
  78. */
  79. Message::Message(MessageID id) {
  80. SetID(id);
  81. }
  82. /**
  83. * Destroy message
  84. */
  85. Message::~Message() {
  86. }
  87. /**
  88. * Set message ID
  89. * @param id Message ID
  90. */
  91. void Message::SetID(MessageID id) {
  92. if (CheckID(id)) {
  93. this->messageID = id;
  94. } else throw std::runtime_error {"Invalid message id for Message"};
  95. }
  96. /**
  97. * Translate content of message into a string that can be displayed
  98. * @return A string describing message contents
  99. */
  100. string Message::ToString() {
  101. if (CheckID(this->messageID))
  102. return "Id: \"" + MESSAGE_ID_STRING[this->messageID] + "\"";
  103. else
  104. return "Invalid message";
  105. }
  106. /**
  107. * Allocate a new mesage and copy contents of current message
  108. * @return A message, copy of current
  109. */
  110. Message* Message::Copy() {
  111. Message *msg = new Message();
  112. return msg;
  113. }
  114. /**
  115. * Get message ID
  116. * @return Current message ID
  117. */
  118. bool Message::CheckID(MessageID id) {
  119. if ((id != MESSAGE_EMPTY) &&
  120. (id != MESSAGE_MONITOR_LOST) &&
  121. (id != MESSAGE_ARENA_CONFIRM) &&
  122. (id != MESSAGE_ARENA_INFIRM) &&
  123. (id != MESSAGE_ASK_ARENA) &&
  124. (id != MESSAGE_CAM_CLOSE) &&
  125. (id != MESSAGE_CAM_OPEN) &&
  126. (id != MESSAGE_CLOSE_COM) &&
  127. (id != MESSAGE_COMPUTE_POSITION) &&
  128. (id != MESSAGE_OPEN_COM) &&
  129. (id != MESSAGE_ROBOT_GET_BATTERY) &&
  130. (id != MESSAGE_ROBOT_GET_STATE) &&
  131. (id != MESSAGE_ROBOT_GO_BACK) &&
  132. (id != MESSAGE_ROBOT_GO_FORWARD) &&
  133. (id != MESSAGE_ROBOT_GO_LEFT) &&
  134. (id != MESSAGE_ROBOT_GO_RIGHT) &&
  135. (id != MESSAGE_ROBOT_PING) &&
  136. (id != MESSAGE_ROBOT_POWEROFF) &&
  137. (id != MESSAGE_ROBOT_RELOAD_WD) &&
  138. (id != MESSAGE_ROBOT_RESET) &&
  139. (id != MESSAGE_ROBOT_START_WITHOUT_WD) &&
  140. (id != MESSAGE_ROBOT_START_WITH_WD) &&
  141. (id != MESSAGE_ROBOT_STOP) &&
  142. (id != MESSAGE_STOP_COMPUTE_POSITION)) {
  143. return false;
  144. } else return true;
  145. }
  146. /* MessageInt */
  147. /**
  148. * Create a new, empty int message
  149. */
  150. MessageInt::MessageInt() {
  151. value = 0.0;
  152. }
  153. /**
  154. * Create a new int message, with given ID and value
  155. * @param id Message ID
  156. * @param val Message value
  157. * @throw std::runtime_error if message ID is incompatible with int data
  158. */
  159. MessageInt::MessageInt(MessageID id, int val) {
  160. MessageInt::SetID(id);
  161. value = val;
  162. }
  163. /**
  164. * Set message ID
  165. * @param id Message ID
  166. * @throw std::runtime_error if message ID is incompatible with float data
  167. */
  168. void MessageInt::SetID(MessageID id) {
  169. if (CheckID(id))
  170. messageID = id;
  171. else
  172. throw std::runtime_error {
  173. "Invalid message id for MessageInt"
  174. };
  175. }
  176. /**
  177. * Translate content of message into a string that can be displayed
  178. * @return A string describing message contents
  179. */
  180. string MessageInt::ToString() {
  181. if (CheckID(this->messageID))
  182. return "Id: \"" + MESSAGE_ID_STRING[this->messageID] + "\"\nValue: " + to_string(this->value);
  183. else
  184. return "Invalid message";
  185. }
  186. /**
  187. * Allocate a new message and copy contents of current message
  188. * @return A message, copy of current
  189. */
  190. Message* MessageInt::Copy() {
  191. return new MessageInt(this->messageID, this->value);
  192. }
  193. /**
  194. * Verify if message ID is compatible with current message type
  195. * @param id Message ID
  196. * @return true, if message ID is acceptable, false otherwise
  197. */
  198. bool MessageInt::CheckID(MessageID id) {
  199. if ((id != MESSAGE_ROBOT_TURN) &&
  200. (id != MESSAGE_ROBOT_MOVE)) {
  201. return false;
  202. } else return true;
  203. }
  204. /* class MessageString */
  205. /**
  206. * Create a new, empty string message
  207. */
  208. MessageString::MessageString() {
  209. s = string("");
  210. }
  211. /**
  212. * Create a new string message, with given ID and string
  213. * @param id Message ID
  214. * @param s Message string
  215. * @throw std::runtime_error if message ID is incompatible with string data
  216. */
  217. MessageString::MessageString(MessageID id, string s) {
  218. MessageString::SetID(id);
  219. this->s = s;
  220. }
  221. /**
  222. * Set message ID
  223. * @param id Message ID
  224. * @throw std::runtime_error if message ID is incompatible with string data
  225. */
  226. void MessageString::SetID(MessageID id) {
  227. if (CheckID(id))
  228. messageID = id;
  229. else
  230. throw std::runtime_error {
  231. "Invalid message id for MessageString"
  232. };
  233. }
  234. /**
  235. * Translate content of message into a string that can be displayed
  236. * @return A string describing message contents
  237. */
  238. string MessageString::ToString() {
  239. if (CheckID(this->messageID))
  240. return "Id: \"" + MESSAGE_ID_STRING[this->messageID] + "\"\nString: \"" + this->s + "\"";
  241. else
  242. return "Invalid message";
  243. }
  244. /**
  245. * Allocate a new message and copy contents of current message
  246. * @return A message, copy of current
  247. */
  248. Message* MessageString::Copy() {
  249. return new MessageString(this->messageID, this->s);
  250. }
  251. /**
  252. * Verify if message ID is compatible with current message type
  253. * @param id Message ID
  254. * @return true, if message ID is acceptable, false otherwise
  255. */
  256. bool MessageString::CheckID(MessageID id) {
  257. if ((id != MESSAGE_LOG)) {
  258. return false;
  259. } else return true;
  260. }
  261. /* class MessageImg */
  262. /**
  263. * Create a new, empty image message
  264. */
  265. MessageImg::MessageImg() {
  266. image = NULL;
  267. }
  268. /**
  269. * Create a new image message, with given ID and image
  270. * @param id Message ID
  271. * @param image Image
  272. * @throw std::runtime_error if message ID is incompatible with image
  273. */
  274. MessageImg::MessageImg(MessageID id, Img* image) {
  275. MessageImg::SetID(id);
  276. MessageImg::SetImage(image);
  277. }
  278. /**
  279. * Destroy Image message
  280. */
  281. MessageImg::~MessageImg() {
  282. delete (this->image);
  283. }
  284. /**
  285. * Set message ID
  286. * @param id Message ID
  287. * @throw std::runtime_error if message ID is incompatible with image
  288. */
  289. void MessageImg::SetID(MessageID id) {
  290. if (CheckID(id))
  291. messageID = id;
  292. else
  293. throw std::runtime_error {
  294. "Invalid message id for MessageImg"
  295. };
  296. }
  297. /**
  298. * Set message image
  299. * @param image Reference to image object
  300. */
  301. void MessageImg::SetImage(Img* image) {
  302. this->image = image->Copy();
  303. }
  304. /**
  305. * Translate content of message into a string that can be displayed
  306. * @return A string describing message contents
  307. */
  308. string MessageImg::ToString() {
  309. if (CheckID(this->messageID))
  310. return "Id: \"" + MESSAGE_ID_STRING[this->messageID] + "\"\n" + this->image->ToString();
  311. else
  312. return "Invalid message";
  313. }
  314. /**
  315. * Allocate a new message and copy contents of current message
  316. * @return A message, copy of current
  317. */
  318. Message* MessageImg::Copy() {
  319. return new MessageImg(this->messageID, this->image->Copy());
  320. }
  321. /**
  322. * Verify if message ID is compatible with current message type
  323. * @param id Message ID
  324. * @return true, if message ID is acceptable, false otherwise
  325. */
  326. bool MessageImg::CheckID(MessageID id) {
  327. if (id != MESSAGE_IMAGE) {
  328. return false;
  329. } else return true;
  330. }
  331. /* class MessageAnswer*/
  332. /**
  333. * Create a new, empty answer message
  334. */
  335. MessageAnswer::MessageAnswer() {
  336. answer=ANSWER_ACK;
  337. }
  338. /**
  339. * Create a new answer message, with given ID and answer
  340. * @param id Message ID
  341. * @param ans Answer ID
  342. * @throw std::runtime_error if message ID is incompatible with string data
  343. */
  344. MessageAnswer::MessageAnswer(MessageID id, AnswerID ans) {
  345. MessageAnswer::SetID(id);
  346. MessageAnswer::SetAnswer(ans);
  347. }
  348. /**
  349. * Set message ID
  350. * @param id Message ID
  351. * @throw std::runtime_error if message ID is incompatible with answer message
  352. */
  353. void MessageAnswer::SetID(MessageID id) {
  354. if (CheckID(id))
  355. messageID = id;
  356. else
  357. throw std::runtime_error {
  358. "Invalid message id for MessageAnswer"
  359. };
  360. }
  361. /**
  362. * Set message answer
  363. * @param ans Answer ID
  364. * @throw std::runtime_error if answer ID is incompatible with answer data
  365. */
  366. void MessageAnswer::SetAnswer(AnswerID ans) {
  367. if ((ans != ANSWER_ACK) &&
  368. (ans != ANSWER_NACK) &&
  369. (ans != ANSWER_LOST_ROBOT) &&
  370. (ans != ANSWER_ROBOT_CHECKSUM) &&
  371. (ans != ANSWER_ROBOT_ERROR) &&
  372. (ans != ANSWER_ROBOT_TIMEOUT) &&
  373. (ans != ANSWER_ROBOT_UNKNOWN_COMMAND)) {
  374. this->answer = answer;
  375. } else {
  376. throw std::runtime_error{
  377. "Invalid answer for MessageAnswer"};
  378. }
  379. }
  380. /**
  381. * Translate content of message into a string that can be displayed
  382. * @return A string describing message contents
  383. */
  384. string MessageAnswer::ToString() {
  385. if (CheckID(this->messageID))
  386. return "Id: \"" + MESSAGE_ID_STRING[this->messageID] + "\"\nAnswer: \"" + ANSWER_ID_STRING[this->answer] + "\"";
  387. else
  388. return "Invalid message";
  389. }
  390. /**
  391. * Allocate a new message and copy contents of current message
  392. * @return A message, copy of current
  393. */
  394. Message* MessageAnswer::Copy() {
  395. return new MessageAnswer(this->messageID, this->answer);
  396. }
  397. /**
  398. * Verify if message ID is compatible with current message type
  399. * @param id Message ID
  400. * @return true, if message ID is acceptable, false otherwise
  401. */
  402. bool MessageAnswer::CheckID(MessageID id) {
  403. if ((id != MESSAGE_ANSWER)) {
  404. return false;
  405. } else return true;
  406. }
  407. /* class MessageBattery */
  408. /**
  409. * Create a new, empty battery message
  410. */
  411. MessageBattery::MessageBattery() {
  412. this->level = BATTERY_UNKNOWN;
  413. }
  414. /**
  415. * Create a new battery message, with given ID and battery level
  416. * @param id Message ID
  417. * @param level Battery level
  418. * @throw std::runtime_error if message ID is incompatible with battery
  419. */
  420. MessageBattery::MessageBattery(MessageID id, BatteryLevel level) {
  421. MessageBattery::SetID(id);
  422. MessageBattery::SetLevel(level);
  423. }
  424. /**
  425. * Set message ID
  426. * @param id Message ID
  427. * @throw std::runtime_error if message ID is incompatible with battery
  428. */
  429. void MessageBattery::SetID(MessageID id) {
  430. if (CheckID(id))
  431. messageID = id;
  432. else
  433. throw std::runtime_error {
  434. "Invalid message id for MessageBattery"
  435. };
  436. }
  437. /**
  438. * Set battery level
  439. * @param level Battery level
  440. */
  441. void MessageBattery::SetLevel(BatteryLevel level) {
  442. if ((level < BATTERY_UNKNOWN) || (level > BATTERY_FULL)) {
  443. throw std::runtime_error{
  444. "Invalid battery level for MessageBattery"};
  445. } else {
  446. this->level = level;
  447. }
  448. }
  449. /**
  450. * Translate content of message into a string that can be displayed
  451. * @return A string describing message contents
  452. */
  453. string MessageBattery::ToString() {
  454. string levelString;
  455. switch (this->level) {
  456. case BATTERY_UNKNOWN:
  457. levelString="Unknown";
  458. break;
  459. case BATTERY_EMPTY:
  460. levelString="Empty";
  461. break;
  462. case BATTERY_LOW:
  463. levelString="Low";
  464. break;
  465. case BATTERY_FULL:
  466. levelString="Full";
  467. break;
  468. default:
  469. levelString="Invalid";
  470. }
  471. if (CheckID(this->messageID))
  472. return "Id: \"" + MESSAGE_ID_STRING[this->messageID] + "\"\nBattery level: \"" + levelString + "\"";
  473. else
  474. return "Invalid message";
  475. }
  476. /**
  477. * Allocate a new message and copy contents of current message
  478. * @return A message, copy of current
  479. */
  480. Message* MessageBattery::Copy() {
  481. return new MessageBattery(this->messageID, this->level);
  482. }
  483. /**
  484. * Verify if message ID is compatible with current message type
  485. * @param id Message ID
  486. * @return true, if message ID is acceptable, false otherwise
  487. */
  488. bool MessageBattery::CheckID(MessageID id) {
  489. if ((id != MESSAGE_ROBOT_BATTERY_LEVEL)) {
  490. return false;
  491. } else return true;
  492. }
  493. /* class MessagePosition */
  494. /**
  495. * Create a new, empty string message
  496. */
  497. MessagePosition::MessagePosition() {
  498. this->pos.angle = 0.0;
  499. this->pos.robotId = 0;
  500. this->pos.center.x=0.0;
  501. this->pos.center.y=0.0;
  502. this->pos.direction.x=0.0;
  503. this->pos.direction.y=0.0;
  504. }
  505. /**
  506. * Create a new string message, with given ID and string
  507. * @param id Message ID
  508. * @param s Message string
  509. * @throw std::runtime_error if message ID is incompatible with string data
  510. */
  511. MessagePosition::MessagePosition(MessageID id, Position& pos) {
  512. MessagePosition::SetID(id);
  513. MessagePosition::SetPosition(pos);
  514. }
  515. /**
  516. * Set message ID
  517. * @param id Message ID
  518. * @throw std::runtime_error if message ID is incompatible with string data
  519. */
  520. void MessagePosition::SetID(MessageID id) {
  521. if (CheckID(id))
  522. messageID = id;
  523. else
  524. throw std::runtime_error {
  525. "Invalid message id for MessagePosition"
  526. };
  527. }
  528. /**
  529. * Set position
  530. * @param pos Reference to position
  531. */
  532. void MessagePosition::SetPosition(Position& pos) {
  533. this->pos.angle = pos.angle;
  534. this->pos.robotId = pos.robotId;
  535. this->pos.center = pos.center;
  536. this->pos.direction = pos.direction;
  537. }
  538. /**
  539. * Translate content of message into a string that can be displayed
  540. * @return A string describing message contents
  541. */
  542. string MessagePosition::ToString() {
  543. if (CheckID(this->messageID))
  544. return "Id: \"" + MESSAGE_ID_STRING[this->messageID] + "\"\nPosition: \"" + to_string(this->pos.center.x) + ";" + to_string(this->pos.center.y) + "\"";
  545. else
  546. return "Invalid message";
  547. }
  548. /**
  549. * Allocate a new message and copy contents of current message
  550. * @return A message, copy of current
  551. */
  552. Message* MessagePosition::Copy() {
  553. return new MessagePosition(this->messageID, this->pos);
  554. }
  555. /**
  556. * Verify if message ID is compatible with current message type
  557. * @param id Message ID
  558. * @return true, if message ID is acceptable, false otherwise
  559. */
  560. bool MessagePosition::CheckID(MessageID id) {
  561. if ((id != MESSAGE_POSITION)) {
  562. return false;
  563. } else return true;
  564. }
  565. /* class MessageState */
  566. /**
  567. * Create a new, empty state message
  568. */
  569. MessageState::MessageState() {
  570. state = ROBOT_NOT_BUSY;
  571. }
  572. /**
  573. * Create a new string message, with given ID and string
  574. * @param id Message ID
  575. * @param s Message string
  576. * @throw std::runtime_error if message ID is incompatible with string data
  577. */
  578. MessageState::MessageState(MessageID id, RobotState state) {
  579. MessageState::SetID(id);
  580. MessageState::SetState(state);
  581. }
  582. /**
  583. * Set message ID
  584. * @param id Message ID
  585. * @throw std::runtime_error if message ID is incompatible with robot state
  586. */
  587. void MessageState::SetID(MessageID id) {
  588. if (CheckID(id))
  589. messageID = id;
  590. else
  591. throw std::runtime_error {
  592. "Invalid message id for MessageState"
  593. };
  594. }
  595. /**
  596. * Set robot state
  597. * @param state Robot state
  598. */
  599. void MessageState::SetState(RobotState state) {
  600. if ((state != ROBOT_NOT_BUSY) && (state != ROBOT_BUSY)) {
  601. throw std::runtime_error{
  602. "Invalid state for MessageState"};
  603. } else {
  604. this->state = state;
  605. }
  606. }
  607. /**
  608. * Translate content of message into a string that can be displayed
  609. * @return A string describing message contents
  610. */
  611. string MessageState::ToString() {
  612. string stateString;
  613. if (this->state == ROBOT_NOT_BUSY) stateString="Not busy";
  614. else if (this->state == ROBOT_BUSY) stateString="Busy";
  615. else stateString="Invalid state";
  616. if (CheckID(this->messageID))
  617. return "Id: \"" + MESSAGE_ID_STRING[this->messageID] + "\"\nState: \"" + stateString + "\"";
  618. else
  619. return "Invalid message";
  620. }
  621. /**
  622. * Allocate a new message and copy contents of current message
  623. * @return A message, copy of current
  624. */
  625. Message* MessageState::Copy() {
  626. return new MessageState(this->messageID, this->state);
  627. }
  628. /**
  629. * Verify if message ID is compatible with current message type
  630. * @param id Message ID
  631. * @return true, if message ID is acceptable, false otherwise
  632. */
  633. bool MessageState::CheckID(MessageID id) {
  634. if ((id != MESSAGE_ROBOT_CURRENT_STATE)) {
  635. return false;
  636. } else return true;
  637. }