isar 1.24.1__tar.gz → 1.24.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 (206) hide show
  1. {isar-1.24.1 → isar-1.24.3}/PKG-INFO +1 -1
  2. {isar-1.24.1 → isar-1.24.3}/src/isar/apis/api.py +21 -1
  3. {isar-1.24.1 → isar-1.24.3}/src/isar/apis/models/models.py +9 -0
  4. isar-1.24.3/src/isar/apis/robot_control/robot_controller.py +35 -0
  5. {isar-1.24.1 → isar-1.24.3}/src/isar/apis/schedule/scheduling_controller.py +2 -18
  6. {isar-1.24.1 → isar-1.24.3}/src/isar/modules.py +22 -3
  7. isar-1.24.3/src/isar/services/utilities/robot_utilities.py +23 -0
  8. {isar-1.24.1 → isar-1.24.3}/src/isar/state_machine/state_machine.py +21 -6
  9. {isar-1.24.1 → isar-1.24.3}/src/isar/state_machine/states/idle.py +3 -0
  10. {isar-1.24.1 → isar-1.24.3}/src/isar/state_machine/states/monitor.py +11 -7
  11. {isar-1.24.1 → isar-1.24.3}/src/isar.egg-info/PKG-INFO +1 -1
  12. {isar-1.24.1 → isar-1.24.3}/src/isar.egg-info/SOURCES.txt +3 -1
  13. {isar-1.24.1 → isar-1.24.3}/src/robot_interface/robot_interface.py +14 -0
  14. {isar-1.24.1 → isar-1.24.3}/src/robot_interface/telemetry/payloads.py +0 -8
  15. {isar-1.24.1 → isar-1.24.3}/tests/conftest.py +3 -3
  16. {isar-1.24.1 → isar-1.24.3}/tests/integration/turtlebot/test_successful_mission.py +2 -2
  17. {isar-1.24.1 → isar-1.24.3}/tests/isar/apis/scheduler/test_scheduler_router.py +1 -8
  18. {isar-1.24.1 → isar-1.24.3}/tests/mocks/robot_interface.py +9 -0
  19. {isar-1.24.1 → isar-1.24.3}/.dockerignore +0 -0
  20. {isar-1.24.1 → isar-1.24.3}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  21. {isar-1.24.1 → isar-1.24.3}/.github/ISSUE_TEMPLATE/feature.md +0 -0
  22. {isar-1.24.1 → isar-1.24.3}/.github/ISSUE_TEMPLATE/improvement.md +0 -0
  23. {isar-1.24.1 → isar-1.24.3}/.github/release.yml +0 -0
  24. {isar-1.24.1 → isar-1.24.3}/.github/workflows/compile_requirements.yml +0 -0
  25. {isar-1.24.1 → isar-1.24.3}/.github/workflows/project_automations.yml +0 -0
  26. {isar-1.24.1 → isar-1.24.3}/.github/workflows/publish_isar_base_image.yml +0 -0
  27. {isar-1.24.1 → isar-1.24.3}/.github/workflows/pythonpackage.yml +0 -0
  28. {isar-1.24.1 → isar-1.24.3}/.github/workflows/pythonpublish.yml +0 -0
  29. {isar-1.24.1 → isar-1.24.3}/.github/workflows/stale.yml +0 -0
  30. {isar-1.24.1 → isar-1.24.3}/.gitignore +0 -0
  31. {isar-1.24.1 → isar-1.24.3}/.pre-commit-config.yaml +0 -0
  32. {isar-1.24.1 → isar-1.24.3}/Dockerfile +0 -0
  33. {isar-1.24.1 → isar-1.24.3}/LICENSE +0 -0
  34. {isar-1.24.1 → isar-1.24.3}/README.md +0 -0
  35. {isar-1.24.1 → isar-1.24.3}/SECURITY.md +0 -0
  36. {isar-1.24.1 → isar-1.24.3}/docker-compose-turtlebot.yml +0 -0
  37. {isar-1.24.1 → isar-1.24.3}/docker-compose.yml +0 -0
  38. {isar-1.24.1 → isar-1.24.3}/docs/Makefile +0 -0
  39. {isar-1.24.1 → isar-1.24.3}/docs/make.bat +0 -0
  40. {isar-1.24.1 → isar-1.24.3}/docs/rst_processing.py +0 -0
  41. {isar-1.24.1 → isar-1.24.3}/docs/source/conf.py +0 -0
  42. {isar-1.24.1 → isar-1.24.3}/docs/source/index.rst +0 -0
  43. {isar-1.24.1 → isar-1.24.3}/docs/source/readme_link.md +0 -0
  44. {isar-1.24.1 → isar-1.24.3}/docs/state_machine_diagram.png +0 -0
  45. {isar-1.24.1 → isar-1.24.3}/main.py +0 -0
  46. {isar-1.24.1 → isar-1.24.3}/pyproject.toml +0 -0
  47. {isar-1.24.1 → isar-1.24.3}/radixconfig.yml +0 -0
  48. {isar-1.24.1 → isar-1.24.3}/requirements.txt +0 -0
  49. {isar-1.24.1 → isar-1.24.3}/setup.cfg +0 -0
  50. {isar-1.24.1 → isar-1.24.3}/src/isar/__init__.py +0 -0
  51. {isar-1.24.1 → isar-1.24.3}/src/isar/apis/__init__.py +0 -0
  52. {isar-1.24.1 → isar-1.24.3}/src/isar/apis/models/__init__.py +0 -0
  53. {isar-1.24.1/src/robot_interface/telemetry → isar-1.24.3/src/isar/apis/models}/media_connection_type.py +0 -0
  54. {isar-1.24.1 → isar-1.24.3}/src/isar/apis/models/start_mission_definition.py +0 -0
  55. {isar-1.24.1 → isar-1.24.3}/src/isar/apis/schedule/__init__.py +0 -0
  56. {isar-1.24.1 → isar-1.24.3}/src/isar/apis/security/__init__.py +0 -0
  57. {isar-1.24.1 → isar-1.24.3}/src/isar/apis/security/authentication.py +0 -0
  58. {isar-1.24.1 → isar-1.24.3}/src/isar/config/__init__.py +0 -0
  59. {isar-1.24.1 → isar-1.24.3}/src/isar/config/certs/ca-cert.pem +0 -0
  60. {isar-1.24.1 → isar-1.24.3}/src/isar/config/configuration_error.py +0 -0
  61. {isar-1.24.1 → isar-1.24.3}/src/isar/config/keyvault/__init__.py +0 -0
  62. {isar-1.24.1 → isar-1.24.3}/src/isar/config/keyvault/keyvault_error.py +0 -0
  63. {isar-1.24.1 → isar-1.24.3}/src/isar/config/keyvault/keyvault_service.py +0 -0
  64. {isar-1.24.1 → isar-1.24.3}/src/isar/config/log.py +0 -0
  65. {isar-1.24.1 → isar-1.24.3}/src/isar/config/logging.conf +0 -0
  66. {isar-1.24.1 → isar-1.24.3}/src/isar/config/maps/JSP1_intermediate_deck.json +0 -0
  67. {isar-1.24.1 → isar-1.24.3}/src/isar/config/maps/JSP1_weather_deck.json +0 -0
  68. {isar-1.24.1 → isar-1.24.3}/src/isar/config/maps/default_map.json +0 -0
  69. {isar-1.24.1 → isar-1.24.3}/src/isar/config/maps/klab_b.json +0 -0
  70. {isar-1.24.1 → isar-1.24.3}/src/isar/config/maps/klab_compressor.json +0 -0
  71. {isar-1.24.1 → isar-1.24.3}/src/isar/config/maps/klab_turtlebot.json +0 -0
  72. {isar-1.24.1 → isar-1.24.3}/src/isar/config/maps/turtleworld.json +0 -0
  73. {isar-1.24.1 → isar-1.24.3}/src/isar/config/predefined_mission_definition/__init__.py +0 -0
  74. {isar-1.24.1 → isar-1.24.3}/src/isar/config/predefined_mission_definition/default_exr.json +0 -0
  75. {isar-1.24.1 → isar-1.24.3}/src/isar/config/predefined_mission_definition/default_mission.json +0 -0
  76. {isar-1.24.1 → isar-1.24.3}/src/isar/config/predefined_mission_definition/default_turtlebot.json +0 -0
  77. {isar-1.24.1 → isar-1.24.3}/src/isar/config/predefined_missions/__init__.py +0 -0
  78. {isar-1.24.1 → isar-1.24.3}/src/isar/config/predefined_missions/default.json +0 -0
  79. {isar-1.24.1 → isar-1.24.3}/src/isar/config/predefined_missions/default_turtlebot.json +0 -0
  80. {isar-1.24.1 → isar-1.24.3}/src/isar/config/predefined_poses/__init__.py +0 -0
  81. {isar-1.24.1 → isar-1.24.3}/src/isar/config/predefined_poses/predefined_poses.py +0 -0
  82. {isar-1.24.1 → isar-1.24.3}/src/isar/config/settings.env +0 -0
  83. {isar-1.24.1 → isar-1.24.3}/src/isar/config/settings.py +0 -0
  84. {isar-1.24.1 → isar-1.24.3}/src/isar/mission_planner/__init__.py +0 -0
  85. {isar-1.24.1 → isar-1.24.3}/src/isar/mission_planner/local_planner.py +0 -0
  86. {isar-1.24.1 → isar-1.24.3}/src/isar/mission_planner/mission_planner_interface.py +0 -0
  87. {isar-1.24.1 → isar-1.24.3}/src/isar/mission_planner/sequential_task_selector.py +0 -0
  88. {isar-1.24.1 → isar-1.24.3}/src/isar/mission_planner/task_selector_interface.py +0 -0
  89. {isar-1.24.1 → isar-1.24.3}/src/isar/models/__init__.py +0 -0
  90. {isar-1.24.1 → isar-1.24.3}/src/isar/models/communication/__init__.py +0 -0
  91. {isar-1.24.1 → isar-1.24.3}/src/isar/models/communication/message.py +0 -0
  92. {isar-1.24.1 → isar-1.24.3}/src/isar/models/communication/queues/__init__.py +0 -0
  93. {isar-1.24.1 → isar-1.24.3}/src/isar/models/communication/queues/queue_io.py +0 -0
  94. {isar-1.24.1 → isar-1.24.3}/src/isar/models/communication/queues/queue_timeout_error.py +0 -0
  95. {isar-1.24.1 → isar-1.24.3}/src/isar/models/communication/queues/queues.py +0 -0
  96. {isar-1.24.1 → isar-1.24.3}/src/isar/models/communication/queues/status_queue.py +0 -0
  97. {isar-1.24.1 → isar-1.24.3}/src/isar/models/mission_metadata/__init__.py +0 -0
  98. {isar-1.24.1 → isar-1.24.3}/src/isar/script.py +0 -0
  99. {isar-1.24.1 → isar-1.24.3}/src/isar/services/__init__.py +0 -0
  100. {isar-1.24.1 → isar-1.24.3}/src/isar/services/auth/__init__.py +0 -0
  101. {isar-1.24.1 → isar-1.24.3}/src/isar/services/auth/azure_credentials.py +0 -0
  102. {isar-1.24.1 → isar-1.24.3}/src/isar/services/readers/__init__.py +0 -0
  103. {isar-1.24.1 → isar-1.24.3}/src/isar/services/readers/base_reader.py +0 -0
  104. {isar-1.24.1 → isar-1.24.3}/src/isar/services/service_connections/__init__.py +0 -0
  105. {isar-1.24.1 → isar-1.24.3}/src/isar/services/service_connections/mqtt/__init__.py +0 -0
  106. {isar-1.24.1 → isar-1.24.3}/src/isar/services/service_connections/mqtt/mqtt_client.py +0 -0
  107. {isar-1.24.1 → isar-1.24.3}/src/isar/services/service_connections/mqtt/robot_heartbeat_publisher.py +0 -0
  108. {isar-1.24.1 → isar-1.24.3}/src/isar/services/service_connections/mqtt/robot_info_publisher.py +0 -0
  109. {isar-1.24.1 → isar-1.24.3}/src/isar/services/service_connections/request_handler.py +0 -0
  110. {isar-1.24.1 → isar-1.24.3}/src/isar/services/service_connections/stid/__init__.py +0 -0
  111. {isar-1.24.1 → isar-1.24.3}/src/isar/services/utilities/__init__.py +0 -0
  112. {isar-1.24.1 → isar-1.24.3}/src/isar/services/utilities/queue_utilities.py +0 -0
  113. {isar-1.24.1 → isar-1.24.3}/src/isar/services/utilities/scheduling_utilities.py +0 -0
  114. {isar-1.24.1 → isar-1.24.3}/src/isar/services/utilities/threaded_request.py +0 -0
  115. {isar-1.24.1 → isar-1.24.3}/src/isar/state_machine/__init__.py +0 -0
  116. {isar-1.24.1 → isar-1.24.3}/src/isar/state_machine/states/__init__.py +0 -0
  117. {isar-1.24.1 → isar-1.24.3}/src/isar/state_machine/states/initialize.py +0 -0
  118. {isar-1.24.1 → isar-1.24.3}/src/isar/state_machine/states/initiate.py +0 -0
  119. {isar-1.24.1 → isar-1.24.3}/src/isar/state_machine/states/off.py +0 -0
  120. {isar-1.24.1 → isar-1.24.3}/src/isar/state_machine/states/offline.py +0 -0
  121. {isar-1.24.1 → isar-1.24.3}/src/isar/state_machine/states/paused.py +0 -0
  122. {isar-1.24.1 → isar-1.24.3}/src/isar/state_machine/states/stop.py +0 -0
  123. {isar-1.24.1 → isar-1.24.3}/src/isar/state_machine/states_enum.py +0 -0
  124. {isar-1.24.1 → isar-1.24.3}/src/isar/storage/__init__.py +0 -0
  125. {isar-1.24.1 → isar-1.24.3}/src/isar/storage/blob_storage.py +0 -0
  126. {isar-1.24.1 → isar-1.24.3}/src/isar/storage/local_storage.py +0 -0
  127. {isar-1.24.1 → isar-1.24.3}/src/isar/storage/slimm_storage.py +0 -0
  128. {isar-1.24.1 → isar-1.24.3}/src/isar/storage/storage_interface.py +0 -0
  129. {isar-1.24.1 → isar-1.24.3}/src/isar/storage/uploader.py +0 -0
  130. {isar-1.24.1 → isar-1.24.3}/src/isar/storage/utilities.py +0 -0
  131. {isar-1.24.1 → isar-1.24.3}/src/isar.egg-info/dependency_links.txt +0 -0
  132. {isar-1.24.1 → isar-1.24.3}/src/isar.egg-info/entry_points.txt +0 -0
  133. {isar-1.24.1 → isar-1.24.3}/src/isar.egg-info/requires.txt +0 -0
  134. {isar-1.24.1 → isar-1.24.3}/src/isar.egg-info/top_level.txt +0 -0
  135. {isar-1.24.1 → isar-1.24.3}/src/robot_interface/__init__.py +0 -0
  136. {isar-1.24.1 → isar-1.24.3}/src/robot_interface/models/__init__.py +0 -0
  137. {isar-1.24.1 → isar-1.24.3}/src/robot_interface/models/exceptions/__init__.py +0 -0
  138. {isar-1.24.1 → isar-1.24.3}/src/robot_interface/models/exceptions/robot_exceptions.py +0 -0
  139. {isar-1.24.1 → isar-1.24.3}/src/robot_interface/models/initialize/__init__.py +0 -0
  140. {isar-1.24.1 → isar-1.24.3}/src/robot_interface/models/initialize/initialize_params.py +0 -0
  141. {isar-1.24.1 → isar-1.24.3}/src/robot_interface/models/inspection/__init__.py +0 -0
  142. {isar-1.24.1 → isar-1.24.3}/src/robot_interface/models/inspection/inspection.py +0 -0
  143. {isar-1.24.1 → isar-1.24.3}/src/robot_interface/models/mission/__init__.py +0 -0
  144. {isar-1.24.1 → isar-1.24.3}/src/robot_interface/models/mission/mission.py +0 -0
  145. {isar-1.24.1 → isar-1.24.3}/src/robot_interface/models/mission/status.py +0 -0
  146. {isar-1.24.1 → isar-1.24.3}/src/robot_interface/models/mission/task.py +0 -0
  147. {isar-1.24.1 → isar-1.24.3}/src/robot_interface/models/robots/__init__.py +0 -0
  148. {isar-1.24.1 → isar-1.24.3}/src/robot_interface/models/robots/robot_model.py +0 -0
  149. {isar-1.24.1 → isar-1.24.3}/src/robot_interface/telemetry/__init__.py +0 -0
  150. {isar-1.24.1 → isar-1.24.3}/src/robot_interface/telemetry/mqtt_client.py +0 -0
  151. {isar-1.24.1 → isar-1.24.3}/src/robot_interface/test_robot_interface.py +0 -0
  152. {isar-1.24.1 → isar-1.24.3}/src/robot_interface/utilities/__init__.py +0 -0
  153. {isar-1.24.1 → isar-1.24.3}/src/robot_interface/utilities/json_service.py +0 -0
  154. {isar-1.24.1 → isar-1.24.3}/src/robot_interface/utilities/uuid_string_factory.py +0 -0
  155. {isar-1.24.1 → isar-1.24.3}/tests/__init__.py +0 -0
  156. {isar-1.24.1 → isar-1.24.3}/tests/integration/__init__.py +0 -0
  157. {isar-1.24.1 → isar-1.24.3}/tests/integration/turtlebot/__init__.py +0 -0
  158. {isar-1.24.1 → isar-1.24.3}/tests/integration/turtlebot/config/__init__.py +0 -0
  159. {isar-1.24.1 → isar-1.24.3}/tests/integration/turtlebot/config/maps/__init__.py +0 -0
  160. {isar-1.24.1 → isar-1.24.3}/tests/integration/turtlebot/config/maps/turtleworld.json +0 -0
  161. {isar-1.24.1 → isar-1.24.3}/tests/integration/turtlebot/config/missions/__init__.py +0 -0
  162. {isar-1.24.1 → isar-1.24.3}/tests/integration/turtlebot/config/missions/default.json +0 -0
  163. {isar-1.24.1 → isar-1.24.3}/tests/isar/__init__.py +0 -0
  164. {isar-1.24.1 → isar-1.24.3}/tests/isar/apis/__init__.py +0 -0
  165. {isar-1.24.1 → isar-1.24.3}/tests/isar/apis/scheduler/__init__.py +0 -0
  166. {isar-1.24.1 → isar-1.24.3}/tests/isar/apis/security/__init__.py +0 -0
  167. {isar-1.24.1 → isar-1.24.3}/tests/isar/apis/security/test_authentication.py +0 -0
  168. {isar-1.24.1 → isar-1.24.3}/tests/isar/mission/__init__.py +0 -0
  169. {isar-1.24.1 → isar-1.24.3}/tests/isar/mission/test_mission.py +0 -0
  170. {isar-1.24.1 → isar-1.24.3}/tests/isar/models/__init__.py +0 -0
  171. {isar-1.24.1 → isar-1.24.3}/tests/isar/models/communication/__init__.py +0 -0
  172. {isar-1.24.1 → isar-1.24.3}/tests/isar/models/communication/test_queues.py +0 -0
  173. {isar-1.24.1 → isar-1.24.3}/tests/isar/models/example_mission_definition.json +0 -0
  174. {isar-1.24.1 → isar-1.24.3}/tests/isar/models/test_start_mission_definition.py +0 -0
  175. {isar-1.24.1 → isar-1.24.3}/tests/isar/services/__init__.py +0 -0
  176. {isar-1.24.1 → isar-1.24.3}/tests/isar/services/readers/__init__.py +0 -0
  177. {isar-1.24.1 → isar-1.24.3}/tests/isar/services/readers/test_base_reader.py +0 -0
  178. {isar-1.24.1 → isar-1.24.3}/tests/isar/services/readers/test_mission_reader.py +0 -0
  179. {isar-1.24.1 → isar-1.24.3}/tests/isar/services/service_connections/__init__.py +0 -0
  180. {isar-1.24.1 → isar-1.24.3}/tests/isar/services/service_connections/echo/__init__.py +0 -0
  181. {isar-1.24.1 → isar-1.24.3}/tests/isar/services/service_connections/test_base_request_handler.py +0 -0
  182. {isar-1.24.1 → isar-1.24.3}/tests/isar/services/utilities/__init__.py +0 -0
  183. {isar-1.24.1 → isar-1.24.3}/tests/isar/services/utilities/test_queue_utilities.py +0 -0
  184. {isar-1.24.1 → isar-1.24.3}/tests/isar/services/utilities/test_scheduling_utilities.py +0 -0
  185. {isar-1.24.1 → isar-1.24.3}/tests/isar/state_machine/__init__.py +0 -0
  186. {isar-1.24.1 → isar-1.24.3}/tests/isar/state_machine/states/__init__.py +0 -0
  187. {isar-1.24.1 → isar-1.24.3}/tests/isar/state_machine/states/test_monitor.py +0 -0
  188. {isar-1.24.1 → isar-1.24.3}/tests/isar/state_machine/test_state_machine.py +0 -0
  189. {isar-1.24.1 → isar-1.24.3}/tests/isar/storage/test_blob_storage.py +0 -0
  190. {isar-1.24.1 → isar-1.24.3}/tests/isar/storage/test_uploader.py +0 -0
  191. {isar-1.24.1 → isar-1.24.3}/tests/mocks/__init__.py +0 -0
  192. {isar-1.24.1 → isar-1.24.3}/tests/mocks/blob_storage.py +0 -0
  193. {isar-1.24.1 → isar-1.24.3}/tests/mocks/mission_definition.py +0 -0
  194. {isar-1.24.1 → isar-1.24.3}/tests/mocks/mqtt_client.py +0 -0
  195. {isar-1.24.1 → isar-1.24.3}/tests/mocks/pose.py +0 -0
  196. {isar-1.24.1 → isar-1.24.3}/tests/mocks/request.py +0 -0
  197. {isar-1.24.1 → isar-1.24.3}/tests/mocks/status.py +0 -0
  198. {isar-1.24.1 → isar-1.24.3}/tests/mocks/task.py +0 -0
  199. {isar-1.24.1 → isar-1.24.3}/tests/mocks/token.py +0 -0
  200. {isar-1.24.1 → isar-1.24.3}/tests/test_data/test_json_file.json +0 -0
  201. {isar-1.24.1 → isar-1.24.3}/tests/test_data/test_map_config/test_map_config.json +0 -0
  202. {isar-1.24.1 → isar-1.24.3}/tests/test_data/test_mission_not_working.json +0 -0
  203. {isar-1.24.1 → isar-1.24.3}/tests/test_data/test_mission_working.json +0 -0
  204. {isar-1.24.1 → isar-1.24.3}/tests/test_data/test_mission_working_no_tasks.json +0 -0
  205. {isar-1.24.1 → isar-1.24.3}/tests/test_data/test_thermal_image_mission.json +0 -0
  206. {isar-1.24.1 → isar-1.24.3}/tests/test_modules.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: isar
