isar 1.30.2__tar.gz → 1.30.3__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 (227) hide show
  1. {isar-1.30.2 → isar-1.30.3}/PKG-INFO +1 -1
  2. {isar-1.30.2 → isar-1.30.3}/requirements.txt +12 -12
  3. {isar-1.30.2 → isar-1.30.3}/src/isar/config/settings.py +1 -0
  4. {isar-1.30.2 → isar-1.30.3}/src/isar/robot/robot_start_mission.py +12 -0
  5. {isar-1.30.2 → isar-1.30.3}/src/isar/robot/robot_status.py +5 -3
  6. isar-1.30.2/src/isar/state_machine/states/robot_standing_still.py → isar-1.30.3/src/isar/state_machine/generic_states/idle.py +51 -18
  7. isar-1.30.2/src/isar/state_machine/states/monitor.py → isar-1.30.3/src/isar/state_machine/generic_states/ongoing_mission.py +64 -26
  8. isar-1.30.2/src/isar/state_machine/states/offline.py → isar-1.30.3/src/isar/state_machine/generic_states/robot_unavailable.py +21 -7
  9. {isar-1.30.2 → isar-1.30.3}/src/isar/state_machine/state_machine.py +9 -0
  10. isar-1.30.3/src/isar/state_machine/states/await_next_mission.py +20 -0
  11. isar-1.30.3/src/isar/state_machine/states/blocked_protective_stop.py +24 -0
  12. isar-1.30.3/src/isar/state_machine/states/home.py +19 -0
  13. isar-1.30.3/src/isar/state_machine/states/monitor.py +24 -0
  14. isar-1.30.3/src/isar/state_machine/states/offline.py +22 -0
  15. {isar-1.30.2 → isar-1.30.3}/src/isar/state_machine/states/paused.py +1 -1
  16. isar-1.30.3/src/isar/state_machine/states/returning_home.py +24 -0
  17. isar-1.30.3/src/isar/state_machine/states/robot_standing_still.py +20 -0
  18. {isar-1.30.2 → isar-1.30.3}/src/isar/state_machine/transitions/mission.py +1 -1
  19. {isar-1.30.2 → isar-1.30.3}/src/isar.egg-info/PKG-INFO +1 -1
  20. {isar-1.30.2 → isar-1.30.3}/src/isar.egg-info/SOURCES.txt +14 -11
  21. {isar-1.30.2 → isar-1.30.3}/src/robot_interface/robot_interface.py +15 -7
  22. {isar-1.30.2 → isar-1.30.3}/tests/conftest.py +7 -7
  23. {isar-1.30.2 → isar-1.30.3}/tests/isar/apis/scheduler/test_scheduler_router.py +25 -23
  24. {isar-1.30.2 → isar-1.30.3}/tests/isar/apis/security/test_authentication.py +2 -2
  25. {isar-1.30.2 → isar-1.30.3}/tests/isar/services/utilities/test_scheduling_utilities.py +3 -3
  26. {isar-1.30.2 → isar-1.30.3}/tests/isar/state_machine/states/test_monitor.py +3 -3
  27. {isar-1.30.2 → isar-1.30.3}/tests/isar/state_machine/test_state_machine.py +30 -30
  28. {isar-1.30.2 → isar-1.30.3}/tests/isar/storage/test_uploader.py +3 -3
  29. {isar-1.30.2/tests/mocks → isar-1.30.3/tests/test_double}/blob_storage.py +2 -2
  30. isar-1.30.3/tests/test_double/mission_definition.py +77 -0
  31. {isar-1.30.2/tests/mocks → isar-1.30.3/tests/test_double}/mqtt_client.py +1 -1
  32. {isar-1.30.2/tests/mocks → isar-1.30.3/tests/test_double}/pose.py +1 -1
  33. {isar-1.30.2/tests/mocks → isar-1.30.3/tests/test_double}/request.py +1 -1
  34. {isar-1.30.2/tests/mocks → isar-1.30.3/tests/test_double}/robot_interface.py +9 -9
  35. {isar-1.30.2/tests/mocks → isar-1.30.3/tests/test_double}/status.py +1 -1
  36. {isar-1.30.2/tests/mocks → isar-1.30.3/tests/test_double}/task.py +1 -1
  37. {isar-1.30.2/tests/mocks → isar-1.30.3/tests/test_double}/token.py +1 -1
  38. isar-1.30.2/src/isar/state_machine/states/await_next_mission.py +0 -92
  39. isar-1.30.2/src/isar/state_machine/states/blocked_protective_stop.py +0 -50
  40. isar-1.30.2/src/isar/state_machine/states/home.py +0 -87
  41. isar-1.30.2/src/isar/state_machine/states/returning_home.py +0 -187
  42. isar-1.30.2/tests/mocks/mission_definition.py +0 -77
  43. {isar-1.30.2 → isar-1.30.3}/.dockerignore +0 -0
  44. {isar-1.30.2 → isar-1.30.3}/.env.test +0 -0
  45. {isar-1.30.2 → isar-1.30.3}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  46. {isar-1.30.2 → isar-1.30.3}/.github/ISSUE_TEMPLATE/feature.md +0 -0
  47. {isar-1.30.2 → isar-1.30.3}/.github/ISSUE_TEMPLATE/improvement.md +0 -0
  48. {isar-1.30.2 → isar-1.30.3}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  49. {isar-1.30.2 → isar-1.30.3}/.github/release.yml +0 -0
  50. {isar-1.30.2 → isar-1.30.3}/.github/workflows/compile_requirements.yml +0 -0
  51. {isar-1.30.2 → isar-1.30.3}/.github/workflows/project_automations.yml +0 -0
  52. {isar-1.30.2 → isar-1.30.3}/.github/workflows/pythonpackage.yml +0 -0
  53. {isar-1.30.2 → isar-1.30.3}/.github/workflows/pythonpublish.yml +0 -0
  54. {isar-1.30.2 → isar-1.30.3}/.github/workflows/stale.yml +0 -0
  55. {isar-1.30.2 → isar-1.30.3}/.gitignore +0 -0
  56. {isar-1.30.2 → isar-1.30.3}/.pre-commit-config.yaml +0 -0
  57. {isar-1.30.2 → isar-1.30.3}/LICENSE +0 -0
  58. {isar-1.30.2 → isar-1.30.3}/README.md +0 -0
  59. {isar-1.30.2 → isar-1.30.3}/SECURITY.md +0 -0
  60. {isar-1.30.2 → isar-1.30.3}/docs/Makefile +0 -0
  61. {isar-1.30.2 → isar-1.30.3}/docs/full_state_machine_diagram.png +0 -0
  62. {isar-1.30.2 → isar-1.30.3}/docs/make.bat +0 -0
  63. {isar-1.30.2 → isar-1.30.3}/docs/mission_state_machine_diagram.png +0 -0
  64. {isar-1.30.2 → isar-1.30.3}/docs/robot_status_state_machine_diagram.png +0 -0
  65. {isar-1.30.2 → isar-1.30.3}/docs/rst_processing.py +0 -0
  66. {isar-1.30.2 → isar-1.30.3}/docs/source/conf.py +0 -0
  67. {isar-1.30.2 → isar-1.30.3}/docs/source/index.rst +0 -0
  68. {isar-1.30.2 → isar-1.30.3}/docs/source/readme_link.md +0 -0
  69. {isar-1.30.2 → isar-1.30.3}/docs/update_state_diagram.py +0 -0
  70. {isar-1.30.2 → isar-1.30.3}/main.py +0 -0
  71. {isar-1.30.2 → isar-1.30.3}/pyproject.toml +0 -0
  72. {isar-1.30.2 → isar-1.30.3}/radixconfig.yml +0 -0
  73. {isar-1.30.2 → isar-1.30.3}/setup.cfg +0 -0
  74. {isar-1.30.2 → isar-1.30.3}/src/isar/__init__.py +0 -0
  75. {isar-1.30.2 → isar-1.30.3}/src/isar/apis/__init__.py +0 -0
  76. {isar-1.30.2 → isar-1.30.3}/src/isar/apis/api.py +0 -0
  77. {isar-1.30.2 → isar-1.30.3}/src/isar/apis/models/__init__.py +0 -0
  78. {isar-1.30.2 → isar-1.30.3}/src/isar/apis/models/models.py +0 -0
  79. {isar-1.30.2 → isar-1.30.3}/src/isar/apis/models/start_mission_definition.py +0 -0
  80. {isar-1.30.2 → isar-1.30.3}/src/isar/apis/robot_control/robot_controller.py +0 -0
  81. {isar-1.30.2 → isar-1.30.3}/src/isar/apis/schedule/__init__.py +0 -0
  82. {isar-1.30.2 → isar-1.30.3}/src/isar/apis/schedule/scheduling_controller.py +0 -0
  83. {isar-1.30.2 → isar-1.30.3}/src/isar/apis/security/__init__.py +0 -0
  84. {isar-1.30.2 → isar-1.30.3}/src/isar/apis/security/authentication.py +0 -0
  85. {isar-1.30.2 → isar-1.30.3}/src/isar/config/__init__.py +0 -0
  86. {isar-1.30.2 → isar-1.30.3}/src/isar/config/certs/ca-cert.pem +0 -0
  87. {isar-1.30.2 → isar-1.30.3}/src/isar/config/configuration_error.py +0 -0
  88. {isar-1.30.2 → isar-1.30.3}/src/isar/config/keyvault/__init__.py +0 -0
  89. {isar-1.30.2 → isar-1.30.3}/src/isar/config/keyvault/keyvault_error.py +0 -0
  90. {isar-1.30.2 → isar-1.30.3}/src/isar/config/keyvault/keyvault_service.py +0 -0
  91. {isar-1.30.2 → isar-1.30.3}/src/isar/config/log.py +0 -0
  92. {isar-1.30.2 → isar-1.30.3}/src/isar/config/logging.conf +0 -0
  93. {isar-1.30.2 → isar-1.30.3}/src/isar/config/maps/JSP1_intermediate_deck.json +0 -0
  94. {isar-1.30.2 → isar-1.30.3}/src/isar/config/maps/JSP1_weather_deck.json +0 -0
  95. {isar-1.30.2 → isar-1.30.3}/src/isar/config/maps/default_map.json +0 -0
  96. {isar-1.30.2 → isar-1.30.3}/src/isar/config/maps/klab_b.json +0 -0
  97. {isar-1.30.2 → isar-1.30.3}/src/isar/config/maps/klab_compressor.json +0 -0
  98. {isar-1.30.2 → isar-1.30.3}/src/isar/config/maps/klab_turtlebot.json +0 -0
  99. {isar-1.30.2 → isar-1.30.3}/src/isar/config/maps/turtleworld.json +0 -0
  100. {isar-1.30.2 → isar-1.30.3}/src/isar/config/predefined_mission_definition/__init__.py +0 -0
  101. {isar-1.30.2 → isar-1.30.3}/src/isar/config/predefined_mission_definition/default_exr.json +0 -0
  102. {isar-1.30.2 → isar-1.30.3}/src/isar/config/predefined_mission_definition/default_mission.json +0 -0
  103. {isar-1.30.2 → isar-1.30.3}/src/isar/config/predefined_mission_definition/default_turtlebot.json +0 -0
  104. {isar-1.30.2 → isar-1.30.3}/src/isar/config/predefined_missions/__init__.py +0 -0
  105. {isar-1.30.2 → isar-1.30.3}/src/isar/config/predefined_missions/default.json +0 -0
  106. {isar-1.30.2 → isar-1.30.3}/src/isar/config/predefined_missions/default_turtlebot.json +0 -0
  107. {isar-1.30.2 → isar-1.30.3}/src/isar/mission_planner/__init__.py +0 -0
  108. {isar-1.30.2 → isar-1.30.3}/src/isar/mission_planner/local_planner.py +0 -0
  109. {isar-1.30.2 → isar-1.30.3}/src/isar/mission_planner/mission_planner_interface.py +0 -0
  110. {isar-1.30.2 → isar-1.30.3}/src/isar/mission_planner/sequential_task_selector.py +0 -0
  111. {isar-1.30.2 → isar-1.30.3}/src/isar/mission_planner/task_selector_interface.py +0 -0
  112. {isar-1.30.2 → isar-1.30.3}/src/isar/models/__init__.py +0 -0
  113. {isar-1.30.2 → isar-1.30.3}/src/isar/models/communication/__init__.py +0 -0
  114. {isar-1.30.2 → isar-1.30.3}/src/isar/models/communication/message.py +0 -0
  115. {isar-1.30.2 → isar-1.30.3}/src/isar/models/communication/queues/__init__.py +0 -0
  116. {isar-1.30.2 → isar-1.30.3}/src/isar/models/communication/queues/events.py +0 -0
  117. {isar-1.30.2 → isar-1.30.3}/src/isar/models/communication/queues/queue_io.py +0 -0
  118. {isar-1.30.2 → isar-1.30.3}/src/isar/models/communication/queues/queue_timeout_error.py +0 -0
  119. {isar-1.30.2 → isar-1.30.3}/src/isar/models/communication/queues/queue_utils.py +0 -0
  120. {isar-1.30.2 → isar-1.30.3}/src/isar/models/communication/queues/status_queue.py +0 -0
  121. {isar-1.30.2 → isar-1.30.3}/src/isar/models/mission_metadata/__init__.py +0 -0
  122. {isar-1.30.2 → isar-1.30.3}/src/isar/modules.py +0 -0
  123. {isar-1.30.2 → isar-1.30.3}/src/isar/robot/robot.py +0 -0
  124. {isar-1.30.2 → isar-1.30.3}/src/isar/robot/robot_stop_mission.py +0 -0
  125. {isar-1.30.2 → isar-1.30.3}/src/isar/robot/robot_task_status.py +0 -0
  126. {isar-1.30.2 → isar-1.30.3}/src/isar/script.py +0 -0
  127. {isar-1.30.2 → isar-1.30.3}/src/isar/services/__init__.py +0 -0
  128. {isar-1.30.2 → isar-1.30.3}/src/isar/services/auth/__init__.py +0 -0
  129. {isar-1.30.2 → isar-1.30.3}/src/isar/services/auth/azure_credentials.py +0 -0
  130. {isar-1.30.2 → isar-1.30.3}/src/isar/services/service_connections/__init__.py +0 -0
  131. {isar-1.30.2 → isar-1.30.3}/src/isar/services/service_connections/mqtt/__init__.py +0 -0
  132. {isar-1.30.2 → isar-1.30.3}/src/isar/services/service_connections/mqtt/mqtt_client.py +0 -0
  133. {isar-1.30.2 → isar-1.30.3}/src/isar/services/service_connections/mqtt/robot_heartbeat_publisher.py +0 -0
  134. {isar-1.30.2 → isar-1.30.3}/src/isar/services/service_connections/mqtt/robot_info_publisher.py +0 -0
  135. {isar-1.30.2 → isar-1.30.3}/src/isar/services/service_connections/request_handler.py +0 -0
  136. {isar-1.30.2 → isar-1.30.3}/src/isar/services/service_connections/stid/__init__.py +0 -0
  137. {isar-1.30.2 → isar-1.30.3}/src/isar/services/utilities/__init__.py +0 -0
  138. {isar-1.30.2 → isar-1.30.3}/src/isar/services/utilities/queue_utilities.py +0 -0
  139. {isar-1.30.2 → isar-1.30.3}/src/isar/services/utilities/robot_utilities.py +0 -0
  140. {isar-1.30.2 → isar-1.30.3}/src/isar/services/utilities/scheduling_utilities.py +0 -0
  141. {isar-1.30.2 → isar-1.30.3}/src/isar/services/utilities/threaded_request.py +0 -0
  142. {isar-1.30.2 → isar-1.30.3}/src/isar/state_machine/__init__.py +0 -0
  143. {isar-1.30.2 → isar-1.30.3}/src/isar/state_machine/states/__init__.py +0 -0
  144. {isar-1.30.2 → isar-1.30.3}/src/isar/state_machine/states/stopping.py +0 -0
  145. {isar-1.30.2 → isar-1.30.3}/src/isar/state_machine/states/unknown_status.py +0 -0
  146. {isar-1.30.2 → isar-1.30.3}/src/isar/state_machine/states_enum.py +0 -0
  147. {isar-1.30.2 → isar-1.30.3}/src/isar/state_machine/transitions/functions/fail_mission.py +0 -0
  148. {isar-1.30.2 → isar-1.30.3}/src/isar/state_machine/transitions/functions/finish_mission.py +0 -0
  149. {isar-1.30.2 → isar-1.30.3}/src/isar/state_machine/transitions/functions/pause.py +0 -0
  150. {isar-1.30.2 → isar-1.30.3}/src/isar/state_machine/transitions/functions/resume.py +0 -0
  151. {isar-1.30.2 → isar-1.30.3}/src/isar/state_machine/transitions/functions/return_home.py +0 -0
  152. {isar-1.30.2 → isar-1.30.3}/src/isar/state_machine/transitions/functions/robot_status.py +0 -0
  153. {isar-1.30.2 → isar-1.30.3}/src/isar/state_machine/transitions/functions/start_mission.py +0 -0
  154. {isar-1.30.2 → isar-1.30.3}/src/isar/state_machine/transitions/functions/stop.py +0 -0
  155. {isar-1.30.2 → isar-1.30.3}/src/isar/state_machine/transitions/functions/utils.py +0 -0
  156. {isar-1.30.2 → isar-1.30.3}/src/isar/state_machine/transitions/return_home.py +0 -0
  157. {isar-1.30.2 → isar-1.30.3}/src/isar/state_machine/transitions/robot_status.py +0 -0
  158. {isar-1.30.2 → isar-1.30.3}/src/isar/storage/__init__.py +0 -0
  159. {isar-1.30.2 → isar-1.30.3}/src/isar/storage/blob_storage.py +0 -0
  160. {isar-1.30.2 → isar-1.30.3}/src/isar/storage/local_storage.py +0 -0
  161. {isar-1.30.2 → isar-1.30.3}/src/isar/storage/storage_interface.py +0 -0
  162. {isar-1.30.2 → isar-1.30.3}/src/isar/storage/uploader.py +0 -0
  163. {isar-1.30.2 → isar-1.30.3}/src/isar/storage/utilities.py +0 -0
  164. {isar-1.30.2 → isar-1.30.3}/src/isar.egg-info/dependency_links.txt +0 -0
  165. {isar-1.30.2 → isar-1.30.3}/src/isar.egg-info/entry_points.txt +0 -0
  166. {isar-1.30.2 → isar-1.30.3}/src/isar.egg-info/requires.txt +0 -0
  167. {isar-1.30.2 → isar-1.30.3}/src/isar.egg-info/top_level.txt +0 -0
  168. {isar-1.30.2 → isar-1.30.3}/src/robot_interface/__init__.py +0 -0
  169. {isar-1.30.2 → isar-1.30.3}/src/robot_interface/models/__init__.py +0 -0
  170. {isar-1.30.2 → isar-1.30.3}/src/robot_interface/models/exceptions/__init__.py +0 -0
  171. {isar-1.30.2 → isar-1.30.3}/src/robot_interface/models/exceptions/robot_exceptions.py +0 -0
  172. {isar-1.30.2 → isar-1.30.3}/src/robot_interface/models/initialize/__init__.py +0 -0
  173. {isar-1.30.2 → isar-1.30.3}/src/robot_interface/models/inspection/__init__.py +0 -0
  174. {isar-1.30.2 → isar-1.30.3}/src/robot_interface/models/inspection/inspection.py +0 -0
  175. {isar-1.30.2 → isar-1.30.3}/src/robot_interface/models/mission/__init__.py +0 -0
  176. {isar-1.30.2 → isar-1.30.3}/src/robot_interface/models/mission/mission.py +0 -0
  177. {isar-1.30.2 → isar-1.30.3}/src/robot_interface/models/mission/status.py +0 -0
  178. {isar-1.30.2 → isar-1.30.3}/src/robot_interface/models/mission/task.py +0 -0
  179. {isar-1.30.2 → isar-1.30.3}/src/robot_interface/models/robots/__init__.py +0 -0
  180. {isar-1.30.2 → isar-1.30.3}/src/robot_interface/models/robots/battery_state.py +0 -0
  181. {isar-1.30.2 → isar-1.30.3}/src/robot_interface/models/robots/media.py +0 -0
  182. {isar-1.30.2 → isar-1.30.3}/src/robot_interface/models/robots/robot_model.py +0 -0
  183. {isar-1.30.2 → isar-1.30.3}/src/robot_interface/telemetry/__init__.py +0 -0
  184. {isar-1.30.2 → isar-1.30.3}/src/robot_interface/telemetry/mqtt_client.py +0 -0
  185. {isar-1.30.2 → isar-1.30.3}/src/robot_interface/telemetry/payloads.py +0 -0
  186. {isar-1.30.2 → isar-1.30.3}/src/robot_interface/test_robot_interface.py +0 -0
  187. {isar-1.30.2 → isar-1.30.3}/src/robot_interface/utilities/__init__.py +0 -0
  188. {isar-1.30.2 → isar-1.30.3}/src/robot_interface/utilities/json_service.py +0 -0
  189. {isar-1.30.2 → isar-1.30.3}/src/robot_interface/utilities/uuid_string_factory.py +0 -0
  190. {isar-1.30.2 → isar-1.30.3}/tests/__init__.py +0 -0
  191. {isar-1.30.2 → isar-1.30.3}/tests/integration/__init__.py +0 -0
  192. {isar-1.30.2 → isar-1.30.3}/tests/integration/turtlebot/__init__.py +0 -0
  193. {isar-1.30.2 → isar-1.30.3}/tests/integration/turtlebot/config/__init__.py +0 -0
  194. {isar-1.30.2 → isar-1.30.3}/tests/integration/turtlebot/config/maps/__init__.py +0 -0
  195. {isar-1.30.2 → isar-1.30.3}/tests/integration/turtlebot/config/maps/turtleworld.json +0 -0
  196. {isar-1.30.2 → isar-1.30.3}/tests/integration/turtlebot/config/missions/__init__.py +0 -0
  197. {isar-1.30.2 → isar-1.30.3}/tests/integration/turtlebot/config/missions/default.json +0 -0
  198. {isar-1.30.2 → isar-1.30.3}/tests/integration/turtlebot/test_successful_mission.py +0 -0
  199. {isar-1.30.2 → isar-1.30.3}/tests/isar/__init__.py +0 -0
  200. {isar-1.30.2 → isar-1.30.3}/tests/isar/apis/__init__.py +0 -0
  201. {isar-1.30.2 → isar-1.30.3}/tests/isar/apis/models/__init__.py +0 -0
  202. {isar-1.30.2 → isar-1.30.3}/tests/isar/apis/models/example_mission_definition.json +0 -0
  203. {isar-1.30.2 → isar-1.30.3}/tests/isar/apis/models/test_start_mission_definition.py +0 -0
  204. {isar-1.30.2 → isar-1.30.3}/tests/isar/apis/scheduler/__init__.py +0 -0
  205. {isar-1.30.2 → isar-1.30.3}/tests/isar/apis/security/__init__.py +0 -0
  206. {isar-1.30.2 → isar-1.30.3}/tests/isar/mission/__init__.py +0 -0
  207. {isar-1.30.2 → isar-1.30.3}/tests/isar/mission/test_mission.py +0 -0
  208. {isar-1.30.2 → isar-1.30.3}/tests/isar/models/__init__.py +0 -0
  209. {isar-1.30.2 → isar-1.30.3}/tests/isar/models/communication/__init__.py +0 -0
  210. {isar-1.30.2 → isar-1.30.3}/tests/isar/models/communication/test_queues.py +0 -0
  211. {isar-1.30.2 → isar-1.30.3}/tests/isar/services/__init__.py +0 -0
  212. {isar-1.30.2 → isar-1.30.3}/tests/isar/services/readers/__init__.py +0 -0
  213. {isar-1.30.2 → isar-1.30.3}/tests/isar/services/readers/test_mission_reader.py +0 -0
  214. {isar-1.30.2 → isar-1.30.3}/tests/isar/services/service_connections/__init__.py +0 -0
  215. {isar-1.30.2 → isar-1.30.3}/tests/isar/services/service_connections/echo/__init__.py +0 -0
  216. {isar-1.30.2 → isar-1.30.3}/tests/isar/services/service_connections/test_base_request_handler.py +0 -0
  217. {isar-1.30.2 → isar-1.30.3}/tests/isar/services/utilities/__init__.py +0 -0
  218. {isar-1.30.2 → isar-1.30.3}/tests/isar/services/utilities/test_queue_utilities.py +0 -0
  219. {isar-1.30.2 → isar-1.30.3}/tests/isar/state_machine/__init__.py +0 -0
  220. {isar-1.30.2 → isar-1.30.3}/tests/isar/state_machine/states/__init__.py +0 -0
  221. {isar-1.30.2 → isar-1.30.3}/tests/isar/storage/test_blob_storage.py +0 -0
  222. {isar-1.30.2 → isar-1.30.3}/tests/test_data/test_map_config/test_map_config.json +0 -0
  223. {isar-1.30.2 → isar-1.30.3}/tests/test_data/test_mission_not_working.json +0 -0
  224. {isar-1.30.2 → isar-1.30.3}/tests/test_data/test_mission_working.json +0 -0
  225. {isar-1.30.2 → isar-1.30.3}/tests/test_data/test_mission_working_no_tasks.json +0 -0
  226. {isar-1.30.2 → isar-1.30.3}/tests/test_data/test_thermal_image_mission.json +0 -0
  227. {isar-1.30.2/tests/mocks → isar-1.30.3/tests/test_double}/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: isar
