isar 1.15.0__py3-none-any.whl → 1.34.9__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 (129) hide show
  1. isar/__init__.py +2 -5
  2. isar/apis/api.py +159 -66
  3. isar/apis/models/__init__.py +0 -1
  4. isar/apis/models/models.py +22 -12
  5. isar/apis/models/start_mission_definition.py +128 -123
  6. isar/apis/robot_control/robot_controller.py +41 -0
  7. isar/apis/schedule/scheduling_controller.py +135 -121
  8. isar/apis/security/authentication.py +5 -5
  9. isar/config/certs/ca-cert.pem +32 -32
  10. isar/config/keyvault/keyvault_service.py +1 -2
  11. isar/config/log.py +47 -39
  12. isar/config/logging.conf +16 -31
  13. isar/config/open_telemetry.py +102 -0
  14. isar/config/predefined_mission_definition/default_exr.json +49 -0
  15. isar/config/predefined_mission_definition/default_mission.json +1 -5
  16. isar/config/predefined_mission_definition/default_turtlebot.json +4 -11
  17. isar/config/predefined_missions/default.json +67 -87
  18. isar/config/predefined_missions/default_extra_capabilities.json +107 -0
  19. isar/config/settings.py +119 -142
  20. isar/eventhandlers/eventhandler.py +123 -0
  21. isar/mission_planner/local_planner.py +6 -20
  22. isar/mission_planner/mission_planner_interface.py +1 -1
  23. isar/models/events.py +184 -0
  24. isar/models/status.py +18 -0
  25. isar/modules.py +118 -205
  26. isar/robot/robot.py +377 -0
  27. isar/robot/robot_battery.py +60 -0
  28. isar/robot/robot_monitor_mission.py +357 -0
  29. isar/robot/robot_pause_mission.py +74 -0
  30. isar/robot/robot_resume_mission.py +67 -0
  31. isar/robot/robot_start_mission.py +66 -0
  32. isar/robot/robot_status.py +61 -0
  33. isar/robot/robot_stop_mission.py +68 -0
  34. isar/robot/robot_upload_inspection.py +75 -0
  35. isar/script.py +171 -0
  36. isar/services/service_connections/mqtt/mqtt_client.py +47 -11
  37. isar/services/service_connections/mqtt/robot_heartbeat_publisher.py +32 -0
  38. isar/services/service_connections/mqtt/robot_info_publisher.py +4 -3
  39. isar/services/service_connections/persistent_memory.py +69 -0
  40. isar/services/utilities/mqtt_utilities.py +93 -0
  41. isar/services/utilities/robot_utilities.py +20 -0
  42. isar/services/utilities/scheduling_utilities.py +393 -65
  43. isar/state_machine/state_machine.py +227 -486
  44. isar/state_machine/states/__init__.py +0 -7
  45. isar/state_machine/states/await_next_mission.py +114 -0
  46. isar/state_machine/states/blocked_protective_stop.py +60 -0
  47. isar/state_machine/states/going_to_lockdown.py +95 -0
  48. isar/state_machine/states/going_to_recharging.py +92 -0
  49. isar/state_machine/states/home.py +115 -0
  50. isar/state_machine/states/intervention_needed.py +77 -0
  51. isar/state_machine/states/lockdown.py +38 -0
  52. isar/state_machine/states/maintenance.py +36 -0
  53. isar/state_machine/states/monitor.py +137 -166
  54. isar/state_machine/states/offline.py +60 -0
  55. isar/state_machine/states/paused.py +92 -23
  56. isar/state_machine/states/pausing.py +48 -0
  57. isar/state_machine/states/pausing_return_home.py +48 -0
  58. isar/state_machine/states/recharging.py +80 -0
  59. isar/state_machine/states/resuming.py +57 -0
  60. isar/state_machine/states/resuming_return_home.py +64 -0
  61. isar/state_machine/states/return_home_paused.py +109 -0
  62. isar/state_machine/states/returning_home.py +217 -0
  63. isar/state_machine/states/stopping.py +61 -0
  64. isar/state_machine/states/stopping_due_to_maintenance.py +61 -0
  65. isar/state_machine/states/stopping_go_to_lockdown.py +60 -0
  66. isar/state_machine/states/stopping_go_to_recharge.py +51 -0
  67. isar/state_machine/states/stopping_return_home.py +77 -0
  68. isar/state_machine/states/unknown_status.py +72 -0
  69. isar/state_machine/states_enum.py +22 -5
  70. isar/state_machine/transitions/mission.py +192 -0
  71. isar/state_machine/transitions/return_home.py +106 -0
  72. isar/state_machine/transitions/robot_status.py +80 -0
  73. isar/state_machine/utils/common_event_handlers.py +73 -0
  74. isar/storage/blob_storage.py +71 -45
  75. isar/storage/local_storage.py +28 -14
  76. isar/storage/storage_interface.py +28 -6
  77. isar/storage/uploader.py +184 -55
  78. isar/storage/utilities.py +35 -27
  79. isar-1.34.9.dist-info/METADATA +496 -0
  80. isar-1.34.9.dist-info/RECORD +135 -0
  81. {isar-1.15.0.dist-info → isar-1.34.9.dist-info}/WHEEL +1 -1
  82. isar-1.34.9.dist-info/entry_points.txt +3 -0
  83. robot_interface/models/exceptions/__init__.py +0 -7
  84. robot_interface/models/exceptions/robot_exceptions.py +274 -4
  85. robot_interface/models/initialize/__init__.py +0 -1
  86. robot_interface/models/inspection/__init__.py +0 -13
  87. robot_interface/models/inspection/inspection.py +43 -34
  88. robot_interface/models/mission/mission.py +18 -14
  89. robot_interface/models/mission/status.py +20 -25
  90. robot_interface/models/mission/task.py +156 -92
  91. robot_interface/models/robots/battery_state.py +6 -0
  92. robot_interface/models/robots/media.py +13 -0
  93. robot_interface/models/robots/robot_model.py +7 -7
  94. robot_interface/robot_interface.py +135 -66
  95. robot_interface/telemetry/mqtt_client.py +84 -12
  96. robot_interface/telemetry/payloads.py +111 -12
  97. robot_interface/utilities/json_service.py +7 -1
  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 -26
  102. isar/mission_planner/sequential_task_selector.py +0 -23
  103. isar/mission_planner/task_selector_interface.py +0 -31
  104. isar/models/communication/__init__.py +0 -0
  105. isar/models/communication/message.py +0 -12
  106. isar/models/communication/queues/__init__.py +0 -4
  107. isar/models/communication/queues/queue_io.py +0 -12
  108. isar/models/communication/queues/queue_timeout_error.py +0 -2
  109. isar/models/communication/queues/queues.py +0 -19
  110. isar/models/communication/queues/status_queue.py +0 -20
  111. isar/models/mission_metadata/__init__.py +0 -0
  112. isar/services/readers/__init__.py +0 -0
  113. isar/services/readers/base_reader.py +0 -37
  114. isar/services/service_connections/mqtt/robot_status_publisher.py +0 -93
  115. isar/services/service_connections/stid/__init__.py +0 -0
  116. isar/services/service_connections/stid/stid_service.py +0 -45
  117. isar/services/utilities/queue_utilities.py +0 -39
  118. isar/state_machine/states/idle.py +0 -40
  119. isar/state_machine/states/initialize.py +0 -60
  120. isar/state_machine/states/initiate.py +0 -129
  121. isar/state_machine/states/off.py +0 -18
  122. isar/state_machine/states/stop.py +0 -78
  123. isar/storage/slimm_storage.py +0 -181
  124. isar-1.15.0.dist-info/METADATA +0 -417
  125. isar-1.15.0.dist-info/RECORD +0 -113
  126. robot_interface/models/initialize/initialize_params.py +0 -9
  127. robot_interface/models/mission/step.py +0 -211
  128. {isar-1.15.0.dist-info → isar-1.34.9.dist-info/licenses}/LICENSE +0 -0
  129. {isar-1.15.0.dist-info → isar-1.34.9.dist-info}/top_level.txt +0 -0
