isar 1.34.2__py3-none-any.whl → 1.34.4__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.
- isar/models/status.py +1 -0
- isar/robot/robot.py +46 -10
- isar/robot/robot_monitor_mission.py +14 -2
- isar/robot/robot_pause_mission.py +8 -6
- isar/robot/robot_start_mission.py +12 -24
- isar/robot/robot_stop_mission.py +3 -0
- isar/robot/robot_upload_inspection.py +0 -5
- isar/state_machine/state_machine.py +8 -0
- isar/state_machine/states/await_next_mission.py +18 -0
- isar/state_machine/states/going_to_recharging.py +81 -0
- isar/state_machine/states/home.py +18 -0
- isar/state_machine/states/monitor.py +5 -5
- isar/state_machine/states/paused.py +4 -1
- isar/state_machine/states/return_home_paused.py +4 -1
- isar/state_machine/states/returning_home.py +20 -4
- isar/state_machine/states/stopping_go_to_recharge.py +51 -0
- isar/state_machine/states_enum.py +2 -0
- isar/state_machine/transitions/functions/resume.py +7 -0
- isar/state_machine/transitions/mission.py +10 -1
- isar/state_machine/transitions/return_home.py +28 -3
- {isar-1.34.2.dist-info → isar-1.34.4.dist-info}/METADATA +1 -1
- {isar-1.34.2.dist-info → isar-1.34.4.dist-info}/RECORD +27 -25
- robot_interface/models/exceptions/robot_exceptions.py +13 -0
- {isar-1.34.2.dist-info → isar-1.34.4.dist-info}/WHEEL +0 -0
- {isar-1.34.2.dist-info → isar-1.34.4.dist-info}/entry_points.txt +0 -0
- {isar-1.34.2.dist-info → isar-1.34.4.dist-info}/licenses/LICENSE +0 -0
- {isar-1.34.2.dist-info → isar-1.34.4.dist-info}/top_level.txt +0 -0
isar/models/status.py
CHANGED
isar/robot/robot.py
CHANGED
|
@@ -70,6 +70,10 @@ class Robot(object):
|
|
|
70
70
|
self.start_mission_thread.join()
|
|
71
71
|
if self.stop_mission_thread is not None and self.stop_mission_thread.is_alive():
|
|
72
72
|
self.stop_mission_thread.join()
|
|
73
|
+
for thread in self.upload_inspection_threads:
|
|
74
|
+
if thread.is_alive():
|
|
75
|
+
thread.join()
|
|
76
|
+
self.upload_inspection_threads = []
|
|
73
77
|
self.robot_status_thread = None
|
|
74
78
|
self.robot_battery_thread = None
|
|
75
79
|
self.start_mission_thread = None
|
|
@@ -82,8 +86,14 @@ class Robot(object):
|
|
|
82
86
|
):
|
|
83
87
|
self.start_mission_thread.join()
|
|
84
88
|
mission = self.start_mission_thread.mission
|
|
89
|
+
error_message = self.start_mission_thread.error_message
|
|
85
90
|
self.start_mission_thread = None
|
|
86
91
|
|
|
92
|
+
if error_message:
|
|
93
|
+
self.robot_service_events.mission_failed.trigger_event(error_message)
|
|
94
|
+
else:
|
|
95
|
+
self.robot_service_events.mission_started.trigger_event(True)
|
|
96
|
+
|
|
87
97
|
if (
|
|
88
98
|
self.monitor_mission_thread is not None
|
|
89
99
|
and self.monitor_mission_thread.is_alive()
|
|
@@ -131,6 +141,24 @@ class Robot(object):
|
|
|
131
141
|
True
|
|
132
142
|
)
|
|
133
143
|
|
|
144
|
+
def _pause_mission_done_handler(self) -> None:
|
|
145
|
+
if (
|
|
146
|
+
self.pause_mission_thread is not None
|
|
147
|
+
and not self.pause_mission_thread.is_alive()
|
|
148
|
+
):
|
|
149
|
+
self.pause_mission_thread.join()
|
|
150
|
+
error_message = self.pause_mission_thread.error_message
|
|
151
|
+
self.pause_mission_thread = None
|
|
152
|
+
|
|
153
|
+
if error_message:
|
|
154
|
+
self.robot_service_events.mission_failed_to_pause.trigger_event(
|
|
155
|
+
error_message
|
|
156
|
+
)
|
|
157
|
+
else:
|
|
158
|
+
self.robot_service_events.mission_successfully_paused.trigger_event(
|
|
159
|
+
True
|
|
160
|
+
)
|
|
161
|
+
|
|
134
162
|
def _start_mission_event_handler(self, event: Event[Mission]) -> None:
|
|
135
163
|
start_mission = event.consume_event()
|
|
136
164
|
if start_mission is not None:
|
|
@@ -144,7 +172,6 @@ class Robot(object):
|
|
|
144
172
|
self.start_mission_thread.join()
|
|
145
173
|
|
|
146
174
|
self.start_mission_thread = RobotStartMissionThread(
|
|
147
|
-
self.robot_service_events,
|
|
148
175
|
self.robot,
|
|
149
176
|
self.signal_thread_quitting,
|
|
150
177
|
start_mission,
|
|
@@ -204,7 +231,7 @@ class Robot(object):
|
|
|
204
231
|
)
|
|
205
232
|
return
|
|
206
233
|
self.pause_mission_thread = RobotPauseMissionThread(
|
|
207
|
-
self.
|
|
234
|
+
self.robot, self.signal_thread_quitting
|
|
208
235
|
)
|
|
209
236
|
self.pause_mission_thread.start()
|
|
210
237
|
|
|
@@ -220,15 +247,20 @@ class Robot(object):
|
|
|
220
247
|
self.upload_inspection_threads.append(upload_inspection_thread)
|
|
221
248
|
upload_inspection_thread.start()
|
|
222
249
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
250
|
+
def _upload_inspection_done_handler(self):
|
|
251
|
+
if len(self.upload_inspection_threads) > 0:
|
|
252
|
+
|
|
253
|
+
def _join_threads(thread: RobotUploadInspectionThread) -> bool:
|
|
254
|
+
if not thread.is_alive():
|
|
255
|
+
thread.join()
|
|
256
|
+
return True
|
|
257
|
+
return False
|
|
228
258
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
259
|
+
self.upload_inspection_threads[:] = [
|
|
260
|
+
thread
|
|
261
|
+
for thread in self.upload_inspection_threads
|
|
262
|
+
if _join_threads(thread)
|
|
263
|
+
]
|
|
232
264
|
|
|
233
265
|
def run(self) -> None:
|
|
234
266
|
self.robot_status_thread = RobotStatusThread(
|
|
@@ -260,4 +292,8 @@ class Robot(object):
|
|
|
260
292
|
|
|
261
293
|
self._stop_mission_done_handler()
|
|
262
294
|
|
|
295
|
+
self._pause_mission_done_handler()
|
|
296
|
+
|
|
297
|
+
self._upload_inspection_done_handler()
|
|
298
|
+
|
|
263
299
|
self.logger.info("Exiting robot service main thread")
|
|
@@ -86,6 +86,10 @@ class RobotMonitorMissionThread(Thread):
|
|
|
86
86
|
if self.signal_thread_quitting.wait(0) or self.signal_mission_stopped.wait(
|
|
87
87
|
0
|
|
88
88
|
):
|
|
89
|
+
failed_task_error = ErrorMessage(
|
|
90
|
+
error_reason=ErrorReason.RobotTaskStatusException,
|
|
91
|
+
error_description="Task status collection was cancelled by monitor thread exit",
|
|
92
|
+
)
|
|
89
93
|
break
|
|
90
94
|
if request_status_failure_counter > 0:
|
|
91
95
|
time.sleep(settings.REQUEST_STATUS_COMMUNICATION_RECONNECT_DELAY)
|
|
@@ -320,10 +324,12 @@ class RobotMonitorMissionThread(Thread):
|
|
|
320
324
|
new_task_status = self._get_task_status(current_task.id)
|
|
321
325
|
except RobotTaskStatusException as e:
|
|
322
326
|
self.logger.error(
|
|
323
|
-
"Failed to collect task status",
|
|
327
|
+
"Failed to collect task status. Error description: %s",
|
|
328
|
+
e.error_description,
|
|
324
329
|
)
|
|
325
330
|
break
|
|
326
331
|
except Exception:
|
|
332
|
+
self.logger.exception("Failed to collect task status")
|
|
327
333
|
break
|
|
328
334
|
|
|
329
335
|
if current_task.status != new_task_status:
|
|
@@ -350,8 +356,14 @@ class RobotMonitorMissionThread(Thread):
|
|
|
350
356
|
|
|
351
357
|
try:
|
|
352
358
|
new_mission_status = self._get_mission_status(self.current_mission.id)
|
|
353
|
-
except RobotMissionStatusException:
|
|
359
|
+
except RobotMissionStatusException as e:
|
|
354
360
|
self.logger.exception("Failed to collect mission status")
|
|
361
|
+
self.robot_service_events.mission_failed.trigger_event(
|
|
362
|
+
ErrorMessage(
|
|
363
|
+
error_reason=e.error_reason,
|
|
364
|
+
error_description=e.error_description,
|
|
365
|
+
)
|
|
366
|
+
)
|
|
355
367
|
break
|
|
356
368
|
if new_mission_status != last_mission_status:
|
|
357
369
|
self.current_mission.status = new_mission_status
|
|
@@ -4,11 +4,11 @@ from threading import Event, Thread
|
|
|
4
4
|
from typing import Optional
|
|
5
5
|
|
|
6
6
|
from isar.config.settings import settings
|
|
7
|
-
from isar.models.events import RobotServiceEvents
|
|
8
7
|
from robot_interface.models.exceptions.robot_exceptions import (
|
|
9
8
|
ErrorMessage,
|
|
10
9
|
RobotActionException,
|
|
11
10
|
RobotException,
|
|
11
|
+
RobotNoMissionRunningException,
|
|
12
12
|
)
|
|
13
13
|
from robot_interface.robot_interface import RobotInterface
|
|
14
14
|
|
|
@@ -16,14 +16,13 @@ from robot_interface.robot_interface import RobotInterface
|
|
|
16
16
|
class RobotPauseMissionThread(Thread):
|
|
17
17
|
def __init__(
|
|
18
18
|
self,
|
|
19
|
-
robot_service_events: RobotServiceEvents,
|
|
20
19
|
robot: RobotInterface,
|
|
21
20
|
signal_thread_quitting: Event,
|
|
22
21
|
):
|
|
23
22
|
self.logger = logging.getLogger("robot")
|
|
24
|
-
self.robot_service_events: RobotServiceEvents = robot_service_events
|
|
25
23
|
self.robot: RobotInterface = robot
|
|
26
24
|
self.signal_thread_quitting: Event = signal_thread_quitting
|
|
25
|
+
self.error_message: Optional[ErrorMessage] = None
|
|
27
26
|
Thread.__init__(self, name="Robot pause mission thread")
|
|
28
27
|
|
|
29
28
|
def run(self) -> None:
|
|
@@ -35,6 +34,11 @@ class RobotPauseMissionThread(Thread):
|
|
|
35
34
|
|
|
36
35
|
try:
|
|
37
36
|
self.robot.pause()
|
|
37
|
+
except RobotNoMissionRunningException as e:
|
|
38
|
+
error = ErrorMessage(
|
|
39
|
+
error_reason=e.error_reason, error_description=e.error_description
|
|
40
|
+
)
|
|
41
|
+
break
|
|
38
42
|
except (RobotActionException, RobotException) as e:
|
|
39
43
|
self.logger.warning(
|
|
40
44
|
f"\nFailed to pause robot because: {e.error_description}"
|
|
@@ -46,7 +50,6 @@ class RobotPauseMissionThread(Thread):
|
|
|
46
50
|
)
|
|
47
51
|
time.sleep(settings.FSM_SLEEP_TIME)
|
|
48
52
|
continue
|
|
49
|
-
self.robot_service_events.mission_successfully_paused.trigger_event(True)
|
|
50
53
|
return
|
|
51
54
|
|
|
52
55
|
error_description = (
|
|
@@ -56,8 +59,7 @@ class RobotPauseMissionThread(Thread):
|
|
|
56
59
|
"been attempted"
|
|
57
60
|
)
|
|
58
61
|
|
|
59
|
-
error_message = ErrorMessage(
|
|
62
|
+
self.error_message = ErrorMessage(
|
|
60
63
|
error_reason=error.error_reason,
|
|
61
64
|
error_description=error_description,
|
|
62
65
|
)
|
|
63
|
-
self.robot_service_events.mission_failed_to_pause.trigger_event(error_message)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
from threading import Event, Thread
|
|
3
|
+
from typing import Optional
|
|
3
4
|
|
|
4
5
|
from isar.config.settings import settings
|
|
5
|
-
from isar.models.events import RobotServiceEvents
|
|
6
6
|
from robot_interface.models.exceptions.robot_exceptions import (
|
|
7
7
|
ErrorMessage,
|
|
8
8
|
RobotException,
|
|
@@ -15,23 +15,21 @@ from robot_interface.robot_interface import RobotInterface
|
|
|
15
15
|
class RobotStartMissionThread(Thread):
|
|
16
16
|
def __init__(
|
|
17
17
|
self,
|
|
18
|
-
robot_service_events: RobotServiceEvents,
|
|
19
18
|
robot: RobotInterface,
|
|
20
19
|
signal_thread_quitting: Event,
|
|
21
20
|
mission: Mission,
|
|
22
21
|
):
|
|
23
22
|
self.logger = logging.getLogger("robot")
|
|
24
|
-
self.robot_service_events: RobotServiceEvents = robot_service_events
|
|
25
23
|
self.robot: RobotInterface = robot
|
|
26
24
|
self.signal_thread_quitting: Event = signal_thread_quitting
|
|
27
25
|
self.mission = mission
|
|
26
|
+
self.error_message: Optional[ErrorMessage] = None
|
|
28
27
|
Thread.__init__(self, name="Robot start mission thread")
|
|
29
28
|
|
|
30
29
|
def run(self):
|
|
31
30
|
retries = 0
|
|
32
|
-
started_mission = False
|
|
33
31
|
try:
|
|
34
|
-
while
|
|
32
|
+
while True:
|
|
35
33
|
if self.signal_thread_quitting.wait(0):
|
|
36
34
|
return
|
|
37
35
|
try:
|
|
@@ -40,11 +38,9 @@ class RobotStartMissionThread(Thread):
|
|
|
40
38
|
self.logger.error(
|
|
41
39
|
f"Mission is infeasible and cannot be scheduled because: {e.error_description}"
|
|
42
40
|
)
|
|
43
|
-
self.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
error_description=e.error_description,
|
|
47
|
-
)
|
|
41
|
+
self.error_message = ErrorMessage(
|
|
42
|
+
error_reason=e.error_reason,
|
|
43
|
+
error_description=e.error_description,
|
|
48
44
|
)
|
|
49
45
|
|
|
50
46
|
break
|
|
@@ -62,23 +58,15 @@ class RobotStartMissionThread(Thread):
|
|
|
62
58
|
f"{e.error_description}"
|
|
63
59
|
)
|
|
64
60
|
|
|
65
|
-
self.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
error_description=e.error_description,
|
|
69
|
-
)
|
|
61
|
+
self.error_message = ErrorMessage(
|
|
62
|
+
error_reason=e.error_reason,
|
|
63
|
+
error_description=e.error_description,
|
|
70
64
|
)
|
|
71
65
|
break
|
|
72
66
|
|
|
73
67
|
continue
|
|
74
|
-
|
|
75
|
-
started_mission = True
|
|
68
|
+
break
|
|
76
69
|
except RobotInfeasibleMissionException as e:
|
|
77
|
-
self.
|
|
78
|
-
|
|
79
|
-
error_reason=e.error_reason, error_description=e.error_description
|
|
80
|
-
),
|
|
70
|
+
self.error_message = ErrorMessage(
|
|
71
|
+
error_reason=e.error_reason, error_description=e.error_description
|
|
81
72
|
)
|
|
82
|
-
|
|
83
|
-
if started_mission:
|
|
84
|
-
self.robot_service_events.mission_started.trigger_event(True)
|
isar/robot/robot_stop_mission.py
CHANGED
|
@@ -9,6 +9,7 @@ from robot_interface.models.exceptions.robot_exceptions import (
|
|
|
9
9
|
ErrorReason,
|
|
10
10
|
RobotActionException,
|
|
11
11
|
RobotException,
|
|
12
|
+
RobotNoMissionRunningException,
|
|
12
13
|
)
|
|
13
14
|
from robot_interface.robot_interface import RobotInterface
|
|
14
15
|
|
|
@@ -38,6 +39,8 @@ class RobotStopMissionThread(Thread):
|
|
|
38
39
|
|
|
39
40
|
try:
|
|
40
41
|
self.robot.stop()
|
|
42
|
+
except RobotNoMissionRunningException:
|
|
43
|
+
return
|
|
41
44
|
except (RobotActionException, RobotException) as e:
|
|
42
45
|
self.logger.warning(
|
|
43
46
|
f"\nFailed to stop robot because: {e.error_description}"
|
|
@@ -27,15 +27,11 @@ class RobotUploadInspectionThread(Thread):
|
|
|
27
27
|
self.task: TASKS = task
|
|
28
28
|
self.upload_queue = upload_queue
|
|
29
29
|
self.mission: Mission = mission
|
|
30
|
-
self._is_done = False
|
|
31
30
|
Thread.__init__(self, name=f"Robot inspection upload thread - {task.id}")
|
|
32
31
|
|
|
33
32
|
def stop(self) -> None:
|
|
34
33
|
return
|
|
35
34
|
|
|
36
|
-
def is_done(self) -> bool:
|
|
37
|
-
return self._is_done
|
|
38
|
-
|
|
39
35
|
def run(self):
|
|
40
36
|
try:
|
|
41
37
|
inspection: Inspection = self.robot.get_inspection(task=self.task)
|
|
@@ -77,4 +73,3 @@ class RobotUploadInspectionThread(Thread):
|
|
|
77
73
|
self.logger.info(
|
|
78
74
|
f"Inspection result: {str(inspection.id)[:8]} queued for upload"
|
|
79
75
|
)
|
|
80
|
-
self._is_done = True
|
|
@@ -14,6 +14,7 @@ from isar.models.status import IsarStatus
|
|
|
14
14
|
from isar.state_machine.states.await_next_mission import AwaitNextMission
|
|
15
15
|
from isar.state_machine.states.blocked_protective_stop import BlockedProtectiveStop
|
|
16
16
|
from isar.state_machine.states.going_to_lockdown import GoingToLockdown
|
|
17
|
+
from isar.state_machine.states.going_to_recharging import GoingToRecharging
|
|
17
18
|
from isar.state_machine.states.home import Home
|
|
18
19
|
from isar.state_machine.states.intervention_needed import InterventionNeeded
|
|
19
20
|
from isar.state_machine.states.lockdown import Lockdown
|
|
@@ -27,6 +28,7 @@ from isar.state_machine.states.return_home_paused import ReturnHomePaused
|
|
|
27
28
|
from isar.state_machine.states.returning_home import ReturningHome
|
|
28
29
|
from isar.state_machine.states.stopping import Stopping
|
|
29
30
|
from isar.state_machine.states.stopping_go_to_lockdown import StoppingGoToLockdown
|
|
31
|
+
from isar.state_machine.states.stopping_go_to_recharge import StoppingGoToRecharge
|
|
30
32
|
from isar.state_machine.states.stopping_return_home import StoppingReturnHome
|
|
31
33
|
from isar.state_machine.states.unknown_status import UnknownStatus
|
|
32
34
|
from isar.state_machine.states_enum import States
|
|
@@ -95,7 +97,9 @@ class StateMachine(object):
|
|
|
95
97
|
self.stopping_return_home_state: State = StoppingReturnHome(self)
|
|
96
98
|
self.pausing_return_home_state: State = PausingReturnHome(self)
|
|
97
99
|
self.stopping_go_to_lockdown_state: State = StoppingGoToLockdown(self)
|
|
100
|
+
self.stopping_go_to_recharge_state: State = StoppingGoToRecharge(self)
|
|
98
101
|
self.going_to_lockdown_state: State = GoingToLockdown(self)
|
|
102
|
+
self.going_to_recharging_state: State = GoingToRecharging(self)
|
|
99
103
|
|
|
100
104
|
# States Waiting for mission
|
|
101
105
|
self.await_next_mission_state: State = AwaitNextMission(self)
|
|
@@ -130,6 +134,8 @@ class StateMachine(object):
|
|
|
130
134
|
self.stopping_go_to_lockdown_state,
|
|
131
135
|
self.going_to_lockdown_state,
|
|
132
136
|
self.lockdown_state,
|
|
137
|
+
self.going_to_recharging_state,
|
|
138
|
+
self.stopping_go_to_recharge_state,
|
|
133
139
|
]
|
|
134
140
|
|
|
135
141
|
self.machine = Machine(
|
|
@@ -279,6 +285,8 @@ class StateMachine(object):
|
|
|
279
285
|
return IsarStatus.Lockdown
|
|
280
286
|
elif self.current_state == States.GoingToLockdown:
|
|
281
287
|
return IsarStatus.GoingToLockdown
|
|
288
|
+
elif self.current_state == States.GoingToRecharging:
|
|
289
|
+
return IsarStatus.GoingToRecharging
|
|
282
290
|
else:
|
|
283
291
|
return IsarStatus.Busy
|
|
284
292
|
|
|
@@ -22,6 +22,7 @@ class AwaitNextMission(EventHandlerBase):
|
|
|
22
22
|
|
|
23
23
|
def __init__(self, state_machine: "StateMachine"):
|
|
24
24
|
events = state_machine.events
|
|
25
|
+
shared_state = state_machine.shared_state
|
|
25
26
|
|
|
26
27
|
def _send_to_lockdown_event_handler(
|
|
27
28
|
event: Event[bool],
|
|
@@ -35,6 +36,18 @@ class AwaitNextMission(EventHandlerBase):
|
|
|
35
36
|
)
|
|
36
37
|
return state_machine.request_lockdown_mission # type: ignore
|
|
37
38
|
|
|
39
|
+
def _robot_battery_level_updated_handler(
|
|
40
|
+
event: Event[float],
|
|
41
|
+
) -> Optional[Callable]:
|
|
42
|
+
battery_level: float = event.check()
|
|
43
|
+
if (
|
|
44
|
+
battery_level is None
|
|
45
|
+
or battery_level >= settings.ROBOT_MISSION_BATTERY_START_THRESHOLD
|
|
46
|
+
):
|
|
47
|
+
return None
|
|
48
|
+
|
|
49
|
+
return state_machine.request_recharging_mission # type: ignore
|
|
50
|
+
|
|
38
51
|
event_handlers: List[EventHandlerMapping] = [
|
|
39
52
|
EventHandlerMapping(
|
|
40
53
|
name="start_mission_event",
|
|
@@ -58,6 +71,11 @@ class AwaitNextMission(EventHandlerBase):
|
|
|
58
71
|
event=events.api_requests.send_to_lockdown.request,
|
|
59
72
|
handler=_send_to_lockdown_event_handler,
|
|
60
73
|
),
|
|
74
|
+
EventHandlerMapping(
|
|
75
|
+
name="robot_battery_update_event",
|
|
76
|
+
event=shared_state.robot_battery_level,
|
|
77
|
+
handler=_robot_battery_level_updated_handler,
|
|
78
|
+
),
|
|
61
79
|
]
|
|
62
80
|
|
|
63
81
|
timers: List[TimeoutHandlerMapping] = [
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, Callable, List, Optional
|
|
2
|
+
|
|
3
|
+
from isar.apis.models.models import LockdownResponse
|
|
4
|
+
from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
|
|
5
|
+
from isar.models.events import Event
|
|
6
|
+
from robot_interface.models.exceptions.robot_exceptions import ErrorMessage
|
|
7
|
+
from robot_interface.models.mission.status import MissionStatus
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from isar.state_machine.state_machine import StateMachine
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class GoingToRecharging(EventHandlerBase):
|
|
14
|
+
|
|
15
|
+
def __init__(self, state_machine: "StateMachine"):
|
|
16
|
+
events = state_machine.events
|
|
17
|
+
|
|
18
|
+
def _mission_failed_event_handler(
|
|
19
|
+
event: Event[Optional[ErrorMessage]],
|
|
20
|
+
) -> Optional[Callable]:
|
|
21
|
+
mission_failed: Optional[ErrorMessage] = event.consume_event()
|
|
22
|
+
if mission_failed is None:
|
|
23
|
+
return None
|
|
24
|
+
|
|
25
|
+
state_machine.logger.warning(
|
|
26
|
+
f"Failed to go to recharging because: "
|
|
27
|
+
f"{mission_failed.error_description}"
|
|
28
|
+
)
|
|
29
|
+
return state_machine.return_home_failed # type: ignore
|
|
30
|
+
|
|
31
|
+
def _mission_status_event_handler(
|
|
32
|
+
event: Event[MissionStatus],
|
|
33
|
+
) -> Optional[Callable]:
|
|
34
|
+
mission_status: Optional[MissionStatus] = event.consume_event()
|
|
35
|
+
|
|
36
|
+
if not mission_status or mission_status in [
|
|
37
|
+
MissionStatus.InProgress,
|
|
38
|
+
MissionStatus.NotStarted,
|
|
39
|
+
MissionStatus.Paused,
|
|
40
|
+
]:
|
|
41
|
+
return None
|
|
42
|
+
|
|
43
|
+
if mission_status != MissionStatus.Successful:
|
|
44
|
+
return state_machine.return_home_failed # type: ignore
|
|
45
|
+
|
|
46
|
+
return state_machine.starting_recharging # type: ignore
|
|
47
|
+
|
|
48
|
+
def _send_to_lockdown_event_handler(
|
|
49
|
+
event: Event[bool],
|
|
50
|
+
) -> Optional[Callable]:
|
|
51
|
+
should_lockdown: bool = event.consume_event()
|
|
52
|
+
if not should_lockdown:
|
|
53
|
+
return None
|
|
54
|
+
|
|
55
|
+
events.api_requests.send_to_lockdown.response.trigger_event(
|
|
56
|
+
LockdownResponse(lockdown_started=True)
|
|
57
|
+
)
|
|
58
|
+
return state_machine.go_to_lockdown # type: ignore
|
|
59
|
+
|
|
60
|
+
event_handlers: List[EventHandlerMapping] = [
|
|
61
|
+
EventHandlerMapping(
|
|
62
|
+
name="mission_failed_event",
|
|
63
|
+
event=events.robot_service_events.mission_failed,
|
|
64
|
+
handler=_mission_failed_event_handler,
|
|
65
|
+
),
|
|
66
|
+
EventHandlerMapping(
|
|
67
|
+
name="mission_status_event",
|
|
68
|
+
event=events.robot_service_events.mission_status_updated,
|
|
69
|
+
handler=_mission_status_event_handler,
|
|
70
|
+
),
|
|
71
|
+
EventHandlerMapping(
|
|
72
|
+
name="send_to_lockdown_event",
|
|
73
|
+
event=events.api_requests.send_to_lockdown.request,
|
|
74
|
+
handler=_send_to_lockdown_event_handler,
|
|
75
|
+
),
|
|
76
|
+
]
|
|
77
|
+
super().__init__(
|
|
78
|
+
state_name="going_to_recharging",
|
|
79
|
+
state_machine=state_machine,
|
|
80
|
+
event_handler_mappings=event_handlers,
|
|
81
|
+
)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from typing import TYPE_CHECKING, Callable, List, Optional
|
|
2
2
|
|
|
3
3
|
from isar.apis.models.models import LockdownResponse
|
|
4
|
+
from isar.config.settings import settings
|
|
4
5
|
from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
|
|
5
6
|
from isar.models.events import Event
|
|
6
7
|
from isar.state_machine.utils.common_event_handlers import (
|
|
@@ -44,6 +45,18 @@ class Home(EventHandlerBase):
|
|
|
44
45
|
return state_machine.robot_status_changed # type: ignore
|
|
45
46
|
return None
|
|
46
47
|
|
|
48
|
+
def _robot_battery_level_updated_handler(
|
|
49
|
+
event: Event[float],
|
|
50
|
+
) -> Optional[Callable]:
|
|
51
|
+
battery_level: float = event.check()
|
|
52
|
+
if (
|
|
53
|
+
battery_level is None
|
|
54
|
+
or battery_level >= settings.ROBOT_MISSION_BATTERY_START_THRESHOLD
|
|
55
|
+
):
|
|
56
|
+
return None
|
|
57
|
+
|
|
58
|
+
return state_machine.starting_recharging # type: ignore
|
|
59
|
+
|
|
47
60
|
event_handlers: List[EventHandlerMapping] = [
|
|
48
61
|
EventHandlerMapping(
|
|
49
62
|
name="start_mission_event",
|
|
@@ -72,6 +85,11 @@ class Home(EventHandlerBase):
|
|
|
72
85
|
event=events.api_requests.send_to_lockdown.request,
|
|
73
86
|
handler=_send_to_lockdown_event_handler,
|
|
74
87
|
),
|
|
88
|
+
EventHandlerMapping(
|
|
89
|
+
name="robot_battery_update_event",
|
|
90
|
+
event=shared_state.robot_battery_level,
|
|
91
|
+
handler=_robot_battery_level_updated_handler,
|
|
92
|
+
),
|
|
75
93
|
]
|
|
76
94
|
super().__init__(
|
|
77
95
|
state_name="home",
|
|
@@ -30,16 +30,16 @@ class Monitor(EventHandlerBase):
|
|
|
30
30
|
event: Event[float],
|
|
31
31
|
) -> Optional[Callable]:
|
|
32
32
|
battery_level: float = event.check()
|
|
33
|
-
if
|
|
33
|
+
if (
|
|
34
|
+
battery_level is None
|
|
35
|
+
or battery_level >= settings.ROBOT_MISSION_BATTERY_START_THRESHOLD
|
|
36
|
+
):
|
|
34
37
|
return None
|
|
35
38
|
|
|
36
|
-
state_machine.publish_mission_aborted(
|
|
37
|
-
"Robot battery too low to continue mission", True
|
|
38
|
-
)
|
|
39
39
|
state_machine.logger.warning(
|
|
40
40
|
"Cancelling current mission due to low battery"
|
|
41
41
|
)
|
|
42
|
-
return state_machine.
|
|
42
|
+
return state_machine.stop_go_to_recharge # type: ignore
|
|
43
43
|
|
|
44
44
|
def _send_to_lockdown_event_handler(
|
|
45
45
|
event: Event[bool],
|
|
@@ -19,7 +19,10 @@ class Paused(EventHandlerBase):
|
|
|
19
19
|
event: Event[float],
|
|
20
20
|
) -> Optional[Callable]:
|
|
21
21
|
battery_level: float = event.check()
|
|
22
|
-
if
|
|
22
|
+
if (
|
|
23
|
+
battery_level is None
|
|
24
|
+
or battery_level >= settings.ROBOT_MISSION_BATTERY_START_THRESHOLD
|
|
25
|
+
):
|
|
23
26
|
return None
|
|
24
27
|
|
|
25
28
|
state_machine.publish_mission_aborted(
|
|
@@ -21,7 +21,10 @@ class ReturnHomePaused(EventHandlerBase):
|
|
|
21
21
|
) -> Optional[Callable]:
|
|
22
22
|
battery_level: float = event.check()
|
|
23
23
|
|
|
24
|
-
if
|
|
24
|
+
if (
|
|
25
|
+
battery_level is None
|
|
26
|
+
or battery_level >= settings.ROBOT_MISSION_BATTERY_START_THRESHOLD
|
|
27
|
+
):
|
|
25
28
|
return None
|
|
26
29
|
|
|
27
30
|
return state_machine.resume # type: ignore
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from typing import TYPE_CHECKING, Callable, List, Optional
|
|
2
2
|
|
|
3
3
|
from isar.apis.models.models import LockdownResponse, MissionStartResponse
|
|
4
|
+
from isar.config.settings import settings
|
|
4
5
|
from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
|
|
5
6
|
from isar.models.events import Event
|
|
6
7
|
from isar.state_machine.utils.common_event_handlers import mission_started_event_handler
|
|
@@ -17,6 +18,7 @@ class ReturningHome(EventHandlerBase):
|
|
|
17
18
|
def __init__(self, state_machine: "StateMachine"):
|
|
18
19
|
self.failed_return_home_attemps: int = 0
|
|
19
20
|
events = state_machine.events
|
|
21
|
+
shared_state = state_machine.shared_state
|
|
20
22
|
|
|
21
23
|
def _pause_mission_event_handler(event: Event[bool]) -> Optional[Callable]:
|
|
22
24
|
if not event.consume_event():
|
|
@@ -59,10 +61,7 @@ class ReturningHome(EventHandlerBase):
|
|
|
59
61
|
return state_machine.return_home_failed # type: ignore
|
|
60
62
|
|
|
61
63
|
self.failed_return_home_attemps = 0
|
|
62
|
-
|
|
63
|
-
return state_machine.starting_recharging # type: ignore
|
|
64
|
-
else:
|
|
65
|
-
return state_machine.returned_home # type: ignore
|
|
64
|
+
return state_machine.returned_home # type: ignore
|
|
66
65
|
return None
|
|
67
66
|
|
|
68
67
|
def _send_to_lockdown_event_handler(
|
|
@@ -89,6 +88,18 @@ class ReturningHome(EventHandlerBase):
|
|
|
89
88
|
return state_machine.return_home_failed # type: ignore
|
|
90
89
|
return None
|
|
91
90
|
|
|
91
|
+
def _robot_battery_level_updated_handler(
|
|
92
|
+
event: Event[float],
|
|
93
|
+
) -> Optional[Callable]:
|
|
94
|
+
battery_level: float = event.check()
|
|
95
|
+
if (
|
|
96
|
+
battery_level is None
|
|
97
|
+
or battery_level >= settings.ROBOT_MISSION_BATTERY_START_THRESHOLD
|
|
98
|
+
):
|
|
99
|
+
return None
|
|
100
|
+
|
|
101
|
+
return state_machine.go_to_recharging # type: ignore
|
|
102
|
+
|
|
92
103
|
event_handlers: List[EventHandlerMapping] = [
|
|
93
104
|
EventHandlerMapping(
|
|
94
105
|
name="pause_mission_event",
|
|
@@ -117,6 +128,11 @@ class ReturningHome(EventHandlerBase):
|
|
|
117
128
|
event=events.robot_service_events.mission_status_updated,
|
|
118
129
|
handler=_mission_status_event_handler,
|
|
119
130
|
),
|
|
131
|
+
EventHandlerMapping(
|
|
132
|
+
name="robot_battery_update_event",
|
|
133
|
+
event=shared_state.robot_battery_level,
|
|
134
|
+
handler=_robot_battery_level_updated_handler,
|
|
135
|
+
),
|
|
120
136
|
EventHandlerMapping(
|
|
121
137
|
name="send_to_lockdown_event",
|
|
122
138
|
event=events.api_requests.send_to_lockdown.request,
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, Callable, List, Optional
|
|
2
|
+
|
|
3
|
+
from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
|
|
4
|
+
from isar.models.events import Event
|
|
5
|
+
from robot_interface.models.exceptions.robot_exceptions import ErrorMessage
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from isar.state_machine.state_machine import StateMachine
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class StoppingGoToRecharge(EventHandlerBase):
|
|
12
|
+
|
|
13
|
+
def __init__(self, state_machine: "StateMachine"):
|
|
14
|
+
events = state_machine.events
|
|
15
|
+
|
|
16
|
+
def _failed_stop_event_handler(
|
|
17
|
+
event: Event[ErrorMessage],
|
|
18
|
+
) -> Optional[Callable]:
|
|
19
|
+
error_message: Optional[ErrorMessage] = event.consume_event()
|
|
20
|
+
if error_message is None:
|
|
21
|
+
return None
|
|
22
|
+
|
|
23
|
+
return state_machine.mission_stopping_failed # type: ignore
|
|
24
|
+
|
|
25
|
+
def _successful_stop_event_handler(event: Event[bool]) -> Optional[Callable]:
|
|
26
|
+
if not event.consume_event():
|
|
27
|
+
return None
|
|
28
|
+
|
|
29
|
+
state_machine.publish_mission_aborted(
|
|
30
|
+
"Robot battery too low to continue mission", True
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
return state_machine.request_recharging_mission # type: ignore
|
|
34
|
+
|
|
35
|
+
event_handlers: List[EventHandlerMapping] = [
|
|
36
|
+
EventHandlerMapping(
|
|
37
|
+
name="failed_stop_event",
|
|
38
|
+
event=events.robot_service_events.mission_failed_to_stop,
|
|
39
|
+
handler=_failed_stop_event_handler,
|
|
40
|
+
),
|
|
41
|
+
EventHandlerMapping(
|
|
42
|
+
name="successful_stop_event",
|
|
43
|
+
event=events.robot_service_events.mission_successfully_stopped,
|
|
44
|
+
handler=_successful_stop_event_handler,
|
|
45
|
+
),
|
|
46
|
+
]
|
|
47
|
+
super().__init__(
|
|
48
|
+
state_name="stopping_go_to_recharge",
|
|
49
|
+
state_machine=state_machine,
|
|
50
|
+
event_handler_mappings=event_handlers,
|
|
51
|
+
)
|
|
@@ -20,6 +20,8 @@ class States(str, Enum):
|
|
|
20
20
|
StoppingGoToLockdown = "stopping_go_to_lockdown"
|
|
21
21
|
GoingToLockdown = "going_to_lockdown"
|
|
22
22
|
Lockdown = "lockdown"
|
|
23
|
+
GoingToRecharging = "going_to_recharging"
|
|
24
|
+
StoppingGoToRecharge = "stopping_go_to_recharge"
|
|
23
25
|
|
|
24
26
|
def __repr__(self):
|
|
25
27
|
return self.value
|
|
@@ -10,6 +10,7 @@ from isar.config.settings import settings
|
|
|
10
10
|
from robot_interface.models.exceptions.robot_exceptions import (
|
|
11
11
|
RobotActionException,
|
|
12
12
|
RobotException,
|
|
13
|
+
RobotNoMissionRunningException,
|
|
13
14
|
)
|
|
14
15
|
|
|
15
16
|
|
|
@@ -32,6 +33,12 @@ def resume_mission(state_machine: "StateMachine") -> bool:
|
|
|
32
33
|
|
|
33
34
|
state_machine.logger.info("Mission resumed successfully.")
|
|
34
35
|
return True
|
|
36
|
+
except RobotNoMissionRunningException as e:
|
|
37
|
+
state_machine.logger.error(
|
|
38
|
+
f"Failed to resume mission: {e.error_reason}. {e.error_description}"
|
|
39
|
+
)
|
|
40
|
+
# TODO: this will make it go to paused, instead of awaitnextmission
|
|
41
|
+
return False
|
|
35
42
|
except RobotActionException as e:
|
|
36
43
|
state_machine.logger.warning(
|
|
37
44
|
f"Attempt {attempt + 1} to resume mission failed: {e.error_description}"
|
|
@@ -110,6 +110,12 @@ def get_mission_transitions(state_machine: "StateMachine") -> List[dict]:
|
|
|
110
110
|
"dest": state_machine.stopping_go_to_lockdown_state,
|
|
111
111
|
"before": def_transition(state_machine, trigger_stop_mission_event),
|
|
112
112
|
},
|
|
113
|
+
{
|
|
114
|
+
"trigger": "stop_go_to_recharge",
|
|
115
|
+
"source": state_machine.monitor_state,
|
|
116
|
+
"dest": state_machine.stopping_go_to_recharge_state,
|
|
117
|
+
"before": def_transition(state_machine, trigger_stop_mission_event),
|
|
118
|
+
},
|
|
113
119
|
{
|
|
114
120
|
"trigger": "stop_return_home",
|
|
115
121
|
"source": [
|
|
@@ -140,7 +146,10 @@ def get_mission_transitions(state_machine: "StateMachine") -> List[dict]:
|
|
|
140
146
|
},
|
|
141
147
|
{
|
|
142
148
|
"trigger": "mission_stopping_failed",
|
|
143
|
-
"source":
|
|
149
|
+
"source": [
|
|
150
|
+
state_machine.stopping_go_to_lockdown_state,
|
|
151
|
+
state_machine.stopping_go_to_recharge_state,
|
|
152
|
+
],
|
|
144
153
|
"dest": state_machine.monitor_state,
|
|
145
154
|
},
|
|
146
155
|
{
|
|
@@ -61,7 +61,7 @@ def get_return_home_transitions(state_machine: "StateMachine") -> List[dict]:
|
|
|
61
61
|
},
|
|
62
62
|
{
|
|
63
63
|
"trigger": "starting_recharging",
|
|
64
|
-
"source": state_machine.
|
|
64
|
+
"source": state_machine.going_to_recharging_state,
|
|
65
65
|
"dest": state_machine.recharging_state,
|
|
66
66
|
"before": [
|
|
67
67
|
def_transition(state_machine, reset_return_home_failure_counter),
|
|
@@ -69,7 +69,7 @@ def get_return_home_transitions(state_machine: "StateMachine") -> List[dict]:
|
|
|
69
69
|
},
|
|
70
70
|
{
|
|
71
71
|
"trigger": "starting_recharging",
|
|
72
|
-
"source": state_machine.lockdown_state,
|
|
72
|
+
"source": [state_machine.lockdown_state, state_machine.home_state],
|
|
73
73
|
"dest": state_machine.recharging_state,
|
|
74
74
|
},
|
|
75
75
|
{
|
|
@@ -86,7 +86,10 @@ def get_return_home_transitions(state_machine: "StateMachine") -> List[dict]:
|
|
|
86
86
|
},
|
|
87
87
|
{
|
|
88
88
|
"trigger": "return_home_failed",
|
|
89
|
-
"source":
|
|
89
|
+
"source": [
|
|
90
|
+
state_machine.returning_home_state,
|
|
91
|
+
state_machine.going_to_recharging_state,
|
|
92
|
+
],
|
|
90
93
|
"dest": state_machine.intervention_needed_state,
|
|
91
94
|
"before": [
|
|
92
95
|
def_transition(
|
|
@@ -112,14 +115,36 @@ def get_return_home_transitions(state_machine: "StateMachine") -> List[dict]:
|
|
|
112
115
|
def_transition(state_machine, initialize_robot),
|
|
113
116
|
],
|
|
114
117
|
},
|
|
118
|
+
{
|
|
119
|
+
"trigger": "request_recharging_mission",
|
|
120
|
+
"source": [
|
|
121
|
+
state_machine.stopping_go_to_recharge_state,
|
|
122
|
+
state_machine.await_next_mission_state,
|
|
123
|
+
],
|
|
124
|
+
"dest": state_machine.going_to_recharging_state,
|
|
125
|
+
"conditions": [
|
|
126
|
+
def_transition(state_machine, start_return_home_mission),
|
|
127
|
+
def_transition(state_machine, initialize_robot),
|
|
128
|
+
],
|
|
129
|
+
},
|
|
115
130
|
{
|
|
116
131
|
"trigger": "go_to_lockdown",
|
|
117
132
|
"source": [
|
|
118
133
|
state_machine.returning_home_state,
|
|
119
134
|
state_machine.return_home_paused_state,
|
|
135
|
+
state_machine.going_to_recharging_state,
|
|
120
136
|
],
|
|
121
137
|
"dest": state_machine.going_to_lockdown_state,
|
|
122
138
|
},
|
|
139
|
+
{
|
|
140
|
+
"trigger": "go_to_recharging",
|
|
141
|
+
"source": [
|
|
142
|
+
state_machine.returning_home_state,
|
|
143
|
+
state_machine.return_home_paused_state,
|
|
144
|
+
state_machine.home_state,
|
|
145
|
+
],
|
|
146
|
+
"dest": state_machine.going_to_recharging_state,
|
|
147
|
+
},
|
|
123
148
|
{
|
|
124
149
|
"trigger": "reached_lockdown",
|
|
125
150
|
"source": [
|
|
@@ -41,15 +41,15 @@ isar/mission_planner/local_planner.py,sha256=Mkg3vvUBF1jImfQnaFvXLNpKVadR21X4mwD
|
|
|
41
41
|
isar/mission_planner/mission_planner_interface.py,sha256=UgpPIM4FbrWOD7fGY3Ul64k3uYb8wo0FwSWGewYoVbc,485
|
|
42
42
|
isar/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
43
43
|
isar/models/events.py,sha256=lwjq745VWJLRLdqNke58sWMRt8zz75hUt7t0QkbLsFU,5602
|
|
44
|
-
isar/models/status.py,sha256=
|
|
45
|
-
isar/robot/robot.py,sha256=
|
|
44
|
+
isar/models/status.py,sha256=qPQdeE_6yB-twWtTHdeUMmSLMjbtWNGLHJOF_aucqx4,474
|
|
45
|
+
isar/robot/robot.py,sha256=bVzD4psVOCc7La1DjwTeRUmxFWwWp-3TwMdmcyoFOwU,11996
|
|
46
46
|
isar/robot/robot_battery.py,sha256=goLdgmn61QCgE2Ja3YuiwE_sqJzIhCkS3u90sz1kdug,2089
|
|
47
|
-
isar/robot/robot_monitor_mission.py,sha256=
|
|
48
|
-
isar/robot/robot_pause_mission.py,sha256=
|
|
49
|
-
isar/robot/robot_start_mission.py,sha256=
|
|
47
|
+
isar/robot/robot_monitor_mission.py,sha256=mdnTZlhBgr-lWsAQRyP_vXiu3DYl-4joC0myZmgcw1o,15938
|
|
48
|
+
isar/robot/robot_pause_mission.py,sha256=MpK3YEux7k0Ks8Orv7Iz7ADhiEC8X_9LQZ5mK7e1a90,2247
|
|
49
|
+
isar/robot/robot_start_mission.py,sha256=KO_gUNEYvjNJ3eSkH-umUOEezwpLKIYBEuF_eot4rIM,2683
|
|
50
50
|
isar/robot/robot_status.py,sha256=dfAls3s8_Vha7ZMLSYngELqsdpaEpcweAWRHanQj8u8,2361
|
|
51
|
-
isar/robot/robot_stop_mission.py,sha256=
|
|
52
|
-
isar/robot/robot_upload_inspection.py,sha256=
|
|
51
|
+
isar/robot/robot_stop_mission.py,sha256=CaXLsZjjazHmydU9iR7uOWUHtJ2zvKh4ItUbkWY5sIk,2321
|
|
52
|
+
isar/robot/robot_upload_inspection.py,sha256=uCc9nuH1Am5uxD2Tgnm4ZTOm0tQnud0F6eHs0rSUfvY,2539
|
|
53
53
|
isar/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
54
54
|
isar/services/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
55
55
|
isar/services/auth/azure_credentials.py,sha256=9PlwGe5FrPRbW2dp0go7LMp8_l_FRvL8xOXotXwzRDo,364
|
|
@@ -64,34 +64,36 @@ isar/services/utilities/robot_utilities.py,sha256=4zCigsLXfqDC8POHchktSq81zr1_pT
|
|
|
64
64
|
isar/services/utilities/scheduling_utilities.py,sha256=AcoMWpNfNJ-IRu5ulLNtriLTKIVgog47im0yQ_ECanQ,20442
|
|
65
65
|
isar/services/utilities/threaded_request.py,sha256=py4G-_RjnIdHljmKFAcQ6ddqMmp-ZYV39Ece-dqRqjs,1874
|
|
66
66
|
isar/state_machine/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
67
|
-
isar/state_machine/state_machine.py,sha256=
|
|
68
|
-
isar/state_machine/states_enum.py,sha256=
|
|
67
|
+
isar/state_machine/state_machine.py,sha256=xd9GISbN-N73k8fme2zctg7H6Ur5Zl27PAg--xmj34k,12038
|
|
68
|
+
isar/state_machine/states_enum.py,sha256=XaFJ1GJMVACE5aw3oYxP-GPT6ucLXhnIMGOu5nTLVnI,845
|
|
69
69
|
isar/state_machine/states/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
70
|
-
isar/state_machine/states/await_next_mission.py,sha256=
|
|
70
|
+
isar/state_machine/states/await_next_mission.py,sha256=MlIyFbiu6odQuX0H7Y1vg9_ay-ZzsTFtraX7yyIOxkY,3433
|
|
71
71
|
isar/state_machine/states/blocked_protective_stop.py,sha256=HJr_jH8OdHMuX8zhjlF5jtNAfMCxkA1X7nOGmkAz-RY,1263
|
|
72
72
|
isar/state_machine/states/going_to_lockdown.py,sha256=qOmJt5V51_fhJobIzzFyFW-sxfoktG8_Vt9a4N-EmWs,2725
|
|
73
|
-
isar/state_machine/states/
|
|
73
|
+
isar/state_machine/states/going_to_recharging.py,sha256=Ubn7YvKs4gr6rlII9BLt2aamIBYIIY9QfcQN-yn1HtY,3051
|
|
74
|
+
isar/state_machine/states/home.py,sha256=BNIuKYjRPGLjcVXfrJLyNM7sab6HB95hFr_n2MWoZpM,3837
|
|
74
75
|
isar/state_machine/states/intervention_needed.py,sha256=nv7054e9gBJQ4-Mshs8cczqnD0IN-N-_5qvUR-cNcUM,1633
|
|
75
76
|
isar/state_machine/states/lockdown.py,sha256=ZFw9XMDENECuH3lh89RKeU_3CTzW0ZBvqCKptFJG5xo,1364
|
|
76
|
-
isar/state_machine/states/monitor.py,sha256=
|
|
77
|
+
isar/state_machine/states/monitor.py,sha256=o68TMYMoYccnbyXsVsIehuYdvMv3FqZYNzFI3oIdl44,4471
|
|
77
78
|
isar/state_machine/states/offline.py,sha256=k1UdcRWLd6lJiL5cnpHKBkvMY4xZMt_x7XIauy-Rgww,1219
|
|
78
|
-
isar/state_machine/states/paused.py,sha256=
|
|
79
|
+
isar/state_machine/states/paused.py,sha256=pR8ZuETs-OAl6oUEZGRCfXAZgQyeDeA8KcOKA1b8c1Y,2922
|
|
79
80
|
isar/state_machine/states/pausing.py,sha256=CJf_wqpajizv-UY3gL8ctHbPbVP-jXkLsaQiCgfCod4,2138
|
|
80
81
|
isar/state_machine/states/pausing_return_home.py,sha256=bQjNp8cC90x7yoTLccrx3oIdaj9at-34p9ez1OqKrmE,2184
|
|
81
82
|
isar/state_machine/states/recharging.py,sha256=TSCZuWhDKBW47peeP73k7aBD4_SEMOOdD1GgOdAq6lk,2447
|
|
82
|
-
isar/state_machine/states/return_home_paused.py,sha256=
|
|
83
|
-
isar/state_machine/states/returning_home.py,sha256=
|
|
83
|
+
isar/state_machine/states/return_home_paused.py,sha256=cm2svV5l1dkDzFkGN0v3ZBEk7x8knU8E2u7N-jmFM7A,3428
|
|
84
|
+
isar/state_machine/states/returning_home.py,sha256=d_VSxLL5qKl6UYGWs-rTv6mhTbw2cvuECrAEyrntugU,5851
|
|
84
85
|
isar/state_machine/states/stopping.py,sha256=MhIU1kZCjOQpZBZ5EQ299zdvBWNaDNVdksh7Zw4Hk68,2208
|
|
85
86
|
isar/state_machine/states/stopping_go_to_lockdown.py,sha256=yl0HFxIBKFCWGQixTULuYb_Z-dwrPeI8TioZ9AQf1Lk,2264
|
|
87
|
+
isar/state_machine/states/stopping_go_to_recharge.py,sha256=eu2rPxeBJbQCNKlIxn9HJ7qZ21Fz81W-HKg8Le8gZtE,1861
|
|
86
88
|
isar/state_machine/states/stopping_return_home.py,sha256=HtoZfSXWLGCRChITZCKjOufowwZzQaJLCZGaYsjP1mE,2854
|
|
87
89
|
isar/state_machine/states/unknown_status.py,sha256=Vu07Sk90zFVInf3XdzFl5IaYrdrYaGO7Na7qAOGwjIk,1871
|
|
88
|
-
isar/state_machine/transitions/mission.py,sha256=
|
|
89
|
-
isar/state_machine/transitions/return_home.py,sha256=
|
|
90
|
+
isar/state_machine/transitions/mission.py,sha256=5H4ZvmsNn3kcaVSC7dN0C2JumzRlqq-daARtexxPgHk,7754
|
|
91
|
+
isar/state_machine/transitions/return_home.py,sha256=42o3etvJeBaWK4bJfqwtFLpSzeJFhsu_UalzLW4CzPA,6525
|
|
90
92
|
isar/state_machine/transitions/robot_status.py,sha256=7fEXHBBo8A6z8eUeNXs01xQ87l26siPB3kyTSbcnPcc,2738
|
|
91
93
|
isar/state_machine/transitions/functions/fail_mission.py,sha256=NFPGIPE0EtefUETbf8Z8plBWghcRQBrbup5xaxF3h6Y,604
|
|
92
94
|
isar/state_machine/transitions/functions/finish_mission.py,sha256=K9paNVz0wbWSkCWvVBaKTM54vdHBH-TNuqG1EstEI8w,229
|
|
93
95
|
isar/state_machine/transitions/functions/pause.py,sha256=8cQIvXDb1hKS-K6-a0fmcqJHde0FRzS-n4N8_EBSA3w,1089
|
|
94
|
-
isar/state_machine/transitions/functions/resume.py,sha256=
|
|
96
|
+
isar/state_machine/transitions/functions/resume.py,sha256=pO2PSLQsXDXGJuFDPb6TqUJ87515OcyZBo3iGSYHZ3g,1932
|
|
95
97
|
isar/state_machine/transitions/functions/return_home.py,sha256=UBXOfYKlvsmpnmUeKFkc2483fdY9pX70F4pmndjCs8Y,1148
|
|
96
98
|
isar/state_machine/transitions/functions/robot_status.py,sha256=dVh0cY6KLt0xcZ2jBQWt4GbR_CPJvrQZWhP3GEpDCZY,1105
|
|
97
99
|
isar/state_machine/transitions/functions/start_mission.py,sha256=1Op-Dutfmbc6kH1bHHu7obQ5I1G5jnYoH4wx5qSXoI0,1254
|
|
@@ -104,13 +106,13 @@ isar/storage/local_storage.py,sha256=Rn-iiiz9DI7PzIhevOMshPIaqzJaqBXeVJMQRhVSl2M
|
|
|
104
106
|
isar/storage/storage_interface.py,sha256=x-imVeQTdL6dCaTaPTHpXwCR6N4e27WxK_Vpumg0x-Y,1230
|
|
105
107
|
isar/storage/uploader.py,sha256=0BBrxyZGGRkNxGeZeoREucegs4yKUow2523oLEie07o,10841
|
|
106
108
|
isar/storage/utilities.py,sha256=oLH0Rp7UtrQQdilfITnmXO1Z0ExdeDhBImYHid55vBA,3449
|
|
107
|
-
isar-1.34.
|
|
109
|
+
isar-1.34.4.dist-info/licenses/LICENSE,sha256=3fc2-ebLwHWwzfQbulGNRdcNob3SBQeCfEVUDYxsuqw,14058
|
|
108
110
|
robot_interface/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
109
111
|
robot_interface/robot_interface.py,sha256=3JAVCzg4WV4gYgDxGfdmXPPlVETmwyoqLh7QZJMerKU,9886
|
|
110
112
|
robot_interface/test_robot_interface.py,sha256=FV1urn7SbsMyWBIcTKjsBwAG4IsXeZ6pLHE0mA9EGGs,692
|
|
111
113
|
robot_interface/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
112
114
|
robot_interface/models/exceptions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
113
|
-
robot_interface/models/exceptions/robot_exceptions.py,sha256=
|
|
115
|
+
robot_interface/models/exceptions/robot_exceptions.py,sha256=B08Om0poV2XWfI3b7nG0dkwU0CoWUUHLuyQnPpPNQec,10885
|
|
114
116
|
robot_interface/models/initialize/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
115
117
|
robot_interface/models/inspection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
116
118
|
robot_interface/models/inspection/inspection.py,sha256=cjAvekL8r82s7bgukWeXpYylHvJG_oRSCJNISPVCvZg,2238
|
|
@@ -128,8 +130,8 @@ robot_interface/telemetry/payloads.py,sha256=A0SWiG609k6o6-Y3vhDWE6an2-_m7D_ND85
|
|
|
128
130
|
robot_interface/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
129
131
|
robot_interface/utilities/json_service.py,sha256=9N1zijW7K4d3WFR2autpaS8U9o1ibymiOX-6stTKCyk,1243
|
|
130
132
|
robot_interface/utilities/uuid_string_factory.py,sha256=_NQIbBQ56w0qqO0MUDP6aPpHbxW7ATRhK8HnQiBSLkc,76
|
|
131
|
-
isar-1.34.
|
|
132
|
-
isar-1.34.
|
|
133
|
-
isar-1.34.
|
|
134
|
-
isar-1.34.
|
|
135
|
-
isar-1.34.
|
|
133
|
+
isar-1.34.4.dist-info/METADATA,sha256=k6ub1kgGNic9LAtm8-lgZNtNUk3-LDnz0mU0fgq7KJI,28866
|
|
134
|
+
isar-1.34.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
135
|
+
isar-1.34.4.dist-info/entry_points.txt,sha256=TFam7uNNw7J0iiDYzsH2gfG0u1eV1wh3JTw_HkhgKLk,49
|
|
136
|
+
isar-1.34.4.dist-info/top_level.txt,sha256=UwIML2RtuQKCyJJkatcSnyp6-ldDjboB9k9JgKipO-U,21
|
|
137
|
+
isar-1.34.4.dist-info/RECORD,,
|
|
@@ -24,6 +24,7 @@ class ErrorReason(str, Enum):
|
|
|
24
24
|
RobotTransformException = "robot_transform_exception"
|
|
25
25
|
RobotUnknownErrorException = "robot_unknown_error_exception"
|
|
26
26
|
RobotDisconnectedException = "robot_disconnected_exception"
|
|
27
|
+
RobotNoMissionRunningException = "robot_no_mission_running_exception"
|
|
27
28
|
|
|
28
29
|
|
|
29
30
|
@dataclass
|
|
@@ -53,6 +54,18 @@ class RobotCommunicationException(RobotException):
|
|
|
53
54
|
pass
|
|
54
55
|
|
|
55
56
|
|
|
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
|
+
|
|
66
|
+
pass
|
|
67
|
+
|
|
68
|
+
|
|
56
69
|
# An exception which should be thrown by the robot package if the communication has timed
|
|
57
70
|
# out and ISAR should retry the request.
|
|
58
71
|
class RobotCommunicationTimeoutException(RobotException):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|