3
- Version: 1.24.1
3
+ Version: 1.24.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
@@ -17,6 +17,7 @@ from opencensus.trace.tracer import Tracer
17
17
  from pydantic import AnyHttpUrl
18
18
 
19
19
  from isar.apis.models.models import ControlMissionResponse, StartMissionResponse
20
+ from isar.apis.robot_control.robot_controller import RobotController
20
21
  from isar.apis.schedule.scheduling_controller import SchedulingController
21
22
  from isar.apis.security.authentication import Authenticator
22
23
  from isar.config.configuration_error import ConfigurationError
@@ -34,12 +35,14 @@ class API:
34
35
  self,
35
36
  authenticator: Authenticator,
36
37
  scheduling_controller: SchedulingController,
38
+ robot_controller: RobotController,
37
39
  keyvault_client: Keyvault,
38
40
  port: int = settings.API_PORT,
39
41
  azure_ai_logging_enabled: bool = settings.LOG_HANDLER_APPLICATION_INSIGHTS_ENABLED,
40
42
  ) -> None:
41
43
  self.authenticator: Authenticator = authenticator
42
44
  self.scheduling_controller: SchedulingController = scheduling_controller
45
+ self.robot_controller: RobotController = robot_controller
43
46
  self.keyvault_client: Keyvault = keyvault_client