@@ -1,7 +0,0 @@
1
- from .robot_exceptions import (
2
- RobotCommunicationException,
3
- RobotException,
4
- RobotInfeasibleMissionException,
5
- RobotInfeasibleStepException,
6
- RobotInvalidResponseException,
7
- )
@@ -1,26 +1,296 @@
1
+ from dataclasses import dataclass
2
+ from enum import Enum
3
+ from typing import Optional
4
+
5
+
6
+ class ErrorReason(str, Enum):
7
+ RobotCommunicationException = "robot_communication_exception"
8
+ RobotCommunicationTimeoutException = "robot_communication_timeout_exception"
9
+ RobotInfeasibleTaskException = "robot_infeasible_task_exception"
10
+ RobotInfeasibleMissionException = "robot_infeasible_mission_exception"
11
+ RobotUnreliableDockingStatusException = "robot_unreliable_docking_status_exception"
12
+ RobotMissionStatusException = "robot_mission_status_exception"
13
+ RobotTaskStatusException = "robot_task_status_exception"
14
+ RobotAPIException = "robot_api_exception"
15
+ RobotActionException = "robot_action_exception"
16
+ RobotRetrieveDataException = "robot_retrieve_data_exception"
17
+ RobotRetrieveInspectionException = "robot_retrieve_inspection_exception"
18
+ RobotStillStartingMissionException = "robot_still_starting_mission_exception"
19
+ RobotTelemetryException = "robot_telemetry_exception"
20
+ RobotTelemetryNoUpdateException = "robot_telemetry_no_update_exception"
21
+ RobotTelemetryPoseException = "robot_telemetry_pose_exception"
22
+ RobotMapException = "robot_map_exception"
23
+ RobotTransformException = "robot_transform_exception"
24
+ RobotUnknownErrorException = "robot_unknown_error_exception"
25
+ RobotDisconnectedException = "robot_disconnected_exception"
26
+ RobotNoMissionRunningException = "robot_no_mission_running_exception"
27
+ RobotAlreadyHomeException = "robot_already_home_exception"
28
+
29
+
30
+ @dataclass
31
+ class ErrorMessage:
32
+ error_reason: Optional[ErrorReason]
33
+ error_description: str
34
+
35
+
36
+ # This is the base exception class for exceptions that should be raised from the robot
37
+ # package and handled in ISAR. Please peruse the different subclasses for information
38
+ # on which exceptions to use where.
1
39
  class RobotException(Exception):
