isar 1.15.0__py3-none-any.whl → 1.34.9__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/__init__.py +2 -5
- isar/apis/api.py +159 -66
- isar/apis/models/__init__.py +0 -1
- isar/apis/models/models.py +22 -12
- isar/apis/models/start_mission_definition.py +128 -123
- isar/apis/robot_control/robot_controller.py +41 -0
- isar/apis/schedule/scheduling_controller.py +135 -121
- isar/apis/security/authentication.py +5 -5
- isar/config/certs/ca-cert.pem +32 -32
- isar/config/keyvault/keyvault_service.py +1 -2
- isar/config/log.py +47 -39
- isar/config/logging.conf +16 -31
- isar/config/open_telemetry.py +102 -0
- isar/config/predefined_mission_definition/default_exr.json +49 -0
- isar/config/predefined_mission_definition/default_mission.json +1 -5
- isar/config/predefined_mission_definition/default_turtlebot.json +4 -11
- isar/config/predefined_missions/default.json +67 -87
- isar/config/predefined_missions/default_extra_capabilities.json +107 -0
- isar/config/settings.py +119 -142
- isar/eventhandlers/eventhandler.py +123 -0
- isar/mission_planner/local_planner.py +6 -20
- isar/mission_planner/mission_planner_interface.py +1 -1
- isar/models/events.py +184 -0
- isar/models/status.py +18 -0
- isar/modules.py +118 -205
- isar/robot/robot.py +377 -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 +171 -0
- isar/services/service_connections/mqtt/mqtt_client.py +47 -11
- isar/services/service_connections/mqtt/robot_heartbeat_publisher.py +32 -0
- isar/services/service_connections/mqtt/robot_info_publisher.py +4 -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 +393 -65
- isar/state_machine/state_machine.py +227 -486
- isar/state_machine/states/__init__.py +0 -7
- 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 +36 -0
- isar/state_machine/states/monitor.py +137 -166
- isar/state_machine/states/offline.py +60 -0
- 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 +61 -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_return_home.py +77 -0
- isar/state_machine/states/unknown_status.py +72 -0
- isar/state_machine/states_enum.py +22 -5
- isar/state_machine/transitions/mission.py +192 -0
- isar/state_machine/transitions/return_home.py +106 -0
- isar/state_machine/transitions/robot_status.py +80 -0
- isar/state_machine/utils/common_event_handlers.py +73 -0
- isar/storage/blob_storage.py +71 -45
- isar/storage/local_storage.py +28 -14
- isar/storage/storage_interface.py +28 -6
- isar/storage/uploader.py +184 -55
- isar/storage/utilities.py +35 -27
- isar-1.34.9.dist-info/METADATA +496 -0
- isar-1.34.9.dist-info/RECORD +135 -0
- {isar-1.15.0.dist-info → isar-1.34.9.dist-info}/WHEEL +1 -1
- isar-1.34.9.dist-info/entry_points.txt +3 -0
- robot_interface/models/exceptions/__init__.py +0 -7
- robot_interface/models/exceptions/robot_exceptions.py +274 -4
- robot_interface/models/initialize/__init__.py +0 -1
- robot_interface/models/inspection/__init__.py +0 -13
- robot_interface/models/inspection/inspection.py +43 -34
- robot_interface/models/mission/mission.py +18 -14
- robot_interface/models/mission/status.py +20 -25
- robot_interface/models/mission/task.py +156 -92
- 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 +135 -66
- robot_interface/telemetry/mqtt_client.py +84 -12
- robot_interface/telemetry/payloads.py +111 -12
- robot_interface/utilities/json_service.py +7 -1
- 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 -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/readers/__init__.py +0 -0
- isar/services/readers/base_reader.py +0 -37
- isar/services/service_connections/mqtt/robot_status_publisher.py +0 -93
- isar/services/service_connections/stid/__init__.py +0 -0
- isar/services/service_connections/stid/stid_service.py +0 -45
- isar/services/utilities/queue_utilities.py +0 -39
- isar/state_machine/states/idle.py +0 -40
- isar/state_machine/states/initialize.py +0 -60
- isar/state_machine/states/initiate.py +0 -129
- isar/state_machine/states/off.py +0 -18
- isar/state_machine/states/stop.py +0 -78
- isar/storage/slimm_storage.py +0 -181
- isar-1.15.0.dist-info/METADATA +0 -417
- isar-1.15.0.dist-info/RECORD +0 -113
- robot_interface/models/initialize/initialize_params.py +0 -9
- robot_interface/models/mission/step.py +0 -211
- {isar-1.15.0.dist-info → isar-1.34.9.dist-info/licenses}/LICENSE +0 -0
- {isar-1.15.0.dist-info → isar-1.34.9.dist-info}/top_level.txt +0 -0
|
@@ -1,15 +1,38 @@
|
|
|
1
|
+
import json
|
|
1
2
|
import time
|
|
2
3
|
from abc import ABCMeta, abstractmethod
|
|
4
|
+
from datetime import datetime, timezone
|
|
3
5
|
from queue import Queue
|
|
4
6
|
from typing import Callable, Tuple
|
|
5
7
|
|
|
6
|
-
from
|
|
8
|
+
from paho.mqtt.packettypes import PacketTypes
|
|
9
|
+
from paho.mqtt.properties import Properties
|
|
10
|
+
|
|
11
|
+
from isar.config.settings import settings
|
|
12
|
+
from robot_interface.models.exceptions.robot_exceptions import (
|
|
13
|
+
RobotTelemetryException,
|
|
14
|
+
RobotTelemetryNoUpdateException,
|
|
15
|
+
RobotTelemetryPoseException,
|
|
16
|
+
)
|
|
17
|
+
from robot_interface.telemetry.payloads import CloudHealthPayload
|
|
18
|
+
from robot_interface.utilities.json_service import EnhancedJSONEncoder
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def props_expiry(seconds: int) -> Properties:
|
|
22
|
+
p = Properties(PacketTypes.PUBLISH)
|
|
23
|
+
p.MessageExpiryInterval = seconds
|
|
24
|
+
return p
|
|
7
25
|
|
|
8
26
|
|
|
9
27
|
class MqttClientInterface(metaclass=ABCMeta):
|
|
10
28
|
@abstractmethod
|
|
11
29
|
def publish(
|
|
12
|
-
self,
|
|
30
|
+
self,
|
|
31
|
+
topic: str,
|
|
32
|
+
payload: str,
|
|
33
|
+
qos: int = 0,
|
|
34
|
+
retain: bool = False,
|
|
35
|
+
properties: Properties = None,
|
|
13
36
|
) -> None:
|
|
14
37
|
"""
|
|
15
38
|
Parameters
|
|
@@ -25,7 +48,6 @@ class MqttClientInterface(metaclass=ABCMeta):
|
|
|
25
48
|
|
|
26
49
|
Returns
|
|
27
50
|
-------
|
|
28
|
-
|
|
29
51
|
"""
|
|
30
52
|
pass
|
|
31
53
|
|
|
@@ -35,9 +57,20 @@ class MqttPublisher(MqttClientInterface):
|
|
|
35
57
|
self.mqtt_queue: Queue = mqtt_queue
|
|
36
58
|
|
|
37
59
|
def publish(
|
|
38
|
-
self,
|
|
60
|
+
self,
|
|
61
|
+
topic: str,
|
|
62
|
+
payload: str,
|
|
63
|
+
qos: int = 0,
|
|
64
|
+
retain: bool = False,
|
|
65
|
+
properties: Properties = None,
|
|
39
66
|
) -> None:
|
|
40
|
-
queue_message: Tuple[str, str, int, bool] = (
|
|
67
|
+
queue_message: Tuple[str, str, int, bool, Properties] = (
|
|
68
|
+
topic,
|
|
69
|
+
payload,
|
|
70
|
+
qos,
|
|
71
|
+
retain,
|
|
72
|
+
properties,
|
|
73
|
+
)
|
|
41
74
|
self.mqtt_queue.put(queue_message)
|
|
42
75
|
|
|
43
76
|
|
|
@@ -50,6 +83,7 @@ class MqttTelemetryPublisher(MqttClientInterface):
|
|
|
50
83
|
interval: float,
|
|
51
84
|
qos: int = 0,
|
|
52
85
|
retain: bool = False,
|
|
86
|
+
properties: Properties = None,
|
|
53
87
|
) -> None:
|
|
54
88
|
self.mqtt_queue: Queue = mqtt_queue
|
|
55
89
|
self.telemetry_method: Callable = telemetry_method
|
|
@@ -57,23 +91,61 @@ class MqttTelemetryPublisher(MqttClientInterface):
|
|
|
57
91
|
self.interval: float = interval
|
|
58
92
|
self.qos: int = qos
|
|
59
93
|
self.retain: bool = retain
|
|
94
|
+
self.properties: Properties = properties
|
|
60
95
|
|
|
61
96
|
def run(self, isar_id: str, robot_name: str) -> None:
|
|
97
|
+
self.cloud_health_topic: str = f"isar/{isar_id}/cloud_health"
|
|
98
|
+
self.battery_topic: str = f"isar/{isar_id}/battery"
|
|
99
|
+
self.pose_topic: str = f"isar/{isar_id}/pose"
|
|
100
|
+
self.pressure_topic: str = f"isar/{isar_id}/pressure"
|
|
101
|
+
topic: str
|
|
102
|
+
payload: str
|
|
103
|
+
|
|
62
104
|
while True:
|
|
63
105
|
try:
|
|
64
|
-
payload
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
106
|
+
payload = self.telemetry_method(isar_id=isar_id, robot_name=robot_name)
|
|
107
|
+
topic = self.topic
|
|
108
|
+
except (RobotTelemetryPoseException, RobotTelemetryNoUpdateException):
|
|
109
|
+
time.sleep(self.interval)
|
|
68
110
|
continue
|
|
111
|
+
except RobotTelemetryException:
|
|
112
|
+
payload = json.dumps(
|
|
113
|
+
CloudHealthPayload(isar_id, robot_name, datetime.now(timezone.utc)),
|
|
114
|
+
cls=EnhancedJSONEncoder,
|
|
115
|
+
)
|
|
116
|
+
topic = self.cloud_health_topic
|
|
117
|
+
|
|
118
|
+
publish_properties = self.properties
|
|
119
|
+
|
|
120
|
+
if topic in (
|
|
121
|
+
self.battery_topic,
|
|
122
|
+
self.pose_topic,
|
|
123
|
+
self.pressure_topic,
|
|
124
|
+
):
|
|
125
|
+
publish_properties = props_expiry(settings.MQTT_TELEMETRY_EXPIRY)
|
|
69
126
|
|
|
70
127
|
self.publish(
|
|
71
|
-
topic=
|
|
128
|
+
topic=topic,
|
|
129
|
+
payload=payload,
|
|
130
|
+
qos=self.qos,
|
|
131
|
+
retain=self.retain,
|
|
132
|
+
properties=publish_properties,
|
|
72
133
|
)
|
|
73
134
|
time.sleep(self.interval)
|
|
74
135
|
|
|
75
136
|
def publish(
|
|
76
|
-
self,
|
|
137
|
+
self,
|
|
138
|
+
topic: str,
|
|
139
|
+
payload: str,
|
|
140
|
+
qos: int = 0,
|
|
141
|
+
retain: bool = False,
|
|
142
|
+
properties: Properties = None,
|
|
77
143
|
) -> None:
|
|
78
|
-
queue_message: Tuple[str, str, int, bool] = (
|
|
144
|
+
queue_message: Tuple[str, str, int, bool, Properties] = (
|
|
145
|
+
topic,
|
|
146
|
+
payload,
|
|
147
|
+
qos,
|
|
148
|
+
retain,
|
|
149
|
+
properties,
|
|
150
|
+
)
|
|
79
151
|
self.mqtt_queue.put(queue_message)
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
2
|
from datetime import datetime
|
|
3
|
-
from typing import List
|
|
3
|
+
from typing import List, Optional
|
|
4
4
|
|
|
5
5
|
from alitra import Pose
|
|
6
|
-
from transitions import State
|
|
7
6
|
|
|
8
|
-
from
|
|
7
|
+
from isar.models.status import IsarStatus
|
|
8
|
+
from isar.storage.storage_interface import BlobStoragePath
|
|
9
|
+
from robot_interface.models.exceptions.robot_exceptions import ErrorReason
|
|
10
|
+
from robot_interface.models.mission.status import MissionStatus, TaskStatus
|
|
11
|
+
from robot_interface.models.mission.task import TaskTypes
|
|
12
|
+
from robot_interface.models.robots.battery_state import BatteryState
|
|
9
13
|
|
|
10
14
|
|
|
11
15
|
@dataclass
|
|
@@ -15,6 +19,13 @@ class TelemetryPayload:
|
|
|
15
19
|
timestamp: datetime
|
|
16
20
|
|
|
17
21
|
|
|
22
|
+
@dataclass
|
|
23
|
+
class CloudHealthPayload:
|
|
24
|
+
isar_id: str
|
|
25
|
+
robot_name: str
|
|
26
|
+
timestamp: datetime
|
|
27
|
+
|
|
28
|
+
|
|
18
29
|
@dataclass
|
|
19
30
|
class TelemetryPosePayload(TelemetryPayload):
|
|
20
31
|
pose: Pose
|
|
@@ -23,6 +34,12 @@ class TelemetryPosePayload(TelemetryPayload):
|
|
|
23
34
|
@dataclass
|
|
24
35
|
class TelemetryBatteryPayload(TelemetryPayload):
|
|
25
36
|
battery_level: float
|
|
37
|
+
battery_state: Optional[BatteryState] = None
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@dataclass
|
|
41
|
+
class TelemetryObstacleStatusPayload(TelemetryPayload):
|
|
42
|
+
obstacle_status: bool
|
|
26
43
|
|
|
27
44
|
|
|
28
45
|
@dataclass
|
|
@@ -31,21 +48,16 @@ class TelemetryPressurePayload(TelemetryPayload):
|
|
|
31
48
|
|
|
32
49
|
|
|
33
50
|
@dataclass
|
|
34
|
-
class
|
|
51
|
+
class DocumentInfo:
|
|
35
52
|
name: str
|
|
36
53
|
url: str
|
|
37
|
-
type: str
|
|
38
54
|
|
|
39
55
|
|
|
40
56
|
@dataclass
|
|
41
|
-
class
|
|
57
|
+
class IsarStatusPayload:
|
|
42
58
|
isar_id: str
|
|
43
59
|
robot_name: str
|
|
44
|
-
|
|
45
|
-
current_isar_state: State
|
|
46
|
-
current_mission_id: str
|
|
47
|
-
current_task_id: str
|
|
48
|
-
current_step_id: str
|
|
60
|
+
status: IsarStatus
|
|
49
61
|
timestamp: datetime
|
|
50
62
|
|
|
51
63
|
|
|
@@ -56,7 +68,94 @@ class RobotInfoPayload:
|
|
|
56
68
|
robot_model: str
|
|
57
69
|
robot_serial_number: str
|
|
58
70
|
robot_asset: str
|
|
59
|
-
|
|
71
|
+
documentation: List[DocumentInfo]
|
|
60
72
|
host: str
|
|
61
73
|
port: int
|
|
74
|
+
capabilities: List[str]
|
|
75
|
+
timestamp: datetime
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@dataclass
|
|
79
|
+
class RobotHeartbeatPayload:
|
|
80
|
+
isar_id: str
|
|
81
|
+
robot_name: str
|
|
82
|
+
timestamp: datetime
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
@dataclass
|
|
86
|
+
class MissionPayload:
|
|
87
|
+
isar_id: str
|
|
88
|
+
robot_name: str
|
|
89
|
+
mission_id: Optional[str]
|
|
90
|
+
status: Optional[MissionStatus]
|
|
91
|
+
error_reason: Optional[ErrorReason]
|
|
92
|
+
error_description: Optional[str]
|
|
93
|
+
timestamp: datetime
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
@dataclass
|
|
97
|
+
class MissionAbortedPayload:
|
|
98
|
+
isar_id: str
|
|
99
|
+
robot_name: str
|
|
100
|
+
mission_id: str
|
|
101
|
+
can_be_continued: bool
|
|
102
|
+
timestamp: datetime
|
|
103
|
+
reason: Optional[str]
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
@dataclass
|
|
107
|
+
class TaskPayload:
|
|
108
|
+
isar_id: str
|
|
109
|
+
robot_name: str
|
|
110
|
+
mission_id: Optional[str]
|
|
111
|
+
task_id: Optional[str]
|
|
112
|
+
status: Optional[TaskStatus]
|
|
113
|
+
task_type: Optional[TaskTypes]
|
|
114
|
+
error_reason: Optional[ErrorReason]
|
|
115
|
+
error_description: Optional[str]
|
|
116
|
+
timestamp: datetime
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
@dataclass
|
|
120
|
+
class InspectionResultPayload:
|
|
121
|
+
isar_id: str
|
|
122
|
+
robot_name: str
|
|
123
|
+
inspection_id: str
|
|
124
|
+
blob_storage_data_path: BlobStoragePath
|
|
125
|
+
blob_storage_metadata_path: BlobStoragePath
|
|
126
|
+
installation_code: str
|
|
127
|
+
tag_id: Optional[str]
|
|
128
|
+
inspection_type: Optional[str]
|
|
129
|
+
inspection_description: Optional[str]
|
|
130
|
+
timestamp: datetime
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
@dataclass
|
|
134
|
+
class InspectionValuePayload:
|
|
135
|
+
isar_id: str
|
|
136
|
+
robot_name: str
|
|
137
|
+
inspection_id: str
|
|
138
|
+
installation_code: str
|
|
139
|
+
tag_id: Optional[str]
|
|
140
|
+
inspection_type: Optional[str]
|
|
141
|
+
inspection_description: Optional[str]
|
|
142
|
+
value: float
|
|
143
|
+
unit: str
|
|
144
|
+
x: float
|
|
145
|
+
y: float
|
|
146
|
+
z: float
|
|
147
|
+
timestamp: datetime
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
@dataclass
|
|
151
|
+
class StartUpMessagePayload:
|
|
152
|
+
isar_id: str
|
|
153
|
+
timestamp: datetime
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
@dataclass
|
|
157
|
+
class InterventionNeededPayload:
|
|
158
|
+
isar_id: str
|
|
159
|
+
robot_name: str
|
|
160
|
+
reason: str
|
|
62
161
|
timestamp: datetime
|
|
@@ -7,6 +7,7 @@ from uuid import UUID
|
|
|
7
7
|
|
|
8
8
|
import numpy as np
|
|
9
9
|
from alitra import Orientation
|
|
10
|
+
from pydantic import BaseModel
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
class EnhancedJSONEncoder(json.JSONEncoder):
|
|
@@ -15,8 +16,13 @@ class EnhancedJSONEncoder(json.JSONEncoder):
|
|
|
15
16
|
"""
|
|
16
17
|
|
|
17
18
|
def default(self, o):
|
|
19
|
+
if isinstance(o, BaseModel):
|
|
20
|
+
dump = getattr(o, "model_dump", None)
|
|
21
|
+
if callable(dump):
|
|
22
|
+
return dump()
|
|
23
|
+
return o.__dict__
|
|
18
24
|
if is_dataclass(o):
|
|
19
|
-
return asdict(o)
|
|
25
|
+
return asdict(o) # type: ignore
|
|
20
26
|
if isinstance(o, UUID):
|
|
21
27
|
return str(o)
|
|
22
28
|
if isinstance(o, Orientation):
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "2",
|
|
3
|
-
"tasks": [
|
|
4
|
-
{
|
|
5
|
-
"steps": [
|
|
6
|
-
{
|
|
7
|
-
"type": "drive_to_pose",
|
|
8
|
-
"pose": {
|
|
9
|
-
"position": {
|
|
10
|
-
"x": -3.6,
|
|
11
|
-
"y": 4,
|
|
12
|
-
"z": 0,
|
|
13
|
-
"frame": "asset"
|
|
14
|
-
},
|
|
15
|
-
"orientation": {
|
|
16
|
-
"x": 0,
|
|
17
|
-
"y": 0,
|
|
18
|
-
"z": -0.7286672256879113,
|
|
19
|
-
"w": -0.6848660759820616,
|
|
20
|
-
"frame": "asset"
|
|
21
|
-
},
|
|
22
|
-
"frame": "asset"
|
|
23
|
-
}
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
"type": "take_image",
|
|
27
|
-
"target": {
|
|
28
|
-
"x": -4.7,
|
|
29
|
-
"y": 4.9,
|
|
30
|
-
"z": 0,
|
|
31
|
-
"frame": "robot"
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
]
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
"steps": [
|
|
38
|
-
{
|
|
39
|
-
"type": "drive_to_pose",
|
|
40
|
-
"pose": {
|
|
41
|
-
"position": {
|
|
42
|
-
"x": 4.7,
|
|
43
|
-
"y": 3,
|
|
44
|
-
"z": 0,
|
|
45
|
-
"frame": "asset"
|
|
46
|
-
},
|
|
47
|
-
"orientation": {
|
|
48
|
-
"x": 0,
|
|
49
|
-
"y": 0,
|
|
50
|
-
"z": 0.5769585,
|
|
51
|
-
"w": 0.8167734,
|
|
52
|
-
"frame": "asset"
|
|
53
|
-
},
|
|
54
|
-
"frame": "asset"
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
"type": "take_image",
|
|
59
|
-
"target": {
|
|
60
|
-
"x": 5.6,
|
|
61
|
-
"y": 5.2,
|
|
62
|
-
"z": 0,
|
|
63
|
-
"frame": "robot"
|
|
64
|
-
}
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
"type": "take_thermal_image",
|
|
68
|
-
"target": {
|
|
69
|
-
"x": 3.1,
|
|
70
|
-
"y": 5.2,
|
|
71
|
-
"z": 0,
|
|
72
|
-
"frame": "robot"
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
]
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
"steps": [
|
|
79
|
-
{
|
|
80
|
-
"type": "drive_to_pose",
|
|
81
|
-
"pose": {
|
|
82
|
-
"position": {
|
|
83
|
-
"x": 0.95,
|
|
84
|
-
"y": 2.6,
|
|
85
|
-
"z": 0,
|
|
86
|
-
"frame": "asset"
|
|
87
|
-
},
|
|
88
|
-
"orientation": {
|
|
89
|
-
"x": 0,
|
|
90
|
-
"y": 0,
|
|
91
|
-
"z": -0.6992469,
|
|
92
|
-
"w": 0.7148802,
|
|
93
|
-
"frame": "asset"
|
|
94
|
-
},
|
|
95
|
-
"frame": "asset"
|
|
96
|
-
}
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
"type": "take_thermal_image",
|
|
100
|
-
"target": {
|
|
101
|
-
"x": 1.9,
|
|
102
|
-
"y": 1.9,
|
|
103
|
-
"z": 0,
|
|
104
|
-
"frame": "robot"
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
]
|
|
108
|
-
}
|
|
109
|
-
]
|
|
110
|
-
}
|
|
File without changes
|