isar 1.25.3__py3-none-any.whl → 1.25.5__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/models/start_mission_definition.py +9 -9
- isar/config/settings.py +4 -0
- isar/script.py +1 -1
- isar/state_machine/state_machine.py +60 -39
- isar/state_machine/states/blocked_protective_stop.py +65 -0
- isar/state_machine/states/idle.py +21 -10
- isar/state_machine/states/monitor.py +1 -1
- isar/state_machine/states_enum.py +1 -0
- isar/storage/uploader.py +11 -12
- {isar-1.25.3.dist-info → isar-1.25.5.dist-info}/METADATA +2 -2
- {isar-1.25.3.dist-info → isar-1.25.5.dist-info}/RECORD +21 -20
- {isar-1.25.3.dist-info → isar-1.25.5.dist-info}/WHEEL +1 -1
- robot_interface/models/exceptions/robot_exceptions.py +20 -22
- robot_interface/models/mission/status.py +19 -18
- robot_interface/models/robots/battery_state.py +2 -2
- robot_interface/models/robots/media.py +1 -1
- robot_interface/models/robots/robot_model.py +7 -7
- robot_interface/telemetry/payloads.py +40 -9
- {isar-1.25.3.dist-info → isar-1.25.5.dist-info}/LICENSE +0 -0
- {isar-1.25.3.dist-info → isar-1.25.5.dist-info}/entry_points.txt +0 -0
- {isar-1.25.3.dist-info → isar-1.25.5.dist-info}/top_level.txt +0 -0
|
@@ -23,18 +23,18 @@ from robot_interface.models.mission.task import (
|
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
class InspectionTypes(str, Enum):
|
|
26
|
-
image
|
|
27
|
-
thermal_image
|
|
28
|
-
video
|
|
29
|
-
thermal_video
|
|
30
|
-
audio
|
|
26
|
+
image = "Image"
|
|
27
|
+
thermal_image = "ThermalImage"
|
|
28
|
+
video = "Video"
|
|
29
|
+
thermal_video = "ThermalVideo"
|
|
30
|
+
audio = "Audio"
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
class TaskType(str, Enum):
|
|
34
|
-
Inspection
|
|
35
|
-
Localization
|
|
36
|
-
ReturnToHome
|
|
37
|
-
Dock
|
|
34
|
+
Inspection = "inspection"
|
|
35
|
+
Localization = "localization"
|
|
36
|
+
ReturnToHome = "return_to_home"
|
|
37
|
+
Dock = "dock"
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
class StartMissionInspectionDefinition(BaseModel):
|
isar/config/settings.py
CHANGED
|
@@ -60,6 +60,10 @@ class Settings(BaseSettings):
|
|
|
60
60
|
# Number of attempts to request a task status in monitor before cancelling
|
|
61
61
|
REQUEST_STATUS_FAILURE_COUNTER_LIMIT: int = Field(default=3)
|
|
62
62
|
|
|
63
|
+
# Time allocated to reconnect when failing to retrieve status due to communication
|
|
64
|
+
# issues
|
|
65
|
+
REQUEST_STATUS_COMMUNICATION_RECONNECT_DELAY: float = Field(default=10)
|
|
66
|
+
|
|
63
67
|
# Number of attempts to stop the robot before giving up
|
|
64
68
|
STOP_ROBOT_ATTEMPTS_LIMIT: int = Field(default=10)
|
|
65
69
|
|
isar/script.py
CHANGED
|
@@ -66,7 +66,7 @@ def print_startup_info():
|
|
|
66
66
|
print_setting(fillchar="-")
|
|
67
67
|
print_setting("Robot package", settings.ROBOT_PACKAGE)
|
|
68
68
|
print_setting("Robot name", settings.ROBOT_NAME)
|
|
69
|
-
print_setting("Run mission
|
|
69
|
+
print_setting("Run mission taskwise", settings.RUN_MISSION_BY_TASK)
|
|
70
70
|
print_setting("Running on port", settings.API_PORT)
|
|
71
71
|
print_setting("Mission planner", settings.MISSION_PLANNER)
|
|
72
72
|
print_setting("Using local storage", settings.STORAGE_LOCAL_ENABLED)
|
|
@@ -24,6 +24,7 @@ from isar.state_machine.states.initiate import Initiate
|
|
|
24
24
|
from isar.state_machine.states.monitor import Monitor
|
|
25
25
|
from isar.state_machine.states.off import Off
|
|
26
26
|
from isar.state_machine.states.offline import Offline
|
|
27
|
+
from isar.state_machine.states.blocked_protective_stop import BlockedProtectiveStop
|
|
27
28
|
from isar.state_machine.states.paused import Paused
|
|
28
29
|
from isar.state_machine.states.stop import Stop
|
|
29
30
|
from isar.state_machine.states_enum import States
|
|
@@ -34,6 +35,11 @@ from robot_interface.models.mission.status import MissionStatus, RobotStatus, Ta
|
|
|
34
35
|
from robot_interface.models.mission.task import TASKS
|
|
35
36
|
from robot_interface.robot_interface import RobotInterface
|
|
36
37
|
from robot_interface.telemetry.mqtt_client import MqttClientInterface
|
|
38
|
+
from robot_interface.telemetry.payloads import (
|
|
39
|
+
RobotStatusPayload,
|
|
40
|
+
MissionPayload,
|
|
41
|
+
TaskPayload,
|
|
42
|
+
)
|
|
37
43
|
from robot_interface.utilities.json_service import EnhancedJSONEncoder
|
|
38
44
|
|
|
39
45
|
|
|
@@ -87,6 +93,7 @@ class StateMachine(object):
|
|
|
87
93
|
self.initiate_state: State = Initiate(self)
|
|
88
94
|
self.off_state: State = Off(self)
|
|
89
95
|
self.offline_state: State = Offline(self)
|
|
96
|
+
self.blocked_protective_stop: State = BlockedProtectiveStop(self)
|
|
90
97
|
|
|
91
98
|
self.states: List[State] = [
|
|
92
99
|
self.off_state,
|
|
@@ -97,6 +104,7 @@ class StateMachine(object):
|
|
|
97
104
|
self.stop_state,
|
|
98
105
|
self.paused_state,
|
|
99
106
|
self.offline_state,
|
|
107
|
+
self.blocked_protective_stop,
|
|
100
108
|
]
|
|
101
109
|
|
|
102
110
|
self.machine = Machine(self, states=self.states, initial="off", queued=True)
|
|
@@ -222,6 +230,18 @@ class StateMachine(object):
|
|
|
222
230
|
"dest": self.idle_state,
|
|
223
231
|
"before": self._online,
|
|
224
232
|
},
|
|
233
|
+
{
|
|
234
|
+
"trigger": "robot_protective_stop_engaged",
|
|
235
|
+
"source": [self.idle_state],
|
|
236
|
+
"dest": self.blocked_protective_stop,
|
|
237
|
+
"before": self._protective_stop_engaged,
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
"trigger": "robot_protective_stop_disengaged",
|
|
241
|
+
"source": self.blocked_protective_stop,
|
|
242
|
+
"dest": self.idle_state,
|
|
243
|
+
"before": self._protective_stop_disengaged,
|
|
244
|
+
},
|
|
225
245
|
]
|
|
226
246
|
)
|
|
227
247
|
|
|
@@ -270,6 +290,12 @@ class StateMachine(object):
|
|
|
270
290
|
def _online(self) -> None:
|
|
271
291
|
return
|
|
272
292
|
|
|
293
|
+
def _protective_stop_engaged(self) -> None:
|
|
294
|
+
return
|
|
295
|
+
|
|
296
|
+
def _protective_stop_disengaged(self) -> None:
|
|
297
|
+
return
|
|
298
|
+
|
|
273
299
|
def _resume(self) -> None:
|
|
274
300
|
self.logger.info(f"Resuming mission: {self.current_mission.id}")
|
|
275
301
|
self.current_mission.status = MissionStatus.InProgress
|
|
@@ -482,24 +508,22 @@ class StateMachine(object):
|
|
|
482
508
|
if self.current_mission:
|
|
483
509
|
if self.current_mission.error_message:
|
|
484
510
|
error_message = self.current_mission.error_message
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
},
|
|
497
|
-
cls=EnhancedJSONEncoder,
|
|
511
|
+
|
|
512
|
+
payload: MissionPayload = MissionPayload(
|
|
513
|
+
isar_id=settings.ISAR_ID,
|
|
514
|
+
robot_name=settings.ROBOT_NAME,
|
|
515
|
+
mission_id=self.current_mission.id if self.current_mission else None,
|
|
516
|
+
status=self.current_mission.status if self.current_mission else None,
|
|
517
|
+
error_reason=error_message.error_reason if error_message else None,
|
|
518
|
+
error_description=(
|
|
519
|
+
error_message.error_description if error_message else None
|
|
520
|
+
),
|
|
521
|
+
timestamp=datetime.now(timezone.utc),
|
|
498
522
|
)
|
|
499
523
|
|
|
500
524
|
self.mqtt_publisher.publish(
|
|
501
525
|
topic=settings.TOPIC_ISAR_MISSION,
|
|
502
|
-
payload=payload,
|
|
526
|
+
payload=json.dumps(payload, cls=EnhancedJSONEncoder),
|
|
503
527
|
qos=1,
|
|
504
528
|
retain=True,
|
|
505
529
|
)
|
|
@@ -514,26 +538,23 @@ class StateMachine(object):
|
|
|
514
538
|
if task.error_message:
|
|
515
539
|
error_message = task.error_message
|
|
516
540
|
|
|
517
|
-
payload:
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
"timestamp": datetime.now(timezone.utc),
|
|
530
|
-
},
|
|
531
|
-
cls=EnhancedJSONEncoder,
|
|
541
|
+
payload: TaskPayload = TaskPayload(
|
|
542
|
+
isar_id=settings.ISAR_ID,
|
|
543
|
+
robot_name=settings.ROBOT_NAME,
|
|
544
|
+
mission_id=self.current_mission.id if self.current_mission else None,
|
|
545
|
+
task_id=task.id if task else None,
|
|
546
|
+
status=task.status if task else None,
|
|
547
|
+
task_type=task.type if task else None,
|
|
548
|
+
error_reason=error_message.error_reason if error_message else None,
|
|
549
|
+
error_description=(
|
|
550
|
+
error_message.error_description if error_message else None
|
|
551
|
+
),
|
|
552
|
+
timestamp=datetime.now(timezone.utc),
|
|
532
553
|
)
|
|
533
554
|
|
|
534
555
|
self.mqtt_publisher.publish(
|
|
535
556
|
topic=settings.TOPIC_ISAR_TASK,
|
|
536
|
-
payload=payload,
|
|
557
|
+
payload=json.dumps(payload, cls=EnhancedJSONEncoder),
|
|
537
558
|
qos=1,
|
|
538
559
|
retain=True,
|
|
539
560
|
)
|
|
@@ -541,19 +562,17 @@ class StateMachine(object):
|
|
|
541
562
|
def publish_status(self) -> None:
|
|
542
563
|
if not self.mqtt_publisher:
|
|
543
564
|
return
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
},
|
|
551
|
-
cls=EnhancedJSONEncoder,
|
|
565
|
+
|
|
566
|
+
payload: RobotStatusPayload = RobotStatusPayload(
|
|
567
|
+
isar_id=settings.ISAR_ID,
|
|
568
|
+
robot_name=settings.ROBOT_NAME,
|
|
569
|
+
status=self._current_status(),
|
|
570
|
+
timestamp=datetime.now(timezone.utc),
|
|
552
571
|
)
|
|
553
572
|
|
|
554
573
|
self.mqtt_publisher.publish(
|
|
555
574
|
topic=settings.TOPIC_ISAR_STATUS,
|
|
556
|
-
payload=payload,
|
|
575
|
+
payload=json.dumps(payload, cls=EnhancedJSONEncoder),
|
|
557
576
|
qos=1,
|
|
558
577
|
retain=True,
|
|
559
578
|
)
|
|
@@ -563,6 +582,8 @@ class StateMachine(object):
|
|
|
563
582
|
return RobotStatus.Available
|
|
564
583
|
elif self.current_state == States.Offline:
|
|
565
584
|
return RobotStatus.Offline
|
|
585
|
+
elif self.current_state == States.BlockedProtectiveStop:
|
|
586
|
+
return RobotStatus.BlockedProtectiveStop
|
|
566
587
|
else:
|
|
567
588
|
return RobotStatus.Busy
|
|
568
589
|
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import time
|
|
3
|
+
from typing import TYPE_CHECKING, Optional
|
|
4
|
+
|
|
5
|
+
from transitions import State
|
|
6
|
+
|
|
7
|
+
from isar.config.settings import settings
|
|
8
|
+
from isar.services.utilities.threaded_request import (
|
|
9
|
+
ThreadedRequest,
|
|
10
|
+
ThreadedRequestNotFinishedError,
|
|
11
|
+
)
|
|
12
|
+
from robot_interface.models.exceptions.robot_exceptions import RobotException
|
|
13
|
+
from robot_interface.models.mission.status import RobotStatus
|
|
14
|
+
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from isar.state_machine.state_machine import StateMachine
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class BlockedProtectiveStop(State):
|
|
20
|
+
def __init__(self, state_machine: "StateMachine") -> None:
|
|
21
|
+
super().__init__(
|
|
22
|
+
name="blocked_protective_stop", on_enter=self.start, on_exit=self.stop
|
|
23
|
+
)
|
|
24
|
+
self.state_machine: "StateMachine" = state_machine
|
|
25
|
+
self.logger = logging.getLogger("state_machine")
|
|
26
|
+
self.robot_status_thread: Optional[ThreadedRequest] = None
|
|
27
|
+
|
|
28
|
+
def start(self) -> None:
|
|
29
|
+
self.state_machine.update_state()
|
|
30
|
+
self._run()
|
|
31
|
+
|
|
32
|
+
def stop(self) -> None:
|
|
33
|
+
if self.robot_status_thread:
|
|
34
|
+
self.robot_status_thread.wait_for_thread()
|
|
35
|
+
self.robot_status_thread = None
|
|
36
|
+
|
|
37
|
+
def _run(self) -> None:
|
|
38
|
+
while True:
|
|
39
|
+
if not self.robot_status_thread:
|
|
40
|
+
self.robot_status_thread = ThreadedRequest(
|
|
41
|
+
request_func=self.state_machine.robot.robot_status
|
|
42
|
+
)
|
|
43
|
+
self.robot_status_thread.start_thread(
|
|
44
|
+
name="State Machine BlockedProtectiveStop Get Robot Status"
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
try:
|
|
48
|
+
robot_status: RobotStatus = self.robot_status_thread.get_output()
|
|
49
|
+
except ThreadedRequestNotFinishedError:
|
|
50
|
+
time.sleep(self.state_machine.sleep_time)
|
|
51
|
+
continue
|
|
52
|
+
|
|
53
|
+
except RobotException as e:
|
|
54
|
+
self.logger.error(
|
|
55
|
+
f"Failed to get robot status because: {e.error_description}"
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
if robot_status != RobotStatus.BlockedProtectiveStop:
|
|
59
|
+
transition = self.state_machine.robot_protective_stop_disengaged # type: ignore
|
|
60
|
+
break
|
|
61
|
+
|
|
62
|
+
self.robot_status_thread = None
|
|
63
|
+
time.sleep(settings.ROBOT_API_STATUS_POLL_INTERVAL)
|
|
64
|
+
|
|
65
|
+
transition()
|
|
@@ -24,6 +24,7 @@ class Idle(State):
|
|
|
24
24
|
self.logger = logging.getLogger("state_machine")
|
|
25
25
|
self.robot_status_thread: Optional[ThreadedRequest] = None
|
|
26
26
|
self.last_robot_status_poll_time: float = time.time()
|
|
27
|
+
self.status_checked_at_least_once: bool = False
|
|
27
28
|
|
|
28
29
|
def start(self) -> None:
|
|
29
30
|
self.state_machine.update_state()
|
|
@@ -33,8 +34,12 @@ class Idle(State):
|
|
|
33
34
|
if self.robot_status_thread:
|
|
34
35
|
self.robot_status_thread.wait_for_thread()
|
|
35
36
|
self.robot_status_thread = None
|
|
37
|
+
self.status_checked_at_least_once = False
|
|
36
38
|
|
|
37
39
|
def _is_ready_to_poll_for_status(self) -> bool:
|
|
40
|
+
if not self.status_checked_at_least_once:
|
|
41
|
+
return True
|
|
42
|
+
|
|
38
43
|
time_since_last_robot_status_poll = (
|
|
39
44
|
time.time() - self.last_robot_status_poll_time
|
|
40
45
|
)
|
|
@@ -47,17 +52,19 @@ class Idle(State):
|
|
|
47
52
|
if self.state_machine.should_stop_mission():
|
|
48
53
|
transition = self.state_machine.stop # type: ignore
|
|
49
54
|
break
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
self.state_machine.start_mission(
|
|
55
|
-
mission=start_mission.mission,
|
|
56
|
-
initial_pose=start_mission.initial_pose,
|
|
55
|
+
|
|
56
|
+
if self.status_checked_at_least_once:
|
|
57
|
+
start_mission: Optional[StartMissionMessage] = (
|
|
58
|
+
self.state_machine.should_start_mission()
|
|
57
59
|
)
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
if start_mission:
|
|
61
|
+
self.state_machine.start_mission(
|
|
62
|
+
mission=start_mission.mission,
|
|
63
|
+
initial_pose=start_mission.initial_pose,
|
|
64
|
+
)
|
|
65
|
+
transition = self.state_machine.mission_started # type: ignore
|
|
66
|
+
break
|
|
67
|
+
time.sleep(self.state_machine.sleep_time)
|
|
61
68
|
|
|
62
69
|
if not self._is_ready_to_poll_for_status():
|
|
63
70
|
continue
|
|
@@ -72,6 +79,7 @@ class Idle(State):
|
|
|
72
79
|
|
|
73
80
|
try:
|
|
74
81
|
robot_status: RobotStatus = self.robot_status_thread.get_output()
|
|
82
|
+
self.status_checked_at_least_once = True
|
|
75
83
|
except ThreadedRequestNotFinishedError:
|
|
76
84
|
time.sleep(self.state_machine.sleep_time)
|
|
77
85
|
continue
|
|
@@ -86,6 +94,9 @@ class Idle(State):
|
|
|
86
94
|
if robot_status == RobotStatus.Offline:
|
|
87
95
|
transition = self.state_machine.robot_turned_offline # type: ignore
|
|
88
96
|
break
|
|
97
|
+
elif robot_status == RobotStatus.BlockedProtectiveStop:
|
|
98
|
+
transition = self.state_machine.robot_protective_stop_engaged # type: ignore
|
|
99
|
+
break
|
|
89
100
|
|
|
90
101
|
self.robot_status_thread = None
|
|
91
102
|
|
isar/storage/uploader.py
CHANGED
|
@@ -13,6 +13,7 @@ from isar.storage.storage_interface import StorageException, StorageInterface
|
|
|
13
13
|
from robot_interface.models.inspection.inspection import Inspection
|
|
14
14
|
from robot_interface.models.mission.mission import Mission
|
|
15
15
|
from robot_interface.telemetry.mqtt_client import MqttClientInterface
|
|
16
|
+
from robot_interface.telemetry.payloads import InspectionResultPayload
|
|
16
17
|
from robot_interface.utilities.json_service import EnhancedJSONEncoder
|
|
17
18
|
|
|
18
19
|
|
|
@@ -149,21 +150,19 @@ class Uploader:
|
|
|
149
150
|
"""
|
|
150
151
|
if not self.mqtt_publisher:
|
|
151
152
|
return
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
},
|
|
162
|
-
cls=EnhancedJSONEncoder,
|
|
153
|
+
|
|
154
|
+
payload: InspectionResultPayload = InspectionResultPayload(
|
|
155
|
+
isar_id=settings.ISAR_ID,
|
|
156
|
+
robot_name=settings.ROBOT_NAME,
|
|
157
|
+
inspection_id=inspection.id,
|
|
158
|
+
inspection_path=inspection_path,
|
|
159
|
+
installation_code=settings.PLANT_SHORT_NAME,
|
|
160
|
+
analysis_to_be_run=inspection.metadata.analysis_type,
|
|
161
|
+
timestamp=datetime.now(timezone.utc),
|
|
163
162
|
)
|
|
164
163
|
self.mqtt_publisher.publish(
|
|
165
164
|
topic=settings.TOPIC_ISAR_INSPECTION_RESULT,
|
|
166
|
-
payload=payload,
|
|
165
|
+
payload=json.dumps(payload, cls=EnhancedJSONEncoder),
|
|
167
166
|
qos=1,
|
|
168
167
|
retain=True,
|
|
169
168
|
)
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
isar/__init__.py,sha256=cH8p8bVveu3FUL6kBhldcSlLaoHgD82Kd0-SwSNfGXw,87
|
|
2
2
|
isar/modules.py,sha256=BeBg2kJi1q-7DzupOM3jFloeMScRk7qkNog9-yGwV5c,7355
|
|
3
|
-
isar/script.py,sha256=
|
|
3
|
+
isar/script.py,sha256=C9u5jIYXpnH8JuEqTSPfbuvZiSi3O9SjnvzHV-AtDbM,5988
|
|
4
4
|
isar/apis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
isar/apis/api.py,sha256=vUy7QbHrKcTHjh2rkU7lqQPkCasI6umha8r6H88JiXE,13942
|
|
6
6
|
isar/apis/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
7
|
isar/apis/models/models.py,sha256=HzLaWhjAv0uJRBWipIgYg_F75eaQ5jl9Pi4UnYbDJ-M,1749
|
|
8
|
-
isar/apis/models/start_mission_definition.py,sha256=
|
|
8
|
+
isar/apis/models/start_mission_definition.py,sha256=kctM1kaK3a8z3Sd307QPZO9T_0OpDGQeGQVjOo49pCc,8775
|
|
9
9
|
isar/apis/robot_control/robot_controller.py,sha256=w0giQf8k1TCL_J_kAcBB8Tgk02laWDCiDiFE8E5sPrg,915
|
|
10
10
|
isar/apis/schedule/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
11
|
isar/apis/schedule/scheduling_controller.py,sha256=9S7OtFCfO0hR9gWtj2u2oqa2Hxj9ynpcXxgqdk5liQ4,11328
|
|
@@ -16,7 +16,7 @@ isar/config/configuration_error.py,sha256=rO6WOhafX6xvVib8WxV-eY483Z0PpN-9PxGsq5
|
|
|
16
16
|
isar/config/log.py,sha256=zHFLmGWQRn8TrcsxUS6KHpJt2JE86kYazU7b-bkcN9o,2285
|
|
17
17
|
isar/config/logging.conf,sha256=mYO1xf27gAopEMHhGzY7-mwyfN16rwRLkPNMvy3zn2g,1127
|
|
18
18
|
isar/config/settings.env,sha256=hJFfyl4S84nmcyf70Pz8nbGlPf4KTVx0UkgP3uf6T8E,534
|
|
19
|
-
isar/config/settings.py,sha256=
|
|
19
|
+
isar/config/settings.py,sha256=1yKab8R_3x-fd296_GolULsQBcarWdvO2gdMnZChr-s,13175
|
|
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
|
|
@@ -65,13 +65,14 @@ isar/services/utilities/robot_utilities.py,sha256=4-ob4kcIiRN_GXFDBMwBadfbwpYqKE
|
|
|
65
65
|
isar/services/utilities/scheduling_utilities.py,sha256=xQ1UqxxTRk2VpTVj7mL_ux9xqoaiSd45W7VAPmpXSfU,8509
|
|
66
66
|
isar/services/utilities/threaded_request.py,sha256=py4G-_RjnIdHljmKFAcQ6ddqMmp-ZYV39Ece-dqRqjs,1874
|
|
67
67
|
isar/state_machine/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
68
|
-
isar/state_machine/state_machine.py,sha256=
|
|
69
|
-
isar/state_machine/states_enum.py,sha256=
|
|
68
|
+
isar/state_machine/state_machine.py,sha256=hZCxG6WuZYtgErohRWIamebEoqAczcOacCqqVyUWy8E,22994
|
|
69
|
+
isar/state_machine/states_enum.py,sha256=GrX2dzVXsyI9vXxIgd7DpOP8V1nhXQS4Jym5z69acHY,332
|
|
70
70
|
isar/state_machine/states/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
71
|
-
isar/state_machine/states/
|
|
71
|
+
isar/state_machine/states/blocked_protective_stop.py,sha256=FNOarwHzkUfRllyxltXSu7W_nXAxpqDhz9PIo6wxE1o,2259
|
|
72
|
+
isar/state_machine/states/idle.py,sha256=96CZCpBBPAZE_szF0UoPh6tBRsDn3FYII8bZ_cBFGuw,3815
|
|
72
73
|
isar/state_machine/states/initialize.py,sha256=TVXV5Ps3N4_flM88j9pQiX88kZgLzLwzlJy_6hPbgcA,2359
|
|
73
74
|
isar/state_machine/states/initiate.py,sha256=j1wvSC3zVODgRkKOVsQROiuWkjihSBtwCs5GsoivLvc,5655
|
|
74
|
-
isar/state_machine/states/monitor.py,sha256=
|
|
75
|
+
isar/state_machine/states/monitor.py,sha256=yQORqROd8jt86T2gPXzw1hGLwhO6IQBRuzf7DzPhVU4,10309
|
|
75
76
|
isar/state_machine/states/off.py,sha256=jjqN_oJMpBtWuY7hP-c9f0w3p2CYCfe-NpmYHHPnmyI,544
|
|
76
77
|
isar/state_machine/states/offline.py,sha256=IfEZ6-kl6OfJSRT1eKHOey7AU23tKiSHqpwGqclmH_c,2166
|
|
77
78
|
isar/state_machine/states/paused.py,sha256=TIg1iJvAxGUIfzE_qWp0wrq4Ka0a3zEf3GNwIWLIK0M,1177
|
|
@@ -81,35 +82,35 @@ isar/storage/blob_storage.py,sha256=L885tgwHeeIp8raIz20Hhbc1IMsQP0wK6HOX9I4sZlw,
|
|
|
81
82
|
isar/storage/local_storage.py,sha256=Bnmoi5gyN8r-oRh0aHrOdGqaH3JqRScFKMRXYojW5kY,1855
|
|
82
83
|
isar/storage/slimm_storage.py,sha256=iVtc7w_VPFoe0fWyPpI9kjau3C1rn7w2n5EJaqloFIU,8991
|
|
83
84
|
isar/storage/storage_interface.py,sha256=DYDry4I7aZpDHJhsBF6s8zrgokFAc7fdKJKfA8AvL7o,828
|
|
84
|
-
isar/storage/uploader.py,sha256=
|
|
85
|
+
isar/storage/uploader.py,sha256=LrbGlAGoqspWtSjmZcfvbRL3_khCnLWwa64XhqUrsr4,6543
|
|
85
86
|
isar/storage/utilities.py,sha256=fitsdQ1ox5gr9fk9VuSk_iTBiEAIS8NZAnHabUZORh0,3173
|
|
86
87
|
robot_interface/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
87
88
|
robot_interface/robot_interface.py,sha256=UEhzAj1kXOdyYiWjz8zxEo5BHMHRE-ZHalPFfv-qBfw,9697
|
|
88
89
|
robot_interface/test_robot_interface.py,sha256=FV1urn7SbsMyWBIcTKjsBwAG4IsXeZ6pLHE0mA9EGGs,692
|
|
89
90
|
robot_interface/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
90
91
|
robot_interface/models/exceptions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
91
|
-
robot_interface/models/exceptions/robot_exceptions.py,sha256=
|
|
92
|
+
robot_interface/models/exceptions/robot_exceptions.py,sha256=DvhH0FxW_7HSLZc43rlF34_lZnb5AY8hx3k9ZkPq7WM,10432
|
|
92
93
|
robot_interface/models/initialize/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
93
94
|
robot_interface/models/initialize/initialize_params.py,sha256=2eG5Aq5bDKU6tVkaUMAoc46GERBgyaKkqv6yLupdRLc,164
|
|
94
95
|
robot_interface/models/inspection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
95
96
|
robot_interface/models/inspection/inspection.py,sha256=nSoKTDPRWnpaJuoKnaE_2EEJ6oH4dQkqEuECcQTvVhI,2059
|
|
96
97
|
robot_interface/models/mission/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
97
98
|
robot_interface/models/mission/mission.py,sha256=QZBDQiOmpb4C7nNCf1PaCWwpvAc8jrhwHSznOe2YhX8,842
|
|
98
|
-
robot_interface/models/mission/status.py,sha256=
|
|
99
|
+
robot_interface/models/mission/status.py,sha256=48y8HEiT7QQbMLBUBYxXR92iZOrnBOukPZ7o09CCR1Q,686
|
|
99
100
|
robot_interface/models/mission/task.py,sha256=dk_CYaABD9WxQswd1xX3D5AHpcXwREwnloREEg1JbI0,4980
|
|
100
101
|
robot_interface/models/robots/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
101
|
-
robot_interface/models/robots/battery_state.py,sha256=
|
|
102
|
-
robot_interface/models/robots/media.py,sha256=
|
|
103
|
-
robot_interface/models/robots/robot_model.py,sha256
|
|
102
|
+
robot_interface/models/robots/battery_state.py,sha256=ktOtJ8ltdK0k_i7BoqYfhc5dbOzIG6Oo-uWC67fCWio,98
|
|
103
|
+
robot_interface/models/robots/media.py,sha256=8A-CuuubfngzPprs6zWB9hSaqe3jzgsE8rcCzRX2Uto,227
|
|
104
|
+
robot_interface/models/robots/robot_model.py,sha256=-0jNKWPcEgtF_2klb1It3u0SCoAR0hSW9nce58Zq0Co,417
|
|
104
105
|
robot_interface/telemetry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
105
106
|
robot_interface/telemetry/mqtt_client.py,sha256=DkzYZNWFaJkG3AVc0dM4Bj52hZEQj-14Q75zqzQcv9A,2988
|
|
106
|
-
robot_interface/telemetry/payloads.py,sha256=
|
|
107
|
+
robot_interface/telemetry/payloads.py,sha256=_Ph2f1M5f18fTJ7Jrd3JCeXhfZzg6i3THlFrbAt2DJA,2329
|
|
107
108
|
robot_interface/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
108
109
|
robot_interface/utilities/json_service.py,sha256=nU2Q_3P9Fq9hs6F_wtUjWtHfl_g1Siy-yDhXXSKwHwg,1018
|
|
109
110
|
robot_interface/utilities/uuid_string_factory.py,sha256=_NQIbBQ56w0qqO0MUDP6aPpHbxW7ATRhK8HnQiBSLkc,76
|
|
110
|
-
isar-1.25.
|
|
111
|
-
isar-1.25.
|
|
112
|
-
isar-1.25.
|
|
113
|
-
isar-1.25.
|
|
114
|
-
isar-1.25.
|
|
115
|
-
isar-1.25.
|
|
111
|
+
isar-1.25.5.dist-info/LICENSE,sha256=3fc2-ebLwHWwzfQbulGNRdcNob3SBQeCfEVUDYxsuqw,14058
|
|
112
|
+
isar-1.25.5.dist-info/METADATA,sha256=I23_1dDDBsHf1UegjEmUQCvU8oAWjFloe5eXWVDZndU,30578
|
|
113
|
+
isar-1.25.5.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
114
|
+
isar-1.25.5.dist-info/entry_points.txt,sha256=TFam7uNNw7J0iiDYzsH2gfG0u1eV1wh3JTw_HkhgKLk,49
|
|
115
|
+
isar-1.25.5.dist-info/top_level.txt,sha256=UwIML2RtuQKCyJJkatcSnyp6-ldDjboB9k9JgKipO-U,21
|
|
116
|
+
isar-1.25.5.dist-info/RECORD,,
|
|
@@ -4,28 +4,26 @@ from typing import Optional
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class ErrorReason(str, Enum):
|
|
7
|
-
RobotCommunicationException
|
|
8
|
-
RobotCommunicationTimeoutException
|
|
9
|
-
RobotInfeasibleTaskException
|
|
10
|
-
RobotInfeasibleMissionException
|
|
11
|
-
RobotMissionStatusException
|
|
12
|
-
RobotTaskStatusException
|
|
13
|
-
RobotAPIException
|
|
14
|
-
RobotActionException
|
|
15
|
-
RobotInitializeException
|
|
16
|
-
RobotRetrieveDataException
|
|
17
|
-
RobotRetrieveInspectionException
|
|
18
|
-
RobotTelemetryException
|
|
19
|
-
RobotTelemetryNoUpdateException
|
|
20
|
-
RobotTelemetryPoseException
|
|
21
|
-
RobotMapException
|
|
22
|
-
RobotTransformException
|
|
23
|
-
RobotUnknownErrorException
|
|
24
|
-
RobotDisconnectedException
|
|
25
|
-
RobotMissionNotSupportedException
|
|
26
|
-
RobotMissionMissingStartPoseException
|
|
27
|
-
"robot_mission_missing_start_pose_exception"
|
|
28
|
-
)
|
|
7
|
+
RobotCommunicationException = "robot_communication_exception"
|
|
8
|
+
RobotCommunicationTimeoutException = "robot_communication_timeout_exception"
|
|
9
|
+
RobotInfeasibleTaskException = "robot_infeasible_task_exception"
|
|
10
|
+
RobotInfeasibleMissionException = "robot_infeasible_mission_exception"
|
|
11
|
+
RobotMissionStatusException = "robot_mission_status_exception"
|
|
12
|
+
RobotTaskStatusException = "robot_task_status_exception"
|
|
13
|
+
RobotAPIException = "robot_api_exception"
|
|
14
|
+
RobotActionException = "robot_action_exception"
|
|
15
|
+
RobotInitializeException = "robot_initialize_exception"
|
|
16
|
+
RobotRetrieveDataException = "robot_retrieve_data_exception"
|
|
17
|
+
RobotRetrieveInspectionException = "robot_retrieve_inspection_exception"
|
|
18
|
+
RobotTelemetryException = "robot_telemetry_exception"
|
|
19
|
+
RobotTelemetryNoUpdateException = "robot_telemetry_no_update_exception"
|
|
20
|
+
RobotTelemetryPoseException = "robot_telemetry_pose_exception"
|
|
21
|
+
RobotMapException = "robot_map_exception"
|
|
22
|
+
RobotTransformException = "robot_transform_exception"
|
|
23
|
+
RobotUnknownErrorException = "robot_unknown_error_exception"
|
|
24
|
+
RobotDisconnectedException = "robot_disconnected_exception"
|
|
25
|
+
RobotMissionNotSupportedException = "robot_mission_not_supported_exception"
|
|
26
|
+
RobotMissionMissingStartPoseException = "robot_mission_missing_start_pose_exception"
|
|
29
27
|
|
|
30
28
|
|
|
31
29
|
@dataclass
|
|
@@ -2,27 +2,28 @@ from enum import Enum
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
class MissionStatus(str, Enum):
|
|
5
|
-
NotStarted
|
|
6
|
-
InProgress
|
|
7
|
-
Paused
|
|
8
|
-
Failed
|
|
9
|
-
Cancelled
|
|
10
|
-
Successful
|
|
11
|
-
PartiallySuccessful
|
|
5
|
+
NotStarted = "not_started"
|
|
6
|
+
InProgress = "in_progress"
|
|
7
|
+
Paused = "paused"
|
|
8
|
+
Failed = "failed"
|
|
9
|
+
Cancelled = "cancelled"
|
|
10
|
+
Successful = "successful"
|
|
11
|
+
PartiallySuccessful = "partially_successful"
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class TaskStatus(str, Enum):
|
|
15
|
-
NotStarted
|
|
16
|
-
InProgress
|
|
17
|
-
Paused
|
|
18
|
-
Failed
|
|
19
|
-
Cancelled
|
|
20
|
-
Successful
|
|
21
|
-
PartiallySuccessful
|
|
15
|
+
NotStarted = "not_started"
|
|
16
|
+
InProgress = "in_progress"
|
|
17
|
+
Paused = "paused"
|
|
18
|
+
Failed = "failed"
|
|
19
|
+
Cancelled = "cancelled"
|
|
20
|
+
Successful = "successful"
|
|
21
|
+
PartiallySuccessful = "partially_successful"
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
class RobotStatus(Enum):
|
|
25
|
-
Available
|
|
26
|
-
Busy
|
|
27
|
-
Offline
|
|
28
|
-
Blocked
|
|
25
|
+
Available = "available"
|
|
26
|
+
Busy = "busy"
|
|
27
|
+
Offline = "offline"
|
|
28
|
+
Blocked = "blocked"
|
|
29
|
+
BlockedProtectiveStop = "blockedprotectivestop"
|
|
@@ -4,10 +4,10 @@ from enum import Enum
|
|
|
4
4
|
# Did you write your own isar-robot package and would like to have it included here?
|
|
5
5
|
# Open a pull request to the ISAR repository!
|
|
6
6
|
class RobotModel(Enum):
|
|
7
|
-
TaurobInspector
|
|
8
|
-
TaurobOperator
|
|
9
|
-
ExR2
|
|
10
|
-
Robot
|
|
11
|
-
Turtlebot
|
|
12
|
-
AnymalX
|
|
13
|
-
AnymalD
|
|
7
|
+
TaurobInspector = "TaurobInspector"
|
|
8
|
+
TaurobOperator = "TaurobOperator"
|
|
9
|
+
ExR2 = "ExR2"
|
|
10
|
+
Robot = "Robot" # This corresponds to the mock in isar_robot
|
|
11
|
+
Turtlebot = "Turtlebot"
|
|
12
|
+
AnymalX = "AnymalX"
|
|
13
|
+
AnymalD = "AnymalD"
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
2
|
from datetime import datetime
|
|
3
|
-
from typing import List, Optional
|
|
3
|
+
from typing import List, Optional, Union
|
|
4
4
|
|
|
5
5
|
from alitra import Pose
|
|
6
|
-
from transitions import State
|
|
7
6
|
|
|
8
|
-
from robot_interface.models.mission.status import RobotStatus
|
|
9
7
|
from robot_interface.models.robots.battery_state import BatteryState
|
|
8
|
+
from robot_interface.models.mission.status import RobotStatus, MissionStatus, TaskStatus
|
|
9
|
+
from robot_interface.models.mission.task import TaskTypes
|
|
10
|
+
from robot_interface.models.exceptions.robot_exceptions import ErrorReason
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
@dataclass
|
|
@@ -54,12 +55,7 @@ class DocumentInfo:
|
|
|
54
55
|
class RobotStatusPayload:
|
|
55
56
|
isar_id: str
|
|
56
57
|
robot_name: str
|
|
57
|
-
|
|
58
|
-
previous_robot_status: RobotStatus
|
|
59
|
-
current_isar_state: State
|
|
60
|
-
current_mission_id: str
|
|
61
|
-
current_task_id: str
|
|
62
|
-
current_step_id: str
|
|
58
|
+
status: RobotStatus
|
|
63
59
|
timestamp: datetime
|
|
64
60
|
|
|
65
61
|
|
|
@@ -82,3 +78,38 @@ class RobotHeartbeatPayload:
|
|
|
82
78
|
isar_id: str
|
|
83
79
|
robot_name: str
|
|
84
80
|
timestamp: datetime
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@dataclass
|
|
84
|
+
class MissionPayload:
|
|
85
|
+
isar_id: str
|
|
86
|
+
robot_name: str
|
|
87
|
+
mission_id: Optional[str]
|
|
88
|
+
status: Optional[MissionStatus]
|
|
89
|
+
error_reason: Optional[ErrorReason]
|
|
90
|
+
error_description: Optional[str]
|
|
91
|
+
timestamp: datetime
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
@dataclass
|
|
95
|
+
class TaskPayload:
|
|
96
|
+
isar_id: str
|
|
97
|
+
robot_name: str
|
|
98
|
+
mission_id: Optional[str]
|
|
99
|
+
task_id: Optional[str]
|
|
100
|
+
status: Optional[TaskStatus]
|
|
101
|
+
task_type: Optional[TaskTypes]
|
|
102
|
+
error_reason: Optional[ErrorReason]
|
|
103
|
+
error_description: Optional[str]
|
|
104
|
+
timestamp: datetime
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
@dataclass
|
|
108
|
+
class InspectionResultPayload:
|
|
109
|
+
isar_id: str
|
|
110
|
+
robot_name: str
|
|
111
|
+
inspection_id: str
|
|
112
|
+
inspection_path: Union[str, dict]
|
|
113
|
+
installation_code: str
|
|
114
|
+
analysis_to_be_run: Optional[str]
|
|
115
|
+
timestamp: datetime
|
|
File without changes
|
|
File without changes
|
|
File without changes
|