2
- pass
40
+ def __init__(self, error_reason: ErrorReason, error_description: str):
41
+ self.error_reason: ErrorReason = error_reason
42
+ self.error_description: str = error_description
3
43
 
4
44
 
45
+ # An exception which should be thrown by the robot package if it is unable to
46
+ # communicate with the robot API. ISAR will retry the request.
5
47
  class RobotCommunicationException(RobotException):
48
+ def __init__(self, error_description: str) -> None:
49
+ super().__init__(
50
+ error_reason=ErrorReason.RobotCommunicationException,
51
+ error_description=error_description,
52
+ )
53
+
6
54
  pass
7
55
 
8
56
 
9
- class RobotInfeasibleStepException(RobotException):
57
+ # An exception which should be thrown by the robot package if it is unable to
58
+ # complete a request as there is no ongoing mission.
59
+ class RobotNoMissionRunningException(RobotException):
60
+ def __init__(self, error_description: str) -> None:
61
+ super().__init__(
62
+ error_reason=ErrorReason.RobotNoMissionRunningException,
63
+ error_description=error_description,
64
+ )
65
+
10
66
  pass
11
67
 
12
68
 
69
+ # An exception which should be thrown by the robot package if the communication has timed
70
+ # out and ISAR should retry the request.
71
+ class RobotCommunicationTimeoutException(RobotException):
72
+ def __init__(self, error_description: str) -> None:
73
+ super().__init__(
74
+ error_reason=ErrorReason.RobotCommunicationTimeoutException,
75
+ error_description=error_description,
76
+ )
77
+
78
+ pass
79
+
80
+
81
+ # An exception which should be thrown by the robot package if it is unable to start the
82
+ # current task.
83
+ class RobotInfeasibleTaskException(RobotException):
84
+ def __init__(self, error_description: str) -> None:
85
+ super().__init__(
86
+ error_reason=ErrorReason.RobotInfeasibleTaskException,
87
+ error_description=error_description,
88
+ )
89
+
90
+ pass
91
+
92
+
93
+ # An exception which should be thrown by the robot package if it is unable to start the
94
+ # current mission.
13
95
  class RobotInfeasibleMissionException(RobotException):
