isar 1.20.2__py3-none-any.whl → 1.34.13__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. isar/apis/api.py +135 -86
  2. isar/apis/models/__init__.py +0 -1
  3. isar/apis/models/models.py +21 -11
  4. isar/apis/models/start_mission_definition.py +115 -170
  5. isar/apis/robot_control/robot_controller.py +41 -0
  6. isar/apis/schedule/scheduling_controller.py +123 -187
  7. isar/apis/security/authentication.py +5 -5
  8. isar/config/certs/ca-cert.pem +33 -31
  9. isar/config/keyvault/keyvault_service.py +4 -2
  10. isar/config/log.py +45 -40
  11. isar/config/logging.conf +16 -31
  12. isar/config/open_telemetry.py +102 -0
  13. isar/config/settings.py +74 -117
  14. isar/eventhandlers/eventhandler.py +123 -0
  15. isar/models/events.py +184 -0
  16. isar/models/status.py +22 -0
  17. isar/modules.py +117 -200
  18. isar/robot/robot.py +383 -0
  19. isar/robot/robot_battery.py +60 -0
  20. isar/robot/robot_monitor_mission.py +357 -0
  21. isar/robot/robot_pause_mission.py +74 -0
  22. isar/robot/robot_resume_mission.py +67 -0
  23. isar/robot/robot_start_mission.py +66 -0
  24. isar/robot/robot_status.py +61 -0
  25. isar/robot/robot_stop_mission.py +68 -0
  26. isar/robot/robot_upload_inspection.py +75 -0
  27. isar/script.py +58 -41
  28. isar/services/service_connections/mqtt/mqtt_client.py +47 -11
  29. isar/services/service_connections/mqtt/robot_heartbeat_publisher.py +5 -2
  30. isar/services/service_connections/mqtt/robot_info_publisher.py +3 -3
  31. isar/services/service_connections/persistent_memory.py +69 -0
  32. isar/services/utilities/mqtt_utilities.py +93 -0
  33. isar/services/utilities/robot_utilities.py +20 -0
  34. isar/services/utilities/scheduling_utilities.py +386 -100
  35. isar/state_machine/state_machine.py +242 -539
  36. isar/state_machine/states/__init__.py +0 -8
  37. isar/state_machine/states/await_next_mission.py +114 -0
  38. isar/state_machine/states/blocked_protective_stop.py +60 -0
  39. isar/state_machine/states/going_to_lockdown.py +95 -0
  40. isar/state_machine/states/going_to_recharging.py +92 -0
  41. isar/state_machine/states/home.py +115 -0
  42. isar/state_machine/states/intervention_needed.py +77 -0
  43. isar/state_machine/states/lockdown.py +38 -0
  44. isar/state_machine/states/maintenance.py +43 -0
  45. isar/state_machine/states/monitor.py +137 -247
  46. isar/state_machine/states/offline.py +51 -53
  47. isar/state_machine/states/paused.py +92 -23
  48. isar/state_machine/states/pausing.py +48 -0
  49. isar/state_machine/states/pausing_return_home.py +48 -0
  50. isar/state_machine/states/recharging.py +80 -0
  51. isar/state_machine/states/resuming.py +57 -0
  52. isar/state_machine/states/resuming_return_home.py +64 -0
  53. isar/state_machine/states/return_home_paused.py +109 -0
  54. isar/state_machine/states/returning_home.py +217 -0
  55. isar/state_machine/states/stopping.py +69 -0
  56. isar/state_machine/states/stopping_due_to_maintenance.py +61 -0
  57. isar/state_machine/states/stopping_go_to_lockdown.py +60 -0
  58. isar/state_machine/states/stopping_go_to_recharge.py +51 -0
  59. isar/state_machine/states/stopping_paused_mission.py +36 -0
  60. isar/state_machine/states/stopping_paused_return_home.py +59 -0
  61. isar/state_machine/states/stopping_return_home.py +59 -0
  62. isar/state_machine/states/unknown_status.py +74 -0
  63. isar/state_machine/states_enum.py +23 -5
  64. isar/state_machine/transitions/mission.py +225 -0
  65. isar/state_machine/transitions/return_home.py +108 -0
  66. isar/state_machine/transitions/robot_status.py +87 -0
  67. isar/state_machine/utils/common_event_handlers.py +138 -0
  68. isar/storage/blob_storage.py +70 -52
  69. isar/storage/local_storage.py +25 -12
  70. isar/storage/storage_interface.py +28 -7
  71. isar/storage/uploader.py +174 -55
  72. isar/storage/utilities.py +32 -29
  73. {isar-1.20.2.dist-info → isar-1.34.13.dist-info}/METADATA +119 -123
  74. isar-1.34.13.dist-info/RECORD +120 -0
  75. {isar-1.20.2.dist-info → isar-1.34.13.dist-info}/WHEEL +1 -1
  76. {isar-1.20.2.dist-info → isar-1.34.13.dist-info}/entry_points.txt +1 -0
  77. robot_interface/models/exceptions/robot_exceptions.py +91 -41
  78. robot_interface/models/inspection/__init__.py +0 -13
  79. robot_interface/models/inspection/inspection.py +42 -33
  80. robot_interface/models/mission/mission.py +14 -15
  81. robot_interface/models/mission/status.py +20 -26
  82. robot_interface/models/mission/task.py +154 -121
  83. robot_interface/models/robots/battery_state.py +6 -0
  84. robot_interface/models/robots/media.py +13 -0
  85. robot_interface/models/robots/robot_model.py +7 -7
  86. robot_interface/robot_interface.py +119 -84
  87. robot_interface/telemetry/mqtt_client.py +74 -12
  88. robot_interface/telemetry/payloads.py +91 -13
  89. robot_interface/utilities/json_service.py +7 -1
  90. isar/config/configuration_error.py +0 -2
  91. isar/config/keyvault/keyvault_error.py +0 -2
  92. isar/config/predefined_mission_definition/__init__.py +0 -0
  93. isar/config/predefined_mission_definition/default_exr.json +0 -51
  94. isar/config/predefined_mission_definition/default_mission.json +0 -91
  95. isar/config/predefined_mission_definition/default_turtlebot.json +0 -124
  96. isar/config/predefined_missions/__init__.py +0 -0
  97. isar/config/predefined_missions/default.json +0 -92
  98. isar/config/predefined_missions/default_turtlebot.json +0 -110
  99. isar/config/predefined_poses/__init__.py +0 -0
  100. isar/config/predefined_poses/predefined_poses.py +0 -616
  101. isar/config/settings.env +0 -25
  102. isar/mission_planner/__init__.py +0 -0
  103. isar/mission_planner/local_planner.py +0 -82
  104. isar/mission_planner/mission_planner_interface.py +0 -26
  105. isar/mission_planner/sequential_task_selector.py +0 -23
  106. isar/mission_planner/task_selector_interface.py +0 -31
  107. isar/models/communication/__init__.py +0 -0
  108. isar/models/communication/message.py +0 -12
  109. isar/models/communication/queues/__init__.py +0 -4
  110. isar/models/communication/queues/queue_io.py +0 -12
  111. isar/models/communication/queues/queue_timeout_error.py +0 -2
  112. isar/models/communication/queues/queues.py +0 -19
  113. isar/models/communication/queues/status_queue.py +0 -20
  114. isar/models/mission_metadata/__init__.py +0 -0
  115. isar/services/auth/__init__.py +0 -0
  116. isar/services/auth/azure_credentials.py +0 -14
  117. isar/services/readers/__init__.py +0 -0
  118. isar/services/readers/base_reader.py +0 -37
  119. isar/services/service_connections/request_handler.py +0 -153
  120. isar/services/service_connections/stid/__init__.py +0 -0
  121. isar/services/utilities/queue_utilities.py +0 -39
  122. isar/services/utilities/threaded_request.py +0 -68
  123. isar/state_machine/states/idle.py +0 -85
  124. isar/state_machine/states/initialize.py +0 -71
  125. isar/state_machine/states/initiate.py +0 -142
  126. isar/state_machine/states/off.py +0 -18
  127. isar/state_machine/states/stop.py +0 -95
  128. isar/storage/slimm_storage.py +0 -191
  129. isar-1.20.2.dist-info/RECORD +0 -116
  130. robot_interface/models/initialize/__init__.py +0 -1
  131. robot_interface/models/initialize/initialize_params.py +0 -9
  132. robot_interface/models/mission/step.py +0 -234
  133. {isar-1.20.2.dist-info → isar-1.34.13.dist-info/licenses}/LICENSE +0 -0
  134. {isar-1.20.2.dist-info → isar-1.34.13.dist-info}/top_level.txt +0 -0