44
47
  self.host: str = "0.0.0.0" # Locking uvicorn to use 0.0.0.0
45
48
  self.port: int = port
@@ -98,6 +101,8 @@ class API:
98
101
 
99
102
  app.include_router(router=self._create_info_router())
100
103
 
104
+ app.include_router(router=self._create_media_control_router())
105
+
101
106
  return app
102
107
 
103
108
  def _create_scheduler_router(self) -> APIRouter:
@@ -277,7 +282,7 @@ class API:
277
282
 
278
283
  router.add_api_route(
279
284
  path="/info/robot-settings",
280
- endpoint=self.scheduling_controller.get_info,
285
+ endpoint=self.robot_controller.get_info,
281
286
  methods=["GET"],
282
287
  dependencies=[authentication_dependency],
283
288
  summary="Information about the robot-settings",
@@ -285,6 +290,21 @@ class API:
285
290
 
286
291
  return router
287
292
 
293
+ def _create_media_control_router(self) -> APIRouter:
294
+ router: APIRouter = APIRouter(tags=["Media"])
295
+
296
+ authentication_dependency: Security = Security(self.authenticator.get_scheme())
297
+
298
+ router.add_api_route(
299
+ path="/media/media-stream-config",
300
+ endpoint=self.robot_controller.generate_media_config,
301
+ methods=["GET"],
302
+ dependencies=[authentication_dependency],
303
+ summary="Generates a media stream connection config",
304
+ )
305
+
306
+ return router
307
+
288
308
  def _log_startup_message(self) -> None:
289
309
  address_format = "%s://%s:%d/docs"
290
310
  message = f"Uvicorn running on {address_format} (Press CTRL+C to quit)"
@@ -1,6 +1,8 @@
1
+ from dataclasses import dataclass
1
2
  from typing import List, Optional
2
3
 
3
4
  from alitra import Frame, Orientation, Pose, Position
5
+ from isar.apis.models.media_connection_type import MediaConnectionType
4
6
  from pydantic import BaseModel, Field
5
7
 
6
8
  from robot_interface.models.mission.task import TaskTypes
@@ -33,6 +35,13 @@ class RobotInfoResponse(BaseModel):
33
35
  plant_short_name: str
34
36
 
35
37
 
38
+ @dataclass
39
+ class MediaConfig:
40
+ url: str
41
+ token: str
42
+ media_connection_type: MediaConnectionType
43
+
44
+
36
45
  class InputOrientation(BaseModel):
37
46
  x: float
38
47
  y: float
@@ -0,0 +1,35 @@
1
+ import logging
2
+ from typing import List
3
+
4
+ from injector import inject
5
+
6
+ from isar.apis.models.models import (
7
+ RobotInfoResponse,
8
+ TaskResponse,
9
+ )
10
+ from isar.config.settings import robot_settings, settings
11
+ from isar.services.utilities.robot_utilities import RobotUtilities
12
+ from robot_interface.models.mission.task import Task
13
+
14
+
15
+ class RobotController:
16
+ @inject
17
+ def __init__(
18
+ self,
19
+ robot_utilities: RobotUtilities,
20
+ ):
21
+ self.robot_utilities: RobotUtilities = robot_utilities
22
+ self.logger = logging.getLogger("api")
23
+
24
+ def generate_media_config(self):
25
+ return self.robot_utilities.generate_media_config()
26
+
27
+ def get_info(self):
28
+ return RobotInfoResponse(
29
+ robot_package=settings.ROBOT_PACKAGE,
30
+ isar_id=settings.ISAR_ID,
31
+ robot_name=settings.ROBOT_NAME,
32
+ robot_capabilities=robot_settings.CAPABILITIES,
33
+ robot_map_name=settings.DEFAULT_MAP,
34
+ plant_short_name=settings.PLANT_SHORT_NAME,
35
+ )
@@ -21,13 +21,7 @@ from isar.mission_planner.mission_planner_interface import MissionPlannerError
21
21
  from isar.services.utilities.scheduling_utilities import SchedulingUtilities
22
22
  from isar.state_machine.states_enum import States
23
23
  from robot_interface.models.mission.mission import Mission
24
- from robot_interface.models.mission.task import (
25
- TASKS,
26
- Localize,
27
- MoveArm,
28
- ReturnToHome,
29
- )
30
- from robot_interface.models.mission.task import Task
24
+ from robot_interface.models.mission.task import TASKS, Localize, MoveArm, ReturnToHome
31
25
 
32
26
 
33
27
  class SchedulingController:
@@ -192,7 +186,7 @@ class SchedulingController:
192
186
 
193
187
  state: States = self.scheduling_utilities.get_state()
194
188
 
195
- if state in [States.Off, States.Idle]:
189
+ if state == States.Off:
196
190
  error_message = (
197
191
  f"Conflict - Stop command received in invalid state - State: {state}"
198
192
  )
@@ -301,16 +295,6 @@ class SchedulingController:
301
295
  )
