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.
- isar/apis/api.py +135 -86
- isar/apis/models/__init__.py +0 -1
- isar/apis/models/models.py +21 -11
- isar/apis/models/start_mission_definition.py +115 -170
- isar/apis/robot_control/robot_controller.py +41 -0
- isar/apis/schedule/scheduling_controller.py +123 -187
- isar/apis/security/authentication.py +5 -5
- isar/config/certs/ca-cert.pem +33 -31
- isar/config/keyvault/keyvault_service.py +4 -2
- isar/config/log.py +45 -40
- isar/config/logging.conf +16 -31
- isar/config/open_telemetry.py +102 -0
- isar/config/settings.py +74 -117
- isar/eventhandlers/eventhandler.py +123 -0
- isar/models/events.py +184 -0
- isar/models/status.py +22 -0
- isar/modules.py +117 -200
- isar/robot/robot.py +383 -0
- isar/robot/robot_battery.py +60 -0
- isar/robot/robot_monitor_mission.py +357 -0
- isar/robot/robot_pause_mission.py +74 -0
- isar/robot/robot_resume_mission.py +67 -0
- isar/robot/robot_start_mission.py +66 -0
- isar/robot/robot_status.py +61 -0
- isar/robot/robot_stop_mission.py +68 -0
- isar/robot/robot_upload_inspection.py +75 -0
- isar/script.py +58 -41
- isar/services/service_connections/mqtt/mqtt_client.py +47 -11
- isar/services/service_connections/mqtt/robot_heartbeat_publisher.py +5 -2
- isar/services/service_connections/mqtt/robot_info_publisher.py +3 -3
- isar/services/service_connections/persistent_memory.py +69 -0
- isar/services/utilities/mqtt_utilities.py +93 -0
- isar/services/utilities/robot_utilities.py +20 -0
- isar/services/utilities/scheduling_utilities.py +386 -100
- isar/state_machine/state_machine.py +242 -539
- isar/state_machine/states/__init__.py +0 -8
- isar/state_machine/states/await_next_mission.py +114 -0
- isar/state_machine/states/blocked_protective_stop.py +60 -0
- isar/state_machine/states/going_to_lockdown.py +95 -0
- isar/state_machine/states/going_to_recharging.py +92 -0
- isar/state_machine/states/home.py +115 -0
- isar/state_machine/states/intervention_needed.py +77 -0
- isar/state_machine/states/lockdown.py +38 -0
- isar/state_machine/states/maintenance.py +43 -0
- isar/state_machine/states/monitor.py +137 -247
- isar/state_machine/states/offline.py +51 -53
- isar/state_machine/states/paused.py +92 -23
- isar/state_machine/states/pausing.py +48 -0
- isar/state_machine/states/pausing_return_home.py +48 -0
- isar/state_machine/states/recharging.py +80 -0
- isar/state_machine/states/resuming.py +57 -0
- isar/state_machine/states/resuming_return_home.py +64 -0
- isar/state_machine/states/return_home_paused.py +109 -0
- isar/state_machine/states/returning_home.py +217 -0
- isar/state_machine/states/stopping.py +69 -0
- isar/state_machine/states/stopping_due_to_maintenance.py +61 -0
- isar/state_machine/states/stopping_go_to_lockdown.py +60 -0
- isar/state_machine/states/stopping_go_to_recharge.py +51 -0
- isar/state_machine/states/stopping_paused_mission.py +36 -0
- isar/state_machine/states/stopping_paused_return_home.py +59 -0
- isar/state_machine/states/stopping_return_home.py +59 -0
- isar/state_machine/states/unknown_status.py +74 -0
- isar/state_machine/states_enum.py +23 -5
- isar/state_machine/transitions/mission.py +225 -0
- isar/state_machine/transitions/return_home.py +108 -0
- isar/state_machine/transitions/robot_status.py +87 -0
- isar/state_machine/utils/common_event_handlers.py +138 -0
- isar/storage/blob_storage.py +70 -52
- isar/storage/local_storage.py +25 -12
- isar/storage/storage_interface.py +28 -7
- isar/storage/uploader.py +174 -55
- isar/storage/utilities.py +32 -29
- {isar-1.20.2.dist-info → isar-1.34.13.dist-info}/METADATA +119 -123
- isar-1.34.13.dist-info/RECORD +120 -0
- {isar-1.20.2.dist-info → isar-1.34.13.dist-info}/WHEEL +1 -1
- {isar-1.20.2.dist-info → isar-1.34.13.dist-info}/entry_points.txt +1 -0
- robot_interface/models/exceptions/robot_exceptions.py +91 -41
- robot_interface/models/inspection/__init__.py +0 -13
- robot_interface/models/inspection/inspection.py +42 -33
- robot_interface/models/mission/mission.py +14 -15
- robot_interface/models/mission/status.py +20 -26
- robot_interface/models/mission/task.py +154 -121
- robot_interface/models/robots/battery_state.py +6 -0
- robot_interface/models/robots/media.py +13 -0
- robot_interface/models/robots/robot_model.py +7 -7
- robot_interface/robot_interface.py +119 -84
- robot_interface/telemetry/mqtt_client.py +74 -12
- robot_interface/telemetry/payloads.py +91 -13
- robot_interface/utilities/json_service.py +7 -1
- isar/config/configuration_error.py +0 -2
- isar/config/keyvault/keyvault_error.py +0 -2
- isar/config/predefined_mission_definition/__init__.py +0 -0
- isar/config/predefined_mission_definition/default_exr.json +0 -51
- isar/config/predefined_mission_definition/default_mission.json +0 -91
- isar/config/predefined_mission_definition/default_turtlebot.json +0 -124
- isar/config/predefined_missions/__init__.py +0 -0
- isar/config/predefined_missions/default.json +0 -92
- isar/config/predefined_missions/default_turtlebot.json +0 -110
- isar/config/predefined_poses/__init__.py +0 -0
- isar/config/predefined_poses/predefined_poses.py +0 -616
- isar/config/settings.env +0 -25
- isar/mission_planner/__init__.py +0 -0
- isar/mission_planner/local_planner.py +0 -82
- isar/mission_planner/mission_planner_interface.py +0 -26
- isar/mission_planner/sequential_task_selector.py +0 -23
- isar/mission_planner/task_selector_interface.py +0 -31
- isar/models/communication/__init__.py +0 -0
- isar/models/communication/message.py +0 -12
- isar/models/communication/queues/__init__.py +0 -4
- isar/models/communication/queues/queue_io.py +0 -12
- isar/models/communication/queues/queue_timeout_error.py +0 -2
- isar/models/communication/queues/queues.py +0 -19
- isar/models/communication/queues/status_queue.py +0 -20
- isar/models/mission_metadata/__init__.py +0 -0
- isar/services/auth/__init__.py +0 -0
- isar/services/auth/azure_credentials.py +0 -14
- isar/services/readers/__init__.py +0 -0
- isar/services/readers/base_reader.py +0 -37
- isar/services/service_connections/request_handler.py +0 -153
- isar/services/service_connections/stid/__init__.py +0 -0
- isar/services/utilities/queue_utilities.py +0 -39
- isar/services/utilities/threaded_request.py +0 -68
- isar/state_machine/states/idle.py +0 -85
- isar/state_machine/states/initialize.py +0 -71
- isar/state_machine/states/initiate.py +0 -142
- isar/state_machine/states/off.py +0 -18
- isar/state_machine/states/stop.py +0 -95
- isar/storage/slimm_storage.py +0 -191
- isar-1.20.2.dist-info/RECORD +0 -116
- robot_interface/models/initialize/__init__.py +0 -1
- robot_interface/models/initialize/initialize_params.py +0 -9
- robot_interface/models/mission/step.py +0 -234
- {isar-1.20.2.dist-info → isar-1.34.13.dist-info/licenses}/LICENSE +0 -0
- {isar-1.20.2.dist-info → isar-1.34.13.dist-info}/top_level.txt +0 -0
|
@@ -1,230 +1,175 @@
|
|
|
1
1
|
import time
|
|
2
2
|
from enum import Enum
|
|
3
|
-
from typing import
|
|
3
|
+
from typing import List, Optional
|
|
4
4
|
|
|
5
|
-
from alitra import Position, Pose, Orientation, Frame
|
|
6
5
|
from pydantic import BaseModel, Field
|
|
7
6
|
|
|
8
7
|
from isar.apis.models.models import InputPose, InputPosition
|
|
9
8
|
from isar.config.settings import settings
|
|
10
|
-
from isar.mission_planner.mission_planner_interface import MissionPlannerError
|
|
11
9
|
from robot_interface.models.mission.mission import Mission
|
|
12
|
-
from robot_interface.models.mission.
|
|
13
|
-
|
|
14
|
-
DockingProcedure,
|
|
15
|
-
DriveToPose,
|
|
16
|
-
Localize,
|
|
10
|
+
from robot_interface.models.mission.task import (
|
|
11
|
+
TASKS,
|
|
17
12
|
RecordAudio,
|
|
18
13
|
ReturnToHome,
|
|
14
|
+
TakeCO2Measurement,
|
|
19
15
|
TakeImage,
|
|
20
16
|
TakeThermalImage,
|
|
21
17
|
TakeThermalVideo,
|
|
22
18
|
TakeVideo,
|
|
19
|
+
ZoomDescription,
|
|
23
20
|
)
|
|
24
|
-
from robot_interface.
|
|
21
|
+
from robot_interface.utilities.uuid_string_factory import uuid4_string
|
|
25
22
|
|
|
26
23
|
|
|
27
24
|
class InspectionTypes(str, Enum):
|
|
28
|
-
image
|
|
29
|
-
thermal_image
|
|
30
|
-
video
|
|
31
|
-
thermal_video
|
|
32
|
-
audio
|
|
25
|
+
image = "Image"
|
|
26
|
+
thermal_image = "ThermalImage"
|
|
27
|
+
video = "Video"
|
|
28
|
+
thermal_video = "ThermalVideo"
|
|
29
|
+
audio = "Audio"
|
|
30
|
+
co2_measurement = "CO2Measurement"
|
|
33
31
|
|
|
34
32
|
|
|
35
33
|
class TaskType(str, Enum):
|
|
36
|
-
Inspection
|
|
37
|
-
|
|
38
|
-
Localization: str = "localization"
|
|
39
|
-
ReturnToHome: str = "return_to_home"
|
|
40
|
-
Dock: str = "dock"
|
|
34
|
+
Inspection = "inspection"
|
|
35
|
+
ReturnToHome = "return_to_home"
|
|
41
36
|
|
|
42
37
|
|
|
43
38
|
class StartMissionInspectionDefinition(BaseModel):
|
|
44
39
|
type: InspectionTypes = Field(default=InspectionTypes.image)
|
|
45
40
|
inspection_target: InputPosition
|
|
46
|
-
|
|
41
|
+
inspection_description: Optional[str] = None
|
|
47
42
|
duration: Optional[float] = None
|
|
48
|
-
metadata: Optional[dict] = None
|
|
49
|
-
id: Optional[str] = None
|
|
50
43
|
|
|
51
44
|
|
|
52
45
|
class StartMissionTaskDefinition(BaseModel):
|
|
46
|
+
id: Optional[str] = None
|
|
53
47
|
type: TaskType = Field(default=TaskType.Inspection)
|
|
54
48
|
pose: InputPose
|
|
55
|
-
|
|
49
|
+
inspection: Optional[StartMissionInspectionDefinition] = None
|
|
56
50
|
tag: Optional[str] = None
|
|
57
|
-
|
|
51
|
+
zoom: Optional[ZoomDescription] = None
|
|
58
52
|
|
|
59
53
|
|
|
60
54
|
class StartMissionDefinition(BaseModel):
|
|
61
|
-
tasks: List[StartMissionTaskDefinition]
|
|
62
55
|
id: Optional[str] = None
|
|
56
|
+
tasks: List[StartMissionTaskDefinition]
|
|
63
57
|
name: Optional[str] = None
|
|
64
58
|
start_pose: Optional[InputPose] = None
|
|
65
59
|
|
|
66
60
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
all_steps_in_mission: List[STEPS] = []
|
|
70
|
-
|
|
71
|
-
for task in mission_definition.tasks:
|
|
72
|
-
steps: List[STEPS] = generate_steps(task)
|
|
73
|
-
all_steps_in_mission.extend(steps)
|
|
74
|
-
|
|
75
|
-
isar_task: Task = Task(steps=steps, tag_id=task.tag)
|
|
76
|
-
if task.id:
|
|
77
|
-
isar_task.id = task.id
|
|
78
|
-
isar_tasks.append(isar_task)
|
|
79
|
-
|
|
80
|
-
if not isar_tasks:
|
|
81
|
-
raise MissionPlannerError("Mission does not contain any valid tasks")
|
|
82
|
-
|
|
83
|
-
check_for_duplicate_ids(isar_tasks)
|
|
84
|
-
check_for_duplicate_ids(all_steps_in_mission)
|
|
61
|
+
class StopMissionDefinition(BaseModel):
|
|
62
|
+
mission_id: Optional[str] = None
|
|
85
63
|
|
|
86
|
-
isar_mission: Mission = Mission(tasks=isar_tasks)
|
|
87
64
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
else:
|
|
91
|
-
isar_mission.name = _build_mission_name()
|
|
92
|
-
|
|
93
|
-
if mission_definition.id:
|
|
94
|
-
isar_mission.id = mission_definition.id
|
|
95
|
-
|
|
96
|
-
if mission_definition.start_pose:
|
|
97
|
-
input_pose: InputPose = mission_definition.start_pose
|
|
98
|
-
input_frame: Frame = Frame(name=input_pose.frame_name)
|
|
99
|
-
input_position: Position = Position(
|
|
100
|
-
input_pose.position.x,
|
|
101
|
-
input_pose.position.y,
|
|
102
|
-
input_pose.position.z,
|
|
103
|
-
input_frame,
|
|
104
|
-
)
|
|
105
|
-
input_orientation: Orientation = Orientation(
|
|
106
|
-
input_pose.orientation.x,
|
|
107
|
-
input_pose.orientation.y,
|
|
108
|
-
input_pose.orientation.z,
|
|
109
|
-
input_pose.orientation.w,
|
|
110
|
-
input_frame,
|
|
111
|
-
)
|
|
112
|
-
isar_mission.start_pose = Pose(
|
|
113
|
-
position=input_position, orientation=input_orientation, frame=input_frame
|
|
114
|
-
)
|
|
65
|
+
class MissionFormatError(Exception):
|
|
66
|
+
pass
|
|
115
67
|
|
|
116
|
-
return isar_mission
|
|
117
68
|
|
|
69
|
+
def to_isar_mission(
|
|
70
|
+
start_mission_definition: StartMissionDefinition,
|
|
71
|
+
) -> Mission:
|
|
72
|
+
isar_tasks: List[TASKS] = []
|
|
118
73
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
raise MissionPlannerError(
|
|
123
|
-
f"Failed to create as there were duplicate IDs which is not allowed "
|
|
124
|
-
f"({duplicate_ids})"
|
|
125
|
-
)
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
def generate_steps(task) -> List[STEPS]:
|
|
129
|
-
steps: List[STEPS] = []
|
|
130
|
-
try:
|
|
131
|
-
match task.type:
|
|
132
|
-
case TaskType.Inspection:
|
|
133
|
-
steps.extend(generate_steps_for_inspection_task(task=task))
|
|
134
|
-
case TaskType.DriveTo:
|
|
135
|
-
steps.append(generate_steps_for_drive_to_task(task=task))
|
|
136
|
-
case TaskType.Localization:
|
|
137
|
-
steps.append(generate_steps_for_localization_task(task=task))
|
|
138
|
-
case TaskType.ReturnToHome:
|
|
139
|
-
steps.append(generate_steps_for_return_to_home_task(task=task))
|
|
140
|
-
case TaskType.Dock:
|
|
141
|
-
steps.append(generate_steps_for_dock_task())
|
|
142
|
-
except ValueError as e:
|
|
143
|
-
raise MissionPlannerError(f"Failed to create task: {str(e)}")
|
|
144
|
-
|
|
145
|
-
return steps
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
def generate_steps_for_inspection_task(task: StartMissionTaskDefinition) -> List[STEPS]:
|
|
149
|
-
drive_step: DriveToPose = DriveToPose(pose=task.pose.to_alitra_pose())
|
|
150
|
-
|
|
151
|
-
inspection_steps: List[STEPS] = [
|
|
152
|
-
create_inspection_step(
|
|
153
|
-
inspection_type=inspection.type,
|
|
154
|
-
duration=inspection.duration,
|
|
155
|
-
target=inspection.inspection_target.to_alitra_position(),
|
|
156
|
-
tag_id=task.tag,
|
|
157
|
-
metadata=inspection.metadata,
|
|
158
|
-
id=inspection.id,
|
|
159
|
-
)
|
|
160
|
-
for inspection in task.inspections
|
|
161
|
-
]
|
|
162
|
-
|
|
163
|
-
return [drive_step, *inspection_steps]
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
def generate_steps_for_drive_to_task(task: StartMissionTaskDefinition) -> DriveToPose:
|
|
167
|
-
return DriveToPose(pose=task.pose.to_alitra_pose())
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
def generate_steps_for_localization_task(task: StartMissionTaskDefinition) -> Localize:
|
|
171
|
-
return Localize(localization_pose=task.pose.to_alitra_pose())
|
|
74
|
+
for task_definition in start_mission_definition.tasks:
|
|
75
|
+
task: TASKS = to_isar_task(task_definition)
|
|
76
|
+
isar_tasks.append(task)
|
|
172
77
|
|
|
78
|
+
if not isar_tasks:
|
|
79
|
+
raise MissionFormatError("Mission does not contain any valid tasks")
|
|
173
80
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
81
|
+
isar_mission_name: str = (
|
|
82
|
+
start_mission_definition.name
|
|
83
|
+
if start_mission_definition.name
|
|
84
|
+
else _build_mission_name()
|
|
85
|
+
)
|
|
178
86
|
|
|
87
|
+
start_pose = None
|
|
88
|
+
if start_mission_definition.start_pose:
|
|
89
|
+
start_pose = start_mission_definition.start_pose.to_alitra_pose()
|
|
179
90
|
|
|
180
|
-
|
|
181
|
-
return DockingProcedure(behavior="dock")
|
|
91
|
+
id = start_mission_definition.id if start_mission_definition.id else uuid4_string()
|
|
182
92
|
|
|
93
|
+
return Mission(
|
|
94
|
+
id=id,
|
|
95
|
+
tasks=isar_tasks,
|
|
96
|
+
name=isar_mission_name,
|
|
97
|
+
start_pose=start_pose,
|
|
98
|
+
)
|
|
183
99
|
|
|
184
|
-
def create_inspection_step(
|
|
185
|
-
inspection_type: InspectionTypes,
|
|
186
|
-
duration: float,
|
|
187
|
-
target: Position,
|
|
188
|
-
tag_id: Optional[str],
|
|
189
|
-
metadata: Optional[dict],
|
|
190
|
-
id: Optional[str],
|
|
191
|
-
) -> STEPS:
|
|
192
|
-
inspection_step_dict: Dict[str, Any] = {
|
|
193
|
-
InspectionTypes.image.value: TakeImage(target=target),
|
|
194
|
-
InspectionTypes.video.value: TakeVideo(target=target, duration=duration),
|
|
195
|
-
InspectionTypes.thermal_image.value: TakeThermalImage(target=target),
|
|
196
|
-
InspectionTypes.thermal_video.value: TakeThermalVideo(
|
|
197
|
-
target=target, duration=duration
|
|
198
|
-
),
|
|
199
|
-
InspectionTypes.audio.value: RecordAudio(target=target, duration=duration),
|
|
200
|
-
}
|
|
201
100
|
|
|
202
|
-
|
|
203
|
-
|
|
101
|
+
def to_isar_task(task_definition: StartMissionTaskDefinition) -> TASKS:
|
|
102
|
+
if task_definition.type == TaskType.Inspection:
|
|
103
|
+
return to_inspection_task(task_definition)
|
|
104
|
+
elif task_definition.type == TaskType.ReturnToHome:
|
|
105
|
+
return ReturnToHome()
|
|
204
106
|
else:
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
inspection_step.tag_id = tag_id
|
|
209
|
-
if metadata:
|
|
210
|
-
inspection_step.metadata = metadata
|
|
211
|
-
if id:
|
|
212
|
-
inspection_step.id = id
|
|
213
|
-
|
|
214
|
-
return inspection_step
|
|
107
|
+
raise MissionFormatError(
|
|
108
|
+
f"Failed to create task: '{task_definition.type}' is not a valid"
|
|
109
|
+
)
|
|
215
110
|
|
|
216
111
|
|
|
217
|
-
def
|
|
218
|
-
|
|
219
|
-
duplicate_ids: List[str] = []
|
|
220
|
-
for item in items:
|
|
221
|
-
id: str = item.id
|
|
222
|
-
if id not in unique_ids:
|
|
223
|
-
unique_ids.append(id)
|
|
224
|
-
else:
|
|
225
|
-
duplicate_ids.append(id)
|
|
112
|
+
def to_inspection_task(task_definition: StartMissionTaskDefinition) -> TASKS:
|
|
113
|
+
inspection_definition = task_definition.inspection
|
|
226
114
|
|
|
227
|
-
|
|
115
|
+
if inspection_definition.type == InspectionTypes.image:
|
|
116
|
+
return TakeImage(
|
|
117
|
+
id=task_definition.id if task_definition.id else uuid4_string(),
|
|
118
|
+
robot_pose=task_definition.pose.to_alitra_pose(),
|
|
119
|
+
tag_id=task_definition.tag,
|
|
120
|
+
inspection_description=task_definition.inspection.inspection_description,
|
|
121
|
+
target=task_definition.inspection.inspection_target.to_alitra_position(),
|
|
122
|
+
zoom=task_definition.zoom,
|
|
123
|
+
)
|
|
124
|
+
elif inspection_definition.type == InspectionTypes.video:
|
|
125
|
+
return TakeVideo(
|
|
126
|
+
id=task_definition.id if task_definition.id else uuid4_string(),
|
|
127
|
+
robot_pose=task_definition.pose.to_alitra_pose(),
|
|
128
|
+
tag_id=task_definition.tag,
|
|
129
|
+
inspection_description=task_definition.inspection.inspection_description,
|
|
130
|
+
target=task_definition.inspection.inspection_target.to_alitra_position(),
|
|
131
|
+
duration=inspection_definition.duration,
|
|
132
|
+
zoom=task_definition.zoom,
|
|
133
|
+
)
|
|
134
|
+
elif inspection_definition.type == InspectionTypes.thermal_image:
|
|
135
|
+
return TakeThermalImage(
|
|
136
|
+
id=task_definition.id if task_definition.id else uuid4_string(),
|
|
137
|
+
robot_pose=task_definition.pose.to_alitra_pose(),
|
|
138
|
+
tag_id=task_definition.tag,
|
|
139
|
+
inspection_description=task_definition.inspection.inspection_description,
|
|
140
|
+
target=task_definition.inspection.inspection_target.to_alitra_position(),
|
|
141
|
+
zoom=task_definition.zoom,
|
|
142
|
+
)
|
|
143
|
+
elif inspection_definition.type == InspectionTypes.thermal_video:
|
|
144
|
+
return TakeThermalVideo(
|
|
145
|
+
id=task_definition.id if task_definition.id else uuid4_string(),
|
|
146
|
+
robot_pose=task_definition.pose.to_alitra_pose(),
|
|
147
|
+
tag_id=task_definition.tag,
|
|
148
|
+
inspection_description=task_definition.inspection.inspection_description,
|
|
149
|
+
target=task_definition.inspection.inspection_target.to_alitra_position(),
|
|
150
|
+
duration=inspection_definition.duration,
|
|
151
|
+
zoom=task_definition.zoom,
|
|
152
|
+
)
|
|
153
|
+
elif inspection_definition.type == InspectionTypes.audio:
|
|
154
|
+
return RecordAudio(
|
|
155
|
+
id=task_definition.id if task_definition.id else uuid4_string(),
|
|
156
|
+
robot_pose=task_definition.pose.to_alitra_pose(),
|
|
157
|
+
tag_id=task_definition.tag,
|
|
158
|
+
inspection_description=task_definition.inspection.inspection_description,
|
|
159
|
+
target=task_definition.inspection.inspection_target.to_alitra_position(),
|
|
160
|
+
duration=inspection_definition.duration,
|
|
161
|
+
)
|
|
162
|
+
elif inspection_definition.type == InspectionTypes.co2_measurement:
|
|
163
|
+
return TakeCO2Measurement(
|
|
164
|
+
id=task_definition.id if task_definition.id else uuid4_string(),
|
|
165
|
+
robot_pose=task_definition.pose.to_alitra_pose(),
|
|
166
|
+
tag_id=task_definition.tag,
|
|
167
|
+
inspection_description=task_definition.inspection.inspection_description,
|
|
168
|
+
)
|
|
169
|
+
else:
|
|
170
|
+
raise ValueError(
|
|
171
|
+
f"Inspection type '{inspection_definition.type}' not supported"
|
|
172
|
+
)
|
|
228
173
|
|
|
229
174
|
|
|
230
175
|
def _build_mission_name() -> str:
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
from fastapi import HTTPException
|
|
4
|
+
from opentelemetry import trace
|
|
5
|
+
|
|
6
|
+
from isar.apis.models.models import RobotInfoResponse
|
|
7
|
+
from isar.config.settings import robot_settings, settings
|
|
8
|
+
from isar.services.utilities.robot_utilities import RobotUtilities
|
|
9
|
+
from robot_interface.models.robots.media import MediaConfig
|
|
10
|
+
|
|
11
|
+
tracer = trace.get_tracer(__name__)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class RobotController:
|
|
15
|
+
def __init__(
|
|
16
|
+
self,
|
|
17
|
+
robot_utilities: RobotUtilities,
|
|
18
|
+
):
|
|
19
|
+
self.robot_utilities: RobotUtilities = robot_utilities
|
|
20
|
+
self.logger = logging.getLogger("api")
|
|
21
|
+
|
|
22
|
+
@tracer.start_as_current_span("generate_media_config")
|
|
23
|
+
def generate_media_config(self) -> MediaConfig:
|
|
24
|
+
media_config: MediaConfig = self.robot_utilities.generate_media_config()
|
|
25
|
+
if media_config is None:
|
|
26
|
+
raise HTTPException(
|
|
27
|
+
status_code=204,
|
|
28
|
+
detail="Robot has no media config",
|
|
29
|
+
)
|
|
30
|
+
return media_config
|
|
31
|
+
|
|
32
|
+
@tracer.start_as_current_span("get_info")
|
|
33
|
+
def get_info(self) -> RobotInfoResponse:
|
|
34
|
+
return RobotInfoResponse(
|
|
35
|
+
robot_package=settings.ROBOT_PACKAGE,
|
|
36
|
+
isar_id=settings.ISAR_ID,
|
|
37
|
+
robot_name=settings.ROBOT_NAME,
|
|
38
|
+
robot_capabilities=robot_settings.CAPABILITIES,
|
|
39
|
+
robot_map_name=settings.DEFAULT_MAP,
|
|
40
|
+
plant_short_name=settings.PLANT_SHORT_NAME,
|
|
41
|
+
)
|