isar 1.34.3__tar.gz → 1.34.4__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 (225) hide show
  1. isar-1.34.4/.github/workflows/execute_stale_labeler.yml +17 -0
  2. isar-1.34.4/.github/workflows/synchronize_labels.yml +13 -0
  3. {isar-1.34.3 → isar-1.34.4}/PKG-INFO +1 -1
  4. {isar-1.34.3 → isar-1.34.4}/src/isar/models/status.py +1 -0
  5. {isar-1.34.3 → isar-1.34.4}/src/isar/robot/robot.py +46 -10
  6. {isar-1.34.3 → isar-1.34.4}/src/isar/robot/robot_monitor_mission.py +6 -1
  7. {isar-1.34.3 → isar-1.34.4}/src/isar/robot/robot_pause_mission.py +8 -6
  8. {isar-1.34.3 → isar-1.34.4}/src/isar/robot/robot_start_mission.py +12 -24
  9. {isar-1.34.3 → isar-1.34.4}/src/isar/robot/robot_stop_mission.py +3 -0
  10. {isar-1.34.3 → isar-1.34.4}/src/isar/robot/robot_upload_inspection.py +0 -5
  11. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/state_machine.py +8 -0
  12. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/states/await_next_mission.py +18 -0
  13. isar-1.34.4/src/isar/state_machine/states/going_to_recharging.py +81 -0
  14. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/states/home.py +18 -0
  15. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/states/monitor.py +5 -5
  16. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/states/paused.py +4 -1
  17. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/states/return_home_paused.py +4 -1
  18. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/states/returning_home.py +20 -4
  19. isar-1.34.4/src/isar/state_machine/states/stopping_go_to_recharge.py +51 -0
  20. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/states_enum.py +2 -0
  21. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/transitions/functions/resume.py +7 -0
  22. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/transitions/mission.py +10 -1
  23. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/transitions/return_home.py +28 -3
  24. {isar-1.34.3 → isar-1.34.4}/src/isar.egg-info/PKG-INFO +1 -1
  25. {isar-1.34.3 → isar-1.34.4}/src/isar.egg-info/SOURCES.txt +4 -0
  26. {isar-1.34.3 → isar-1.34.4}/src/robot_interface/models/exceptions/robot_exceptions.py +13 -0
  27. {isar-1.34.3 → isar-1.34.4}/tests/isar/state_machine/test_state_machine.py +139 -16
  28. {isar-1.34.3 → isar-1.34.4}/.dockerignore +0 -0
  29. {isar-1.34.3 → isar-1.34.4}/.env.test +0 -0
  30. {isar-1.34.3 → isar-1.34.4}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  31. {isar-1.34.3 → isar-1.34.4}/.github/ISSUE_TEMPLATE/feature.md +0 -0
  32. {isar-1.34.3 → isar-1.34.4}/.github/ISSUE_TEMPLATE/improvement.md +0 -0
  33. {isar-1.34.3 → isar-1.34.4}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  34. {isar-1.34.3 → isar-1.34.4}/.github/release.yml +0 -0
  35. {isar-1.34.3 → isar-1.34.4}/.github/workflows/compile_requirements.yml +0 -0
  36. {isar-1.34.3 → isar-1.34.4}/.github/workflows/project_automations.yml +0 -0
  37. {isar-1.34.3 → isar-1.34.4}/.github/workflows/pythonpackage.yml +0 -0
  38. {isar-1.34.3 → isar-1.34.4}/.github/workflows/pythonpublish.yml +0 -0
  39. {isar-1.34.3 → isar-1.34.4}/.github/workflows/stale.yml +0 -0
  40. {isar-1.34.3 → isar-1.34.4}/.github/workflows/trivy-config.yml +0 -0
  41. {isar-1.34.3 → isar-1.34.4}/.gitignore +0 -0
  42. {isar-1.34.3 → isar-1.34.4}/.pre-commit-config.yaml +0 -0
  43. {isar-1.34.3 → isar-1.34.4}/LICENSE +0 -0
  44. {isar-1.34.3 → isar-1.34.4}/README.md +0 -0
  45. {isar-1.34.3 → isar-1.34.4}/SECURITY.md +0 -0
  46. {isar-1.34.3 → isar-1.34.4}/docs/Makefile +0 -0
  47. {isar-1.34.3 → isar-1.34.4}/docs/full_state_machine_diagram.png +0 -0
  48. {isar-1.34.3 → isar-1.34.4}/docs/make.bat +0 -0
  49. {isar-1.34.3 → isar-1.34.4}/docs/mission_state_machine_diagram.png +0 -0
  50. {isar-1.34.3 → isar-1.34.4}/docs/robot_status_state_machine_diagram.png +0 -0
  51. {isar-1.34.3 → isar-1.34.4}/docs/rst_processing.py +0 -0
  52. {isar-1.34.3 → isar-1.34.4}/docs/source/conf.py +0 -0
  53. {isar-1.34.3 → isar-1.34.4}/docs/source/index.rst +0 -0
  54. {isar-1.34.3 → isar-1.34.4}/docs/source/readme_link.md +0 -0
  55. {isar-1.34.3 → isar-1.34.4}/docs/update_state_diagram.py +0 -0
  56. {isar-1.34.3 → isar-1.34.4}/main.py +0 -0
  57. {isar-1.34.3 → isar-1.34.4}/pyproject.toml +0 -0
  58. {isar-1.34.3 → isar-1.34.4}/radixconfig.yml +0 -0
  59. {isar-1.34.3 → isar-1.34.4}/requirements.txt +0 -0
  60. {isar-1.34.3 → isar-1.34.4}/setup.cfg +0 -0
  61. {isar-1.34.3 → isar-1.34.4}/src/isar/__init__.py +0 -0
  62. {isar-1.34.3 → isar-1.34.4}/src/isar/apis/__init__.py +0 -0
  63. {isar-1.34.3 → isar-1.34.4}/src/isar/apis/api.py +0 -0
  64. {isar-1.34.3 → isar-1.34.4}/src/isar/apis/models/__init__.py +0 -0
  65. {isar-1.34.3 → isar-1.34.4}/src/isar/apis/models/models.py +0 -0
  66. {isar-1.34.3 → isar-1.34.4}/src/isar/apis/models/start_mission_definition.py +0 -0
  67. {isar-1.34.3 → isar-1.34.4}/src/isar/apis/robot_control/robot_controller.py +0 -0
  68. {isar-1.34.3 → isar-1.34.4}/src/isar/apis/schedule/__init__.py +0 -0
  69. {isar-1.34.3 → isar-1.34.4}/src/isar/apis/schedule/scheduling_controller.py +0 -0
  70. {isar-1.34.3 → isar-1.34.4}/src/isar/apis/security/__init__.py +0 -0
  71. {isar-1.34.3 → isar-1.34.4}/src/isar/apis/security/authentication.py +0 -0
  72. {isar-1.34.3 → isar-1.34.4}/src/isar/config/__init__.py +0 -0
  73. {isar-1.34.3 → isar-1.34.4}/src/isar/config/certs/ca-cert.pem +0 -0
  74. {isar-1.34.3 → isar-1.34.4}/src/isar/config/configuration_error.py +0 -0
  75. {isar-1.34.3 → isar-1.34.4}/src/isar/config/keyvault/__init__.py +0 -0
  76. {isar-1.34.3 → isar-1.34.4}/src/isar/config/keyvault/keyvault_error.py +0 -0
  77. {isar-1.34.3 → isar-1.34.4}/src/isar/config/keyvault/keyvault_service.py +0 -0
  78. {isar-1.34.3 → isar-1.34.4}/src/isar/config/log.py +0 -0
  79. {isar-1.34.3 → isar-1.34.4}/src/isar/config/logging.conf +0 -0
  80. {isar-1.34.3 → isar-1.34.4}/src/isar/config/maps/JSP1_intermediate_deck.json +0 -0
  81. {isar-1.34.3 → isar-1.34.4}/src/isar/config/maps/JSP1_weather_deck.json +0 -0
  82. {isar-1.34.3 → isar-1.34.4}/src/isar/config/maps/default_map.json +0 -0
  83. {isar-1.34.3 → isar-1.34.4}/src/isar/config/maps/klab_b.json +0 -0
  84. {isar-1.34.3 → isar-1.34.4}/src/isar/config/maps/klab_compressor.json +0 -0
  85. {isar-1.34.3 → isar-1.34.4}/src/isar/config/maps/klab_turtlebot.json +0 -0
  86. {isar-1.34.3 → isar-1.34.4}/src/isar/config/maps/turtleworld.json +0 -0
  87. {isar-1.34.3 → isar-1.34.4}/src/isar/config/open_telemetry.py +0 -0
  88. {isar-1.34.3 → isar-1.34.4}/src/isar/config/predefined_mission_definition/__init__.py +0 -0
  89. {isar-1.34.3 → isar-1.34.4}/src/isar/config/predefined_mission_definition/default_exr.json +0 -0
  90. {isar-1.34.3 → isar-1.34.4}/src/isar/config/predefined_mission_definition/default_mission.json +0 -0
  91. {isar-1.34.3 → isar-1.34.4}/src/isar/config/predefined_mission_definition/default_turtlebot.json +0 -0
  92. {isar-1.34.3 → isar-1.34.4}/src/isar/config/predefined_missions/__init__.py +0 -0
  93. {isar-1.34.3 → isar-1.34.4}/src/isar/config/predefined_missions/default.json +0 -0
  94. {isar-1.34.3 → isar-1.34.4}/src/isar/config/predefined_missions/default_turtlebot.json +0 -0
  95. {isar-1.34.3 → isar-1.34.4}/src/isar/config/settings.py +0 -0
  96. {isar-1.34.3 → isar-1.34.4}/src/isar/eventhandlers/eventhandler.py +0 -0
  97. {isar-1.34.3 → isar-1.34.4}/src/isar/mission_planner/__init__.py +0 -0
  98. {isar-1.34.3 → isar-1.34.4}/src/isar/mission_planner/local_planner.py +0 -0
  99. {isar-1.34.3 → isar-1.34.4}/src/isar/mission_planner/mission_planner_interface.py +0 -0
  100. {isar-1.34.3 → isar-1.34.4}/src/isar/models/__init__.py +0 -0
  101. {isar-1.34.3 → isar-1.34.4}/src/isar/models/events.py +0 -0
  102. {isar-1.34.3 → isar-1.34.4}/src/isar/modules.py +0 -0
  103. {isar-1.34.3 → isar-1.34.4}/src/isar/robot/robot_battery.py +0 -0
  104. {isar-1.34.3 → isar-1.34.4}/src/isar/robot/robot_status.py +0 -0
  105. {isar-1.34.3 → isar-1.34.4}/src/isar/script.py +0 -0
  106. {isar-1.34.3 → isar-1.34.4}/src/isar/services/__init__.py +0 -0
  107. {isar-1.34.3 → isar-1.34.4}/src/isar/services/auth/__init__.py +0 -0
  108. {isar-1.34.3 → isar-1.34.4}/src/isar/services/auth/azure_credentials.py +0 -0
  109. {isar-1.34.3 → isar-1.34.4}/src/isar/services/service_connections/__init__.py +0 -0
  110. {isar-1.34.3 → isar-1.34.4}/src/isar/services/service_connections/mqtt/__init__.py +0 -0
  111. {isar-1.34.3 → isar-1.34.4}/src/isar/services/service_connections/mqtt/mqtt_client.py +0 -0
  112. {isar-1.34.3 → isar-1.34.4}/src/isar/services/service_connections/mqtt/robot_heartbeat_publisher.py +0 -0
  113. {isar-1.34.3 → isar-1.34.4}/src/isar/services/service_connections/mqtt/robot_info_publisher.py +0 -0
  114. {isar-1.34.3 → isar-1.34.4}/src/isar/services/service_connections/request_handler.py +0 -0
  115. {isar-1.34.3 → isar-1.34.4}/src/isar/services/utilities/__init__.py +0 -0
  116. {isar-1.34.3 → isar-1.34.4}/src/isar/services/utilities/robot_utilities.py +0 -0
  117. {isar-1.34.3 → isar-1.34.4}/src/isar/services/utilities/scheduling_utilities.py +0 -0
  118. {isar-1.34.3 → isar-1.34.4}/src/isar/services/utilities/threaded_request.py +0 -0
  119. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/__init__.py +0 -0
  120. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/states/__init__.py +0 -0
  121. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/states/blocked_protective_stop.py +0 -0
  122. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/states/going_to_lockdown.py +0 -0
  123. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/states/intervention_needed.py +0 -0
  124. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/states/lockdown.py +0 -0
  125. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/states/offline.py +0 -0
  126. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/states/pausing.py +0 -0
  127. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/states/pausing_return_home.py +0 -0
  128. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/states/recharging.py +0 -0
  129. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/states/stopping.py +0 -0
  130. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/states/stopping_go_to_lockdown.py +0 -0
  131. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/states/stopping_return_home.py +0 -0
  132. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/states/unknown_status.py +0 -0
  133. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/transitions/functions/fail_mission.py +0 -0
  134. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/transitions/functions/finish_mission.py +0 -0
  135. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/transitions/functions/pause.py +0 -0
  136. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/transitions/functions/return_home.py +0 -0
  137. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/transitions/functions/robot_status.py +0 -0
  138. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/transitions/functions/start_mission.py +0 -0
  139. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/transitions/functions/stop.py +0 -0
  140. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/transitions/functions/utils.py +0 -0
  141. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/transitions/robot_status.py +0 -0
  142. {isar-1.34.3 → isar-1.34.4}/src/isar/state_machine/utils/common_event_handlers.py +0 -0
  143. {isar-1.34.3 → isar-1.34.4}/src/isar/storage/__init__.py +0 -0
  144. {isar-1.34.3 → isar-1.34.4}/src/isar/storage/blob_storage.py +0 -0
  145. {isar-1.34.3 → isar-1.34.4}/src/isar/storage/local_storage.py +0 -0
  146. {isar-1.34.3 → isar-1.34.4}/src/isar/storage/storage_interface.py +0 -0
  147. {isar-1.34.3 → isar-1.34.4}/src/isar/storage/uploader.py +0 -0
  148. {isar-1.34.3 → isar-1.34.4}/src/isar/storage/utilities.py +0 -0
  149. {isar-1.34.3 → isar-1.34.4}/src/isar.egg-info/dependency_links.txt +0 -0
  150. {isar-1.34.3 → isar-1.34.4}/src/isar.egg-info/entry_points.txt +0 -0
  151. {isar-1.34.3 → isar-1.34.4}/src/isar.egg-info/requires.txt +0 -0
  152. {isar-1.34.3 → isar-1.34.4}/src/isar.egg-info/top_level.txt +0 -0
  153. {isar-1.34.3 → isar-1.34.4}/src/robot_interface/__init__.py +0 -0
  154. {isar-1.34.3 → isar-1.34.4}/src/robot_interface/models/__init__.py +0 -0
  155. {isar-1.34.3 → isar-1.34.4}/src/robot_interface/models/exceptions/__init__.py +0 -0
  156. {isar-1.34.3 → isar-1.34.4}/src/robot_interface/models/initialize/__init__.py +0 -0
  157. {isar-1.34.3 → isar-1.34.4}/src/robot_interface/models/inspection/__init__.py +0 -0
  158. {isar-1.34.3 → isar-1.34.4}/src/robot_interface/models/inspection/inspection.py +0 -0
  159. {isar-1.34.3 → isar-1.34.4}/src/robot_interface/models/mission/__init__.py +0 -0
  160. {isar-1.34.3 → isar-1.34.4}/src/robot_interface/models/mission/mission.py +0 -0
  161. {isar-1.34.3 → isar-1.34.4}/src/robot_interface/models/mission/status.py +0 -0
  162. {isar-1.34.3 → isar-1.34.4}/src/robot_interface/models/mission/task.py +0 -0
  163. {isar-1.34.3 → isar-1.34.4}/src/robot_interface/models/robots/__init__.py +0 -0
  164. {isar-1.34.3 → isar-1.34.4}/src/robot_interface/models/robots/battery_state.py +0 -0
  165. {isar-1.34.3 → isar-1.34.4}/src/robot_interface/models/robots/media.py +0 -0
  166. {isar-1.34.3 → isar-1.34.4}/src/robot_interface/models/robots/robot_model.py +0 -0
  167. {isar-1.34.3 → isar-1.34.4}/src/robot_interface/robot_interface.py +0 -0
  168. {isar-1.34.3 → isar-1.34.4}/src/robot_interface/telemetry/__init__.py +0 -0
  169. {isar-1.34.3 → isar-1.34.4}/src/robot_interface/telemetry/mqtt_client.py +0 -0
  170. {isar-1.34.3 → isar-1.34.4}/src/robot_interface/telemetry/payloads.py +0 -0
  171. {isar-1.34.3 → isar-1.34.4}/src/robot_interface/test_robot_interface.py +0 -0
  172. {isar-1.34.3 → isar-1.34.4}/src/robot_interface/utilities/__init__.py +0 -0
  173. {isar-1.34.3 → isar-1.34.4}/src/robot_interface/utilities/json_service.py +0 -0
  174. {isar-1.34.3 → isar-1.34.4}/src/robot_interface/utilities/uuid_string_factory.py +0 -0
  175. {isar-1.34.3 → isar-1.34.4}/tests/__init__.py +0 -0
  176. {isar-1.34.3 → isar-1.34.4}/tests/conftest.py +0 -0
  177. {isar-1.34.3 → isar-1.34.4}/tests/integration/__init__.py +0 -0
  178. {isar-1.34.3 → isar-1.34.4}/tests/integration/turtlebot/__init__.py +0 -0
  179. {isar-1.34.3 → isar-1.34.4}/tests/integration/turtlebot/config/__init__.py +0 -0
  180. {isar-1.34.3 → isar-1.34.4}/tests/integration/turtlebot/config/maps/__init__.py +0 -0
  181. {isar-1.34.3 → isar-1.34.4}/tests/integration/turtlebot/config/maps/turtleworld.json +0 -0
  182. {isar-1.34.3 → isar-1.34.4}/tests/integration/turtlebot/config/missions/__init__.py +0 -0
  183. {isar-1.34.3 → isar-1.34.4}/tests/integration/turtlebot/config/missions/default.json +0 -0
  184. {isar-1.34.3 → isar-1.34.4}/tests/integration/turtlebot/test_successful_mission.py +0 -0
  185. {isar-1.34.3 → isar-1.34.4}/tests/isar/__init__.py +0 -0
  186. {isar-1.34.3 → isar-1.34.4}/tests/isar/apis/__init__.py +0 -0
  187. {isar-1.34.3 → isar-1.34.4}/tests/isar/apis/models/__init__.py +0 -0
  188. {isar-1.34.3 → isar-1.34.4}/tests/isar/apis/models/example_mission_definition.json +0 -0
  189. {isar-1.34.3 → isar-1.34.4}/tests/isar/apis/models/test_start_mission_definition.py +0 -0
  190. {isar-1.34.3 → isar-1.34.4}/tests/isar/apis/scheduler/__init__.py +0 -0
  191. {isar-1.34.3 → isar-1.34.4}/tests/isar/apis/scheduler/test_scheduler_router.py +0 -0
  192. {isar-1.34.3 → isar-1.34.4}/tests/isar/apis/security/__init__.py +0 -0
  193. {isar-1.34.3 → isar-1.34.4}/tests/isar/apis/security/test_authentication.py +0 -0
  194. {isar-1.34.3 → isar-1.34.4}/tests/isar/mission/__init__.py +0 -0
  195. {isar-1.34.3 → isar-1.34.4}/tests/isar/mission/test_mission.py +0 -0
  196. {isar-1.34.3 → isar-1.34.4}/tests/isar/models/__init__.py +0 -0
  197. {isar-1.34.3 → isar-1.34.4}/tests/isar/models/communication/__init__.py +0 -0
  198. {isar-1.34.3 → isar-1.34.4}/tests/isar/models/communication/test_events.py +0 -0
  199. {isar-1.34.3 → isar-1.34.4}/tests/isar/services/__init__.py +0 -0
  200. {isar-1.34.3 → isar-1.34.4}/tests/isar/services/readers/__init__.py +0 -0
  201. {isar-1.34.3 → isar-1.34.4}/tests/isar/services/readers/test_mission_reader.py +0 -0
  202. {isar-1.34.3 → isar-1.34.4}/tests/isar/services/service_connections/__init__.py +0 -0
  203. {isar-1.34.3 → isar-1.34.4}/tests/isar/services/service_connections/echo/__init__.py +0 -0
  204. {isar-1.34.3 → isar-1.34.4}/tests/isar/services/service_connections/test_base_request_handler.py +0 -0
  205. {isar-1.34.3 → isar-1.34.4}/tests/isar/services/utilities/__init__.py +0 -0
  206. {isar-1.34.3 → isar-1.34.4}/tests/isar/services/utilities/test_queue_utilities.py +0 -0
  207. {isar-1.34.3 → isar-1.34.4}/tests/isar/services/utilities/test_scheduling_utilities.py +0 -0
  208. {isar-1.34.3 → isar-1.34.4}/tests/isar/state_machine/__init__.py +0 -0
  209. {isar-1.34.3 → isar-1.34.4}/tests/isar/storage/test_blob_storage.py +0 -0
  210. {isar-1.34.3 → isar-1.34.4}/tests/isar/storage/test_uploader.py +0 -0
  211. {isar-1.34.3 → isar-1.34.4}/tests/test_data/test_map_config/test_map_config.json +0 -0
  212. {isar-1.34.3 → isar-1.34.4}/tests/test_data/test_mission_not_working.json +0 -0
  213. {isar-1.34.3 → isar-1.34.4}/tests/test_data/test_mission_working.json +0 -0
  214. {isar-1.34.3 → isar-1.34.4}/tests/test_data/test_mission_working_no_tasks.json +0 -0
  215. {isar-1.34.3 → isar-1.34.4}/tests/test_data/test_thermal_image_mission.json +0 -0
  216. {isar-1.34.3 → isar-1.34.4}/tests/test_double/__init__.py +0 -0
  217. {isar-1.34.3 → isar-1.34.4}/tests/test_double/blob_storage.py +0 -0
  218. {isar-1.34.3 → isar-1.34.4}/tests/test_double/mission_definition.py +0 -0
  219. {isar-1.34.3 → isar-1.34.4}/tests/test_double/mqtt_client.py +0 -0
  220. {isar-1.34.3 → isar-1.34.4}/tests/test_double/pose.py +0 -0
  221. {isar-1.34.3 → isar-1.34.4}/tests/test_double/request.py +0 -0
  222. {isar-1.34.3 → isar-1.34.4}/tests/test_double/robot_interface.py +0 -0
  223. {isar-1.34.3 → isar-1.34.4}/tests/test_double/status.py +0 -0
  224. {isar-1.34.3 → isar-1.34.4}/tests/test_double/task.py +0 -0
  225. {isar-1.34.3 → isar-1.34.4}/tests/test_double/token.py +0 -0