3
- Version: 1.30.2
3
+ Version: 1.30.3
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
@@ -4,7 +4,7 @@
4
4
  #
5
5
  # pip-compile --output-file=requirements.txt pyproject.toml
6
6
  #
7
- alitra==1.1.3
7
+ alitra==1.1.5
8
8
  # via isar (pyproject.toml)
9
9
  annotated-types==0.7.0
10
10
  # via pydantic
@@ -12,7 +12,7 @@ anyio==4.9.0
12
12
  # via
13
13
  # httpx
14
14
  # starlette
15
- azure-core==1.34.0
15
+ azure-core==1.35.0
16
16
  # via
17
17
  # azure-identity
18
18
  # azure-keyvault-secrets
@@ -43,7 +43,7 @@ click==8.2.1
43
43
  # via
44
44
  # isar (pyproject.toml)
45
45
  # uvicorn
46
- cryptography==45.0.4
46
+ cryptography==45.0.5
47
47
  # via
48
48
  # azure-identity
49
49
  # azure-storage-blob
@@ -54,9 +54,9 @@ dacite==1.9.2
54
54
  # via
55
55
  # alitra
56
56
  # isar (pyproject.toml)
57
- dependency-injector==4.48.0
57
+ dependency-injector==4.48.1
58
58
  # via isar (pyproject.toml)