96
+ def __init__(self, error_description: str) -> None:
97
+ super().__init__(
98
+ error_reason=ErrorReason.RobotInfeasibleMissionException,
99
+ error_description=error_description,
100
+ )
101
+
14
102
  pass
15
103
 
16
104
 
17
- class RobotInvalidResponseException(RobotException):
105
+ class RobotUnreliableDockingStatusException(RobotException):
106
+ def __init__(self, error_description: str) -> None:
107
+ super().__init__(
108
+ error_reason=ErrorReason.RobotUnreliableDockingStatusException,
109
+ error_description=error_description,
110
+ )
111
+
18
112
  pass
19
113
 
20
114
 
115
+ # An exception which should be thrown by the robot package if it is unable to collect
116
+ # the status of the current mission.
117
+ class RobotMissionStatusException(RobotException):
118
+ def __init__(self, error_description: str) -> None:
119
+ super().__init__(
120
+ error_reason=ErrorReason.RobotMissionStatusException,
121
+ error_description=error_description,
122
+ )
123
+
124
+ pass
125
+
126
+
127
+ # An exception which should be thrown by the robot package if it is unable to collect
128
+ # the status of the current task.
129
+ class RobotTaskStatusException(RobotException):
130
+ def __init__(self, error_description: str) -> None:
131
+ super().__init__(
132
+ error_reason=ErrorReason.RobotTaskStatusException,
133
+ error_description=error_description,
134
+ )
135
+
136
+ pass
137
+
138
+
139
+ # An exception which should be thrown by the robot package if it is able to communicate
140
+ # with the robot API but the result of the communication leads to an exception. An
141
+ # example could be a KeyError while reading from the response dictionary.
142
+ class RobotAPIException(RobotException):
143
+ def __init__(self, error_description: str) -> None:
144
+ super().__init__(
145
+ error_reason=ErrorReason.RobotAPIException,
146
+ error_description=error_description,
147
+ )
148
+
149
+ pass
150
+
151
+
152
+ # An exception which should be thrown by the robot package if it is unable to perform a
153
+ # requested action. For example the package is unable to stop the robot.
154
+ class RobotActionException(RobotException):
155
+ def __init__(self, error_description: str) -> None:
156
+ super().__init__(
157
+ error_reason=ErrorReason.RobotActionException,
158
+ error_description=error_description,
159
+ )
160
+
161
+ pass
162
+
163
+
164
+ # An exception which should be thrown by the robot package if it is unable to retrieve
165
+ # data from the API like currently executing missions, status of the current mission
166
+ # and similar.
167
+ class RobotRetrieveDataException(RobotException):
168
+ def __init__(self, error_description: str) -> None:
169
+ super().__init__(
170
+ error_reason=ErrorReason.RobotRetrieveDataException,
171
+ error_description=error_description,
172
+ )
173
+
174
+ pass
175
+
176
+
177
+ # An exception which should be thrown by the robot package if it is unable to collect
178
+ # the inspections that were generated for the currently executing task or mission.
179
+ class RobotRetrieveInspectionException(RobotException):
180
+ def __init__(self, error_description: str) -> None:
181
+ super().__init__(
182
+ error_reason=ErrorReason.RobotRetrieveInspectionException,
183
+ error_description=error_description,
184
+ )
185
+
186
+ pass
187
+
188
+
189
+ # An exception which should be thrown by the robot package if it is still starting the
190
+ # mission when another action is requested. An example of this can be trying to stop
191
+ # the robot while it is still starting the mission.
192
+ class RobotStillStartingMissionException(RobotException):
193
+ def __init__(self, error_description: str) -> None:
194
+ super().__init__(
195
+ error_reason=ErrorReason.RobotStillStartingMissionException,
196
+ error_description=error_description,
197
+ )
198
+
199
+ pass
200
+
201
+
202
+ # An exception which should be thrown by the robot package if it is unable to retrieve
203
+ # telemetry data. It should be used exclusively by the telemetry publishers and their
204
+ # functions.
205
+ class RobotTelemetryException(RobotException):
206
+ def __init__(self, error_description: str) -> None:
207
+ super().__init__(
208
+ error_reason=ErrorReason.RobotTelemetryException,
209
+ error_description=error_description,
210
+ )
211
+
212
+ pass
213
+
214
+
215
+ # An exception which should be thrown by the robot package if it is unable to retrieve
216
+ # telemetry pose data. It should be used exclusively by the telemetry pose publisher.
217
+ class RobotTelemetryPoseException(RobotException):
218
+ def __init__(self, error_description: str) -> None:
219
+ super().__init__(
220
+ error_reason=ErrorReason.RobotTelemetryPoseException,
221
+ error_description=error_description,
222
+ )
223
+
224
+ pass
225
+
226
+
227
+ # An exception which should be thrown by the robot package if there is no new telemetry update.
228
+ class RobotTelemetryNoUpdateException(RobotException):
229
+ def __init__(self, error_description: str) -> None:
230
+ super().__init__(
231
+ error_reason=ErrorReason.RobotTelemetryNoUpdateException,
232
+ error_description=error_description,
233
+ )
234
+
235
+ pass
236
+
237
+
238
+ # An exception which should be thrown by the robot package if it is unable to load the
239
+ # configuration for maps and transformations. This could be caused by faulty
240
+ # configuration and this exception will cause ISAR to crash as further execution is not
241
+ # advised.
21
242
  class RobotMapException(RobotException):
