isar 1.31.0__py3-none-any.whl → 1.32.0__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.

Files changed (58) hide show
  1. isar/apis/api.py +18 -0
  2. isar/apis/schedule/scheduling_controller.py +16 -0
  3. isar/config/log.py +1 -2
  4. isar/config/logging.conf +9 -30
  5. isar/config/open_telemetry.py +2 -8
  6. isar/config/settings.py +4 -0
  7. isar/eventhandlers/eventhandler.py +93 -0
  8. isar/models/events.py +119 -0
  9. isar/modules.py +1 -1
  10. isar/robot/robot.py +16 -18
  11. isar/robot/robot_start_mission.py +8 -14
  12. isar/robot/robot_status.py +2 -3
  13. isar/robot/robot_stop_mission.py +3 -9
  14. isar/robot/robot_task_status.py +3 -7
  15. isar/script.py +9 -17
  16. isar/services/utilities/scheduling_utilities.py +45 -23
  17. isar/state_machine/state_machine.py +104 -9
  18. isar/state_machine/states/await_next_mission.py +46 -11
  19. isar/state_machine/states/blocked_protective_stop.py +24 -15
  20. isar/state_machine/states/home.py +40 -9
  21. isar/state_machine/states/intervention_needed.py +43 -0
  22. isar/state_machine/states/monitor.py +83 -12
  23. isar/state_machine/states/offline.py +25 -13
  24. isar/state_machine/states/paused.py +24 -38
  25. isar/state_machine/states/returning_home.py +75 -14
  26. isar/state_machine/states/robot_standing_still.py +41 -11
  27. isar/state_machine/states/stopping.py +52 -67
  28. isar/state_machine/states/unknown_status.py +37 -64
  29. isar/state_machine/states_enum.py +1 -0
  30. isar/state_machine/transitions/functions/fail_mission.py +7 -0
  31. isar/state_machine/transitions/functions/robot_status.py +4 -5
  32. isar/state_machine/transitions/functions/stop.py +3 -12
  33. isar/state_machine/transitions/mission.py +0 -6
  34. isar/state_machine/transitions/return_home.py +14 -2
  35. isar/state_machine/utils/common_event_handlers.py +166 -0
  36. isar/storage/uploader.py +1 -1
  37. {isar-1.31.0.dist-info → isar-1.32.0.dist-info}/METADATA +1 -1
  38. {isar-1.31.0.dist-info → isar-1.32.0.dist-info}/RECORD +44 -54
  39. robot_interface/models/mission/status.py +1 -0
  40. robot_interface/telemetry/payloads.py +8 -0
  41. isar/models/communication/__init__.py +0 -0
  42. isar/models/communication/message.py +0 -8
  43. isar/models/communication/queues/__init__.py +0 -0
  44. isar/models/communication/queues/events.py +0 -58
  45. isar/models/communication/queues/queue_io.py +0 -12
  46. isar/models/communication/queues/queue_timeout_error.py +0 -2
  47. isar/models/communication/queues/queue_utils.py +0 -38
  48. isar/models/communication/queues/status_queue.py +0 -22
  49. isar/models/mission_metadata/__init__.py +0 -0
  50. isar/services/service_connections/stid/__init__.py +0 -0
  51. isar/services/utilities/queue_utilities.py +0 -39
  52. isar/state_machine/generic_states/idle.py +0 -133
  53. isar/state_machine/generic_states/ongoing_mission.py +0 -309
  54. isar/state_machine/generic_states/robot_unavailable.py +0 -61
  55. {isar-1.31.0.dist-info → isar-1.32.0.dist-info}/WHEEL +0 -0
  56. {isar-1.31.0.dist-info → isar-1.32.0.dist-info}/entry_points.txt +0 -0
  57. {isar-1.31.0.dist-info → isar-1.32.0.dist-info}/licenses/LICENSE +0 -0
  58. {isar-1.31.0.dist-info → isar-1.32.0.dist-info}/top_level.txt +0 -0
@@ -2,6 +2,7 @@ from typing import TYPE_CHECKING, List
2
2
 
3
3
  from isar.state_machine.transitions.functions.fail_mission import (
4
4
  report_failed_mission_and_finalize,
5
+ report_failed_return_home_and_intervention_needed,
5
6
  )
6
7
  from isar.state_machine.transitions.functions.return_home import (
7
8
  return_home_finished,
@@ -26,6 +27,7 @@ def get_return_home_transitions(state_machine: "StateMachine") -> List[dict]:
26
27
  state_machine.await_next_mission_state,
27
28
  state_machine.home_state,
28
29
  state_machine.robot_standing_still_state,
30
+ state_machine.intervention_needed_state,
29
31
  ],
30
32
  "dest": state_machine.returning_home_state,
31
33
  "conditions": [
@@ -62,8 +64,18 @@ def get_return_home_transitions(state_machine: "StateMachine") -> List[dict]:
62
64
  {
63
65
  "trigger": "return_home_failed",
64
66
  "source": state_machine.returning_home_state,
65
- "dest": state_machine.robot_standing_still_state,
66
- "before": def_transition(state_machine, report_failed_mission_and_finalize),
67
+ "dest": state_machine.intervention_needed_state,
68
+ "before": [
69
+ def_transition(
70
+ state_machine, report_failed_return_home_and_intervention_needed
71
+ ),
72
+ def_transition(state_machine, report_failed_mission_and_finalize),
73
+ ],
74
+ },
75
+ {
76
+ "trigger": "release_intervention_needed",
77
+ "source": state_machine.intervention_needed_state,
78
+ "dest": state_machine.unknown_status_state,
67
79
  },
68
80
  ]
