isar 1.20.2__py3-none-any.whl → 1.34.13__py3-none-any.whl

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.
Files changed (134) hide show
  1. isar/apis/api.py +135 -86
  2. isar/apis/models/__init__.py +0 -1
  3. isar/apis/models/models.py +21 -11
  4. isar/apis/models/start_mission_definition.py +115 -170
  5. isar/apis/robot_control/robot_controller.py +41 -0
  6. isar/apis/schedule/scheduling_controller.py +123 -187
  7. isar/apis/security/authentication.py +5 -5
  8. isar/config/certs/ca-cert.pem +33 -31
  9. isar/config/keyvault/keyvault_service.py +4 -2
  10. isar/config/log.py +45 -40
  11. isar/config/logging.conf +16 -31
  12. isar/config/open_telemetry.py +102 -0
  13. isar/config/settings.py +74 -117
  14. isar/eventhandlers/eventhandler.py +123 -0
  15. isar/models/events.py +184 -0
  16. isar/models/status.py +22 -0
  17. isar/modules.py +117 -200
  18. isar/robot/robot.py +383 -0
  19. isar/robot/robot_battery.py +60 -0
  20. isar/robot/robot_monitor_mission.py +357 -0
  21. isar/robot/robot_pause_mission.py +74 -0
  22. isar/robot/robot_resume_mission.py +67 -0
  23. isar/robot/robot_start_mission.py +66 -0
  24. isar/robot/robot_status.py +61 -0
  25. isar/robot/robot_stop_mission.py +68 -0
  26. isar/robot/robot_upload_inspection.py +75 -0
  27. isar/script.py +58 -41
  28. isar/services/service_connections/mqtt/mqtt_client.py +47 -11
  29. isar/services/service_connections/mqtt/robot_heartbeat_publisher.py +5 -2
  30. isar/services/service_connections/mqtt/robot_info_publisher.py +3 -3
  31. isar/services/service_connections/persistent_memory.py +69 -0
  32. isar/services/utilities/mqtt_utilities.py +93 -0
  33. isar/services/utilities/robot_utilities.py +20 -0
  34. isar/services/utilities/scheduling_utilities.py +386 -100
  35. isar/state_machine/state_machine.py +242 -539
  36. isar/state_machine/states/__init__.py +0 -8
  37. isar/state_machine/states/await_next_mission.py +114 -0
  38. isar/state_machine/states/blocked_protective_stop.py +60 -0
  39. isar/state_machine/states/going_to_lockdown.py +95 -0
  40. isar/state_machine/states/going_to_recharging.py +92 -0
  41. isar/state_machine/states/home.py +115 -0
  42. isar/state_machine/states/intervention_needed.py +77 -0
  43. isar/state_machine/states/lockdown.py +38 -0
  44. isar/state_machine/states/maintenance.py +43 -0
  45. isar/state_machine/states/monitor.py +137 -247
  46. isar/state_machine/states/offline.py +51 -53
  47. isar/state_machine/states/paused.py +92 -23
  48. isar/state_machine/states/pausing.py +48 -0
  49. isar/state_machine/states/pausing_return_home.py +48 -0
  50. isar/state_machine/states/recharging.py +80 -0
  51. isar/state_machine/states/resuming.py +57 -0
  52. isar/state_machine/states/resuming_return_home.py +64 -0
  53. isar/state_machine/states/return_home_paused.py +109 -0
  54. isar/state_machine/states/returning_home.py +217 -0
  55. isar/state_machine/states/stopping.py +69 -0
  56. isar/state_machine/states/stopping_due_to_maintenance.py +61 -0
  57. isar/state_machine/states/stopping_go_to_lockdown.py +60 -0
  58. isar/state_machine/states/stopping_go_to_recharge.py +51 -0
  59. isar/state_machine/states/stopping_paused_mission.py +36 -0
  60. isar/state_machine/states/stopping_paused_return_home.py +59 -0
  61. isar/state_machine/states/stopping_return_home.py +59 -0
  62. isar/state_machine/states/unknown_status.py +74 -0
  63. isar/state_machine/states_enum.py +23 -5
  64. isar/state_machine/transitions/mission.py +225 -0
  65. isar/state_machine/transitions/return_home.py +108 -0
  66. isar/state_machine/transitions/robot_status.py +87 -0
  67. isar/state_machine/utils/common_event_handlers.py +138 -0
  68. isar/storage/blob_storage.py +70 -52
  69. isar/storage/local_storage.py +25 -12
  70. isar/storage/storage_interface.py +28 -7
  71. isar/storage/uploader.py +174 -55
  72. isar/storage/utilities.py +32 -29
  73. {isar-1.20.2.dist-info → isar-1.34.13.dist-info}/METADATA +119 -123
  74. isar-1.34.13.dist-info/RECORD +120 -0
  75. {isar-1.20.2.dist-info → isar-1.34.13.dist-info}/WHEEL +1 -1
  76. {isar-1.20.2.dist-info → isar-1.34.13.dist-info}/entry_points.txt +1 -0
  77. robot_interface/models/exceptions/robot_exceptions.py +91 -41
  78. robot_interface/models/inspection/__init__.py +0 -13
  79. robot_interface/models/inspection/inspection.py +42 -33
  80. robot_interface/models/mission/mission.py +14 -15
  81. robot_interface/models/mission/status.py +20 -26
  82. robot_interface/models/mission/task.py +154 -121
  83. robot_interface/models/robots/battery_state.py +6 -0
  84. robot_interface/models/robots/media.py +13 -0
  85. robot_interface/models/robots/robot_model.py +7 -7
  86. robot_interface/robot_interface.py +119 -84
  87. robot_interface/telemetry/mqtt_client.py +74 -12
  88. robot_interface/telemetry/payloads.py +91 -13
  89. robot_interface/utilities/json_service.py +7 -1
  90. isar/config/configuration_error.py +0 -2
  91. isar/config/keyvault/keyvault_error.py +0 -2
  92. isar/config/predefined_mission_definition/__init__.py +0 -0
  93. isar/config/predefined_mission_definition/default_exr.json +0 -51
  94. isar/config/predefined_mission_definition/default_mission.json +0 -91
  95. isar/config/predefined_mission_definition/default_turtlebot.json +0 -124
  96. isar/config/predefined_missions/__init__.py +0 -0
  97. isar/config/predefined_missions/default.json +0 -92
  98. isar/config/predefined_missions/default_turtlebot.json +0 -110
  99. isar/config/predefined_poses/__init__.py +0 -0
  100. isar/config/predefined_poses/predefined_poses.py +0 -616
  101. isar/config/settings.env +0 -25
  102. isar/mission_planner/__init__.py +0 -0
  103. isar/mission_planner/local_planner.py +0 -82
  104. isar/mission_planner/mission_planner_interface.py +0 -26
  105. isar/mission_planner/sequential_task_selector.py +0 -23
  106. isar/mission_planner/task_selector_interface.py +0 -31
  107. isar/models/communication/__init__.py +0 -0
  108. isar/models/communication/message.py +0 -12
  109. isar/models/communication/queues/__init__.py +0 -4
  110. isar/models/communication/queues/queue_io.py +0 -12
  111. isar/models/communication/queues/queue_timeout_error.py +0 -2
  112. isar/models/communication/queues/queues.py +0 -19
  113. isar/models/communication/queues/status_queue.py +0 -20
  114. isar/models/mission_metadata/__init__.py +0 -0
  115. isar/services/auth/__init__.py +0 -0
  116. isar/services/auth/azure_credentials.py +0 -14
  117. isar/services/readers/__init__.py +0 -0
  118. isar/services/readers/base_reader.py +0 -37
  119. isar/services/service_connections/request_handler.py +0 -153
  120. isar/services/service_connections/stid/__init__.py +0 -0
  121. isar/services/utilities/queue_utilities.py +0 -39
  122. isar/services/utilities/threaded_request.py +0 -68
  123. isar/state_machine/states/idle.py +0 -85
  124. isar/state_machine/states/initialize.py +0 -71
  125. isar/state_machine/states/initiate.py +0 -142
  126. isar/state_machine/states/off.py +0 -18
  127. isar/state_machine/states/stop.py +0 -95
  128. isar/storage/slimm_storage.py +0 -191
  129. isar-1.20.2.dist-info/RECORD +0 -116
  130. robot_interface/models/initialize/__init__.py +0 -1
  131. robot_interface/models/initialize/initialize_params.py +0 -9
  132. robot_interface/models/mission/step.py +0 -234
  133. {isar-1.20.2.dist-info → isar-1.34.13.dist-info/licenses}/LICENSE +0 -0
  134. {isar-1.20.2.dist-info → isar-1.34.13.dist-info}/top_level.txt +0 -0