243
+ def __init__(self, error_description: str) -> None:
244
+ super().__init__(
245
+ error_reason=ErrorReason.RobotMapException,
246
+ error_description=error_description,
247
+ )
248
+
249
+ pass
250
+
251
+
252
+ # An exception which should be thrown by the robot package if it is unable to transform
253
+ # the coordinates correctly between asset and robot frame.
254
+ class RobotTransformException(RobotException):
255
+ def __init__(self, error_description: str) -> None:
256
+ super().__init__(
257
+ error_reason=ErrorReason.RobotTransformException,
258
+ error_description=error_description,
259
+ )
260
+
22
261
  pass
23
262
 
24
263
 
25
- class RobotInvalidTelemetryException(RobotException):
264
+ # An exception which should be thrown by the robot package if something occurred that
265
+ # was unexpected and the error reason is unknown.
266
+ class RobotUnknownErrorException(RobotException):
267
+ def __init__(self, error_description: str) -> None:
268
+ super().__init__(
269
+ error_reason=ErrorReason.RobotUnknownErrorException,
270
+ error_description=error_description,
271
+ )
272
+
273
+ pass
274
+
275
+
276
+ # An exception which should be thrown by the robot package if the robot is not connected to the cloud
277
+ class RobotDisconnectedException(RobotException):
278
+ def __init__(self, error_description: str) -> None:
279
+ super().__init__(
280
+ error_reason=ErrorReason.RobotDisconnectedException,
281
+ error_description=error_description,
282
+ )
283
+
284
+ pass
285
+
286
+
287
+ # An exception which should be thrown by the robot package if the robot receives a command
288
+ # to go home and decide to ignore this request as it is already at home.
289
+ class RobotAlreadyHomeException(RobotException):
290
+ def __init__(self, error_description: str) -> None:
291
+ super().__init__(
292
+ error_reason=ErrorReason.RobotAlreadyHomeException,
293
+ error_description=error_description,
294
+ )
295
+
26
296
  pass
@@ -1 +0,0 @@
1
- from .initialize_params import InitializeParams
@@ -1,13 +0,0 @@
1
- from .inspection import (
2
- Audio,
3
- Image,
4
- ImageMetadata,
5
- Inspection,
6
- InspectionMetadata,
7
- ThermalImage,
8
- ThermalImageMetadata,
9
- ThermalVideo,
10
- ThermalVideoMetadata,
11
- Video,
12
- VideoMetadata,
13
- )
@@ -1,61 +1,62 @@
1
- from abc import ABC
2
- from dataclasses import dataclass, field
3
1
  from datetime import datetime
4
- from typing import List, Optional, Type
2
+ from typing import Optional, Type
5
3
 
