isar 1.33.6__tar.gz → 1.33.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of isar might be problematic. Click here for more details.

Files changed (226) hide show
  1. {isar-1.33.6 → isar-1.33.8}/PKG-INFO +1 -1
  2. isar-1.33.8/docs/full_state_machine_diagram.png +0 -0
  3. isar-1.33.8/docs/mission_state_machine_diagram.png +0 -0
  4. isar-1.33.8/docs/robot_status_state_machine_diagram.png +0 -0
  5. {isar-1.33.6 → isar-1.33.8}/src/isar/config/settings.py +4 -0
  6. {isar-1.33.6 → isar-1.33.8}/src/isar/models/events.py +6 -0
  7. isar-1.33.8/src/isar/models/status.py +16 -0
  8. {isar-1.33.6 → isar-1.33.8}/src/isar/robot/robot.py +18 -1
  9. isar-1.33.6/src/isar/robot/robot_status.py → isar-1.33.8/src/isar/robot/robot_battery.py +17 -15
  10. isar-1.33.8/src/isar/robot/robot_status.py +71 -0
  11. {isar-1.33.6 → isar-1.33.8}/src/isar/services/utilities/scheduling_utilities.py +87 -1
  12. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/state_machine.py +20 -16
  13. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/states/blocked_protective_stop.py +9 -9
  14. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/states/home.py +21 -13
  15. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/states/offline.py +9 -10
  16. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/transitions/functions/robot_status.py +15 -0
  17. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/transitions/return_home.py +9 -0
  18. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/utils/common_event_handlers.py +5 -2
  19. {isar-1.33.6 → isar-1.33.8}/src/isar/storage/uploader.py +3 -0
  20. {isar-1.33.6 → isar-1.33.8}/src/isar.egg-info/PKG-INFO +1 -1
  21. {isar-1.33.6 → isar-1.33.8}/src/isar.egg-info/SOURCES.txt +2 -0
  22. {isar-1.33.6 → isar-1.33.8}/src/robot_interface/models/mission/status.py +0 -6
  23. {isar-1.33.6 → isar-1.33.8}/src/robot_interface/telemetry/payloads.py +4 -3
  24. {isar-1.33.6 → isar-1.33.8}/tests/conftest.py +2 -0
  25. {isar-1.33.6 → isar-1.33.8}/tests/isar/state_machine/test_state_machine.py +33 -13
  26. {isar-1.33.6 → isar-1.33.8}/tests/test_double/robot_interface.py +38 -1
  27. isar-1.33.6/docs/full_state_machine_diagram.png +0 -0
  28. isar-1.33.6/docs/mission_state_machine_diagram.png +0 -0
  29. isar-1.33.6/docs/robot_status_state_machine_diagram.png +0 -0
  30. {isar-1.33.6 → isar-1.33.8}/.dockerignore +0 -0
  31. {isar-1.33.6 → isar-1.33.8}/.env.test +0 -0
  32. {isar-1.33.6 → isar-1.33.8}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  33. {isar-1.33.6 → isar-1.33.8}/.github/ISSUE_TEMPLATE/feature.md +0 -0
  34. {isar-1.33.6 → isar-1.33.8}/.github/ISSUE_TEMPLATE/improvement.md +0 -0
  35. {isar-1.33.6 → isar-1.33.8}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  36. {isar-1.33.6 → isar-1.33.8}/.github/release.yml +0 -0
  37. {isar-1.33.6 → isar-1.33.8}/.github/workflows/compile_requirements.yml +0 -0
  38. {isar-1.33.6 → isar-1.33.8}/.github/workflows/project_automations.yml +0 -0
  39. {isar-1.33.6 → isar-1.33.8}/.github/workflows/pythonpackage.yml +0 -0
  40. {isar-1.33.6 → isar-1.33.8}/.github/workflows/pythonpublish.yml +0 -0
  41. {isar-1.33.6 → isar-1.33.8}/.github/workflows/stale.yml +0 -0
  42. {isar-1.33.6 → isar-1.33.8}/.gitignore +0 -0
  43. {isar-1.33.6 → isar-1.33.8}/.pre-commit-config.yaml +0 -0
  44. {isar-1.33.6 → isar-1.33.8}/LICENSE +0 -0
  45. {isar-1.33.6 → isar-1.33.8}/README.md +0 -0
  46. {isar-1.33.6 → isar-1.33.8}/SECURITY.md +0 -0
  47. {isar-1.33.6 → isar-1.33.8}/docs/Makefile +0 -0
  48. {isar-1.33.6 → isar-1.33.8}/docs/make.bat +0 -0
  49. {isar-1.33.6 → isar-1.33.8}/docs/rst_processing.py +0 -0
  50. {isar-1.33.6 → isar-1.33.8}/docs/source/conf.py +0 -0
  51. {isar-1.33.6 → isar-1.33.8}/docs/source/index.rst +0 -0
  52. {isar-1.33.6 → isar-1.33.8}/docs/source/readme_link.md +0 -0
  53. {isar-1.33.6 → isar-1.33.8}/docs/update_state_diagram.py +0 -0
  54. {isar-1.33.6 → isar-1.33.8}/main.py +0 -0
  55. {isar-1.33.6 → isar-1.33.8}/pyproject.toml +0 -0
  56. {isar-1.33.6 → isar-1.33.8}/radixconfig.yml +0 -0
  57. {isar-1.33.6 → isar-1.33.8}/requirements.txt +0 -0
  58. {isar-1.33.6 → isar-1.33.8}/setup.cfg +0 -0
  59. {isar-1.33.6 → isar-1.33.8}/src/isar/__init__.py +0 -0
  60. {isar-1.33.6 → isar-1.33.8}/src/isar/apis/__init__.py +0 -0
  61. {isar-1.33.6 → isar-1.33.8}/src/isar/apis/api.py +0 -0
  62. {isar-1.33.6 → isar-1.33.8}/src/isar/apis/models/__init__.py +0 -0
  63. {isar-1.33.6 → isar-1.33.8}/src/isar/apis/models/models.py +0 -0
  64. {isar-1.33.6 → isar-1.33.8}/src/isar/apis/models/start_mission_definition.py +0 -0
  65. {isar-1.33.6 → isar-1.33.8}/src/isar/apis/robot_control/robot_controller.py +0 -0
  66. {isar-1.33.6 → isar-1.33.8}/src/isar/apis/schedule/__init__.py +0 -0
  67. {isar-1.33.6 → isar-1.33.8}/src/isar/apis/schedule/scheduling_controller.py +0 -0
  68. {isar-1.33.6 → isar-1.33.8}/src/isar/apis/security/__init__.py +0 -0
  69. {isar-1.33.6 → isar-1.33.8}/src/isar/apis/security/authentication.py +0 -0
  70. {isar-1.33.6 → isar-1.33.8}/src/isar/config/__init__.py +0 -0
  71. {isar-1.33.6 → isar-1.33.8}/src/isar/config/certs/ca-cert.pem +0 -0
  72. {isar-1.33.6 → isar-1.33.8}/src/isar/config/configuration_error.py +0 -0
  73. {isar-1.33.6 → isar-1.33.8}/src/isar/config/keyvault/__init__.py +0 -0
  74. {isar-1.33.6 → isar-1.33.8}/src/isar/config/keyvault/keyvault_error.py +0 -0
  75. {isar-1.33.6 → isar-1.33.8}/src/isar/config/keyvault/keyvault_service.py +0 -0
  76. {isar-1.33.6 → isar-1.33.8}/src/isar/config/log.py +0 -0
  77. {isar-1.33.6 → isar-1.33.8}/src/isar/config/logging.conf +0 -0
  78. {isar-1.33.6 → isar-1.33.8}/src/isar/config/maps/JSP1_intermediate_deck.json +0 -0
  79. {isar-1.33.6 → isar-1.33.8}/src/isar/config/maps/JSP1_weather_deck.json +0 -0
  80. {isar-1.33.6 → isar-1.33.8}/src/isar/config/maps/default_map.json +0 -0
  81. {isar-1.33.6 → isar-1.33.8}/src/isar/config/maps/klab_b.json +0 -0
  82. {isar-1.33.6 → isar-1.33.8}/src/isar/config/maps/klab_compressor.json +0 -0
  83. {isar-1.33.6 → isar-1.33.8}/src/isar/config/maps/klab_turtlebot.json +0 -0
  84. {isar-1.33.6 → isar-1.33.8}/src/isar/config/maps/turtleworld.json +0 -0
  85. {isar-1.33.6 → isar-1.33.8}/src/isar/config/open_telemetry.py +0 -0
  86. {isar-1.33.6 → isar-1.33.8}/src/isar/config/predefined_mission_definition/__init__.py +0 -0
  87. {isar-1.33.6 → isar-1.33.8}/src/isar/config/predefined_mission_definition/default_exr.json +0 -0
  88. {isar-1.33.6 → isar-1.33.8}/src/isar/config/predefined_mission_definition/default_mission.json +0 -0
  89. {isar-1.33.6 → isar-1.33.8}/src/isar/config/predefined_mission_definition/default_turtlebot.json +0 -0
  90. {isar-1.33.6 → isar-1.33.8}/src/isar/config/predefined_missions/__init__.py +0 -0
  91. {isar-1.33.6 → isar-1.33.8}/src/isar/config/predefined_missions/default.json +0 -0
  92. {isar-1.33.6 → isar-1.33.8}/src/isar/config/predefined_missions/default_turtlebot.json +0 -0
  93. {isar-1.33.6 → isar-1.33.8}/src/isar/eventhandlers/eventhandler.py +0 -0
  94. {isar-1.33.6 → isar-1.33.8}/src/isar/mission_planner/__init__.py +0 -0
  95. {isar-1.33.6 → isar-1.33.8}/src/isar/mission_planner/local_planner.py +0 -0
  96. {isar-1.33.6 → isar-1.33.8}/src/isar/mission_planner/mission_planner_interface.py +0 -0
  97. {isar-1.33.6 → isar-1.33.8}/src/isar/mission_planner/sequential_task_selector.py +0 -0
  98. {isar-1.33.6 → isar-1.33.8}/src/isar/mission_planner/task_selector_interface.py +0 -0
  99. {isar-1.33.6 → isar-1.33.8}/src/isar/models/__init__.py +0 -0
  100. {isar-1.33.6 → isar-1.33.8}/src/isar/modules.py +0 -0
  101. {isar-1.33.6 → isar-1.33.8}/src/isar/robot/robot_pause_mission.py +0 -0
  102. {isar-1.33.6 → isar-1.33.8}/src/isar/robot/robot_start_mission.py +0 -0
  103. {isar-1.33.6 → isar-1.33.8}/src/isar/robot/robot_stop_mission.py +0 -0
  104. {isar-1.33.6 → isar-1.33.8}/src/isar/robot/robot_task_status.py +0 -0
  105. {isar-1.33.6 → isar-1.33.8}/src/isar/script.py +0 -0
  106. {isar-1.33.6 → isar-1.33.8}/src/isar/services/__init__.py +0 -0
  107. {isar-1.33.6 → isar-1.33.8}/src/isar/services/auth/__init__.py +0 -0
  108. {isar-1.33.6 → isar-1.33.8}/src/isar/services/auth/azure_credentials.py +0 -0
  109. {isar-1.33.6 → isar-1.33.8}/src/isar/services/service_connections/__init__.py +0 -0
  110. {isar-1.33.6 → isar-1.33.8}/src/isar/services/service_connections/mqtt/__init__.py +0 -0
  111. {isar-1.33.6 → isar-1.33.8}/src/isar/services/service_connections/mqtt/mqtt_client.py +0 -0
  112. {isar-1.33.6 → isar-1.33.8}/src/isar/services/service_connections/mqtt/robot_heartbeat_publisher.py +0 -0
  113. {isar-1.33.6 → isar-1.33.8}/src/isar/services/service_connections/mqtt/robot_info_publisher.py +0 -0
  114. {isar-1.33.6 → isar-1.33.8}/src/isar/services/service_connections/request_handler.py +0 -0
  115. {isar-1.33.6 → isar-1.33.8}/src/isar/services/utilities/__init__.py +0 -0
  116. {isar-1.33.6 → isar-1.33.8}/src/isar/services/utilities/robot_utilities.py +0 -0
  117. {isar-1.33.6 → isar-1.33.8}/src/isar/services/utilities/threaded_request.py +0 -0
  118. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/__init__.py +0 -0
  119. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/states/__init__.py +0 -0
  120. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/states/await_next_mission.py +0 -0
  121. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/states/going_to_lockdown.py +0 -0
  122. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/states/intervention_needed.py +0 -0
  123. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/states/lockdown.py +0 -0
  124. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/states/monitor.py +0 -0
  125. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/states/paused.py +0 -0
  126. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/states/pausing.py +0 -0
  127. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/states/pausing_return_home.py +0 -0
  128. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/states/recharging.py +0 -0
  129. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/states/return_home_paused.py +0 -0
  130. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/states/returning_home.py +0 -0
  131. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/states/stopping.py +0 -0
  132. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/states/stopping_go_to_lockdown.py +0 -0
  133. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/states/stopping_return_home.py +0 -0
  134. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/states/unknown_status.py +0 -0
  135. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/states_enum.py +0 -0
  136. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/transitions/functions/fail_mission.py +0 -0
  137. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/transitions/functions/finish_mission.py +0 -0
  138. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/transitions/functions/pause.py +0 -0
  139. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/transitions/functions/resume.py +0 -0
  140. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/transitions/functions/return_home.py +0 -0
  141. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/transitions/functions/start_mission.py +0 -0
  142. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/transitions/functions/stop.py +0 -0
  143. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/transitions/functions/utils.py +0 -0
  144. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/transitions/mission.py +0 -0
  145. {isar-1.33.6 → isar-1.33.8}/src/isar/state_machine/transitions/robot_status.py +0 -0
  146. {isar-1.33.6 → isar-1.33.8}/src/isar/storage/__init__.py +0 -0
  147. {isar-1.33.6 → isar-1.33.8}/src/isar/storage/blob_storage.py +0 -0
  148. {isar-1.33.6 → isar-1.33.8}/src/isar/storage/local_storage.py +0 -0
  149. {isar-1.33.6 → isar-1.33.8}/src/isar/storage/storage_interface.py +0 -0
  150. {isar-1.33.6 → isar-1.33.8}/src/isar/storage/utilities.py +0 -0
  151. {isar-1.33.6 → isar-1.33.8}/src/isar.egg-info/dependency_links.txt +0 -0
  152. {isar-1.33.6 → isar-1.33.8}/src/isar.egg-info/entry_points.txt +0 -0
  153. {isar-1.33.6 → isar-1.33.8}/src/isar.egg-info/requires.txt +0 -0
  154. {isar-1.33.6 → isar-1.33.8}/src/isar.egg-info/top_level.txt +0 -0
  155. {isar-1.33.6 → isar-1.33.8}/src/robot_interface/__init__.py +0 -0
  156. {isar-1.33.6 → isar-1.33.8}/src/robot_interface/models/__init__.py +0 -0
  157. {isar-1.33.6 → isar-1.33.8}/src/robot_interface/models/exceptions/__init__.py +0 -0
  158. {isar-1.33.6 → isar-1.33.8}/src/robot_interface/models/exceptions/robot_exceptions.py +0 -0
  159. {isar-1.33.6 → isar-1.33.8}/src/robot_interface/models/initialize/__init__.py +0 -0
  160. {isar-1.33.6 → isar-1.33.8}/src/robot_interface/models/inspection/__init__.py +0 -0
  161. {isar-1.33.6 → isar-1.33.8}/src/robot_interface/models/inspection/inspection.py +0 -0
  162. {isar-1.33.6 → isar-1.33.8}/src/robot_interface/models/mission/__init__.py +0 -0
  163. {isar-1.33.6 → isar-1.33.8}/src/robot_interface/models/mission/mission.py +0 -0
  164. {isar-1.33.6 → isar-1.33.8}/src/robot_interface/models/mission/task.py +0 -0
  165. {isar-1.33.6 → isar-1.33.8}/src/robot_interface/models/robots/__init__.py +0 -0
  166. {isar-1.33.6 → isar-1.33.8}/src/robot_interface/models/robots/battery_state.py +0 -0
  167. {isar-1.33.6 → isar-1.33.8}/src/robot_interface/models/robots/media.py +0 -0
  168. {isar-1.33.6 → isar-1.33.8}/src/robot_interface/models/robots/robot_model.py +0 -0
  169. {isar-1.33.6 → isar-1.33.8}/src/robot_interface/robot_interface.py +0 -0
  170. {isar-1.33.6 → isar-1.33.8}/src/robot_interface/telemetry/__init__.py +0 -0
  171. {isar-1.33.6 → isar-1.33.8}/src/robot_interface/telemetry/mqtt_client.py +0 -0
  172. {isar-1.33.6 → isar-1.33.8}/src/robot_interface/test_robot_interface.py +0 -0
  173. {isar-1.33.6 → isar-1.33.8}/src/robot_interface/utilities/__init__.py +0 -0
  174. {isar-1.33.6 → isar-1.33.8}/src/robot_interface/utilities/json_service.py +0 -0
  175. {isar-1.33.6 → isar-1.33.8}/src/robot_interface/utilities/uuid_string_factory.py +0 -0
  176. {isar-1.33.6 → isar-1.33.8}/tests/__init__.py +0 -0
  177. {isar-1.33.6 → isar-1.33.8}/tests/integration/__init__.py +0 -0
  178. {isar-1.33.6 → isar-1.33.8}/tests/integration/turtlebot/__init__.py +0 -0
  179. {isar-1.33.6 → isar-1.33.8}/tests/integration/turtlebot/config/__init__.py +0 -0
  180. {isar-1.33.6 → isar-1.33.8}/tests/integration/turtlebot/config/maps/__init__.py +0 -0
  181. {isar-1.33.6 → isar-1.33.8}/tests/integration/turtlebot/config/maps/turtleworld.json +0 -0
  182. {isar-1.33.6 → isar-1.33.8}/tests/integration/turtlebot/config/missions/__init__.py +0 -0
  183. {isar-1.33.6 → isar-1.33.8}/tests/integration/turtlebot/config/missions/default.json +0 -0
  184. {isar-1.33.6 → isar-1.33.8}/tests/integration/turtlebot/test_successful_mission.py +0 -0
  185. {isar-1.33.6 → isar-1.33.8}/tests/isar/__init__.py +0 -0
  186. {isar-1.33.6 → isar-1.33.8}/tests/isar/apis/__init__.py +0 -0
  187. {isar-1.33.6 → isar-1.33.8}/tests/isar/apis/models/__init__.py +0 -0
  188. {isar-1.33.6 → isar-1.33.8}/tests/isar/apis/models/example_mission_definition.json +0 -0
  189. {isar-1.33.6 → isar-1.33.8}/tests/isar/apis/models/test_start_mission_definition.py +0 -0
  190. {isar-1.33.6 → isar-1.33.8}/tests/isar/apis/scheduler/__init__.py +0 -0
  191. {isar-1.33.6 → isar-1.33.8}/tests/isar/apis/scheduler/test_scheduler_router.py +0 -0
  192. {isar-1.33.6 → isar-1.33.8}/tests/isar/apis/security/__init__.py +0 -0
  193. {isar-1.33.6 → isar-1.33.8}/tests/isar/apis/security/test_authentication.py +0 -0
  194. {isar-1.33.6 → isar-1.33.8}/tests/isar/mission/__init__.py +0 -0
  195. {isar-1.33.6 → isar-1.33.8}/tests/isar/mission/test_mission.py +0 -0
  196. {isar-1.33.6 → isar-1.33.8}/tests/isar/models/__init__.py +0 -0
  197. {isar-1.33.6 → isar-1.33.8}/tests/isar/models/communication/__init__.py +0 -0
  198. {isar-1.33.6 → isar-1.33.8}/tests/isar/models/communication/test_events.py +0 -0
  199. {isar-1.33.6 → isar-1.33.8}/tests/isar/services/__init__.py +0 -0
  200. {isar-1.33.6 → isar-1.33.8}/tests/isar/services/readers/__init__.py +0 -0
  201. {isar-1.33.6 → isar-1.33.8}/tests/isar/services/readers/test_mission_reader.py +0 -0
  202. {isar-1.33.6 → isar-1.33.8}/tests/isar/services/service_connections/__init__.py +0 -0
  203. {isar-1.33.6 → isar-1.33.8}/tests/isar/services/service_connections/echo/__init__.py +0 -0
  204. {isar-1.33.6 → isar-1.33.8}/tests/isar/services/service_connections/test_base_request_handler.py +0 -0
  205. {isar-1.33.6 → isar-1.33.8}/tests/isar/services/utilities/__init__.py +0 -0
  206. {isar-1.33.6 → isar-1.33.8}/tests/isar/services/utilities/test_queue_utilities.py +0 -0
  207. {isar-1.33.6 → isar-1.33.8}/tests/isar/services/utilities/test_scheduling_utilities.py +0 -0
  208. {isar-1.33.6 → isar-1.33.8}/tests/isar/state_machine/__init__.py +0 -0
  209. {isar-1.33.6 → isar-1.33.8}/tests/isar/state_machine/states/__init__.py +0 -0
  210. {isar-1.33.6 → isar-1.33.8}/tests/isar/state_machine/states/test_monitor.py +0 -0
  211. {isar-1.33.6 → isar-1.33.8}/tests/isar/storage/test_blob_storage.py +0 -0
  212. {isar-1.33.6 → isar-1.33.8}/tests/isar/storage/test_uploader.py +0 -0
  213. {isar-1.33.6 → isar-1.33.8}/tests/test_data/test_map_config/test_map_config.json +0 -0
  214. {isar-1.33.6 → isar-1.33.8}/tests/test_data/test_mission_not_working.json +0 -0
  215. {isar-1.33.6 → isar-1.33.8}/tests/test_data/test_mission_working.json +0 -0
  216. {isar-1.33.6 → isar-1.33.8}/tests/test_data/test_mission_working_no_tasks.json +0 -0
  217. {isar-1.33.6 → isar-1.33.8}/tests/test_data/test_thermal_image_mission.json +0 -0
  218. {isar-1.33.6 → isar-1.33.8}/tests/test_double/__init__.py +0 -0
  219. {isar-1.33.6 → isar-1.33.8}/tests/test_double/blob_storage.py +0 -0
  220. {isar-1.33.6 → isar-1.33.8}/tests/test_double/mission_definition.py +0 -0
  221. {isar-1.33.6 → isar-1.33.8}/tests/test_double/mqtt_client.py +0 -0
  222. {isar-1.33.6 → isar-1.33.8}/tests/test_double/pose.py +0 -0
  223. {isar-1.33.6 → isar-1.33.8}/tests/test_double/request.py +0 -0
  224. {isar-1.33.6 → isar-1.33.8}/tests/test_double/status.py +0 -0
  225. {isar-1.33.6 → isar-1.33.8}/tests/test_double/task.py +0 -0
  226. {isar-1.33.6 → isar-1.33.8}/tests/test_double/token.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: isar