59
- fastapi==0.115.13
59
+ fastapi==0.115.14
60
60
  # via
61
61
  # fastapi-azure-auth
62
62
  # isar (pyproject.toml)
@@ -91,7 +91,7 @@ msal==1.32.3
91
91
  # msal-extensions
92
92
  msal-extensions==1.3.1
93
93
  # via azure-identity
94
- numpy==2.3.0
94
+ numpy==2.3.1
95
95
  # via
96
96
  # alitra
97
97
  # isar (pyproject.toml)
@@ -135,14 +135,14 @@ pydantic==2.11.7
135
135
  # pydantic-settings
136
136
  pydantic-core==2.33.2
137
137
  # via pydantic
138
- pydantic-settings==2.9.1
138
+ pydantic-settings==2.10.1
139
139
  # via isar (pyproject.toml)
140
140
  pyjwt[crypto]==2.10.1
141
141
  # via
142
142
  # fastapi-azure-auth
143
143
  # isar (pyproject.toml)
144
144
  # msal
145
- python-dotenv==1.1.0
145
+ python-dotenv==1.1.1
146
146
  # via
147
147
  # isar (pyproject.toml)
148
148
  # pydantic-settings
@@ -161,7 +161,7 @@ requests-toolbelt==1.0.0
161
161
  # via isar (pyproject.toml)