302
296
  return self._api_response(mission)
303
297
 
304
- def get_info(self):
305
- return RobotInfoResponse(
306
- robot_package=settings.ROBOT_PACKAGE,
307
- isar_id=settings.ISAR_ID,
308
- robot_name=settings.ROBOT_NAME,
309
- robot_capabilities=robot_settings.CAPABILITIES,
310
- robot_map_name=settings.DEFAULT_MAP,
311
- plant_short_name=settings.PLANT_SHORT_NAME,
312
- )
313
-
314
298
  def _api_response(self, mission: Mission) -> StartMissionResponse:
315
299
  return StartMissionResponse(
316
300
  id=mission.id,
@@ -8,6 +8,7 @@ from injector import Injector, Module, multiprovider, provider, singleton
8
8
 
9
9
  from isar.apis.api import API
10
10
  from isar.apis.schedule.scheduling_controller import SchedulingController
11
+ from isar.apis.robot_control.robot_controller import RobotController
11
12
  from isar.apis.security.authentication import Authenticator
12
13
  from isar.config.keyvault.keyvault_service import Keyvault
13
14
  from isar.config.settings import settings
@@ -18,6 +19,7 @@ from isar.mission_planner.task_selector_interface import TaskSelectorInterface
18
19
  from isar.models.communication.queues.queues import Queues
19
20
  from isar.services.service_connections.request_handler import RequestHandler
20
21
  from isar.services.utilities.scheduling_utilities import SchedulingUtilities
22
+ from isar.services.utilities.robot_utilities import RobotUtilities
21
23
  from isar.state_machine.state_machine import StateMachine
22
24
  from isar.storage.blob_storage import BlobStorage
23
25
  from isar.storage.local_storage import LocalStorage
@@ -35,9 +37,10 @@ class APIModule(Module):
35
37
  self,
36
38
  authenticator: Authenticator,
37
39
  scheduling_controller: SchedulingController,
40
+ robot_controller: RobotController,
38
41
  keyvault: Keyvault,
39
42
  ) -> API:
40
- return API(authenticator, scheduling_controller, keyvault)
43
+ return API(authenticator, scheduling_controller, robot_controller, keyvault)
41
44
 
42
45
  @provider
43
46
  @singleton
@@ -47,6 +50,14 @@ class APIModule(Module):
47
50
  ) -> SchedulingController:
48
51
  return SchedulingController(scheduling_utilities)
49
52
 
53
+ @provider
54
+ @singleton
55
+ def provide_robot_controller(
56
+ self,
57
+ robot_utilities: RobotUtilities,
58
+ ) -> RobotController:
59
+ return RobotController(robot_utilities)
60
+
50
61
 
51
62
  class AuthenticationModule(Module):
52
63
  @provider
@@ -142,7 +153,7 @@ class UploaderModule(Module):
142
153
  )
143
154
 
144
155
 
145
- class UtilitiesModule(Module):
156
+ class SchedulingUtilitiesModule(Module):
146
157
  @provider
147
158
  @singleton
148
159
  def provide_scheduling_utilities(
@@ -151,6 +162,13 @@ class UtilitiesModule(Module):
151
162
  return SchedulingUtilities(queues, mission_planner)
152
163
 
153
164
 
165
+ class RobotUtilitiesModule(Module):
166
+ @provider
167
+ @singleton
168
+ def provide_robot_utilities(self, robot: RobotInterface) -> RobotUtilities:
169
+ return RobotUtilities(robot)
170
+
171
+
154
172
  class ServiceModule(Module):
155
173
  @provider
156
174
  @singleton
@@ -193,7 +211,8 @@ modules: Dict[str, Tuple[Module, Union[str, bool]]] = {
193
211
  "storage_blob": (BlobStorageModule, settings.STORAGE_BLOB_ENABLED),
194
212
  "storage_slimm": (SlimmStorageModule, settings.STORAGE_SLIMM_ENABLED),
195
213
  "mqtt": (MqttModule, "required"),
196
- "utilities": (UtilitiesModule, "required"),
214
+ "utilities": (SchedulingUtilitiesModule, "required"),
215
+ "robot_utilities": (RobotUtilitiesModule, "required"),
197
216
  }
198
217
 
199
218
 
@@ -0,0 +1,23 @@
1
+ import logging
2
+
3
+ from injector import inject
4
+
5
+ from isar.apis.models.models import MediaConfig
6
+ from robot_interface.robot_interface import RobotInterface
7
+
8
+
9
+ class RobotUtilities:
10
+ """
11
+ Contains utility functions for getting robot information from the API.
12
+ """
13
+
14
+ @inject
15
+ def __init__(
16
+ self,
17
+ robot: RobotInterface,
18
+ ):
19
+ self.robot: RobotInterface = robot
20
+ self.logger = logging.getLogger("api")
21
+
22
+ def generate_media_config(self) -> MediaConfig:
23
+ return self.robot.generate_media_config()
@@ -32,11 +32,7 @@ from isar.state_machine.states_enum import States
32
32
  from robot_interface.models.exceptions.robot_exceptions import ErrorMessage
33
33
  from robot_interface.models.initialize.initialize_params import InitializeParams
34
34
  from robot_interface.models.mission.mission import Mission
35
- from robot_interface.models.mission.status import (
36
- MissionStatus,
37
- RobotStatus,
38
- TaskStatus,
39
- )
35
+ from robot_interface.models.mission.status import MissionStatus, RobotStatus, TaskStatus
40
36
  from robot_interface.models.mission.task import TASKS, Task
41
37
  from robot_interface.robot_interface import RobotInterface
42
38
  from robot_interface.telemetry.mqtt_client import MqttClientInterface
@@ -134,7 +130,11 @@ class StateMachine(object):
134
130
  },