@@ -0,0 +1,17 @@
1
+ name: Execute stale labeler
2
+ on:
3
+ workflow_dispatch:
4
+ schedule:
5
+ - cron: "35 6 * * *"
6
+
7
+ permissions:
8
+ contents: read
9
+ actions: write
10
+ issues: write
11
+ pull-requests: write
12
+
13
+ jobs:
14
+ labels:
15
+ uses: equinor/armada/.github/workflows/mark_issues_and_prs_as_stale.yml@main
16
+ secrets:
17
+ STALE_ISSUE_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,13 @@
1
+ name: Execute label synchronization
2
+ on:
3
+ workflow_dispatch:
4
+
5
+ permissions:
6
+ contents: read
7
+ issues: write
8
+
9
+ jobs:
10
+ labels:
11
+ uses: equinor/armada/.github/workflows/synchronize_labels.yml@main
12
+ secrets:
13
+ LABEL_SYNC_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: isar
3
- Version: 1.34.3
3
+ Version: 1.34.4
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
@@ -14,3 +14,4 @@ class IsarStatus(Enum):
14
14
  Recharging = "recharging"
15
15
  Lockdown = "lockdown"
16
16
  GoingToLockdown = "goingtolockdown"
17
+ GoingToRecharging = "goingtorecharging"
@@ -70,6 +70,10 @@ class Robot(object):
70
70
  self.start_mission_thread.join()