3
- Version: 1.33.6
3
+ Version: 1.33.8
4
4
  Summary: Integration and Supervisory control of Autonomous Robots
5
5
  Author-email: Equinor ASA <fg_robots_dev@equinor.com>
6
6
  License: Eclipse Public License version 2.0
@@ -59,6 +59,9 @@ class Settings(BaseSettings):
59
59
  # issues
60
60
  REQUEST_STATUS_COMMUNICATION_RECONNECT_DELAY: float = Field(default=10)
61
61
 
62
+ # Time allowed to clear the robot status before giving up
63
+ CLEAR_ROBOT_STATUS_TIMEOUT: int = Field(default=3)
64
+
62
65
  # Number of attempts for state transitions resume and pause if failed
63
66
  STATE_TRANSITION_NUM_RETIRES: int = Field(default=10)
64
67
 
@@ -78,6 +81,7 @@ class Settings(BaseSettings):
78
81
  ROBOT_STATUS_PUBLISH_INTERVAL: float = Field(default=1)
79
82
  ROBOT_HEARTBEAT_PUBLISH_INTERVAL: float = Field(default=1)
80
83
  ROBOT_INFO_PUBLISH_INTERVAL: float = Field(default=5)
84
+ ROBOT_API_BATTERY_POLL_INTERVAL: float = Field(default=5)
81
85
  ROBOT_API_STATUS_POLL_INTERVAL: float = Field(default=5)