135
131
  {
136
132
  "trigger": "stop",
137
- "source": [self.initiate_state, self.monitor_state],
133
+ "source": [
134
+ self.initiate_state,
135
+ self.monitor_state,
136
+ self.idle_state,
137
+ ],
138
138
  "dest": self.stop_state,
139
139
  "before": self._stop,
140
140
  },
@@ -371,6 +371,11 @@ class StateMachine(object):
371
371
  self.iterate_current_task()
372
372
 
373
373
  def _mission_stopped(self) -> None:
374
+ if self.current_mission is None:
375
+ self._queue_empty_response()
376
+ self.reset_state_machine()
377
+ return
378
+
374
379
  self.current_mission.status = MissionStatus.Cancelled
375
380
 
376
381
  for task in self.current_mission.tasks:
@@ -588,6 +593,16 @@ class StateMachine(object):
588
593
  task_status=self.current_task.status,
589
594
  )
590
595
 
596
+ def _queue_empty_response(self):
597
+ self.queues.stop_mission.output.put(
598
+ ControlMissionResponse(
599
+ mission_id="None",
600
+ mission_status="None",
601
+ task_id="None",
602
+ task_status="None",
603
+ )
604
+ )
605
+
591
606
 
592
607
  def main(state_machine: StateMachine):