71
71
  if self.stop_mission_thread is not None and self.stop_mission_thread.is_alive():
72
72
  self.stop_mission_thread.join()
73
+ for thread in self.upload_inspection_threads:
74
+ if thread.is_alive():
75
+ thread.join()
76
+ self.upload_inspection_threads = []
73
77
  self.robot_status_thread = None
74
78
  self.robot_battery_thread = None
75
79
  self.start_mission_thread = None
@@ -82,8 +86,14 @@ class Robot(object):
82
86
  ):
83
87
  self.start_mission_thread.join()
84
88
  mission = self.start_mission_thread.mission
89
+ error_message = self.start_mission_thread.error_message
85
90
  self.start_mission_thread = None
86
91
 
92
+ if error_message:
93
+ self.robot_service_events.mission_failed.trigger_event(error_message)
94
+ else:
95
+ self.robot_service_events.mission_started.trigger_event(True)
96
+
87
97
  if (
88
98
  self.monitor_mission_thread is not None
89
99
  and self.monitor_mission_thread.is_alive()
@@ -131,6 +141,24 @@ class Robot(object):
131
141
  True
132
142
  )
133
143
 
144
+ def _pause_mission_done_handler(self) -> None:
145
+ if (
146
+ self.pause_mission_thread is not None
147
+ and not self.pause_mission_thread.is_alive()
148
+ ):
149
+ self.pause_mission_thread.join()
150
+ error_message = self.pause_mission_thread.error_message
151
+ self.pause_mission_thread = None
152
+
153
+ if error_message:
154
+ self.robot_service_events.mission_failed_to_pause.trigger_event(
155
+ error_message
156
+ )
157
+ else:
158
+ self.robot_service_events.mission_successfully_paused.trigger_event(
159
+ True
160
+ )
161
+
134
162
  def _start_mission_event_handler(self, event: Event[Mission]) -> None:
135
163
  start_mission = event.consume_event()
136
164
  if start_mission is not None:
@@ -144,7 +172,6 @@ class Robot(object):
144
172
  self.start_mission_thread.join()
145
173
 
146
174
  self.start_mission_thread = RobotStartMissionThread(
147
- self.robot_service_events,
148
175
  self.robot,
149
176
  self.signal_thread_quitting,
150
177
  start_mission,
@@ -204,7 +231,7 @@ class Robot(object):
204
231
  )
205
232
  return
206
233
  self.pause_mission_thread = RobotPauseMissionThread(
207
- self.robot_service_events, self.robot, self.signal_thread_quitting
234
+ self.robot, self.signal_thread_quitting
208
235
  )
209
236
  self.pause_mission_thread.start()
210
237
 
@@ -220,15 +247,20 @@ class Robot(object):
220
247
  self.upload_inspection_threads.append(upload_inspection_thread)
221
248
  upload_inspection_thread.start()
222
249
 
223
- def _join_threads(thread: RobotUploadInspectionThread) -> bool:
224
- if thread.is_done():
225
- thread.join()
226
- return True
227
- return False
250
+ def _upload_inspection_done_handler(self):
251
+ if len(self.upload_inspection_threads) > 0:
252
+
253
+ def _join_threads(thread: RobotUploadInspectionThread) -> bool:
254
+ if not thread.is_alive():
255
+ thread.join()
256
+ return True
257
+ return False
228
258
 