6
- from alitra import Pose
4
+ from alitra import Pose, Position
5
+ from pydantic import BaseModel, Field
7
6
 
8
- from robot_interface.utilities.uuid_string_factory import uuid4_string
9
7
 
10
-
11
- @dataclass
12
- class InspectionMetadata(ABC):
8
+ class InspectionMetadata(BaseModel):
13
9
  start_time: datetime
14
- pose: Pose
10
+ robot_pose: Pose
11
+ target_position: Position
15
12
  file_type: str
16
- analysis: Optional[str] = field(default=None, init=False)
17
- tag_id: Optional[str] = field(default=None, init=False)
18
- additional: Optional[dict] = field(default_factory=dict, init=False)
13
+ tag_id: Optional[str] = None
14
+ inspection_description: Optional[str] = None
19
15
 
20
16
 
21
- @dataclass
22
17
  class ImageMetadata(InspectionMetadata):
23
18
  pass
24
19
 
25
20
 
26
- @dataclass
27
21
  class ThermalImageMetadata(InspectionMetadata):
28
22
  pass
29
23
 
30
24
 
31
- @dataclass
32
25
  class VideoMetadata(InspectionMetadata):
33
- duration: Optional[float] = field(default=None)
26
+ duration: float
34
27
 
35
28
 
36
- @dataclass
37
29
  class ThermalVideoMetadata(InspectionMetadata):
38
- duration: Optional[float] = field(default=None)
30
+ duration: float
39
31
 
40
32
 
41
- @dataclass
42
33
  class AudioMetadata(InspectionMetadata):
43
- duration: Optional[float] = field(default=None)
34
+ duration: float
35
+
36
+
37
+ class GasMeasurementMetadata(InspectionMetadata):
38
+ pass
44
39
 
45
40
 
46
- @dataclass
47
- class Inspection:
48
- id: str = field(default_factory=uuid4_string, init=False)
41
+ class Inspection(BaseModel):
49
42
  metadata: InspectionMetadata
50
- data: Optional[bytes] = field(default=None, init=False)
43
+ id: str = Field(frozen=True)
51
44
 
52
45
  @staticmethod
53
46
  def get_metadata_type() -> Type[InspectionMetadata]:
54
47
  return InspectionMetadata
55
48
 
56
49
 
57
- @dataclass
58
- class Image(Inspection):
50
+ class InspectionValue(Inspection):
51
+ value: float = Field(frozen=True)
52
+ unit: str = Field(frozen=True)
53
+
54
+
55
+ class InspectionBlob(Inspection):
56
+ data: Optional[bytes] = Field(default=None, frozen=True)
57
+
58
+
59
+ class Image(InspectionBlob):
59
60
  metadata: ImageMetadata
60
61
 
61
62
  @staticmethod
@@ -63,8 +64,7 @@ class Image(Inspection):
63
64
  return ImageMetadata
64
65
 
65
66
 
66
- @dataclass
67
- class ThermalImage(Inspection):
67
+ class ThermalImage(InspectionBlob):
68
68
  metadata: ThermalImageMetadata
69
69
 
70
70
  @staticmethod
@@ -72,8 +72,7 @@ class ThermalImage(Inspection):
72
72
  return ThermalImageMetadata
73
73
 
74
74
 
75
- @dataclass
76
- class Video(Inspection):
75
+ class Video(InspectionBlob):
77
76
  metadata: VideoMetadata
78
77
 
79
78
  @staticmethod
@@ -81,8 +80,7 @@ class Video(Inspection):
81
80
  return VideoMetadata
82
81
 
83
82
 
84
- @dataclass
85
- class ThermalVideo(Inspection):
83
+ class ThermalVideo(InspectionBlob):
86
84
  metadata: ThermalVideoMetadata
87
85
 
88
86
  @staticmethod
@@ -90,10 +88,21 @@ class ThermalVideo(Inspection):
90
88
  return ThermalVideoMetadata
91
89
 
92
90
 
93
- @dataclass
94
- class Audio(Inspection):
91
+ class Audio(InspectionBlob):
95
92
  metadata: AudioMetadata
96
93
 
97
94
  @staticmethod
98
95
  def get_metadata_type() -> Type[InspectionMetadata]:
99
96
  return AudioMetadata
97
+
98
+
99
+ class GasMeasurement(InspectionValue):
100
+ metadata: GasMeasurementMetadata
101
+
102
+ @staticmethod
103
+ def get_metadata_type() -> Type[InspectionMetadata]:
104
+ return GasMeasurementMetadata
105
+
106
+
107
+ class CO2Measurement(GasMeasurement):
108
+ pass
@@ -1,21 +1,25 @@
1
- from dataclasses import dataclass, field
2
- from typing import List
1
+ from typing import List, Optional
3
2
 
3
+ from alitra import Pose
4
+ from pydantic import BaseModel, Field
5
+
6
+ from robot_interface.models.exceptions.robot_exceptions import ErrorMessage
4
7
  from robot_interface.models.mission.status import MissionStatus
5
- from robot_interface.models.mission.task import Task
8
+ from robot_interface.models.mission.task import TASKS, TaskTypes
6
9
  from robot_interface.utilities.uuid_string_factory import uuid4_string
7
10
 
8
11
 
9
- @dataclass
10
- class Mission:
11
- tasks: List[Task]
12
- id: str = field(default_factory=uuid4_string, init=True)
13
- name: str = ""
12
+ class Mission(BaseModel):
13
+ id: str = Field(default_factory=uuid4_string, frozen=True)
14
+ tasks: List[TASKS] = Field(default_factory=list, frozen=True)
15
+ name: str = Field(frozen=True)
16
+ start_pose: Optional[Pose] = Field(default=None, frozen=True)
14
17
  status: MissionStatus = MissionStatus.NotStarted
18
+ error_message: Optional[ErrorMessage] = Field(default=None)
15
19
 
16
- def _set_unique_id(self) -> None:
17
- self.id: str = uuid4_string()
18
-
19
- def __post_init__(self) -> None:
20
- if self.id is None:
21
- self._set_unique_id()
20
+ def _is_return_to_home_mission(self) -> bool:
21
+ if len(self.tasks) != 1:
22
+ return False
23
+ if self.tasks[0].type != TaskTypes.ReturnToHome:
24
+ return False
25
+ return True
@@ -2,34 +2,29 @@ from enum import Enum
2
2
 
3
3
 
4
4
  class MissionStatus(str, Enum):
5
- NotStarted: str = "not_started"
6
- InProgress: str = "in_progress"
7
- Paused: str = "paused"
8
- Failed: str = "failed"
9
- Cancelled: str = "cancelled"
10
- Successful: str = "successful"
11
- PartiallySuccessful: str = "partially_successful"
12
-
13
-
14
- class StepStatus(str, Enum):
15
- NotStarted: str = "not_started"
16
- Successful: str = "successful"
17
- InProgress: str = "in_progress"
18
- Failed: str = "failed"
19
- Cancelled: str = "cancelled"
5
+ NotStarted = "not_started"
6
+ InProgress = "in_progress"
7
+ Paused = "paused"
8
+ Failed = "failed"
9
+ Cancelled = "cancelled"
10
+ Successful = "successful"
11
+ PartiallySuccessful = "partially_successful"
20
12
 
21
13
 
22
14
  class TaskStatus(str, Enum):
23
- NotStarted: str = "not_started"
24
- InProgress: str = "in_progress"
25
- Paused: str = "paused"
26
- Failed: str = "failed"
27
- Cancelled: str = "cancelled"
28
- Successful: str = "successful"
29
- PartiallySuccessful: str = "partially_successful"
15
+ NotStarted = "not_started"
16
+ InProgress = "in_progress"
17
+ Paused = "paused"
18
+ Failed = "failed"
19
+ Cancelled = "cancelled"
20
+ Successful = "successful"
21
+ PartiallySuccessful = "partially_successful"
30
22
 
31
23
 
32
24
  class RobotStatus(Enum):
33
- Available: str = "available"
34
- Busy: str = "busy"
35
- Offline: str = "offline"
25
+ Available = "available"
26
+ Paused = "paused"
27
+ Busy = "busy"
28
+ Home = "home"
29
+ Offline = "offline"
30
+ BlockedProtectiveStop = "blockedprotectivestop"