593
608
  """Starts a state machine instance."""
@@ -36,6 +36,9 @@ class Idle(State):
36
36
 
37
37
  def _run(self) -> None:
38
38
  while True:
39
+ if self.state_machine.should_stop_mission():
40
+ transition = self.state_machine.stop # type: ignore
41
+ break
39
42
  start_mission: Optional[StartMissionMessage] = (
40
43
  self.state_machine.should_start_mission()
41
44
  )
@@ -49,7 +49,6 @@ class Monitor(State):
49
49
  if self.task_status_thread:
50
50
  self.task_status_thread.wait_for_thread()
51
51
  self.task_status_thread = None
52
- self.request_status_failure_counter = 0
53
52
 
54
53
  def _run(self) -> None:
55
54
  transition: Callable
@@ -76,15 +75,19 @@ class Monitor(State):
76
75
  except ThreadedRequestNotFinishedError:
77
76
  time.sleep(self.state_machine.sleep_time)
78
77
  continue
79
-
80
78
  except (
81
79
  RobotCommunicationTimeoutException,
82
80
  RobotCommunicationException,
83
81
  ) as e:
84
- task_failed: bool = self._handle_communication_retry(e)
85
- if task_failed:
82
+ retry_limit_exceeded: bool = self._check_if_exceeded_retry_limit(e)
83
+ if retry_limit_exceeded:
84
+ self.logger.error(
85
+ f"Monitoring task {self.state_machine.current_task.id[:8]} failed "
86
+ f"because: {e.error_description}"
87
+ )
86
88
  status = TaskStatus.Failed
87
89
  else:
90
+ time.sleep(self.state_machine.sleep_time)
88
91
  continue
89
92
 
90
93
  except RobotTaskStatusException as e:
@@ -111,7 +114,7 @@ class Monitor(State):
111
114
  )
112
115
  break
113
116
 
114
- if self.state_machine.current_task == None:
117
+ if self.state_machine.current_task is None:
115
118
  self.state_machine.iterate_current_task()
116
119
 
117
120
  self.state_machine.current_task.status = status
@@ -142,7 +145,7 @@ class Monitor(State):
142
145
  )
143
146
 
144
147
  self.state_machine.iterate_current_task()
145
- if self.state_machine.current_task == None:
148
+ if self.state_machine.current_task is None:
146
149
  transition = self.state_machine.full_mission_finished # type: ignore
147
150
  break
148
151
 
@@ -193,6 +196,7 @@ class Monitor(State):
193
196
  self.logger.info(f"Inspection: {str(inspection.id)[:8]} queued for upload")
194
197
 
195
198
  def _report_task_status(self, task: Task) -> None:
199
+ self.request_status_failure_counter = 0
196
200
  if task.status == TaskStatus.Failed:
197
201
  self.logger.warning(
198
202
  f"Task: {str(task.id)[:8]} was reported as failed by the robot"
@@ -215,7 +219,7 @@ class Monitor(State):
215
219
  )
216
220
  self.state_machine.current_task.error_message = error_message
217
221
 