162
162
  rsa==4.9.1
163
163
  # via google-auth
164
- scipy==1.15.3
164
+ scipy==1.16.0
165
165
  # via alitra
166
166
  six==1.17.0
167
167
  # via
@@ -172,7 +172,7 @@ sniffio==1.3.1
172
172
  # via anyio
173
173
  starlette==0.46.2
174
174
  # via fastapi
175
- transitions==0.9.2
175
+ transitions==0.9.3
176
176
  # via isar (pyproject.toml)
177
177
  typing-extensions==4.14.0
178
178
  # via
@@ -188,9 +188,9 @@ typing-inspection==0.4.1
188
188
  # via
189
189
  # pydantic
190
190
  # pydantic-settings
191
- urllib3==2.4.0
191
+ urllib3==2.5.0
192
192
  # via requests
193
- uvicorn==0.34.3
193
+ uvicorn==0.35.0
194
194
  # via isar (pyproject.toml)
195
195
  wrapt==1.17.2
196
196
  # via opencensus-ext-requests
@@ -66,6 +66,7 @@ class Settings(BaseSettings):
66
66
  ROBOT_HEARTBEAT_PUBLISH_INTERVAL: float = Field(default=1)
67
67
  ROBOT_INFO_PUBLISH_INTERVAL: float = Field(default=5)
