isar 1.33.0__py3-none-any.whl → 1.33.1__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 +21 -52
- isar/models/events.py +45 -26
- isar/services/utilities/scheduling_utilities.py +3 -0
- isar/state_machine/state_machine.py +1 -1
- isar/state_machine/states/monitor.py +1 -3
- isar/state_machine/states/returning_home.py +9 -12
- isar/state_machine/states/stopping.py +33 -0
- isar/state_machine/transitions/functions/pause.py +1 -1
- isar/state_machine/transitions/functions/resume.py +1 -1
- isar/state_machine/transitions/functions/start_mission.py +3 -3
- isar/state_machine/transitions/functions/stop.py +3 -30
- isar/state_machine/transitions/mission.py +0 -2
- isar/state_machine/transitions/return_home.py +1 -1
- isar/state_machine/utils/common_event_handlers.py +10 -13
- {isar-1.33.0.dist-info → isar-1.33.1.dist-info}/METADATA +1 -1
- {isar-1.33.0.dist-info → isar-1.33.1.dist-info}/RECORD +20 -20
- {isar-1.33.0.dist-info → isar-1.33.1.dist-info}/WHEEL +0 -0
- {isar-1.33.0.dist-info → isar-1.33.1.dist-info}/entry_points.txt +0 -0
- {isar-1.33.0.dist-info → isar-1.33.1.dist-info}/licenses/LICENSE +0 -0
- {isar-1.33.0.dist-info → isar-1.33.1.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
from http import HTTPStatus
|
|
3
|
-
from threading import Lock
|
|
4
3
|
|
|
5
4
|
from fastapi import Body, HTTPException, Path
|
|
6
5
|
|
|
@@ -29,7 +28,6 @@ class SchedulingController:
|
|
|
29
28
|
):
|
|
30
29
|
self.scheduling_utilities: SchedulingUtilities = scheduling_utilities
|
|
31
30
|
self.logger = logging.getLogger("api")
|
|
32
|
-
self.start_mission_lock: Lock = Lock()
|
|
33
31
|
|
|
34
32
|
def start_mission_by_id(
|
|
35
33
|
self,
|
|
@@ -77,67 +75,38 @@ class SchedulingController:
|
|
|
77
75
|
detail=error_message_no_mission_definition,
|
|
78
76
|
)
|
|
79
77
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
"Conflict - Another mission is currently being started"
|
|
83
|
-
)
|
|
84
|
-
self.logger.warning(error_message_another_mission_starting)
|
|
85
|
-
raise HTTPException(
|
|
86
|
-
status_code=HTTPStatus.CONFLICT,
|
|
87
|
-
detail=error_message_another_mission_starting,
|
|
88
|
-
)
|
|
78
|
+
state: States = self.scheduling_utilities.get_state()
|
|
79
|
+
self.scheduling_utilities.verify_state_machine_ready_to_receive_mission(state)
|
|
89
80
|
|
|
90
81
|
try:
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
state
|
|
82
|
+
mission: Mission = to_isar_mission(
|
|
83
|
+
start_mission_definition=mission_definition
|
|
94
84
|
)
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
error_message = f"Bad Request - Cannot create ISAR mission: {e}"
|
|
102
|
-
self.logger.warning(error_message)
|
|
103
|
-
raise HTTPException(
|
|
104
|
-
status_code=HTTPStatus.BAD_REQUEST,
|
|
105
|
-
detail=error_message,
|
|
106
|
-
)
|
|
107
|
-
|
|
108
|
-
self.scheduling_utilities.verify_robot_capable_of_mission(
|
|
109
|
-
mission=mission, robot_capabilities=robot_settings.CAPABILITIES
|
|
85
|
+
except MissionPlannerError as e:
|
|
86
|
+
error_message = f"Bad Request - Cannot create ISAR mission: {e}"
|
|
87
|
+
self.logger.warning(error_message)
|
|
88
|
+
raise HTTPException(
|
|
89
|
+
status_code=HTTPStatus.BAD_REQUEST,
|
|
90
|
+
detail=error_message,
|
|
110
91
|
)
|
|
111
92
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
93
|
+
self.scheduling_utilities.verify_robot_capable_of_mission(
|
|
94
|
+
mission=mission, robot_capabilities=robot_settings.CAPABILITIES
|
|
95
|
+
)
|
|
115
96
|
|
|
116
|
-
|
|
117
|
-
|
|
97
|
+
self.logger.info("Starting mission: %s", mission.id)
|
|
98
|
+
self.scheduling_utilities.start_mission(mission=mission)
|
|
99
|
+
return self._api_response(mission)
|
|
118
100
|
|
|
119
101
|
def return_home(self) -> None:
|
|
120
102
|
self.logger.info("Received request to return home")
|
|
121
103
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
self.logger.warning(error_message_another_mission_starting)
|
|
127
|
-
raise HTTPException(
|
|
128
|
-
status_code=HTTPStatus.CONFLICT,
|
|
129
|
-
detail=error_message_another_mission_starting,
|
|
130
|
-
)
|
|
131
|
-
|
|
132
|
-
try:
|
|
133
|
-
state: States = self.scheduling_utilities.get_state()
|
|
134
|
-
self.scheduling_utilities.verify_state_machine_ready_to_receive_return_home_mission(
|
|
135
|
-
state
|
|
136
|
-
)
|
|
104
|
+
state: States = self.scheduling_utilities.get_state()
|
|
105
|
+
self.scheduling_utilities.verify_state_machine_ready_to_receive_return_home_mission(
|
|
106
|
+
state
|
|
107
|
+
)
|
|
137
108
|
|
|
138
|
-
|
|
139
|
-
finally:
|
|
140
|
-
self.start_mission_lock.release()
|
|
109
|
+
self.scheduling_utilities.return_home()
|
|
141
110
|
|
|
142
111
|
def pause_mission(self) -> ControlMissionResponse:
|
|
143
112
|
self.logger.info("Received request to pause current mission")
|
isar/models/events.py
CHANGED
|
@@ -17,12 +17,15 @@ T2 = TypeVar("T2")
|
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
class Event(Queue[T]):
|
|
20
|
-
def __init__(self) -> None:
|
|
20
|
+
def __init__(self, name: str) -> None:
|
|
21
21
|
super().__init__(maxsize=1)
|
|
22
|
+
self.name = name
|
|
22
23
|
|
|
23
24
|
def trigger_event(self, data: T, timeout: int = None) -> None:
|
|
24
25
|
try:
|
|
25
|
-
|
|
26
|
+
# We always want a timeout when blocking for results, so that
|
|
27
|
+
# the thread will never get stuck waiting for a result
|
|
28
|
+
self.put(data, block=timeout is not None, timeout=timeout)
|
|
26
29
|
except Exception:
|
|
27
30
|
if timeout is not None:
|
|
28
31
|
raise EventTimeoutError
|
|
@@ -79,46 +82,62 @@ class APIEvent(Generic[T1, T2]):
|
|
|
79
82
|
api to state machine while the response is from state machine to api.
|
|
80
83
|
"""
|
|
81
84
|
|
|
82
|
-
def __init__(self):
|
|
83
|
-
self.request: Event[T1] = Event()
|
|
84
|
-
self.response: Event[T2] = Event()
|
|
85
|
+
def __init__(self, name: str):
|
|
86
|
+
self.request: Event[T1] = Event("api-" + name + "-request")
|
|
87
|
+
self.response: Event[T2] = Event("api-" + name + "-request")
|
|
85
88
|
|
|
86
89
|
|
|
87
90
|
class APIRequests:
|
|
88
91
|
def __init__(self) -> None:
|
|
89
|
-
self.start_mission: APIEvent[Mission, MissionStartResponse] = APIEvent(
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
self.
|
|
93
|
-
|
|
94
|
-
|
|
92
|
+
self.start_mission: APIEvent[Mission, MissionStartResponse] = APIEvent(
|
|
93
|
+
"start_mission"
|
|
94
|
+
)
|
|
95
|
+
self.stop_mission: APIEvent[str, ControlMissionResponse] = APIEvent(
|
|
96
|
+
"stop_mission"
|
|
97
|
+
)
|
|
98
|
+
self.pause_mission: APIEvent[bool, ControlMissionResponse] = APIEvent(
|
|
99
|
+
"pause_mission"
|
|
100
|
+
)
|
|
101
|
+
self.resume_mission: APIEvent[bool, ControlMissionResponse] = APIEvent(
|
|
102
|
+
"resume_mission"
|
|
103
|
+
)
|
|
104
|
+
self.return_home: APIEvent[bool, bool] = APIEvent("return_home")
|
|
105
|
+
self.release_intervention_needed: APIEvent[bool, bool] = APIEvent(
|
|
106
|
+
"release_intervention_needed"
|
|
107
|
+
)
|
|
95
108
|
|
|
96
109
|
|
|
97
110
|
class StateMachineEvents:
|
|
98
111
|
def __init__(self) -> None:
|
|
99
|
-
self.start_mission: Event[Mission] = Event()
|
|
100
|
-
self.stop_mission: Event[bool] = Event()
|
|
101
|
-
self.pause_mission: Event[bool] = Event()
|
|
102
|
-
self.task_status_request: Event[str] = Event()
|
|
112
|
+
self.start_mission: Event[Mission] = Event("start_mission")
|
|
113
|
+
self.stop_mission: Event[bool] = Event("stop_mission")
|
|
114
|
+
self.pause_mission: Event[bool] = Event("pause_mission")
|
|
115
|
+
self.task_status_request: Event[str] = Event("task_status_request")
|
|
103
116
|
|
|
104
117
|
|
|
105
118
|
class RobotServiceEvents:
|
|
106
119
|
def __init__(self) -> None:
|
|
107
|
-
self.task_status_updated: Event[TaskStatus] = Event()
|
|
108
|
-
self.task_status_failed: Event[ErrorMessage] = Event()
|
|
109
|
-
self.mission_started: Event[bool] = Event()
|
|
110
|
-
self.mission_failed: Event[ErrorMessage] = Event()
|
|
111
|
-
self.robot_status_changed: Event[bool] = Event()
|
|
112
|
-
self.mission_failed_to_stop: Event[ErrorMessage] = Event(
|
|
113
|
-
|
|
120
|
+
self.task_status_updated: Event[TaskStatus] = Event("task_status_updated")
|
|
121
|
+
self.task_status_failed: Event[ErrorMessage] = Event("task_status_failed")
|
|
122
|
+
self.mission_started: Event[bool] = Event("mission_started")
|
|
123
|
+
self.mission_failed: Event[ErrorMessage] = Event("mission_failed")
|
|
124
|
+
self.robot_status_changed: Event[bool] = Event("robot_status_changed")
|
|
125
|
+
self.mission_failed_to_stop: Event[ErrorMessage] = Event(
|
|
126
|
+
"mission_failed_to_stop"
|
|
127
|
+
)
|
|
128
|
+
self.mission_successfully_stopped: Event[bool] = Event(
|
|
129
|
+
"mission_successfully_stopped"
|
|
130
|
+
)
|
|
114
131
|
|
|
115
132
|
|
|
116
133
|
class SharedState:
|
|
117
134
|
def __init__(self) -> None:
|
|
118
|
-
self.state: Event[State] = Event()
|
|
119
|
-
self.robot_status: Event[RobotStatus] = Event()
|
|
120
|
-
self.state_machine_current_task: Event[TASKS] = Event(
|
|
121
|
-
|
|
135
|
+
self.state: Event[State] = Event("state")
|
|
136
|
+
self.robot_status: Event[RobotStatus] = Event("robot_status")
|
|
137
|
+
self.state_machine_current_task: Event[TASKS] = Event(
|
|
138
|
+
"state_machine_current_task"
|
|
139
|
+
)
|
|
140
|
+
self.robot_battery_level: Event[float] = Event("robot_battery_level")
|
|
122
141
|
|
|
123
142
|
|
|
124
143
|
class EventTimeoutError(Exception):
|
|
@@ -406,7 +406,7 @@ class StateMachine(object):
|
|
|
406
406
|
)
|
|
407
407
|
|
|
408
408
|
def _queue_empty_response(self) -> None:
|
|
409
|
-
self.events.api_requests.stop_mission.response.
|
|
409
|
+
self.events.api_requests.stop_mission.response.trigger_event(
|
|
410
410
|
ControlMissionResponse(
|
|
411
411
|
mission_id="None",
|
|
412
412
|
mission_status="None",
|
|
@@ -60,9 +60,7 @@ class Monitor(EventHandlerBase):
|
|
|
60
60
|
state_machine.logger.warning(
|
|
61
61
|
"Cancelling current mission due to low battery"
|
|
62
62
|
)
|
|
63
|
-
state_machine.
|
|
64
|
-
state_machine.current_task = None
|
|
65
|
-
return state_machine.request_return_home # type: ignore
|
|
63
|
+
return state_machine.stop # type: ignore
|
|
66
64
|
return None
|
|
67
65
|
|
|
68
66
|
event_handlers: List[EventHandlerMapping] = [
|
|
@@ -2,7 +2,7 @@ from typing import TYPE_CHECKING, Callable, List, Optional
|
|
|
2
2
|
|
|
3
3
|
from isar.apis.models.models import MissionStartResponse
|
|
4
4
|
from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
|
|
5
|
-
from isar.models.events import Event
|
|
5
|
+
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,
|
|
@@ -43,17 +43,14 @@ class ReturningHome(EventHandlerBase):
|
|
|
43
43
|
) -> Optional[Callable]:
|
|
44
44
|
if event.has_event():
|
|
45
45
|
if not state_machine.battery_level_is_above_mission_start_threshold():
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
)
|
|
55
|
-
except EventTimeoutError:
|
|
56
|
-
pass
|
|
46
|
+
response = MissionStartResponse(
|
|
47
|
+
mission_id=None,
|
|
48
|
+
mission_started=False,
|
|
49
|
+
mission_not_started_reason="Robot battery too low",
|
|
50
|
+
)
|
|
51
|
+
state_machine.events.api_requests.start_mission.response.trigger_event(
|
|
52
|
+
response
|
|
53
|
+
)
|
|
57
54
|
return None
|
|
58
55
|
return state_machine.stop # type: ignore
|
|
59
56
|
return None
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
from typing import TYPE_CHECKING, Callable, List, Optional
|
|
3
3
|
|
|
4
|
+
from isar.apis.models.models import ControlMissionResponse
|
|
4
5
|
from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
|
|
5
6
|
from isar.models.events import Event
|
|
6
7
|
from robot_interface.models.exceptions.robot_exceptions import ErrorMessage
|
|
8
|
+
from robot_interface.models.mission.status import MissionStatus, TaskStatus
|
|
7
9
|
|
|
8
10
|
if TYPE_CHECKING:
|
|
9
11
|
from isar.state_machine.state_machine import StateMachine
|
|
@@ -15,6 +17,32 @@ class Stopping(EventHandlerBase):
|
|
|
15
17
|
logger = logging.getLogger("state_machine")
|
|
16
18
|
events = state_machine.events
|
|
17
19
|
|
|
20
|
+
def _stop_mission_cleanup() -> None:
|
|
21
|
+
if state_machine.current_mission is None:
|
|
22
|
+
state_machine._queue_empty_response()
|
|
23
|
+
state_machine.reset_state_machine()
|
|
24
|
+
return None
|
|
25
|
+
|
|
26
|
+
state_machine.current_mission.status = MissionStatus.Cancelled
|
|
27
|
+
|
|
28
|
+
for task in state_machine.current_mission.tasks:
|
|
29
|
+
if task.status in [
|
|
30
|
+
TaskStatus.NotStarted,
|
|
31
|
+
TaskStatus.InProgress,
|
|
32
|
+
TaskStatus.Paused,
|
|
33
|
+
]:
|
|
34
|
+
task.status = TaskStatus.Cancelled
|
|
35
|
+
|
|
36
|
+
stopped_mission_response: ControlMissionResponse = (
|
|
37
|
+
state_machine._make_control_mission_response()
|
|
38
|
+
)
|
|
39
|
+
state_machine.events.api_requests.stop_mission.response.trigger_event(
|
|
40
|
+
stopped_mission_response
|
|
41
|
+
)
|
|
42
|
+
state_machine.publish_task_status(task=state_machine.current_task)
|
|
43
|
+
state_machine._finalize()
|
|
44
|
+
return None
|
|
45
|
+
|
|
18
46
|
def _failed_stop_event_handler(
|
|
19
47
|
event: Event[ErrorMessage],
|
|
20
48
|
) -> Optional[Callable]:
|
|
@@ -38,6 +66,11 @@ class Stopping(EventHandlerBase):
|
|
|
38
66
|
):
|
|
39
67
|
return state_machine.return_home_mission_stopped # type: ignore
|
|
40
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
|
|
41
74
|
return state_machine.mission_stopped # type: ignore
|
|
42
75
|
return None
|
|
43
76
|
|
|
@@ -29,7 +29,7 @@ def pause_mission(state_machine: "StateMachine") -> bool:
|
|
|
29
29
|
paused_mission_response: ControlMissionResponse = (
|
|
30
30
|
state_machine._make_control_mission_response()
|
|
31
31
|
)
|
|
32
|
-
state_machine.events.api_requests.pause_mission.response.
|
|
32
|
+
state_machine.events.api_requests.pause_mission.response.trigger_event(
|
|
33
33
|
paused_mission_response
|
|
34
34
|
)
|
|
35
35
|
|
|
@@ -35,7 +35,7 @@ def resume_mission(state_machine: "StateMachine") -> bool:
|
|
|
35
35
|
resume_mission_response: ControlMissionResponse = (
|
|
36
36
|
state_machine._make_control_mission_response()
|
|
37
37
|
)
|
|
38
|
-
state_machine.events.api_requests.resume_mission.response.
|
|
38
|
+
state_machine.events.api_requests.resume_mission.response.trigger_event(
|
|
39
39
|
resume_mission_response
|
|
40
40
|
)
|
|
41
41
|
|
|
@@ -13,7 +13,7 @@ from robot_interface.models.mission.status import MissionStatus, TaskStatus
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
def acknowledge_mission(state_machine: "StateMachine") -> bool:
|
|
16
|
-
state_machine.events.api_requests.start_mission.response.
|
|
16
|
+
state_machine.events.api_requests.start_mission.response.trigger_event(
|
|
17
17
|
MissionStartResponse(mission_started=True)
|
|
18
18
|
)
|
|
19
19
|
return True
|
|
@@ -66,14 +66,14 @@ def set_mission_to_in_progress(state_machine: "StateMachine") -> bool:
|
|
|
66
66
|
|
|
67
67
|
|
|
68
68
|
def trigger_start_mission_event(state_machine: "StateMachine") -> bool:
|
|
69
|
-
state_machine.events.state_machine_events.start_mission.
|
|
69
|
+
state_machine.events.state_machine_events.start_mission.trigger_event(
|
|
70
70
|
state_machine.current_mission
|
|
71
71
|
)
|
|
72
72
|
return True
|
|
73
73
|
|
|
74
74
|
|
|
75
75
|
def _initialization_failed(state_machine: "StateMachine") -> None:
|
|
76
|
-
state_machine.events.api_requests.start_mission.response.
|
|
76
|
+
state_machine.events.api_requests.start_mission.response.trigger_event(
|
|
77
77
|
MissionStartResponse(
|
|
78
78
|
mission_started=False,
|
|
79
79
|
mission_not_started_reason="Failed to initialize robot",
|
|
@@ -12,38 +12,11 @@ def trigger_stop_mission_event(state_machine: "StateMachine") -> bool:
|
|
|
12
12
|
return True
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
def stop_mission_cleanup(state_machine: "StateMachine") -> bool:
|
|
16
|
-
if state_machine.current_mission is None:
|
|
17
|
-
state_machine._queue_empty_response()
|
|
18
|
-
state_machine.reset_state_machine()
|
|
19
|
-
return True
|
|
20
|
-
|
|
21
|
-
state_machine.current_mission.status = MissionStatus.Cancelled
|
|
22
|
-
|
|
23
|
-
for task in state_machine.current_mission.tasks:
|
|
24
|
-
if task.status in [
|
|
25
|
-
TaskStatus.NotStarted,
|
|
26
|
-
TaskStatus.InProgress,
|
|
27
|
-
TaskStatus.Paused,
|
|
28
|
-
]:
|
|
29
|
-
task.status = TaskStatus.Cancelled
|
|
30
|
-
|
|
31
|
-
stopped_mission_response: ControlMissionResponse = (
|
|
32
|
-
state_machine._make_control_mission_response()
|
|
33
|
-
)
|
|
34
|
-
state_machine.events.api_requests.stop_mission.response.put(
|
|
35
|
-
stopped_mission_response
|
|
36
|
-
)
|
|
37
|
-
state_machine.publish_task_status(task=state_machine.current_task)
|
|
38
|
-
state_machine._finalize()
|
|
39
|
-
return True
|
|
40
|
-
|
|
41
|
-
|
|
42
15
|
def stop_mission_failed(state_machine: "StateMachine") -> bool:
|
|
43
16
|
stopped_mission_response: ControlMissionResponse = (
|
|
44
17
|
state_machine._make_control_mission_response()
|
|
45
18
|
)
|
|
46
|
-
state_machine.events.api_requests.stop_mission.response.
|
|
19
|
+
state_machine.events.api_requests.stop_mission.response.trigger_event(
|
|
47
20
|
stopped_mission_response
|
|
48
21
|
)
|
|
49
22
|
return True
|
|
@@ -69,7 +42,7 @@ def stop_return_home_mission_cleanup(state_machine: "StateMachine") -> bool:
|
|
|
69
42
|
stopped_mission_response: ControlMissionResponse = (
|
|
70
43
|
state_machine._make_control_mission_response()
|
|
71
44
|
)
|
|
72
|
-
state_machine.events.api_requests.stop_mission.response.
|
|
45
|
+
state_machine.events.api_requests.stop_mission.response.trigger_event(
|
|
73
46
|
stopped_mission_response
|
|
74
47
|
)
|
|
75
48
|
|
|
@@ -83,7 +56,7 @@ def stop_return_home_mission_failed(state_machine: "StateMachine") -> bool:
|
|
|
83
56
|
stopped_mission_response: ControlMissionResponse = (
|
|
84
57
|
state_machine._make_control_mission_response()
|
|
85
58
|
)
|
|
86
|
-
state_machine.events.api_requests.stop_mission.response.
|
|
59
|
+
state_machine.events.api_requests.stop_mission.response.trigger_event(
|
|
87
60
|
stopped_mission_response
|
|
88
61
|
)
|
|
89
62
|
return True
|
|
@@ -14,7 +14,6 @@ from isar.state_machine.transitions.functions.start_mission import (
|
|
|
14
14
|
trigger_start_mission_event,
|
|
15
15
|
)
|
|
16
16
|
from isar.state_machine.transitions.functions.stop import (
|
|
17
|
-
stop_mission_cleanup,
|
|
18
17
|
stop_mission_failed,
|
|
19
18
|
stop_return_home_mission_cleanup,
|
|
20
19
|
stop_return_home_mission_failed,
|
|
@@ -66,7 +65,6 @@ def get_mission_transitions(state_machine: "StateMachine") -> List[dict]:
|
|
|
66
65
|
"trigger": "mission_stopped",
|
|
67
66
|
"source": state_machine.stopping_state,
|
|
68
67
|
"dest": state_machine.await_next_mission_state,
|
|
69
|
-
"before": def_transition(state_machine, stop_mission_cleanup),
|
|
70
68
|
},
|
|
71
69
|
{
|
|
72
70
|
"trigger": "mission_stopping_failed",
|
|
@@ -31,13 +31,13 @@ def get_return_home_transitions(state_machine: "StateMachine") -> List[dict]:
|
|
|
31
31
|
state_machine.robot_standing_still_state,
|
|
32
32
|
state_machine.intervention_needed_state,
|
|
33
33
|
state_machine.monitor_state,
|
|
34
|
+
state_machine.stopping_state,
|
|
34
35
|
],
|
|
35
36
|
"dest": state_machine.returning_home_state,
|
|
36
37
|
"conditions": [
|
|
37
38
|
def_transition(state_machine, start_return_home_mission),
|
|
38
39
|
def_transition(state_machine, set_return_home_status),
|
|
39
40
|
def_transition(state_machine, initialize_robot),
|
|
40
|
-
def_transition(state_machine, initialize_robot),
|
|
41
41
|
],
|
|
42
42
|
"before": def_transition(state_machine, trigger_start_mission_event),
|
|
43
43
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from typing import TYPE_CHECKING, Callable, Optional
|
|
2
2
|
|
|
3
3
|
from isar.apis.models.models import ControlMissionResponse, MissionStartResponse
|
|
4
|
-
from isar.models.events import Event
|
|
4
|
+
from isar.models.events import Event
|
|
5
5
|
from robot_interface.models.exceptions.robot_exceptions import ErrorMessage
|
|
6
6
|
from robot_interface.models.mission.mission import Mission
|
|
7
7
|
from robot_interface.models.mission.status import RobotStatus, TaskStatus
|
|
@@ -18,17 +18,13 @@ def start_mission_event_handler(
|
|
|
18
18
|
mission: Optional[Mission] = event.consume_event()
|
|
19
19
|
if mission:
|
|
20
20
|
if not state_machine.battery_level_is_above_mission_start_threshold():
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
mission_not_started_reason="Robot battery too low",
|
|
27
|
-
),
|
|
28
|
-
timeout=1, # This conflict can happen if two API requests are received at the same time
|
|
21
|
+
response.trigger_event(
|
|
22
|
+
MissionStartResponse(
|
|
23
|
+
mission_id=mission.id,
|
|
24
|
+
mission_started=False,
|
|
25
|
+
mission_not_started_reason="Robot battery too low",
|
|
29
26
|
)
|
|
30
|
-
|
|
31
|
-
pass
|
|
27
|
+
)
|
|
32
28
|
return None
|
|
33
29
|
state_machine.start_mission(mission=mission)
|
|
34
30
|
return state_machine.request_mission_start # type: ignore
|
|
@@ -39,7 +35,7 @@ def return_home_event_handler(
|
|
|
39
35
|
state_machine: "StateMachine", event: Event[bool]
|
|
40
36
|
) -> Optional[Callable]:
|
|
41
37
|
if event.consume_event():
|
|
42
|
-
state_machine.events.api_requests.return_home.response.
|
|
38
|
+
state_machine.events.api_requests.return_home.response.trigger_event(True)
|
|
43
39
|
return state_machine.request_return_home # type: ignore
|
|
44
40
|
return None
|
|
45
41
|
|
|
@@ -63,7 +59,7 @@ def stop_mission_event_handler(
|
|
|
63
59
|
if state_machine.current_mission.id == mission_id or mission_id == "":
|
|
64
60
|
return state_machine.stop # type: ignore
|
|
65
61
|
else:
|
|
66
|
-
state_machine.events.api_requests.stop_mission.response.
|
|
62
|
+
state_machine.events.api_requests.stop_mission.response.trigger_event(
|
|
67
63
|
ControlMissionResponse(
|
|
68
64
|
mission_id=mission_id,
|
|
69
65
|
mission_status=state_machine.current_mission.status,
|
|
@@ -80,6 +76,7 @@ def mission_started_event_handler(
|
|
|
80
76
|
event: Event[bool],
|
|
81
77
|
) -> Optional[Callable]:
|
|
82
78
|
if event.consume_event():
|
|
79
|
+
state_machine.logger.info("Received confirmation that mission has started")
|
|
83
80
|
state_machine.mission_ongoing = True
|
|
84
81
|
return None
|
|
85
82
|
|
|
@@ -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=xpKlxxxBQuHZ37WP1OU8SR198YIIrr2NdWWJeaZpuEc,9366
|
|
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
|
|
@@ -42,7 +42,7 @@ isar/mission_planner/mission_planner_interface.py,sha256=UgpPIM4FbrWOD7fGY3Ul64k
|
|
|
42
42
|
isar/mission_planner/sequential_task_selector.py,sha256=66agRPHuJnEa1vArPyty4muTasAZ50XPjjrSaTdY_Cc,643
|
|
43
43
|
isar/mission_planner/task_selector_interface.py,sha256=pnLeaGPIuyXThcflZ_A7YL2b2xQjFT88hAZidkMomxU,707
|
|
44
44
|
isar/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
45
|
-
isar/models/events.py,sha256=
|
|
45
|
+
isar/models/events.py,sha256=M-0p4krtLpCfBMbClQvBFvfFB4NWBm55AlO1ngzVM_g,5024
|
|
46
46
|
isar/robot/robot.py,sha256=keqsYmfRlyIC4CWkMG0erDt_4uIC0IPvyG2ni4MemyI,5350
|
|
47
47
|
isar/robot/robot_start_mission.py,sha256=RPYH9VtXDFdPqhOpt6kSbT17RHkJQPKkQ6d4784_pFE,3210
|
|
48
48
|
isar/robot/robot_status.py,sha256=OXx18Qj0bvb2sKzn5-yKXWGdZ9GYyCOIgiTaGof-0Wc,2055
|
|
@@ -59,44 +59,44 @@ isar/services/service_connections/mqtt/robot_heartbeat_publisher.py,sha256=_bUOG
|
|
|
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=3vFU7t7oEZTFQNJdAxfhaADScRJIxznWhDbagHyLKOQ,13605
|
|
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=
|
|
65
|
+
isar/state_machine/state_machine.py,sha256=6P88wFxvkHaYWK_WBCzTVdNkn7wqbwJVR0So-en2u_w,18038
|
|
66
66
|
isar/state_machine/states_enum.py,sha256=4Kysag9JPi2JSyC2me2B1sLH3Sfo7qGJonc-Q_IiUug,511
|
|
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
70
|
isar/state_machine/states/home.py,sha256=TYv7WF5yX31Zw6Cn5MY2GHebUfypL5w510I92BEi_vE,1950
|
|
71
71
|
isar/state_machine/states/intervention_needed.py,sha256=A0QYz1vD1tDKAealihXDuoGuMLtXrRfn_AwFoaUhT_Q,1640
|
|
72
|
-
isar/state_machine/states/monitor.py,sha256=
|
|
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
74
|
isar/state_machine/states/paused.py,sha256=osmLZhm0-2jcZmNRauveeidCBYayDZvLy-1TNYv6CgQ,1091
|
|
75
75
|
isar/state_machine/states/recharging.py,sha256=ni5WqFU0VDhdGC3ZfHcabSICm_5kwaS72wc3ecAB_os,1651
|
|
76
|
-
isar/state_machine/states/returning_home.py,sha256=
|
|
76
|
+
isar/state_machine/states/returning_home.py,sha256=mPwsOFxMTO6On5PzeYKW8Roy6TaQIXsoWCsbtzcV7M8,4267
|
|
77
77
|
isar/state_machine/states/robot_standing_still.py,sha256=EWG2_IPbxK6HFERHcmMFlWdN5PnXJXjwEfNlpsJnPkQ,1985
|
|
78
|
-
isar/state_machine/states/stopping.py,sha256=
|
|
78
|
+
isar/state_machine/states/stopping.py,sha256=ROKbQcJFS4A_U0Pd8lAViG7Dz8JqfBaR3vHmpvKC2oc,3848
|
|
79
79
|
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=
|
|
80
|
+
isar/state_machine/transitions/mission.py,sha256=oJiANT1lHd6YhEA_mQscDPDyfwMxwfosq7UcP0gfTNk,5456
|
|
81
|
+
isar/state_machine/transitions/return_home.py,sha256=EIR14rnukV_mEYkwtz0J_D1Dp51oVna0wV71HSbqtuw,4630
|
|
82
82
|
isar/state_machine/transitions/robot_status.py,sha256=sALt9BwZUnIFmVe35N1ptC-PyhfdHiTGu1R0GzpAQXk,3056
|
|
83
83
|
isar/state_machine/transitions/functions/fail_mission.py,sha256=jHHXhfQVYQEzCXgTEhv5e6uEK9p6iDPFFXqS9bzs_-A,720
|
|
84
84
|
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/resume.py,sha256=
|
|
85
|
+
isar/state_machine/transitions/functions/pause.py,sha256=Wa9XlhXVRNzxoYSsHc0w87ht4nQ5dGh50fjfA9lrAmI,1987
|
|
86
|
+
isar/state_machine/transitions/functions/resume.py,sha256=SAu4hWomPlrvO0lnpc6uM3rj79Bwq01acnaTEvNbO9U,2116
|
|
87
87
|
isar/state_machine/transitions/functions/return_home.py,sha256=5WPO40MtuRKm9-NtyrS6m0IVEit14MXfMKjgZ2sCXRU,1666
|
|
88
88
|
isar/state_machine/transitions/functions/robot_status.py,sha256=P1Cu8xVysbiKRKL4E8mSyoL2-72HfxrLvvOcdnBOlvw,889
|
|
89
|
-
isar/state_machine/transitions/functions/start_mission.py,sha256=
|
|
90
|
-
isar/state_machine/transitions/functions/stop.py,sha256=
|
|
89
|
+
isar/state_machine/transitions/functions/start_mission.py,sha256=tIpZzYXCoeC6ZWj18UB4DiZuICpxfzFUK23wfunad7Q,2864
|
|
90
|
+
isar/state_machine/transitions/functions/stop.py,sha256=4idsNh7v6CRJivD36oKnVmdKlP7mSugTLCh9n12R1-U,2114
|
|
91
91
|
isar/state_machine/transitions/functions/utils.py,sha256=Wa72Ocq4QT1E6qkpEJZQ3h5o33pGvx7Tlkt2JZ2Grbk,314
|
|
92
|
-
isar/state_machine/utils/common_event_handlers.py,sha256=
|
|
92
|
+
isar/state_machine/utils/common_event_handlers.py,sha256=yFZzTmTLVWzHU4RNW3q9gc6NU9eajNn50L-vt6geH38,6318
|
|
93
93
|
isar/storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
94
94
|
isar/storage/blob_storage.py,sha256=QueyHzCJfUUyOLxBeYwK0Ot7w_CYakBEhtTtITelKAo,3026
|
|
95
95
|
isar/storage/local_storage.py,sha256=-9Bz2WmniLKwKMeAdrgoMzkj781AOLIUsfaqQERqpUk,1985
|
|
96
96
|
isar/storage/storage_interface.py,sha256=DRIiy0mRZL3KMZysG0R2Cque6hoqd5haZBw11WM53Vc,840
|
|
97
97
|
isar/storage/uploader.py,sha256=uD1DzvJ2yYtNAwQGa7UD7kNOxZfKxJ1cCdi7sfOVZ10,9443
|
|
98
98
|
isar/storage/utilities.py,sha256=oLH0Rp7UtrQQdilfITnmXO1Z0ExdeDhBImYHid55vBA,3449
|
|
99
|
-
isar-1.33.
|
|
99
|
+
isar-1.33.1.dist-info/licenses/LICENSE,sha256=3fc2-ebLwHWwzfQbulGNRdcNob3SBQeCfEVUDYxsuqw,14058
|
|
100
100
|
robot_interface/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
101
101
|
robot_interface/robot_interface.py,sha256=A6t19lcNU_6AfkYKY5DaF0sheym_SZEAawbfaj36Kjk,8997
|
|
102
102
|
robot_interface/test_robot_interface.py,sha256=FV1urn7SbsMyWBIcTKjsBwAG4IsXeZ6pLHE0mA9EGGs,692
|
|
@@ -120,8 +120,8 @@ robot_interface/telemetry/payloads.py,sha256=T7EK-b0bVhADDTKMIAHmcPVtPxuR16csmZo
|
|
|
120
120
|
robot_interface/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
121
121
|
robot_interface/utilities/json_service.py,sha256=qkzVkb60Gi_pto-b5n1vNzCrQze2yqgIJqSLNLYj1Fg,1034
|
|
122
122
|
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.
|
|
123
|
+
isar-1.33.1.dist-info/METADATA,sha256=DA8JyLIr7mtdSeQwJP_9WV5phTA4QlDj8YQd0lE7ppE,31217
|
|
124
|
+
isar-1.33.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
125
|
+
isar-1.33.1.dist-info/entry_points.txt,sha256=TFam7uNNw7J0iiDYzsH2gfG0u1eV1wh3JTw_HkhgKLk,49
|
|
126
|
+
isar-1.33.1.dist-info/top_level.txt,sha256=UwIML2RtuQKCyJJkatcSnyp6-ldDjboB9k9JgKipO-U,21
|
|
127
|
+
isar-1.33.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|