229
- self.upload_inspection_threads[:] = [
230
- thread for thread in self.upload_inspection_threads if _join_threads(thread)
231
- ]
259
+ self.upload_inspection_threads[:] = [
260
+ thread
261
+ for thread in self.upload_inspection_threads
262
+ if _join_threads(thread)
263
+ ]
232
264
 
233
265
  def run(self) -> None:
234
266
  self.robot_status_thread = RobotStatusThread(
@@ -260,4 +292,8 @@ class Robot(object):
260
292
 
261
293
  self._stop_mission_done_handler()
262
294
 
295
+ self._pause_mission_done_handler()
296
+
297
+ self._upload_inspection_done_handler()
298
+
263
299
  self.logger.info("Exiting robot service main thread")
@@ -86,6 +86,10 @@ class RobotMonitorMissionThread(Thread):
86
86
  if self.signal_thread_quitting.wait(0) or self.signal_mission_stopped.wait(
87
87
  0
88
88
  ):
89
+ failed_task_error = ErrorMessage(
90
+ error_reason=ErrorReason.RobotTaskStatusException,
91
+ error_description="Task status collection was cancelled by monitor thread exit",
92
+ )
89
93
  break
90
94
  if request_status_failure_counter > 0:
91
95
  time.sleep(settings.REQUEST_STATUS_COMMUNICATION_RECONNECT_DELAY)
@@ -320,7 +324,8 @@ class RobotMonitorMissionThread(Thread):
320
324
  new_task_status = self._get_task_status(current_task.id)
321
325
  except RobotTaskStatusException as e:
322
326
  self.logger.error(
323
- "Failed to collect task status", e.error_description
327
+ "Failed to collect task status. Error description: %s",
328
+ e.error_description,
324
329
  )
325
330
  break
326
331
  except Exception:
@@ -4,11 +4,11 @@ from threading import Event, Thread
4
4
  from typing import Optional
5
5
 
6
6
  from isar.config.settings import settings
7
- from isar.models.events import RobotServiceEvents
8
7
  from robot_interface.models.exceptions.robot_exceptions import (
9
8
  ErrorMessage,
10
9
  RobotActionException,
11
10
  RobotException,
11
+ RobotNoMissionRunningException,
12
12
  )
13
13
  from robot_interface.robot_interface import RobotInterface
14
14
 
@@ -16,14 +16,13 @@ from robot_interface.robot_interface import RobotInterface
16
16
  class RobotPauseMissionThread(Thread):
17
17
  def __init__(
18
18
  self,
19
- robot_service_events: RobotServiceEvents,
20
19
  robot: RobotInterface,
21
20
  signal_thread_quitting: Event,
22
21
  ):
23
22
  self.logger = logging.getLogger("robot")
24
- self.robot_service_events: RobotServiceEvents = robot_service_events
25
23
  self.robot: RobotInterface = robot
26
24
  self.signal_thread_quitting: Event = signal_thread_quitting
25
+ self.error_message: Optional[ErrorMessage] = None
27
26
  Thread.__init__(self, name="Robot pause mission thread")
28
27
 
29
28
  def run(self) -> None:
@@ -35,6 +34,11 @@ class RobotPauseMissionThread(Thread):
35
34
 
36
35
  try:
37
36
  self.robot.pause()
37
+ except RobotNoMissionRunningException as e:
38
+ error = ErrorMessage(
39
+ error_reason=e.error_reason, error_description=e.error_description
40
+ )
41
+ break
38
42
  except (RobotActionException, RobotException) as e:
39
43
  self.logger.warning(
40
44
  f"\nFailed to pause robot because: {e.error_description}"
@@ -46,7 +50,6 @@ class RobotPauseMissionThread(Thread):
46
50
  )
47
51
  time.sleep(settings.FSM_SLEEP_TIME)
48
52
  continue
49
- self.robot_service_events.mission_successfully_paused.trigger_event(True)
50
53
  return
51
54
 
52
55
  error_description = (
@@ -56,8 +59,7 @@ class RobotPauseMissionThread(Thread):
56
59
  "been attempted"
57
60
  )
58
61
 
59
- error_message = ErrorMessage(
62
+ self.error_message = ErrorMessage(
60
63
  error_reason=error.error_reason,
61
64
  error_description=error_description,
62
65
  )
63
- self.robot_service_events.mission_failed_to_pause.trigger_event(error_message)
@@ -1,8 +1,8 @@
1
1
  import logging
2
2
  from threading import Event, Thread
3
+ from typing import Optional
3
4
 
4
5
  from isar.config.settings import settings
5
- from isar.models.events import RobotServiceEvents
6
6
  from robot_interface.models.exceptions.robot_exceptions import (
7
7
  ErrorMessage,
8
8
  RobotException,
@@ -15,23 +15,21 @@ from robot_interface.robot_interface import RobotInterface
15
15
  class RobotStartMissionThread(Thread):
16
16
  def __init__(
17
17
  self,
18
- robot_service_events: RobotServiceEvents,
19
18
  robot: RobotInterface,
20
19
  signal_thread_quitting: Event,
21
20
  mission: Mission,
22
21
  ):
23
22
  self.logger = logging.getLogger("robot")
24
- self.robot_service_events: RobotServiceEvents = robot_service_events
25
23
  self.robot: RobotInterface = robot
26
24
  self.signal_thread_quitting: Event = signal_thread_quitting
27
25
  self.mission = mission
26
+ self.error_message: Optional[ErrorMessage] = None
28
27
  Thread.__init__(self, name="Robot start mission thread")
29
28
 
30
29
  def run(self):
31
30
  retries = 0
32
- started_mission = False
33
31
  try:
34
- while not started_mission:
32
+ while True:
35
33
  if self.signal_thread_quitting.wait(0):
36
34
  return
37
35
  try:
@@ -40,11 +38,9 @@ class RobotStartMissionThread(Thread):
40
38
  self.logger.error(
41
39
  f"Mission is infeasible and cannot be scheduled because: {e.error_description}"
42
40
  )
43
- self.robot_service_events.mission_failed.trigger_event(
44
- ErrorMessage(
45
- error_reason=e.error_reason,
46
- error_description=e.error_description,
47
- )
41
+ self.error_message = ErrorMessage(
42
+ error_reason=e.error_reason,
43
+ error_description=e.error_description,
48
44
  )
49
45
 
50
46
  break
@@ -62,23 +58,15 @@ class RobotStartMissionThread(Thread):
62
58
  f"{e.error_description}"
63
59
  )
64
60
 
65
- self.robot_service_events.mission_failed.trigger_event(
66
- ErrorMessage(
67
- error_reason=e.error_reason,
68
- error_description=e.error_description,
69
- )
61
+ self.error_message = ErrorMessage(
62
+ error_reason=e.error_reason,
63
+ error_description=e.error_description,
70
64
  )
71
65
  break
72
66
 
73
67
  continue
74
-
75
- started_mission = True
68
+ break
76
69
  except RobotInfeasibleMissionException as e:
77
- self.robot_service_events.mission_failed.trigger_event(
78
- ErrorMessage(
79
- error_reason=e.error_reason, error_description=e.error_description
80
- ),
70
+ self.error_message = ErrorMessage(
71
+ error_reason=e.error_reason, error_description=e.error_description
81
72
  )
82
-
83
- if started_mission:
84
- self.robot_service_events.mission_started.trigger_event(True)
@@ -9,6 +9,7 @@ from robot_interface.models.exceptions.robot_exceptions import (
9
9
  ErrorReason,
10
10
  RobotActionException,
11
11
  RobotException,
12
+ RobotNoMissionRunningException,
12
13
  )
13
14
  from robot_interface.robot_interface import RobotInterface
14
15
 
@@ -38,6 +39,8 @@ class RobotStopMissionThread(Thread):
38
39
 
39
40
  try:
40
41
  self.robot.stop()
42
+ except RobotNoMissionRunningException:
43
+ return
41
44
  except (RobotActionException, RobotException) as e:
42
45
  self.logger.warning(
43
46
  f"\nFailed to stop robot because: {e.error_description}"
@@ -27,15 +27,11 @@ class RobotUploadInspectionThread(Thread):
27
27
  self.task: TASKS = task
28
28
  self.upload_queue = upload_queue
29
29
  self.mission: Mission = mission
30
- self._is_done = False
31
30
  Thread.__init__(self, name=f"Robot inspection upload thread - {task.id}")
32
31
 
33
32
  def stop(self) -> None:
34
33
  return
35
34
 
36
- def is_done(self) -> bool:
37
- return self._is_done
38
-
39
35
  def run(self):
40
36
  try:
41
37
  inspection: Inspection = self.robot.get_inspection(task=self.task)
@@ -77,4 +73,3 @@ class RobotUploadInspectionThread(Thread):
77
73
  self.logger.info(
78
74
  f"Inspection result: {str(inspection.id)[:8]} queued for upload"
79
75
  )
80
- self._is_done = True
@@ -14,6 +14,7 @@ from isar.models.status import IsarStatus
14
14
  from isar.state_machine.states.await_next_mission import AwaitNextMission
15
15
  from isar.state_machine.states.blocked_protective_stop import BlockedProtectiveStop
16
16
  from isar.state_machine.states.going_to_lockdown import GoingToLockdown
17
+ from isar.state_machine.states.going_to_recharging import GoingToRecharging
17
18
  from isar.state_machine.states.home import Home
18
19
  from isar.state_machine.states.intervention_needed import InterventionNeeded
19
20
  from isar.state_machine.states.lockdown import Lockdown
@@ -27,6 +28,7 @@ from isar.state_machine.states.return_home_paused import ReturnHomePaused
27
28
  from isar.state_machine.states.returning_home import ReturningHome
28
29
  from isar.state_machine.states.stopping import Stopping
29
30
  from isar.state_machine.states.stopping_go_to_lockdown import StoppingGoToLockdown
31
+ from isar.state_machine.states.stopping_go_to_recharge import StoppingGoToRecharge
30
32
  from isar.state_machine.states.stopping_return_home import StoppingReturnHome
31
33
  from isar.state_machine.states.unknown_status import UnknownStatus
32
34
  from isar.state_machine.states_enum import States
@@ -95,7 +97,9 @@ class StateMachine(object):
95
97
  self.stopping_return_home_state: State = StoppingReturnHome(self)
96
98
  self.pausing_return_home_state: State = PausingReturnHome(self)
97
99
  self.stopping_go_to_lockdown_state: State = StoppingGoToLockdown(self)
100
+ self.stopping_go_to_recharge_state: State = StoppingGoToRecharge(self)
98
101
  self.going_to_lockdown_state: State = GoingToLockdown(self)
102
+ self.going_to_recharging_state: State = GoingToRecharging(self)
99
103
 
100
104
  # States Waiting for mission
101
105
  self.await_next_mission_state: State = AwaitNextMission(self)
@@ -130,6 +134,8 @@ class StateMachine(object):
130
134
  self.stopping_go_to_lockdown_state,
131
135
  self.going_to_lockdown_state,
132
136
  self.lockdown_state,
137
+ self.going_to_recharging_state,
138
+ self.stopping_go_to_recharge_state,
133
139
  ]
134
140
 
135
141
  self.machine = Machine(
@@ -279,6 +285,8 @@ class StateMachine(object):
279
285
  return IsarStatus.Lockdown
280
286
  elif self.current_state == States.GoingToLockdown:
281
287
  return IsarStatus.GoingToLockdown
288
+ elif self.current_state == States.GoingToRecharging:
289
+ return IsarStatus.GoingToRecharging
282
290
  else:
283
291
  return IsarStatus.Busy
284
292
 
@@ -22,6 +22,7 @@ class AwaitNextMission(EventHandlerBase):
22
22
 
23
23
  def __init__(self, state_machine: "StateMachine"):
24
24
  events = state_machine.events
25
+ shared_state = state_machine.shared_state
25
26
 
26
27
  def _send_to_lockdown_event_handler(
27
28
  event: Event[bool],
@@ -35,6 +36,18 @@ class AwaitNextMission(EventHandlerBase):
35
36
  )
36
37
  return state_machine.request_lockdown_mission # type: ignore
37
38
 
39
+ def _robot_battery_level_updated_handler(
40
+ event: Event[float],
41
+ ) -> Optional[Callable]:
42
+ battery_level: float = event.check()
43
+ if (
44
+ battery_level is None
45
+ or battery_level >= settings.ROBOT_MISSION_BATTERY_START_THRESHOLD
46
+ ):
47
+ return None
48
+
49
+ return state_machine.request_recharging_mission # type: ignore
50
+
38
51
  event_handlers: List[EventHandlerMapping] = [
39
52
  EventHandlerMapping(
40
53
  name="start_mission_event",
@@ -58,6 +71,11 @@ class AwaitNextMission(EventHandlerBase):
58
71
  event=events.api_requests.send_to_lockdown.request,
59
72
  handler=_send_to_lockdown_event_handler,
60
73
  ),
74
+ EventHandlerMapping(
75
+ name="robot_battery_update_event",
76
+ event=shared_state.robot_battery_level,
77
+ handler=_robot_battery_level_updated_handler,
78
+ ),
61
79
  ]
62
80
 
63
81
  timers: List[TimeoutHandlerMapping] = [
@@ -0,0 +1,81 @@
1
+ from typing import TYPE_CHECKING, Callable, List, Optional
2
+
3
+ from isar.apis.models.models import LockdownResponse
4
+ from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
5
+ from isar.models.events import Event
6
+ from robot_interface.models.exceptions.robot_exceptions import ErrorMessage
7
+ from robot_interface.models.mission.status import MissionStatus
8
+
9
+ if TYPE_CHECKING:
10
+ from isar.state_machine.state_machine import StateMachine
11
+
12
+
13
+ class GoingToRecharging(EventHandlerBase):
14
+
15
+ def __init__(self, state_machine: "StateMachine"):
16
+ events = state_machine.events
17
+
18
+ def _mission_failed_event_handler(
19
+ event: Event[Optional[ErrorMessage]],
20
+ ) -> Optional[Callable]:
21
+ mission_failed: Optional[ErrorMessage] = event.consume_event()
22
+ if mission_failed is None:
23
+ return None
24
+
25
+ state_machine.logger.warning(
26
+ f"Failed to go to recharging because: "
27
+ f"{mission_failed.error_description}"
28
+ )
29
+ return state_machine.return_home_failed # type: ignore
30
+
31
+ def _mission_status_event_handler(
32
+ event: Event[MissionStatus],
33
+ ) -> Optional[Callable]:
34
+ mission_status: Optional[MissionStatus] = event.consume_event()
35
+
36
+ if not mission_status or mission_status in [
37
+ MissionStatus.InProgress,
38
+ MissionStatus.NotStarted,
39
+ MissionStatus.Paused,
40
+ ]:
41
+ return None
42
+
43
+ if mission_status != MissionStatus.Successful:
44
+ return state_machine.return_home_failed # type: ignore
45
+
46
+ return state_machine.starting_recharging # type: ignore
47
+
48
+ def _send_to_lockdown_event_handler(
49
+ event: Event[bool],
50
+ ) -> Optional[Callable]:
51
+ should_lockdown: bool = event.consume_event()
52
+ if not should_lockdown:
53
+ return None
54
+
55
+ events.api_requests.send_to_lockdown.response.trigger_event(
56
+ LockdownResponse(lockdown_started=True)
57
+ )
58
+ return state_machine.go_to_lockdown # type: ignore
59
+
60
+ event_handlers: List[EventHandlerMapping] = [
61
+ EventHandlerMapping(
62
+ name="mission_failed_event",
63
+ event=events.robot_service_events.mission_failed,
64
+ handler=_mission_failed_event_handler,
65
+ ),
66
+ EventHandlerMapping(
67
+ name="mission_status_event",
68
+ event=events.robot_service_events.mission_status_updated,
69
+ handler=_mission_status_event_handler,
70
+ ),
71
+ EventHandlerMapping(
72
+ name="send_to_lockdown_event",
73
+ event=events.api_requests.send_to_lockdown.request,
74
+ handler=_send_to_lockdown_event_handler,
75
+ ),
76
+ ]
77
+ super().__init__(
78
+ state_name="going_to_recharging",
79
+ state_machine=state_machine,
80
+ event_handler_mappings=event_handlers,
81
+ )
@@ -1,6 +1,7 @@
1
1
  from typing import TYPE_CHECKING, Callable, List, Optional
2
2
 
3
3
  from isar.apis.models.models import LockdownResponse
4
+ from isar.config.settings import settings
4
5
  from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
5
6
  from isar.models.events import Event
6
7
  from isar.state_machine.utils.common_event_handlers import (
@@ -44,6 +45,18 @@ class Home(EventHandlerBase):
44
45
  return state_machine.robot_status_changed # type: ignore
45
46
  return None
46
47
 
48
+ def _robot_battery_level_updated_handler(
49
+ event: Event[float],
50
+ ) -> Optional[Callable]:
51
+ battery_level: float = event.check()
52
+ if (
53
+ battery_level is None
54
+ or battery_level >= settings.ROBOT_MISSION_BATTERY_START_THRESHOLD
55
+ ):
56
+ return None
57
+
58
+ return state_machine.starting_recharging # type: ignore
59
+
47
60
  event_handlers: List[EventHandlerMapping] = [
48
61
  EventHandlerMapping(
49
62
  name="start_mission_event",
@@ -72,6 +85,11 @@ class Home(EventHandlerBase):
72
85
  event=events.api_requests.send_to_lockdown.request,
73
86
  handler=_send_to_lockdown_event_handler,
74
87
  ),
88
+ EventHandlerMapping(
89
+ name="robot_battery_update_event",
90
+ event=shared_state.robot_battery_level,
91
+ handler=_robot_battery_level_updated_handler,
92
+ ),
75
93
  ]
76
94
  super().__init__(
77
95
  state_name="home",
@@ -30,16 +30,16 @@ class Monitor(EventHandlerBase):
30
30
  event: Event[float],
31
31
  ) -> Optional[Callable]:
32
32
  battery_level: float = event.check()
33
- if battery_level >= settings.ROBOT_MISSION_BATTERY_START_THRESHOLD:
33
+ if (
34
+ battery_level is None
35
+ or battery_level >= settings.ROBOT_MISSION_BATTERY_START_THRESHOLD
36
+ ):
34
37
  return None
35
38
 
36
- state_machine.publish_mission_aborted(
37
- "Robot battery too low to continue mission", True
38
- )
39
39
  state_machine.logger.warning(
40
40
  "Cancelling current mission due to low battery"
41
41
  )
42
- return state_machine.stop # type: ignore
42
+ return state_machine.stop_go_to_recharge # type: ignore
43
43
 
44
44
  def _send_to_lockdown_event_handler(
45
45
  event: Event[bool],
@@ -19,7 +19,10 @@ class Paused(EventHandlerBase):
19
19
  event: Event[float],
20
20
  ) -> Optional[Callable]:
21
21
  battery_level: float = event.check()
22
- if battery_level >= settings.ROBOT_MISSION_BATTERY_START_THRESHOLD:
22
+ if (
23
+ battery_level is None
24
+ or battery_level >= settings.ROBOT_MISSION_BATTERY_START_THRESHOLD
25
+ ):
23
26
  return None
24
27
 
25
28
  state_machine.publish_mission_aborted(
@@ -21,7 +21,10 @@ class ReturnHomePaused(EventHandlerBase):
21
21
  ) -> Optional[Callable]:
22
22
  battery_level: float = event.check()
23
23
 
24
- if battery_level >= settings.ROBOT_MISSION_BATTERY_START_THRESHOLD:
24
+ if (
25
+ battery_level is None
26
+ or battery_level >= settings.ROBOT_MISSION_BATTERY_START_THRESHOLD
27
+ ):
25
28
  return None
26
29
 
27
30
  return state_machine.resume # type: ignore
@@ -1,6 +1,7 @@
1
1
  from typing import TYPE_CHECKING, Callable, List, Optional
2
2
 
3
3
  from isar.apis.models.models import LockdownResponse, MissionStartResponse
4
+ from isar.config.settings import settings
4
5
  from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
5
6
  from isar.models.events import Event
6
7
  from isar.state_machine.utils.common_event_handlers import mission_started_event_handler
@@ -17,6 +18,7 @@ class ReturningHome(EventHandlerBase):
17
18
  def __init__(self, state_machine: "StateMachine"):
18
19
  self.failed_return_home_attemps: int = 0
19
20
  events = state_machine.events
21
+ shared_state = state_machine.shared_state
20
22
 
21
23
  def _pause_mission_event_handler(event: Event[bool]) -> Optional[Callable]:
22
24
  if not event.consume_event():
@@ -59,10 +61,7 @@ class ReturningHome(EventHandlerBase):
59
61
  return state_machine.return_home_failed # type: ignore
60
62
 
61
63
  self.failed_return_home_attemps = 0
62
- if not state_machine.battery_level_is_above_mission_start_threshold():
63
- return state_machine.starting_recharging # type: ignore
64
- else:
65
- return state_machine.returned_home # type: ignore
64
+ return state_machine.returned_home # type: ignore
66
65
  return None
67
66
 
68
67
  def _send_to_lockdown_event_handler(
@@ -89,6 +88,18 @@ class ReturningHome(EventHandlerBase):
89
88
  return state_machine.return_home_failed # type: ignore
90
89
  return None
91
90
 
91
+ def _robot_battery_level_updated_handler(
92
+ event: Event[float],
93
+ ) -> Optional[Callable]:
94
+ battery_level: float = event.check()
95
+ if (
96
+ battery_level is None
97
+ or battery_level >= settings.ROBOT_MISSION_BATTERY_START_THRESHOLD
98
+ ):
99
+ return None
100
+
101
+ return state_machine.go_to_recharging # type: ignore
102
+
92
103
  event_handlers: List[EventHandlerMapping] = [
93
104
  EventHandlerMapping(
94
105
  name="pause_mission_event",
@@ -117,6 +128,11 @@ class ReturningHome(EventHandlerBase):
117
128
  event=events.robot_service_events.mission_status_updated,
118
129
  handler=_mission_status_event_handler,
119
130
  ),
131
+ EventHandlerMapping(
132
+ name="robot_battery_update_event",
133
+ event=shared_state.robot_battery_level,
134
+ handler=_robot_battery_level_updated_handler,
135
+ ),
120
136
  EventHandlerMapping(
121
137
  name="send_to_lockdown_event",
122
138
  event=events.api_requests.send_to_lockdown.request,