68
68
  ROBOT_API_STATUS_POLL_INTERVAL: float = Field(default=5)
69
+ THREAD_CHECK_INTERVAL: float = Field(default=0.01)
69
70
 
70
71
  # FastAPI host
71
72
  API_HOST_VIEWED_EXTERNALLY: str = Field(default="0.0.0.0")
@@ -40,6 +40,18 @@ class RobotStartMissionThread(Thread):
40
40
  return
41
41
  try:
42
42
  self.robot.initiate_mission(self.mission)
43
+ except RobotInfeasibleMissionException as e:
44
+ self.logger.error(
45
+ f"Mission is infeasible and cannot be scheduled because: {e.error_description}"
46
+ )
47
+ trigger_event(
48
+ self.robot_service_events.mission_failed,
49
+ ErrorMessage(
50
+ error_reason=e.error_reason,
51
+ error_description=e.error_description,
52
+ ),
53
+ )
54
+ break
43
55
  except RobotException as e:
44
56
  retries += 1
45
57
  self.logger.warning(
@@ -40,14 +40,16 @@ class RobotStatusThread(Thread):
40
40
  if self.signal_thread_quitting.is_set():
41
41
  return
42
42
 
43
- while not self.signal_thread_quitting.wait(0.001):
43
+ thread_check_interval = settings.THREAD_CHECK_INTERVAL
44
+
45
+ while not self.signal_thread_quitting.wait(thread_check_interval):
44
46
  if not self._is_ready_to_poll_for_status():
45
47
  continue
46
48
  try:
47
- robot_status = self.robot.robot_status()
49
+ self.last_robot_status_poll_time = time.time()
48
50
 
51
+ robot_status = self.robot.robot_status()
49
52
  update_shared_state(self.shared_state.robot_status, robot_status)
50
- self.last_robot_status_poll_time = time.time()
51
53
  except RobotException as e:
52
54
  self.logger.error(f"Failed to retrieve robot status: {e}")
53
55
  continue
@@ -1,10 +1,10 @@
1
1
  import logging
2
2
  import time
3
+ from enum import Enum
3
4
  from queue import Queue
4
5
  from typing import TYPE_CHECKING, Optional
5
6
 
6
- from transitions import State
7
-
7
+ from isar.config.settings import settings
8
8
  from isar.models.communication.message import StartMissionMessage
9
9
  from isar.models.communication.queues.queue_io import QueueIO
10
10
  from isar.models.communication.queues.queue_utils import (
@@ -18,30 +18,41 @@ if TYPE_CHECKING:
18
18
  from isar.state_machine.state_machine import StateMachine
19
19
 
20
20
 
21
- class RobotStandingStill(State):
22
- def __init__(self, state_machine: "StateMachine") -> None:
23
- super().__init__(
24
- name="robot_standing_still", on_enter=self.start, on_exit=self.stop
25
- )
21
+ class IdleStates(str, Enum):
22
+ AwaitNextMission = "awaitNextMission"
23
+ Home = "home"
24
+ RobotStandingStill = "robotStandingStill"
25
+
26
+
27
+ if TYPE_CHECKING:
28
+ from isar.state_machine.state_machine import StateMachine
29
+
30
+
31
+ class Idle:
32
+ def __init__(
33
+ self,
34
+ state_machine: "StateMachine",
35
+ state: IdleStates,
36
+ ) -> None:
26
37
  self.state_machine: "StateMachine" = state_machine
27
38
  self.logger = logging.getLogger("state_machine")
28
- self.events = self.state_machine.events
39
+ self.events = state_machine.events
29
40
  self.shared_state = self.state_machine.shared_state
30
41
  self.signal_state_machine_to_stop = state_machine.signal_state_machine_to_stop
42
+ self.state: IdleStates = state
43
+
44
+ # Only used for await_next_mission state
45
+ self.entered_time: float = time.time()
46
+ self.return_home_delay: float = settings.RETURN_HOME_DELAY
31
47
 
32
48
  def start(self) -> None:
33
49
  self.state_machine.update_state()
50
+ self.entered_time = time.time()
34
51
  self._run()
35
52
 
36
53
  def stop(self) -> None:
37
54
  return
38
55
 
39
- def _check_and_handle_stop_mission_event(self, event: Queue) -> bool:
40
- if check_for_event(event):
41
- self.state_machine.stop() # type: ignore
42
- return True
43
- return False
44
-
45
56
  def _check_and_handle_start_mission_event(
46
57
  self, event: Queue[StartMissionMessage]
47
58
  ) -> bool:
@@ -63,17 +74,32 @@ class RobotStandingStill(State):
63
74
  self, event: StatusQueue[RobotStatus]
64
75
  ) -> bool:
65
76
  robot_status: RobotStatus = check_shared_state(event)
66
- if robot_status != RobotStatus.Available:
77
+
78
+ expected_robot_status = (
79
+ RobotStatus.Home if self.state == IdleStates.Home else RobotStatus.Available
80
+ )
81
+
82
+ if robot_status != expected_robot_status:
67
83
  self.state_machine.robot_status_changed() # type: ignore
68
84
  return True
69
85
 
70
86
  return False
71
87
 
88
+ def _check_and_handle_stop_mission_event(self, event: Queue) -> bool:
89
+ if check_for_event(event):
90
+ self.state_machine.stop() # type: ignore
91
+ return True
92
+ return False
93
+
94
+ def _should_return_home(self) -> bool:
95
+ time_since_entered = time.time() - self.entered_time
96
+ return time_since_entered > self.return_home_delay
97
+
72
98
  def _run(self) -> None:
73
99
  while True:
74
100
  if self.signal_state_machine_to_stop.is_set():
75
101
  self.logger.info(
76
- "Stopping state machine from %s state", self.__class__.__name__
102
+ "Stopping state machine from %s state", self.state.name
77
103
  )
78
104
  break
79
105
 
@@ -92,9 +118,16 @@ class RobotStandingStill(State):
92
118
  ):