82
86
  THREAD_CHECK_INTERVAL: float = Field(default=0.01)
83
87
 
@@ -42,6 +42,8 @@ class Event(Queue[T]):
42
42
  if timeout is not None:
43
43
  raise EventTimeoutError
44
44
  return None
45
+ except ValueError:
46
+ raise EventConflictError
45
47
 
46
48
  def clear_event(self) -> None:
47
49
  while True:
@@ -49,6 +51,8 @@ class Event(Queue[T]):
49
51
  self.get(block=False)
50
52
  except Empty:
51
53
  break
54
+ except ValueError:
55
+ break
52
56
 
53
57
  def has_event(self) -> bool:
54
58
  return (
@@ -123,6 +127,7 @@ class StateMachineEvents:
123
127
  self.stop_mission: Event[bool] = Event("stop_mission")
124
128
  self.pause_mission: Event[bool] = Event("pause_mission")
125
129
  self.task_status_request: Event[str] = Event("task_status_request")
130
+ self.clear_robot_status: Event[bool] = Event("clear_robot_status")
126
131
 
127
132
 
128
133
  class RobotServiceEvents:
@@ -132,6 +137,7 @@ class RobotServiceEvents:
132
137
  self.mission_started: Event[bool] = Event("mission_started")
133
138
  self.mission_failed: Event[ErrorMessage] = Event("mission_failed")
134
139
  self.robot_status_changed: Event[bool] = Event("robot_status_changed")
140
+ self.robot_status_cleared: Event[bool] = Event("robot_status_cleared")
135
141
  self.mission_failed_to_stop: Event[ErrorMessage] = Event(
136
142
  "mission_failed_to_stop"
137
143
  )
@@ -0,0 +1,16 @@
1
+ from enum import Enum
2
+
3
+
4
+ class IsarStatus(Enum):
5
+ Available = "available"
6
+ ReturnHomePaused = "returnhomepaused"
7
+ Paused = "paused"
8
+ Busy = "busy"
9
+ Home = "home"
10
+ Offline = "offline"
11
+ BlockedProtectiveStop = "blockedprotectivestop"
12
+ ReturningHome = "returninghome"
13
+ InterventionNeeded = "interventionneeded"
14
+ Recharging = "recharging"
15
+ Lockdown = "lockdown"
16
+ GoingToLockdown = "goingtolockdown"
@@ -9,6 +9,7 @@ from isar.models.events import (
9
9
  SharedState,
10
10
  StateMachineEvents,
11
11
  )
12
+ from isar.robot.robot_battery import RobotBatteryThread
12
13
  from isar.robot.robot_pause_mission import RobotPauseMissionThread
13
14
  from isar.robot.robot_start_mission import RobotStartMissionThread
14
15
  from isar.robot.robot_status import RobotStatusThread
@@ -29,6 +30,7 @@ class Robot(object):
29
30
  self.shared_state: SharedState = shared_state
30
31
  self.robot: RobotInterface = robot
31
32
  self.start_mission_thread: Optional[RobotStartMissionThread] = None
33
+ self.robot_battery_thread: Optional[RobotBatteryThread] = None
32
34
  self.robot_status_thread: Optional[RobotStatusThread] = None
33
35
  self.robot_task_status_thread: Optional[RobotTaskStatusThread] = None
34
36
  self.stop_mission_thread: Optional[RobotStopMissionThread] = None
@@ -39,6 +41,11 @@ class Robot(object):
39
41
  self.signal_thread_quitting.set()
40
42
  if self.robot_status_thread is not None and self.robot_status_thread.is_alive():
41
43
  self.robot_status_thread.join()
44
+ if (
45
+ self.robot_battery_thread is not None
46
+ and self.robot_battery_thread.is_alive()
47
+ ):
48
+ self.robot_battery_thread.join()
42
49
  if (
43
50
  self.robot_task_status_thread is not None
44
51
  and self.robot_task_status_thread.is_alive()
@@ -52,6 +59,7 @@ class Robot(object):
52
59
  if self.stop_mission_thread is not None and self.stop_mission_thread.is_alive():
53
60
  self.stop_mission_thread.join()
54
61
  self.robot_status_thread = None
62
+ self.robot_battery_thread = None
55
63
  self.robot_task_status_thread = None
56
64
  self.start_mission_thread = None
57
65
 
@@ -143,10 +151,19 @@ class Robot(object):
143
151
 
144
152
  def run(self) -> None:
145
153
  self.robot_status_thread = RobotStatusThread(
146
- self.robot, self.signal_thread_quitting, self.shared_state
154
+ robot=self.robot,
155
+ signal_thread_quitting=self.signal_thread_quitting,
156
+ shared_state=self.shared_state,
157
+ state_machine_events=self.state_machine_events,
158
+ robot_service_events=self.robot_service_events,
147
159
  )
148
160
  self.robot_status_thread.start()
149
161
 
162
+ self.robot_battery_thread = RobotBatteryThread(
163
+ self.robot, self.signal_thread_quitting, self.shared_state
164
+ )
165
+ self.robot_battery_thread.start()
166
+
150
167
  while not self.signal_thread_quitting.wait(0):
151
168
  self._start_mission_event_handler(self.state_machine_events.start_mission)
152
169
 
@@ -8,7 +8,7 @@ from robot_interface.models.exceptions.robot_exceptions import RobotException
8
8
  from robot_interface.robot_interface import RobotInterface
9
9
 
10
10
 
11
- class RobotStatusThread(Thread):
11
+ class RobotBatteryThread(Thread):
12
12
  def __init__(
13
13
  self,
14
14
  robot: RobotInterface,
@@ -19,20 +19,24 @@ class RobotStatusThread(Thread):
19
19
  self.shared_state: SharedState = shared_state
20
20
  self.robot: RobotInterface = robot
21
21
  self.signal_thread_quitting: Event = signal_thread_quitting
22
- self.last_robot_status_poll_time: float = (
23
- time.time() - settings.ROBOT_API_STATUS_POLL_INTERVAL
24
- )
25
- Thread.__init__(self, name="Robot status thread")
22
+ self.last_robot_battery_poll_time: float = time.time()
23
+ self.force_battery_poll_next_iteration: bool = True
24
+ Thread.__init__(self, name="Robot battery thread")
26
25
 
27
26
  def stop(self) -> None:
28
27
  return
29
28
 
30
- def _is_ready_to_poll_for_status(self) -> bool:
31
- time_since_last_robot_status_poll = (
32
- time.time() - self.last_robot_status_poll_time
29
+ def _is_ready_to_poll_for_battery(self) -> bool:
30
+ if self.force_battery_poll_next_iteration:
31
+ self.force_battery_poll_next_iteration = False
32
+ return True
33
+
34
+ time_since_last_robot_battery_poll = (
35
+ time.time() - self.last_robot_battery_poll_time
33
36
  )
34
37
  return (
35
- time_since_last_robot_status_poll > settings.ROBOT_API_STATUS_POLL_INTERVAL
38
+ time_since_last_robot_battery_poll
39
+ > settings.ROBOT_API_BATTERY_POLL_INTERVAL
36
40
  )
37
41
 
38
42
  def run(self):
@@ -42,17 +46,15 @@ class RobotStatusThread(Thread):
42
46
  thread_check_interval = settings.THREAD_CHECK_INTERVAL
43
47
 
44
48
  while not self.signal_thread_quitting.wait(thread_check_interval):
45
- if not self._is_ready_to_poll_for_status():
49
+ if not self._is_ready_to_poll_for_battery():
46
50
  continue
47
51
  try:
48
- self.last_robot_status_poll_time = time.time()
52
+ self.last_robot_battery_poll_time = time.time()
49
53
 
50
- robot_status = self.robot.robot_status()
51
54
  robot_battery_level = self.robot.get_battery_level()
52
55
 
53
- self.shared_state.robot_status.update(robot_status)
54
56
  self.shared_state.robot_battery_level.update(robot_battery_level)
55
57
  except RobotException as e:
56
- self.logger.error(f"Failed to retrieve robot status: {e}")
58
+ self.logger.error(f"Failed to retrieve robot battery level: {e}")
57
59
  continue
58
- self.logger.info("Exiting robot status thread")
60
+ self.logger.info("Exiting robot battery thread")
@@ -0,0 +1,71 @@
1
+ import logging
2
+ import time
3
+ from threading import Event, Thread
4
+
5
+ from isar.config.settings import settings
6
+ from isar.models.events import RobotServiceEvents, SharedState, StateMachineEvents
7
+ from robot_interface.models.exceptions.robot_exceptions import RobotException
8
+ from robot_interface.robot_interface import RobotInterface
9
+
10
+
11
+ class RobotStatusThread(Thread):
12
+ def __init__(
13
+ self,
14
+ robot: RobotInterface,
15
+ signal_thread_quitting: Event,
16
+ shared_state: SharedState,
17
+ robot_service_events: RobotServiceEvents,
18
+ state_machine_events: StateMachineEvents,
19
+ ):
20
+ self.logger = logging.getLogger("robot")
21
+ self.shared_state: SharedState = shared_state
22
+ self.robot_service_events: RobotServiceEvents = robot_service_events
23
+ self.state_machine_events: StateMachineEvents = state_machine_events
24
+ self.robot: RobotInterface = robot
25
+ self.signal_thread_quitting: Event = signal_thread_quitting
26
+ self.robot_status_poll_interval: float = settings.ROBOT_API_STATUS_POLL_INTERVAL
27
+ self.last_robot_status_poll_time: float = time.time()
28
+ self.force_status_poll_next_iteration: bool = True
29
+ Thread.__init__(self, name="Robot status thread")
30
+
31
+ def stop(self) -> None:
32
+ return
33
+
34
+ def _is_ready_to_poll_for_status(self) -> bool:
35
+ if self.force_status_poll_next_iteration:
36
+ self.force_status_poll_next_iteration = False
37
+ return True
38
+
39
+ time_since_last_robot_status_poll = (
40
+ time.time() - self.last_robot_status_poll_time
41
+ )
42
+ return time_since_last_robot_status_poll > self.robot_status_poll_interval
43
+
44
+ def run(self):
45
+ if self.signal_thread_quitting.is_set():
46
+ return
47
+
48
+ thread_check_interval = settings.THREAD_CHECK_INTERVAL
49
+
50
+ while not self.signal_thread_quitting.wait(thread_check_interval):
51
+ if self.state_machine_events.clear_robot_status.consume_event() is not None:
52
+ self.shared_state.robot_status.clear_event()
53
+ self.robot_service_events.robot_status_changed.clear_event()
54
+ self.robot_service_events.robot_status_cleared.trigger_event(True)
55
+ self.force_status_poll_next_iteration = True
56
+
57
+ if not self._is_ready_to_poll_for_status():
58
+ continue
59
+
60
+ try:
61
+ self.last_robot_status_poll_time = time.time()
62
+
63
+ robot_status = self.robot.robot_status()
64
+
65
+ if robot_status is not self.shared_state.robot_status.check():
66
+ self.shared_state.robot_status.update(robot_status)
67
+ self.robot_service_events.robot_status_changed.trigger_event(True)
68
+ except RobotException as e:
69
+ self.logger.error(f"Failed to retrieve robot status: {e}")
70
+ continue
71
+ self.logger.info("Exiting robot status thread")
@@ -94,6 +94,12 @@ class SchedulingUtilities:
94
94
  status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
95
95
  detail="Could not plan mission",
96
96
  )
97
+ except Exception as e:
98
+ self.logger.error(e)
99
+ raise HTTPException(
100
+ status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
101
+ detail="Could not return mission",
102
+ )
97
103
 
98
104
  def verify_robot_capable_of_mission(
99
105
  self, mission: Mission, robot_capabilities: List[str]
@@ -171,6 +177,10 @@ class SchedulingUtilities:
171
177
  ------
172
178
  HTTTPException 408 Request timeout
173
179
  If there is a timeout while communicating with the state machine
180
+ HTTPException 409 Conflict
181
+ If the state machine is not ready to receive a mission
182
+ HTTPException 500 Internal Server Error
183
+ If there is an unexpected error while sending the mission to the state machine
174
184
  """
175
185
  try:
176
186
  mission_start_response = self._send_command(
@@ -195,6 +205,14 @@ class SchedulingUtilities:
195
205
  )
196
206
  self.logger.warning(error_message)
197
207
  raise HTTPException(status_code=HTTPStatus.CONFLICT, detail=error_message)
208
+ except Exception as e:
209
+ error_message = (
210
+ f"Unexpected error while sending mission to state machine: {e}"
211
+ )
212
+ self.logger.error(error_message)
213
+ raise HTTPException(
214
+ status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=error_message
215
+ )
198
216
  self.logger.info("OK - Mission started in ISAR")
199
217
 
200
218
  def return_home(
@@ -206,6 +224,10 @@ class SchedulingUtilities:
206
224
  ------
207
225
  HTTTPException 408 Request timeout
208
226
  If there is a timeout while communicating with the state machine
227
+ HTTPException 409 Conflict
228
+ If the state machine is not ready to receive a return home mission
229
+ HTTPException 500 Internal Server Error
230
+ If there is an unexpected error while sending the return home command
209
231
  """
210
232
  try:
211
233
  self._send_command(
@@ -220,6 +242,12 @@ class SchedulingUtilities:
220
242
  error_message = "State machine has entered a state which cannot start a return home mission"
221
243
  self.logger.warning(error_message)
222
244
  raise HTTPException(status_code=HTTPStatus.CONFLICT, detail=error_message)
245
+ except Exception as e:
246
+ error_message = f"Unexpected error while sending return home command: {e}"
247
+ self.logger.error(error_message)
248
+ raise HTTPException(
249
+ status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=error_message
250
+ )
223
251
  self.logger.info("OK - Return home mission started in ISAR")
224
252
 
225
253
  def pause_mission(self) -> ControlMissionResponse:
@@ -229,6 +257,8 @@ class SchedulingUtilities:
229
257
  ------
230
258
  HTTTPException 408 Request timeout
231
259
  If there is a timeout while communicating with the state machine
260
+ HTTPException 409 Conflict
261
+ If the state machine is not in a state which can pause a mission
232
262
  """
233
263
  try:
234
264
  response = self._send_command(True, self.api_events.pause_mission)
@@ -244,6 +274,12 @@ class SchedulingUtilities:
244
274
  )
245
275
  self.logger.warning(error_message)
246
276
  raise HTTPException(status_code=HTTPStatus.CONFLICT, detail=error_message)
277
+ except Exception as e:
278
+ error_message = f"Unexpected error while pausing mission: {e}"
279
+ self.logger.error(error_message)
280
+ raise HTTPException(
281
+ status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=error_message
282
+ )
247
283
 
248
284
  def resume_mission(self) -> ControlMissionResponse:
249
285
  """Resume mission
@@ -252,6 +288,10 @@ class SchedulingUtilities:
252
288
  ------
253
289
  HTTTPException 408 Request timeout
254
290
  If there is a timeout while communicating with the state machine
291
+ HTTPException 409 Conflict
292
+ If the state machine is not in a state which can resume a mission
293
+ HTTPException 500 Internal Server Error
294
+ If there is an unexpected error while resuming the mission
255
295
  """
256
296
  try:
257
297
  response = self._send_command(True, self.api_events.resume_mission)
@@ -267,6 +307,12 @@ class SchedulingUtilities:
267
307
  raise HTTPException(
268
308
  status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=error_message
269
309
  )
310
+ except Exception as e:
311
+ error_message = f"Unexpected error while resuming mission: {e}"
312
+ self.logger.error(error_message)
313
+ raise HTTPException(
314
+ status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=error_message
315
+ )
270
316
 
271
317
  def stop_mission(self, mission_id: str = "") -> ControlMissionResponse:
272
318
  """Stop mission
@@ -279,6 +325,10 @@ class SchedulingUtilities:
279
325
  The request was understood, but attempting to stop the mission failed
280
326
  HTTPException 408 Request timeout
281
327
  If there is a timeout while communicating with the state machine
328
+ HTTPException 409 Conflict
329
+ If the state machine is not in a state which can stop a mission
330
+ HTTPException 500 Internal Server Error
331
+ If there is an unexpected error while stopping the mission
282
332
  """
283
333
  try:
284
334
  stop_mission_response: ControlMissionResponse = self._send_command(
@@ -293,7 +343,7 @@ class SchedulingUtilities:
293
343
  )
294
344
 
295
345
  if stop_mission_response.mission_status != MissionStatus.Cancelled.value:
296
- error_message = "Failed to stop mission"
346
+ error_message = f"Failed to stop mission, mission status is {stop_mission_response.mission_status}"
297
347
  self.logger.error(error_message)
298
348
  raise HTTPException(
299
349
  status_code=HTTPStatus.CONFLICT, detail=error_message
@@ -308,6 +358,14 @@ class SchedulingUtilities:
308
358
  )
309
359
  self.logger.warning(error_message)
310
360
  raise HTTPException(status_code=HTTPStatus.CONFLICT, detail=error_message)
361
+ except HTTPException as e:
362
+ raise e
363
+ except Exception as e:
364
+ error_message = f"Unexpected error while stopping mission: {e}"
365
+ self.logger.error(error_message)
366
+ raise HTTPException(
367
+ status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=error_message
368
+ )
311
369
  self.logger.info("OK - Mission successfully stopped")
312
370
  return stop_mission_response
313
371
 
@@ -316,6 +374,10 @@ class SchedulingUtilities:
316
374
 
317
375
  Raises
318
376
  ------
377
+ HTTPException 409 Conflict
378
+ If the state machine is not in intervention needed state
379
+ HTTPException 408 Request timeout
380
+ If there is a timeout while communicating with the state machine
319
381
  HTTPException 500 Internal Server Error
320
382
  If the intervention needed state could not be released
321
383
  """
@@ -332,12 +394,22 @@ class SchedulingUtilities:
332
394
  error_message = "Cannot release intervention needed as it is not in intervention needed state"
333
395
  self.logger.warning(error_message)
334
396
  raise HTTPException(status_code=HTTPStatus.CONFLICT, detail=error_message)
397
+ except Exception as e:
398
+ error_message = (
399
+ f"Unexpected error while releasing intervention needed state: {e}"
400
+ )
401
+ self.logger.error(error_message)
402
+ raise HTTPException(
403
+ status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=error_message
404
+ )
335
405
 
336
406
  def lock_down_robot(self) -> None:
337
407
  """Lock down robot
338
408
 
339
409
  Raises
340
410
  ------
411
+ HTTPException 409 Conflict
412
+ If the state machine is not in a state which can be locked down
341
413
  HTTPException 500 Internal Server Error
342
414
  If the robot could not be locked down
343
415
  """
@@ -352,12 +424,20 @@ class SchedulingUtilities:
352
424
  error_message = "Cannot send robot to lockdown as it is already in lockdown"
353
425
  self.logger.warning(error_message)
354
426
  raise HTTPException(status_code=HTTPStatus.CONFLICT, detail=error_message)
427
+ except Exception as e:
428
+ error_message = f"Unexpected error while locking down robot: {e}"
429
+ self.logger.error(error_message)
430
+ raise HTTPException(
431
+ status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=error_message
432
+ )
355
433
 
356
434
  def release_robot_lockdown(self) -> None:
357
435
  """Release robot from lockdown
358
436
 
359
437
  Raises
360
438
  ------
439
+ HTTPException 409 Conflict
440
+ If the state machine is not in lockdown
361
441
  HTTPException 500 Internal Server Error
362
442
  If the robot could not be released from lockdown
363
443
  """
@@ -376,6 +456,12 @@ class SchedulingUtilities:
376
456
  )
377
457
  self.logger.warning(error_message)
378
458
  raise HTTPException(status_code=HTTPStatus.CONFLICT, detail=error_message)
459
+ except Exception as e:
460
+ error_message = f"Unexpected error while releasing robot from lockdown: {e}"
461
+ self.logger.error(error_message)
462
+ raise HTTPException(
463
+ status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=error_message
464
+ )
379
465
 
380
466
  def _send_command(self, input: T1, api_event: APIEvent[T1, T2]) -> T2:
381
467
  if api_event.request.has_event():
@@ -15,6 +15,7 @@ from isar.mission_planner.task_selector_interface import (
15
15
  TaskSelectorStop,
16
16
  )
17
17
  from isar.models.events import Events, SharedState
18
+ from isar.models.status import IsarStatus
18
19
  from isar.services.service_connections.mqtt.mqtt_client import props_expiry
19
20
  from isar.state_machine.states.await_next_mission import AwaitNextMission
20
21
  from isar.state_machine.states.blocked_protective_stop import BlockedProtectiveStop
@@ -45,15 +46,15 @@ from robot_interface.models.exceptions.robot_exceptions import (
45
46
  )
46
47
  from robot_interface.models.inspection.inspection import Inspection
47
48
  from robot_interface.models.mission.mission import Mission
48
- from robot_interface.models.mission.status import RobotStatus, TaskStatus
49
+ from robot_interface.models.mission.status import TaskStatus
49
50
  from robot_interface.models.mission.task import TASKS, InspectionTask, Task
50
51
  from robot_interface.robot_interface import RobotInterface
51
52
  from robot_interface.telemetry.mqtt_client import MqttClientInterface
52
53
  from robot_interface.telemetry.payloads import (
53
54
  InterventionNeededPayload,
55
+ IsarStatusPayload,
54
56
  MissionAbortedPayload,
55
57
  MissionPayload,
56
- RobotStatusPayload,
57
58
  TaskPayload,
58
59
  )
59
60
  from robot_interface.utilities.json_service import EnhancedJSONEncoder
@@ -213,6 +214,9 @@ class StateMachine(object):
213
214
  self.send_task_status()
214
215
 
215
216
  def battery_level_is_above_mission_start_threshold(self):
217
+ if not self.shared_state.robot_battery_level.check():
218
+ self.logger.warning("Battery level is None")
219
+ return False
216
220
  return (
217
221
  not self.shared_state.robot_battery_level.check()
218
222
  < settings.ROBOT_MISSION_BATTERY_START_THRESHOLD
@@ -367,7 +371,7 @@ class StateMachine(object):
367
371
  if not self.mqtt_publisher:
368
372
  return
369
373
 
370
- payload: RobotStatusPayload = RobotStatusPayload(
374
+ payload: IsarStatusPayload = IsarStatusPayload(
371
375
  isar_id=settings.ISAR_ID,
372
376
  robot_name=settings.ROBOT_NAME,
373
377
  status=self._current_status(),
@@ -381,31 +385,31 @@ class StateMachine(object):
381
385
  retain=True,
382
386
  )
383
387
 
384
- def _current_status(self) -> RobotStatus:
388
+ def _current_status(self) -> IsarStatus:
385
389
  if self.current_state == States.AwaitNextMission:
386
- return RobotStatus.Available
390
+ return IsarStatus.Available
387
391
  elif self.current_state == States.ReturnHomePaused:
388
- return RobotStatus.ReturnHomePaused
392
+ return IsarStatus.ReturnHomePaused
389
393
  elif self.current_state == States.Paused:
390
- return RobotStatus.Paused
394
+ return IsarStatus.Paused
391
395
  elif self.current_state == States.Home:
392
- return RobotStatus.Home
396
+ return IsarStatus.Home
393
397
  elif self.current_state == States.ReturningHome:
394
- return RobotStatus.ReturningHome
398
+ return IsarStatus.ReturningHome
395
399
  elif self.current_state == States.Offline:
396
- return RobotStatus.Offline
400
+ return IsarStatus.Offline
397
401
  elif self.current_state == States.BlockedProtectiveStop:
398
- return RobotStatus.BlockedProtectiveStop
402
+ return IsarStatus.BlockedProtectiveStop
399
403
  elif self.current_state == States.InterventionNeeded:
400
- return RobotStatus.InterventionNeeded
404
+ return IsarStatus.InterventionNeeded
401
405
  elif self.current_state == States.Recharging:
402
- return RobotStatus.Recharging
406
+ return IsarStatus.Recharging
403
407
  elif self.current_state == States.Lockdown:
404
- return RobotStatus.Lockdown
408
+ return IsarStatus.Lockdown
405
409
  elif self.current_state == States.GoingToLockdown:
406
- return RobotStatus.GoingToLockdown
410
+ return IsarStatus.GoingToLockdown
407
411
  else:
408
- return RobotStatus.Busy
412
+ return IsarStatus.Busy
409
413
 
410
414
  def _log_state_transition(self, next_state) -> None:
411
415
  """Logs all state transitions that are not self-transitions."""
@@ -1,7 +1,7 @@
1
1
  from typing import TYPE_CHECKING, List
2
2
 
3
3
  from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
4
- from isar.models.events import Event
4
+ from isar.state_machine.utils.common_event_handlers import robot_status_event_handler
5
5
  from robot_interface.models.mission.status import RobotStatus
6
6
 
7
7
  if TYPE_CHECKING:
@@ -11,19 +11,19 @@ if TYPE_CHECKING:
11
11
  class BlockedProtectiveStop(EventHandlerBase):
12
12
 
13
13
  def __init__(self, state_machine: "StateMachine"):
14
+ events = state_machine.events
14
15
  shared_state = state_machine.shared_state
15
16
 
16
- def _robot_status_event_handler(event: Event[RobotStatus]):
17
- robot_status: RobotStatus = event.check()
18
- if robot_status != RobotStatus.BlockedProtectiveStop:
19
- return state_machine.robot_status_changed # type: ignore
20
- return None
21
-
22
17
  event_handlers: List[EventHandlerMapping] = [
23
18
  EventHandlerMapping(
24
19
  name="robot_status_event",
25
- event=shared_state.robot_status,
26
- handler=_robot_status_event_handler,
20
+ event=events.robot_service_events.robot_status_changed,
21
+ handler=lambda event: robot_status_event_handler(
22
+ state_machine=state_machine,
23
+ expected_status=RobotStatus.BlockedProtectiveStop,
24
+ status_changed_event=event,
25
+ status_event=shared_state.robot_status,
26
+ ),
27
27
  ),
28
28
  ]
29
29
  super().__init__(
@@ -20,17 +20,6 @@ class Home(EventHandlerBase):
20
20
  events = state_machine.events
21
21
  shared_state = state_machine.shared_state
22
22
 
23
- def _robot_status_event_handler(
24
- event: Event[RobotStatus],
25
- ) -> Optional[Callable]:
26
- robot_status: RobotStatus = event.check()
27
- if not (
28
- robot_status == RobotStatus.Available
29
- or robot_status == RobotStatus.Home
30
- ):
31
- return state_machine.robot_status_changed # type: ignore
32
- return None
33
-
34
23
  def _send_to_lockdown_event_handler(event: Event[bool]):
35
24
  should_send_robot_home: bool = event.consume_event()
36
25
  if should_send_robot_home:
@@ -40,6 +29,21 @@ class Home(EventHandlerBase):
40
29
  return state_machine.reached_lockdown # type: ignore
41
30
  return None
42
31
 
32
+ def _robot_status_event_handler(
33
+ state_machine: "StateMachine",
34
+ status_changed_event: Event[bool],
35
+ status_event: Event[RobotStatus],
36
+ ) -> Optional[Callable]:
37
+ if not status_changed_event.consume_event():
38
+ return None
39
+ robot_status: Optional[RobotStatus] = status_event.check()
40
+ if not (
41
+ robot_status == RobotStatus.Available
42
+ or robot_status == RobotStatus.Home
43
+ ):
44
+ return state_machine.robot_status_changed # type: ignore
45
+ return None
46
+
43
47
  event_handlers: List[EventHandlerMapping] = [
44
48
  EventHandlerMapping(
45
49
  name="start_mission_event",
@@ -60,8 +64,12 @@ class Home(EventHandlerBase):
60
64
  ),
61
65
  EventHandlerMapping(
62
66
  name="robot_status_event",
63
- event=shared_state.robot_status,
64
- handler=_robot_status_event_handler,
67
+ event=events.robot_service_events.robot_status_changed,
68
+ handler=lambda event: _robot_status_event_handler(
69
+ state_machine=state_machine,
70
+ status_changed_event=event,
71
+ status_event=shared_state.robot_status,
72
+ ),
65
73
  ),
66
74
  EventHandlerMapping(
67
75
  name="send_to_lockdown_event",