@@ -1,127 +1,160 @@
1
- from dataclasses import dataclass, field
2
- from typing import Iterator, List, Optional
1
+ from enum import Enum
2
+ from typing import Literal, Optional, Type, Union
3
+
4
+ from alitra import Pose, Position
5
+ from pydantic import BaseModel, Field
3
6
 
4
7
  from robot_interface.models.exceptions.robot_exceptions import ErrorMessage
5
- from robot_interface.models.mission.status import StepStatus, TaskStatus
6
- from robot_interface.models.mission.step import (
7
- STEPS,
8
- DriveToPose,
9
- InspectionStep,
10
- MotionStep,
11
- Step,
8
+ from robot_interface.models.inspection.inspection import (
9
+ Audio,
10
+ CO2Measurement,
11
+ Image,
12
+ Inspection,
13
+ ThermalImage,
14
+ ThermalVideo,
15
+ Video,
12
16
  )
17
+ from robot_interface.models.mission.status import TaskStatus
13
18
  from robot_interface.utilities.uuid_string_factory import uuid4_string
14
19
 
15
20
 
16
- @dataclass
17
- class Task:
18
- steps: List[STEPS]
19
- status: TaskStatus = field(default=TaskStatus.NotStarted, init=False)
20
- error_message: Optional[ErrorMessage] = field(default=None, init=False)
21
- tag_id: Optional[str] = field(default=None)
22
- id: str = field(default_factory=uuid4_string, init=True)
23
- _iterator: Iterator = None
24
-
25
- def next_step(self) -> Step:
26
- step: Step = next(self._iterator)
27
- while step.status != StepStatus.NotStarted:
28
- step = next(self._iterator)
29
- return step
30
-
31
- def is_finished(self) -> bool:
32
- for step in self.steps:
33
- if step.status is StepStatus.Failed and isinstance(step, MotionStep):
34
- # One motion step has failed meaning the task as a whole should be
35
- # considered as failed
36
- return True
37
-
38
- elif (step.status is StepStatus.Failed) and isinstance(
39
- step, InspectionStep
40
- ):
41
- # It should be possible to perform several inspections per task. If
42
- # one out of many inspections fail the task is considered as
43
- # partially successful.
44
- continue
45
-
46
- elif step.status is StepStatus.Successful:
47
- # The task is complete once all steps are completed
48
- continue
49
- else:
50
- # Not all steps have been completed yet
51
- return False
52
-
53
- return True
54
-
55
- def update_task_status(self) -> None:
56
- some_not_started: bool = False
57
- for step in self.steps:
58
- if step.status is StepStatus.Failed and isinstance(step, MotionStep):
59
- self.error_message = ErrorMessage(
60
- error_reason=None,
61
- error_description=f"Inspection "
62
- f"{'of ' + self.tag_id if self.tag_id else ''}failed because the "
63
- f"robot could not navigate to the desired location",
64
- )
65
- self.status = TaskStatus.Failed
66
- return
67
-
68
- elif (step.status is StepStatus.Failed) and isinstance(
69
- step, InspectionStep
70
- ):
71
- self.error_message = ErrorMessage(
72
- error_reason=None,
73
- error_description=f"Inspection "
74
- f"{'of ' + self.tag_id if self.tag_id else ''}was partially "
75
- f"successful because one or more inspection steps failed",
76
- )
77
- self.status = TaskStatus.PartiallySuccessful
78
- continue
79
-
80
- elif step.status is StepStatus.Successful:
81
- continue
82
-
83
- elif (step.status is StepStatus.NotStarted) and isinstance(
84
- step, InspectionStep
85
- ):
86
- some_not_started = True
87
-
88
- if self.status is not TaskStatus.PartiallySuccessful:
89
- if some_not_started:
90
- self.status = TaskStatus.InProgress # TODO: handle all not_started
91
- else:
92
- self.status = TaskStatus.Successful
93
-
94
- elif self._all_inspection_steps_failed():
95
- self.error_message = ErrorMessage(
96
- error_reason=None,
97
- error_description=f"Inspection "
98
- f"{'of ' + self.tag_id if self.tag_id else ''}failed as all inspection "
99
- f"steps failed",
100
- )
101
- self.status = TaskStatus.Failed
102
-
103
- def reset_task(self):
104
- self.error_message = None
105
- for step in self.steps:
106
- step.error_message = None
107
- if isinstance(step, DriveToPose):
108
- step.status = StepStatus.NotStarted
109
- elif (
110
- isinstance(step, InspectionStep)
111
- and step.status == StepStatus.InProgress
112
- ):
113
- step.status = StepStatus.NotStarted
114
- self._iterator = iter(self.steps)
115
-
116
- def _all_inspection_steps_failed(self) -> bool:
117
- for step in self.steps:
118
- if isinstance(step, MotionStep):
119
- continue
120
- elif step.status is not StepStatus.Failed:
121
- return False
122
-
123
- return True
124
-
125
- def __post_init__(self) -> None:
126
- if self._iterator is None:
127
- self._iterator = iter(self.steps)
21
+ class TaskTypes(str, Enum):
22
+ ReturnToHome = "return_to_home"
23
+ TakeImage = "take_image"
24
+ TakeThermalImage = "take_thermal_image"
25
+ TakeVideo = "take_video"
26
+ TakeThermalVideo = "take_thermal_video"
27
+ TakeCO2Measurement = "take_co2_measurement"
28
+ RecordAudio = "record_audio"
29
+
30
+
31
+ class ZoomDescription(BaseModel):
32
+ objectWidth: float
33
+ objectHeight: float
34
+
35
+
36
+ class Task(BaseModel):
37
+ status: TaskStatus = Field(default=TaskStatus.NotStarted)
38
+ error_message: Optional[ErrorMessage] = Field(default=None)
39
+ tag_id: Optional[str] = Field(default=None)
40
+ id: str = Field(default_factory=uuid4_string, frozen=True)
41
+
42
+
43
+ class InspectionTask(Task):
44
+ """
45
+ Base class for all inspection tasks which produce results to be uploaded.
46
+ """
47
+
48
+ inspection_id: str = Field(default_factory=uuid4_string, frozen=True)
49
+ robot_pose: Pose = Field(default=None, init=True)
50
+ inspection_description: Optional[str] = Field(default=None)
51
+ zoom: Optional[ZoomDescription] = Field(default=None)
52
+
53
+ @staticmethod
54
+ def get_inspection_type() -> Type[Inspection]:
55
+ return Inspection
56
+
57
+
58
+ class ReturnToHome(Task):
59
+ """
60
+ Task which cases the robot to return home
61
+ """
62
+
63
+ type: Literal[TaskTypes.ReturnToHome] = TaskTypes.ReturnToHome
64
+
65
+
66
+ class TakeImage(InspectionTask):
67
+ """
68
+ Task which causes the robot to take an image towards the given target.
69
+ """
70
+
71
+ target: Position = Field(default=None)
72
+ type: Literal[TaskTypes.TakeImage] = TaskTypes.TakeImage
73
+
74
+ @staticmethod
75
+ def get_inspection_type() -> Type[Inspection]:
76
+ return Image
77
+
78
+
79
+ class TakeThermalImage(InspectionTask):
80
+ """
81
+ Task which causes the robot to take a thermal image towards the given target.
82
+ """
83
+
84
+ target: Position = Field(default=None)
85
+ type: Literal[TaskTypes.TakeThermalImage] = TaskTypes.TakeThermalImage
86
+
87
+ @staticmethod
88
+ def get_inspection_type() -> Type[Inspection]:
89
+ return ThermalImage
90
+
91
+
92
+ class TakeVideo(InspectionTask):
93
+ """
94
+ Task which causes the robot to take a video towards the given target.
95
+
96
+ Duration of video is given in seconds.
97
+ """
98
+
99
+ target: Position = Field(default=None)
100
+ duration: float = Field(default=None)
101
+ type: Literal[TaskTypes.TakeVideo] = TaskTypes.TakeVideo
102
+
103
+ @staticmethod
104
+ def get_inspection_type() -> Type[Inspection]:
105
+ return Video
106
+
107
+
108
+ class TakeThermalVideo(InspectionTask):
109
+ """
110
+ Task which causes the robot to record thermal video towards the given target
111
+
112
+ Duration of video is given in seconds.
113
+ """
114
+
115
+ target: Position = Field(default=None)
116
+ duration: float = Field(default=None)
117
+ type: Literal[TaskTypes.TakeThermalVideo] = TaskTypes.TakeThermalVideo
118
+
119
+ @staticmethod
120
+ def get_inspection_type() -> Type[Inspection]:
121
+ return ThermalVideo
122
+
123
+
124
+ class RecordAudio(InspectionTask):
125
+ """
126
+ Task which causes the robot to record a video at its position, facing the target.
127
+
128
+ Duration of audio is given in seconds.
129
+ """
130
+
131
+ target: Position = Field(default=None)
132
+ duration: float = Field(default=None)
133
+ type: Literal[TaskTypes.RecordAudio] = TaskTypes.RecordAudio
134
+
135
+ @staticmethod
136
+ def get_inspection_type() -> Type[Inspection]:
137
+ return Audio
138
+
139
+
140
+ class TakeCO2Measurement(InspectionTask):
141
+ """
142
+ Task which causes the robot to take a CO2 measurement at its position.
143
+ """
144
+
145
+ type: Literal[TaskTypes.TakeCO2Measurement] = TaskTypes.TakeCO2Measurement
146
+
147
+ @staticmethod
148
+ def get_inspection_type() -> Type[Inspection]:
149
+ return CO2Measurement
150
+
151
+
152
+ TASKS = Union[
153
+ ReturnToHome,
154
+ TakeImage,
155
+ TakeThermalImage,
156
+ TakeVideo,
157
+ TakeThermalVideo,
158
+ TakeCO2Measurement,
159
+ RecordAudio,
160
+ ]
@@ -0,0 +1,6 @@
1
+ from enum import Enum
2
+
3
+
4
+ class BatteryState(Enum):
5
+ Normal = "Normal"
6
+ Charging = "Charging"
@@ -0,0 +1,13 @@
1
+ from dataclasses import dataclass
2
+ from enum import Enum
3
+
4
+
5
+ class MediaConnectionType(str, Enum):
6
+ LiveKit = "LiveKit"
7
+
8
+
9
+ @dataclass
10
+ class MediaConfig:
11
+ url: str
12
+ token: str
13
+ media_connection_type: MediaConnectionType
@@ -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: str = "TaurobInspector"
8
- TaurobOperator: str = "TaurobOperator"
9
- ExR2: str = "ExR2"
10
- Robot: str = "Robot" # This corresponds to the mock in isar_robot
11
- Turtlebot: str = "Turtlebot"
12
- AnymalX: str = "AnymalX"
13
- AnymalD: str = "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,13 +1,13 @@
1
1
  from abc import ABCMeta, abstractmethod
2
2
  from queue import Queue
3
3
  from threading import Thread
4
- from typing import List, Sequence
4
+ from typing import Callable, List, Optional
5
5
 
6
- from robot_interface.models.initialize import InitializeParams
7
6
  from robot_interface.models.inspection.inspection import Inspection
8
7
  from robot_interface.models.mission.mission import Mission
9
- from robot_interface.models.mission.status import MissionStatus, RobotStatus, StepStatus
10
- from robot_interface.models.mission.step import InspectionStep, Step
8
+ from robot_interface.models.mission.status import MissionStatus, RobotStatus, TaskStatus
9
+ from robot_interface.models.mission.task import InspectionTask
10
+ from robot_interface.models.robots.media import MediaConfig
11
11
 
12
12
 
13
13
  class RobotInterface(metaclass=ABCMeta):
@@ -17,10 +17,6 @@ class RobotInterface(metaclass=ABCMeta):
17
17
  def initiate_mission(self, mission: Mission) -> None:
18
18
  """Send a mission to the robot and initiate execution of the mission
19
19
 
20
- This function should be used in combination with the mission_status function
21
- if the robot is designed to run full missions and not in a stepwise
22
- configuration.
23
-
24
20
  Parameters
25
21
  ----------
26
22
  mission: Mission
@@ -31,55 +27,66 @@ class RobotInterface(metaclass=ABCMeta):
31
27
 
32
28
  Raises
33
29
  ------
30
+ RobotAlreadyHomeException
31
+ If the mission is a return home mission and the robot wish to disregard the
32
+ mission as it is already at home
34
33
  RobotInfeasibleMissionException
35
34
  If the mission input is infeasible and the mission fails to be scheduled in
36
35
  a way that means attempting to schedule again is not necessary
37
36
  RobotException
38
37
  Will catch all RobotExceptions not previously listed and retry scheduling of
39
38
  the mission until the number of allowed retries is exceeded
40
- NotImplementedError
41
- If the robot is designed for stepwise mission execution
42
39
 
43
40
  """
44
41
  raise NotImplementedError
45
42
 
46
- def mission_status(self) -> MissionStatus:
47
- """Gets the status of the currently active mission on the robot
43
+ @abstractmethod
44
+ def task_status(self, task_id: str) -> TaskStatus:
45
+ """Gets the status of the currently active task on robot.
46
+
47
+ Returns
48
+ -------
49
+ TaskStatus
50
+ Status of the execution of current task.
51
+
52
+ Raises
53
+ ------
54
+ RobotCommunicationTimeoutException or RobotCommunicationException
55
+ If the robot package is unable to communicate with the robot API the fetching
56
+ of task status will be attempted again until a certain number of retries
57
+ RobotTaskStatusException
58
+ If there was an error when retrieving the task status
59
+ RobotException
60
+ If the task status could not be retrieved.
61
+
62
+ """
63
+ raise NotImplementedError
48
64
 
49
- This function should be used in combination with the initiate_mission function
50
- if the robot is designed to run full missions and not in a stepwise
51
- configuration.
65
+ @abstractmethod
66
+ def mission_status(self, mission_id: str) -> MissionStatus:
67
+ """Gets the status of the mission with ID mission_id on robot.
52
68
 
53
69
  Returns
54
70
  -------
55
71
  MissionStatus
56
- Status of the executing mission on the robot.
72
+ Status of the execution of mission.
57
73
 
58
74
  Raises
59
75
  ------
76
+ RobotCommunicationTimeoutException or RobotCommunicationException
77
+ If the robot package is unable to communicate with the robot API the fetching
78
+ of mission status will be attempted again until a certain number of retries
60
79
  RobotMissionStatusException
61
- If the mission status could not be collected this will lead to the mission
62
- being marked as failed
80
+ If there was an error when retrieving the mission status
63
81
  RobotException
64
- An uncaught RobotException in the robot package while retrieving the status
65
- will cause the mission to be marked as failed
66
- NotImplementedError
67
- If the robot is designed for stepwise mission execution
82
+ If the mission status could not be retrieved.
68
83
 
69
84
  """
85
+ raise NotImplementedError
70
86
 
71
87
  @abstractmethod
72
- def initiate_step(self, step: Step) -> None:
73
- """Send a step to the robot and initiate the execution of the step
74
-
75
- This function should be used in combination with the step_status function
76
- if the robot is designed to run stepwise missions and not in a full mission
77
- configuration.
78
-
79
- Parameters
80
- ----------
81
- step : Step
82
- The step that should be initiated on the robot.
88
+ def stop(self) -> None:
89
+ """Stops the execution of the current task and corresponding mission.
83
90
 
84
91
  Returns
85
92
  -------
@@ -87,45 +94,37 @@ class RobotInterface(metaclass=ABCMeta):
87
94
 
88
95
  Raises
89
96
  ------
90
- RobotInfeasibleStepException
91
- If the step input is infeasible and the step fails to be scheduled in
92
- a way that means attempting to schedule again is not necessary
97
+ RobotActionException
98
+ If the robot fails to perform the requested action to stop mission execution
99
+ the action to stop will be attempted again until a certain number of retries
93
100
  RobotException
94
- Will catch all RobotExceptions not previously listed and retry scheduling
95
- of the step until the number of allowed retries is exceeded before the step
96
- will be marked as failed and the mission cancelled
97
- NotImplementedError
98
- If the robot is designed for full mission execution.
101
+ Will catch other RobotExceptions and retry to stop the mission
99
102
 
100
103
  """
101
104
  raise NotImplementedError
102
105
 
103
106
  @abstractmethod
104
- def step_status(self) -> StepStatus:
105
- """Gets the status of the currently active step on robot.
106
-
107
- This function should be used in combination with the initiate_step function
108
- if the robot is designed to run stepwise missions and not in a full mission
109
- configuration.
107
+ def pause(self) -> None:
108
+ """Pauses the execution of the current task and stops the movement of the robot.
110
109
 
111
110
  Returns
112
111
  -------
113
- StepStatus
114
- Status of the execution of current step.
112
+ None
115
113
 
116
114
  Raises
117
115
  ------
116
+ RobotActionException
117
+ If the robot fails to perform the requested action to pause mission execution
118
+ the action to pause will be attempted again until a certain number of retries
118
119
  RobotException
119
- If the step status could not be retrieved.
120
- NotImplementedError
121
- If the robot is designed for full mission execution.
120
+ Will catch other RobotExceptions and retry to pause the mission
122
121
 
123
122
  """
124
123
  raise NotImplementedError
125
124
 
126
125
  @abstractmethod
127
- def stop(self) -> None:
128
- """Stops the execution of the current step and stops the movement of the robot.
126
+ def resume(self) -> None:
127
+ """Resumes the execution of the current task and continues the rest of the mission.
129
128
 
130
129
  Returns
131
130
  -------
@@ -134,32 +133,34 @@ class RobotInterface(metaclass=ABCMeta):
134
133
  Raises
135
134
  ------
136
135
  RobotActionException
137
- If the robot fails to perform the requested action to stop mission execution
138
- the action to stop will be attempted again until a certain number of retries
136
+ If the robot fails to perform the requested action to resume mission execution
137
+ the action to resume will be attempted again until a certain number of retries
139
138
  RobotException
140
- Will catch other RobotExceptions and retry to stop the mission
139
+ Will catch other RobotExceptions and retry to resume the mission
141
140
 
142
141
  """
143
142
  raise NotImplementedError
144
143
 
145
144
  @abstractmethod
146
- def get_inspections(self, step: InspectionStep) -> Sequence[Inspection]:
147
- """Return the inspections connected to the given step.
145
+ def get_inspection(self, task: InspectionTask) -> Inspection:
146
+ """Return the inspection connected to the given task.
148
147
 
149
148
  Parameters
150
149
  ----------
151
- step : Step
150
+ task : InspectionTask
152
151
 
153
152
  Returns
154
153
  -------
155
- Sequence[InspectionResult]
156
- List containing all the inspection results connected to the given step
154
+ Inspection
155
+ The inspection connected to the given task.
156
+ get_inspection has responsibility to assign the inspection_id of the task
157
+ to the inspection that it returns.
157
158
 
158
159
  Raises
159
160
  ------
160
161
  RobotRetrieveInspectionException
161
162
  If the robot package is unable to retrieve the inspections for the relevant
162
- mission or step an error message is logged and the state machine continues
163
+ mission or task an error message is logged and the state machine continues
163
164
  RobotException
164
165
  Catches other RobotExceptions that lead to the same result as a
165
166
  RobotRetrieveInspectionException
@@ -168,27 +169,33 @@ class RobotInterface(metaclass=ABCMeta):
168
169
  raise NotImplementedError
169
170
 
170
171
  @abstractmethod
171
- def initialize(self, params: InitializeParams) -> None:
172
- """Initializes the robot. The initialization needed is robot dependent and the
173
- function can be a simple return statement if no initialization is needed for the
174
- robot.
172
+ def register_inspection_callback(
173
+ self, callback_function: Callable[[Inspection, Mission], None]
174
+ ) -> None:
175
+ """Register a function which should be run when inspection data is received
176
+ asynchronously. This function should expect to receive an Inspection from.
175
177
 
176
178
  Parameters
177
179
  ----------
178
- params: InitializeParams
180
+ callback_function : Callable[[Inspection, Mission], None]
179
181
 
180
182
  Returns
181
183
  -------
182
184
  None
183
185
 
184
- Raises
185
- ------
186
- RobotInitializeException
187
- If the robot package is unable to initialize the robot correctly the mission
188
- will be cancelled
189
- RobotException
190
- Catches other RobotExceptions that might have occurred during initialization
191
- where the result is that the mission is cancelled
186
+ """
187
+ raise NotImplementedError
188
+
189
+ @abstractmethod
190
+ def generate_media_config(self) -> Optional[MediaConfig]:
191
+ """
192
+ Generate a JSON containing the url and token needed to establish a media stream
193
+ connection to a robot.
194
+
195
+ Returns
196
+ -------
197
+ MediaConfig
198
+ An object containing the connection information for a media stream connection
192
199
 
193
200
  """
194
201
  raise NotImplementedError
@@ -212,16 +219,14 @@ class RobotInterface(metaclass=ABCMeta):
212
219
  -------
213
220
  List[Thread]
214
221
  List containing all threads that will be started to publish telemetry.
222
+
215
223
  """
216
224
  raise NotImplementedError
217
225
 
218
226
  @abstractmethod
219
227
  def robot_status(self) -> RobotStatus:
220
228
  """
221
- Method which returns an enum indicating if the robot package is able to reach
222
- the interface which is used to communicate with the robot. This is further used
223
- by ISAR to indicate whether the ISAR instance is fully functional and may be
224
- used by other systems.
229
+ Method which returns an enum indicating the status of the robot.
225
230
 
226
231
  Returns
227
232
  -------
@@ -231,13 +236,43 @@ class RobotInterface(metaclass=ABCMeta):
231
236
  Raises
232
237
  -------
233
238
  RobotCommunicationException
234
- Raised if the robot package is unable to communicate with the robot API
239
+ Raised if the robot package is unable to communicate with the robot API.
240
+ The fetching of robot status will be attempted again until success
241
+ RobotAPIException
242
+ Raised if the robot package is able to communicate with the API but an error
243
+ occurred while interpreting the response. The fetching of robot status will
244
+ be attempted again until success
245
+ RobotException
246
+ Catches other RobotExceptions that may have occurred while retrieving the
247
+ robot status. The fetching of robot status will be attempted again until
248
+ success
249
+
250
+ """
251
+ raise NotImplementedError
252
+
253
+ @abstractmethod
254
+ def get_battery_level(self) -> float:
255
+ """
256
+ Method which returns the percent charge remaining in the robot battery.
257
+
258
+ Returns
259
+ -------
260
+ float
261
+ The battery percentage on the robot
262
+
263
+ Raises
264
+ -------
265
+ RobotCommunicationException
266
+ Raised if the robot package is unable to communicate with the robot API.
267
+ The fetching of robot battery level will be attempted again until success
235
268
  RobotAPIException
236
269
  Raised if the robot package is able to communicate with the API but an error
237
- occurred while interpreting the response
270
+ occurred while interpreting the response. The fetching of robot battery level
271
+ will be attempted again until success
238
272
  RobotException
239
273
  Catches other RobotExceptions that may have occurred while retrieving the
240
- robot status
241
- At this point ISAR will attempt to request the robot status again
274
+ robot battery level. The fetching of robot battery level will
275
+ be attempted again until success
276
+
242
277
  """
243
278
  raise NotImplementedError