93
119
  break
94
120
 
95
- if self._check_and_handle_robot_status_event(
96
- self.shared_state.robot_status
121
+ if (
122
+ self.state != IdleStates.AwaitNextMission
123
+ and self._check_and_handle_robot_status_event(
124
+ self.shared_state.robot_status
125
+ )
97
126
  ):
98
127
  break
99
128
 
129
+ if self.state == IdleStates.AwaitNextMission and self._should_return_home():
130
+ self.state_machine.request_return_home() # type: ignore
131
+ break
132
+
100
133
  time.sleep(self.state_machine.sleep_time)
@@ -1,15 +1,18 @@
1
1
  import logging
2
2
  import time
3
3
  from copy import deepcopy
4
+ from enum import Enum
4
5
  from queue import Queue
5
6
  from threading import Event
6
7
  from typing import TYPE_CHECKING, Optional, Tuple
7
8
 
8
- from dependency_injector.wiring import inject
9
- from transitions import State
10
-
11
9
  from isar.config.settings import settings
12
- from isar.models.communication.queues.queue_utils import check_for_event, trigger_event
10
+ from isar.models.communication.message import StartMissionMessage
11
+ from isar.models.communication.queues.queue_utils import (
12
+ check_for_event,
13
+ check_for_event_without_consumption,
14
+ trigger_event,
15
+ )
13
16
  from isar.services.utilities.threaded_request import ThreadedRequest
14
17
  from robot_interface.models.exceptions.robot_exceptions import (
15
18
  ErrorMessage,
@@ -21,24 +24,30 @@ from robot_interface.models.mission.mission import Mission
21
24
  from robot_interface.models.mission.status import TaskStatus
22
25
  from robot_interface.models.mission.task import InspectionTask, Task
23
26
 
27
+
28
+ class OngoingMissionStates(str, Enum):
29
+ Monitor = "monitor"
30
+ ReturningHome = "returningHome"
31
+
32
+
24
33
  if TYPE_CHECKING:
25
34
  from isar.state_machine.state_machine import StateMachine
26
35
 
27
36
 
28
- class Monitor(State):
29
- @inject
30
- def __init__(self, state_machine: "StateMachine") -> None:
31
- super().__init__(name="monitor", on_enter=self.start, on_exit=self.stop)
37
+ class OngoingMission:
38
+ def __init__(
39
+ self,
40
+ state_machine: "StateMachine",
41
+ state: OngoingMissionStates,
42
+ ) -> None:
32
43
  self.state_machine: "StateMachine" = state_machine
33
-
34
44
  self.logger = logging.getLogger("state_machine")
35
- self.events = self.state_machine.events
36
-
45
+ self.events = state_machine.events
37
46
  self.awaiting_task_status: bool = False
38
-
39
47
  self.signal_state_machine_to_stop: Event = (
40
48
  state_machine.signal_state_machine_to_stop
41
49
  )
50
+ self.state: OngoingMissionStates = state
42
51
 
43
52
  def start(self) -> None:
44
53
  self.state_machine.update_state()
@@ -46,7 +55,6 @@ class Monitor(State):
46
55
 
47
56
  def stop(self) -> None:
48
57
  self.state_machine.mission_ongoing = False
49
- return
50
58
 
51
59
  def _check_and_handle_stop_mission_event(self, event: Queue) -> bool:
52
60
  if check_for_event(event):
@@ -60,9 +68,11 @@ class Monitor(State):
60
68
  return True
61
69
  return False
62
70
 
63
- def _check_and_handle_mission_started_event(self, event: Queue) -> None:
71
+ def _check_and_handle_mission_started_event(self, event: Queue) -> bool:
64
72
  if check_for_event(event):
65
73
  self.state_machine.mission_ongoing = True
74
+ return True
75
+ return False
66
76
 
67
77
  def _check_and_handle_mission_failed_event(self, event: Queue) -> bool:
68
78
  mission_failed: Optional[ErrorMessage] = check_for_event(event)
@@ -76,7 +86,6 @@ class Monitor(State):
76
86
  error_reason=mission_failed.error_reason,
77
87
  error_description=mission_failed.error_description,
78
88
  )
79
-
80
89
  self.state_machine.mission_failed_to_start() # type: ignore
81
90
  return True
82
91
  return False
@@ -124,18 +133,27 @@ class Monitor(State):
124
133
 
125
134
  self.state_machine.current_task.status = status
126
135
 
127
- if self._should_upload_inspections():
128
- get_inspection_thread = ThreadedRequest(self._queue_inspections_for_upload)
129
- get_inspection_thread.start_thread(
130
- deepcopy(self.state_machine.current_mission),
131
- deepcopy(self.state_machine.current_task),
132
- name="State Machine Get Inspections",
133
- )
134
-
135
136
  if self.state_machine.current_task.is_finished():
136
137
  self._report_task_status(self.state_machine.current_task)
137
138
  self.state_machine.publish_task_status(task=self.state_machine.current_task)
138
139
 
140
+ if self.state == OngoingMissionStates.ReturningHome:
141
+ if status != TaskStatus.Successful:
142
+ self.state_machine.return_home_failed() # type: ignore
143
+ return True
144
+ self.state_machine.returned_home() # type: ignore
145
+ return True
146
+
147
+ if self._should_upload_inspections():
148
+ get_inspection_thread = ThreadedRequest(
149
+ self._queue_inspections_for_upload
150
+ )
151
+ get_inspection_thread.start_thread(
152
+ deepcopy(self.state_machine.current_mission),
153
+ deepcopy(self.state_machine.current_task),
154
+ name="State Machine Get Inspections",
155
+ )
156
+
139
157
  self.state_machine.iterate_current_task()
140
158
  if self.state_machine.current_task is None:
141
159
  self.state_machine.mission_finished() # type: ignore
@@ -146,12 +164,21 @@ class Monitor(State):
146
164
  self.state_machine.publish_task_status(task=self.state_machine.current_task)
147
165
  return False
148
166
 
167
+ def _check_and_handle_start_mission_event(
168
+ self, event: Queue[StartMissionMessage]
169
+ ) -> bool:
170
+ if check_for_event_without_consumption(event):
171
+ self.state_machine.stop() # type: ignore
172
+ return True
173
+
174
+ return False
175
+
149
176
  def _run(self) -> None:
150
177
  self.awaiting_task_status = False
151
178
  while True:
152
179
  if self.signal_state_machine_to_stop.is_set():
153
180
  self.logger.info(
154
- "Stopping state machine from %s state", self.__class__.__name__
181
+ "Stopping state machine from %s state", self.state.name
155
182
  )
156
183
  break
157
184
 
@@ -160,8 +187,11 @@ class Monitor(State):
160
187
  ):