218
- def _handle_communication_retry(
222
+ def _check_if_exceeded_retry_limit(
219
223
  self, e: Union[RobotCommunicationTimeoutException, RobotCommunicationException]
220
224
  ) -> bool:
221
225
  self.state_machine.current_mission.error_message = ErrorMessage(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: isar
3
- Version: 1.24.1
3
+ Version: 1.24.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
@@ -40,8 +40,10 @@ src/isar.egg-info/top_level.txt
40
40
  src/isar/apis/__init__.py
41
41
  src/isar/apis/api.py
42
42
  src/isar/apis/models/__init__.py
43
+ src/isar/apis/models/media_connection_type.py
43
44
  src/isar/apis/models/models.py
44
45
  src/isar/apis/models/start_mission_definition.py
46
+ src/isar/apis/robot_control/robot_controller.py
45
47
  src/isar/apis/schedule/__init__.py
46
48
  src/isar/apis/schedule/scheduling_controller.py
47
49
  src/isar/apis/security/__init__.py
@@ -100,6 +102,7 @@ src/isar/services/service_connections/mqtt/robot_info_publisher.py
100
102
  src/isar/services/service_connections/stid/__init__.py
101
103
  src/isar/services/utilities/__init__.py
102
104
  src/isar/services/utilities/queue_utilities.py
105
+ src/isar/services/utilities/robot_utilities.py
103
106
  src/isar/services/utilities/scheduling_utilities.py
104
107
  src/isar/services/utilities/threaded_request.py
105
108
  src/isar/state_machine/__init__.py
@@ -138,7 +141,6 @@ src/robot_interface/models/mission/task.py
138
141
  src/robot_interface/models/robots/__init__.py
139
142
  src/robot_interface/models/robots/robot_model.py
140
143
  src/robot_interface/telemetry/__init__.py
141
- src/robot_interface/telemetry/media_connection_type.py
142
144
  src/robot_interface/telemetry/mqtt_client.py
143
145
  src/robot_interface/telemetry/payloads.py
144
146
  src/robot_interface/utilities/__init__.py
@@ -3,6 +3,7 @@ from queue import Queue
3
3
  from threading import Thread
4
4
  from typing import Callable, List
5
5
 
6
+ from isar.apis.models.models import MediaConfig
6
7
  from robot_interface.models.initialize import InitializeParams
7
8
  from robot_interface.models.inspection.inspection import Inspection
8
9
  from robot_interface.models.mission.mission import Mission
@@ -224,6 +225,19 @@ class RobotInterface(metaclass=ABCMeta):
224
225
  """
225
226
  raise NotImplementedError
226
227
 
228
+ @abstractmethod
229
+ def generate_media_config(self) -> MediaConfig:
230
+ """
231
+ Generate a JSON containing the url and token needed to establish a media stream
232
+ connection to a robot.
233
+
234
+ Returns
235
+ -------
236
+ MediaConfig
237
+ An object containing the connection information for a media stream connection
238
+ """
239
+ raise NotImplementedError
240
+
227
241
  @abstractmethod
228
242
  def get_telemetry_publishers(
229
243
  self, queue: Queue, isar_id: str, robot_name: str
@@ -6,7 +6,6 @@ from alitra import Pose
6
6
  from transitions import State
7
7
 
8
8
  from robot_interface.models.mission.status import RobotStatus
9
- from robot_interface.telemetry.media_connection_type import MediaConnectionType
10
9
 
11
10
 
12
11
  @dataclass
@@ -56,13 +55,6 @@ class VideoStream:
56
55
  type: str
57
56
 
58
57
 
59
- @dataclass
60
- class MediaConfig(TelemetryPayload):
61
- url: str
62
- token: str
63
- media_connection_type: MediaConnectionType
64
-
65
-
66
58
  @dataclass
67
59
  class RobotStatusPayload:
68
60
  isar_id: str
@@ -15,7 +15,7 @@ from isar.modules import (
15
15
  SequentialTaskSelectorModule,
16
16
  ServiceModule,
17
17
  StateMachineModule,
18
- UtilitiesModule,
18
+ SchedulingUtilitiesModule,
19
19
  )
20
20
  from isar.services.service_connections.request_handler import RequestHandler
21
21
  from isar.services.utilities.scheduling_utilities import SchedulingUtilities
@@ -47,7 +47,7 @@ def injector():
47
47
  ServiceModule,
48
48
  StateMachineModule,
49
49
  SequentialTaskSelectorModule,
50
- UtilitiesModule,
50
+ SchedulingUtilitiesModule,
51
51
  ]
52
52
  )
53
53
 
@@ -66,7 +66,7 @@ def injector_auth():
66
66
  RequestHandlerModule,
67
67
  ServiceModule,
68
68
  StateMachineModule,
69
- UtilitiesModule,
69
+ SchedulingUtilitiesModule,
70
70
  ]
71
71
  )
72
72
 
@@ -23,7 +23,7 @@ from isar.modules import (
23
23
  RobotModule,
24
24
  ServiceModule,
25
25
  StateMachineModule,
26
- UtilitiesModule,
26
+ SchedulingUtilitiesModule,
27
27
  )
28
28
  from isar.services.readers.base_reader import BaseReader
29
29
  from isar.state_machine.states_enum import States
@@ -57,7 +57,7 @@ def injector_turtlebot():
57
57
  StateMachineModule,
58
58
  LocalPlannerModule,
59
59
  LocalStorageModule,
60
- UtilitiesModule,
60
+ SchedulingUtilitiesModule,
61
61
  MockMqttModule,
62
62
  ]
63
63
  )
@@ -269,6 +269,7 @@ class TestStopMission:
269
269
  valid_states = [
270
270
  States.Initiate,
271
271
  States.Initialize,
272
+ States.Idle,
272
273
  States.Monitor,
273
274
  States.Paused,
274
275
  States.Stop,
@@ -286,14 +287,6 @@ class TestStopMission:
286
287
  assert response.status_code == HTTPStatus.OK
287
288
  assert response.json() == jsonable_encoder(mock_control_mission_response)
288
289
 
289
- @mock.patch.object(SchedulingUtilities, "get_state", mock_return_idle)
290
- @mock.patch.object(
291
- SchedulingUtilities, "stop_mission", mock_control_mission_response
292
- )
293
- def test_can_not_stop_mission_in_idle(self, client: TestClient):
294
- response = client.post(url=self.schedule_stop_mission_path)
295
- assert response.status_code == HTTPStatus.CONFLICT
296
-
297
290
  @mock.patch.object(SchedulingUtilities, "get_state", mock_return_off)
298
291
  @mock.patch.object(
299
292
  SchedulingUtilities, "stop_mission", mock_control_mission_response
@@ -6,6 +6,8 @@ from typing import Callable, List, Sequence
6
6
 
7
7
  from alitra import Frame, Orientation, Pose, Position
8
8
 
9
+ from isar.apis.models.media_connection_type import MediaConnectionType
10
+ from isar.apis.models.models import MediaConfig
9
11
  from robot_interface.models.initialize import InitializeParams
10
12
  from robot_interface.models.inspection.inspection import (
11
13
  Image,
@@ -62,6 +64,13 @@ class MockRobot(RobotInterface):
62
64
  image.data = b"Some binary image data"
63
65
  return image
64
66
 
67
+ def generate_media_config(self) -> MediaConfig:
68
+ return MediaConfig(
69
+ url="mockURL",
70
+ token="mockToken",
71
+ media_connection_type=MediaConnectionType.LiveKit,
72
+ )
73
+
65
74
  def register_inspection_callback(
66
75
  self, callback_function: Callable[[Inspection, Mission], None]
67
76
  ) -> None:
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes