isar 1.25.9__py3-none-any.whl → 1.26.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of isar might be problematic. Click here for more details.
- isar/apis/models/start_mission_definition.py +55 -112
- isar/apis/robot_control/robot_controller.py +5 -4
- isar/apis/schedule/scheduling_controller.py +6 -57
- isar/apis/security/authentication.py +2 -2
- isar/config/settings.env +1 -3
- isar/config/settings.py +6 -6
- isar/models/communication/message.py +0 -4
- isar/models/communication/queues/events.py +57 -0
- isar/models/communication/queues/queue_utils.py +32 -0
- isar/models/communication/queues/status_queue.py +7 -5
- isar/modules.py +26 -13
- isar/robot/robot.py +124 -0
- isar/robot/robot_start_mission.py +73 -0
- isar/robot/robot_status.py +49 -0
- isar/robot/robot_stop_mission.py +72 -0
- isar/robot/robot_task_status.py +92 -0
- isar/script.py +14 -7
- isar/services/utilities/scheduling_utilities.py +21 -30
- isar/state_machine/state_machine.py +70 -212
- isar/state_machine/states/blocked_protective_stop.py +10 -30
- isar/state_machine/states/idle.py +45 -67
- isar/state_machine/states/monitor.py +129 -139
- isar/state_machine/states/offline.py +12 -33
- isar/state_machine/states/paused.py +6 -3
- isar/state_machine/states/stop.py +29 -58
- isar/state_machine/states_enum.py +0 -2
- isar/state_machine/transitions/fail_mission.py +13 -0
- isar/state_machine/transitions/finish_mission.py +39 -0
- isar/state_machine/transitions/pause.py +24 -0
- isar/state_machine/transitions/resume.py +27 -0
- isar/state_machine/transitions/start_mission.py +73 -0
- isar/state_machine/transitions/stop.py +40 -0
- isar/state_machine/transitions/utils.py +10 -0
- isar/storage/slimm_storage.py +2 -2
- isar/storage/uploader.py +5 -5
- {isar-1.25.9.dist-info → isar-1.26.1.dist-info}/METADATA +5 -19
- {isar-1.25.9.dist-info → isar-1.26.1.dist-info}/RECORD +45 -34
- {isar-1.25.9.dist-info → isar-1.26.1.dist-info}/WHEEL +1 -1
- robot_interface/models/mission/task.py +1 -1
- robot_interface/telemetry/mqtt_client.py +0 -1
- robot_interface/telemetry/payloads.py +3 -3
- robot_interface/utilities/json_service.py +1 -1
- isar/models/communication/queues/queues.py +0 -19
- isar/state_machine/states/initialize.py +0 -70
- isar/state_machine/states/initiate.py +0 -111
- {isar-1.25.9.dist-info → isar-1.26.1.dist-info}/entry_points.txt +0 -0
- {isar-1.25.9.dist-info → isar-1.26.1.dist-info/licenses}/LICENSE +0 -0
- {isar-1.25.9.dist-info → isar-1.26.1.dist-info}/top_level.txt +0 -0
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import time
|
|
3
|
-
from
|
|
3
|
+
from queue import Queue
|
|
4
|
+
from typing import TYPE_CHECKING, Optional
|
|
4
5
|
|
|
5
6
|
from transitions import State
|
|
6
7
|
|
|
7
|
-
from isar.
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
)
|
|
11
|
-
from robot_interface.models.exceptions.robot_exceptions import (
|
|
12
|
-
ErrorMessage,
|
|
13
|
-
RobotActionException,
|
|
14
|
-
RobotException,
|
|
15
|
-
)
|
|
8
|
+
from isar.models.communication.queues.queue_utils import check_for_event
|
|
9
|
+
from isar.services.utilities.threaded_request import ThreadedRequest
|
|
10
|
+
from robot_interface.models.exceptions.robot_exceptions import ErrorMessage
|
|
16
11
|
|
|
17
12
|
if TYPE_CHECKING:
|
|
18
13
|
from isar.state_machine.state_machine import StateMachine
|
|
@@ -23,6 +18,7 @@ class Stop(State):
|
|
|
23
18
|
super().__init__(name="stop", on_enter=self.start, on_exit=self.stop)
|
|
24
19
|
self.state_machine: "StateMachine" = state_machine
|
|
25
20
|
self.logger = logging.getLogger("state_machine")
|
|
21
|
+
self.events = self.state_machine.events
|
|
26
22
|
self.stop_thread: Optional[ThreadedRequest] = None
|
|
27
23
|
self._count_number_retries: int = 0
|
|
28
24
|
|
|
@@ -36,56 +32,31 @@ class Stop(State):
|
|
|
36
32
|
self.stop_thread = None
|
|
37
33
|
self._count_number_retries = 0
|
|
38
34
|
|
|
39
|
-
def
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
try:
|
|
47
|
-
self.stop_thread.get_output()
|
|
48
|
-
except ThreadedRequestNotFinishedError:
|
|
49
|
-
time.sleep(self.state_machine.sleep_time)
|
|
50
|
-
continue
|
|
51
|
-
|
|
52
|
-
except (RobotActionException, RobotException) as e:
|
|
53
|
-
if self.handle_stop_fail(
|
|
54
|
-
retry_limit=self.state_machine.stop_robot_attempts_limit,
|
|
55
|
-
error_message=ErrorMessage(
|
|
56
|
-
error_reason=e.error_reason,
|
|
57
|
-
error_description=e.error_description,
|
|
58
|
-
),
|
|
59
|
-
):
|
|
60
|
-
transition = self.state_machine.mission_stopped # type: ignore
|
|
61
|
-
break
|
|
62
|
-
|
|
63
|
-
self.logger.warning(
|
|
64
|
-
f"\nFailed to stop robot because: {e.error_description}"
|
|
65
|
-
f"\nAttempting to stop the robot again"
|
|
66
|
-
)
|
|
67
|
-
|
|
68
|
-
self.stop_thread = None
|
|
69
|
-
continue
|
|
70
|
-
|
|
71
|
-
transition = self.state_machine.mission_stopped # type: ignore
|
|
35
|
+
def _check_and_handle_failed_stop(self, event: Queue[ErrorMessage]) -> bool:
|
|
36
|
+
error_message: Optional[ErrorMessage] = check_for_event(event)
|
|
37
|
+
if error_message is not None:
|
|
38
|
+
self.logger.warning(error_message.error_description)
|
|
39
|
+
self.state_machine.mission_stopped() # type: ignore
|
|
40
|
+
return True
|
|
41
|
+
return False
|
|
72
42
|
|
|
73
|
-
|
|
43
|
+
def _check_and_handle_successful_stop(self, event: Queue[bool]) -> bool:
|
|
44
|
+
if check_for_event(event):
|
|
45
|
+
self.state_machine.mission_stopped() # type: ignore
|
|
46
|
+
return True
|
|
47
|
+
return False
|
|
74
48
|
|
|
75
|
-
|
|
49
|
+
def _run(self) -> None:
|
|
50
|
+
while True:
|
|
76
51
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
52
|
+
if self._check_and_handle_failed_stop(
|
|
53
|
+
self.events.robot_service_events.mission_failed_to_stop
|
|
54
|
+
):
|
|
55
|
+
break
|
|
81
56
|
|
|
82
|
-
self.
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
"been attempted"
|
|
87
|
-
)
|
|
57
|
+
if self._check_and_handle_successful_stop(
|
|
58
|
+
self.events.robot_service_events.mission_successfully_stopped
|
|
59
|
+
):
|
|
60
|
+
break
|
|
88
61
|
|
|
89
|
-
|
|
90
|
-
time.sleep(self.state_machine.sleep_time)
|
|
91
|
-
return False
|
|
62
|
+
time.sleep(self.state_machine.sleep_time)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
2
|
+
|
|
3
|
+
if TYPE_CHECKING:
|
|
4
|
+
from isar.state_machine.state_machine import StateMachine
|
|
5
|
+
|
|
6
|
+
from robot_interface.models.mission.status import MissionStatus, TaskStatus
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def report_failed_mission_and_finalize(state_machine: "StateMachine") -> None:
|
|
10
|
+
state_machine.current_task.status = TaskStatus.Failed
|
|
11
|
+
state_machine.current_mission.status = MissionStatus.Failed
|
|
12
|
+
state_machine.publish_task_status(task=state_machine.current_task)
|
|
13
|
+
state_machine._finalize()
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, List
|
|
2
|
+
|
|
3
|
+
if TYPE_CHECKING:
|
|
4
|
+
from isar.state_machine.state_machine import StateMachine
|
|
5
|
+
|
|
6
|
+
from robot_interface.models.exceptions.robot_exceptions import ErrorMessage
|
|
7
|
+
from robot_interface.models.mission.status import MissionStatus, TaskStatus
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def finish_mission(state_machine: "StateMachine") -> bool:
|
|
11
|
+
fail_statuses: List[TaskStatus] = [
|
|
12
|
+
TaskStatus.Cancelled,
|
|
13
|
+
TaskStatus.Failed,
|
|
14
|
+
]
|
|
15
|
+
partially_fail_statuses = fail_statuses + [TaskStatus.PartiallySuccessful]
|
|
16
|
+
|
|
17
|
+
if len(state_machine.current_mission.tasks) == 0:
|
|
18
|
+
state_machine.current_mission.status = MissionStatus.Successful
|
|
19
|
+
elif all(
|
|
20
|
+
task.status in fail_statuses for task in state_machine.current_mission.tasks
|
|
21
|
+
):
|
|
22
|
+
state_machine.current_mission.error_message = ErrorMessage(
|
|
23
|
+
error_reason=None,
|
|
24
|
+
error_description="The mission failed because all tasks in the mission "
|
|
25
|
+
"failed",
|
|
26
|
+
)
|
|
27
|
+
state_machine.current_mission.status = MissionStatus.Failed
|
|
28
|
+
elif any(
|
|
29
|
+
task.status in partially_fail_statuses
|
|
30
|
+
for task in state_machine.current_mission.tasks
|
|
31
|
+
):
|
|
32
|
+
state_machine.current_mission.status = MissionStatus.PartiallySuccessful
|
|
33
|
+
else:
|
|
34
|
+
state_machine.current_mission.status = MissionStatus.Successful
|
|
35
|
+
state_machine._finalize()
|
|
36
|
+
|
|
37
|
+
state_machine.current_task = None
|
|
38
|
+
state_machine.send_task_status()
|
|
39
|
+
return True
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
2
|
+
|
|
3
|
+
if TYPE_CHECKING:
|
|
4
|
+
from isar.state_machine.state_machine import StateMachine
|
|
5
|
+
|
|
6
|
+
from isar.apis.models.models import ControlMissionResponse
|
|
7
|
+
from robot_interface.models.mission.status import MissionStatus, TaskStatus
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def pause_mission(state_machine: "StateMachine") -> bool:
|
|
11
|
+
state_machine.logger.info(f"Pausing mission: {state_machine.current_mission.id}")
|
|
12
|
+
state_machine.current_mission.status = MissionStatus.Paused
|
|
13
|
+
state_machine.current_task.status = TaskStatus.Paused
|
|
14
|
+
|
|
15
|
+
paused_mission_response: ControlMissionResponse = (
|
|
16
|
+
state_machine._make_control_mission_response()
|
|
17
|
+
)
|
|
18
|
+
state_machine.events.api_requests.pause_mission.output.put(paused_mission_response)
|
|
19
|
+
|
|
20
|
+
state_machine.publish_mission_status()
|
|
21
|
+
state_machine.publish_task_status(task=state_machine.current_task)
|
|
22
|
+
|
|
23
|
+
state_machine.robot.pause()
|
|
24
|
+
return True
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
2
|
+
|
|
3
|
+
if TYPE_CHECKING:
|
|
4
|
+
from isar.state_machine.state_machine import StateMachine
|
|
5
|
+
|
|
6
|
+
from isar.apis.models.models import ControlMissionResponse
|
|
7
|
+
from robot_interface.models.mission.status import MissionStatus, TaskStatus
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def resume_mission(state_machine: "StateMachine") -> bool:
|
|
11
|
+
state_machine.logger.info(f"Resuming mission: {state_machine.current_mission.id}")
|
|
12
|
+
state_machine.current_mission.status = MissionStatus.InProgress
|
|
13
|
+
state_machine.current_mission.error_message = None
|
|
14
|
+
state_machine.current_task.status = TaskStatus.InProgress
|
|
15
|
+
|
|
16
|
+
state_machine.mission_ongoing = True
|
|
17
|
+
|
|
18
|
+
state_machine.publish_mission_status()
|
|
19
|
+
state_machine.publish_task_status(task=state_machine.current_task)
|
|
20
|
+
|
|
21
|
+
resume_mission_response: ControlMissionResponse = (
|
|
22
|
+
state_machine._make_control_mission_response()
|
|
23
|
+
)
|
|
24
|
+
state_machine.events.api_requests.resume_mission.output.put(resume_mission_response)
|
|
25
|
+
|
|
26
|
+
state_machine.robot.resume()
|
|
27
|
+
return True
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
2
|
+
|
|
3
|
+
if TYPE_CHECKING:
|
|
4
|
+
from isar.state_machine.state_machine import StateMachine
|
|
5
|
+
|
|
6
|
+
from robot_interface.models.exceptions.robot_exceptions import (
|
|
7
|
+
ErrorMessage,
|
|
8
|
+
RobotException,
|
|
9
|
+
RobotInitializeException,
|
|
10
|
+
)
|
|
11
|
+
from robot_interface.models.mission.status import MissionStatus, TaskStatus
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def put_start_mission_on_queue(state_machine: "StateMachine") -> bool:
|
|
15
|
+
state_machine.events.api_requests.start_mission.output.put(True)
|
|
16
|
+
return True
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def initiate_mission(state_machine: "StateMachine") -> bool:
|
|
20
|
+
state_machine.logger.info(
|
|
21
|
+
f"Initialization successful. Starting new mission: "
|
|
22
|
+
f"{state_machine.current_mission.id}"
|
|
23
|
+
)
|
|
24
|
+
state_machine.log_mission_overview(mission=state_machine.current_mission)
|
|
25
|
+
|
|
26
|
+
state_machine.current_mission.status = MissionStatus.InProgress
|
|
27
|
+
state_machine.publish_mission_status()
|
|
28
|
+
state_machine.current_task = state_machine.task_selector.next_task()
|
|
29
|
+
state_machine.send_task_status()
|
|
30
|
+
if state_machine.current_task is None:
|
|
31
|
+
return False
|
|
32
|
+
|
|
33
|
+
state_machine.current_task.status = TaskStatus.InProgress
|
|
34
|
+
state_machine.publish_task_status(task=state_machine.current_task)
|
|
35
|
+
return True
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def initialize_robot(state_machine: "StateMachine") -> bool:
|
|
39
|
+
try:
|
|
40
|
+
state_machine.robot.initialize()
|
|
41
|
+
except (RobotInitializeException, RobotException) as e:
|
|
42
|
+
state_machine.current_task.error_message = ErrorMessage(
|
|
43
|
+
error_reason=e.error_reason, error_description=e.error_description
|
|
44
|
+
)
|
|
45
|
+
state_machine.logger.error(
|
|
46
|
+
f"Failed to initialize robot because: {e.error_description}"
|
|
47
|
+
)
|
|
48
|
+
_initialization_failed(state_machine)
|
|
49
|
+
return False
|
|
50
|
+
return True
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def set_mission_to_in_progress(state_machine: "StateMachine") -> bool:
|
|
54
|
+
state_machine.current_mission.status = MissionStatus.InProgress
|
|
55
|
+
state_machine.publish_task_status(task=state_machine.current_task)
|
|
56
|
+
state_machine.logger.info(
|
|
57
|
+
f"Successfully initiated "
|
|
58
|
+
f"{type(state_machine.current_task).__name__} "
|
|
59
|
+
f"task: {str(state_machine.current_task.id)[:8]}"
|
|
60
|
+
)
|
|
61
|
+
return True
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def trigger_start_mission_or_task_event(state_machine: "StateMachine") -> bool:
|
|
65
|
+
state_machine.events.state_machine_events.start_mission.put(
|
|
66
|
+
state_machine.current_mission
|
|
67
|
+
)
|
|
68
|
+
return True
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _initialization_failed(state_machine: "StateMachine") -> None:
|
|
72
|
+
state_machine.events.api_requests.start_mission.output.put(False)
|
|
73
|
+
state_machine._finalize()
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
2
|
+
|
|
3
|
+
from isar.models.communication.queues.queue_utils import trigger_event_without_data
|
|
4
|
+
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
from isar.state_machine.state_machine import StateMachine
|
|
7
|
+
|
|
8
|
+
from isar.apis.models.models import ControlMissionResponse
|
|
9
|
+
from robot_interface.models.mission.status import MissionStatus, TaskStatus
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def trigger_stop_mission_event(state_machine: "StateMachine") -> bool:
|
|
13
|
+
trigger_event_without_data(state_machine.events.state_machine_events.stop_mission)
|
|
14
|
+
return True
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def stop_mission_cleanup(state_machine: "StateMachine") -> bool:
|
|
18
|
+
if state_machine.current_mission is None:
|
|
19
|
+
state_machine._queue_empty_response()
|
|
20
|
+
state_machine.reset_state_machine()
|
|
21
|
+
return True
|
|
22
|
+
|
|
23
|
+
state_machine.current_mission.status = MissionStatus.Cancelled
|
|
24
|
+
|
|
25
|
+
for task in state_machine.current_mission.tasks:
|
|
26
|
+
if task.status in [
|
|
27
|
+
TaskStatus.NotStarted,
|
|
28
|
+
TaskStatus.InProgress,
|
|
29
|
+
TaskStatus.Paused,
|
|
30
|
+
]:
|
|
31
|
+
task.status = TaskStatus.Cancelled
|
|
32
|
+
|
|
33
|
+
stopped_mission_response: ControlMissionResponse = (
|
|
34
|
+
state_machine._make_control_mission_response()
|
|
35
|
+
)
|
|
36
|
+
state_machine.events.api_requests.stop_mission.output.put(stopped_mission_response)
|
|
37
|
+
|
|
38
|
+
state_machine.publish_task_status(task=state_machine.current_task)
|
|
39
|
+
state_machine._finalize()
|
|
40
|
+
return True
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, Callable
|
|
2
|
+
|
|
3
|
+
if TYPE_CHECKING:
|
|
4
|
+
from isar.state_machine.state_machine import StateMachine
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def def_transition(
|
|
8
|
+
state_machine: "StateMachine", transition_function: Callable[["StateMachine"], bool]
|
|
9
|
+
) -> Callable[[], bool]:
|
|
10
|
+
return lambda: transition_function(state_machine)
|
isar/storage/slimm_storage.py
CHANGED
|
@@ -100,7 +100,7 @@ class SlimmStorage(StorageInterface):
|
|
|
100
100
|
@staticmethod
|
|
101
101
|
def _construct_multiform_request_image(
|
|
102
102
|
filename: str, inspection: Inspection, mission: Mission
|
|
103
|
-
):
|
|
103
|
+
) -> MultipartEncoder:
|
|
104
104
|
array_of_orientation = (
|
|
105
105
|
inspection.metadata.pose.orientation.to_quat_array().tolist()
|
|
106
106
|
)
|
|
@@ -148,7 +148,7 @@ class SlimmStorage(StorageInterface):
|
|
|
148
148
|
filename: str,
|
|
149
149
|
inspection: Inspection,
|
|
150
150
|
mission: Mission,
|
|
151
|
-
):
|
|
151
|
+
) -> MultipartEncoder:
|
|
152
152
|
array_of_orientation = (
|
|
153
153
|
inspection.metadata.pose.orientation.to_quat_array().tolist()
|
|
154
154
|
)
|
isar/storage/uploader.py
CHANGED
|
@@ -8,7 +8,7 @@ from typing import List, Union
|
|
|
8
8
|
from injector import inject
|
|
9
9
|
|
|
10
10
|
from isar.config.settings import settings
|
|
11
|
-
from isar.models.communication.queues.
|
|
11
|
+
from isar.models.communication.queues.events import Events
|
|
12
12
|
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
|
|
@@ -48,7 +48,7 @@ class Uploader:
|
|
|
48
48
|
@inject
|
|
49
49
|
def __init__(
|
|
50
50
|
self,
|
|
51
|
-
|
|
51
|
+
events: Events,
|
|
52
52
|
storage_handlers: List[StorageInterface],
|
|
53
53
|
mqtt_publisher: MqttClientInterface,
|
|
54
54
|
max_wait_time: int = settings.UPLOAD_FAILURE_MAX_WAIT,
|
|
@@ -58,8 +58,8 @@ class Uploader:
|
|
|
58
58
|
|
|
59
59
|
Parameters
|
|
60
60
|
----------
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
events : Events
|
|
62
|
+
Events used for cross-thread communication.
|
|
63
63
|
storage_handlers : List[StorageInterface]
|
|
64
64
|
List of handlers for different upload options
|
|
65
65
|
max_wait_time : float
|
|
@@ -67,7 +67,7 @@ class Uploader:
|
|
|
67
67
|
max_retry_attempts : int
|
|
68
68
|
Maximum attempts to retry an upload when it fails
|
|
69
69
|
"""
|
|
70
|
-
self.upload_queue: Queue =
|
|
70
|
+
self.upload_queue: Queue = events.upload_queue
|
|
71
71
|
self.storage_handlers: List[StorageInterface] = storage_handlers
|
|
72
72
|
self.mqtt_publisher = mqtt_publisher
|
|
73
73
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: isar
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.26.1
|
|
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
|
|
@@ -95,6 +95,7 @@ Classifier: Programming Language :: Python :: 3.9
|
|
|
95
95
|
Classifier: Programming Language :: Python :: 3.10
|
|
96
96
|
Classifier: Programming Language :: Python :: 3.11
|
|
97
97
|
Classifier: Programming Language :: Python :: 3.12
|
|
98
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
98
99
|
Classifier: Topic :: Scientific/Engineering
|
|
99
100
|
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
100
101
|
Classifier: Topic :: Software Development :: Libraries
|
|
@@ -127,6 +128,7 @@ Requires-Dist: transitions
|
|
|
127
128
|
Requires-Dist: uvicorn
|
|
128
129
|
Provides-Extra: dev
|
|
129
130
|
Requires-Dist: black; extra == "dev"
|
|
131
|
+
Requires-Dist: isort; extra == "dev"
|
|
130
132
|
Requires-Dist: mypy; extra == "dev"
|
|
131
133
|
Requires-Dist: pip-tools; extra == "dev"
|
|
132
134
|
Requires-Dist: pre-commit; extra == "dev"
|
|
@@ -136,6 +138,7 @@ Requires-Dist: pytest-xdist; extra == "dev"
|
|
|
136
138
|
Requires-Dist: pytest; extra == "dev"
|
|
137
139
|
Requires-Dist: requests-mock; extra == "dev"
|
|
138
140
|
Requires-Dist: ruff; extra == "dev"
|
|
141
|
+
Dynamic: license-file
|
|
139
142
|
|
|
140
143
|
# ISAR
|
|
141
144
|
|
|
@@ -253,21 +256,6 @@ In [this](./src/isar/config/predefined_missions) folder there are predefined def
|
|
|
253
256
|
corresponding to `mission_id=1`. A new mission may be added by adding a new json-file with a mission description. Note,
|
|
254
257
|
the mission IDs must be unique.
|
|
255
258
|
|
|
256
|
-
### Running with docker-compose
|
|
257
|
-
|
|
258
|
-
ISAR may be started with an instance of the [isar-robot](https://github.com/equinor/isar-robot) package by
|
|
259
|
-
|
|
260
|
-
```shell
|
|
261
|
-
docker-compose up --build
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
Provided that the simulator from [isar-turtlebot](https://github.com/equinor/isar-turtlebot) is running ISAR may be
|
|
265
|
-
started with the turtlebot by
|
|
266
|
-
|
|
267
|
-
```shell
|
|
268
|
-
docker-compose -f docker-compose-turtlebot.yml up --build
|
|
269
|
-
```
|
|
270
|
-
|
|
271
259
|
### Configuration
|
|
272
260
|
|
|
273
261
|
The system consists of many configuration variables which may alter the functionality. As an example, it is possible to
|
|
@@ -350,8 +338,6 @@ In general the states
|
|
|
350
338
|
|
|
351
339
|
```
|
|
352
340
|
States.Off,
|
|
353
|
-
States.Initialize,
|
|
354
|
-
States.Initiate,
|
|
355
341
|
States.Stop,
|
|
356
342
|
States.Monitor,
|
|
357
343
|
States.Paused,
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
isar/__init__.py,sha256=cH8p8bVveu3FUL6kBhldcSlLaoHgD82Kd0-SwSNfGXw,87
|
|
2
|
-
isar/modules.py,sha256=
|
|
3
|
-
isar/script.py,sha256=
|
|
2
|
+
isar/modules.py,sha256=X0olcDdnqyKE2w5_54qQhD7Ewpdw-pLULBsg7NtSf0k,7705
|
|
3
|
+
isar/script.py,sha256=DA_rpQyvo1GM8fhOAC8iuZVsQRLtIZ-Q3VF2XivMWyQ,6157
|
|
4
4
|
isar/apis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
isar/apis/api.py,sha256=ARf7-GsjTSqWj9UOSiEJ1YnSF-fH7Tr0-mkkfL10MZ4,12620
|
|
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=
|
|
9
|
-
isar/apis/robot_control/robot_controller.py,sha256=
|
|
8
|
+
isar/apis/models/start_mission_definition.py,sha256=rGpdb51LIrGRE5RjBONWflumow4ev8oTbDTx5Ph2_Pc,6210
|
|
9
|
+
isar/apis/robot_control/robot_controller.py,sha256=D8LVMU8TRLohn1nlw2NQXjOxYmzjsOwjm_kr6f-h2VY,1259
|
|
10
10
|
isar/apis/schedule/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
-
isar/apis/schedule/scheduling_controller.py,sha256=
|
|
11
|
+
isar/apis/schedule/scheduling_controller.py,sha256=aKfISl781FTByZMkRYvLhWzbhUDJmUqpAtDUvhMyc3U,7799
|
|
12
12
|
isar/apis/security/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
-
isar/apis/security/authentication.py,sha256=
|
|
13
|
+
isar/apis/security/authentication.py,sha256=kGveLAKqEwpP7eNNRbBUv7R1PHFJRWgh4uDujEPhcmo,1991
|
|
14
14
|
isar/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
15
|
isar/config/configuration_error.py,sha256=rO6WOhafX6xvVib8WxV-eY483Z0PpN-9PxGsq5ATfKc,46
|
|
16
16
|
isar/config/log.py,sha256=zHFLmGWQRn8TrcsxUS6KHpJt2JE86kYazU7b-bkcN9o,2285
|
|
17
17
|
isar/config/logging.conf,sha256=mYO1xf27gAopEMHhGzY7-mwyfN16rwRLkPNMvy3zn2g,1127
|
|
18
|
-
isar/config/settings.env,sha256=
|
|
19
|
-
isar/config/settings.py,sha256=
|
|
18
|
+
isar/config/settings.env,sha256=cLIlcXTM8x0N-6XjXmC0Qclx5dfDC6myqa25tvVwmRw,500
|
|
19
|
+
isar/config/settings.py,sha256=cFKINb2VRBrLLCzSK0zmRny2fu7S3sGKbDCBv28DxHI,12859
|
|
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,13 +42,19 @@ isar/mission_planner/sequential_task_selector.py,sha256=66agRPHuJnEa1vArPyty4muT
|
|
|
42
42
|
isar/mission_planner/task_selector_interface.py,sha256=pnLeaGPIuyXThcflZ_A7YL2b2xQjFT88hAZidkMomxU,707
|
|
43
43
|
isar/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
44
44
|
isar/models/communication/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
45
|
-
isar/models/communication/message.py,sha256=
|
|
45
|
+
isar/models/communication/message.py,sha256=ge2EdUXRnYkiEu5TIAYJFQET_5w-N8MRgc2Y31vetno,155
|
|
46
46
|
isar/models/communication/queues/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
47
|
+
isar/models/communication/queues/events.py,sha256=2UjFWmjQeYavRzF336H4rqe20gjMoShlX3-BXyb1W4w,2340
|
|
47
48
|
isar/models/communication/queues/queue_io.py,sha256=AnHWUCkZ0tunkxKKeBarq-OUkRM97IaMfA-a1pmf1cQ,394
|
|
48
49
|
isar/models/communication/queues/queue_timeout_error.py,sha256=rF8TlNF7RHS_ueTZ5mp7aFkhLY1j0dcwMwH-Ba6lVpE,45
|
|
49
|
-
isar/models/communication/queues/
|
|
50
|
-
isar/models/communication/queues/status_queue.py,sha256
|
|
50
|
+
isar/models/communication/queues/queue_utils.py,sha256=BGydIndLOFbj_Hyd2RiAlwdm7rWrem9BzoAnXH-ulxo,684
|
|
51
|
+
isar/models/communication/queues/status_queue.py,sha256=on8kvlNsG6MJjEVsyqtBswIpmOdOggQiKr7F5x0T3jw,514
|
|
51
52
|
isar/models/mission_metadata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
53
|
+
isar/robot/robot.py,sha256=t7spWRnZwMVkohs6trrnZjTCxarOH1cPU8iy9vaYTiM,4699
|
|
54
|
+
isar/robot/robot_start_mission.py,sha256=pppndYWPmg-GxU69RglB-4L4MlgXdLcsd0S5gFtfM3o,2767
|
|
55
|
+
isar/robot/robot_status.py,sha256=l7tS-Rl-Xj0f8TgdCuZrhvi4Ubckw92u1VfBOoAFbUM,1605
|
|
56
|
+
isar/robot/robot_stop_mission.py,sha256=V7hSfjeoprqkCwbLoDEHeIELPLRR0HvYH7Uc-_Wa8dM,2443
|
|
57
|
+
isar/robot/robot_task_status.py,sha256=iSSfxn8uu40-qouT0sgPwIcB8h-2Bm3m3_tlXTuLoKk,3306
|
|
52
58
|
isar/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
53
59
|
isar/services/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
54
60
|
isar/services/auth/azure_credentials.py,sha256=9PlwGe5FrPRbW2dp0go7LMp8_l_FRvL8xOXotXwzRDo,364
|
|
@@ -62,28 +68,34 @@ isar/services/service_connections/stid/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JC
|
|
|
62
68
|
isar/services/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
63
69
|
isar/services/utilities/queue_utilities.py,sha256=Pw3hehSwkXJNeDv-bDVDfs58VOwtt3i5hpiJ2ZpphuQ,1225
|
|
64
70
|
isar/services/utilities/robot_utilities.py,sha256=4-ob4kcIiRN_GXFDBMwBadfbwpYqKEkyzyC40wzvmko,555
|
|
65
|
-
isar/services/utilities/scheduling_utilities.py,sha256=
|
|
71
|
+
isar/services/utilities/scheduling_utilities.py,sha256=WaQXEK_cmPM9KNP3aBZGVnZCi97kR-M_rJWyWIGWZa4,8238
|
|
66
72
|
isar/services/utilities/threaded_request.py,sha256=py4G-_RjnIdHljmKFAcQ6ddqMmp-ZYV39Ece-dqRqjs,1874
|
|
67
73
|
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=
|
|
74
|
+
isar/state_machine/state_machine.py,sha256=2Ibgb7NXpMv3tbKQlm8eZp-4esOWbrHerCT2RGq6o_0,15245
|
|
75
|
+
isar/state_machine/states_enum.py,sha256=uqa3VD2Ig0PR5xG7s4-q5OLWiGdvEn-KYClv3KpRJ68,276
|
|
70
76
|
isar/state_machine/states/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
71
|
-
isar/state_machine/states/blocked_protective_stop.py,sha256=
|
|
72
|
-
isar/state_machine/states/idle.py,sha256=
|
|
73
|
-
isar/state_machine/states/
|
|
74
|
-
isar/state_machine/states/initiate.py,sha256=xtKopnU5Ug_0PAV3yFm0v8O7DCa5CwGE4vN_7qahA0A,4139
|
|
75
|
-
isar/state_machine/states/monitor.py,sha256=5BpEO-yzVE_yJc6POdvcECOXyQDXMiijVry4C0s6tIw,9759
|
|
77
|
+
isar/state_machine/states/blocked_protective_stop.py,sha256=_InOhfCwCshrdUOquDy-js0cMrk8ddgPsHbHMLJzlNU,1540
|
|
78
|
+
isar/state_machine/states/idle.py,sha256=0E9vFMXVJ7u2det3aN17KaNIBosA0zHr5mHIZqPL7dU,2771
|
|
79
|
+
isar/state_machine/states/monitor.py,sha256=v-gPPjxmhNDpA2IKa7X1rm_xZC84pqHmgfSqCodz8PY,9153
|
|
76
80
|
isar/state_machine/states/off.py,sha256=jjqN_oJMpBtWuY7hP-c9f0w3p2CYCfe-NpmYHHPnmyI,544
|
|
77
|
-
isar/state_machine/states/offline.py,sha256
|
|
78
|
-
isar/state_machine/states/paused.py,sha256=
|
|
79
|
-
isar/state_machine/states/stop.py,sha256=
|
|
81
|
+
isar/state_machine/states/offline.py,sha256=-4PgEm52rnOXqhFYy0phXfPaNq99xkeBm_ylla-jPeU,1380
|
|
82
|
+
isar/state_machine/states/paused.py,sha256=r0jXxlTIwsVw8eR3vNRPMjz-rzKepyaCrzquKLd0E9o,1156
|
|
83
|
+
isar/state_machine/states/stop.py,sha256=bGtukno8n_f6nHqW6Zow4e21TYA72Vvmhj8coUFBLYM,2147
|
|
84
|
+
isar/state_machine/transitions/fail_mission.py,sha256=_6HqBMALDinFZ4yh5GMpeqqgV5tw5i8OVMj5UDdqesg,495
|
|
85
|
+
isar/state_machine/transitions/finish_mission.py,sha256=TRQrk7HdllmAkwsp25HRZAFAk46Y1hLx3jmkIAKrHDI,1442
|
|
86
|
+
isar/state_machine/transitions/pause.py,sha256=LbSNXDKjWzaoYATwu4ZgvWLd6rDXgwrV-ioweirqhvA,888
|
|
87
|
+
isar/state_machine/transitions/resume.py,sha256=q_3rstGmlQpEOA_I0m9q7N8N6MhpVRMnFTiUdlNXDwI,997
|
|
88
|
+
isar/state_machine/transitions/start_mission.py,sha256=BJdJvk0O5kq2DZkRHroVtkBziMivNTsZVX3KLJ-m7YQ,2524
|
|
89
|
+
isar/state_machine/transitions/stop.py,sha256=NzPvr6C1tmDqji5XJf5vw9up_Ow7ApuhjAzDVlJLZPw,1368
|
|
90
|
+
isar/state_machine/transitions/utils.py,sha256=Wa72Ocq4QT1E6qkpEJZQ3h5o33pGvx7Tlkt2JZ2Grbk,314
|
|
80
91
|
isar/storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
81
92
|
isar/storage/blob_storage.py,sha256=L885tgwHeeIp8raIz20Hhbc1IMsQP0wK6HOX9I4sZlw,3199
|
|
82
93
|
isar/storage/local_storage.py,sha256=Bnmoi5gyN8r-oRh0aHrOdGqaH3JqRScFKMRXYojW5kY,1855
|
|
83
|
-
isar/storage/slimm_storage.py,sha256=
|
|
94
|
+
isar/storage/slimm_storage.py,sha256=4UON1tcrP-p1w1atDqtdCmKwmfj9dwwuCIt18d8adZk,9031
|
|
84
95
|
isar/storage/storage_interface.py,sha256=DYDry4I7aZpDHJhsBF6s8zrgokFAc7fdKJKfA8AvL7o,828
|
|
85
|
-
isar/storage/uploader.py,sha256=
|
|
96
|
+
isar/storage/uploader.py,sha256=mJ-ax_6SvNpM2fG8WdyOUVKSB_J_nedJlCTJ_Xg2E4c,6543
|
|
86
97
|
isar/storage/utilities.py,sha256=fitsdQ1ox5gr9fk9VuSk_iTBiEAIS8NZAnHabUZORh0,3173
|
|
98
|
+
isar-1.26.1.dist-info/licenses/LICENSE,sha256=3fc2-ebLwHWwzfQbulGNRdcNob3SBQeCfEVUDYxsuqw,14058
|
|
87
99
|
robot_interface/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
88
100
|
robot_interface/robot_interface.py,sha256=Bkk-joyIzRHxv8iZt7FLPFnlE8chlJad9vgjwc-fDkw,8786
|
|
89
101
|
robot_interface/test_robot_interface.py,sha256=FV1urn7SbsMyWBIcTKjsBwAG4IsXeZ6pLHE0mA9EGGs,692
|
|
@@ -96,20 +108,19 @@ robot_interface/models/inspection/inspection.py,sha256=Q8vyiTMV2Ws1B4N10kQ3C1AZk
|
|
|
96
108
|
robot_interface/models/mission/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
97
109
|
robot_interface/models/mission/mission.py,sha256=GR_X9-dIf-15oogfv_c6JNIKnTIk5u80rWLNUk95xm0,738
|
|
98
110
|
robot_interface/models/mission/status.py,sha256=48y8HEiT7QQbMLBUBYxXR92iZOrnBOukPZ7o09CCR1Q,686
|
|
99
|
-
robot_interface/models/mission/task.py,sha256=
|
|
111
|
+
robot_interface/models/mission/task.py,sha256=0yDg940gOTTxbpFeh9K5iIbBSf10v16PPTy-iOBJvDQ,4896
|
|
100
112
|
robot_interface/models/robots/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
101
113
|
robot_interface/models/robots/battery_state.py,sha256=ktOtJ8ltdK0k_i7BoqYfhc5dbOzIG6Oo-uWC67fCWio,98
|
|
102
114
|
robot_interface/models/robots/media.py,sha256=8A-CuuubfngzPprs6zWB9hSaqe3jzgsE8rcCzRX2Uto,227
|
|
103
115
|
robot_interface/models/robots/robot_model.py,sha256=-0jNKWPcEgtF_2klb1It3u0SCoAR0hSW9nce58Zq0Co,417
|
|
104
116
|
robot_interface/telemetry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
105
|
-
robot_interface/telemetry/mqtt_client.py,sha256=
|
|
106
|
-
robot_interface/telemetry/payloads.py,sha256=
|
|
117
|
+
robot_interface/telemetry/mqtt_client.py,sha256=ueXdtIFNCwciTj4spvdJj9emd-IOmUuJjpsXQSSWZPY,2987
|
|
118
|
+
robot_interface/telemetry/payloads.py,sha256=m55aFrIczI-PDwQXvsFA6M7YNCTy83w7Ff-HIaZNbwI,2329
|
|
107
119
|
robot_interface/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
108
|
-
robot_interface/utilities/json_service.py,sha256=
|
|
120
|
+
robot_interface/utilities/json_service.py,sha256=qkzVkb60Gi_pto-b5n1vNzCrQze2yqgIJqSLNLYj1Fg,1034
|
|
109
121
|
robot_interface/utilities/uuid_string_factory.py,sha256=_NQIbBQ56w0qqO0MUDP6aPpHbxW7ATRhK8HnQiBSLkc,76
|
|
110
|
-
isar-1.
|
|
111
|
-
isar-1.
|
|
112
|
-
isar-1.
|
|
113
|
-
isar-1.
|
|
114
|
-
isar-1.
|
|
115
|
-
isar-1.25.9.dist-info/RECORD,,
|
|
122
|
+
isar-1.26.1.dist-info/METADATA,sha256=zTnCz5U-ERt19jVM93rwhD03eiZI0q_GXPgyt3xeliw,30252
|
|
123
|
+
isar-1.26.1.dist-info/WHEEL,sha256=DK49LOLCYiurdXXOXwGJm6U4DkHkg4lcxjhqwRa0CP4,91
|
|
124
|
+
isar-1.26.1.dist-info/entry_points.txt,sha256=TFam7uNNw7J0iiDYzsH2gfG0u1eV1wh3JTw_HkhgKLk,49
|
|
125
|
+
isar-1.26.1.dist-info/top_level.txt,sha256=UwIML2RtuQKCyJJkatcSnyp6-ldDjboB9k9JgKipO-U,21
|
|
126
|
+
isar-1.26.1.dist-info/RECORD,,
|
|
@@ -7,11 +7,11 @@ from pydantic import BaseModel, Field
|
|
|
7
7
|
from robot_interface.models.exceptions.robot_exceptions import ErrorMessage
|
|
8
8
|
from robot_interface.models.inspection.inspection import (
|
|
9
9
|
Audio,
|
|
10
|
+
GasMeasurement,
|
|
10
11
|
Image,
|
|
11
12
|
Inspection,
|
|
12
13
|
ThermalImage,
|
|
13
14
|
ThermalVideo,
|
|
14
|
-
GasMeasurement,
|
|
15
15
|
Video,
|
|
16
16
|
)
|
|
17
17
|
from robot_interface.models.mission.status import TaskStatus
|