69
81
  return return_home_transitions
@@ -0,0 +1,166 @@
1
+ from typing import TYPE_CHECKING, Callable, Optional
2
+
3
+ from isar.apis.models.models import ControlMissionResponse
4
+ from isar.models.events import Event
5
+ from robot_interface.models.exceptions.robot_exceptions import ErrorMessage
6
+ from robot_interface.models.mission.mission import Mission
7
+ from robot_interface.models.mission.status import RobotStatus, TaskStatus
8
+
9
+ if TYPE_CHECKING:
10
+ from isar.state_machine.state_machine import StateMachine
11
+
12
+
13
+ def start_mission_event_handler(
14
+ state_machine: "StateMachine", event: Event[Mission]
15
+ ) -> Optional[Callable]:
16
+ mission: Optional[Mission] = event.consume_event()
17
+ if mission:
18
+ state_machine.start_mission(mission=mission)
19
+ return state_machine.request_mission_start # type: ignore
20
+ return None
21
+
22
+
23
+ def return_home_event_handler(
24
+ state_machine: "StateMachine", event: Event[bool]
25
+ ) -> Optional[Callable]:
26
+ if event.consume_event():
27
+ state_machine.events.api_requests.return_home.output.put(True)
28
+ return state_machine.request_return_home # type: ignore
29
+ return None
30
+
31
+
32
+ def robot_status_event_handler(
33
+ state_machine: "StateMachine",
34
+ expected_status: RobotStatus,
35
+ event: Event[RobotStatus],
36
+ ) -> Optional[Callable]:
37
+ robot_status: RobotStatus = event.check()
38
+ if robot_status != expected_status:
39
+ return state_machine.robot_status_changed # type: ignore
40
+ return None
41
+
42
+
43
+ def stop_mission_event_handler(
44
+ state_machine: "StateMachine", event: Event[str]
45
+ ) -> Optional[Callable]:
46
+ mission_id: str = event.consume_event()
47
+ if mission_id is not None:
48
+ if state_machine.current_mission.id == mission_id or mission_id == "":
49
+ return state_machine.stop # type: ignore
50
+ else:
51
+ state_machine.events.api_requests.stop_mission.output.put(
52
+ ControlMissionResponse(
53
+ mission_id=mission_id,
54
+ mission_status=state_machine.current_mission.status,
55
+ mission_not_found=True,
56
+ task_id=state_machine.current_task.id,
57
+ task_status=state_machine.current_task.status,
58
+ )
59
+ )
60
+ return None
61
+
62
+
63
+ def mission_started_event_handler(
64
+ state_machine: "StateMachine",
65
+ event: Event[bool],
66
+ ) -> Optional[Callable]:
67
+ if event.consume_event():
68
+ state_machine.mission_ongoing = True
69
+ return None
70
+
71
+
72
+ def mission_failed_event_handler(
73
+ state_machine: "StateMachine",
74
+ event: Event[Optional[ErrorMessage]],
75
+ ) -> Optional[Callable]:
76
+ mission_failed: Optional[ErrorMessage] = event.consume_event()
77
+ if mission_failed is not None:
78
+ state_machine.logger.warning(
79
+ f"Failed to initiate mission "
80
+ f"{str(state_machine.current_mission.id)[:8]} because: "
81
+ f"{mission_failed.error_description}"
82
+ )
83
+ state_machine.current_mission.error_message = ErrorMessage(
84
+ error_reason=mission_failed.error_reason,
85
+ error_description=mission_failed.error_description,
86
+ )
87
+ return state_machine.mission_failed_to_start # type: ignore
88
+ return None
89
+
90
+
91
+ def task_status_failed_event_handler(
92
+ state_machine: "StateMachine",
93
+ handle_task_completed: Callable[[TaskStatus], Callable],
94
+ event: Event[Optional[ErrorMessage]],
95
+ ) -> Optional[Callable]:
96
+ if not state_machine.mission_ongoing:
97
+ return None
98
+
99
+ task_failure: Optional[ErrorMessage] = event.consume_event()
100
+ if task_failure is not None:
101
+ if state_machine.current_task is None:
102
+ state_machine.logger.warning(
103
+ "Received task status failed event when no task was running"
104
+ )
105
+ return None
106
+ state_machine.awaiting_task_status = False
107
+ state_machine.current_task.error_message = task_failure
108
+ state_machine.logger.error(
109
+ f"Monitoring task {state_machine.current_task.id[:8]} failed "
110
+ f"because: {task_failure.error_description}"
111
+ )
112
+ return _handle_new_task_status(
113
+ state_machine, handle_task_completed, TaskStatus.Failed
114
+ )
115
+
116
+ elif (
117
+ not state_machine.awaiting_task_status
118
+ and state_machine.current_task is not None
119
+ ):
120
+ state_machine.events.state_machine_events.task_status_request.trigger_event(
121
+ state_machine.current_task.id,
122
+ )
123
+ state_machine.awaiting_task_status = True
124
+ return None
125
+
126
+
127
+ def task_status_event_handler(
128
+ state_machine: "StateMachine",
129
+ handle_task_completed: Callable[[TaskStatus], Callable],
130
+ event: Event[Optional[TaskStatus]],
131
+ ) -> Optional[Callable]:
132
+ if not state_machine.mission_ongoing:
133
+ return None
134
+
135
+ status: Optional[TaskStatus] = event.consume_event()
136
+ if status is not None:
137
+ state_machine.awaiting_task_status = False
138
+ return _handle_new_task_status(state_machine, handle_task_completed, status)
139
+
140
+ elif (
141
+ not state_machine.awaiting_task_status
142
+ and state_machine.current_task is not None
143
+ ):
144
+ state_machine.events.state_machine_events.task_status_request.trigger_event(
145
+ state_machine.current_task.id,
146
+ )
147
+ state_machine.awaiting_task_status = True
148
+ return None
149
+
150
+
151
+ def _handle_new_task_status(
152
+ state_machine: "StateMachine",
153
+ handle_task_completed: Callable[[TaskStatus], Callable],
154
+ status: TaskStatus,
155
+ ) -> Optional[Callable]:
156
+ if state_machine.current_task is None:
157
+ state_machine.iterate_current_task()
158
+
159
+ state_machine.current_task.status = status
160
+
161
+ if state_machine.current_task.is_finished():
162
+ state_machine.report_task_status(state_machine.current_task)
163
+ state_machine.publish_task_status(task=state_machine.current_task)
164
+
165
+ return handle_task_completed(status)
166
+ return None
isar/storage/uploader.py CHANGED
@@ -7,7 +7,7 @@ from threading import Event
7
7
  from typing import List, Union
