isar 1.33.6__py3-none-any.whl → 1.33.7__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/config/settings.py +4 -0
- isar/models/events.py +2 -0
- isar/robot/robot.py +18 -1
- isar/robot/robot_battery.py +60 -0
- isar/robot/robot_status.py +23 -10
- isar/state_machine/states/blocked_protective_stop.py +9 -9
- isar/state_machine/states/home.py +21 -13
- isar/state_machine/states/offline.py +9 -10
- isar/state_machine/transitions/functions/robot_status.py +15 -0
- isar/state_machine/transitions/return_home.py +9 -0
- isar/state_machine/utils/common_event_handlers.py +5 -2
- {isar-1.33.6.dist-info → isar-1.33.7.dist-info}/METADATA +1 -1
- {isar-1.33.6.dist-info → isar-1.33.7.dist-info}/RECORD +17 -16
- {isar-1.33.6.dist-info → isar-1.33.7.dist-info}/WHEEL +0 -0
- {isar-1.33.6.dist-info → isar-1.33.7.dist-info}/entry_points.txt +0 -0
- {isar-1.33.6.dist-info → isar-1.33.7.dist-info}/licenses/LICENSE +0 -0
- {isar-1.33.6.dist-info → isar-1.33.7.dist-info}/top_level.txt +0 -0
isar/config/settings.py
CHANGED
|
@@ -59,6 +59,9 @@ class Settings(BaseSettings):
|
|
|
59
59
|
# issues
|
|
60
60
|
REQUEST_STATUS_COMMUNICATION_RECONNECT_DELAY: float = Field(default=10)
|
|
61
61
|
|
|
62
|
+
# Time allowed to clear the robot status before giving up
|
|
63
|
+
CLEAR_ROBOT_STATUS_TIMEOUT: int = Field(default=3)
|
|
64
|
+
|
|
62
65
|
# Number of attempts for state transitions resume and pause if failed
|
|
63
66
|
STATE_TRANSITION_NUM_RETIRES: int = Field(default=10)
|
|
64
67
|
|
|
@@ -78,6 +81,7 @@ class Settings(BaseSettings):
|
|
|
78
81
|
ROBOT_STATUS_PUBLISH_INTERVAL: float = Field(default=1)
|
|
79
82
|
ROBOT_HEARTBEAT_PUBLISH_INTERVAL: float = Field(default=1)
|
|
80
83
|
ROBOT_INFO_PUBLISH_INTERVAL: float = Field(default=5)
|
|
84
|
+
ROBOT_API_BATTERY_POLL_INTERVAL: float = Field(default=5)
|
|
81
85
|
ROBOT_API_STATUS_POLL_INTERVAL: float = Field(default=5)
|
|
82
86
|
THREAD_CHECK_INTERVAL: float = Field(default=0.01)
|
|
83
87
|
|
isar/models/events.py
CHANGED
|
@@ -123,6 +123,7 @@ class StateMachineEvents:
|
|
|
123
123
|
self.stop_mission: Event[bool] = Event("stop_mission")
|
|
124
124
|
self.pause_mission: Event[bool] = Event("pause_mission")
|
|
125
125
|
self.task_status_request: Event[str] = Event("task_status_request")
|
|
126
|
+
self.clear_robot_status: Event[bool] = Event("clear_robot_status")
|
|
126
127
|
|
|
127
128
|
|
|
128
129
|
class RobotServiceEvents:
|
|
@@ -132,6 +133,7 @@ class RobotServiceEvents:
|
|
|
132
133
|
self.mission_started: Event[bool] = Event("mission_started")
|
|
133
134
|
self.mission_failed: Event[ErrorMessage] = Event("mission_failed")
|
|
134
135
|
self.robot_status_changed: Event[bool] = Event("robot_status_changed")
|
|
136
|
+
self.robot_status_cleared: Event[bool] = Event("robot_status_cleared")
|
|
135
137
|
self.mission_failed_to_stop: Event[ErrorMessage] = Event(
|
|
136
138
|
"mission_failed_to_stop"
|
|
137
139
|
)
|
isar/robot/robot.py
CHANGED
|
@@ -9,6 +9,7 @@ from isar.models.events import (
|
|
|
9
9
|
SharedState,
|
|
10
10
|
StateMachineEvents,
|
|
11
11
|
)
|
|
12
|
+
from isar.robot.robot_battery import RobotBatteryThread
|
|
12
13
|
from isar.robot.robot_pause_mission import RobotPauseMissionThread
|
|
13
14
|
from isar.robot.robot_start_mission import RobotStartMissionThread
|
|
14
15
|
from isar.robot.robot_status import RobotStatusThread
|
|
@@ -29,6 +30,7 @@ class Robot(object):
|
|
|
29
30
|
self.shared_state: SharedState = shared_state
|
|
30
31
|
self.robot: RobotInterface = robot
|
|
31
32
|
self.start_mission_thread: Optional[RobotStartMissionThread] = None
|
|
33
|
+
self.robot_battery_thread: Optional[RobotBatteryThread] = None
|
|
32
34
|
self.robot_status_thread: Optional[RobotStatusThread] = None
|
|
33
35
|
self.robot_task_status_thread: Optional[RobotTaskStatusThread] = None
|
|
34
36
|
self.stop_mission_thread: Optional[RobotStopMissionThread] = None
|
|
@@ -39,6 +41,11 @@ class Robot(object):
|
|
|
39
41
|
self.signal_thread_quitting.set()
|
|
40
42
|
if self.robot_status_thread is not None and self.robot_status_thread.is_alive():
|
|
41
43
|
self.robot_status_thread.join()
|
|
44
|
+
if (
|
|
45
|
+
self.robot_battery_thread is not None
|
|
46
|
+
and self.robot_battery_thread.is_alive()
|
|
47
|
+
):
|
|
48
|
+
self.robot_battery_thread.join()
|
|
42
49
|
if (
|
|
43
50
|
self.robot_task_status_thread is not None
|
|
44
51
|
and self.robot_task_status_thread.is_alive()
|
|
@@ -52,6 +59,7 @@ class Robot(object):
|
|
|
52
59
|
if self.stop_mission_thread is not None and self.stop_mission_thread.is_alive():
|
|
53
60
|
self.stop_mission_thread.join()
|
|
54
61
|
self.robot_status_thread = None
|
|
62
|
+
self.robot_battery_thread = None
|
|
55
63
|
self.robot_task_status_thread = None
|
|
56
64
|
self.start_mission_thread = None
|
|
57
65
|
|
|
@@ -143,10 +151,19 @@ class Robot(object):
|
|
|
143
151
|
|
|
144
152
|
def run(self) -> None:
|
|
145
153
|
self.robot_status_thread = RobotStatusThread(
|
|
146
|
-
self.robot,
|
|
154
|
+
robot=self.robot,
|
|
155
|
+
signal_thread_quitting=self.signal_thread_quitting,
|
|
156
|
+
shared_state=self.shared_state,
|
|
157
|
+
state_machine_events=self.state_machine_events,
|
|
158
|
+
robot_service_events=self.robot_service_events,
|
|
147
159
|
)
|
|
148
160
|
self.robot_status_thread.start()
|
|
149
161
|
|
|
162
|
+
self.robot_battery_thread = RobotBatteryThread(
|
|
163
|
+
self.robot, self.signal_thread_quitting, self.shared_state
|
|
164
|
+
)
|
|
165
|
+
self.robot_battery_thread.start()
|
|
166
|
+
|
|
150
167
|
while not self.signal_thread_quitting.wait(0):
|
|
151
168
|
self._start_mission_event_handler(self.state_machine_events.start_mission)
|
|
152
169
|
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import time
|
|
3
|
+
from threading import Event, Thread
|
|
4
|
+
|
|
5
|
+
from isar.config.settings import settings
|
|
6
|
+
from isar.models.events import SharedState
|
|
7
|
+
from robot_interface.models.exceptions.robot_exceptions import RobotException
|
|
8
|
+
from robot_interface.robot_interface import RobotInterface
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class RobotBatteryThread(Thread):
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
robot: RobotInterface,
|
|
15
|
+
signal_thread_quitting: Event,
|
|
16
|
+
shared_state: SharedState,
|
|
17
|
+
):
|
|
18
|
+
self.logger = logging.getLogger("robot")
|
|
19
|
+
self.shared_state: SharedState = shared_state
|
|
20
|
+
self.robot: RobotInterface = robot
|
|
21
|
+
self.signal_thread_quitting: Event = signal_thread_quitting
|
|
22
|
+
self.last_robot_battery_poll_time: float = time.time()
|
|
23
|
+
self.force_battery_poll_next_iteration: bool = True
|
|
24
|
+
Thread.__init__(self, name="Robot battery thread")
|
|
25
|
+
|
|
26
|
+
def stop(self) -> None:
|
|
27
|
+
return
|
|
28
|
+
|
|
29
|
+
def _is_ready_to_poll_for_battery(self) -> bool:
|
|
30
|
+
if self.force_battery_poll_next_iteration:
|
|
31
|
+
self.force_battery_poll_next_iteration = False
|
|
32
|
+
return True
|
|
33
|
+
|
|
34
|
+
time_since_last_robot_battery_poll = (
|
|
35
|
+
time.time() - self.last_robot_battery_poll_time
|
|
36
|
+
)
|
|
37
|
+
return (
|
|
38
|
+
time_since_last_robot_battery_poll
|
|
39
|
+
> settings.ROBOT_API_BATTERY_POLL_INTERVAL
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
def run(self):
|
|
43
|
+
if self.signal_thread_quitting.is_set():
|
|
44
|
+
return
|
|
45
|
+
|
|
46
|
+
thread_check_interval = settings.THREAD_CHECK_INTERVAL
|
|
47
|
+
|
|
48
|
+
while not self.signal_thread_quitting.wait(thread_check_interval):
|
|
49
|
+
if not self._is_ready_to_poll_for_battery():
|
|
50
|
+
continue
|
|
51
|
+
try:
|
|
52
|
+
self.last_robot_battery_poll_time = time.time()
|
|
53
|
+
|
|
54
|
+
robot_battery_level = self.robot.get_battery_level()
|
|
55
|
+
|
|
56
|
+
self.shared_state.robot_battery_level.update(robot_battery_level)
|
|
57
|
+
except RobotException as e:
|
|
58
|
+
self.logger.error(f"Failed to retrieve robot battery level: {e}")
|
|
59
|
+
continue
|
|
60
|
+
self.logger.info("Exiting robot battery thread")
|
isar/robot/robot_status.py
CHANGED
|
@@ -3,7 +3,7 @@ import time
|
|
|
3
3
|
from threading import Event, Thread
|
|
4
4
|
|
|
5
5
|
from isar.config.settings import settings
|
|
6
|
-
from isar.models.events import SharedState
|
|
6
|
+
from isar.models.events import RobotServiceEvents, SharedState, StateMachineEvents
|
|
7
7
|
from robot_interface.models.exceptions.robot_exceptions import RobotException
|
|
8
8
|
from robot_interface.robot_interface import RobotInterface
|
|
9
9
|
|
|
@@ -14,26 +14,32 @@ class RobotStatusThread(Thread):
|
|
|
14
14
|
robot: RobotInterface,
|
|
15
15
|
signal_thread_quitting: Event,
|
|
16
16
|
shared_state: SharedState,
|
|
17
|
+
robot_service_events: RobotServiceEvents,
|
|
18
|
+
state_machine_events: StateMachineEvents,
|
|
17
19
|
):
|
|
18
20
|
self.logger = logging.getLogger("robot")
|
|
19
21
|
self.shared_state: SharedState = shared_state
|
|
22
|
+
self.robot_service_events: RobotServiceEvents = robot_service_events
|
|
23
|
+
self.state_machine_events: StateMachineEvents = state_machine_events
|
|
20
24
|
self.robot: RobotInterface = robot
|
|
21
25
|
self.signal_thread_quitting: Event = signal_thread_quitting
|
|
22
|
-
self.
|
|
23
|
-
|
|
24
|
-
|
|
26
|
+
self.robot_status_poll_interval: float = settings.ROBOT_API_STATUS_POLL_INTERVAL
|
|
27
|
+
self.last_robot_status_poll_time: float = time.time()
|
|
28
|
+
self.force_status_poll_next_iteration: bool = True
|
|
25
29
|
Thread.__init__(self, name="Robot status thread")
|
|
26
30
|
|
|
27
31
|
def stop(self) -> None:
|
|
28
32
|
return
|
|
29
33
|
|
|
30
34
|
def _is_ready_to_poll_for_status(self) -> bool:
|
|
35
|
+
if self.force_status_poll_next_iteration:
|
|
36
|
+
self.force_status_poll_next_iteration = False
|
|
37
|
+
return True
|
|
38
|
+
|
|
31
39
|
time_since_last_robot_status_poll = (
|
|
32
40
|
time.time() - self.last_robot_status_poll_time
|
|
33
41
|
)
|
|
34
|
-
return
|
|
35
|
-
time_since_last_robot_status_poll > settings.ROBOT_API_STATUS_POLL_INTERVAL
|
|
36
|
-
)
|
|
42
|
+
return time_since_last_robot_status_poll > self.robot_status_poll_interval
|
|
37
43
|
|
|
38
44
|
def run(self):
|
|
39
45
|
if self.signal_thread_quitting.is_set():
|
|
@@ -42,16 +48,23 @@ class RobotStatusThread(Thread):
|
|
|
42
48
|
thread_check_interval = settings.THREAD_CHECK_INTERVAL
|
|
43
49
|
|
|
44
50
|
while not self.signal_thread_quitting.wait(thread_check_interval):
|
|
51
|
+
if self.state_machine_events.clear_robot_status.consume_event() is not None:
|
|
52
|
+
self.shared_state.robot_status.clear_event()
|
|
53
|
+
self.robot_service_events.robot_status_changed.clear_event()
|
|
54
|
+
self.robot_service_events.robot_status_cleared.trigger_event(True)
|
|
55
|
+
self.force_status_poll_next_iteration = True
|
|
56
|
+
|
|
45
57
|
if not self._is_ready_to_poll_for_status():
|
|
46
58
|
continue
|
|
59
|
+
|
|
47
60
|
try:
|
|
48
61
|
self.last_robot_status_poll_time = time.time()
|
|
49
62
|
|
|
50
63
|
robot_status = self.robot.robot_status()
|
|
51
|
-
robot_battery_level = self.robot.get_battery_level()
|
|
52
64
|
|
|
53
|
-
self.shared_state.robot_status.
|
|
54
|
-
|
|
65
|
+
if robot_status is not self.shared_state.robot_status.check():
|
|
66
|
+
self.shared_state.robot_status.update(robot_status)
|
|
67
|
+
self.robot_service_events.robot_status_changed.trigger_event(True)
|
|
55
68
|
except RobotException as e:
|
|
56
69
|
self.logger.error(f"Failed to retrieve robot status: {e}")
|
|
57
70
|
continue
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from typing import TYPE_CHECKING, List
|
|
2
2
|
|
|
3
3
|
from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
|
|
4
|
-
from isar.
|
|
4
|
+
from isar.state_machine.utils.common_event_handlers import robot_status_event_handler
|
|
5
5
|
from robot_interface.models.mission.status import RobotStatus
|
|
6
6
|
|
|
7
7
|
if TYPE_CHECKING:
|
|
@@ -11,19 +11,19 @@ if TYPE_CHECKING:
|
|
|
11
11
|
class BlockedProtectiveStop(EventHandlerBase):
|
|
12
12
|
|
|
13
13
|
def __init__(self, state_machine: "StateMachine"):
|
|
14
|
+
events = state_machine.events
|
|
14
15
|
shared_state = state_machine.shared_state
|
|
15
16
|
|
|
16
|
-
def _robot_status_event_handler(event: Event[RobotStatus]):
|
|
17
|
-
robot_status: RobotStatus = event.check()
|
|
18
|
-
if robot_status != RobotStatus.BlockedProtectiveStop:
|
|
19
|
-
return state_machine.robot_status_changed # type: ignore
|
|
20
|
-
return None
|
|
21
|
-
|
|
22
17
|
event_handlers: List[EventHandlerMapping] = [
|
|
23
18
|
EventHandlerMapping(
|
|
24
19
|
name="robot_status_event",
|
|
25
|
-
event=
|
|
26
|
-
handler=
|
|
20
|
+
event=events.robot_service_events.robot_status_changed,
|
|
21
|
+
handler=lambda event: robot_status_event_handler(
|
|
22
|
+
state_machine=state_machine,
|
|
23
|
+
expected_status=RobotStatus.BlockedProtectiveStop,
|
|
24
|
+
status_changed_event=event,
|
|
25
|
+
status_event=shared_state.robot_status,
|
|
26
|
+
),
|
|
27
27
|
),
|
|
28
28
|
]
|
|
29
29
|
super().__init__(
|
|
@@ -20,17 +20,6 @@ class Home(EventHandlerBase):
|
|
|
20
20
|
events = state_machine.events
|
|
21
21
|
shared_state = state_machine.shared_state
|
|
22
22
|
|
|
23
|
-
def _robot_status_event_handler(
|
|
24
|
-
event: Event[RobotStatus],
|
|
25
|
-
) -> Optional[Callable]:
|
|
26
|
-
robot_status: RobotStatus = event.check()
|
|
27
|
-
if not (
|
|
28
|
-
robot_status == RobotStatus.Available
|
|
29
|
-
or robot_status == RobotStatus.Home
|
|
30
|
-
):
|
|
31
|
-
return state_machine.robot_status_changed # type: ignore
|
|
32
|
-
return None
|
|
33
|
-
|
|
34
23
|
def _send_to_lockdown_event_handler(event: Event[bool]):
|
|
35
24
|
should_send_robot_home: bool = event.consume_event()
|
|
36
25
|
if should_send_robot_home:
|
|
@@ -40,6 +29,21 @@ class Home(EventHandlerBase):
|
|
|
40
29
|
return state_machine.reached_lockdown # type: ignore
|
|
41
30
|
return None
|
|
42
31
|
|
|
32
|
+
def _robot_status_event_handler(
|
|
33
|
+
state_machine: "StateMachine",
|
|
34
|
+
status_changed_event: Event[bool],
|
|
35
|
+
status_event: Event[RobotStatus],
|
|
36
|
+
) -> Optional[Callable]:
|
|
37
|
+
if not status_changed_event.consume_event():
|
|
38
|
+
return None
|
|
39
|
+
robot_status: Optional[RobotStatus] = status_event.check()
|
|
40
|
+
if not (
|
|
41
|
+
robot_status == RobotStatus.Available
|
|
42
|
+
or robot_status == RobotStatus.Home
|
|
43
|
+
):
|
|
44
|
+
return state_machine.robot_status_changed # type: ignore
|
|
45
|
+
return None
|
|
46
|
+
|
|
43
47
|
event_handlers: List[EventHandlerMapping] = [
|
|
44
48
|
EventHandlerMapping(
|
|
45
49
|
name="start_mission_event",
|
|
@@ -60,8 +64,12 @@ class Home(EventHandlerBase):
|
|
|
60
64
|
),
|
|
61
65
|
EventHandlerMapping(
|
|
62
66
|
name="robot_status_event",
|
|
63
|
-
event=
|
|
64
|
-
handler=_robot_status_event_handler
|
|
67
|
+
event=events.robot_service_events.robot_status_changed,
|
|
68
|
+
handler=lambda event: _robot_status_event_handler(
|
|
69
|
+
state_machine=state_machine,
|
|
70
|
+
status_changed_event=event,
|
|
71
|
+
status_event=shared_state.robot_status,
|
|
72
|
+
),
|
|
65
73
|
),
|
|
66
74
|
EventHandlerMapping(
|
|
67
75
|
name="send_to_lockdown_event",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from typing import TYPE_CHECKING, List
|
|
2
2
|
|
|
3
3
|
from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
|
|
4
|
-
from isar.
|
|
4
|
+
from isar.state_machine.utils.common_event_handlers import robot_status_event_handler
|
|
5
5
|
from robot_interface.models.mission.status import RobotStatus
|
|
6
6
|
|
|
7
7
|
if TYPE_CHECKING:
|
|
@@ -11,20 +11,19 @@ if TYPE_CHECKING:
|
|
|
11
11
|
class Offline(EventHandlerBase):
|
|
12
12
|
|
|
13
13
|
def __init__(self, state_machine: "StateMachine"):
|
|
14
|
-
|
|
14
|
+
events = state_machine.events
|
|
15
15
|
shared_state = state_machine.shared_state
|
|
16
16
|
|
|
17
|
-
def _robot_status_event_handler(event: Event[RobotStatus]):
|
|
18
|
-
robot_status: RobotStatus = event.check()
|
|
19
|
-
if robot_status != RobotStatus.Offline:
|
|
20
|
-
return state_machine.robot_status_changed # type: ignore
|
|
21
|
-
return None
|
|
22
|
-
|
|
23
17
|
event_handlers: List[EventHandlerMapping] = [
|
|
24
18
|
EventHandlerMapping(
|
|
25
19
|
name="robot_status_event",
|
|
26
|
-
event=
|
|
27
|
-
handler=
|
|
20
|
+
event=events.robot_service_events.robot_status_changed,
|
|
21
|
+
handler=lambda event: robot_status_event_handler(
|
|
22
|
+
state_machine=state_machine,
|
|
23
|
+
expected_status=RobotStatus.Offline,
|
|
24
|
+
status_changed_event=event,
|
|
25
|
+
status_event=shared_state.robot_status,
|
|
26
|
+
),
|
|
28
27
|
),
|
|
29
28
|
]
|
|
30
29
|
super().__init__(
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import time
|
|
1
2
|
from typing import TYPE_CHECKING
|
|
2
3
|
|
|
4
|
+
from isar.config.settings import settings
|
|
3
5
|
from robot_interface.models.mission.status import RobotStatus
|
|
4
6
|
|
|
5
7
|
if TYPE_CHECKING:
|
|
@@ -19,3 +21,16 @@ def is_available_or_home(state_machine: "StateMachine") -> bool:
|
|
|
19
21
|
def is_blocked_protective_stop(state_machine: "StateMachine") -> bool:
|
|
20
22
|
robot_status = state_machine.shared_state.robot_status.check()
|
|
21
23
|
return robot_status == RobotStatus.BlockedProtectiveStop
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def clear_robot_status(state_machine: "StateMachine") -> bool:
|
|
27
|
+
state_machine.events.state_machine_events.clear_robot_status.trigger_event(True)
|
|
28
|
+
start_time: float = time.time()
|
|
29
|
+
while time.time() - start_time < settings.CLEAR_ROBOT_STATUS_TIMEOUT:
|
|
30
|
+
if (
|
|
31
|
+
state_machine.events.robot_service_events.robot_status_cleared.consume_event()
|
|
32
|
+
):
|
|
33
|
+
return True
|
|
34
|
+
time.sleep(settings.FSM_SLEEP_TIME)
|
|
35
|
+
state_machine.logger.error("Timed out waiting for robot status to be cleared")
|
|
36
|
+
return False
|
|
@@ -12,6 +12,7 @@ from isar.state_machine.transitions.functions.return_home import (
|
|
|
12
12
|
should_retry_return_home,
|
|
13
13
|
start_return_home_mission,
|
|
14
14
|
)
|
|
15
|
+
from isar.state_machine.transitions.functions.robot_status import clear_robot_status
|
|
15
16
|
from isar.state_machine.transitions.functions.start_mission import (
|
|
16
17
|
initialize_robot,
|
|
17
18
|
trigger_start_mission_event,
|
|
@@ -58,11 +59,19 @@ def get_return_home_transitions(state_machine: "StateMachine") -> List[dict]:
|
|
|
58
59
|
"trigger": "returned_home",
|
|
59
60
|
"source": state_machine.returning_home_state,
|
|
60
61
|
"dest": state_machine.home_state,
|
|
62
|
+
"conditions": [
|
|
63
|
+
def_transition(state_machine, clear_robot_status),
|
|
64
|
+
],
|
|
61
65
|
"before": [
|
|
62
66
|
def_transition(state_machine, reset_return_home_failure_counter),
|
|
63
67
|
def_transition(state_machine, return_home_finished),
|
|
64
68
|
],
|
|
65
69
|
},
|
|
70
|
+
{
|
|
71
|
+
"trigger": "returned_home",
|
|
72
|
+
"source": state_machine.returning_home_state,
|
|
73
|
+
"dest": state_machine.intervention_needed_state,
|
|
74
|
+
},
|
|
66
75
|
{
|
|
67
76
|
"trigger": "starting_recharging",
|
|
68
77
|
"source": state_machine.returning_home_state,
|
|
@@ -43,9 +43,12 @@ def return_home_event_handler(
|
|
|
43
43
|
def robot_status_event_handler(
|
|
44
44
|
state_machine: "StateMachine",
|
|
45
45
|
expected_status: RobotStatus,
|
|
46
|
-
|
|
46
|
+
status_changed_event: Event[bool],
|
|
47
|
+
status_event: Event[RobotStatus],
|
|
47
48
|
) -> Optional[Callable]:
|
|
48
|
-
|
|
49
|
+
if not status_changed_event.consume_event():
|
|
50
|
+
return None
|
|
51
|
+
robot_status: Optional[RobotStatus] = status_event.check()
|
|
49
52
|
if robot_status != expected_status:
|
|
50
53
|
return state_machine.robot_status_changed # type: ignore
|
|
51
54
|
return None
|
|
@@ -16,7 +16,7 @@ isar/config/configuration_error.py,sha256=rO6WOhafX6xvVib8WxV-eY483Z0PpN-9PxGsq5
|
|
|
16
16
|
isar/config/log.py,sha256=f_mLLz5RSa0kZkdpi1m0iMdwwDc4RQp12mnT6gu2exE,1303
|
|
17
17
|
isar/config/logging.conf,sha256=a7ZBvZkrMDaPU3eRGAjL_eZz6hZsa6BaRJOfx8mbnnM,629
|
|
18
18
|
isar/config/open_telemetry.py,sha256=Lgu0lbRQA-zz6ZDoBKKk0whQex5w18jl1wjqWzHUGdg,3634
|
|
19
|
-
isar/config/settings.py,sha256=
|
|
19
|
+
isar/config/settings.py,sha256=XMPU4d1V6FspjvMmto5TFmC8Slt8Nrpmn9n_tsyPTYk,14423
|
|
20
20
|
isar/config/certs/ca-cert.pem,sha256=qoNljfad_qcMxhXJIUMLd7nT-Qwf_d4dYSdoOFEOE8I,2179
|
|
21
21
|
isar/config/keyvault/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
22
|
isar/config/keyvault/keyvault_error.py,sha256=zvPCsZLjboxsxthYkxpRERCTFxYV8R5WmACewAUQLwk,41
|
|
@@ -42,11 +42,12 @@ 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=
|
|
46
|
-
isar/robot/robot.py,sha256=
|
|
45
|
+
isar/models/events.py,sha256=D3f5v0mmGlkIYT1ZSfSZILuMyVi4zDA-VxohuzRM6AA,5675
|
|
46
|
+
isar/robot/robot.py,sha256=sn-JfJE6lC6Auo13fdS556Uwq_xZE6VSrR4DhNcgOno,7560
|
|
47
|
+
isar/robot/robot_battery.py,sha256=goLdgmn61QCgE2Ja3YuiwE_sqJzIhCkS3u90sz1kdug,2089
|
|
47
48
|
isar/robot/robot_pause_mission.py,sha256=BFTLVFOnCeuLlyz1Lu12_6EgYBhk8frsviCs-kGq7AA,2277
|
|
48
49
|
isar/robot/robot_start_mission.py,sha256=RPYH9VtXDFdPqhOpt6kSbT17RHkJQPKkQ6d4784_pFE,3210
|
|
49
|
-
isar/robot/robot_status.py,sha256=
|
|
50
|
+
isar/robot/robot_status.py,sha256=8201XW9SmYFLVjys9zk972a8ge9aEgCsdm-V1S2VTjM,2924
|
|
50
51
|
isar/robot/robot_stop_mission.py,sha256=lKWY9LsBeeMsBZHJEN-Mfm2h3DYoBQT71TgEKlxw9ng,2269
|
|
51
52
|
isar/robot/robot_task_status.py,sha256=jefIDfrbly7vWZztWA2zLmK5Yz1NSEytw2YUmprccNA,3161
|
|
52
53
|
isar/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -67,13 +68,13 @@ isar/state_machine/state_machine.py,sha256=CUDTwPEOVpyV8up5bhVLKLkPDcc1mMx_Nchmq
|
|
|
67
68
|
isar/state_machine/states_enum.py,sha256=EzqLHsNbR7KBMIY5Fa_CDaHm9v6g8UFzq9DJs4x0OU8,746
|
|
68
69
|
isar/state_machine/states/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
69
70
|
isar/state_machine/states/await_next_mission.py,sha256=3_KrK7nWu1Dm-VA3Rt1gwVsUbn9WuB7MoqLCfobGJSM,2749
|
|
70
|
-
isar/state_machine/states/blocked_protective_stop.py,sha256=
|
|
71
|
+
isar/state_machine/states/blocked_protective_stop.py,sha256=HJr_jH8OdHMuX8zhjlF5jtNAfMCxkA1X7nOGmkAz-RY,1263
|
|
71
72
|
isar/state_machine/states/going_to_lockdown.py,sha256=RLMOH2lXiT3hQhfUtbBVAUfwKUd33yxbjq4uZDZ_Tkc,3388
|
|
72
|
-
isar/state_machine/states/home.py,sha256=
|
|
73
|
+
isar/state_machine/states/home.py,sha256=mCwXSb9LygNpY4qaKEkEYC3nP-6HdsSGmEyjsENumgM,3396
|
|
73
74
|
isar/state_machine/states/intervention_needed.py,sha256=A0QYz1vD1tDKAealihXDuoGuMLtXrRfn_AwFoaUhT_Q,1640
|
|
74
75
|
isar/state_machine/states/lockdown.py,sha256=mWjhjtky5GbW6BLjsi2TsS0LXI-yq7l29FaqZ2TbTek,1375
|
|
75
76
|
isar/state_machine/states/monitor.py,sha256=wmiJrbKntnNw9ExS6-VdJJuW2Q3Jzl9DozmZmEXJ0Cw,5285
|
|
76
|
-
isar/state_machine/states/offline.py,sha256=
|
|
77
|
+
isar/state_machine/states/offline.py,sha256=k1UdcRWLd6lJiL5cnpHKBkvMY4xZMt_x7XIauy-Rgww,1219
|
|
77
78
|
isar/state_machine/states/paused.py,sha256=1ADoTJ3b137k7dmZYxeyGVhyrRF8qotxoV1NaWCbBUk,2870
|
|
78
79
|
isar/state_machine/states/pausing.py,sha256=r0GywI1-JDOJLZEnxhnq_yFKza37eL45qHP0ir8SBsY,2762
|
|
79
80
|
isar/state_machine/states/pausing_return_home.py,sha256=USyBLWpJqrsJ2hsdyW6i-gvEsog2l7OMJLdgIj-hq0Y,2808
|
|
@@ -85,25 +86,25 @@ isar/state_machine/states/stopping_go_to_lockdown.py,sha256=npbz0aFbbCpsEbmBYc8w
|
|
|
85
86
|
isar/state_machine/states/stopping_return_home.py,sha256=ub952Ulas3a0lsV_dI4liBiInADo3zaPAGod2bPe_18,2985
|
|
86
87
|
isar/state_machine/states/unknown_status.py,sha256=Y-g9cgme5zriyZ6YUzFRYhOvv9ZylCSwfaY8MJ7xEJ0,1791
|
|
87
88
|
isar/state_machine/transitions/mission.py,sha256=lwXdC5Jn19gO-wrSaZp3_77mLnvj-CaBYZk61U-qgoo,8211
|
|
88
|
-
isar/state_machine/transitions/return_home.py,sha256=
|
|
89
|
+
isar/state_machine/transitions/return_home.py,sha256=ho4Nae-C5BaxVFciFL546EuoMSDIWLqT58E8bNraW4o,6749
|
|
89
90
|
isar/state_machine/transitions/robot_status.py,sha256=qJMurCpuficOiXs9us4lZJ5p_kOFSwKxJigiXfB1OS8,2430
|
|
90
91
|
isar/state_machine/transitions/functions/fail_mission.py,sha256=fBwLW22d8MyrH4047hb3eXn87yLq4v5SkLSIhV9Ge5k,947
|
|
91
92
|
isar/state_machine/transitions/functions/finish_mission.py,sha256=TRQrk7HdllmAkwsp25HRZAFAk46Y1hLx3jmkIAKrHDI,1442
|
|
92
93
|
isar/state_machine/transitions/functions/pause.py,sha256=QCIKTpB_CAkUVaSy02i2cpLJAWx3-qGN5RPbK9L2qPY,983
|
|
93
94
|
isar/state_machine/transitions/functions/resume.py,sha256=SAu4hWomPlrvO0lnpc6uM3rj79Bwq01acnaTEvNbO9U,2116
|
|
94
95
|
isar/state_machine/transitions/functions/return_home.py,sha256=5WPO40MtuRKm9-NtyrS6m0IVEit14MXfMKjgZ2sCXRU,1666
|
|
95
|
-
isar/state_machine/transitions/functions/robot_status.py,sha256=
|
|
96
|
+
isar/state_machine/transitions/functions/robot_status.py,sha256=bA8G5WtY7TA88MKpdOcR6qftFjW8OttntmptZDXpTKg,1365
|
|
96
97
|
isar/state_machine/transitions/functions/start_mission.py,sha256=tIpZzYXCoeC6ZWj18UB4DiZuICpxfzFUK23wfunad7Q,2864
|
|
97
98
|
isar/state_machine/transitions/functions/stop.py,sha256=4idsNh7v6CRJivD36oKnVmdKlP7mSugTLCh9n12R1-U,2114
|
|
98
99
|
isar/state_machine/transitions/functions/utils.py,sha256=Wa72Ocq4QT1E6qkpEJZQ3h5o33pGvx7Tlkt2JZ2Grbk,314
|
|
99
|
-
isar/state_machine/utils/common_event_handlers.py,sha256=
|
|
100
|
+
isar/state_machine/utils/common_event_handlers.py,sha256=LqXPB4qojzz0LqKF14g4pUd0HYBqZiCV83I4UMgy9DY,6450
|
|
100
101
|
isar/storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
101
102
|
isar/storage/blob_storage.py,sha256=d44z3XpZDUbiKwN8Av2gytTJxnefMXrp5VhiGm4PWxU,3703
|
|
102
103
|
isar/storage/local_storage.py,sha256=Rn-iiiz9DI7PzIhevOMshPIaqzJaqBXeVJMQRhVSl2M,2191
|
|
103
104
|
isar/storage/storage_interface.py,sha256=x-imVeQTdL6dCaTaPTHpXwCR6N4e27WxK_Vpumg0x-Y,1230
|
|
104
105
|
isar/storage/uploader.py,sha256=oaGhHqYrtyvJoFUuD7ZyBgdPNkYaSgQokQZkAjmd4vI,10702
|
|
105
106
|
isar/storage/utilities.py,sha256=oLH0Rp7UtrQQdilfITnmXO1Z0ExdeDhBImYHid55vBA,3449
|
|
106
|
-
isar-1.33.
|
|
107
|
+
isar-1.33.7.dist-info/licenses/LICENSE,sha256=3fc2-ebLwHWwzfQbulGNRdcNob3SBQeCfEVUDYxsuqw,14058
|
|
107
108
|
robot_interface/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
108
109
|
robot_interface/robot_interface.py,sha256=A6t19lcNU_6AfkYKY5DaF0sheym_SZEAawbfaj36Kjk,8997
|
|
109
110
|
robot_interface/test_robot_interface.py,sha256=FV1urn7SbsMyWBIcTKjsBwAG4IsXeZ6pLHE0mA9EGGs,692
|
|
@@ -127,8 +128,8 @@ robot_interface/telemetry/payloads.py,sha256=RfLlm_te-bV_xcLtbBx27bgE8gkwPAhWBTF
|
|
|
127
128
|
robot_interface/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
128
129
|
robot_interface/utilities/json_service.py,sha256=9N1zijW7K4d3WFR2autpaS8U9o1ibymiOX-6stTKCyk,1243
|
|
129
130
|
robot_interface/utilities/uuid_string_factory.py,sha256=_NQIbBQ56w0qqO0MUDP6aPpHbxW7ATRhK8HnQiBSLkc,76
|
|
130
|
-
isar-1.33.
|
|
131
|
-
isar-1.33.
|
|
132
|
-
isar-1.33.
|
|
133
|
-
isar-1.33.
|
|
134
|
-
isar-1.33.
|
|
131
|
+
isar-1.33.7.dist-info/METADATA,sha256=azNe_j08RzYztSEwtbNt_zov9uaQauwP34HW3NuZwF4,31190
|
|
132
|
+
isar-1.33.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
133
|
+
isar-1.33.7.dist-info/entry_points.txt,sha256=TFam7uNNw7J0iiDYzsH2gfG0u1eV1wh3JTw_HkhgKLk,49
|
|
134
|
+
isar-1.33.7.dist-info/top_level.txt,sha256=UwIML2RtuQKCyJJkatcSnyp6-ldDjboB9k9JgKipO-U,21
|
|
135
|
+
isar-1.33.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|