isar 1.20.2__py3-none-any.whl → 1.34.13__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.
- isar/apis/api.py +135 -86
- isar/apis/models/__init__.py +0 -1
- isar/apis/models/models.py +21 -11
- isar/apis/models/start_mission_definition.py +115 -170
- isar/apis/robot_control/robot_controller.py +41 -0
- isar/apis/schedule/scheduling_controller.py +123 -187
- isar/apis/security/authentication.py +5 -5
- isar/config/certs/ca-cert.pem +33 -31
- isar/config/keyvault/keyvault_service.py +4 -2
- isar/config/log.py +45 -40
- isar/config/logging.conf +16 -31
- isar/config/open_telemetry.py +102 -0
- isar/config/settings.py +74 -117
- isar/eventhandlers/eventhandler.py +123 -0
- isar/models/events.py +184 -0
- isar/models/status.py +22 -0
- isar/modules.py +117 -200
- isar/robot/robot.py +383 -0
- isar/robot/robot_battery.py +60 -0
- isar/robot/robot_monitor_mission.py +357 -0
- isar/robot/robot_pause_mission.py +74 -0
- isar/robot/robot_resume_mission.py +67 -0
- isar/robot/robot_start_mission.py +66 -0
- isar/robot/robot_status.py +61 -0
- isar/robot/robot_stop_mission.py +68 -0
- isar/robot/robot_upload_inspection.py +75 -0
- isar/script.py +58 -41
- isar/services/service_connections/mqtt/mqtt_client.py +47 -11
- isar/services/service_connections/mqtt/robot_heartbeat_publisher.py +5 -2
- isar/services/service_connections/mqtt/robot_info_publisher.py +3 -3
- isar/services/service_connections/persistent_memory.py +69 -0
- isar/services/utilities/mqtt_utilities.py +93 -0
- isar/services/utilities/robot_utilities.py +20 -0
- isar/services/utilities/scheduling_utilities.py +386 -100
- isar/state_machine/state_machine.py +242 -539
- isar/state_machine/states/__init__.py +0 -8
- isar/state_machine/states/await_next_mission.py +114 -0
- isar/state_machine/states/blocked_protective_stop.py +60 -0
- isar/state_machine/states/going_to_lockdown.py +95 -0
- isar/state_machine/states/going_to_recharging.py +92 -0
- isar/state_machine/states/home.py +115 -0
- isar/state_machine/states/intervention_needed.py +77 -0
- isar/state_machine/states/lockdown.py +38 -0
- isar/state_machine/states/maintenance.py +43 -0
- isar/state_machine/states/monitor.py +137 -247
- isar/state_machine/states/offline.py +51 -53
- isar/state_machine/states/paused.py +92 -23
- isar/state_machine/states/pausing.py +48 -0
- isar/state_machine/states/pausing_return_home.py +48 -0
- isar/state_machine/states/recharging.py +80 -0
- isar/state_machine/states/resuming.py +57 -0
- isar/state_machine/states/resuming_return_home.py +64 -0
- isar/state_machine/states/return_home_paused.py +109 -0
- isar/state_machine/states/returning_home.py +217 -0
- isar/state_machine/states/stopping.py +69 -0
- isar/state_machine/states/stopping_due_to_maintenance.py +61 -0
- isar/state_machine/states/stopping_go_to_lockdown.py +60 -0
- isar/state_machine/states/stopping_go_to_recharge.py +51 -0
- isar/state_machine/states/stopping_paused_mission.py +36 -0
- isar/state_machine/states/stopping_paused_return_home.py +59 -0
- isar/state_machine/states/stopping_return_home.py +59 -0
- isar/state_machine/states/unknown_status.py +74 -0
- isar/state_machine/states_enum.py +23 -5
- isar/state_machine/transitions/mission.py +225 -0
- isar/state_machine/transitions/return_home.py +108 -0
- isar/state_machine/transitions/robot_status.py +87 -0
- isar/state_machine/utils/common_event_handlers.py +138 -0
- isar/storage/blob_storage.py +70 -52
- isar/storage/local_storage.py +25 -12
- isar/storage/storage_interface.py +28 -7
- isar/storage/uploader.py +174 -55
- isar/storage/utilities.py +32 -29
- {isar-1.20.2.dist-info → isar-1.34.13.dist-info}/METADATA +119 -123
- isar-1.34.13.dist-info/RECORD +120 -0
- {isar-1.20.2.dist-info → isar-1.34.13.dist-info}/WHEEL +1 -1
- {isar-1.20.2.dist-info → isar-1.34.13.dist-info}/entry_points.txt +1 -0
- robot_interface/models/exceptions/robot_exceptions.py +91 -41
- robot_interface/models/inspection/__init__.py +0 -13
- robot_interface/models/inspection/inspection.py +42 -33
- robot_interface/models/mission/mission.py +14 -15
- robot_interface/models/mission/status.py +20 -26
- robot_interface/models/mission/task.py +154 -121
- robot_interface/models/robots/battery_state.py +6 -0
- robot_interface/models/robots/media.py +13 -0
- robot_interface/models/robots/robot_model.py +7 -7
- robot_interface/robot_interface.py +119 -84
- robot_interface/telemetry/mqtt_client.py +74 -12
- robot_interface/telemetry/payloads.py +91 -13
- robot_interface/utilities/json_service.py +7 -1
- isar/config/configuration_error.py +0 -2
- isar/config/keyvault/keyvault_error.py +0 -2
- isar/config/predefined_mission_definition/__init__.py +0 -0
- isar/config/predefined_mission_definition/default_exr.json +0 -51
- isar/config/predefined_mission_definition/default_mission.json +0 -91
- isar/config/predefined_mission_definition/default_turtlebot.json +0 -124
- isar/config/predefined_missions/__init__.py +0 -0
- isar/config/predefined_missions/default.json +0 -92
- isar/config/predefined_missions/default_turtlebot.json +0 -110
- isar/config/predefined_poses/__init__.py +0 -0
- isar/config/predefined_poses/predefined_poses.py +0 -616
- isar/config/settings.env +0 -25
- isar/mission_planner/__init__.py +0 -0
- isar/mission_planner/local_planner.py +0 -82
- isar/mission_planner/mission_planner_interface.py +0 -26
- isar/mission_planner/sequential_task_selector.py +0 -23
- isar/mission_planner/task_selector_interface.py +0 -31
- isar/models/communication/__init__.py +0 -0
- isar/models/communication/message.py +0 -12
- isar/models/communication/queues/__init__.py +0 -4
- isar/models/communication/queues/queue_io.py +0 -12
- isar/models/communication/queues/queue_timeout_error.py +0 -2
- isar/models/communication/queues/queues.py +0 -19
- isar/models/communication/queues/status_queue.py +0 -20
- isar/models/mission_metadata/__init__.py +0 -0
- isar/services/auth/__init__.py +0 -0
- isar/services/auth/azure_credentials.py +0 -14
- isar/services/readers/__init__.py +0 -0
- isar/services/readers/base_reader.py +0 -37
- isar/services/service_connections/request_handler.py +0 -153
- isar/services/service_connections/stid/__init__.py +0 -0
- isar/services/utilities/queue_utilities.py +0 -39
- isar/services/utilities/threaded_request.py +0 -68
- isar/state_machine/states/idle.py +0 -85
- isar/state_machine/states/initialize.py +0 -71
- isar/state_machine/states/initiate.py +0 -142
- isar/state_machine/states/off.py +0 -18
- isar/state_machine/states/stop.py +0 -95
- isar/storage/slimm_storage.py +0 -191
- isar-1.20.2.dist-info/RECORD +0 -116
- robot_interface/models/initialize/__init__.py +0 -1
- robot_interface/models/initialize/initialize_params.py +0 -9
- robot_interface/models/mission/step.py +0 -234
- {isar-1.20.2.dist-info → isar-1.34.13.dist-info/licenses}/LICENSE +0 -0
- {isar-1.20.2.dist-info → isar-1.34.13.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, Callable, List, Optional
|
|
2
|
+
|
|
3
|
+
from isar.apis.models.models import ControlMissionResponse
|
|
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
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from isar.state_machine.state_machine import StateMachine
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Stopping(EventHandlerBase):
|
|
13
|
+
|
|
14
|
+
def __init__(self, state_machine: "StateMachine"):
|
|
15
|
+
events = state_machine.events
|
|
16
|
+
|
|
17
|
+
def _failed_stop_event_handler(
|
|
18
|
+
event: Event[ErrorMessage],
|
|
19
|
+
) -> Optional[Callable]:
|
|
20
|
+
error_message: Optional[ErrorMessage] = event.consume_event()
|
|
21
|
+
if error_message is None:
|
|
22
|
+
return None
|
|
23
|
+
|
|
24
|
+
stopped_mission_response: ControlMissionResponse = ControlMissionResponse(
|
|
25
|
+
success=False, failure_reason="ISAR failed to stop mission"
|
|
26
|
+
)
|
|
27
|
+
state_machine.events.api_requests.stop_mission.response.trigger_event(
|
|
28
|
+
stopped_mission_response
|
|
29
|
+
)
|
|
30
|
+
return state_machine.mission_stopping_failed # type: ignore
|
|
31
|
+
|
|
32
|
+
def _successful_stop_event_handler(event: Event[bool]) -> Optional[Callable]:
|
|
33
|
+
if not event.consume_event():
|
|
34
|
+
return None
|
|
35
|
+
|
|
36
|
+
state_machine.events.api_requests.stop_mission.response.trigger_event(
|
|
37
|
+
ControlMissionResponse(success=True)
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
if state_machine.shared_state.mission_id.check() is None:
|
|
41
|
+
reason: str = (
|
|
42
|
+
"Robot was busy and mission stopped but no ongoing mission found in shared state."
|
|
43
|
+
)
|
|
44
|
+
state_machine.logger.warning(reason)
|
|
45
|
+
state_machine.publish_mission_aborted(reason, False)
|
|
46
|
+
|
|
47
|
+
state_machine.print_transitions()
|
|
48
|
+
if not state_machine.battery_level_is_above_mission_start_threshold():
|
|
49
|
+
state_machine.start_return_home_mission()
|
|
50
|
+
return state_machine.start_return_home_monitoring # type: ignore
|
|
51
|
+
return state_machine.mission_stopped # type: ignore
|
|
52
|
+
|
|
53
|
+
event_handlers: List[EventHandlerMapping] = [
|
|
54
|
+
EventHandlerMapping(
|
|
55
|
+
name="failed_stop_event",
|
|
56
|
+
event=events.robot_service_events.mission_failed_to_stop,
|
|
57
|
+
handler=_failed_stop_event_handler,
|
|
58
|
+
),
|
|
59
|
+
EventHandlerMapping(
|
|
60
|
+
name="successful_stop_event",
|
|
61
|
+
event=events.robot_service_events.mission_successfully_stopped,
|
|
62
|
+
handler=_successful_stop_event_handler,
|
|
63
|
+
),
|
|
64
|
+
]
|
|
65
|
+
super().__init__(
|
|
66
|
+
state_name="stopping",
|
|
67
|
+
state_machine=state_machine,
|
|
68
|
+
event_handler_mappings=event_handlers,
|
|
69
|
+
)
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, Callable, List, Optional
|
|
2
|
+
|
|
3
|
+
from isar.apis.models.models import MaintenanceResponse
|
|
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
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from isar.state_machine.state_machine import StateMachine
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class StoppingDueToMaintenance(EventHandlerBase):
|
|
13
|
+
|
|
14
|
+
def __init__(self, state_machine: "StateMachine"):
|
|
15
|
+
events = state_machine.events
|
|
16
|
+
|
|
17
|
+
def _failed_stop_event_handler(
|
|
18
|
+
event: Event[ErrorMessage],
|
|
19
|
+
) -> Optional[Callable]:
|
|
20
|
+
error_message: Optional[ErrorMessage] = event.consume_event()
|
|
21
|
+
if error_message is not None:
|
|
22
|
+
events.api_requests.set_maintenance_mode.response.trigger_event(
|
|
23
|
+
MaintenanceResponse(
|
|
24
|
+
is_maintenance_mode=False,
|
|
25
|
+
failure_reason="Failed to stop ongoing mission",
|
|
26
|
+
)
|
|
27
|
+
)
|
|
28
|
+
state_machine.logger.error(
|
|
29
|
+
f"Failed to stop mission in StoppingDueToMaintenance. Message: {error_message.error_description}"
|
|
30
|
+
)
|
|
31
|
+
return state_machine.mission_stopping_failed # type: ignore
|
|
32
|
+
return None
|
|
33
|
+
|
|
34
|
+
def _successful_stop_event_handler(event: Event[bool]) -> Optional[Callable]:
|
|
35
|
+
if event.consume_event():
|
|
36
|
+
state_machine.publish_mission_aborted(
|
|
37
|
+
"Mission aborted, robot being sent to maintenance", True
|
|
38
|
+
)
|
|
39
|
+
events.api_requests.set_maintenance_mode.response.trigger_event(
|
|
40
|
+
MaintenanceResponse(is_maintenance_mode=True)
|
|
41
|
+
)
|
|
42
|
+
return state_machine.mission_stopped # type: ignore
|
|
43
|
+
return None
|
|
44
|
+
|
|
45
|
+
event_handlers: List[EventHandlerMapping] = [
|
|
46
|
+
EventHandlerMapping(
|
|
47
|
+
name="failed_stop_event",
|
|
48
|
+
event=events.robot_service_events.mission_failed_to_stop,
|
|
49
|
+
handler=_failed_stop_event_handler,
|
|
50
|
+
),
|
|
51
|
+
EventHandlerMapping(
|
|
52
|
+
name="successful_stop_event",
|
|
53
|
+
event=events.robot_service_events.mission_successfully_stopped,
|
|
54
|
+
handler=_successful_stop_event_handler,
|
|
55
|
+
),
|
|
56
|
+
]
|
|
57
|
+
super().__init__(
|
|
58
|
+
state_name="stopping_due_to_maintenance",
|
|
59
|
+
state_machine=state_machine,
|
|
60
|
+
event_handler_mappings=event_handlers,
|
|
61
|
+
)
|
|
@@ -0,0 +1,60 @@
|
|
|
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
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from isar.state_machine.state_machine import StateMachine
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class StoppingGoToLockdown(EventHandlerBase):
|
|
13
|
+
|
|
14
|
+
def __init__(self, state_machine: "StateMachine"):
|
|
15
|
+
events = state_machine.events
|
|
16
|
+
|
|
17
|
+
def _failed_stop_event_handler(
|
|
18
|
+
event: Event[ErrorMessage],
|
|
19
|
+
) -> Optional[Callable]:
|
|
20
|
+
error_message: Optional[ErrorMessage] = event.consume_event()
|
|
21
|
+
if error_message is None:
|
|
22
|
+
return None
|
|
23
|
+
|
|
24
|
+
events.api_requests.send_to_lockdown.response.trigger_event(
|
|
25
|
+
LockdownResponse(
|
|
26
|
+
lockdown_started=False,
|
|
27
|
+
failure_reason="Failed to stop ongoing mission",
|
|
28
|
+
)
|
|
29
|
+
)
|
|
30
|
+
return state_machine.mission_stopping_failed # type: ignore
|
|
31
|
+
|
|
32
|
+
def _successful_stop_event_handler(event: Event[bool]) -> Optional[Callable]:
|
|
33
|
+
if not event.consume_event():
|
|
34
|
+
return None
|
|
35
|
+
|
|
36
|
+
state_machine.publish_mission_aborted("Robot being sent to lockdown", True)
|
|
37
|
+
|
|
38
|
+
events.api_requests.send_to_lockdown.response.trigger_event(
|
|
39
|
+
LockdownResponse(lockdown_started=True)
|
|
40
|
+
)
|
|
41
|
+
state_machine.start_return_home_mission()
|
|
42
|
+
return state_machine.start_lockdown_mission_monitoring # type: ignore
|
|
43
|
+
|
|
44
|
+
event_handlers: List[EventHandlerMapping] = [
|
|
45
|
+
EventHandlerMapping(
|
|
46
|
+
name="failed_stop_event",
|
|
47
|
+
event=events.robot_service_events.mission_failed_to_stop,
|
|
48
|
+
handler=_failed_stop_event_handler,
|
|
49
|
+
),
|
|
50
|
+
EventHandlerMapping(
|
|
51
|
+
name="successful_stop_event",
|
|
52
|
+
event=events.robot_service_events.mission_successfully_stopped,
|
|
53
|
+
handler=_successful_stop_event_handler,
|
|
54
|
+
),
|
|
55
|
+
]
|
|
56
|
+
super().__init__(
|
|
57
|
+
state_name="stopping_go_to_lockdown",
|
|
58
|
+
state_machine=state_machine,
|
|
59
|
+
event_handler_mappings=event_handlers,
|
|
60
|
+
)
|
|
@@ -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
|
+
state_machine.start_return_home_mission()
|
|
33
|
+
return state_machine.start_recharging_mission_monitoring # 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
|
+
)
|
|
@@ -0,0 +1,36 @@
|
|
|
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
|
+
failed_stop_event_handler,
|
|
6
|
+
successful_stop_event_handler,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from isar.state_machine.state_machine import StateMachine
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class StoppingPausedMission(EventHandlerBase):
|
|
14
|
+
|
|
15
|
+
def __init__(self, state_machine: "StateMachine"):
|
|
16
|
+
events = state_machine.events
|
|
17
|
+
|
|
18
|
+
event_handlers: List[EventHandlerMapping] = [
|
|
19
|
+
EventHandlerMapping(
|
|
20
|
+
name="failed_stop_event",
|
|
21
|
+
event=events.robot_service_events.mission_failed_to_stop,
|
|
22
|
+
handler=lambda event: failed_stop_event_handler(state_machine, event),
|
|
23
|
+
),
|
|
24
|
+
EventHandlerMapping(
|
|
25
|
+
name="successful_stop_event",
|
|
26
|
+
event=events.robot_service_events.mission_successfully_stopped,
|
|
27
|
+
handler=lambda event: successful_stop_event_handler(
|
|
28
|
+
state_machine, event
|
|
29
|
+
),
|
|
30
|
+
),
|
|
31
|
+
]
|
|
32
|
+
super().__init__(
|
|
33
|
+
state_name="stopping_paused_mission",
|
|
34
|
+
state_machine=state_machine,
|
|
35
|
+
event_handler_mappings=event_handlers,
|
|
36
|
+
)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, List, Optional
|
|
2
|
+
|
|
3
|
+
from isar.apis.models.models import MissionStartResponse
|
|
4
|
+
from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
|
|
5
|
+
from isar.state_machine.utils.common_event_handlers import (
|
|
6
|
+
failed_stop_return_home_event_handler,
|
|
7
|
+
successful_stop_return_home_event_handler,
|
|
8
|
+
)
|
|
9
|
+
from robot_interface.models.mission.mission import Mission
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from isar.state_machine.state_machine import StateMachine
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class StoppingPausedReturnHome(EventHandlerBase):
|
|
16
|
+
|
|
17
|
+
def __init__(self, state_machine: "StateMachine"):
|
|
18
|
+
events = state_machine.events
|
|
19
|
+
self.mission: Optional[Mission] = None
|
|
20
|
+
|
|
21
|
+
def _respond_to_start_mission_request():
|
|
22
|
+
self.mission = (
|
|
23
|
+
state_machine.events.api_requests.start_mission.request.consume_event()
|
|
24
|
+
)
|
|
25
|
+
if not self.mission:
|
|
26
|
+
state_machine.logger.error(
|
|
27
|
+
"Reached stopping paused return home without a mission request"
|
|
28
|
+
)
|
|
29
|
+
else:
|
|
30
|
+
response = MissionStartResponse(
|
|
31
|
+
mission_id=self.mission.id,
|
|
32
|
+
mission_started=True,
|
|
33
|
+
)
|
|
34
|
+
state_machine.events.api_requests.start_mission.response.trigger_event(
|
|
35
|
+
response
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
event_handlers: List[EventHandlerMapping] = [
|
|
39
|
+
EventHandlerMapping(
|
|
40
|
+
name="failed_stop_event",
|
|
41
|
+
event=events.robot_service_events.mission_failed_to_stop,
|
|
42
|
+
handler=lambda event: failed_stop_return_home_event_handler(
|
|
43
|
+
state_machine, event
|
|
44
|
+
),
|
|
45
|
+
),
|
|
46
|
+
EventHandlerMapping(
|
|
47
|
+
name="successful_stop_event",
|
|
48
|
+
event=events.robot_service_events.mission_successfully_stopped,
|
|
49
|
+
handler=lambda event: successful_stop_return_home_event_handler(
|
|
50
|
+
state_machine, event, self.mission
|
|
51
|
+
),
|
|
52
|
+
),
|
|
53
|
+
]
|
|
54
|
+
super().__init__(
|
|
55
|
+
state_name="stopping_paused_return_home",
|
|
56
|
+
state_machine=state_machine,
|
|
57
|
+
event_handler_mappings=event_handlers,
|
|
58
|
+
on_entry=_respond_to_start_mission_request,
|
|
59
|
+
)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, List, Optional
|
|
2
|
+
|
|
3
|
+
from isar.apis.models.models import MissionStartResponse
|
|
4
|
+
from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
|
|
5
|
+
from isar.state_machine.utils.common_event_handlers import (
|
|
6
|
+
failed_stop_return_home_event_handler,
|
|
7
|
+
successful_stop_return_home_event_handler,
|
|
8
|
+
)
|
|
9
|
+
from robot_interface.models.mission.mission import Mission
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from isar.state_machine.state_machine import StateMachine
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class StoppingReturnHome(EventHandlerBase):
|
|
16
|
+
|
|
17
|
+
def __init__(self, state_machine: "StateMachine"):
|
|
18
|
+
events = state_machine.events
|
|
19
|
+
self.mission: Optional[Mission] = None
|
|
20
|
+
|
|
21
|
+
def _respond_to_start_mission_request():
|
|
22
|
+
self.mission = (
|
|
23
|
+
state_machine.events.api_requests.start_mission.request.consume_event()
|
|
24
|
+
)
|
|
25
|
+
if not self.mission:
|
|
26
|
+
state_machine.logger.error(
|
|
27
|
+
"Reached stopping return home without a mission request"
|
|
28
|
+
)
|
|
29
|
+
else:
|
|
30
|
+
response = MissionStartResponse(
|
|
31
|
+
mission_id=self.mission.id,
|
|
32
|
+
mission_started=True,
|
|
33
|
+
)
|
|
34
|
+
state_machine.events.api_requests.start_mission.response.trigger_event(
|
|
35
|
+
response
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
event_handlers: List[EventHandlerMapping] = [
|
|
39
|
+
EventHandlerMapping(
|
|
40
|
+
name="failed_stop_event",
|
|
41
|
+
event=events.robot_service_events.mission_failed_to_stop,
|
|
42
|
+
handler=lambda event: failed_stop_return_home_event_handler(
|
|
43
|
+
state_machine, event
|
|
44
|
+
),
|
|
45
|
+
),
|
|
46
|
+
EventHandlerMapping(
|
|
47
|
+
name="successful_stop_event",
|
|
48
|
+
event=events.robot_service_events.mission_successfully_stopped,
|
|
49
|
+
handler=lambda event: successful_stop_return_home_event_handler(
|
|
50
|
+
state_machine, event, self.mission
|
|
51
|
+
),
|
|
52
|
+
),
|
|
53
|
+
]
|
|
54
|
+
super().__init__(
|
|
55
|
+
state_name="stopping_return_home",
|
|
56
|
+
state_machine=state_machine,
|
|
57
|
+
event_handler_mappings=event_handlers,
|
|
58
|
+
on_entry=_respond_to_start_mission_request,
|
|
59
|
+
)
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, Callable, List, Optional
|
|
2
|
+
|
|
3
|
+
from isar.apis.models.models import MaintenanceResponse
|
|
4
|
+
from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
|
|
5
|
+
from isar.models.events import Event
|
|
6
|
+
from isar.state_machine.utils.common_event_handlers import stop_mission_event_handler
|
|
7
|
+
from robot_interface.models.mission.status import RobotStatus
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from isar.state_machine.state_machine import StateMachine
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class UnknownStatus(EventHandlerBase):
|
|
14
|
+
|
|
15
|
+
def __init__(self, state_machine: "StateMachine"):
|
|
16
|
+
events = state_machine.events
|
|
17
|
+
shared_state = state_machine.shared_state
|
|
18
|
+
|
|
19
|
+
def _set_maintenance_mode_event_handler(event: Event[bool]):
|
|
20
|
+
should_set_maintenande_mode: bool = event.consume_event()
|
|
21
|
+
if should_set_maintenande_mode:
|
|
22
|
+
events.api_requests.set_maintenance_mode.response.trigger_event(
|
|
23
|
+
MaintenanceResponse(is_maintenance_mode=True)
|
|
24
|
+
)
|
|
25
|
+
return state_machine.set_maintenance_mode # type: ignore
|
|
26
|
+
return None
|
|
27
|
+
|
|
28
|
+
def _robot_status_event_handler(
|
|
29
|
+
status_changed_event: Event[bool],
|
|
30
|
+
) -> Optional[Callable]:
|
|
31
|
+
has_changed = status_changed_event.consume_event()
|
|
32
|
+
if not has_changed:
|
|
33
|
+
return None
|
|
34
|
+
robot_status: Optional[RobotStatus] = shared_state.robot_status.check()
|
|
35
|
+
|
|
36
|
+
if robot_status == RobotStatus.Home:
|
|
37
|
+
return state_machine.robot_status_home # type: ignore
|
|
38
|
+
elif robot_status == RobotStatus.Available:
|
|
39
|
+
return state_machine.robot_status_available # type: ignore
|
|
40
|
+
elif robot_status == RobotStatus.Offline:
|
|
41
|
+
return state_machine.robot_status_offline # type: ignore
|
|
42
|
+
elif robot_status == RobotStatus.BlockedProtectiveStop:
|
|
43
|
+
return state_machine.robot_status_blocked_protective_stop # type: ignore
|
|
44
|
+
elif robot_status == RobotStatus.Busy:
|
|
45
|
+
return state_machine.robot_status_busy # type: ignore
|
|
46
|
+
return None
|
|
47
|
+
|
|
48
|
+
def _reset_status_check():
|
|
49
|
+
# Ensures that we will check the status immediately instead of waiting for it to change
|
|
50
|
+
self.events.robot_service_events.robot_status_changed.trigger_event(True)
|
|
51
|
+
|
|
52
|
+
event_handlers: List[EventHandlerMapping] = [
|
|
53
|
+
EventHandlerMapping(
|
|
54
|
+
name="stop_mission_event",
|
|
55
|
+
event=events.api_requests.stop_mission.request,
|
|
56
|
+
handler=lambda event: stop_mission_event_handler(state_machine, event),
|
|
57
|
+
),
|
|
58
|
+
EventHandlerMapping(
|
|
59
|
+
name="robot_status_event",
|
|
60
|
+
event=events.robot_service_events.robot_status_changed,
|
|
61
|
+
handler=_robot_status_event_handler,
|
|
62
|
+
),
|
|
63
|
+
EventHandlerMapping(
|
|
64
|
+
name="set_maintenance_mode",
|
|
65
|
+
event=events.api_requests.set_maintenance_mode.request,
|
|
66
|
+
handler=_set_maintenance_mode_event_handler,
|
|
67
|
+
),
|
|
68
|
+
]
|
|
69
|
+
super().__init__(
|
|
70
|
+
state_name="unknown_status",
|
|
71
|
+
state_machine=state_machine,
|
|
72
|
+
event_handler_mappings=event_handlers,
|
|
73
|
+
on_entry=_reset_status_check,
|
|
74
|
+
)
|
|
@@ -2,14 +2,32 @@ from enum import Enum
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
class States(str, Enum):
|
|
5
|
-
Off = "off"
|
|
6
|
-
Idle = "idle"
|
|
7
|
-
Initiate = "initiate"
|
|
8
|
-
Initialize = "initialize"
|
|
9
5
|
Monitor = "monitor"
|
|
6
|
+
ReturningHome = "returning_home"
|
|
7
|
+
Stopping = "stopping"
|
|
8
|
+
StoppingReturnHome = "stopping_return_home"
|
|
10
9
|
Paused = "paused"
|
|
11
|
-
|
|
10
|
+
Pausing = "pausing"
|
|
11
|
+
Resuming = "resuming"
|
|
12
|
+
PausingReturnHome = "pausing_return_home"
|
|
13
|
+
ResumingReturnHome = "resuming_return_home"
|
|
14
|
+
ReturnHomePaused = "return_home_paused"
|
|
15
|
+
AwaitNextMission = "await_next_mission"
|
|
16
|
+
Home = "home"
|
|
12
17
|
Offline = "offline"
|
|
18
|
+
BlockedProtectiveStop = "blocked_protective_stop"
|
|
19
|
+
UnknownStatus = "unknown_status"
|
|
20
|
+
InterventionNeeded = "intervention_needed"
|
|
21
|
+
Recharging = "recharging"
|
|
22
|
+
StoppingGoToLockdown = "stopping_go_to_lockdown"
|
|
23
|
+
GoingToLockdown = "going_to_lockdown"
|
|
24
|
+
Lockdown = "lockdown"
|
|
25
|
+
GoingToRecharging = "going_to_recharging"
|
|
26
|
+
StoppingGoToRecharge = "stopping_go_to_recharge"
|
|
27
|
+
Maintenance = "maintenance"
|
|
28
|
+
StoppingDueToMaintenance = "stopping_due_to_maintenance"
|
|
29
|
+
StoppingPausedMission = "stopping_paused_mission"
|
|
30
|
+
StoppingPausedReturnHome = "stopping_paused_return_home"
|
|
13
31
|
|
|
14
32
|
def __repr__(self):
|
|
15
33
|
return self.value
|