8
8
 
9
9
  from isar.config.settings import settings
10
- from isar.models.communication.queues.events import Events
10
+ from isar.models.events import Events
11
11
  from isar.storage.storage_interface import StorageException, StorageInterface
12
12
  from robot_interface.models.inspection.inspection import (
13
13
  Inspection,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: isar
3
- Version: 1.31.0
3
+ Version: 1.32.0
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
@@ -1,22 +1,22 @@
1
1
  isar/__init__.py,sha256=cH8p8bVveu3FUL6kBhldcSlLaoHgD82Kd0-SwSNfGXw,87
2
- isar/modules.py,sha256=QBB1pge1i17HVMLA5n-qd9K3APCrX9bFF2vlfjheOhU,4778
3
- isar/script.py,sha256=OC0O3y5HO5OAstg7g-tLKgF7mulKfglkpztDRk9PvT0,6159
2
+ isar/modules.py,sha256=1QdULg-9gV5Ds4pMV4IQTlImSgsVwqs-g15ifllF2kg,4757
3
+ isar/script.py,sha256=LCb7CHvNyZhQz1OaQ-BUX8w7RDmu975zA0kL6FPwfzk,5912
4
4
  isar/apis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- isar/apis/api.py,sha256=B0fVZPKtnvrxzk48xoazGPYsJVjjBH4IL6glDJ3PGWI,13328
5
+ isar/apis/api.py,sha256=VM_WBlHJ4Juv9A0FvaUTeaMVYCN6a7pAojxIGCmDtf0,14154
6
6
  isar/apis/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  isar/apis/models/models.py,sha256=GMOss2C8lBeRFV7E37mLwSOM6RhiyLQLcLBRzm_51d4,1835
8
8
  isar/apis/models/start_mission_definition.py,sha256=m9M5dZCmvRM1b4N8xYGquCSplSr4GDk376s2QoVL8F4,6231
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=yQM2HMgelBnbkzPR_tLHOY2EbThUcSO5jMA6Xtp5FQA,9915
11
+ isar/apis/schedule/scheduling_controller.py,sha256=S93DNyOWqVYAe3EnBnWuoCHLkeVFFjkR7ayBRw9J7f4,10603
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
15
15
  isar/config/configuration_error.py,sha256=rO6WOhafX6xvVib8WxV-eY483Z0PpN-9PxGsq5ATfKc,46
16
- isar/config/log.py,sha256=_zeHrsI4XqoHc1Um50PLHFjlwGiClM_M5CzcXoqwZuY,1380
17
- isar/config/logging.conf,sha256=mYO1xf27gAopEMHhGzY7-mwyfN16rwRLkPNMvy3zn2g,1127
18
- isar/config/open_telemetry.py,sha256=7hO6lR4lgK3IRZVh0a4shxIuamyt9paLM6d_FwXw5OY,2661
19
- isar/config/settings.py,sha256=-fBxs0TUGmoCX4nF1Rwg0YMZ-WQ6qsqFZpWHxqwOrlk,13029
16
+ isar/config/log.py,sha256=f_mLLz5RSa0kZkdpi1m0iMdwwDc4RQp12mnT6gu2exE,1303
17
+ isar/config/logging.conf,sha256=a7ZBvZkrMDaPU3eRGAjL_eZz6hZsa6BaRJOfx8mbnnM,629
18
+ isar/config/open_telemetry.py,sha256=965IlPi7urVTL0Yy4uYu4e1P2Ne6HC_RXizM2vCX9kY,2371
19
+ isar/config/settings.py,sha256=dRQwL6qCnFoyJkMiBxzVv_JwTfs8UJTnuPnwPlQFhUM,13187
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
@@ -35,26 +35,19 @@ isar/config/predefined_mission_definition/default_turtlebot.json,sha256=20ee7q1E
35
35
  isar/config/predefined_missions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
36
  isar/config/predefined_missions/default.json,sha256=NWo9y5noPmpjlNUxLnZK95Sz7DIEaUR-ISYlw3MP8i0,1251
37
37
  isar/config/predefined_missions/default_turtlebot.json,sha256=8Vk1_0P0BBsG0vwh4vwIYINiiWioErHZ0Ppjq3ctaPM,2143
38
+ isar/eventhandlers/eventhandler.py,sha256=POriVZzl97igY9Ny4_hILKf-PWFSsegxuqkXpOsdMIw,2771
38
39
  isar/mission_planner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
40
  isar/mission_planner/local_planner.py,sha256=Mkg3vvUBF1jImfQnaFvXLNpKVadR21X4mwDd_wHqJ2w,2520
40
41
  isar/mission_planner/mission_planner_interface.py,sha256=UgpPIM4FbrWOD7fGY3Ul64k3uYb8wo0FwSWGewYoVbc,485
41
42
  isar/mission_planner/sequential_task_selector.py,sha256=66agRPHuJnEa1vArPyty4muTasAZ50XPjjrSaTdY_Cc,643
42
43
  isar/mission_planner/task_selector_interface.py,sha256=pnLeaGPIuyXThcflZ_A7YL2b2xQjFT88hAZidkMomxU,707
43
44
  isar/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
44
- isar/models/communication/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
- isar/models/communication/message.py,sha256=ge2EdUXRnYkiEu5TIAYJFQET_5w-N8MRgc2Y31vetno,155
46
- isar/models/communication/queues/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
- isar/models/communication/queues/events.py,sha256=mZt1ZarqmyDW_y42w7aD1Iv-m7HLwrpUyOh3pM4w79Q,2412
48
- isar/models/communication/queues/queue_io.py,sha256=AnHWUCkZ0tunkxKKeBarq-OUkRM97IaMfA-a1pmf1cQ,394
49
- isar/models/communication/queues/queue_timeout_error.py,sha256=rF8TlNF7RHS_ueTZ5mp7aFkhLY1j0dcwMwH-Ba6lVpE,45
50
- isar/models/communication/queues/queue_utils.py,sha256=3kw7LxMVxCUM7JF7DVQgxbiUzMBMtVa8nwfpr7xDSGc,872
51
- isar/models/communication/queues/status_queue.py,sha256=on8kvlNsG6MJjEVsyqtBswIpmOdOggQiKr7F5x0T3jw,514
52
- isar/models/mission_metadata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
- isar/robot/robot.py,sha256=MmdrJzC4U_dGK3NLA6vgGNi0awNQwFvsPDsr9030fso,5431
54
- isar/robot/robot_start_mission.py,sha256=vQKsKnrWQuY70jEK-qeeaZYpXxQH4vElorczYZheXTQ,3423
55
- isar/robot/robot_status.py,sha256=FpkTIAA-O5vKuyU7fnWn2YXtbstq5qbk9XSxbn_0MXU,2015
56
- isar/robot/robot_stop_mission.py,sha256=jUyfemvbyigxrlIp9aKPn-PvarhagJEgajQPS_LgJ7g,2442
57
- isar/robot/robot_task_status.py,sha256=71SYPnoqaFbTe1bELLTvAUigAJ-McpomC2sjYQNQs_A,3290
45
+ isar/models/events.py,sha256=e6hNQ5vtIdSZ81StzIwGYZqwW9T_7ur088o78iydU4g,3858
46
+ isar/robot/robot.py,sha256=keqsYmfRlyIC4CWkMG0erDt_4uIC0IPvyG2ni4MemyI,5350
47
+ isar/robot/robot_start_mission.py,sha256=RPYH9VtXDFdPqhOpt6kSbT17RHkJQPKkQ6d4784_pFE,3210
48
+ isar/robot/robot_status.py,sha256=NMZZOV1DHOVrJwMsSjKbDSaSiWYnrfAW1cQHtc6heKk,1903
49
+ isar/robot/robot_stop_mission.py,sha256=4GZyhLU0hB6ZK0ArCVhFS9Sf3ZbqFI9DvPNfvD889Ps,2270
50
+ isar/robot/robot_task_status.py,sha256=jefIDfrbly7vWZztWA2zLmK5Yz1NSEytw2YUmprccNA,3161
58
51
  isar/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
52
  isar/services/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
53
  isar/services/auth/azure_credentials.py,sha256=9PlwGe5FrPRbW2dp0go7LMp8_l_FRvL8xOXotXwzRDo,364
@@ -64,48 +57,45 @@ isar/services/service_connections/mqtt/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JC
64
57
  isar/services/service_connections/mqtt/mqtt_client.py,sha256=se8uLvjy-cElM-WhmHEPXfEA8u05huOLnkcOCYRpcE4,3551
65
58
  isar/services/service_connections/mqtt/robot_heartbeat_publisher.py,sha256=_bUOG7CfqBlCRvG4vh2XGoMXucBxsJarFIeXIKOH1aw,1019
66
59
  isar/services/service_connections/mqtt/robot_info_publisher.py,sha256=AxokGk51hRPTxxD2r0P9braPJCMrf1InaCxrUBKkF4g,1402
67
- isar/services/service_connections/stid/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
68
60
  isar/services/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
69
- isar/services/utilities/queue_utilities.py,sha256=Pw3hehSwkXJNeDv-bDVDfs58VOwtt3i5hpiJ2ZpphuQ,1225
70
61
  isar/services/utilities/robot_utilities.py,sha256=4zCigsLXfqDC8POHchktSq81zr1_pTaRve_LQsVr6Mk,514
71
- isar/services/utilities/scheduling_utilities.py,sha256=eXeTEe4JmP2mgVd77DC5SLGTPjpG6O9IhN330dAyh-4,11122
62
+ isar/services/utilities/scheduling_utilities.py,sha256=H6p1M_GM4_0-HZUtaVWJU5Xn04OL9urOPes8ReZ8ZaQ,11668
72
63
  isar/services/utilities/threaded_request.py,sha256=py4G-_RjnIdHljmKFAcQ6ddqMmp-ZYV39Ece-dqRqjs,1874
73
64
  isar/state_machine/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
74
- isar/state_machine/state_machine.py,sha256=6rksxhG4OLoZYfRSB5wfpqHXQUperbRjqwnY-6ue8Gk,13099
75
- isar/state_machine/states_enum.py,sha256=Z3dO6k6JmQAZ1lzcR58oVCxoCky_-ZS9MaL3RSaNbZ4,434
76
- isar/state_machine/generic_states/idle.py,sha256=uXVHtKeX3jPZC7iVmic1sKD6nLtSOVynrHNiUCdTDcw,4371
77
- isar/state_machine/generic_states/ongoing_mission.py,sha256=ns6mbaSJvjM7JAbl1txPA9VdjxTv4iWKGbdYahtTtGc,11571
78
- isar/state_machine/generic_states/robot_unavailable.py,sha256=pHmed1uRPwCWAR4uBJmdnxi9WX8veTbGG9ephmROhm0,1851
65
+ isar/state_machine/state_machine.py,sha256=-BIIBP61COFnTYD78wu8VeC-ZHSvkas-hL1Z-YwqjvU,16668
66
+ isar/state_machine/states_enum.py,sha256=4XZ6dGGjXVZ8PwQCnAIH3MMNbMP2h3bmmPHFk6m_RlY,481
79
67
  isar/state_machine/states/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
80
- isar/state_machine/states/await_next_mission.py,sha256=U0oGi-O05S-ZvdhpQRuirrY3ZBbblURo5U95PsscMlQ,573
81
- isar/state_machine/states/blocked_protective_stop.py,sha256=KDux2lm5kwEEarnDt9FG4MFrWbYUzs1_DX5hu2ILIlI,675
82
- isar/state_machine/states/home.py,sha256=2v7BFQn4QZ0npOrXpWLWCoHD5IpSyAJr-vQCS3MQWJs,514
83
- isar/state_machine/states/monitor.py,sha256=BVrfZb-EWIdNYTC75F8HCi_OOtjBYbphrwki98p1WdE,597
84
- isar/state_machine/states/offline.py,sha256=vZnBMVDnehZ-0gPsHNVRpZtb8OBBFkeEnq2olo_Ep6M,609
85
- isar/state_machine/states/paused.py,sha256=IgnWBM6WXj3wjFZMARAPWIpzWGyUSW35DVBvNHuiNP8,1460
86
- isar/state_machine/states/returning_home.py,sha256=BBQo3PoNP-THlvJa5gQr0fNBhInh_Ox1L2OeH8evUq8,638
87
- isar/state_machine/states/robot_standing_still.py,sha256=RbOZSiQz72tWAJID5ksgzcb4lND6OniiG35IE1wMUHk,579
88
- isar/state_machine/states/stopping.py,sha256=yJE7KT1aGo_qd1VTETfg1rTrlM-hKKQYKQp7xu4py_Y,2854
89
- isar/state_machine/states/unknown_status.py,sha256=qfIoL5f7Hj-aZKq5tCM1FctkuEI6SwgpQuixzKx11Zk,2428
90
- isar/state_machine/transitions/mission.py,sha256=Lsiee_hSn5wd7KWpmvIdaG-49f6HGdkCdiXAo5L0ciE,5803
91
- isar/state_machine/transitions/return_home.py,sha256=6aBpKpozT48RJ__w13gv-r7dSz-fEOCzkAuKq5Hwm6k,2728
68
+ isar/state_machine/states/await_next_mission.py,sha256=RDWqGFdQ6PX7AtSjlrR-fH6s441mKooOpkceTO7pvkc,1873
69
+ isar/state_machine/states/blocked_protective_stop.py,sha256=GEOvxnHXjpCsrh3aa8Idtn1zMYv5HLQzj9qQAq8HvaU,1180
70
+ isar/state_machine/states/home.py,sha256=NUVmSmwG5_N7ZDLfbS0eWMnDVpVXmADrZXjh-s_klks,1862
71
+ isar/state_machine/states/intervention_needed.py,sha256=xMKzdie7quvnfdgQwgHytIgKTPXXeevbA-P6IJTwEZU,1634
72
+ isar/state_machine/states/monitor.py,sha256=QEV_lc-lHoFAOK2e6HD4FdzpN607LbqZx2Y9-LknrLA,3666
73
+ isar/state_machine/states/offline.py,sha256=5wdNzC1wG0cWrpuT_r_mk8UNFHA4QSyg8ejXUTAg4Io,1137
74
+ isar/state_machine/states/paused.py,sha256=tegYTUioSIKP2TUiMqBLNp9owyLwcuEM3a_LyKZSwQM,1087
75
+ isar/state_machine/states/returning_home.py,sha256=bO8i61xzQAvT0upgK1Fi_OzyRfsRaZlfK3A_2-tThpo,3420
76
+ isar/state_machine/states/robot_standing_still.py,sha256=ee2ORQD0IfUMMBz7bpuUMyA_sMYtdiy17h48KrZJxRc,1897
77
+ isar/state_machine/states/stopping.py,sha256=fMXXvcXtzML-Q5A-uRD_gXePy51fnt9jhOTVFN-3qqA,2420
78
+ isar/state_machine/states/unknown_status.py,sha256=m9XoGGgdjhjX-LRW31mwiU8r7LREB0yOSv2DFZtZH7Y,1789
79
+ isar/state_machine/transitions/mission.py,sha256=pB8eKaJAA1vLqTXuqs21Y-6A39uEs5ysUZhzWpb49KY,5531
80
+ isar/state_machine/transitions/return_home.py,sha256=Vy_Q_mmTj4wsWL8qxUkmC1CTXEzGsdKNYb4V4rw2IeE,3202
92
81
  isar/state_machine/transitions/robot_status.py,sha256=c1ceyWRGCtx-KTDtxHXRD7oPbt8TQ2ej24A0wyim8vc,2720
93
- isar/state_machine/transitions/functions/fail_mission.py,sha256=_6HqBMALDinFZ4yh5GMpeqqgV5tw5i8OVMj5UDdqesg,495
82
+ isar/state_machine/transitions/functions/fail_mission.py,sha256=jHHXhfQVYQEzCXgTEhv5e6uEK9p6iDPFFXqS9bzs_-A,720
94
83
  isar/state_machine/transitions/functions/finish_mission.py,sha256=TRQrk7HdllmAkwsp25HRZAFAk46Y1hLx3jmkIAKrHDI,1442
95
84
  isar/state_machine/transitions/functions/pause.py,sha256=oaIFd4aZnbeaHb-EGQE9ozJctskqXKsRKkNc68M8sp0,1975
96
85
  isar/state_machine/transitions/functions/resume.py,sha256=HgAEn4jQOPkVPWWZCAh7dqnIerdF8nGcgFcZ1KsCNSQ,2104
97
86
  isar/state_machine/transitions/functions/return_home.py,sha256=UlniwYvpz74hxqgN0TyVv3LCmiMsqsosKEtEGLqkNj0,1139
98
- isar/state_machine/transitions/functions/robot_status.py,sha256=xhKZ5u_X8uDvnhvGnAIABuKaPXeVqFjkgj4H2Om-j_A,1013
87
+ isar/state_machine/transitions/functions/robot_status.py,sha256=P1Cu8xVysbiKRKL4E8mSyoL2-72HfxrLvvOcdnBOlvw,889
99
88
  isar/state_machine/transitions/functions/start_mission.py,sha256=ricRfhLH1_lNpqWxneMZcm7ps2YfY6sQGHkiT0Glf6M,2564
100
- isar/state_machine/transitions/functions/stop.py,sha256=JK4hjGc3QtgSzvCWeOr1YG61SH1QOhmVNjw_jOnahQg,3123
89
+ isar/state_machine/transitions/functions/stop.py,sha256=5tPYE4WB98iammX81wEdrAUvX0huJ2PBooVaY_7i6GY,2902
101
90
  isar/state_machine/transitions/functions/utils.py,sha256=Wa72Ocq4QT1E6qkpEJZQ3h5o33pGvx7Tlkt2JZ2Grbk,314
91
+ isar/state_machine/utils/common_event_handlers.py,sha256=Grv34hVwDjzi9BizqRLMJAKtRpucuklXGR3hoC_0kkQ,5773
102
92
  isar/storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
103
93
  isar/storage/blob_storage.py,sha256=D67y3Z939iXoRxs8npOuKOhgs2o6dYz2ivTm5IXXhJE,3168
104
94
  isar/storage/local_storage.py,sha256=Bnmoi5gyN8r-oRh0aHrOdGqaH3JqRScFKMRXYojW5kY,1855
105
95
  isar/storage/storage_interface.py,sha256=DYDry4I7aZpDHJhsBF6s8zrgokFAc7fdKJKfA8AvL7o,828
106
- isar/storage/uploader.py,sha256=1F4M34aVnD828WV62muTIE04vj3D52lrTOOh8r6SgwA,9464
96
+ isar/storage/uploader.py,sha256=uD1DzvJ2yYtNAwQGa7UD7kNOxZfKxJ1cCdi7sfOVZ10,9443
107
97
  isar/storage/utilities.py,sha256=oLH0Rp7UtrQQdilfITnmXO1Z0ExdeDhBImYHid55vBA,3449
108
- isar-1.31.0.dist-info/licenses/LICENSE,sha256=3fc2-ebLwHWwzfQbulGNRdcNob3SBQeCfEVUDYxsuqw,14058
98
+ isar-1.32.0.dist-info/licenses/LICENSE,sha256=3fc2-ebLwHWwzfQbulGNRdcNob3SBQeCfEVUDYxsuqw,14058
109
99
  robot_interface/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
110
100
  robot_interface/robot_interface.py,sha256=-jCAKkZ2eiyzUyHVQmOzw4hMgLWR7pE8MHj-WZo85ZY,7978
111
101
  robot_interface/test_robot_interface.py,sha256=FV1urn7SbsMyWBIcTKjsBwAG4IsXeZ6pLHE0mA9EGGs,692
@@ -117,7 +107,7 @@ robot_interface/models/inspection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeR
117
107
  robot_interface/models/inspection/inspection.py,sha256=2T8czQcNt9J1M96tKGQA6P3s5CikdZ7-0RevXQ4-CfA,2520
118
108
  robot_interface/models/mission/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
119
109
  robot_interface/models/mission/mission.py,sha256=MQ9p5cuclLXexaZu9bkDh5-aN99eunvYC0vP-Z_kUwI,960
120
- robot_interface/models/mission/status.py,sha256=UOCARLfLxLFXJEjfIH7aXYXO7xajOKBJsxz-Wd6gZQ4,740
110
+ robot_interface/models/mission/status.py,sha256=rlgU9Xpsk-rOHF-z6ziIMCYpOAqtu7lOMIUY1e0yZCY,786
121
111
  robot_interface/models/mission/task.py,sha256=YzaqJ_KIIm-3S2Y2-BG4Pdkc8sjFMzMx5jj8FtXSmFg,4744
122
112
  robot_interface/models/robots/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
123
113
  robot_interface/models/robots/battery_state.py,sha256=ktOtJ8ltdK0k_i7BoqYfhc5dbOzIG6Oo-uWC67fCWio,98
@@ -125,12 +115,12 @@ robot_interface/models/robots/media.py,sha256=8A-CuuubfngzPprs6zWB9hSaqe3jzgsE8r
125
115
  robot_interface/models/robots/robot_model.py,sha256=-0jNKWPcEgtF_2klb1It3u0SCoAR0hSW9nce58Zq0Co,417
126
116
  robot_interface/telemetry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
127
117
  robot_interface/telemetry/mqtt_client.py,sha256=ueXdtIFNCwciTj4spvdJj9emd-IOmUuJjpsXQSSWZPY,2987
128
- robot_interface/telemetry/payloads.py,sha256=PpvmV7XeGgfhc_aRUYFOdwBTwV2x8TwTBINJ-rKchVw,2804
118
+ robot_interface/telemetry/payloads.py,sha256=Fqkfv77_T2Ttk5EjWRU5HH0XAxFhIuz7k-LMftuXk2k,2927
129
119
  robot_interface/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
130
120
  robot_interface/utilities/json_service.py,sha256=qkzVkb60Gi_pto-b5n1vNzCrQze2yqgIJqSLNLYj1Fg,1034
131
121
  robot_interface/utilities/uuid_string_factory.py,sha256=_NQIbBQ56w0qqO0MUDP6aPpHbxW7ATRhK8HnQiBSLkc,76
132
- isar-1.31.0.dist-info/METADATA,sha256=RZo3tvmuEPeEdu1CQeqgKAQyWysrlJExNPMVn8zjqPs,31217
133
- isar-1.31.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
134
- isar-1.31.0.dist-info/entry_points.txt,sha256=TFam7uNNw7J0iiDYzsH2gfG0u1eV1wh3JTw_HkhgKLk,49
135
- isar-1.31.0.dist-info/top_level.txt,sha256=UwIML2RtuQKCyJJkatcSnyp6-ldDjboB9k9JgKipO-U,21
136
- isar-1.31.0.dist-info/RECORD,,
122
+ isar-1.32.0.dist-info/METADATA,sha256=-K9njLYJr_JCWlTmoJMm6hYJgBhpvLWxwFFNUsYo3Ms,31217
123
+ isar-1.32.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
124
+ isar-1.32.0.dist-info/entry_points.txt,sha256=TFam7uNNw7J0iiDYzsH2gfG0u1eV1wh3JTw_HkhgKLk,49
125
+ isar-1.32.0.dist-info/top_level.txt,sha256=UwIML2RtuQKCyJJkatcSnyp6-ldDjboB9k9JgKipO-U,21
126
+ isar-1.32.0.dist-info/RECORD,,
@@ -29,3 +29,4 @@ class RobotStatus(Enum):
29
29
  Blocked = "blocked"
30
30
  BlockedProtectiveStop = "blockedprotectivestop"
31
31
  ReturningHome = "returninghome"
32
+ InterventionNeeded = "interventionneeded"
@@ -138,3 +138,11 @@ class InspectionValuePayload:
138
138
  class StartUpMessagePayload:
139
139
  isar_id: str
140
140
  timestamp: datetime
141
+
142
+
143
+ @dataclass
144
+ class InterventionNeededPayload:
145
+ isar_id: str
146
+ robot_name: str
147
+ reason: str
148
+ timestamp: datetime
File without changes
@@ -1,8 +0,0 @@
1
- from dataclasses import dataclass
2
-
3
- from robot_interface.models.mission.mission import Mission
4
-
5
-
6
- @dataclass
7
- class StartMissionMessage:
8
- mission: Mission
File without changes
@@ -1,58 +0,0 @@
1
- from queue import Queue
2
-
3
- from transitions import State
4
-
5
- from isar.config.settings import settings
6
- from isar.models.communication.queues.queue_io import QueueIO
7
- from isar.models.communication.queues.status_queue import StatusQueue
8
- from robot_interface.models.exceptions.robot_exceptions import ErrorMessage
9
- from robot_interface.models.mission.mission import Mission
10
- from robot_interface.models.mission.status import RobotStatus, TaskStatus
11
- from robot_interface.models.mission.task import TASKS
12
-
13
-
14
- class Events:
15
- def __init__(self) -> None:
16
- self.api_requests: APIRequests = APIRequests()
17
- self.state_machine_events: StateMachineEvents = StateMachineEvents()
18
- self.robot_service_events: RobotServiceEvents = RobotServiceEvents()
19
-
20
- self.upload_queue: Queue = Queue(maxsize=10)
21
-
22
- if settings.MQTT_ENABLED:
23
- self.mqtt_queue: Queue = Queue()
24
-
25
-
26
- class APIRequests:
27
- def __init__(self) -> None:
28
- self.start_mission: QueueIO = QueueIO(input_size=1, output_size=1)
29
- self.stop_mission: QueueIO = QueueIO(input_size=1, output_size=1)
30
- self.pause_mission: QueueIO = QueueIO(input_size=1, output_size=1)
31
- self.resume_mission: QueueIO = QueueIO(input_size=1, output_size=1)
32
- self.return_home: QueueIO = QueueIO(input_size=1, output_size=1)
33
-
34
-
35
- class StateMachineEvents:
36
- def __init__(self) -> None:
37
- self.start_mission: Queue[Mission] = Queue(maxsize=1)
38
- self.stop_mission: Queue[str] = Queue(maxsize=1)
39
- self.pause_mission: Queue[bool] = Queue(maxsize=1)
40
- self.task_status_request: Queue[str] = Queue(maxsize=1)
41
-
42
-
43
- class RobotServiceEvents:
44
- def __init__(self) -> None:
45
- self.task_status_updated: Queue[TaskStatus] = Queue(maxsize=1)
46
- self.task_status_failed: Queue[ErrorMessage] = Queue(maxsize=1)
47
- self.mission_started: Queue[bool] = Queue(maxsize=1)
48
- self.mission_failed: Queue[ErrorMessage] = Queue(maxsize=1)
49
- self.robot_status_changed: Queue[bool] = Queue(maxsize=1)
50
- self.mission_failed_to_stop: Queue[ErrorMessage] = Queue(maxsize=1)
51
- self.mission_successfully_stopped: Queue[bool] = Queue(maxsize=1)
52
-
53
-
54
- class SharedState:
55
- def __init__(self) -> None:
56
- self.state: StatusQueue[State] = StatusQueue()
57
- self.robot_status: StatusQueue[RobotStatus] = StatusQueue()
58
- self.state_machine_current_task: StatusQueue[TASKS] = StatusQueue()
@@ -1,12 +0,0 @@
1
- from queue import Queue
2
-
3
-
4
- class QueueIO:
5
- """
6
- Creates input and output queue. The queues are defined such that the input is from
7
- api to state machine while the output is from state machine to api.
8
- """
9
-
10
- def __init__(self, input_size: int = 0, output_size: int = 0):
11
- self.input: Queue = Queue(maxsize=input_size)
12
- self.output: Queue = Queue(maxsize=output_size)
@@ -1,2 +0,0 @@
1
- class QueueTimeoutError(Exception):
2
- pass
@@ -1,38 +0,0 @@
1
- from queue import Empty, Queue
2
- from typing import Any, Optional, TypeVar
3
-
4
- from isar.models.communication.queues.status_queue import StatusQueue
5
-
6
- T = TypeVar("T")
7
-
8
-
9
- def trigger_event_without_data(queue: Queue[Any]) -> None:
10
- queue.put(True)
11
-
12
-
13
- def trigger_event(queue: Queue[T], data: T) -> None:
14
- queue.put(data)
15
-
16
-
17
- def check_shared_state(queue: StatusQueue[T]) -> Optional[T]:
18
- try:
19
- return queue.check()
20
- except Empty:
21
- return None
22
-
23
-
24
- def update_shared_state(queue: StatusQueue[T], data: T) -> None:
25
- queue.update(data)
26
-
27
-
28
- def check_for_event(queue: Queue[T]) -> Optional[T]:
29
- try:
30
- return queue.get(block=False)
31
- except Empty:
32
- return None
33
-
34
-
35
- def check_for_event_without_consumption(queue: Queue[T]) -> bool:
36
- return (
37
- queue.qsize() != 0
38
- ) # Queue size is not reliable, but should be sufficient for this case
@@ -1,22 +0,0 @@
1
- from collections import deque
2
- from queue import Empty, Queue
3
- from typing import TypeVar
4
-
5
- T = TypeVar("T")
6
-
7
-
8
- class StatusQueue(Queue[T]):
9
- def __init__(self) -> None:
10
- super().__init__()
11
-
12
- def check(self) -> T:
13
- if not self._qsize():
14
- raise Empty
15
- with self.mutex:
16
- queueList = list(self.queue)
17
- return queueList.pop()
18
-
19
- def update(self, item: T):
20
- with self.mutex:
21
- self.queue: deque[T] = deque()
22
- self.queue.append(item)
File without changes
File without changes
@@ -1,39 +0,0 @@
1
- import logging
2
- from queue import Empty, Queue
3
- from typing import Any
4
-
5
- from isar.models.communication.queues.queue_timeout_error import QueueTimeoutError
6
-
7
- logger = logging.getLogger("api")
8
-
9
-
10
- class QueueUtilities:
11
- """
12
- Contains utility functions for handling queue communication between threads.
13
- """
14
-
15
- @staticmethod
16
- def check_queue(queue: Queue, queue_timeout: int = None) -> Any:
17
- """
18
- Checks if there is a message on a queue. If a timeout is specified the function
19
- will raise a QueueTimeoutError if there is no message within the timeout. If
20
- there is no timeout specified this function will block.
21
- :param queue: The queue to be checked for a message
22
- :param queue_timeout: Timeout in seconds
23
- :return: Message found on queue
24
- :raises QueueTimeoutError
25
- """
26
- try:
27
- message: Any = queue.get(timeout=queue_timeout)
28
- except Empty:
29
- logger.error("Queue timed out")
30
- raise QueueTimeoutError
31
- return message
32
-
33
- @staticmethod
34
- def clear_queue(queue: Queue) -> None:
35
- while True:
36
- try:
37
- queue.get(block=False)
38
- except Empty:
39
- break