isar 1.25.4__py3-none-any.whl → 1.25.6__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.

Potentially problematic release.


This version of isar might be problematic. Click here for more details.

@@ -18,6 +18,7 @@ from robot_interface.models.mission.task import (
18
18
  TakeThermalImage,
19
19
  TakeThermalVideo,
20
20
  TakeVideo,
21
+ TakeGasMeasurement,
21
22
  ZoomDescription,
22
23
  )
23
24
 
@@ -28,6 +29,7 @@ class InspectionTypes(str, Enum):
28
29
  video = "Video"
29
30
  thermal_video = "ThermalVideo"
30
31
  audio = "Audio"
32
+ gas_measurement = "GasMeasurement"
31
33
 
32
34
 
33
35
  class TaskType(str, Enum):
@@ -200,7 +202,6 @@ def to_inspection_task(task_definition: StartMissionTaskDefinition) -> TASKS:
200
202
  target=task_definition.inspection.inspection_target.to_alitra_position(),
201
203
  duration=inspection_definition.duration,
202
204
  metadata=task_definition.inspection.metadata,
203
- zoom=task_definition.zoom,
204
205
  )
205
206
  else:
206
207
  return RecordAudio(
@@ -209,7 +210,20 @@ def to_inspection_task(task_definition: StartMissionTaskDefinition) -> TASKS:
209
210
  target=task_definition.inspection.inspection_target.to_alitra_position(),
210
211
  duration=inspection_definition.duration,
211
212
  metadata=task_definition.inspection.metadata,
212
- zoom=task_definition.zoom,
213
+ )
214
+ elif inspection_definition.type == InspectionTypes.gas_measurement:
215
+ if task_definition.id:
216
+ return TakeGasMeasurement(
217
+ id=task_definition.id,
218
+ robot_pose=task_definition.pose.to_alitra_pose(),
219
+ tag_id=task_definition.tag,
220
+ metadata=task_definition.inspection.metadata,
221
+ )
222
+ else:
223
+ return TakeGasMeasurement(
224
+ robot_pose=task_definition.pose.to_alitra_pose(),
225
+ tag_id=task_definition.tag,
226
+ metadata=task_definition.inspection.metadata,
213
227
  )
214
228
  else:
215
229
  raise ValueError(
isar/config/settings.py CHANGED
@@ -25,9 +25,6 @@ class Settings(BaseSettings):
25
25
  # Name must match with an installed python package in the local environment
26
26
  ROBOT_PACKAGE: str = Field(default="isar_robot")
27
27
 
28
- # The run mode of the robot (stepwise or full mission)
29
- RUN_MISSION_BY_TASK: bool = Field(default=True)
30
-
31
28
  # Determines the local path in which results from missions are stored
32
29
  LOCAL_STORAGE_PATH: str = Field(default="./results")
33
30
 
@@ -60,6 +57,10 @@ class Settings(BaseSettings):
60
57
  # Number of attempts to request a task status in monitor before cancelling
61
58
  REQUEST_STATUS_FAILURE_COUNTER_LIMIT: int = Field(default=3)
62
59
 
60
+ # Time allocated to reconnect when failing to retrieve status due to communication
61
+ # issues
62
+ REQUEST_STATUS_COMMUNICATION_RECONNECT_DELAY: float = Field(default=10)
63
+
63
64
  # Number of attempts to stop the robot before giving up
64
65
  STOP_ROBOT_ATTEMPTS_LIMIT: int = Field(default=10)
65
66
 
@@ -327,7 +328,3 @@ class RobotSettings(BaseSettings):
327
328
 
328
329
 
329
330
  robot_settings = RobotSettings()
330
-
331
- if not settings.RUN_MISSION_BY_TASK: # If mission-wise, do not run localize missions
332
- if "localize" in robot_settings.CAPABILITIES:
333
- robot_settings.CAPABILITIES.remove("localize")
isar/script.py CHANGED
@@ -66,7 +66,6 @@ def print_startup_info():
66
66
  print_setting(fillchar="-")
67
67
  print_setting("Robot package", settings.ROBOT_PACKAGE)
68
68
  print_setting("Robot name", settings.ROBOT_NAME)
69
- print_setting("Run mission taskwise", settings.RUN_MISSION_BY_TASK)
70
69
  print_setting("Running on port", settings.API_PORT)
71
70
  print_setting("Mission planner", settings.MISSION_PLANNER)
72
71
  print_setting("Using local storage", settings.STORAGE_LOCAL_ENABLED)
@@ -54,7 +54,6 @@ class StateMachine(object):
54
54
  mqtt_publisher: MqttClientInterface,
55
55
  task_selector: TaskSelectorInterface,
56
56
  sleep_time: float = settings.FSM_SLEEP_TIME,
57
- run_mission_by_task: bool = settings.RUN_MISSION_BY_TASK,
58
57
  stop_robot_attempts_limit: int = settings.STOP_ROBOT_ATTEMPTS_LIMIT,
59
58
  transitions_log_length: int = settings.STATE_TRANSITIONS_LOG_LENGTH,
60
59
  ):
@@ -82,7 +81,6 @@ class StateMachine(object):
82
81
  self.robot: RobotInterface = robot
83
82
  self.mqtt_publisher: Optional[MqttClientInterface] = mqtt_publisher
84
83
  self.task_selector: TaskSelectorInterface = task_selector
85
- self.run_mission_by_task: bool = run_mission_by_task
86
84
 
87
85
  # List of states
88
86
  self.stop_state: State = Stop(self)
@@ -114,7 +112,6 @@ class StateMachine(object):
114
112
  "trigger": "start_machine",
115
113
  "source": self.off_state,
116
114
  "dest": self.idle_state,
117
- "before": self._off,
118
115
  },
119
116
  {
120
117
  "trigger": "initiated",
@@ -123,32 +120,24 @@ class StateMachine(object):
123
120
  "before": self._initiated,
124
121
  },
125
122
  {
126
- "trigger": "pause_full_mission",
127
- "source": [self.initiate_state, self.monitor_state],
123
+ "trigger": "pause",
124
+ "source": self.monitor_state,
128
125
  "dest": self.paused_state,
129
126
  "before": self._mission_paused,
130
127
  },
131
- {
132
- "trigger": "pause",
133
- "source": [self.initiate_state, self.monitor_state],
134
- "dest": self.stop_state,
135
- "before": self._pause,
136
- },
137
128
  {
138
129
  "trigger": "stop",
139
130
  "source": [
131
+ self.idle_state,
140
132
  self.initiate_state,
141
133
  self.monitor_state,
142
- self.idle_state,
134
+ self.paused_state,
143
135
  ],
144
136
  "dest": self.stop_state,
145
- "before": self._stop,
146
137
  },
147
138
  {
148
139
  "trigger": "mission_finished",
149
- "source": [
150
- self.initiate_state,
151
- ],
140
+ "source": self.monitor_state,
152
141
  "dest": self.idle_state,
153
142
  "before": self._mission_finished,
154
143
  },
@@ -173,39 +162,9 @@ class StateMachine(object):
173
162
  {
174
163
  "trigger": "resume",
175
164
  "source": self.paused_state,
176
- "dest": self.initiate_state,
177
- "before": self._resume,
178
- },
179
- {
180
- "trigger": "resume_full_mission",
181
- "source": self.paused_state,
182
165
  "dest": self.monitor_state,
183
166
  "before": self._resume,
184
167
  },
185
- {
186
- "trigger": "task_finished",
187
- "source": self.monitor_state,
188
- "dest": self.initiate_state,
189
- "before": self._task_finished,
190
- },
191
- {
192
- "trigger": "full_mission_finished",
193
- "source": self.monitor_state,
194
- "dest": self.initiate_state,
195
- "before": self._full_mission_finished,
196
- },
197
- {
198
- "trigger": "mission_paused",
199
- "source": self.stop_state,
200
- "dest": self.paused_state,
201
- "before": self._mission_paused,
202
- },
203
- {
204
- "trigger": "initiate_infeasible",
205
- "source": self.initiate_state,
206
- "dest": self.initiate_state,
207
- "before": self._initiate_infeasible,
208
- },
209
168
  {
210
169
  "trigger": "initiate_failed",
211
170
  "source": self.initiate_state,
@@ -214,33 +173,29 @@ class StateMachine(object):
214
173
  },
215
174
  {
216
175
  "trigger": "mission_stopped",
217
- "source": [self.stop_state, self.paused_state],
176
+ "source": self.stop_state,
218
177
  "dest": self.idle_state,
219
178
  "before": self._mission_stopped,
220
179
  },
221
180
  {
222
181
  "trigger": "robot_turned_offline",
223
- "source": [self.idle_state],
182
+ "source": self.idle_state,
224
183
  "dest": self.offline_state,
225
- "before": self._offline,
226
184
  },
227
185
  {
228
186
  "trigger": "robot_turned_online",
229
187
  "source": self.offline_state,
230
188
  "dest": self.idle_state,
231
- "before": self._online,
232
189
  },
233
190
  {
234
191
  "trigger": "robot_protective_stop_engaged",
235
- "source": [self.idle_state],
192
+ "source": self.idle_state,
236
193
  "dest": self.blocked_protective_stop,
237
- "before": self._protective_stop_engaged,
238
194
  },
239
195
  {
240
196
  "trigger": "robot_protective_stop_disengaged",
241
197
  "source": self.blocked_protective_stop,
242
198
  "dest": self.idle_state,
243
- "before": self._protective_stop_disengaged,
244
199
  },
245
200
  ]
246
201
  )
@@ -248,7 +203,6 @@ class StateMachine(object):
248
203
  self.stop_robot_attempts_limit: int = stop_robot_attempts_limit
249
204
  self.sleep_time: float = sleep_time
250
205
 
251
- self.stopped: bool = False
252
206
  self.current_mission: Optional[Mission] = None
253
207
  self.current_task: Optional[TASKS] = None
254
208
  self.initial_pose: Optional[Pose] = None
@@ -268,8 +222,6 @@ class StateMachine(object):
268
222
  self._finalize()
269
223
 
270
224
  def _initiated(self) -> None:
271
- if self.run_mission_by_task:
272
- self.current_task.status = TaskStatus.InProgress
273
225
  self.current_mission.status = MissionStatus.InProgress
274
226
  self.publish_task_status(task=self.current_task)
275
227
  self.logger.info(
@@ -278,24 +230,6 @@ class StateMachine(object):
278
230
  f"task: {str(self.current_task.id)[:8]}"
279
231
  )
280
232
 
281
- def _pause(self) -> None:
282
- return
283
-
284
- def _off(self) -> None:
285
- return
286
-
287
- def _offline(self) -> None:
288
- return
289
-
290
- def _online(self) -> None:
291
- return
292
-
293
- def _protective_stop_engaged(self) -> None:
294
- return
295
-
296
- def _protective_stop_disengaged(self) -> None:
297
- return
298
-
299
233
  def _resume(self) -> None:
300
234
  self.logger.info(f"Resuming mission: {self.current_mission.id}")
301
235
  self.current_mission.status = MissionStatus.InProgress
@@ -354,11 +288,6 @@ class StateMachine(object):
354
288
  self.current_task.status = TaskStatus.InProgress
355
289
  self.publish_task_status(task=self.current_task)
356
290
 
357
- def _task_finished(self) -> None:
358
- self.publish_task_status(task=self.current_task)
359
- self.current_task.update_task_status()
360
- self.iterate_current_task()
361
-
362
291
  def _full_mission_finished(self) -> None:
363
292
  self.current_task = None
364
293
 
@@ -377,21 +306,12 @@ class StateMachine(object):
377
306
 
378
307
  self.robot.pause()
379
308
 
380
- def _stop(self) -> None:
381
- self.stopped = True
382
-
383
309
  def _initiate_failed(self) -> None:
384
310
  self.current_task.status = TaskStatus.Failed
385
311
  self.current_mission.status = MissionStatus.Failed
386
312
  self.publish_task_status(task=self.current_task)
387
313
  self._finalize()
388
314
 
389
- def _initiate_infeasible(self) -> None:
390
- if self.run_mission_by_task:
391
- self.current_task.status = TaskStatus.Failed
392
- self.publish_task_status(task=self.current_task)
393
- self.iterate_current_task()
394
-
395
315
  def _mission_stopped(self) -> None:
396
316
  if self.current_mission is None:
397
317
  self._queue_empty_response()
@@ -458,7 +378,6 @@ class StateMachine(object):
458
378
 
459
379
  def reset_state_machine(self) -> None:
460
380
  self.logger.info("Resetting state machine")
461
- self.stopped = False
462
381
  self.current_task = None
463
382
  self.current_mission = None
464
383
  self.initial_pose = None
@@ -13,7 +13,6 @@ from robot_interface.models.exceptions.robot_exceptions import (
13
13
  ErrorMessage,
14
14
  RobotException,
15
15
  RobotInfeasibleMissionException,
16
- RobotInfeasibleTaskException,
17
16
  )
18
17
 
19
18
  if TYPE_CHECKING:
@@ -49,30 +48,12 @@ class Initiate(State):
49
48
  transition = self.state_machine.stop # type: ignore
50
49
  break
51
50
 
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
51
  if not self.initiate_thread:
64
- if self.state_machine.run_mission_by_task:
65
- self._run_initiate_thread(
66
- initiate_function=self.state_machine.robot.initiate_task,
67
- function_argument=self.state_machine.current_task,
68
- thread_name="State Machine Initiate Task",
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
- )
52
+ self._run_initiate_thread(
53
+ initiate_function=self.state_machine.robot.initiate_mission,
54
+ function_argument=self.state_machine.current_mission,
55
+ thread_name="State Machine Initiate Mission",
56
+ )
76
57
 
77
58
  try:
78
59
  self.initiate_thread.get_output()
@@ -81,18 +62,6 @@ class Initiate(State):
81
62
  except ThreadedRequestNotFinishedError:
82
63
  time.sleep(self.state_machine.sleep_time)
83
64
  continue
84
- except RobotInfeasibleTaskException as e:
85
- self.state_machine.current_task.error_message = ErrorMessage(
86
- error_reason=e.error_reason, error_description=e.error_description
87
- )
88
- self.logger.warning(
89
- f"Failed to initiate task "
90
- f"{str(self.state_machine.current_task.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
65
 
97
66
  except RobotInfeasibleMissionException as e:
98
67
  self.state_machine.current_mission.error_message = ErrorMessage(
@@ -58,10 +58,7 @@ class Monitor(State):
58
58
  break
59
59
 
60
60
  if self.state_machine.should_pause_mission():
61
- if self.state_machine.run_mission_by_task:
62
- transition = self.state_machine.pause # type: ignore
63
- else:
64
- transition = self.state_machine.pause_full_mission # type: ignore
61
+ transition = self.state_machine.pause # type: ignore
65
62
  break
66
63
 
67
64
  if not self.task_status_thread:
@@ -87,7 +84,7 @@ class Monitor(State):
87
84
  )
88
85
  status = TaskStatus.Failed
89
86
  else:
90
- time.sleep(self.state_machine.sleep_time)
87
+ time.sleep(settings.REQUEST_STATUS_COMMUNICATION_RECONNECT_DELAY)
91
88
  continue
92
89
 
93
90
  except RobotTaskStatusException as e:
@@ -133,28 +130,22 @@ class Monitor(State):
133
130
  name="State Machine Get Inspections",
134
131
  )
135
132
 
136
- if self.state_machine.run_mission_by_task:
137
- if self.state_machine.current_task.is_finished():
138
- self._report_task_status(self.state_machine.current_task)
139
- transition = self.state_machine.task_finished # type: ignore
140
- break
141
- else:
142
- if self.state_machine.current_task.is_finished():
143
- self._report_task_status(self.state_machine.current_task)
144
- self.state_machine.publish_task_status(
145
- task=self.state_machine.current_task
146
- )
133
+ if self.state_machine.current_task.is_finished():
134
+ self._report_task_status(self.state_machine.current_task)
135
+ self.state_machine.publish_task_status(
136
+ task=self.state_machine.current_task
137
+ )
147
138
 
148
- self.state_machine.iterate_current_task()
149
- if self.state_machine.current_task is None:
150
- transition = self.state_machine.full_mission_finished # type: ignore
151
- break
139
+ self.state_machine.iterate_current_task()
140
+ if self.state_machine.current_task is None:
141
+ transition = self.state_machine.mission_finished # type: ignore
142
+ break
152
143
 
153
- # Report and update next task
154
- self.state_machine.current_task.update_task_status()
155
- self.state_machine.publish_task_status(
156
- task=self.state_machine.current_task
157
- )
144
+ # Report and update next task
145
+ self.state_machine.current_task.update_task_status()
146
+ self.state_machine.publish_task_status(
147
+ task=self.state_machine.current_task
148
+ )
158
149
 
159
150
  self.task_status_thread = None
160
151
  time.sleep(self.state_machine.sleep_time)
@@ -174,7 +165,7 @@ class Monitor(State):
174
165
  inspection: Inspection = self.state_machine.robot.get_inspection(
175
166
  task=current_task
176
167
  )
177
- if current_task.inspection_id == inspection.id:
168
+ if current_task.inspection_id != inspection.id:
178
169
  self.logger.warning(
179
170
  f"The inspection_id of task ({current_task.inspection_id}) "
180
171
  f"and result ({inspection.id}) is not matching. "
@@ -22,14 +22,11 @@ class Paused(State):
22
22
  transition: Callable
23
23
  while True:
24
24
  if self.state_machine.should_stop_mission():
25
- transition = self.state_machine.mission_stopped # type: ignore
25
+ transition = self.state_machine.stop # type: ignore
26
26
  break
27
27
 
28
28
  if self.state_machine.should_resume_mission():
29
- if self.state_machine.run_mission_by_task:
30
- transition = self.state_machine.resume # type: ignore
31
- else:
32
- transition = self.state_machine.resume_full_mission # type: ignore
29
+ transition = self.state_machine.resume # type: ignore
33
30
  break
34
31
 
35
32
  time.sleep(self.state_machine.sleep_time)
@@ -43,9 +43,6 @@ class Stop(State):
43
43
  self.stop_thread = ThreadedRequest(self.state_machine.robot.stop)
44
44
  self.stop_thread.start_thread(name="State Machine Stop Robot")
45
45
 
46
- if self.state_machine.should_stop_mission():
47
- self.state_machine.stopped = True
48
-
49
46
  try:
50
47
  self.stop_thread.get_output()
51
48
  except ThreadedRequestNotFinishedError:
@@ -70,10 +67,9 @@ class Stop(State):
70
67
 
71
68
  self.stop_thread = None
72
69
  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
70
+
71
+ transition = self.state_machine.mission_stopped # type: ignore
72
+
77
73
  break
78
74
 
79
75
  transition()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: isar
3
- Version: 1.25.4
3
+ Version: 1.25.6
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
@@ -1,11 +1,11 @@
1
1
  isar/__init__.py,sha256=cH8p8bVveu3FUL6kBhldcSlLaoHgD82Kd0-SwSNfGXw,87
2
2
  isar/modules.py,sha256=BeBg2kJi1q-7DzupOM3jFloeMScRk7qkNog9-yGwV5c,7355
3
- isar/script.py,sha256=C9u5jIYXpnH8JuEqTSPfbuvZiSi3O9SjnvzHV-AtDbM,5988
3
+ isar/script.py,sha256=AHt1azidHit-fX3NnoXxJ5Eas-c30J3hFFOGGVrg084,5916
4
4
  isar/apis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  isar/apis/api.py,sha256=vUy7QbHrKcTHjh2rkU7lqQPkCasI6umha8r6H88JiXE,13942
6
6
  isar/apis/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  isar/apis/models/models.py,sha256=HzLaWhjAv0uJRBWipIgYg_F75eaQ5jl9Pi4UnYbDJ-M,1749
8
- isar/apis/models/start_mission_definition.py,sha256=kctM1kaK3a8z3Sd307QPZO9T_0OpDGQeGQVjOo49pCc,8775
8
+ isar/apis/models/start_mission_definition.py,sha256=QlL3iXnA1LyeyygA2yUw6FDxG9_30vPRVjTVwjcHyH4,9358
9
9
  isar/apis/robot_control/robot_controller.py,sha256=w0giQf8k1TCL_J_kAcBB8Tgk02laWDCiDiFE8E5sPrg,915
10
10
  isar/apis/schedule/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  isar/apis/schedule/scheduling_controller.py,sha256=9S7OtFCfO0hR9gWtj2u2oqa2Hxj9ynpcXxgqdk5liQ4,11328
@@ -16,7 +16,7 @@ isar/config/configuration_error.py,sha256=rO6WOhafX6xvVib8WxV-eY483Z0PpN-9PxGsq5
16
16
  isar/config/log.py,sha256=zHFLmGWQRn8TrcsxUS6KHpJt2JE86kYazU7b-bkcN9o,2285
17
17
  isar/config/logging.conf,sha256=mYO1xf27gAopEMHhGzY7-mwyfN16rwRLkPNMvy3zn2g,1127
18
18
  isar/config/settings.env,sha256=hJFfyl4S84nmcyf70Pz8nbGlPf4KTVx0UkgP3uf6T8E,534
19
- isar/config/settings.py,sha256=NdFZSRTEeULulvU8tX904YblUFxZPwQpLu1opA5hbNE,12998
19
+ isar/config/settings.py,sha256=JJS4W45cGcNFXBl5cT1_hK6qaWXfsx3w6a3TvmOiqgk,12871
20
20
  isar/config/certs/ca-cert.pem,sha256=qoNljfad_qcMxhXJIUMLd7nT-Qwf_d4dYSdoOFEOE8I,2179
21
21
  isar/config/keyvault/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
22
  isar/config/keyvault/keyvault_error.py,sha256=zvPCsZLjboxsxthYkxpRERCTFxYV8R5WmACewAUQLwk,41
@@ -65,18 +65,18 @@ isar/services/utilities/robot_utilities.py,sha256=4-ob4kcIiRN_GXFDBMwBadfbwpYqKE
65
65
  isar/services/utilities/scheduling_utilities.py,sha256=xQ1UqxxTRk2VpTVj7mL_ux9xqoaiSd45W7VAPmpXSfU,8509
66
66
  isar/services/utilities/threaded_request.py,sha256=py4G-_RjnIdHljmKFAcQ6ddqMmp-ZYV39Ece-dqRqjs,1874
67
67
  isar/state_machine/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
68
- isar/state_machine/state_machine.py,sha256=hZCxG6WuZYtgErohRWIamebEoqAczcOacCqqVyUWy8E,22994
68
+ isar/state_machine/state_machine.py,sha256=fv2IWDqWmlJyid6o2s_8sK3ADW7LZIWXs9HSc0WhmCA,20110
69
69
  isar/state_machine/states_enum.py,sha256=GrX2dzVXsyI9vXxIgd7DpOP8V1nhXQS4Jym5z69acHY,332
70
70
  isar/state_machine/states/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
71
71
  isar/state_machine/states/blocked_protective_stop.py,sha256=FNOarwHzkUfRllyxltXSu7W_nXAxpqDhz9PIo6wxE1o,2259
72
72
  isar/state_machine/states/idle.py,sha256=96CZCpBBPAZE_szF0UoPh6tBRsDn3FYII8bZ_cBFGuw,3815
73
73
  isar/state_machine/states/initialize.py,sha256=TVXV5Ps3N4_flM88j9pQiX88kZgLzLwzlJy_6hPbgcA,2359
74
- isar/state_machine/states/initiate.py,sha256=j1wvSC3zVODgRkKOVsQROiuWkjihSBtwCs5GsoivLvc,5655
75
- isar/state_machine/states/monitor.py,sha256=03h8OHFQ00_BuR_M7FOVeA4h_lJE2L1x37t0SyGZoX8,10285
74
+ isar/state_machine/states/initiate.py,sha256=xtKopnU5Ug_0PAV3yFm0v8O7DCa5CwGE4vN_7qahA0A,4139
75
+ isar/state_machine/states/monitor.py,sha256=xIrwQqL3q6h7R2mFdjj44YWpOsIEC01Nudxce3J91JI,9751
76
76
  isar/state_machine/states/off.py,sha256=jjqN_oJMpBtWuY7hP-c9f0w3p2CYCfe-NpmYHHPnmyI,544
77
77
  isar/state_machine/states/offline.py,sha256=IfEZ6-kl6OfJSRT1eKHOey7AU23tKiSHqpwGqclmH_c,2166
78
- isar/state_machine/states/paused.py,sha256=TIg1iJvAxGUIfzE_qWp0wrq4Ka0a3zEf3GNwIWLIK0M,1177
79
- isar/state_machine/states/stop.py,sha256=WVyjhndHcccy7_P9bU7SXyZB3qphsGahdSymaghGc08,3348
78
+ isar/state_machine/states/paused.py,sha256=pA7POYiCeprqTk0ktvGWJ9bElZKKYBXmupoiFYrfA5E,993
79
+ isar/state_machine/states/stop.py,sha256=LRhqhqHuElrsrwJJnxI9gLqSGuzuik8BT2V2GO4fvOs,3098
80
80
  isar/storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
81
81
  isar/storage/blob_storage.py,sha256=L885tgwHeeIp8raIz20Hhbc1IMsQP0wK6HOX9I4sZlw,3199
82
82
  isar/storage/local_storage.py,sha256=Bnmoi5gyN8r-oRh0aHrOdGqaH3JqRScFKMRXYojW5kY,1855
@@ -85,7 +85,7 @@ isar/storage/storage_interface.py,sha256=DYDry4I7aZpDHJhsBF6s8zrgokFAc7fdKJKfA8A
85
85
  isar/storage/uploader.py,sha256=LrbGlAGoqspWtSjmZcfvbRL3_khCnLWwa64XhqUrsr4,6543
86
86
  isar/storage/utilities.py,sha256=fitsdQ1ox5gr9fk9VuSk_iTBiEAIS8NZAnHabUZORh0,3173
87
87
  robot_interface/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
88
- robot_interface/robot_interface.py,sha256=UEhzAj1kXOdyYiWjz8zxEo5BHMHRE-ZHalPFfv-qBfw,9697
88
+ robot_interface/robot_interface.py,sha256=iNDjvmJALhffyMdxMKqmpIkfoVI_f5mauj9ghz-2Poc,8965
89
89
  robot_interface/test_robot_interface.py,sha256=FV1urn7SbsMyWBIcTKjsBwAG4IsXeZ6pLHE0mA9EGGs,692
90
90
  robot_interface/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
91
91
  robot_interface/models/exceptions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -93,11 +93,11 @@ robot_interface/models/exceptions/robot_exceptions.py,sha256=DvhH0FxW_7HSLZc43rl
93
93
  robot_interface/models/initialize/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
94
94
  robot_interface/models/initialize/initialize_params.py,sha256=2eG5Aq5bDKU6tVkaUMAoc46GERBgyaKkqv6yLupdRLc,164
95
95
  robot_interface/models/inspection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
96
- robot_interface/models/inspection/inspection.py,sha256=nSoKTDPRWnpaJuoKnaE_2EEJ6oH4dQkqEuECcQTvVhI,2059
96
+ robot_interface/models/inspection/inspection.py,sha256=Q8vyiTMV2Ws1B4N10kQ3C1AZkck0Mh5pwOyWux7OQms,2318
97
97
  robot_interface/models/mission/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
98
98
  robot_interface/models/mission/mission.py,sha256=QZBDQiOmpb4C7nNCf1PaCWwpvAc8jrhwHSznOe2YhX8,842
99
99
  robot_interface/models/mission/status.py,sha256=48y8HEiT7QQbMLBUBYxXR92iZOrnBOukPZ7o09CCR1Q,686
100
- robot_interface/models/mission/task.py,sha256=dk_CYaABD9WxQswd1xX3D5AHpcXwREwnloREEg1JbI0,4980
100
+ robot_interface/models/mission/task.py,sha256=8qyobH4DJRlqdwt4lwo1k6zGexh-ccJjF7106WwJsnI,5431
101
101
  robot_interface/models/robots/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
102
102
  robot_interface/models/robots/battery_state.py,sha256=ktOtJ8ltdK0k_i7BoqYfhc5dbOzIG6Oo-uWC67fCWio,98
103
103
  robot_interface/models/robots/media.py,sha256=8A-CuuubfngzPprs6zWB9hSaqe3jzgsE8rcCzRX2Uto,227
@@ -108,9 +108,9 @@ robot_interface/telemetry/payloads.py,sha256=_Ph2f1M5f18fTJ7Jrd3JCeXhfZzg6i3THlF
108
108
  robot_interface/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
109
109
  robot_interface/utilities/json_service.py,sha256=nU2Q_3P9Fq9hs6F_wtUjWtHfl_g1Siy-yDhXXSKwHwg,1018
110
110
  robot_interface/utilities/uuid_string_factory.py,sha256=_NQIbBQ56w0qqO0MUDP6aPpHbxW7ATRhK8HnQiBSLkc,76
111
- isar-1.25.4.dist-info/LICENSE,sha256=3fc2-ebLwHWwzfQbulGNRdcNob3SBQeCfEVUDYxsuqw,14058
112
- isar-1.25.4.dist-info/METADATA,sha256=eHo0fpQBnVD2pHC6aRNqs1K4KvB3x1boptOCL5DzqZw,30578
113
- isar-1.25.4.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
114
- isar-1.25.4.dist-info/entry_points.txt,sha256=TFam7uNNw7J0iiDYzsH2gfG0u1eV1wh3JTw_HkhgKLk,49
115
- isar-1.25.4.dist-info/top_level.txt,sha256=UwIML2RtuQKCyJJkatcSnyp6-ldDjboB9k9JgKipO-U,21
116
- isar-1.25.4.dist-info/RECORD,,
111
+ isar-1.25.6.dist-info/LICENSE,sha256=3fc2-ebLwHWwzfQbulGNRdcNob3SBQeCfEVUDYxsuqw,14058
112
+ isar-1.25.6.dist-info/METADATA,sha256=kfTji3vn-YqFTy_Tk3aCNJOGr-IRSPMmSftjoZEXNQU,30578
113
+ isar-1.25.6.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
114
+ isar-1.25.6.dist-info/entry_points.txt,sha256=TFam7uNNw7J0iiDYzsH2gfG0u1eV1wh3JTw_HkhgKLk,49
115
+ isar-1.25.6.dist-info/top_level.txt,sha256=UwIML2RtuQKCyJJkatcSnyp6-ldDjboB9k9JgKipO-U,21
116
+ isar-1.25.6.dist-info/RECORD,,
@@ -42,6 +42,11 @@ class AudioMetadata(InspectionMetadata):
42
42
  duration: Optional[float] = field(default=None)
43
43
 
44
44
 
45
+ @dataclass
46
+ class GasMeasurementMetadata(InspectionMetadata):
47
+ pass
48
+
49
+
45
50
  class Inspection(BaseModel):
46
51
  metadata: InspectionMetadata
47
52
  id: str = Field(frozen=True)
@@ -90,3 +95,11 @@ class Audio(Inspection):
90
95
  @staticmethod
91
96
  def get_metadata_type() -> Type[InspectionMetadata]:
92
97
  return AudioMetadata
98
+
99
+
100
+ class GasMeasurement(Inspection):
101
+ metadata: GasMeasurementMetadata
102
+
103
+ @staticmethod
104
+ def get_metadata_type() -> Type[InspectionMetadata]:
105
+ return GasMeasurementMetadata
@@ -11,6 +11,7 @@ from robot_interface.models.inspection.inspection import (
11
11
  Inspection,
12
12
  ThermalImage,
13
13
  ThermalVideo,
14
+ GasMeasurement,
14
15
  Video,
15
16
  )
16
17
  from robot_interface.models.mission.status import TaskStatus
@@ -25,6 +26,7 @@ class TaskTypes(str, Enum):
25
26
  TakeThermalImage = "take_thermal_image"
26
27
  TakeVideo = "take_video"
27
28
  TakeThermalVideo = "take_thermal_video"
29
+ TakeGasMeasurement = "take_gas_measurement"
28
30
  RecordAudio = "record_audio"
29
31
  DockingProcedure = "docking_procedure"
30
32
 
@@ -179,6 +181,20 @@ class RecordAudio(InspectionTask):
179
181
  return Audio
180
182
 
181
183
 
184
+ class TakeGasMeasurement(InspectionTask):
185
+ """
186
+ Task which causes the robot to take a CO2 measurement at its position.
187
+
188
+ Duration of audio is given in seconds.
189
+ """
190
+
191
+ type: Literal[TaskTypes.TakeGasMeasurement] = TaskTypes.TakeGasMeasurement
192
+
193
+ @staticmethod
194
+ def get_inspection_type() -> Type[Inspection]:
195
+ return GasMeasurement
196
+
197
+
182
198
  TASKS = Union[
183
199
  ReturnToHome,
184
200
  Localize,
@@ -187,6 +203,7 @@ TASKS = Union[
187
203
  TakeThermalImage,
188
204
  TakeVideo,
189
205
  TakeThermalVideo,
206
+ TakeGasMeasurement,
190
207
  RecordAudio,
191
208
  DockingProcedure,
192
209
  ]
@@ -18,10 +18,6 @@ class RobotInterface(metaclass=ABCMeta):
18
18
  def initiate_mission(self, mission: Mission) -> None:
19
19
  """Send a mission to the robot and initiate execution of the mission
20
20
 
21
- This function should be used in combination with the mission_status function
22
- if the robot is designed to run full missions and not in a taskwise
23
- configuration.
24
-
25
21
  Parameters
26
22
  ----------
27
23
  mission: Mission
@@ -38,8 +34,6 @@ class RobotInterface(metaclass=ABCMeta):
38
34
  RobotException
39
35
  Will catch all RobotExceptions not previously listed and retry scheduling of
40
36
  the mission until the number of allowed retries is exceeded
41
- NotImplementedError
42
- If the robot is designed for taskwise mission execution
43
37
 
44
38
  """
45
39
  raise NotImplementedError
@@ -48,10 +42,6 @@ class RobotInterface(metaclass=ABCMeta):
48
42
  def initiate_task(self, task: Task) -> None:
49
43
  """Send a task to the robot and initiate the execution of the task
50
44
 
51
- This function should be used in combination with the task_status function
52
- if the robot is designed to run taskwise missions and not in a full mission
53
- configuration.
54
-
55
45
  Parameters
56
46
  ----------
57
47
  task : Task
@@ -71,7 +61,7 @@ class RobotInterface(metaclass=ABCMeta):
71
61
  of the task until the number of allowed retries is exceeded before the task
72
62
  will be marked as failed and the mission cancelled
73
63
  NotImplementedError
74
- If the robot is designed for full mission execution.
64
+ If there is a mismatch between the implemented tasks and listed capabilities
75
65
 
76
66
  """
77
67
  raise NotImplementedError
@@ -80,10 +70,6 @@ class RobotInterface(metaclass=ABCMeta):
80
70
  def task_status(self, task_id: str) -> TaskStatus:
81
71
  """Gets the status of the currently active task on robot.
82
72
 
83
- This function should be used in combination with the initiate_task function
84
- if the robot is designed to run taskwise missions and not in a full mission
85
- configuration.
86
-
87
73
  Returns
88
74
  -------
89
75
  TaskStatus
@@ -93,8 +79,6 @@ class RobotInterface(metaclass=ABCMeta):
93
79
  ------
94
80
  RobotException
95
81
  If the task status could not be retrieved.
96
- NotImplementedError
97
- If the robot is designed for full mission execution.
98
82
 
99
83
  """
100
84
  raise NotImplementedError
File without changes
File without changes