@@ -1,71 +0,0 @@
1
- import logging
2
- import time
3
- from typing import TYPE_CHECKING, Callable, Optional
4
-
5
- from injector import inject
6
- from transitions import State
7
-
8
- from isar.services.utilities.threaded_request import (
9
- ThreadedRequest,
10
- ThreadedRequestNotFinishedError,
11
- )
12
- from robot_interface.models.exceptions.robot_exceptions import (
13
- ErrorMessage,
14
- RobotException,
15
- RobotInitializeException,
16
- )
17
-
18
- if TYPE_CHECKING:
19
- from isar.state_machine.state_machine import StateMachine
20
-
21
-
22
- class Initialize(State):
23
- @inject
24
- def __init__(self, state_machine: "StateMachine") -> None:
25
- super().__init__(name="initialize", on_enter=self.start, on_exit=self.stop)
26
- self.state_machine: "StateMachine" = state_machine
27
-
28
- self.logger = logging.getLogger("state_machine")
29
- self.initialize_thread: Optional[ThreadedRequest] = None
30
-
31
- def start(self) -> None:
32
- self.state_machine.update_state()
33
- self._run()
34
-
35
- def stop(self) -> None:
36
- if self.initialize_thread:
37
- self.initialize_thread.wait_for_thread()
38
- self.initialize_thread = None
39
-
40
- def _run(self) -> None:
41
- transition: Callable
42
- while True:
43
- if not self.initialize_thread:
44
- self.initialize_thread = ThreadedRequest(
45
- self.state_machine.robot.initialize
46
- )
47
- self.initialize_thread.start_thread(
48
- self.state_machine.get_initialize_params(),
49
- name="State Machine Initialize Robot",
50
- )
51
-
52
- try:
53
- self.initialize_thread.get_output()
54
-
55
- except ThreadedRequestNotFinishedError:
56
- time.sleep(self.state_machine.sleep_time)
57
- continue
58
-
59
- except (RobotInitializeException, RobotException) as e:
60
- self.state_machine.current_step.error_message = ErrorMessage(
61
- error_reason=e.error_reason, error_description=e.error_description
62
- )
63
- self.logger.error(
64
- f"Failed to initialize robot because: {e.error_description}"
65
- )
66
- transition = self.state_machine.initialization_failed # type: ignore
67
- break
68
-
69
- transition = self.state_machine.initialization_successful # type: ignore
70
- break
71
- transition()
@@ -1,142 +0,0 @@
1
- import logging
2
- import time
3
- from typing import TYPE_CHECKING, Any, Callable, Optional
4
-
5
- from transitions import State
6
-
7
- from isar.config.settings import settings
8
- from isar.services.utilities.threaded_request import (
9
- ThreadedRequest,
10
- ThreadedRequestNotFinishedError,
11
- )
12
- from robot_interface.models.exceptions.robot_exceptions import (
13
- ErrorMessage,
14
- RobotException,
15
- RobotInfeasibleMissionException,
16
- RobotInfeasibleStepException,
17
- )
18
-
19
- if TYPE_CHECKING:
20
- from isar.state_machine.state_machine import StateMachine
21
-
22
-
23
- class Initiate(State):
24
- def __init__(self, state_machine: "StateMachine") -> None:
25
- super().__init__(name="initiate", on_enter=self.start, on_exit=self.stop)
26
- self.state_machine: "StateMachine" = state_machine
27
- self.initiate_failure_counter: int = 0
28
- self.initiate_failure_counter_limit: int = (
29
- settings.INITIATE_FAILURE_COUNTER_LIMIT
30
- )
31
- self.logger = logging.getLogger("state_machine")
32
-
33
- self.initiate_thread: Optional[ThreadedRequest] = None
34
-
35
- def start(self) -> None:
36
- self.state_machine.update_state()
37
- self._run()
38
-
39
- def stop(self) -> None:
40
- self.initiate_failure_counter = 0
41
- if self.initiate_thread:
42
- self.initiate_thread.wait_for_thread()
43
- self.initiate_thread = None
44
-
45
- def _run(self) -> None:
46
- transition: Callable
47
- while True:
48
- if self.state_machine.should_stop_mission():
49
- transition = self.state_machine.stop # type: ignore
50
- break
51
-
52
- if self.state_machine.should_pause_mission():
53
- transition = self.state_machine.pause # type: ignore
54
- break
55
-
56
- if not self.state_machine.current_task:
57
- self.logger.info(
58
- f"Completed mission: {self.state_machine.current_mission.id}"
59
- )
60
- transition = self.state_machine.mission_finished # type: ignore
61
- break
62
-
63
- if not self.initiate_thread:
64
- if self.state_machine.stepwise_mission:
65
- self._run_initiate_thread(
66
- initiate_function=self.state_machine.robot.initiate_step,
67
- function_argument=self.state_machine.current_step,
68
- thread_name="State Machine Initiate Step",
69
- )
70
- else:
71
- self._run_initiate_thread(
72
- initiate_function=self.state_machine.robot.initiate_mission,
73
- function_argument=self.state_machine.current_mission,
74
- thread_name="State Machine Initiate Mission",
75
- )
76
-
77
- try:
78
- self.initiate_thread.get_output()
79
- transition = self.state_machine.initiated # type: ignore
80
- break
81
- except ThreadedRequestNotFinishedError:
82
- time.sleep(self.state_machine.sleep_time)
83
- continue
84
- except RobotInfeasibleStepException as e:
85
- self.state_machine.current_step.error_message = ErrorMessage(
86
- error_reason=e.error_reason, error_description=e.error_description
87
- )
88
- self.logger.warning(
89
- f"Failed to initiate step "
90
- f"{str(self.state_machine.current_step.id)[:8]} after retrying "
91
- f"{self.initiate_failure_counter} times because: "
92
- f"{e.error_description}"
93
- )
94
- transition = self.state_machine.initiate_infeasible # type: ignore
95
- break
96
-
97
- except RobotInfeasibleMissionException as e:
98
- self.state_machine.current_mission.error_message = ErrorMessage(
99
- error_reason=e.error_reason, error_description=e.error_description
100
- )
101
- self.logger.warning(
102
- f"Failed to initiate mission "
103
- f"{str(self.state_machine.current_mission.id)[:8]} because: "
104
- f"{e.error_description}"
105
- )
106
- transition = self.state_machine.initiate_failed # type: ignore
107
- break
108
-
109
- except RobotException as e:
110
- self.initiate_thread = None
111
- self.initiate_failure_counter += 1
112
- self.logger.warning(
113
- f"Initiating failed #: {str(self.initiate_failure_counter)} "
114
- f"because: {e.error_description}"
115
- )
116
-
117
- if self.initiate_failure_counter >= self.initiate_failure_counter_limit:
118
- self.state_machine.current_step.error_message = ErrorMessage(
119
- error_reason=e.error_reason,
120
- error_description=e.error_description,
121
- )
122
- self.logger.error(
123
- f"Mission will be cancelled after failing to initiate "
124
- f"{self.initiate_failure_counter_limit} times because: "
125
- f"{e.error_description}"
126
- )
127
- transition = self.state_machine.initiate_failed # type: ignore
128
- break
129
-
130
- time.sleep(self.state_machine.sleep_time)
131
-
132
- transition()
133
-
134
- def _run_initiate_thread(
135
- self, initiate_function: Callable, function_argument: Any, thread_name: str
136
- ) -> None:
137
- self.initiate_thread = ThreadedRequest(request_func=initiate_function)
138
-
139
- self.initiate_thread.start_thread(
140
- function_argument,
141
- name=thread_name,
142
- )
@@ -1,18 +0,0 @@
1
- import logging
2
- from typing import TYPE_CHECKING
3
-
4
- from transitions import State
5
-
6
- if TYPE_CHECKING:
7
- from isar.state_machine.state_machine import StateMachine
8
-
9
-
10
- class Off(State):
11
- def __init__(self, state_machine: "StateMachine"):
12
- super().__init__(name="off", on_enter=self.start)
13
- self.logger = logging.getLogger("state_machine")
14
- self.state_machine: "StateMachine" = state_machine
15
-
16
- def start(self):
17
- self.state_machine.update_state()
18
- self.logger.info(f"State: {self.state_machine.current_state}")
@@ -1,95 +0,0 @@
1
- import logging
2
- import time
3
- from typing import TYPE_CHECKING, Callable, Optional
4
-
5
- from transitions import State
6
-
7
- from isar.services.utilities.threaded_request import (
8
- ThreadedRequest,
9
- ThreadedRequestNotFinishedError,
10
- )
11
- from robot_interface.models.exceptions.robot_exceptions import (
12
- ErrorMessage,
13
- RobotActionException,
14
- RobotException,
15
- )
16
-
17
- if TYPE_CHECKING:
18
- from isar.state_machine.state_machine import StateMachine
19
-
20
-
21
- class Stop(State):
22
- def __init__(self, state_machine: "StateMachine") -> None:
23
- super().__init__(name="stop", on_enter=self.start, on_exit=self.stop)
24
- self.state_machine: "StateMachine" = state_machine
25
- self.logger = logging.getLogger("state_machine")
26
- self.stop_thread: Optional[ThreadedRequest] = None
27
- self._count_number_retries: int = 0
28
-
29
- def start(self) -> None:
30
- self.state_machine.update_state()
31
- self._run()
32
-
33
- def stop(self) -> None:
34
- if self.stop_thread:
35
- self.stop_thread.wait_for_thread()
36
- self.stop_thread = None
37
- self._count_number_retries = 0
38
-
39
- def _run(self) -> None:
40
- transition: Callable
41
- while True:
42
- if not self.stop_thread:
43
- self.stop_thread = ThreadedRequest(self.state_machine.robot.stop)
44
- self.stop_thread.start_thread(name="State Machine Stop Robot")
45
-
46
- if self.state_machine.should_stop_mission():
47
- self.state_machine.stopped = True
48
-
49
- try:
50
- self.stop_thread.get_output()
51
- except ThreadedRequestNotFinishedError:
52
- time.sleep(self.state_machine.sleep_time)
53
- continue
54
-
55
- except (RobotActionException, RobotException) as e:
56
- if self.handle_stop_fail(
57
- retry_limit=self.state_machine.stop_robot_attempts_limit,
58
- error_message=ErrorMessage(
59
- error_reason=e.error_reason,
60
- error_description=e.error_description,
61
- ),
62
- ):
63
- transition = self.state_machine.mission_stopped # type: ignore
64
- break
65
-
66
- self.logger.warning(
67
- f"\nFailed to stop robot because: {e.error_description}"
68
- f"\nAttempting to stop the robot again"
69
- )
70
-
71
- self.stop_thread = None
72
- continue
73
- if self.state_machine.stopped:
74
- transition = self.state_machine.mission_stopped # type: ignore
75
- else:
76
- transition = self.state_machine.mission_paused # type: ignore
77
- break
78
-
79
- transition()
80
-
81
- def handle_stop_fail(self, retry_limit: int, error_message: ErrorMessage) -> bool:
82
- self._count_number_retries += 1
83
- if self._count_number_retries > retry_limit:
84
- self.state_machine.current_step.error_message = error_message
85
-
86
- self.logger.error(
87
- f"\nFailed to stop the robot after {retry_limit} attempts because: "
88
- f"{error_message.error_description}"
89
- f"\nBe aware that the robot may still be moving even though a stop has "
90
- "been attempted"
91
- )
92
-
93
- return True
94
- time.sleep(self.state_machine.sleep_time)
95
- return False
@@ -1,191 +0,0 @@
1
- import json
2
- import logging
3
-
4
- from azure.identity import DefaultAzureCredential
5
- from injector import inject
6
- from requests import HTTPError, RequestException
7
- from requests_toolbelt import MultipartEncoder
8
-
9
- from isar.config.settings import settings
10
- from isar.services.auth.azure_credentials import AzureCredentials
11
- from isar.services.service_connections.request_handler import RequestHandler
12
- from isar.storage.storage_interface import StorageException, StorageInterface
13
- from isar.storage.utilities import get_filename
14
- from robot_interface.models.inspection.inspection import Inspection, ThermalVideo, Video
15
- from robot_interface.models.mission.mission import Mission
16
-
17
-
18
- class SlimmStorage(StorageInterface):
19
- @inject
20
- def __init__(self, request_handler: RequestHandler) -> None:
21
- self.request_handler: RequestHandler = request_handler
22
- self.logger = logging.getLogger("uploader")
23
-
24
- self.credentials: DefaultAzureCredential = (
25
- AzureCredentials.get_azure_credentials()
26
- )
27
-
28
- client_id: str = settings.SLIMM_CLIENT_ID
29
- scope: str = settings.SLIMM_APP_SCOPE
30
- self.request_scope: str = f"{client_id}/{scope}"
31
-
32
- self.url: str = settings.SLIMM_API_URL
33
-
34
- def store(self, inspection: Inspection, mission: Mission) -> str:
35
- filename: str = get_filename(
36
- inspection=inspection,
37
- )
38
- filename = f"{filename}.{inspection.metadata.file_type}"
39
- if type(inspection) in [Video, ThermalVideo]:
40
- inspection_path = self._store_video(filename, inspection, mission)
41
- else:
42
- inspection_path = self._store_image(filename, inspection, mission)
43
- return inspection_path
44
-
45
- def _store_image(
46
- self, filename: str, inspection: Inspection, mission: Mission
47
- ) -> str:
48
- multiform_body: MultipartEncoder = self._construct_multiform_request_image(
49
- filename=filename, inspection=inspection, mission=mission
50
- )
51
- request_url: str = f"{self.url}/UploadSingleImage"
52
- inspection_path = self._ingest(
53
- inspection=inspection,
54
- multiform_body=multiform_body,
55
- request_url=request_url,
56
- )
57
- return inspection_path
58
-
59
- def _store_video(
60
- self, filename: str, inspection: Inspection, mission: Mission
61
- ) -> str:
62
- multiform_body: MultipartEncoder = self._construct_multiform_request_video(
63
- filename=filename, inspection=inspection, mission=mission
64
- )
65
- request_url = f"{self.url}/UploadSingleVideo"
66
- inspection_path = self._ingest(
67
- inspection=inspection,
68
- multiform_body=multiform_body,
69
- request_url=request_url,
70
- )
71
- return inspection_path
72
-
73
- def _ingest(
74
- self, inspection: Inspection, multiform_body: MultipartEncoder, request_url: str
75
- ) -> str:
76
- token: str = self.credentials.get_token(self.request_scope).token
77
- try:
78
- response = self.request_handler.post(
79
- url=request_url,
80
- data=multiform_body,
81
- headers={
82
- "Authorization": f"Bearer {token}",
83
- "Content-Type": multiform_body.content_type,
84
- },
85
- )
86
- guid = json.loads(response.text)["guid"]
87
- self.logger.info(f"SLIMM upload GUID: {guid}")
88
- except (RequestException, HTTPError) as e:
89
- self.logger.warning(
90
- f"Failed to upload inspection: {inspection.id} to SLIMM due to a "
91
- f"request exception"
92
- )
93
- raise StorageException from e
94
- data = json.loads(response.content)
95
- return data["guid"]
96
-
97
- @staticmethod
98
- def _construct_multiform_request_image(
99
- filename: str, inspection: Inspection, mission: Mission
100
- ):
101
- array_of_orientation = (
102
- inspection.metadata.pose.orientation.to_quat_array().tolist()
103
- )
104
- multiform_body: MultipartEncoder = MultipartEncoder(
105
- fields={
106
- "PlantFacilitySAPCode": settings.PLANT_CODE,
107
- "InstCode": settings.PLANT_SHORT_NAME,
108
- "InternalClassification": settings.DATA_CLASSIFICATION,
109
- "IsoCountryCode": "NO",
110
- "Geodetic.CoordinateReferenceSystemCode": settings.COORDINATE_REFERENCE_SYSTEM, # noqa: E501
111
- "Geodetic.VerticalCoordinateReferenceSystemCode": settings.VERTICAL_REFERENCE_SYSTEM, # noqa: E501
112
- "Geodetic.OrientationReferenceSystem": settings.MEDIA_ORIENTATION_REFERENCE_SYSTEM, # noqa: E501
113
- "SensorCarrier.SensorCarrierId": settings.ISAR_ID,
114
- "SensorCarrier.ModelName": settings.ROBOT_TYPE,
115
- "Mission.MissionId": mission.id,
116
- "Mission.Client": "Equinor",
117
- "ImageMetadata.Timestamp": inspection.metadata.start_time.isoformat(), # noqa: E501
118
- "ImageMetadata.X": str(inspection.metadata.pose.position.x),
119
- "ImageMetadata.Y": str(inspection.metadata.pose.position.y),
120
- "ImageMetadata.Z": str(inspection.metadata.pose.position.z),
121
- "ImageMetadata.CameraOrientation1": str(array_of_orientation[0]),
122
- "ImageMetadata.CameraOrientation2": str(array_of_orientation[1]),
123
- "ImageMetadata.CameraOrientation3": str(array_of_orientation[2]),
124
- "ImageMetadata.CameraOrientation4": str(array_of_orientation[3]),
125
- "ImageMetadata.AnalysisMethods": (
126
- inspection.metadata.additional["analysis_type"]
127
- if inspection.metadata.additional
128
- and inspection.metadata.additional["analysis_type"]
129
- else "N/A"
130
- ),
131
- "ImageMetadata.Description": str(inspection.metadata.additional),
132
- "ImageMetadata.FunctionalLocation": (
133
- inspection.metadata.tag_id # noqa: E501
134
- if inspection.metadata.tag_id
135
- else "N/A"
136
- ),
137
- "Filename": filename,
138
- "AttachedFile": (filename, inspection.data),
139
- }
140
- )
141
- return multiform_body
142
-
143
- @staticmethod
144
- def _construct_multiform_request_video(
145
- filename: str,
146
- inspection: Inspection,
147
- mission: Mission,
148
- ):
149
- array_of_orientation = (
150
- inspection.metadata.pose.orientation.to_quat_array().tolist()
151
- )
152
- multiform_body: MultipartEncoder = MultipartEncoder(
153
- fields={
154
- "PlantFacilitySAPCode": settings.PLANT_CODE,
155
- "InstCode": settings.PLANT_SHORT_NAME,
156
- "InternalClassification": settings.DATA_CLASSIFICATION,
157
- "IsoCountryCode": "NO",
158
- "Geodetic.CoordinateReferenceSystemCode": settings.COORDINATE_REFERENCE_SYSTEM, # noqa: E501
159
- "Geodetic.VerticalCoordinateReferenceSystemCode": settings.VERTICAL_REFERENCE_SYSTEM, # noqa: E501
160
- "Geodetic.OrientationReferenceSystem": settings.MEDIA_ORIENTATION_REFERENCE_SYSTEM, # noqa: E501
161
- "SensorCarrier.SensorCarrierId": settings.ISAR_ID,
162
- "SensorCarrier.ModelName": settings.ROBOT_TYPE,
163
- "Mission.MissionId": mission.id,
164
- "Mission.Client": "Equinor",
165
- "VideoMetadata.Timestamp": inspection.metadata.start_time.isoformat(), # noqa: E501
166
- # Converting to int because SLIMM expects an int, while we use floats in operations.
167
- "VideoMetadata.Duration": str(int(inspection.metadata.duration)), # type: ignore
168
- "VideoMetadata.X": str(inspection.metadata.pose.position.x),
169
- "VideoMetadata.Y": str(inspection.metadata.pose.position.y),
170
- "VideoMetadata.Z": str(inspection.metadata.pose.position.z),
171
- "VideoMetadata.CameraOrientation1": str(array_of_orientation[0]),
172
- "VideoMetadata.CameraOrientation2": str(array_of_orientation[1]),
173
- "VideoMetadata.CameraOrientation3": str(array_of_orientation[2]),
174
- "VideoMetadata.CameraOrientation4": str(array_of_orientation[3]),
175
- "VideoMetadata.AnalysisMethods": (
176
- inspection.metadata.additional["analysis_type"]
177
- if inspection.metadata.additional
178
- and inspection.metadata.additional["analysis_type"]
179
- else "N/A"
180
- ),
181
- "VideoMetadata.Description": str(inspection.metadata.additional),
182
- "VideoMetadata.FunctionalLocation": (
183
- inspection.metadata.tag_id # noqa: E501
184
- if inspection.metadata.tag_id
185
- else "N/A"
186
- ),
187
- "Filename": filename,
188
- "AttachedFile": (filename, inspection.data),
189
- }
190
- )
191
- return multiform_body
@@ -1,116 +0,0 @@
1
- isar/__init__.py,sha256=cH8p8bVveu3FUL6kBhldcSlLaoHgD82Kd0-SwSNfGXw,87
2
- isar/modules.py,sha256=aO8bLSC4i_Qo4bOJ6aFfwAZRTJAw8o9SOOfkceUGCiU,6708
3
- isar/script.py,sha256=145KXMqKWkP5SjB2MyvO1HmIPJnFOQdwwWM3jy6s-9A,5260
4
- isar/apis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- isar/apis/api.py,sha256=vSXfkWR7iITWbh4BsDzjEDtQrz6KS-vi2S8AeaeDc3Q,13112
6
- isar/apis/models/__init__.py,sha256=NI1BYyN__Ogr00Qqe0XJ-9gEVPva2brXo2RJsbrS4tM,52
7
- isar/apis/models/models.py,sha256=BRm3Wl6TJHdHEKLRQ2SGDx6Y54qq8IesMbBuVO7RuxE,1757
8
- isar/apis/models/start_mission_definition.py,sha256=GuihnkVRXjzopMEiRQ4rOfeCGw98IFK9EYylB-5S0aI,7253
9
- isar/apis/schedule/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- isar/apis/schedule/scheduling_controller.py,sha256=w2F-6IKBgVN9HVopAOWBb3KUgPjhsnuPLQ3eqjDNfOg,11888
11
- isar/apis/security/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- isar/apis/security/authentication.py,sha256=TI8U9Y_L6ihHLMeM50ZONd5EPfuHdw_XMU_Q987W4AY,1975
13
- isar/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
- isar/config/configuration_error.py,sha256=rO6WOhafX6xvVib8WxV-eY483Z0PpN-9PxGsq5ATfKc,46
15
- isar/config/log.py,sha256=zHFLmGWQRn8TrcsxUS6KHpJt2JE86kYazU7b-bkcN9o,2285
16
- isar/config/logging.conf,sha256=mYO1xf27gAopEMHhGzY7-mwyfN16rwRLkPNMvy3zn2g,1127
17
- isar/config/settings.env,sha256=-kivj0osAAKlInnY81ugySTlcImhVABbnj9kUoBDLu8,535
18
- isar/config/settings.py,sha256=pZrZGe60WoMNl_SlCzJFavU3Qqil_ocCuaKcKfDn0KM,13175
19
- isar/config/certs/ca-cert.pem,sha256=gSBTyY0tKSFnssyvrvbFvHpQwii0kEkBryklVmevdtc,2029
20
- isar/config/keyvault/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
- isar/config/keyvault/keyvault_error.py,sha256=zvPCsZLjboxsxthYkxpRERCTFxYV8R5WmACewAUQLwk,41
22
- isar/config/keyvault/keyvault_service.py,sha256=b2EWNiNQmZ-FUWjZidNg5KXRcVH-U8CsiqcBf1devNw,3124
23
- isar/config/maps/JSP1_intermediate_deck.json,sha256=fdotzN6MVotyLbqpIjRSrbBYM84vogLkdS585NjBnL8,826
24
- isar/config/maps/JSP1_weather_deck.json,sha256=_dG3cSBI8q4_uHqHMOO5kSYqMXn85JL3_9PaH4uk1yQ,832
25
- isar/config/maps/default_map.json,sha256=3CdGMr0Qn3PrL4TfUK8I5a-hotMrS_n5DKfaEORJPT4,776
26
- isar/config/maps/klab_b.json,sha256=qXgWVUYPaTdVuomf6lQL-uRbV3Tsa6CftnzcbT3dY78,842
27
- isar/config/maps/klab_compressor.json,sha256=1Vrk5u_l4WXjrTtG4YfXlrCPbOoRs4TtYHOm0430u2A,803
28
- isar/config/maps/klab_turtlebot.json,sha256=HcB79XFEdY0Wm96EssIFO4TMyAWzc2KENoqN7TbTT0k,823
29
- isar/config/maps/turtleworld.json,sha256=EKLMpSK9Gu2lAN-E9l41XOaO3f9Su5n_I97mA6z7sWY,764
30
- isar/config/predefined_mission_definition/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
- isar/config/predefined_mission_definition/default_exr.json,sha256=L3-kqjfgXoULDUgGsD3Zci7m3wdbwAuSrn4yaH4aPIA,1667
32
- isar/config/predefined_mission_definition/default_mission.json,sha256=nEk1ql17RAs2I5Ws2wA-0GJ6oqJco-Q0Q0vhf4k6ajc,2926
33
- isar/config/predefined_mission_definition/default_turtlebot.json,sha256=Ka379MLu8qiGIa6Fu-8p8A4OgHVccLkKYSX0RthUOeI,4060
34
- isar/config/predefined_missions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
- isar/config/predefined_missions/default.json,sha256=3J1KtQIFKxJsVoKlg0nKsj8asev-2dSz6IOrd4A57jY,2759
36
- isar/config/predefined_missions/default_turtlebot.json,sha256=gStYz_hCgQDBEeUW7W4bq_0R3OO55jRnwZt0CNYvHSM,3352
37
- isar/config/predefined_poses/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
- isar/config/predefined_poses/predefined_poses.py,sha256=fhq8JF00feDLFKNBlyWeFoLfvfs5dVb__C7CmiVbwmQ,25779
39
- isar/mission_planner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
- isar/mission_planner/local_planner.py,sha256=1Qcz7QntWXuYL1PcF6R9aZNCCdL-j_RJ2UGc1_rNZd8,3037
41
- isar/mission_planner/mission_planner_interface.py,sha256=51k6KKXqC8wZ4Mc8ZWo00Nwy8c6yNa81nEZNZelwJeo,485
42
- isar/mission_planner/sequential_task_selector.py,sha256=4OJ1Rvg6MaDQQxNcgAUtp2gvhHm3Srha5XJUu8X-Uzg,640
43
- isar/mission_planner/task_selector_interface.py,sha256=aXL2RXb_XmTNW-WXt6E7wFfJf_BjbownDa3zSqgQ4Ww,703
44
- isar/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
- isar/models/communication/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
- isar/models/communication/message.py,sha256=yN4SXYM-W_6u3Cf9yuAE3jy4e6mMrL3yUr-iVV4r55E,241
47
- isar/models/communication/queues/__init__.py,sha256=JqwWbdBQnBeIEhSTjBOkl-O3bYBVBSmjPcWUdscsobw,146
48
- isar/models/communication/queues/queue_io.py,sha256=AnHWUCkZ0tunkxKKeBarq-OUkRM97IaMfA-a1pmf1cQ,394
49
- isar/models/communication/queues/queue_timeout_error.py,sha256=rF8TlNF7RHS_ueTZ5mp7aFkhLY1j0dcwMwH-Ba6lVpE,45
50
- isar/models/communication/queues/queues.py,sha256=FzoqlT4AQ4Q5Jufh6yRPV2uq5iUZd1odrpjBl77yU5o,803
51
- isar/models/communication/queues/status_queue.py,sha256=K_i01uzCu1eciDt9QlDXLBINJnuRLqm6fzrM-PY6qD0,467
52
- isar/models/mission_metadata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
- isar/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
- isar/services/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
- isar/services/auth/azure_credentials.py,sha256=9PlwGe5FrPRbW2dp0go7LMp8_l_FRvL8xOXotXwzRDo,364
56
- isar/services/readers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
- isar/services/readers/base_reader.py,sha256=_fNd5fb5dFeMtOvfWzIAGO-KIgl3zT19iEuzSjeZNPc,987
58
- isar/services/service_connections/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
- isar/services/service_connections/request_handler.py,sha256=0LxC0lu_HXeEf_xmJWjfEsh14oAUI97cpG1IWtBlcs4,4278
60
- isar/services/service_connections/mqtt/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
61
- isar/services/service_connections/mqtt/mqtt_client.py,sha256=Aib0lqaddxW9aVXXYD7wGL9jIpr2USCCH91SQgFdIG4,3548
62
- isar/services/service_connections/mqtt/robot_heartbeat_publisher.py,sha256=0Qjo2wRZZoooXG-UE4z8YJc9QCCz6v-9YAqHRJgx-kE,1005
63
- isar/services/service_connections/mqtt/robot_info_publisher.py,sha256=f1vhBNPlx6p3Au8l7OsWIJXRM_xjA8qcLHvnkwCtRBM,1388
64
- isar/services/service_connections/stid/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
65
- isar/services/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
66
- isar/services/utilities/queue_utilities.py,sha256=Pw3hehSwkXJNeDv-bDVDfs58VOwtt3i5hpiJ2ZpphuQ,1225
67
- isar/services/utilities/scheduling_utilities.py,sha256=LFimEmacML3J9q-FNLfKPhcAr-R3f2rkYkbsoro0Gyo,8434
68
- isar/services/utilities/threaded_request.py,sha256=py4G-_RjnIdHljmKFAcQ6ddqMmp-ZYV39Ece-dqRqjs,1874
69
- isar/state_machine/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
70
- isar/state_machine/state_machine.py,sha256=-i7m2xVcgL3cW6AIMGAom97wzt433MXM8EQEGUykAJA,23653
71
- isar/state_machine/states_enum.py,sha256=BlrUcBWkM5K6D_UZXRwTaUgGpAagWmVZH6HhDBGzVU4,278
72
- isar/state_machine/states/__init__.py,sha256=kErbKPDTwNfCLijvdyN6_AuOqDwR23nu9F0Qovsnir4,218
73
- isar/state_machine/states/idle.py,sha256=_nrM17s4artaHezanl28_WcNyJod1_hkCyzAqZlPQiE,3034
74
- isar/state_machine/states/initialize.py,sha256=KUuyXVwzWK5bJNspA1JnYO_Xwu8fPPK6bnHK4mtwf5A,2359
75
- isar/state_machine/states/initiate.py,sha256=WqBROOGAh0DVB0f39RFkpqzkr0qrHMyrBGkh2svBbKw,5652
76
- isar/state_machine/states/monitor.py,sha256=t0wtRPrjnWnGQ8JXia7kLkSc8tyd33mBI7UDDAsJ6FM,10874
77
- isar/state_machine/states/off.py,sha256=jjqN_oJMpBtWuY7hP-c9f0w3p2CYCfe-NpmYHHPnmyI,544
78
- isar/state_machine/states/offline.py,sha256=wEMMIwM4JWfmDjI7pe9yKce_Mfz9aXqs6WEkxn8cx5I,2125
79
- isar/state_machine/states/paused.py,sha256=HqrvONw6r6AoYPUyFGGOy2ToT7Tid8JEw2pKp2ZhZ7Y,1004
80
- isar/state_machine/states/stop.py,sha256=zu7bVKR5zfkzU7iCrh8Pe2WRDHHzU2RBeFBxFK6Z-eA,3348
81
- isar/storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
82
- isar/storage/blob_storage.py,sha256=oKdml1VVN8iTr-d_5H4Lz5E7zrhJRknCzOxHD-tO7m8,3230
83
- isar/storage/local_storage.py,sha256=Bnmoi5gyN8r-oRh0aHrOdGqaH3JqRScFKMRXYojW5kY,1855
84
- isar/storage/slimm_storage.py,sha256=Hp7ZIgZgIR4KAFjzxDKfgMZjPZwP2kmdc1gG8zVcsMk,8966
85
- isar/storage/storage_interface.py,sha256=DYDry4I7aZpDHJhsBF6s8zrgokFAc7fdKJKfA8AvL7o,828
86
- isar/storage/uploader.py,sha256=te3GyiSeu96MhbiqQ7ueIMUPLSKblx3UqYAshkxfVIE,6368
87
- isar/storage/utilities.py,sha256=eTyY56WCTda5YswE9znWNeNEoTbT3jokNbwcLVmmQjA,3113
88
- robot_interface/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
89
- robot_interface/robot_interface.py,sha256=i2qw1V9mLO-ljtS7LiRliQ7XNmmBJIwD4NG8mDfwMEI,8317
90
- robot_interface/test_robot_interface.py,sha256=FV1urn7SbsMyWBIcTKjsBwAG4IsXeZ6pLHE0mA9EGGs,692
91
- robot_interface/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
92
- robot_interface/models/exceptions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
93
- robot_interface/models/exceptions/robot_exceptions.py,sha256=l1h62gq7lfLzWoHh2ytdEWgn_4lS4M-GPxHkjgAXcP4,9036
94
- robot_interface/models/initialize/__init__.py,sha256=rz5neEDr59GDbzzI_FF0DId-C-I-50l113P-h-C_QBY,48
95
- robot_interface/models/initialize/initialize_params.py,sha256=2eG5Aq5bDKU6tVkaUMAoc46GERBgyaKkqv6yLupdRLc,164
96
- robot_interface/models/inspection/__init__.py,sha256=14wfuj4XZazrigKD7fL98khFKz-eckIpEgPcYRj40Kg,227
97
- robot_interface/models/inspection/inspection.py,sha256=TVqUl5o3d3fp8IravOMwJIuRoEU8y4BltFrF1IkwvTA,2176
98
- robot_interface/models/mission/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
99
- robot_interface/models/mission/mission.py,sha256=xJ7i79TQkmO0Tv2IQeguhyliNP2J42ziS5iO-FyBpW0,839
100
- robot_interface/models/mission/status.py,sha256=R5jLmmn6M7oNX907QvbrhoAqAo4C1zB653Ed1PcxAtg,922
101
- robot_interface/models/mission/step.py,sha256=DEzU-LD-i3RTAaXBy5KwJZ6OnN5S0F3wwDaqX2DZ72M,5587
102
- robot_interface/models/mission/task.py,sha256=JJ062AIdwVoj3PUkWYmJDvRl5B7Tcu9S11J2F_0tfjE,4695
103
- robot_interface/models/robots/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
104
- robot_interface/models/robots/robot_model.py,sha256=pZQsqhn9hh6XE3EjMZhWMzYqg5oJ4CJ4CXeOASKvEf8,452
105
- robot_interface/telemetry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
106
- robot_interface/telemetry/mqtt_client.py,sha256=AHBmOpVvoo6pY5uXwyBY7SooN_cnpuS0DMkfLUPwpl8,2743
107
- robot_interface/telemetry/payloads.py,sha256=eMK7mjZPsLY6yvu7AK-OcdvkeUpChzDrySDY7IjQ9RM,1464
108
- robot_interface/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
109
- robot_interface/utilities/json_service.py,sha256=nU2Q_3P9Fq9hs6F_wtUjWtHfl_g1Siy-yDhXXSKwHwg,1018
110
- robot_interface/utilities/uuid_string_factory.py,sha256=_NQIbBQ56w0qqO0MUDP6aPpHbxW7ATRhK8HnQiBSLkc,76
111
- isar-1.20.2.dist-info/LICENSE,sha256=3fc2-ebLwHWwzfQbulGNRdcNob3SBQeCfEVUDYxsuqw,14058
112
- isar-1.20.2.dist-info/METADATA,sha256=eGOpcvDhrvMdIocMCNNBxUQ_9q4Z_F_1aZOu9kNisiI,30574
113
- isar-1.20.2.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
114
- isar-1.20.2.dist-info/entry_points.txt,sha256=TFam7uNNw7J0iiDYzsH2gfG0u1eV1wh3JTw_HkhgKLk,49
115
- isar-1.20.2.dist-info/top_level.txt,sha256=UwIML2RtuQKCyJJkatcSnyp6-ldDjboB9k9JgKipO-U,21
116
- isar-1.20.2.dist-info/RECORD,,
@@ -1 +0,0 @@
1
- from .initialize_params import InitializeParams
@@ -1,9 +0,0 @@
1
- from dataclasses import dataclass
2
- from typing import Optional
3
-
4
- from alitra import Pose
5
-
6
-
7
- @dataclass
8
- class InitializeParams:
9
- initial_pose: Optional[Pose] = None