isar 1.33.2__py3-none-any.whl → 1.33.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/apis/schedule/scheduling_controller.py +3 -1
- isar/services/service_connections/mqtt/mqtt_client.py +9 -9
- isar/services/utilities/scheduling_utilities.py +5 -9
- isar/state_machine/state_machine.py +11 -7
- isar/state_machine/states/home.py +14 -5
- isar/state_machine/states/paused.py +24 -1
- isar/state_machine/states/return_home_paused.py +66 -0
- isar/state_machine/states/returning_home.py +10 -5
- isar/state_machine/states/stopping.py +5 -22
- isar/state_machine/states/stopping_return_home.py +73 -0
- isar/state_machine/states_enum.py +2 -1
- isar/state_machine/transitions/functions/pause.py +38 -0
- isar/state_machine/transitions/functions/robot_status.py +2 -7
- isar/state_machine/transitions/mission.py +46 -19
- isar/state_machine/transitions/return_home.py +1 -7
- isar/state_machine/transitions/robot_status.py +2 -17
- isar/storage/uploader.py +15 -0
- {isar-1.33.2.dist-info → isar-1.33.4.dist-info}/METADATA +2 -2
- {isar-1.33.2.dist-info → isar-1.33.4.dist-info}/RECORD +24 -23
- robot_interface/models/mission/status.py +2 -1
- isar/state_machine/states/robot_standing_still.py +0 -52
- {isar-1.33.2.dist-info → isar-1.33.4.dist-info}/WHEEL +0 -0
- {isar-1.33.2.dist-info → isar-1.33.4.dist-info}/entry_points.txt +0 -0
- {isar-1.33.2.dist-info → isar-1.33.4.dist-info}/licenses/LICENSE +0 -0
- {isar-1.33.2.dist-info → isar-1.33.4.dist-info}/top_level.txt +0 -0
|
@@ -115,6 +115,7 @@ class SchedulingController:
|
|
|
115
115
|
|
|
116
116
|
if state not in [
|
|
117
117
|
States.Monitor,
|
|
118
|
+
States.ReturningHome,
|
|
118
119
|
]:
|
|
119
120
|
error_message = (
|
|
120
121
|
f"Conflict - Pause command received in invalid state - State: {state}"
|
|
@@ -135,7 +136,7 @@ class SchedulingController:
|
|
|
135
136
|
|
|
136
137
|
state: States = self.scheduling_utilities.get_state()
|
|
137
138
|
|
|
138
|
-
if state
|
|
139
|
+
if state not in [States.Paused, States.ReturnHomePaused]:
|
|
139
140
|
error_message = (
|
|
140
141
|
f"Conflict - Resume command received in invalid state - State: {state}"
|
|
141
142
|
)
|
|
@@ -167,6 +168,7 @@ class SchedulingController:
|
|
|
167
168
|
or state == States.BlockedProtectiveStop
|
|
168
169
|
or state == States.Offline
|
|
169
170
|
or state == States.Home
|
|
171
|
+
or state == States.ReturningHome
|
|
170
172
|
):
|
|
171
173
|
error_message = (
|
|
172
174
|
f"Conflict - Stop command received in invalid state - State: {state}"
|
|
@@ -106,15 +106,15 @@ class MqttClient(MqttClientInterface):
|
|
|
106
106
|
)
|
|
107
107
|
|
|
108
108
|
def on_connect(self, client, userdata, flags, reason_code, properties):
|
|
109
|
-
self.logger.info(
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
if
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
)
|
|
109
|
+
self.logger.info(f"Connected: {reason_code}")
|
|
110
|
+
|
|
111
|
+
def on_disconnect(self, client, userdata, *args):
|
|
112
|
+
if not args:
|
|
113
|
+
return
|
|
114
|
+
reason_code = args[0] if len(args) < 3 else args[1]
|
|
115
|
+
rc = getattr(reason_code, "value", reason_code)
|
|
116
|
+
if rc != 0:
|
|
117
|
+
self.logger.warning(f"Unexpected disconnect: {reason_code}.")
|
|
118
118
|
|
|
119
119
|
@backoff.on_exception(
|
|
120
120
|
backoff.expo,
|
|
@@ -129,13 +129,13 @@ class SchedulingUtilities:
|
|
|
129
129
|
------
|
|
130
130
|
HTTPException 409 Conflict
|
|
131
131
|
If state machine is not home, robot standing still, awaiting next mission
|
|
132
|
-
or returning home and therefore cannot start a new mission
|
|
132
|
+
return home paused or returning home and therefore cannot start a new mission
|
|
133
133
|
"""
|
|
134
134
|
if (
|
|
135
|
-
state == States.
|
|
136
|
-
or state == States.Home
|
|
135
|
+
state == States.Home
|
|
137
136
|
or state == States.AwaitNextMission
|
|
138
137
|
or state == States.ReturningHome
|
|
138
|
+
or state == States.ReturnHomePaused
|
|
139
139
|
):
|
|
140
140
|
return True
|
|
141
141
|
|
|
@@ -154,11 +154,7 @@ class SchedulingUtilities:
|
|
|
154
154
|
If state machine is not home, robot standing still or awaiting next mission
|
|
155
155
|
and therefore cannot start a new return home mission
|
|
156
156
|
"""
|
|
157
|
-
if
|
|
158
|
-
state == States.RobotStandingStill
|
|
159
|
-
or state == States.Home
|
|
160
|
-
or state == States.AwaitNextMission
|
|
161
|
-
):
|
|
157
|
+
if state == States.Home or state == States.AwaitNextMission:
|
|
162
158
|
return True
|
|
163
159
|
|
|
164
160
|
error_message = f"Conflict - Robot is not home, robot standing still or awaiting next mission - State: {state}"
|
|
@@ -336,7 +332,7 @@ class SchedulingUtilities:
|
|
|
336
332
|
)
|
|
337
333
|
|
|
338
334
|
def _send_command(self, input: T1, api_event: APIEvent[T1, T2]) -> T2:
|
|
339
|
-
if api_event.request.has_event()
|
|
335
|
+
if api_event.request.has_event():
|
|
340
336
|
raise EventConflictError("API event has already been sent")
|
|
341
337
|
|
|
342
338
|
try:
|
|
@@ -24,9 +24,10 @@ from isar.state_machine.states.monitor import Monitor
|
|
|
24
24
|
from isar.state_machine.states.offline import Offline
|
|
25
25
|
from isar.state_machine.states.paused import Paused
|
|
26
26
|
from isar.state_machine.states.recharging import Recharging
|
|
27
|
+
from isar.state_machine.states.return_home_paused import ReturnHomePaused
|
|
27
28
|
from isar.state_machine.states.returning_home import ReturningHome
|
|
28
|
-
from isar.state_machine.states.robot_standing_still import RobotStandingStill
|
|
29
29
|
from isar.state_machine.states.stopping import Stopping
|
|
30
|
+
from isar.state_machine.states.stopping_return_home import StoppingReturnHome
|
|
30
31
|
from isar.state_machine.states.unknown_status import UnknownStatus
|
|
31
32
|
from isar.state_machine.states_enum import States
|
|
32
33
|
from isar.state_machine.transitions.mission import get_mission_transitions
|
|
@@ -101,11 +102,12 @@ class StateMachine(object):
|
|
|
101
102
|
self.returning_home_state: State = ReturningHome(self)
|
|
102
103
|
self.stopping_state: State = Stopping(self)
|
|
103
104
|
self.paused_state: State = Paused(self)
|
|
105
|
+
self.return_home_paused_state: State = ReturnHomePaused(self)
|
|
106
|
+
self.stopping_return_home_state: State = StoppingReturnHome(self)
|
|
104
107
|
|
|
105
108
|
# States Waiting for mission
|
|
106
109
|
self.await_next_mission_state: State = AwaitNextMission(self)
|
|
107
110
|
self.home_state: State = Home(self)
|
|
108
|
-
self.robot_standing_still_state: State = RobotStandingStill(self)
|
|
109
111
|
self.intervention_needed_state: State = InterventionNeeded(self)
|
|
110
112
|
|
|
111
113
|
# Status states
|
|
@@ -120,10 +122,11 @@ class StateMachine(object):
|
|
|
120
122
|
self.monitor_state,
|
|
121
123
|
self.returning_home_state,
|
|
122
124
|
self.stopping_state,
|
|
125
|
+
self.stopping_return_home_state,
|
|
123
126
|
self.paused_state,
|
|
127
|
+
self.return_home_paused_state,
|
|
124
128
|
self.await_next_mission_state,
|
|
125
129
|
self.home_state,
|
|
126
|
-
self.robot_standing_still_state,
|
|
127
130
|
self.offline_state,
|
|
128
131
|
self.blocked_protective_stopping_state,
|
|
129
132
|
self.unknown_status_state,
|
|
@@ -363,11 +366,12 @@ class StateMachine(object):
|
|
|
363
366
|
)
|
|
364
367
|
|
|
365
368
|
def _current_status(self) -> RobotStatus:
|
|
366
|
-
if
|
|
367
|
-
self.current_state == States.RobotStandingStill
|
|
368
|
-
or self.current_state == States.AwaitNextMission
|
|
369
|
-
):
|
|
369
|
+
if self.current_state == States.AwaitNextMission:
|
|
370
370
|
return RobotStatus.Available
|
|
371
|
+
elif self.current_state == States.ReturnHomePaused:
|
|
372
|
+
return RobotStatus.ReturnHomePaused
|
|
373
|
+
elif self.current_state == States.Paused:
|
|
374
|
+
return RobotStatus.Paused
|
|
371
375
|
elif self.current_state == States.Home:
|
|
372
376
|
return RobotStatus.Home
|
|
373
377
|
elif self.current_state == States.ReturningHome:
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
from typing import TYPE_CHECKING, List
|
|
1
|
+
from typing import TYPE_CHECKING, Callable, List, Optional
|
|
2
2
|
|
|
3
3
|
from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
|
|
4
|
+
from isar.models.events import Event
|
|
4
5
|
from isar.state_machine.utils.common_event_handlers import (
|
|
5
6
|
return_home_event_handler,
|
|
6
|
-
robot_status_event_handler,
|
|
7
7
|
start_mission_event_handler,
|
|
8
8
|
stop_mission_event_handler,
|
|
9
9
|
)
|
|
@@ -19,6 +19,17 @@ class Home(EventHandlerBase):
|
|
|
19
19
|
events = state_machine.events
|
|
20
20
|
shared_state = state_machine.shared_state
|
|
21
21
|
|
|
22
|
+
def _robot_status_event_handler(
|
|
23
|
+
event: Event[RobotStatus],
|
|
24
|
+
) -> Optional[Callable]:
|
|
25
|
+
robot_status: RobotStatus = event.check()
|
|
26
|
+
if not (
|
|
27
|
+
robot_status == RobotStatus.Available
|
|
28
|
+
or robot_status == RobotStatus.Home
|
|
29
|
+
):
|
|
30
|
+
return state_machine.robot_status_changed # type: ignore
|
|
31
|
+
return None
|
|
32
|
+
|
|
22
33
|
event_handlers: List[EventHandlerMapping] = [
|
|
23
34
|
EventHandlerMapping(
|
|
24
35
|
name="start_mission_event",
|
|
@@ -40,9 +51,7 @@ class Home(EventHandlerBase):
|
|
|
40
51
|
EventHandlerMapping(
|
|
41
52
|
name="robot_status_event",
|
|
42
53
|
event=shared_state.robot_status,
|
|
43
|
-
handler=
|
|
44
|
-
state_machine, RobotStatus.Home, event
|
|
45
|
-
),
|
|
54
|
+
handler=_robot_status_event_handler,
|
|
46
55
|
),
|
|
47
56
|
]
|
|
48
57
|
super().__init__(
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
from typing import TYPE_CHECKING, List
|
|
1
|
+
from typing import TYPE_CHECKING, Callable, List, Optional
|
|
2
2
|
|
|
3
|
+
from isar.config.settings import settings
|
|
3
4
|
from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
|
|
5
|
+
from isar.models.events import Event
|
|
4
6
|
|
|
5
7
|
if TYPE_CHECKING:
|
|
6
8
|
from isar.state_machine.state_machine import StateMachine
|
|
@@ -10,6 +12,22 @@ class Paused(EventHandlerBase):
|
|
|
10
12
|
|
|
11
13
|
def __init__(self, state_machine: "StateMachine"):
|
|
12
14
|
events = state_machine.events
|
|
15
|
+
shared_state = state_machine.shared_state
|
|
16
|
+
|
|
17
|
+
def _robot_battery_level_updated_handler(
|
|
18
|
+
event: Event[float],
|
|
19
|
+
) -> Optional[Callable]:
|
|
20
|
+
battery_level: float = event.check()
|
|
21
|
+
if battery_level < settings.ROBOT_MISSION_BATTERY_START_THRESHOLD:
|
|
22
|
+
state_machine.publish_mission_aborted(
|
|
23
|
+
"Robot battery too low to continue mission", True
|
|
24
|
+
)
|
|
25
|
+
state_machine._finalize()
|
|
26
|
+
state_machine.logger.warning(
|
|
27
|
+
"Cancelling current mission due to low battery"
|
|
28
|
+
)
|
|
29
|
+
return state_machine.stop # type: ignore
|
|
30
|
+
return None
|
|
13
31
|
|
|
14
32
|
event_handlers: List[EventHandlerMapping] = [
|
|
15
33
|
EventHandlerMapping(
|
|
@@ -22,6 +40,11 @@ class Paused(EventHandlerBase):
|
|
|
22
40
|
event=events.api_requests.resume_mission.request,
|
|
23
41
|
handler=lambda event: state_machine.resume if event.consume_event() else None, # type: ignore
|
|
24
42
|
),
|
|
43
|
+
EventHandlerMapping(
|
|
44
|
+
name="robot_battery_update_event",
|
|
45
|
+
event=shared_state.robot_battery_level,
|
|
46
|
+
handler=_robot_battery_level_updated_handler,
|
|
47
|
+
),
|
|
25
48
|
]
|
|
26
49
|
super().__init__(
|
|
27
50
|
state_name="paused",
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, Callable, List, Optional
|
|
2
|
+
|
|
3
|
+
from isar.apis.models.models import MissionStartResponse
|
|
4
|
+
from isar.config.settings import settings
|
|
5
|
+
from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
|
|
6
|
+
from isar.models.events import Event
|
|
7
|
+
from robot_interface.models.mission.mission import Mission
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from isar.state_machine.state_machine import StateMachine
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ReturnHomePaused(EventHandlerBase):
|
|
14
|
+
|
|
15
|
+
def __init__(self, state_machine: "StateMachine"):
|
|
16
|
+
events = state_machine.events
|
|
17
|
+
shared_state = state_machine.shared_state
|
|
18
|
+
|
|
19
|
+
def _robot_battery_level_updated_handler(
|
|
20
|
+
event: Event[float],
|
|
21
|
+
) -> Optional[Callable]:
|
|
22
|
+
battery_level: float = event.check()
|
|
23
|
+
if battery_level < settings.ROBOT_MISSION_BATTERY_START_THRESHOLD:
|
|
24
|
+
return state_machine.resume # type: ignore
|
|
25
|
+
return None
|
|
26
|
+
|
|
27
|
+
def _start_mission_event_handler(
|
|
28
|
+
event: Event[Mission],
|
|
29
|
+
) -> Optional[Callable]:
|
|
30
|
+
if event.has_event():
|
|
31
|
+
if not state_machine.battery_level_is_above_mission_start_threshold():
|
|
32
|
+
state_machine.events.api_requests.start_mission.request.consume_event()
|
|
33
|
+
response = MissionStartResponse(
|
|
34
|
+
mission_id=None,
|
|
35
|
+
mission_started=False,
|
|
36
|
+
mission_not_started_reason="Robot battery too low",
|
|
37
|
+
)
|
|
38
|
+
state_machine.events.api_requests.start_mission.response.trigger_event(
|
|
39
|
+
response
|
|
40
|
+
)
|
|
41
|
+
return None
|
|
42
|
+
return state_machine.stop_return_home # type: ignore
|
|
43
|
+
return None
|
|
44
|
+
|
|
45
|
+
event_handlers: List[EventHandlerMapping] = [
|
|
46
|
+
EventHandlerMapping(
|
|
47
|
+
name="resume_return_home_event",
|
|
48
|
+
event=events.api_requests.resume_mission.request,
|
|
49
|
+
handler=lambda event: state_machine.resume if event.consume_event() else None, # type: ignore
|
|
50
|
+
),
|
|
51
|
+
EventHandlerMapping(
|
|
52
|
+
name="robot_battery_update_event",
|
|
53
|
+
event=shared_state.robot_battery_level,
|
|
54
|
+
handler=_robot_battery_level_updated_handler,
|
|
55
|
+
),
|
|
56
|
+
EventHandlerMapping(
|
|
57
|
+
name="start_mission_event",
|
|
58
|
+
event=events.api_requests.start_mission.request,
|
|
59
|
+
handler=_start_mission_event_handler,
|
|
60
|
+
),
|
|
61
|
+
]
|
|
62
|
+
super().__init__(
|
|
63
|
+
state_name="return_home_paused",
|
|
64
|
+
state_machine=state_machine,
|
|
65
|
+
event_handler_mappings=event_handlers,
|
|
66
|
+
)
|
|
@@ -6,7 +6,6 @@ from isar.models.events import Event
|
|
|
6
6
|
from isar.state_machine.utils.common_event_handlers import (
|
|
7
7
|
mission_failed_event_handler,
|
|
8
8
|
mission_started_event_handler,
|
|
9
|
-
stop_mission_event_handler,
|
|
10
9
|
task_status_event_handler,
|
|
11
10
|
task_status_failed_event_handler,
|
|
12
11
|
)
|
|
@@ -24,6 +23,11 @@ class ReturningHome(EventHandlerBase):
|
|
|
24
23
|
self.failed_return_home_attemps: int = 0
|
|
25
24
|
events = state_machine.events
|
|
26
25
|
|
|
26
|
+
def _pause_mission_event_handler(event: Event[bool]) -> Optional[Callable]:
|
|
27
|
+
if event.consume_event():
|
|
28
|
+
return state_machine.pause # type: ignore
|
|
29
|
+
return None
|
|
30
|
+
|
|
27
31
|
def _handle_task_completed(status: TaskStatus):
|
|
28
32
|
if status != TaskStatus.Successful:
|
|
29
33
|
state_machine.current_mission.error_message = ErrorMessage(
|
|
@@ -43,6 +47,7 @@ class ReturningHome(EventHandlerBase):
|
|
|
43
47
|
) -> Optional[Callable]:
|
|
44
48
|
if event.has_event():
|
|
45
49
|
if not state_machine.battery_level_is_above_mission_start_threshold():
|
|
50
|
+
state_machine.events.api_requests.start_mission.request.consume_event()
|
|
46
51
|
response = MissionStartResponse(
|
|
47
52
|
mission_id=None,
|
|
48
53
|
mission_started=False,
|
|
@@ -52,14 +57,14 @@ class ReturningHome(EventHandlerBase):
|
|
|
52
57
|
response
|
|
53
58
|
)
|
|
54
59
|
return None
|
|
55
|
-
return state_machine.
|
|
60
|
+
return state_machine.stop_return_home # type: ignore
|
|
56
61
|
return None
|
|
57
62
|
|
|
58
63
|
event_handlers: List[EventHandlerMapping] = [
|
|
59
64
|
EventHandlerMapping(
|
|
60
|
-
name="
|
|
61
|
-
event=events.api_requests.
|
|
62
|
-
handler=
|
|
65
|
+
name="pause_mission_event",
|
|
66
|
+
event=events.api_requests.pause_mission.request,
|
|
67
|
+
handler=_pause_mission_event_handler,
|
|
63
68
|
),
|
|
64
69
|
EventHandlerMapping(
|
|
65
70
|
name="mission_started_event",
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import logging
|
|
2
1
|
from typing import TYPE_CHECKING, Callable, List, Optional
|
|
3
2
|
|
|
4
3
|
from isar.apis.models.models import ControlMissionResponse
|
|
@@ -14,7 +13,6 @@ if TYPE_CHECKING:
|
|
|
14
13
|
class Stopping(EventHandlerBase):
|
|
15
14
|
|
|
16
15
|
def __init__(self, state_machine: "StateMachine"):
|
|
17
|
-
logger = logging.getLogger("state_machine")
|
|
18
16
|
events = state_machine.events
|
|
19
17
|
|
|
20
18
|
def _stop_mission_cleanup() -> None:
|
|
@@ -48,30 +46,15 @@ class Stopping(EventHandlerBase):
|
|
|
48
46
|
) -> Optional[Callable]:
|
|
49
47
|
error_message: Optional[ErrorMessage] = event.consume_event()
|
|
50
48
|
if error_message is not None:
|
|
51
|
-
|
|
52
|
-
if (
|
|
53
|
-
state_machine.current_mission is not None
|
|
54
|
-
and state_machine.current_mission._is_return_to_home_mission()
|
|
55
|
-
):
|
|
56
|
-
return state_machine.return_home_mission_stopping_failed # type: ignore
|
|
57
|
-
else:
|
|
58
|
-
return state_machine.mission_stopping_failed # type: ignore
|
|
49
|
+
return state_machine.mission_stopping_failed # type: ignore
|
|
59
50
|
return None
|
|
60
51
|
|
|
61
52
|
def _successful_stop_event_handler(event: Event[bool]) -> Optional[Callable]:
|
|
62
53
|
if event.consume_event():
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return state_machine.return_home_mission_stopped # type: ignore
|
|
68
|
-
else:
|
|
69
|
-
_stop_mission_cleanup()
|
|
70
|
-
if (
|
|
71
|
-
not state_machine.battery_level_is_above_mission_start_threshold()
|
|
72
|
-
):
|
|
73
|
-
return state_machine.request_return_home # type: ignore
|
|
74
|
-
return state_machine.mission_stopped # type: ignore
|
|
54
|
+
_stop_mission_cleanup()
|
|
55
|
+
if not state_machine.battery_level_is_above_mission_start_threshold():
|
|
56
|
+
return state_machine.request_return_home # type: ignore
|
|
57
|
+
return state_machine.mission_stopped # type: ignore
|
|
75
58
|
return None
|
|
76
59
|
|
|
77
60
|
event_handlers: List[EventHandlerMapping] = [
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import TYPE_CHECKING, Callable, List, Optional
|
|
3
|
+
|
|
4
|
+
from isar.apis.models.models import MissionStartResponse
|
|
5
|
+
from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
|
|
6
|
+
from isar.models.events import Event
|
|
7
|
+
from robot_interface.models.exceptions.robot_exceptions import ErrorMessage
|
|
8
|
+
from robot_interface.models.mission.mission import Mission
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from isar.state_machine.state_machine import StateMachine
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class StoppingReturnHome(EventHandlerBase):
|
|
15
|
+
|
|
16
|
+
def __init__(self, state_machine: "StateMachine"):
|
|
17
|
+
logger = logging.getLogger("state_machine")
|
|
18
|
+
events = state_machine.events
|
|
19
|
+
|
|
20
|
+
def _failed_stop_event_handler(
|
|
21
|
+
event: Event[ErrorMessage],
|
|
22
|
+
) -> Optional[Callable]:
|
|
23
|
+
error_message: Optional[ErrorMessage] = event.consume_event()
|
|
24
|
+
if error_message is not None:
|
|
25
|
+
logger.warning(error_message.error_description)
|
|
26
|
+
mission: Mission = (
|
|
27
|
+
state_machine.events.api_requests.start_mission.request.consume_event()
|
|
28
|
+
)
|
|
29
|
+
state_machine.events.api_requests.start_mission.response.trigger_event(
|
|
30
|
+
MissionStartResponse(
|
|
31
|
+
mission_id=mission.id,
|
|
32
|
+
mission_started=False,
|
|
33
|
+
mission_not_started_reason="Failed to cancel return home mission",
|
|
34
|
+
)
|
|
35
|
+
)
|
|
36
|
+
return state_machine.return_home_mission_stopping_failed # type: ignore
|
|
37
|
+
return None
|
|
38
|
+
|
|
39
|
+
def _successful_stop_event_handler(event: Event[bool]) -> Optional[Callable]:
|
|
40
|
+
if event.consume_event():
|
|
41
|
+
mission: Mission = (
|
|
42
|
+
state_machine.events.api_requests.start_mission.request.consume_event()
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
state_machine.reset_state_machine()
|
|
46
|
+
|
|
47
|
+
if mission:
|
|
48
|
+
state_machine.start_mission(mission=mission)
|
|
49
|
+
return state_machine.request_mission_start # type: ignore
|
|
50
|
+
|
|
51
|
+
state_machine.logger.error(
|
|
52
|
+
"Stopped return home without a new mission to start"
|
|
53
|
+
)
|
|
54
|
+
return state_machine.request_return_home # type: ignore
|
|
55
|
+
return None
|
|
56
|
+
|
|
57
|
+
event_handlers: List[EventHandlerMapping] = [
|
|
58
|
+
EventHandlerMapping(
|
|
59
|
+
name="failed_stop_event",
|
|
60
|
+
event=events.robot_service_events.mission_failed_to_stop,
|
|
61
|
+
handler=_failed_stop_event_handler,
|
|
62
|
+
),
|
|
63
|
+
EventHandlerMapping(
|
|
64
|
+
name="successful_stop_event",
|
|
65
|
+
event=events.robot_service_events.mission_successfully_stopped,
|
|
66
|
+
handler=_successful_stop_event_handler,
|
|
67
|
+
),
|
|
68
|
+
]
|
|
69
|
+
super().__init__(
|
|
70
|
+
state_name="stopping_return_home",
|
|
71
|
+
state_machine=state_machine,
|
|
72
|
+
event_handler_mappings=event_handlers,
|
|
73
|
+
)
|
|
@@ -5,10 +5,11 @@ class States(str, Enum):
|
|
|
5
5
|
Monitor = "monitor"
|
|
6
6
|
ReturningHome = "returning_home"
|
|
7
7
|
Stopping = "stopping"
|
|
8
|
+
StoppingReturnHome = "stopping_return_home"
|
|
8
9
|
Paused = "paused"
|
|
10
|
+
ReturnHomePaused = "return_home_paused"
|
|
9
11
|
AwaitNextMission = "await_next_mission"
|
|
10
12
|
Home = "home"
|
|
11
|
-
RobotStandingStill = "robot_standing_still"
|
|
12
13
|
Offline = "offline"
|
|
13
14
|
BlockedProtectiveStop = "blocked_protective_stop"
|
|
14
15
|
UnknownStatus = "unknown_status"
|
|
@@ -51,3 +51,41 @@ def pause_mission(state_machine: "StateMachine") -> bool:
|
|
|
51
51
|
|
|
52
52
|
state_machine.logger.error("Failed to pause mission after multiple attempts.")
|
|
53
53
|
return False
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def pause_return_home_mission(state_machine: "StateMachine") -> bool:
|
|
57
|
+
state_machine.logger.info("Pausing return home misson")
|
|
58
|
+
|
|
59
|
+
max_retries = settings.STATE_TRANSITION_NUM_RETIRES
|
|
60
|
+
retry_interval = settings.STATE_TRANSITION_RETRY_INTERVAL_SEC
|
|
61
|
+
|
|
62
|
+
for attempt in range(max_retries):
|
|
63
|
+
try:
|
|
64
|
+
state_machine.robot.pause()
|
|
65
|
+
state_machine.current_mission.status = MissionStatus.Paused
|
|
66
|
+
state_machine.current_task.status = TaskStatus.Paused
|
|
67
|
+
|
|
68
|
+
paused_mission_response: ControlMissionResponse = (
|
|
69
|
+
state_machine._make_control_mission_response()
|
|
70
|
+
)
|
|
71
|
+
state_machine.events.api_requests.pause_mission.response.trigger_event(
|
|
72
|
+
paused_mission_response
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
state_machine.logger.info("Return home mission paused successfully.")
|
|
76
|
+
return True
|
|
77
|
+
except RobotActionException as e:
|
|
78
|
+
state_machine.logger.warning(
|
|
79
|
+
f"Attempt {attempt + 1} to pause return home mission failed: {e.error_description}"
|
|
80
|
+
)
|
|
81
|
+
time.sleep(retry_interval)
|
|
82
|
+
except RobotException as e:
|
|
83
|
+
state_machine.logger.warning(
|
|
84
|
+
f"Attempt {attempt + 1} to pause return home mission raised a RobotException: {e.error_description}"
|
|
85
|
+
)
|
|
86
|
+
time.sleep(retry_interval)
|
|
87
|
+
|
|
88
|
+
state_machine.logger.error(
|
|
89
|
+
"Failed to pause return home mission after multiple attempts."
|
|
90
|
+
)
|
|
91
|
+
return False
|
|
@@ -11,14 +11,9 @@ def is_offline(state_machine: "StateMachine") -> bool:
|
|
|
11
11
|
return robot_status == RobotStatus.Offline
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
def
|
|
14
|
+
def is_available_or_home(state_machine: "StateMachine") -> bool:
|
|
15
15
|
robot_status = state_machine.shared_state.robot_status.check()
|
|
16
|
-
return robot_status == RobotStatus.Available
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def is_home(state_machine: "StateMachine") -> bool:
|
|
20
|
-
robot_status = state_machine.shared_state.robot_status.check()
|
|
21
|
-
return robot_status == RobotStatus.Home
|
|
16
|
+
return robot_status == RobotStatus.Available or robot_status == RobotStatus.Home
|
|
22
17
|
|
|
23
18
|
|
|
24
19
|
def is_blocked_protective_stop(state_machine: "StateMachine") -> bool:
|
|
@@ -4,8 +4,15 @@ from isar.state_machine.transitions.functions.fail_mission import (
|
|
|
4
4
|
report_failed_mission_and_finalize,
|
|
5
5
|
)
|
|
6
6
|
from isar.state_machine.transitions.functions.finish_mission import finish_mission
|
|
7
|
-
from isar.state_machine.transitions.functions.pause import
|
|
7
|
+
from isar.state_machine.transitions.functions.pause import (
|
|
8
|
+
pause_mission,
|
|
9
|
+
pause_return_home_mission,
|
|
10
|
+
)
|
|
8
11
|
from isar.state_machine.transitions.functions.resume import resume_mission
|
|
12
|
+
from isar.state_machine.transitions.functions.return_home import (
|
|
13
|
+
reset_return_home_failure_counter,
|
|
14
|
+
return_home_finished,
|
|
15
|
+
)
|
|
9
16
|
from isar.state_machine.transitions.functions.start_mission import (
|
|
10
17
|
acknowledge_mission,
|
|
11
18
|
initialize_robot,
|
|
@@ -15,7 +22,6 @@ from isar.state_machine.transitions.functions.start_mission import (
|
|
|
15
22
|
)
|
|
16
23
|
from isar.state_machine.transitions.functions.stop import (
|
|
17
24
|
stop_mission_failed,
|
|
18
|
-
stop_return_home_mission_cleanup,
|
|
19
25
|
stop_return_home_mission_failed,
|
|
20
26
|
trigger_stop_mission_event,
|
|
21
27
|
)
|
|
@@ -38,6 +44,17 @@ def get_mission_transitions(state_machine: "StateMachine") -> List[dict]:
|
|
|
38
44
|
"source": state_machine.monitor_state,
|
|
39
45
|
"dest": state_machine.monitor_state,
|
|
40
46
|
},
|
|
47
|
+
{
|
|
48
|
+
"trigger": "pause",
|
|
49
|
+
"source": state_machine.returning_home_state,
|
|
50
|
+
"dest": state_machine.return_home_paused_state,
|
|
51
|
+
"conditions": def_transition(state_machine, pause_return_home_mission),
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"trigger": "pause",
|
|
55
|
+
"source": state_machine.returning_home_state,
|
|
56
|
+
"dest": state_machine.returning_home_state,
|
|
57
|
+
},
|
|
41
58
|
{
|
|
42
59
|
"trigger": "resume",
|
|
43
60
|
"source": state_machine.paused_state,
|
|
@@ -49,18 +66,40 @@ def get_mission_transitions(state_machine: "StateMachine") -> List[dict]:
|
|
|
49
66
|
"source": state_machine.paused_state,
|
|
50
67
|
"dest": state_machine.paused_state,
|
|
51
68
|
},
|
|
69
|
+
{
|
|
70
|
+
"trigger": "resume",
|
|
71
|
+
"source": state_machine.return_home_paused_state,
|
|
72
|
+
"dest": state_machine.returning_home_state,
|
|
73
|
+
"conditions": def_transition(state_machine, resume_mission),
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"trigger": "resume",
|
|
77
|
+
"source": state_machine.return_home_paused_state,
|
|
78
|
+
"dest": state_machine.return_home_paused_state,
|
|
79
|
+
},
|
|
52
80
|
{
|
|
53
81
|
"trigger": "stop",
|
|
54
82
|
"source": [
|
|
55
83
|
state_machine.await_next_mission_state,
|
|
56
|
-
state_machine.robot_standing_still_state,
|
|
57
84
|
state_machine.monitor_state,
|
|
58
|
-
state_machine.returning_home_state,
|
|
59
85
|
state_machine.paused_state,
|
|
60
86
|
],
|
|
61
87
|
"dest": state_machine.stopping_state,
|
|
62
88
|
"before": def_transition(state_machine, trigger_stop_mission_event),
|
|
63
89
|
},
|
|
90
|
+
{
|
|
91
|
+
"trigger": "stop_return_home",
|
|
92
|
+
"source": [
|
|
93
|
+
state_machine.returning_home_state,
|
|
94
|
+
state_machine.return_home_paused_state,
|
|
95
|
+
],
|
|
96
|
+
"dest": state_machine.stopping_return_home_state,
|
|
97
|
+
"before": [
|
|
98
|
+
def_transition(state_machine, trigger_stop_mission_event),
|
|
99
|
+
def_transition(state_machine, reset_return_home_failure_counter),
|
|
100
|
+
def_transition(state_machine, return_home_finished),
|
|
101
|
+
],
|
|
102
|
+
},
|
|
64
103
|
{
|
|
65
104
|
"trigger": "mission_stopped",
|
|
66
105
|
"source": state_machine.stopping_state,
|
|
@@ -74,22 +113,16 @@ def get_mission_transitions(state_machine: "StateMachine") -> List[dict]:
|
|
|
74
113
|
},
|
|
75
114
|
{
|
|
76
115
|
"trigger": "return_home_mission_stopping_failed",
|
|
77
|
-
"source": state_machine.
|
|
116
|
+
"source": state_machine.stopping_return_home_state,
|
|
78
117
|
"dest": state_machine.returning_home_state,
|
|
79
118
|
"before": def_transition(state_machine, stop_return_home_mission_failed),
|
|
80
119
|
},
|
|
81
|
-
{
|
|
82
|
-
"trigger": "return_home_mission_stopped",
|
|
83
|
-
"source": state_machine.stopping_state,
|
|
84
|
-
"dest": state_machine.robot_standing_still_state,
|
|
85
|
-
"before": def_transition(state_machine, stop_return_home_mission_cleanup),
|
|
86
|
-
},
|
|
87
120
|
{
|
|
88
121
|
"trigger": "request_mission_start",
|
|
89
122
|
"source": [
|
|
90
123
|
state_machine.await_next_mission_state,
|
|
91
124
|
state_machine.home_state,
|
|
92
|
-
state_machine.
|
|
125
|
+
state_machine.stopping_return_home_state,
|
|
93
126
|
],
|
|
94
127
|
"dest": state_machine.monitor_state,
|
|
95
128
|
"prepare": def_transition(state_machine, acknowledge_mission),
|
|
@@ -108,12 +141,6 @@ def get_mission_transitions(state_machine: "StateMachine") -> List[dict]:
|
|
|
108
141
|
"dest": state_machine.await_next_mission_state,
|
|
109
142
|
"before": def_transition(state_machine, report_failed_mission_and_finalize),
|
|
110
143
|
},
|
|
111
|
-
{
|
|
112
|
-
"trigger": "request_mission_start",
|
|
113
|
-
"source": state_machine.robot_standing_still_state,
|
|
114
|
-
"dest": state_machine.robot_standing_still_state,
|
|
115
|
-
"before": def_transition(state_machine, report_failed_mission_and_finalize),
|
|
116
|
-
},
|
|
117
144
|
{
|
|
118
145
|
"trigger": "request_mission_start",
|
|
119
146
|
"source": state_machine.home_state,
|
|
@@ -123,7 +150,7 @@ def get_mission_transitions(state_machine: "StateMachine") -> List[dict]:
|
|
|
123
150
|
{
|
|
124
151
|
"trigger": "mission_failed_to_start",
|
|
125
152
|
"source": [state_machine.monitor_state, state_machine.returning_home_state],
|
|
126
|
-
"dest": state_machine.
|
|
153
|
+
"dest": state_machine.await_next_mission_state,
|
|
127
154
|
"before": def_transition(state_machine, report_failed_mission_and_finalize),
|
|
128
155
|
},
|
|
129
156
|
{
|
|
@@ -28,10 +28,10 @@ def get_return_home_transitions(state_machine: "StateMachine") -> List[dict]:
|
|
|
28
28
|
"source": [
|
|
29
29
|
state_machine.await_next_mission_state,
|
|
30
30
|
state_machine.home_state,
|
|
31
|
-
state_machine.robot_standing_still_state,
|
|
32
31
|
state_machine.intervention_needed_state,
|
|
33
32
|
state_machine.monitor_state,
|
|
34
33
|
state_machine.stopping_state,
|
|
34
|
+
state_machine.stopping_return_home_state,
|
|
35
35
|
],
|
|
36
36
|
"dest": state_machine.returning_home_state,
|
|
37
37
|
"conditions": [
|
|
@@ -53,12 +53,6 @@ def get_return_home_transitions(state_machine: "StateMachine") -> List[dict]:
|
|
|
53
53
|
"dest": state_machine.home_state,
|
|
54
54
|
"before": def_transition(state_machine, report_failed_mission_and_finalize),
|
|
55
55
|
},
|
|
56
|
-
{
|
|
57
|
-
"trigger": "request_return_home",
|
|
58
|
-
"source": state_machine.robot_standing_still_state,
|
|
59
|
-
"dest": state_machine.robot_standing_still_state,
|
|
60
|
-
"before": def_transition(state_machine, report_failed_mission_and_finalize),
|
|
61
|
-
},
|
|
62
56
|
{
|
|
63
57
|
"trigger": "returned_home",
|
|
64
58
|
"source": state_machine.returning_home_state,
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
from typing import TYPE_CHECKING, List
|
|
2
2
|
|
|
3
3
|
from isar.state_machine.transitions.functions.robot_status import (
|
|
4
|
-
|
|
4
|
+
is_available_or_home,
|
|
5
5
|
is_blocked_protective_stop,
|
|
6
|
-
is_home,
|
|
7
6
|
is_offline,
|
|
8
7
|
)
|
|
9
8
|
from isar.state_machine.transitions.functions.utils import def_transition
|
|
@@ -22,24 +21,12 @@ def get_robot_status_transitions(state_machine: "StateMachine") -> List[dict]:
|
|
|
22
21
|
state_machine.offline_state,
|
|
23
22
|
state_machine.unknown_status_state,
|
|
24
23
|
],
|
|
25
|
-
"dest": state_machine.robot_standing_still_state,
|
|
26
|
-
"conditions": def_transition(state_machine, is_available),
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
"trigger": "robot_status_changed",
|
|
30
|
-
"source": [
|
|
31
|
-
state_machine.robot_standing_still_state,
|
|
32
|
-
state_machine.blocked_protective_stopping_state,
|
|
33
|
-
state_machine.offline_state,
|
|
34
|
-
state_machine.unknown_status_state,
|
|
35
|
-
],
|
|
36
24
|
"dest": state_machine.home_state,
|
|
37
|
-
"conditions": def_transition(state_machine,
|
|
25
|
+
"conditions": def_transition(state_machine, is_available_or_home),
|
|
38
26
|
},
|
|
39
27
|
{
|
|
40
28
|
"trigger": "robot_status_changed",
|
|
41
29
|
"source": [
|
|
42
|
-
state_machine.robot_standing_still_state,
|
|
43
30
|
state_machine.home_state,
|
|
44
31
|
state_machine.offline_state,
|
|
45
32
|
state_machine.unknown_status_state,
|
|
@@ -50,7 +37,6 @@ def get_robot_status_transitions(state_machine: "StateMachine") -> List[dict]:
|
|
|
50
37
|
{
|
|
51
38
|
"trigger": "robot_status_changed",
|
|
52
39
|
"source": [
|
|
53
|
-
state_machine.robot_standing_still_state,
|
|
54
40
|
state_machine.home_state,
|
|
55
41
|
state_machine.blocked_protective_stopping_state,
|
|
56
42
|
state_machine.unknown_status_state,
|
|
@@ -61,7 +47,6 @@ def get_robot_status_transitions(state_machine: "StateMachine") -> List[dict]:
|
|
|
61
47
|
{
|
|
62
48
|
"trigger": "robot_status_changed",
|
|
63
49
|
"source": [
|
|
64
|
-
state_machine.robot_standing_still_state,
|
|
65
50
|
state_machine.home_state,
|
|
66
51
|
state_machine.blocked_protective_stopping_state,
|
|
67
52
|
state_machine.offline_state,
|
isar/storage/uploader.py
CHANGED
|
@@ -29,6 +29,14 @@ from robot_interface.telemetry.payloads import (
|
|
|
29
29
|
from robot_interface.utilities.json_service import EnhancedJSONEncoder
|
|
30
30
|
|
|
31
31
|
|
|
32
|
+
def has_empty_blob_storage_path(storage_paths: StoragePaths):
|
|
33
|
+
for path in (storage_paths.data_path, storage_paths.metadata_path):
|
|
34
|
+
for value in (path.storage_account, path.blob_container, path.blob_name):
|
|
35
|
+
if not (value and value.strip()):
|
|
36
|
+
return True
|
|
37
|
+
return False
|
|
38
|
+
|
|
39
|
+
|
|
32
40
|
@dataclass
|
|
33
41
|
class UploaderQueueItem:
|
|
34
42
|
inspection: Inspection
|
|
@@ -192,6 +200,13 @@ class Uploader:
|
|
|
192
200
|
inspection_paths = self._upload(item)
|
|
193
201
|
if isinstance(inspection_paths.data_path, LocalStoragePath):
|
|
194
202
|
self.logger.info("Skipping publishing when using local storage")
|
|
203
|
+
elif isinstance(
|
|
204
|
+
inspection_paths.data_path, BlobStoragePath
|
|
205
|
+
) and has_empty_blob_storage_path(inspection_paths):
|
|
206
|
+
self.logger.warning(
|
|
207
|
+
"Skipping publishing: Blob storage paths are empty for inspection %s",
|
|
208
|
+
str(item.inspection.id)[:8],
|
|
209
|
+
)
|
|
195
210
|
else:
|
|
196
211
|
self._publish_inspection_result(
|
|
197
212
|
inspection=item.inspection,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: isar
|
|
3
|
-
Version: 1.33.
|
|
3
|
+
Version: 1.33.4
|
|
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
|
|
@@ -369,7 +369,7 @@ States.Paused,
|
|
|
369
369
|
indicates that the state machine is already running. For running a mission the state machine need to be in the states
|
|
370
370
|
|
|
371
371
|
```
|
|
372
|
-
States.Home, States.
|
|
372
|
+
States.Home, States.AwaitNextMission or States.ReturningHome
|
|
373
373
|
```
|
|
374
374
|
|
|
375
375
|
### FastAPI
|
|
@@ -8,7 +8,7 @@ isar/apis/models/models.py,sha256=iRyqflpjGopm4KJjgRrOnC2swNEk3a-iwVynzw3Nm6c,19
|
|
|
8
8
|
isar/apis/models/start_mission_definition.py,sha256=v-wt1XDd53Sw7DCdFAkxBBut-xd_uGJa7qMJnE3VI9k,6364
|
|
9
9
|
isar/apis/robot_control/robot_controller.py,sha256=0EHjMqOBdfJlMrCItGPz5X-4X2kc-2XlNnUU2LOcLfc,1219
|
|
10
10
|
isar/apis/schedule/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
-
isar/apis/schedule/scheduling_controller.py,sha256=
|
|
11
|
+
isar/apis/schedule/scheduling_controller.py,sha256=RKtQmNtcepG0mgu5ihidc2J7ZJ9c1plIgUQCEBz_3SE,9476
|
|
12
12
|
isar/apis/security/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
13
|
isar/apis/security/authentication.py,sha256=Se2puhe2TUBmfio2RLma52-VSLRhqvWgu0Cd1bhdwMo,2000
|
|
14
14
|
isar/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -54,38 +54,39 @@ isar/services/auth/azure_credentials.py,sha256=9PlwGe5FrPRbW2dp0go7LMp8_l_FRvL8x
|
|
|
54
54
|
isar/services/service_connections/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
55
55
|
isar/services/service_connections/request_handler.py,sha256=0LxC0lu_HXeEf_xmJWjfEsh14oAUI97cpG1IWtBlcs4,4278
|
|
56
56
|
isar/services/service_connections/mqtt/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
57
|
-
isar/services/service_connections/mqtt/mqtt_client.py,sha256=
|
|
57
|
+
isar/services/service_connections/mqtt/mqtt_client.py,sha256=8Dr65JNwPx5-kRY8UsRtZ_nrQ2gXXSUH6LWFOYlnluo,4482
|
|
58
58
|
isar/services/service_connections/mqtt/robot_heartbeat_publisher.py,sha256=SKPvY2QwBxqnhL9aGuZQDGQ8F_NDqPtQI5bzRBIUxkQ,1203
|
|
59
59
|
isar/services/service_connections/mqtt/robot_info_publisher.py,sha256=AxokGk51hRPTxxD2r0P9braPJCMrf1InaCxrUBKkF4g,1402
|
|
60
60
|
isar/services/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
61
61
|
isar/services/utilities/robot_utilities.py,sha256=4zCigsLXfqDC8POHchktSq81zr1_pTaRve_LQsVr6Mk,514
|
|
62
|
-
isar/services/utilities/scheduling_utilities.py,sha256=
|
|
62
|
+
isar/services/utilities/scheduling_utilities.py,sha256=6t42uyHXRr8QtRU6qH_EzYKlvwXEAUCwe7U5IDUp4nc,13502
|
|
63
63
|
isar/services/utilities/threaded_request.py,sha256=py4G-_RjnIdHljmKFAcQ6ddqMmp-ZYV39Ece-dqRqjs,1874
|
|
64
64
|
isar/state_machine/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
65
|
-
isar/state_machine/state_machine.py,sha256=
|
|
66
|
-
isar/state_machine/states_enum.py,sha256=
|
|
65
|
+
isar/state_machine/state_machine.py,sha256=W2RMBhSRtu5kH0LAuRHbPhxHxtFa0knWfBv7EMRuQcI,18610
|
|
66
|
+
isar/state_machine/states_enum.py,sha256=hBbP87Aw9JiIBScfAkflWgQHYBrLA17ex0XXO4suRYY,555
|
|
67
67
|
isar/state_machine/states/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
68
68
|
isar/state_machine/states/await_next_mission.py,sha256=yg0aH4eukcnE1xRKiPVafRxqHt3WdvqD08EATzdEojk,1961
|
|
69
69
|
isar/state_machine/states/blocked_protective_stop.py,sha256=GEOvxnHXjpCsrh3aa8Idtn1zMYv5HLQzj9qQAq8HvaU,1180
|
|
70
|
-
isar/state_machine/states/home.py,sha256=
|
|
70
|
+
isar/state_machine/states/home.py,sha256=718NFxbYQTM5VLKbL8e5ELlbXWYis1GfaZfl34EhfQo,2292
|
|
71
71
|
isar/state_machine/states/intervention_needed.py,sha256=A0QYz1vD1tDKAealihXDuoGuMLtXrRfn_AwFoaUhT_Q,1640
|
|
72
72
|
isar/state_machine/states/monitor.py,sha256=GiNGyPcskrv3QDxMfsOmHUe_MRCaNA-pYuk9p6kcKp0,4623
|
|
73
73
|
isar/state_machine/states/offline.py,sha256=5wdNzC1wG0cWrpuT_r_mk8UNFHA4QSyg8ejXUTAg4Io,1137
|
|
74
|
-
isar/state_machine/states/paused.py,sha256=
|
|
74
|
+
isar/state_machine/states/paused.py,sha256=OruA2oPGWsVjnQ8xxVJJsGO3xKzXz2xF5uWsrvH27Ng,2101
|
|
75
75
|
isar/state_machine/states/recharging.py,sha256=ni5WqFU0VDhdGC3ZfHcabSICm_5kwaS72wc3ecAB_os,1651
|
|
76
|
-
isar/state_machine/states/
|
|
77
|
-
isar/state_machine/states/
|
|
78
|
-
isar/state_machine/states/stopping.py,sha256=
|
|
76
|
+
isar/state_machine/states/return_home_paused.py,sha256=nVfNqutEG251NCk18UqIerh0SdAgGsXMXBt5iT2oRK0,2711
|
|
77
|
+
isar/state_machine/states/returning_home.py,sha256=75pfHNCjpV4jfhcmNAoabTwBzed1_-aFJE_KkTUTAnA,4513
|
|
78
|
+
isar/state_machine/states/stopping.py,sha256=h0x94hVoIUJyml3WMrbJlbxG2dzMCeOL1rJoNCQfzGQ,3057
|
|
79
|
+
isar/state_machine/states/stopping_return_home.py,sha256=ub952Ulas3a0lsV_dI4liBiInADo3zaPAGod2bPe_18,2985
|
|
79
80
|
isar/state_machine/states/unknown_status.py,sha256=Y-g9cgme5zriyZ6YUzFRYhOvv9ZylCSwfaY8MJ7xEJ0,1791
|
|
80
|
-
isar/state_machine/transitions/mission.py,sha256=
|
|
81
|
-
isar/state_machine/transitions/return_home.py,sha256=
|
|
82
|
-
isar/state_machine/transitions/robot_status.py,sha256=
|
|
81
|
+
isar/state_machine/transitions/mission.py,sha256=W56bs4jSFwH2K4yAwxzLWh7dDuLi8j-L4mVvmfeKjWw,6313
|
|
82
|
+
isar/state_machine/transitions/return_home.py,sha256=9fXFVozsCZqtKjQwiPLLc3ExrgLj5zU9AD7a9IMe0Pw,4348
|
|
83
|
+
isar/state_machine/transitions/robot_status.py,sha256=qJMurCpuficOiXs9us4lZJ5p_kOFSwKxJigiXfB1OS8,2430
|
|
83
84
|
isar/state_machine/transitions/functions/fail_mission.py,sha256=jHHXhfQVYQEzCXgTEhv5e6uEK9p6iDPFFXqS9bzs_-A,720
|
|
84
85
|
isar/state_machine/transitions/functions/finish_mission.py,sha256=TRQrk7HdllmAkwsp25HRZAFAk46Y1hLx3jmkIAKrHDI,1442
|
|
85
|
-
isar/state_machine/transitions/functions/pause.py,sha256=
|
|
86
|
+
isar/state_machine/transitions/functions/pause.py,sha256=R4Bbb-XcmcCwGiY3-lsYiK-WAz2KfVj4kM_pzE8OFyg,3472
|
|
86
87
|
isar/state_machine/transitions/functions/resume.py,sha256=SAu4hWomPlrvO0lnpc6uM3rj79Bwq01acnaTEvNbO9U,2116
|
|
87
88
|
isar/state_machine/transitions/functions/return_home.py,sha256=5WPO40MtuRKm9-NtyrS6m0IVEit14MXfMKjgZ2sCXRU,1666
|
|
88
|
-
isar/state_machine/transitions/functions/robot_status.py,sha256=
|
|
89
|
+
isar/state_machine/transitions/functions/robot_status.py,sha256=2P3EfP2c06GY-LUquyBTyHn1Ard31Hl3UeT-e-VaIWE,768
|
|
89
90
|
isar/state_machine/transitions/functions/start_mission.py,sha256=tIpZzYXCoeC6ZWj18UB4DiZuICpxfzFUK23wfunad7Q,2864
|
|
90
91
|
isar/state_machine/transitions/functions/stop.py,sha256=4idsNh7v6CRJivD36oKnVmdKlP7mSugTLCh9n12R1-U,2114
|
|
91
92
|
isar/state_machine/transitions/functions/utils.py,sha256=Wa72Ocq4QT1E6qkpEJZQ3h5o33pGvx7Tlkt2JZ2Grbk,314
|
|
@@ -94,9 +95,9 @@ isar/storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
94
95
|
isar/storage/blob_storage.py,sha256=d44z3XpZDUbiKwN8Av2gytTJxnefMXrp5VhiGm4PWxU,3703
|
|
95
96
|
isar/storage/local_storage.py,sha256=Rn-iiiz9DI7PzIhevOMshPIaqzJaqBXeVJMQRhVSl2M,2191
|
|
96
97
|
isar/storage/storage_interface.py,sha256=x-imVeQTdL6dCaTaPTHpXwCR6N4e27WxK_Vpumg0x-Y,1230
|
|
97
|
-
isar/storage/uploader.py,sha256=
|
|
98
|
+
isar/storage/uploader.py,sha256=oaGhHqYrtyvJoFUuD7ZyBgdPNkYaSgQokQZkAjmd4vI,10702
|
|
98
99
|
isar/storage/utilities.py,sha256=oLH0Rp7UtrQQdilfITnmXO1Z0ExdeDhBImYHid55vBA,3449
|
|
99
|
-
isar-1.33.
|
|
100
|
+
isar-1.33.4.dist-info/licenses/LICENSE,sha256=3fc2-ebLwHWwzfQbulGNRdcNob3SBQeCfEVUDYxsuqw,14058
|
|
100
101
|
robot_interface/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
101
102
|
robot_interface/robot_interface.py,sha256=A6t19lcNU_6AfkYKY5DaF0sheym_SZEAawbfaj36Kjk,8997
|
|
102
103
|
robot_interface/test_robot_interface.py,sha256=FV1urn7SbsMyWBIcTKjsBwAG4IsXeZ6pLHE0mA9EGGs,692
|
|
@@ -108,7 +109,7 @@ robot_interface/models/inspection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeR
|
|
|
108
109
|
robot_interface/models/inspection/inspection.py,sha256=cjAvekL8r82s7bgukWeXpYylHvJG_oRSCJNISPVCvZg,2238
|
|
109
110
|
robot_interface/models/mission/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
110
111
|
robot_interface/models/mission/mission.py,sha256=MQ9p5cuclLXexaZu9bkDh5-aN99eunvYC0vP-Z_kUwI,960
|
|
111
|
-
robot_interface/models/mission/status.py,sha256=
|
|
112
|
+
robot_interface/models/mission/status.py,sha256=e5Yr-GSV_CNSOV9MH2TQP4H_WbSG-z8Ty0JKkYFbZKA,856
|
|
112
113
|
robot_interface/models/mission/task.py,sha256=YzaqJ_KIIm-3S2Y2-BG4Pdkc8sjFMzMx5jj8FtXSmFg,4744
|
|
113
114
|
robot_interface/models/robots/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
114
115
|
robot_interface/models/robots/battery_state.py,sha256=ktOtJ8ltdK0k_i7BoqYfhc5dbOzIG6Oo-uWC67fCWio,98
|
|
@@ -120,8 +121,8 @@ robot_interface/telemetry/payloads.py,sha256=RfLlm_te-bV_xcLtbBx27bgE8gkwPAhWBTF
|
|
|
120
121
|
robot_interface/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
121
122
|
robot_interface/utilities/json_service.py,sha256=9N1zijW7K4d3WFR2autpaS8U9o1ibymiOX-6stTKCyk,1243
|
|
122
123
|
robot_interface/utilities/uuid_string_factory.py,sha256=_NQIbBQ56w0qqO0MUDP6aPpHbxW7ATRhK8HnQiBSLkc,76
|
|
123
|
-
isar-1.33.
|
|
124
|
-
isar-1.33.
|
|
125
|
-
isar-1.33.
|
|
126
|
-
isar-1.33.
|
|
127
|
-
isar-1.33.
|
|
124
|
+
isar-1.33.4.dist-info/METADATA,sha256=kFWjErpSnEh4cucIUoioOsgWRnzcxU9BsI65g3hUKqI,31190
|
|
125
|
+
isar-1.33.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
126
|
+
isar-1.33.4.dist-info/entry_points.txt,sha256=TFam7uNNw7J0iiDYzsH2gfG0u1eV1wh3JTw_HkhgKLk,49
|
|
127
|
+
isar-1.33.4.dist-info/top_level.txt,sha256=UwIML2RtuQKCyJJkatcSnyp6-ldDjboB9k9JgKipO-U,21
|
|
128
|
+
isar-1.33.4.dist-info/RECORD,,
|
|
@@ -23,10 +23,11 @@ class TaskStatus(str, Enum):
|
|
|
23
23
|
|
|
24
24
|
class RobotStatus(Enum):
|
|
25
25
|
Available = "available"
|
|
26
|
+
ReturnHomePaused = "returnhomepaused"
|
|
27
|
+
Paused = "paused"
|
|
26
28
|
Busy = "busy"
|
|
27
29
|
Home = "home"
|
|
28
30
|
Offline = "offline"
|
|
29
|
-
Blocked = "blocked"
|
|
30
31
|
BlockedProtectiveStop = "blockedprotectivestop"
|
|
31
32
|
ReturningHome = "returninghome"
|
|
32
33
|
InterventionNeeded = "interventionneeded"
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
from typing import TYPE_CHECKING, List
|
|
2
|
-
|
|
3
|
-
from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
|
|
4
|
-
from isar.state_machine.utils.common_event_handlers import (
|
|
5
|
-
return_home_event_handler,
|
|
6
|
-
robot_status_event_handler,
|
|
7
|
-
start_mission_event_handler,
|
|
8
|
-
stop_mission_event_handler,
|
|
9
|
-
)
|
|
10
|
-
from robot_interface.models.mission.status import RobotStatus
|
|
11
|
-
|
|
12
|
-
if TYPE_CHECKING:
|
|
13
|
-
from isar.state_machine.state_machine import StateMachine
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class RobotStandingStill(EventHandlerBase):
|
|
17
|
-
|
|
18
|
-
def __init__(self, state_machine: "StateMachine"):
|
|
19
|
-
events = state_machine.events
|
|
20
|
-
shared_state = state_machine.shared_state
|
|
21
|
-
|
|
22
|
-
event_handlers: List[EventHandlerMapping] = [
|
|
23
|
-
EventHandlerMapping(
|
|
24
|
-
name="start_mission_event",
|
|
25
|
-
event=events.api_requests.start_mission.request,
|
|
26
|
-
handler=lambda event: start_mission_event_handler(
|
|
27
|
-
state_machine, event, events.api_requests.start_mission.response
|
|
28
|
-
),
|
|
29
|
-
),
|
|
30
|
-
EventHandlerMapping(
|
|
31
|
-
name="return_home_event",
|
|
32
|
-
event=events.api_requests.return_home.request,
|
|
33
|
-
handler=lambda event: return_home_event_handler(state_machine, event),
|
|
34
|
-
),
|
|
35
|
-
EventHandlerMapping(
|
|
36
|
-
name="stop_mission_event",
|
|
37
|
-
event=events.api_requests.return_home.request,
|
|
38
|
-
handler=lambda event: stop_mission_event_handler(state_machine, event),
|
|
39
|
-
),
|
|
40
|
-
EventHandlerMapping(
|
|
41
|
-
name="robot_status_event",
|
|
42
|
-
event=shared_state.robot_status,
|
|
43
|
-
handler=lambda event: robot_status_event_handler(
|
|
44
|
-
state_machine, RobotStatus.Available, event
|
|
45
|
-
),
|
|
46
|
-
),
|
|
47
|
-
]
|
|
48
|
-
super().__init__(
|
|
49
|
-
state_name="robot_standing_still",
|
|
50
|
-
state_machine=state_machine,
|
|
51
|
-
event_handler_mappings=event_handlers,
|
|
52
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|