161
188
  break
162
189
 
163
- if self._check_and_handle_pause_mission_event(
164
- self.events.api_requests.pause_mission.input
190
+ if (
191
+ self.state == OngoingMissionStates.Monitor
192
+ and self._check_and_handle_pause_mission_event(
193
+ self.events.api_requests.pause_mission.input
194
+ )
165
195
  ):
166
196
  break
167
197
 
@@ -174,6 +204,14 @@ class Monitor(State):
174
204
  ):
175
205
  break
176
206
 
207
+ if (
208
+ self.state == OngoingMissionStates.ReturningHome
209
+ and self._check_and_handle_start_mission_event(
210
+ self.events.api_requests.start_mission.input
211
+ )
212
+ ):
213
+ break
214
+
177
215
  if self._check_and_handle_task_status_failed_event(
178
216
  self.events.robot_service_events.task_status_failed
179
217
  ):
@@ -1,23 +1,32 @@
1
1
  import logging
2
2
  import time
3
+ from enum import Enum
3
4
  from typing import TYPE_CHECKING
4
5
 
5
- from transitions import State
6
-
7
6
  from isar.models.communication.queues.queue_utils import check_shared_state
8
7
  from robot_interface.models.mission.status import RobotStatus
9
8
 
9
+
10
+ class RobotUnavailableStates(str, Enum):
11
+ BlockedProtectiveStop = "blockedProtectiveStop"
12
+ Offline = "offline"
13
+
14
+
10
15
  if TYPE_CHECKING:
11
16
  from isar.state_machine.state_machine import StateMachine
12
17
 
13
18
 
14
- class Offline(State):
15
- def __init__(self, state_machine: "StateMachine") -> None:
16
- super().__init__(name="offline", on_enter=self.start, on_exit=self.stop)
19
+ class RobotUnavailable:
20
+ def __init__(
21
+ self,
22
+ state_machine: "StateMachine",
23
+ state: RobotUnavailableStates,
24
+ ) -> None:
17
25
  self.state_machine: "StateMachine" = state_machine
18
26
  self.logger = logging.getLogger("state_machine")
19
27
  self.shared_state = self.state_machine.shared_state
20
28
  self.signal_state_machine_to_stop = state_machine.signal_state_machine_to_stop
29
+ self.state: RobotUnavailableStates = state
21
30
 
22
31
  def start(self) -> None:
23
32
  self.state_machine.update_state()
@@ -30,7 +39,7 @@ class Offline(State):
30
39
  while True:
31
40
  if self.signal_state_machine_to_stop.is_set():
32
41
  self.logger.info(
33
- "Stopping state machine from %s state", self.__class__.__name__
42
+ "Stopping state machine from %s state", self.state.name
34
43
  )
35
44
  break
36
45
 
@@ -38,7 +47,12 @@ class Offline(State):
38
47
  self.shared_state.robot_status
39
48
  )
40
49
 
41
- if robot_status != RobotStatus.Offline:
50
+ expected_status = (
51
+ RobotStatus.BlockedProtectiveStop
52
+ if self.state == RobotUnavailableStates.BlockedProtectiveStop
53
+ else RobotStatus.Offline
54
+ )
55
+ if robot_status != expected_status:
42
56
  transition = self.state_machine.robot_status_changed # type: ignore
43
57
  break
44
58
 
@@ -168,6 +168,9 @@ class StateMachine(object):
168
168
  self.signal_state_machine_to_stop.set()
169
169
 
170
170
  def iterate_current_task(self):
171
+ if self.current_task is None:
172
+ raise ValueError("No current task is set")
173
+
171
174
  if self.current_task.is_finished():
172
175
  try:
173
176
  self.current_task = self.task_selector.next_task()
@@ -313,6 +316,12 @@ class StateMachine(object):
313
316
  self.logger.info("Mission overview:\n%s", log_statement)
314
317
 
315
318
  def _make_control_mission_response(self) -> ControlMissionResponse:
319
+ if self.current_mission is None:
320
+ raise ValueError("No current mission is set")
321
+
322
+ if self.current_task is None:
323
+ raise ValueError("No current task is set")
324
+
316
325
  return ControlMissionResponse(
317
326
  mission_id=self.current_mission.id,
318
327
  mission_status=self.current_mission.status,
@@ -0,0 +1,20 @@
1
+ from typing import TYPE_CHECKING
2
+
3
+ from transitions import State
4
+
5
+ if TYPE_CHECKING:
6
+ from isar.state_machine.state_machine import StateMachine
7
+
8
+ from isar.state_machine.generic_states.idle import Idle, IdleStates
9
+
10
+
11
+ class AwaitNextMission(State, Idle):
12
+ def __init__(self, state_machine: "StateMachine") -> None:
13
+ State.__init__(
14
+ self, name="await_next_mission", on_enter=self.start, on_exit=self.stop
15
+ )
16
+ Idle.__init__(
17
+ self,
18
+ state_machine=state_machine,
19
+ state=IdleStates.AwaitNextMission,
20
+ )
@@ -0,0 +1,24 @@
1
+ from typing import TYPE_CHECKING
2
+
3
+ from transitions import State
4
+
5
+ from isar.state_machine.generic_states.robot_unavailable import (
6
+ RobotUnavailable,
7
+ RobotUnavailableStates,
8
+ )
9
+
10
+ if TYPE_CHECKING:
11
+ from isar.state_machine.state_machine import StateMachine
12
+
13
+
14
+ class BlockedProtectiveStop(State, RobotUnavailable):
15
+ def __init__(self, state_machine: "StateMachine") -> None:
16
+ State.__init__(
17
+ self, name="blocked_protective_stop", on_enter=self.start, on_exit=self.stop
18
+ )
19
+
20
+ RobotUnavailable.__init__(
21
+ self,
22
+ state_machine=state_machine,
23
+ state=RobotUnavailableStates.BlockedProtectiveStop,
24
+ )
@@ -0,0 +1,19 @@
1
+ from typing import TYPE_CHECKING
2
+
3
+ from transitions import State
4
+
5
+ if TYPE_CHECKING:
6
+ from isar.state_machine.state_machine import StateMachine
7
+
8
+ from isar.state_machine.generic_states.idle import Idle, IdleStates
9
+
10
+
11
+ class Home(State, Idle):
12
+ def __init__(self, state_machine: "StateMachine") -> None:
13
+ State.__init__(self, name="home", on_enter=self.start, on_exit=self.stop)
14
+
15
+ Idle.__init__(
16
+ self,
17
+ state_machine=state_machine,
18
+ state=IdleStates.Home,
19
+ )
@@ -0,0 +1,24 @@
1
+ from typing import TYPE_CHECKING
2
+
3
+ from dependency_injector.wiring import inject
4
+ from transitions import State
5
+
6
+ from isar.state_machine.generic_states.ongoing_mission import (
7
+ OngoingMission,
8
+ OngoingMissionStates,
9
+ )
10
+
11
+ if TYPE_CHECKING:
12
+ from isar.state_machine.state_machine import StateMachine
13
+
14
+
15
+ class Monitor(State, OngoingMission):
16
+ @inject
17
+ def __init__(self, state_machine: "StateMachine") -> None:
18
+ State.__init__(self, name="monitor", on_enter=self.start, on_exit=self.stop)
19
+
20
+ OngoingMission.__init__(
21
+ self,
22
+ state_machine=state_machine,
23
+ state=OngoingMissionStates.Monitor,
24
+ )
@@ -0,0 +1,22 @@
1
+ from typing import TYPE_CHECKING
2
+
3
+ from transitions import State
4
+
5
+ from isar.state_machine.generic_states.robot_unavailable import (
6
+ RobotUnavailable,
7
+ RobotUnavailableStates,
8
+ )
9
+
10
+ if TYPE_CHECKING:
11
+ from isar.state_machine.state_machine import StateMachine
12
+
13
+
14
+ class Offline(State, RobotUnavailable):
15
+ def __init__(self, state_machine: "StateMachine") -> None:
16
+ State.__init__(self, name="offline", on_enter=self.start, on_exit=self.stop)
17
+
18
+ RobotUnavailable.__init__(
19
+ self,
20
+ state_machine=state_machine,
21
+ state=RobotUnavailableStates.Offline,
22
+ )
@@ -31,7 +31,7 @@ class Paused(State):
31
31
  )
32
32
  break
33
33
 
34
- if check_for_event(self.events.api_requests.pause_mission.input):
34
+ if check_for_event(self.events.api_requests.stop_mission.input):
35
35
  transition = self.state_machine.stop # type: ignore
36
36
  break
37
37
 
@@ -0,0 +1,24 @@
1
+ from typing import TYPE_CHECKING
2
+
3
+ from transitions import State
4
+
5
+ from isar.state_machine.generic_states.ongoing_mission import (
6
+ OngoingMission,
7
+ OngoingMissionStates,
8
+ )
9
+
10
+ if TYPE_CHECKING:
11
+ from isar.state_machine.state_machine import StateMachine
12
+
13
+
14
+ class ReturningHome(State, OngoingMission):
15
+ def __init__(self, state_machine: "StateMachine") -> None:
16
+ State.__init__(
17
+ self, name="returning_home", on_enter=self.start, on_exit=self.stop
18
+ )
19
+
20
+ OngoingMission.__init__(
21
+ self,
22
+ state_machine=state_machine,
23
+ state=OngoingMissionStates.ReturningHome,
24
+ )