standardbots 2.0.0.dev1708994068__py3-none-any.whl → 2.0.0.dev1737138088__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 standardbots might be problematic. Click here for more details.
- standardbots/auto_generated/__init__.py +1 -0
- standardbots/auto_generated/apis.py +2542 -902
- standardbots/auto_generated/models.py +4898 -628
- standardbots-2.0.0.dev1737138088.dist-info/METADATA +22 -0
- standardbots-2.0.0.dev1737138088.dist-info/RECORD +8 -0
- {standardbots-2.0.0.dev1708994068.dist-info → standardbots-2.0.0.dev1737138088.dist-info}/WHEEL +1 -1
- standardbots-2.0.0.dev1708994068.dist-info/METADATA +0 -15
- standardbots-2.0.0.dev1708994068.dist-info/RECORD +0 -8
- {standardbots-2.0.0.dev1708994068.dist-info → standardbots-2.0.0.dev1737138088.dist-info}/top_level.txt +0 -0
|
@@ -1,942 +1,2582 @@
|
|
|
1
1
|
# Code autogenerated by StandardBots
|
|
2
|
-
import urllib3
|
|
3
|
-
from enum import Enum
|
|
4
2
|
import json
|
|
5
3
|
from contextlib import contextmanager
|
|
4
|
+
from enum import Enum
|
|
6
5
|
from typing import Dict, Generic, TypeVar, Union
|
|
7
6
|
|
|
7
|
+
import urllib3
|
|
8
|
+
|
|
8
9
|
from . import models
|
|
9
10
|
|
|
11
|
+
|
|
10
12
|
class RobotKind(Enum):
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
Live = "live"
|
|
14
|
+
Simulated = "simulated"
|
|
15
|
+
|
|
13
16
|
|
|
14
17
|
GenericResponseType = TypeVar('GenericResponseType')
|
|
15
18
|
OkResponseType = TypeVar('OkResponseType')
|
|
16
19
|
|
|
20
|
+
|
|
17
21
|
class Response(Generic[GenericResponseType, OkResponseType]):
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def __init__(self, data: GenericResponseType, status: int, response: urllib3.HTTPResponse):
|
|
22
|
-
self.data = data
|
|
23
|
-
self.status = status
|
|
24
|
-
self.response = response
|
|
25
|
-
|
|
26
|
-
def ok(self) -> OkResponseType:
|
|
27
|
-
if self.status != 200:
|
|
28
|
-
raise Exception("Request failed with status " + str(self.status) + ": " + str(self.data))
|
|
29
|
-
return self.data
|
|
30
|
-
|
|
31
|
-
def assert_status(self, status: int):
|
|
32
|
-
if self.status != status:
|
|
33
|
-
raise Exception("Expecting status " + str(self.status) + ", but found " + str(self.status))
|
|
22
|
+
data: GenericResponseType
|
|
23
|
+
status: int
|
|
24
|
+
response: urllib3.HTTPResponse
|
|
34
25
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
self
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
robot_kind: RobotKind
|
|
45
|
-
):
|
|
46
|
-
self.http = http
|
|
47
|
-
self.token = token
|
|
48
|
-
self.host = host
|
|
49
|
-
self.robot_kind = robot_kind
|
|
26
|
+
def __init__(self, data: GenericResponseType, status: int, response: urllib3.HTTPResponse):
|
|
27
|
+
self.data = data
|
|
28
|
+
self.status = status
|
|
29
|
+
self.response = response
|
|
30
|
+
|
|
31
|
+
def ok(self) -> GenericResponseType:
|
|
32
|
+
if self.status != 200:
|
|
33
|
+
raise Exception("Request failed with status " + str(self.status) + ": " + str(self.data))
|
|
34
|
+
return self.data
|
|
50
35
|
|
|
51
|
-
|
|
52
|
-
|
|
36
|
+
def d(self) -> GenericResponseType:
|
|
37
|
+
return self.data
|
|
53
38
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
"Content-Type": "application/json",
|
|
57
|
-
"Authorization": "Bearer " + self.token,
|
|
58
|
-
"robot_kind": self.robot_kind.value,
|
|
59
|
-
}
|
|
39
|
+
def isNotOk(self):
|
|
40
|
+
return self.status != 200
|
|
60
41
|
|
|
61
|
-
|
|
62
|
-
|
|
42
|
+
def assert_status(self, status: int):
|
|
43
|
+
if self.status != status:
|
|
44
|
+
raise Exception("Expecting status " + str(self.status) + ", but found " + str(self.status))
|
|
45
|
+
|
|
46
|
+
class RequestManager:
|
|
47
|
+
token: str
|
|
48
|
+
host: str
|
|
49
|
+
robot_kind: RobotKind
|
|
50
|
+
def __init__(
|
|
51
|
+
self,
|
|
52
|
+
http: urllib3.PoolManager,
|
|
53
|
+
token: str,
|
|
54
|
+
host: str,
|
|
55
|
+
robot_kind: RobotKind
|
|
56
|
+
):
|
|
57
|
+
self.http = http
|
|
58
|
+
self.token = token
|
|
59
|
+
self.host = host
|
|
60
|
+
self.robot_kind = robot_kind
|
|
61
|
+
|
|
62
|
+
def request(self, method: str, url: str, **kwargs):
|
|
63
|
+
return self.http.request(method, self.host + url, **kwargs)
|
|
64
|
+
|
|
65
|
+
def json_headers(self) -> Dict[str, str]:
|
|
66
|
+
return {
|
|
67
|
+
"Content-Type": "application/json",
|
|
68
|
+
"Authorization": "Bearer " + self.token,
|
|
69
|
+
# Include both for backwards-compatibility purposes.
|
|
70
|
+
"robot_kind": self.robot_kind.value,
|
|
71
|
+
"robot-kind": self.robot_kind.value,
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
def close(self):
|
|
75
|
+
self.http.clear()
|
|
63
76
|
|
|
64
77
|
class Default:
|
|
65
|
-
|
|
66
|
-
|
|
78
|
+
_request_manager: RequestManager
|
|
79
|
+
class Equipment:
|
|
80
|
+
def __init__(self, request_manager: RequestManager):
|
|
81
|
+
self._request_manager = request_manager
|
|
82
|
+
|
|
83
|
+
def onrobot_2fg7_move(
|
|
84
|
+
self,
|
|
85
|
+
value: Union[int, float],
|
|
86
|
+
direction: Union[str, models.LinearGripDirectionEnum] = models.LinearGripDirectionEnum.Inward,
|
|
87
|
+
unit_kind: Union[str, models.LinearUnitKind] = models.LinearUnitKind.Millimeters
|
|
88
|
+
):
|
|
89
|
+
"""Move the robot to the onrobot_2fg7 position.
|
|
90
|
+
"""
|
|
91
|
+
return self.control_gripper(
|
|
92
|
+
models.GripperCommandRequest(
|
|
93
|
+
kind=models.GripperKindEnum.Onrobot2Fg7,
|
|
94
|
+
onrobot_2fg7=models.OnRobot2FG7GripperCommandRequest(
|
|
95
|
+
control_kind=models.OnRobot2FG7ControlKindEnum.Move,
|
|
96
|
+
target_grip_width=models.LinearUnit(
|
|
97
|
+
unit_kind=models.LinearUnitKind(unit_kind),
|
|
98
|
+
value=float(value),
|
|
99
|
+
),
|
|
100
|
+
grip_direction=models.LinearGripDirectionEnum(direction),
|
|
101
|
+
)
|
|
102
|
+
)
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
def onrobot_2fg7_grip(
|
|
106
|
+
self,
|
|
107
|
+
value: Union[int, float],
|
|
108
|
+
direction: Union[str, models.LinearGripDirectionEnum] = models.LinearGripDirectionEnum.Inward,
|
|
109
|
+
unit_kind: Union[str, models.LinearUnitKind] = models.LinearUnitKind.Millimeters,
|
|
110
|
+
force: Union[int, float] = 0.0,
|
|
111
|
+
force_unit: Union[str, models.ForceUnitKind] = models.ForceUnitKind.Newtons
|
|
112
|
+
):
|
|
113
|
+
"""Move the robot to the onrobot_2fg7 position.
|
|
114
|
+
"""
|
|
115
|
+
return self.control_gripper(
|
|
116
|
+
models.GripperCommandRequest(
|
|
117
|
+
kind=models.GripperKindEnum.Onrobot2Fg7,
|
|
118
|
+
onrobot_2fg7=models.OnRobot2FG7GripperCommandRequest(
|
|
119
|
+
control_kind=models.OnRobot2FG7ControlKindEnum.ForceGrip,
|
|
120
|
+
target_grip_width=models.LinearUnit(
|
|
121
|
+
unit_kind=models.LinearUnitKind(unit_kind),
|
|
122
|
+
value=float(value),
|
|
123
|
+
),
|
|
124
|
+
target_force=models.ForceUnit(
|
|
125
|
+
unit_kind=models.ForceUnitKind(force_unit),
|
|
126
|
+
value=float(force),
|
|
127
|
+
),
|
|
128
|
+
grip_direction=models.LinearGripDirectionEnum(direction),
|
|
129
|
+
)
|
|
130
|
+
)
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
def dh_ag_grip(
|
|
134
|
+
self,
|
|
135
|
+
target_diameter: float,
|
|
136
|
+
target_force: float | None,
|
|
137
|
+
target_speed: float | None,
|
|
138
|
+
):
|
|
139
|
+
"""
|
|
140
|
+
Control the DH AG gripper.
|
|
141
|
+
Args:
|
|
142
|
+
- target_diameter: 0.0 - 1.0
|
|
143
|
+
- target_force: 0.2 - 1.0
|
|
144
|
+
- target_speed: 0.01 - 1.0
|
|
145
|
+
"""
|
|
146
|
+
return self.control_gripper(
|
|
147
|
+
body=models.GripperCommandRequest(
|
|
148
|
+
kind=models.GripperKindEnum.DhAg,
|
|
149
|
+
dh_ag=models.DHAGGripperCommandRequest(
|
|
150
|
+
target_diameter, target_force, target_speed
|
|
151
|
+
),
|
|
152
|
+
),
|
|
153
|
+
)
|
|
154
|
+
def dh_pgc_grip(
|
|
155
|
+
self,
|
|
156
|
+
target_diameter: float,
|
|
157
|
+
target_force: float | None,
|
|
158
|
+
target_speed: float | None,
|
|
159
|
+
):
|
|
160
|
+
"""
|
|
161
|
+
Control the DH PGC gripper.
|
|
162
|
+
Args:
|
|
163
|
+
- target_diameter: 0.0 - 1.0
|
|
164
|
+
- target_force: 0.2 - 1.0
|
|
165
|
+
- target_speed: 0.01 - 1.0
|
|
166
|
+
"""
|
|
167
|
+
return self.control_gripper(
|
|
168
|
+
body=models.GripperCommandRequest(
|
|
169
|
+
kind=models.GripperKindEnum.DhPgc,
|
|
170
|
+
dh_pgc=models.DHPGCGripperCommandRequest(
|
|
171
|
+
target_diameter, target_force, target_speed
|
|
172
|
+
),
|
|
173
|
+
),
|
|
174
|
+
)
|
|
175
|
+
def dh_cgi_grip(
|
|
176
|
+
self,
|
|
177
|
+
target_diameter: float,
|
|
178
|
+
target_force: float | None,
|
|
179
|
+
target_speed: float | None,
|
|
180
|
+
):
|
|
181
|
+
"""
|
|
182
|
+
Control the DH CGI gripper.
|
|
183
|
+
Args:
|
|
184
|
+
- target_diameter: 0.0 - 1.0
|
|
185
|
+
- target_force: 0.2 - 1.0
|
|
186
|
+
- target_speed: 0.01 - 1.0
|
|
187
|
+
"""
|
|
188
|
+
return self.control_gripper(
|
|
189
|
+
body=models.GripperCommandRequest(
|
|
190
|
+
kind=models.GripperKindEnum.DhCgi,
|
|
191
|
+
dh_pgc=models.DHCGIGripperCommandRequest(
|
|
192
|
+
target_diameter, target_force, target_speed
|
|
193
|
+
),
|
|
194
|
+
),
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def control_gripper(
|
|
199
|
+
self,
|
|
200
|
+
body: models.GripperCommandRequest,
|
|
201
|
+
) -> Response[
|
|
202
|
+
None,
|
|
203
|
+
None
|
|
204
|
+
]:
|
|
205
|
+
"""
|
|
206
|
+
Send commands to control the Gripper (End Effector) of the robot. The gripper can be any of Standard Bots supported grippers.
|
|
207
|
+
|
|
208
|
+
"""
|
|
209
|
+
path = "/api/v1/equipment/end-effector/control"
|
|
210
|
+
try:
|
|
211
|
+
response = self._request_manager.request(
|
|
212
|
+
"POST",
|
|
213
|
+
path,
|
|
214
|
+
headers=self._request_manager.json_headers(),
|
|
215
|
+
body=json.dumps(models.serialize_gripper_command_request(body)),
|
|
216
|
+
)
|
|
217
|
+
parsed = None
|
|
218
|
+
|
|
219
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
220
|
+
is_unavailable = response.status == 503
|
|
221
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
222
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
223
|
+
|
|
224
|
+
return Response(
|
|
225
|
+
parsed,
|
|
226
|
+
response.status,
|
|
227
|
+
response
|
|
228
|
+
)
|
|
229
|
+
except urllib3.exceptions.MaxRetryError:
|
|
230
|
+
return Response(
|
|
231
|
+
models.ErrorResponse(
|
|
232
|
+
error=models.ErrorEnum.InternalServerError,
|
|
233
|
+
message="Connection Refused"
|
|
234
|
+
),
|
|
235
|
+
503,
|
|
236
|
+
None
|
|
237
|
+
)
|
|
238
|
+
def get_gripper_configuration(
|
|
239
|
+
self,
|
|
240
|
+
) -> Response[
|
|
241
|
+
Union[
|
|
242
|
+
models.GripperConfiguration,
|
|
243
|
+
models.ErrorResponse,
|
|
244
|
+
None
|
|
245
|
+
],
|
|
246
|
+
models.GripperConfiguration
|
|
247
|
+
]:
|
|
248
|
+
"""
|
|
249
|
+
Get the current gripper configuration
|
|
250
|
+
|
|
251
|
+
"""
|
|
252
|
+
path = "/api/v1/equipment/end-effector/configuration"
|
|
253
|
+
try:
|
|
254
|
+
response = self._request_manager.request(
|
|
255
|
+
"GET",
|
|
256
|
+
path,
|
|
257
|
+
headers=self._request_manager.json_headers(),
|
|
258
|
+
)
|
|
259
|
+
parsed = None
|
|
260
|
+
if response.status == 200:
|
|
261
|
+
parsed = models.parse_gripper_configuration(json.loads(response.data))
|
|
262
|
+
|
|
263
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
264
|
+
is_unavailable = response.status == 503
|
|
265
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
266
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
267
|
+
|
|
268
|
+
return Response(
|
|
269
|
+
parsed,
|
|
270
|
+
response.status,
|
|
271
|
+
response
|
|
272
|
+
)
|
|
273
|
+
except urllib3.exceptions.MaxRetryError:
|
|
274
|
+
return Response(
|
|
275
|
+
models.ErrorResponse(
|
|
276
|
+
error=models.ErrorEnum.InternalServerError,
|
|
277
|
+
message="Connection Refused"
|
|
278
|
+
),
|
|
279
|
+
503,
|
|
280
|
+
None
|
|
281
|
+
)
|
|
282
|
+
class Sensors:
|
|
283
|
+
def __init__(self, request_manager: RequestManager):
|
|
284
|
+
self._request_manager = request_manager
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def get_sensors(
|
|
288
|
+
self,
|
|
289
|
+
) -> Response[
|
|
290
|
+
Union[
|
|
291
|
+
models.SensorsConfiguration,
|
|
292
|
+
models.ErrorResponse,
|
|
293
|
+
None
|
|
294
|
+
],
|
|
295
|
+
models.SensorsConfiguration
|
|
296
|
+
]:
|
|
297
|
+
"""
|
|
298
|
+
Get the current state of all sensors
|
|
299
|
+
"""
|
|
300
|
+
path = "/api/v1/equipment/custom/sensors"
|
|
301
|
+
try:
|
|
302
|
+
response = self._request_manager.request(
|
|
303
|
+
"GET",
|
|
304
|
+
path,
|
|
305
|
+
headers=self._request_manager.json_headers(),
|
|
306
|
+
)
|
|
307
|
+
parsed = None
|
|
308
|
+
if response.status == 200:
|
|
309
|
+
parsed = models.parse_sensors_configuration(json.loads(response.data))
|
|
310
|
+
|
|
311
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
312
|
+
is_unavailable = response.status == 503
|
|
313
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
314
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
315
|
+
|
|
316
|
+
return Response(
|
|
317
|
+
parsed,
|
|
318
|
+
response.status,
|
|
319
|
+
response
|
|
320
|
+
)
|
|
321
|
+
except urllib3.exceptions.MaxRetryError:
|
|
322
|
+
return Response(
|
|
323
|
+
models.ErrorResponse(
|
|
324
|
+
error=models.ErrorEnum.InternalServerError,
|
|
325
|
+
message="Connection Refused"
|
|
326
|
+
),
|
|
327
|
+
503,
|
|
328
|
+
None
|
|
329
|
+
)
|
|
330
|
+
class Space:
|
|
331
|
+
def __init__(self, request_manager: RequestManager):
|
|
332
|
+
self._request_manager = request_manager
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
def list_planes(
|
|
336
|
+
self,
|
|
337
|
+
limit: int,
|
|
338
|
+
offset: int,
|
|
339
|
+
) -> Response[
|
|
340
|
+
Union[
|
|
341
|
+
models.PlanesPaginatedResponse,
|
|
342
|
+
models.ErrorResponse,
|
|
343
|
+
None
|
|
344
|
+
],
|
|
345
|
+
models.PlanesPaginatedResponse
|
|
346
|
+
]:
|
|
347
|
+
"""
|
|
348
|
+
List Planes
|
|
349
|
+
"""
|
|
350
|
+
path = "/api/v1/space/planes"
|
|
351
|
+
try:
|
|
352
|
+
response = self._request_manager.request(
|
|
353
|
+
"GET",
|
|
354
|
+
path,
|
|
355
|
+
headers=self._request_manager.json_headers(),
|
|
356
|
+
fields={
|
|
357
|
+
"limit": models.serialize_i_64(limit),
|
|
358
|
+
"offset": models.serialize_i_64(offset),
|
|
359
|
+
}
|
|
360
|
+
)
|
|
361
|
+
parsed = None
|
|
362
|
+
if response.status == 200:
|
|
363
|
+
parsed = models.parse_planes_paginated_response(json.loads(response.data))
|
|
364
|
+
|
|
365
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
366
|
+
is_unavailable = response.status == 503
|
|
367
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
368
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
369
|
+
|
|
370
|
+
return Response(
|
|
371
|
+
parsed,
|
|
372
|
+
response.status,
|
|
373
|
+
response
|
|
374
|
+
)
|
|
375
|
+
except urllib3.exceptions.MaxRetryError:
|
|
376
|
+
return Response(
|
|
377
|
+
models.ErrorResponse(
|
|
378
|
+
error=models.ErrorEnum.InternalServerError,
|
|
379
|
+
message="Connection Refused"
|
|
380
|
+
),
|
|
381
|
+
503,
|
|
382
|
+
None
|
|
383
|
+
)
|
|
384
|
+
|
|
385
|
+
equipment: Equipment
|
|
386
|
+
sensors: Sensors
|
|
387
|
+
space: Space
|
|
388
|
+
|
|
67
389
|
def __init__(self, request_manager: RequestManager):
|
|
68
|
-
|
|
390
|
+
self._request_manager = request_manager
|
|
391
|
+
self.equipment = Default.Equipment(request_manager)
|
|
392
|
+
self.sensors = Default.Sensors(request_manager)
|
|
393
|
+
self.space = Default.Space(request_manager)
|
|
69
394
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
395
|
+
class Movement:
|
|
396
|
+
_request_manager: RequestManager
|
|
397
|
+
class Brakes:
|
|
398
|
+
def __init__(self, request_manager: RequestManager):
|
|
399
|
+
self._request_manager = request_manager
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
def brake(self):
|
|
403
|
+
"""Brake the robot
|
|
404
|
+
"""
|
|
405
|
+
return self.set_brakes_state(
|
|
406
|
+
models.BrakesState(
|
|
407
|
+
state=models.BrakesStateEnum.Engaged,
|
|
408
|
+
),
|
|
409
|
+
)
|
|
410
|
+
|
|
411
|
+
def unbrake(self):
|
|
412
|
+
"""Unbrake the robot
|
|
413
|
+
"""
|
|
414
|
+
return self.set_brakes_state(
|
|
415
|
+
models.BrakesState(
|
|
416
|
+
state=models.BrakesStateEnum.Disengaged,
|
|
417
|
+
),
|
|
418
|
+
)
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
def set_brakes_state(
|
|
422
|
+
self,
|
|
423
|
+
body: models.BrakesState,
|
|
424
|
+
) -> Response[
|
|
425
|
+
Union[
|
|
426
|
+
models.BrakesState,
|
|
427
|
+
models.ErrorResponse,
|
|
428
|
+
None
|
|
429
|
+
],
|
|
430
|
+
models.BrakesState
|
|
431
|
+
]:
|
|
432
|
+
"""
|
|
433
|
+
Control Joint Brakes in the robot
|
|
434
|
+
|
|
435
|
+
"""
|
|
436
|
+
path = "/api/v1/movement/brakes"
|
|
437
|
+
try:
|
|
438
|
+
response = self._request_manager.request(
|
|
439
|
+
"POST",
|
|
440
|
+
path,
|
|
441
|
+
headers=self._request_manager.json_headers(),
|
|
442
|
+
body=json.dumps(models.serialize_brakes_state(body)),
|
|
443
|
+
)
|
|
444
|
+
parsed = None
|
|
445
|
+
if response.status == 200:
|
|
446
|
+
parsed = models.parse_brakes_state(json.loads(response.data))
|
|
447
|
+
|
|
448
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
449
|
+
is_unavailable = response.status == 503
|
|
450
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
451
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
452
|
+
|
|
453
|
+
return Response(
|
|
454
|
+
parsed,
|
|
455
|
+
response.status,
|
|
456
|
+
response
|
|
457
|
+
)
|
|
458
|
+
except urllib3.exceptions.MaxRetryError:
|
|
459
|
+
return Response(
|
|
460
|
+
models.ErrorResponse(
|
|
461
|
+
error=models.ErrorEnum.InternalServerError,
|
|
462
|
+
message="Connection Refused"
|
|
463
|
+
),
|
|
464
|
+
503,
|
|
465
|
+
None
|
|
466
|
+
)
|
|
467
|
+
def get_brakes_state(
|
|
468
|
+
self,
|
|
469
|
+
) -> Response[
|
|
470
|
+
Union[
|
|
471
|
+
models.BrakesState,
|
|
472
|
+
models.ErrorResponse,
|
|
473
|
+
None
|
|
474
|
+
],
|
|
475
|
+
models.BrakesState
|
|
476
|
+
]:
|
|
477
|
+
"""
|
|
478
|
+
Get the current state of the robot brakes
|
|
479
|
+
|
|
480
|
+
"""
|
|
481
|
+
path = "/api/v1/movement/brakes"
|
|
482
|
+
try:
|
|
483
|
+
response = self._request_manager.request(
|
|
484
|
+
"GET",
|
|
485
|
+
path,
|
|
486
|
+
headers=self._request_manager.json_headers(),
|
|
487
|
+
)
|
|
488
|
+
parsed = None
|
|
489
|
+
if response.status == 200:
|
|
490
|
+
parsed = models.parse_brakes_state(json.loads(response.data))
|
|
491
|
+
|
|
492
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
493
|
+
is_unavailable = response.status == 503
|
|
494
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
495
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
496
|
+
|
|
497
|
+
return Response(
|
|
498
|
+
parsed,
|
|
499
|
+
response.status,
|
|
500
|
+
response
|
|
501
|
+
)
|
|
502
|
+
except urllib3.exceptions.MaxRetryError:
|
|
503
|
+
return Response(
|
|
504
|
+
models.ErrorResponse(
|
|
505
|
+
error=models.ErrorEnum.InternalServerError,
|
|
506
|
+
message="Connection Refused"
|
|
507
|
+
),
|
|
508
|
+
503,
|
|
509
|
+
None
|
|
510
|
+
)
|
|
511
|
+
def engage_emergency_stop(
|
|
512
|
+
self,
|
|
513
|
+
body: models.EngageEmergencyStopRequest,
|
|
514
|
+
) -> Response[
|
|
515
|
+
None,
|
|
516
|
+
None
|
|
517
|
+
]:
|
|
518
|
+
"""
|
|
519
|
+
Engage Emergency braking system.
|
|
520
|
+
> **⚠️ Warning:** This will immediately stop the robot and may cause damage to the robot or surrounding environment.
|
|
521
|
+
|
|
522
|
+
"""
|
|
523
|
+
path = "/api/v1/movement/brakes/emergency-stop"
|
|
524
|
+
try:
|
|
525
|
+
response = self._request_manager.request(
|
|
526
|
+
"POST",
|
|
527
|
+
path,
|
|
528
|
+
headers=self._request_manager.json_headers(),
|
|
529
|
+
body=json.dumps(models.serialize_engage_emergency_stop_request(body)),
|
|
530
|
+
)
|
|
531
|
+
parsed = None
|
|
532
|
+
|
|
533
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
534
|
+
is_unavailable = response.status == 503
|
|
535
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
536
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
537
|
+
|
|
538
|
+
return Response(
|
|
539
|
+
parsed,
|
|
540
|
+
response.status,
|
|
541
|
+
response
|
|
542
|
+
)
|
|
543
|
+
except urllib3.exceptions.MaxRetryError:
|
|
544
|
+
return Response(
|
|
545
|
+
models.ErrorResponse(
|
|
546
|
+
error=models.ErrorEnum.InternalServerError,
|
|
547
|
+
message="Connection Refused"
|
|
548
|
+
),
|
|
549
|
+
503,
|
|
550
|
+
None
|
|
551
|
+
)
|
|
552
|
+
class Position:
|
|
553
|
+
def __init__(self, request_manager: RequestManager):
|
|
554
|
+
self._request_manager = request_manager
|
|
555
|
+
|
|
556
|
+
def move(
|
|
557
|
+
self,
|
|
558
|
+
position: models.Position,
|
|
559
|
+
orientation: models.Orientation,
|
|
560
|
+
reference_frame: str = 'base',
|
|
561
|
+
axis_alignment: str = 'base',
|
|
562
|
+
local_accuracy_calibration: str | None = None,
|
|
563
|
+
movement_kind: models.MovementKindEnum | None = models.MovementKindEnum.Joint,
|
|
564
|
+
speed_profile: models.SpeedProfile | None = None,
|
|
565
|
+
):
|
|
566
|
+
return self.move_tooltip(
|
|
567
|
+
position=position,
|
|
568
|
+
orientation=orientation,
|
|
569
|
+
reference_frame=reference_frame,
|
|
570
|
+
axis_alignment=axis_alignment,
|
|
571
|
+
local_accuracy_calibration=local_accuracy_calibration,
|
|
572
|
+
movement_kind=movement_kind,
|
|
573
|
+
speed_profile=speed_profile
|
|
88
574
|
)
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
),
|
|
111
|
-
target_force=models.ForceUnit(
|
|
112
|
-
unit_kind=models.ForceUnitKind(force_unit),
|
|
113
|
-
value=float(force),
|
|
575
|
+
|
|
576
|
+
def move_tooltip(
|
|
577
|
+
self,
|
|
578
|
+
position: models.Position,
|
|
579
|
+
orientation: models.Orientation,
|
|
580
|
+
reference_frame: str = 'base',
|
|
581
|
+
axis_alignment: str = 'base',
|
|
582
|
+
local_accuracy_calibration: str | None = None,
|
|
583
|
+
movement_kind: models.MovementKindEnum | None = models.MovementKindEnum.Joint,
|
|
584
|
+
speed_profile: models.SpeedProfile | None = None,
|
|
585
|
+
):
|
|
586
|
+
"""Move tooltip of robot to specified position
|
|
587
|
+
"""
|
|
588
|
+
request = models.ArmPositionUpdateRequest(
|
|
589
|
+
kind=models.ArmPositionUpdateRequestKindEnum.TooltipPosition,
|
|
590
|
+
tooltip_position=models.PositionAndOrientation(
|
|
591
|
+
position=position,
|
|
592
|
+
orientation=orientation,
|
|
593
|
+
reference_frame=reference_frame,
|
|
594
|
+
local_accuracy_calibration=local_accuracy_calibration,
|
|
595
|
+
axis_alignment=axis_alignment,
|
|
114
596
|
),
|
|
115
|
-
|
|
597
|
+
movement_kind=movement_kind,
|
|
598
|
+
speed_profile=speed_profile
|
|
116
599
|
)
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
600
|
+
return self.set_arm_position(request)
|
|
601
|
+
|
|
602
|
+
|
|
603
|
+
def get_arm_position(
|
|
604
|
+
self,
|
|
605
|
+
) -> Response[
|
|
606
|
+
Union[
|
|
607
|
+
models.CombinedArmPosition,
|
|
608
|
+
models.ErrorResponse,
|
|
609
|
+
None
|
|
610
|
+
],
|
|
611
|
+
models.CombinedArmPosition
|
|
612
|
+
]:
|
|
613
|
+
"""
|
|
614
|
+
Get the current position of the robot arm
|
|
615
|
+
"""
|
|
616
|
+
path = "/api/v1/movement/position/arm"
|
|
617
|
+
try:
|
|
618
|
+
response = self._request_manager.request(
|
|
619
|
+
"GET",
|
|
620
|
+
path,
|
|
621
|
+
headers=self._request_manager.json_headers(),
|
|
622
|
+
)
|
|
623
|
+
parsed = None
|
|
624
|
+
if response.status == 200:
|
|
625
|
+
parsed = models.parse_combined_arm_position(json.loads(response.data))
|
|
626
|
+
|
|
627
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
628
|
+
is_unavailable = response.status == 503
|
|
629
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
630
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
631
|
+
|
|
632
|
+
return Response(
|
|
633
|
+
parsed,
|
|
634
|
+
response.status,
|
|
635
|
+
response
|
|
636
|
+
)
|
|
637
|
+
except urllib3.exceptions.MaxRetryError:
|
|
638
|
+
return Response(
|
|
639
|
+
models.ErrorResponse(
|
|
640
|
+
error=models.ErrorEnum.InternalServerError,
|
|
641
|
+
message="Connection Refused"
|
|
642
|
+
),
|
|
643
|
+
503,
|
|
644
|
+
None
|
|
645
|
+
)
|
|
646
|
+
def set_arm_position(
|
|
647
|
+
self,
|
|
648
|
+
body: models.ArmPositionUpdateRequest,
|
|
649
|
+
) -> Response[
|
|
650
|
+
Union[
|
|
651
|
+
models.ArmPositionUpdateEvent,
|
|
652
|
+
models.ErrorResponse,
|
|
653
|
+
None
|
|
654
|
+
],
|
|
655
|
+
models.ArmPositionUpdateEvent
|
|
656
|
+
]:
|
|
657
|
+
"""
|
|
658
|
+
Control the position of the RO1 Robot arm.
|
|
659
|
+
|
|
660
|
+
"""
|
|
661
|
+
path = "/api/v1/movement/position/arm"
|
|
662
|
+
try:
|
|
663
|
+
response = self._request_manager.request(
|
|
664
|
+
"POST",
|
|
665
|
+
path,
|
|
666
|
+
headers=self._request_manager.json_headers(),
|
|
667
|
+
body=json.dumps(models.serialize_arm_position_update_request(body)),
|
|
668
|
+
)
|
|
669
|
+
parsed = None
|
|
670
|
+
if response.status == 200:
|
|
671
|
+
parsed = models.parse_arm_position_update_event(json.loads(response.data))
|
|
672
|
+
|
|
673
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
674
|
+
is_unavailable = response.status == 503
|
|
675
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
676
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
677
|
+
|
|
678
|
+
return Response(
|
|
679
|
+
parsed,
|
|
680
|
+
response.status,
|
|
681
|
+
response
|
|
682
|
+
)
|
|
683
|
+
except urllib3.exceptions.MaxRetryError:
|
|
684
|
+
return Response(
|
|
685
|
+
models.ErrorResponse(
|
|
686
|
+
error=models.ErrorEnum.InternalServerError,
|
|
687
|
+
message="Connection Refused"
|
|
688
|
+
),
|
|
689
|
+
503,
|
|
690
|
+
None
|
|
691
|
+
)
|
|
692
|
+
|
|
693
|
+
brakes: Brakes
|
|
694
|
+
position: Position
|
|
695
|
+
|
|
188
696
|
def __init__(self, request_manager: RequestManager):
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
697
|
+
self._request_manager = request_manager
|
|
698
|
+
self.brakes = Movement.Brakes(request_manager)
|
|
699
|
+
self.position = Movement.Position(request_manager)
|
|
700
|
+
|
|
701
|
+
class Camera:
|
|
702
|
+
_request_manager: RequestManager
|
|
703
|
+
class Data:
|
|
704
|
+
def __init__(self, request_manager: RequestManager):
|
|
705
|
+
self._request_manager = request_manager
|
|
706
|
+
|
|
707
|
+
|
|
708
|
+
def get_color_frame(
|
|
709
|
+
self,
|
|
710
|
+
body: models.CameraFrameRequest,
|
|
711
|
+
) -> Response[
|
|
712
|
+
None,
|
|
713
|
+
None
|
|
714
|
+
]:
|
|
715
|
+
"""
|
|
716
|
+
Retrieve the latest RGB frame from the camera.
|
|
717
|
+
"""
|
|
718
|
+
path = "/api/v1/camera/frame/rgb"
|
|
719
|
+
try:
|
|
720
|
+
response = self._request_manager.request(
|
|
721
|
+
"GET",
|
|
722
|
+
path,
|
|
723
|
+
headers=self._request_manager.json_headers(),
|
|
724
|
+
body=json.dumps(models.serialize_camera_frame_request(body)),
|
|
725
|
+
)
|
|
726
|
+
parsed = None
|
|
727
|
+
|
|
728
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
729
|
+
is_unavailable = response.status == 503
|
|
730
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
731
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
732
|
+
|
|
733
|
+
return Response(
|
|
734
|
+
parsed,
|
|
735
|
+
response.status,
|
|
736
|
+
response
|
|
737
|
+
)
|
|
738
|
+
except urllib3.exceptions.MaxRetryError:
|
|
739
|
+
return Response(
|
|
740
|
+
models.ErrorResponse(
|
|
741
|
+
error=models.ErrorEnum.InternalServerError,
|
|
742
|
+
message="Connection Refused"
|
|
743
|
+
),
|
|
744
|
+
503,
|
|
745
|
+
None
|
|
746
|
+
)
|
|
747
|
+
def get_camera_intrinsics_color(
|
|
748
|
+
self,
|
|
749
|
+
) -> Response[
|
|
750
|
+
None,
|
|
751
|
+
None
|
|
752
|
+
]:
|
|
753
|
+
"""
|
|
754
|
+
Retrieve the intrinsic parameters for the color camera.
|
|
755
|
+
"""
|
|
756
|
+
path = "/api/v1/camera/intrinsics/rgb"
|
|
757
|
+
try:
|
|
758
|
+
response = self._request_manager.request(
|
|
759
|
+
"GET",
|
|
760
|
+
path,
|
|
761
|
+
headers=self._request_manager.json_headers(),
|
|
762
|
+
)
|
|
763
|
+
parsed = None
|
|
764
|
+
|
|
765
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
766
|
+
is_unavailable = response.status == 503
|
|
767
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
768
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
769
|
+
|
|
770
|
+
return Response(
|
|
771
|
+
parsed,
|
|
772
|
+
response.status,
|
|
773
|
+
response
|
|
774
|
+
)
|
|
775
|
+
except urllib3.exceptions.MaxRetryError:
|
|
776
|
+
return Response(
|
|
777
|
+
models.ErrorResponse(
|
|
778
|
+
error=models.ErrorEnum.InternalServerError,
|
|
779
|
+
message="Connection Refused"
|
|
780
|
+
),
|
|
781
|
+
503,
|
|
782
|
+
None
|
|
783
|
+
)
|
|
784
|
+
def get_camera_stream(
|
|
785
|
+
self,
|
|
786
|
+
) -> Response[
|
|
787
|
+
None,
|
|
788
|
+
None
|
|
789
|
+
]:
|
|
790
|
+
"""
|
|
791
|
+
Retrieve the latest RGB frame from the camera.
|
|
792
|
+
"""
|
|
793
|
+
path = "/api/v1/camera/stream/rgb"
|
|
794
|
+
try:
|
|
795
|
+
response = self._request_manager.request(
|
|
796
|
+
"GET",
|
|
797
|
+
path,
|
|
798
|
+
headers=self._request_manager.json_headers(),
|
|
799
|
+
preload_content=False,
|
|
800
|
+
)
|
|
801
|
+
parsed = None
|
|
802
|
+
|
|
803
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
804
|
+
is_unavailable = response.status == 503
|
|
805
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
806
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
807
|
+
|
|
808
|
+
return Response(
|
|
809
|
+
parsed,
|
|
810
|
+
response.status,
|
|
811
|
+
response
|
|
812
|
+
)
|
|
813
|
+
except urllib3.exceptions.MaxRetryError:
|
|
814
|
+
return Response(
|
|
815
|
+
models.ErrorResponse(
|
|
816
|
+
error=models.ErrorEnum.InternalServerError,
|
|
817
|
+
message="Connection Refused"
|
|
818
|
+
),
|
|
819
|
+
503,
|
|
820
|
+
None
|
|
821
|
+
)
|
|
822
|
+
class Settings:
|
|
823
|
+
def __init__(self, request_manager: RequestManager):
|
|
824
|
+
self._request_manager = request_manager
|
|
825
|
+
|
|
826
|
+
|
|
827
|
+
def set_camera_settings(
|
|
828
|
+
self,
|
|
829
|
+
body: models.CameraSettings,
|
|
830
|
+
) -> Response[
|
|
831
|
+
None,
|
|
832
|
+
None
|
|
833
|
+
]:
|
|
834
|
+
"""
|
|
835
|
+
Set the camera settings.
|
|
836
|
+
"""
|
|
837
|
+
path = "/api/v1/camera/settings"
|
|
838
|
+
try:
|
|
839
|
+
response = self._request_manager.request(
|
|
840
|
+
"POST",
|
|
841
|
+
path,
|
|
842
|
+
headers=self._request_manager.json_headers(),
|
|
843
|
+
body=json.dumps(models.serialize_camera_settings(body)),
|
|
844
|
+
)
|
|
845
|
+
parsed = None
|
|
846
|
+
|
|
847
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
848
|
+
is_unavailable = response.status == 503
|
|
849
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
850
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
851
|
+
|
|
852
|
+
return Response(
|
|
853
|
+
parsed,
|
|
854
|
+
response.status,
|
|
855
|
+
response
|
|
856
|
+
)
|
|
857
|
+
except urllib3.exceptions.MaxRetryError:
|
|
858
|
+
return Response(
|
|
859
|
+
models.ErrorResponse(
|
|
860
|
+
error=models.ErrorEnum.InternalServerError,
|
|
861
|
+
message="Connection Refused"
|
|
862
|
+
),
|
|
863
|
+
503,
|
|
864
|
+
None
|
|
865
|
+
)
|
|
866
|
+
|
|
867
|
+
data: Data
|
|
868
|
+
settings: Settings
|
|
279
869
|
|
|
280
|
-
class Movement:
|
|
281
|
-
_request_manager: RequestManager
|
|
282
|
-
class Brakes:
|
|
283
870
|
def __init__(self, request_manager: RequestManager):
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
def get_brakes_state(
|
|
344
|
-
self,
|
|
345
|
-
) -> Response[
|
|
346
|
-
Union[
|
|
347
|
-
models.BrakesState,
|
|
348
|
-
models.ErrorResponse,
|
|
349
|
-
None
|
|
350
|
-
],
|
|
351
|
-
models.BrakesState
|
|
352
|
-
]:
|
|
353
|
-
"""
|
|
354
|
-
Get the current state of the robot brakes
|
|
355
|
-
|
|
356
|
-
"""
|
|
357
|
-
path = "/api/v1/movement/brakes"
|
|
358
|
-
response = self._request_manager.request(
|
|
359
|
-
"GET",
|
|
360
|
-
path,
|
|
361
|
-
headers=self._request_manager.json_headers(),
|
|
362
|
-
)
|
|
363
|
-
parsed = None
|
|
364
|
-
if response.status == 200:
|
|
365
|
-
parsed = models.parse_brakes_state(json.loads(response.data))
|
|
366
|
-
|
|
367
|
-
is_user_error = response.status >= 400 and response.status < 500
|
|
368
|
-
is_unavailable = response.status == 503
|
|
369
|
-
if parsed is None and (is_user_error or is_unavailable):
|
|
370
|
-
parsed = models.parse_error_response(json.loads(response.data))
|
|
371
|
-
|
|
372
|
-
return Response(
|
|
373
|
-
parsed,
|
|
374
|
-
response.status,
|
|
375
|
-
response
|
|
376
|
-
)
|
|
377
|
-
|
|
378
|
-
def engage_emergency_stop(
|
|
379
|
-
self,
|
|
380
|
-
body: models.EngageEmergencyStopRequest,
|
|
381
|
-
) -> Response[
|
|
382
|
-
None,
|
|
383
|
-
None
|
|
384
|
-
]:
|
|
385
|
-
"""
|
|
386
|
-
Engage Emergency braking system.
|
|
387
|
-
> **⚠️ Warning:** This will immediately stop the robot and may cause damage to the robot or surrounding environment.
|
|
871
|
+
self._request_manager = request_manager
|
|
872
|
+
self.data = Camera.Data(request_manager)
|
|
873
|
+
self.settings = Camera.Settings(request_manager)
|
|
874
|
+
|
|
875
|
+
class Faults:
|
|
876
|
+
_request_manager: RequestManager
|
|
877
|
+
class UserFaults:
|
|
878
|
+
def __init__(self, request_manager: RequestManager):
|
|
879
|
+
self._request_manager = request_manager
|
|
880
|
+
|
|
881
|
+
|
|
882
|
+
def trigger_user_fault(
|
|
883
|
+
self,
|
|
884
|
+
body: models.TriggerFaultRequest,
|
|
885
|
+
) -> Response[
|
|
886
|
+
Union[
|
|
887
|
+
models.ErrorResponse,
|
|
888
|
+
models.ErrorResponse,
|
|
889
|
+
None
|
|
890
|
+
],
|
|
891
|
+
None
|
|
892
|
+
]:
|
|
893
|
+
"""
|
|
894
|
+
Trigger user faults for routine
|
|
895
|
+
|
|
896
|
+
"""
|
|
897
|
+
path = "/api/v1/faults/user-fault"
|
|
898
|
+
try:
|
|
899
|
+
response = self._request_manager.request(
|
|
900
|
+
"POST",
|
|
901
|
+
path,
|
|
902
|
+
headers=self._request_manager.json_headers(),
|
|
903
|
+
body=json.dumps(models.serialize_trigger_fault_request(body)),
|
|
904
|
+
)
|
|
905
|
+
parsed = None
|
|
906
|
+
if response.status == 400:
|
|
907
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
908
|
+
|
|
909
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
910
|
+
is_unavailable = response.status == 503
|
|
911
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
912
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
913
|
+
|
|
914
|
+
return Response(
|
|
915
|
+
parsed,
|
|
916
|
+
response.status,
|
|
917
|
+
response
|
|
918
|
+
)
|
|
919
|
+
except urllib3.exceptions.MaxRetryError:
|
|
920
|
+
return Response(
|
|
921
|
+
models.ErrorResponse(
|
|
922
|
+
error=models.ErrorEnum.InternalServerError,
|
|
923
|
+
message="Connection Refused"
|
|
924
|
+
),
|
|
925
|
+
503,
|
|
926
|
+
None
|
|
927
|
+
)
|
|
928
|
+
|
|
929
|
+
user_faults: UserFaults
|
|
388
930
|
|
|
389
|
-
"""
|
|
390
|
-
path = "/api/v1/movement/brakes/emergency-stop"
|
|
391
|
-
response = self._request_manager.request(
|
|
392
|
-
"POST",
|
|
393
|
-
path,
|
|
394
|
-
headers=self._request_manager.json_headers(),
|
|
395
|
-
body=json.dumps(models.serialize_engage_emergency_stop_request(body)),
|
|
396
|
-
)
|
|
397
|
-
parsed = None
|
|
398
|
-
|
|
399
|
-
is_user_error = response.status >= 400 and response.status < 500
|
|
400
|
-
is_unavailable = response.status == 503
|
|
401
|
-
if parsed is None and (is_user_error or is_unavailable):
|
|
402
|
-
parsed = models.parse_error_response(json.loads(response.data))
|
|
403
|
-
|
|
404
|
-
return Response(
|
|
405
|
-
parsed,
|
|
406
|
-
response.status,
|
|
407
|
-
response
|
|
408
|
-
)
|
|
409
|
-
|
|
410
|
-
class Position:
|
|
411
931
|
def __init__(self, request_manager: RequestManager):
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
response.status,
|
|
517
|
-
response
|
|
518
|
-
)
|
|
519
|
-
|
|
520
|
-
brakes: Brakes
|
|
521
|
-
position: Position
|
|
522
|
-
|
|
523
|
-
def __init__(self, request_manager: RequestManager):
|
|
524
|
-
self._request_manager = request_manager
|
|
525
|
-
self.brakes = Movement.Brakes(request_manager)
|
|
526
|
-
self.position = Movement.Position(request_manager)
|
|
932
|
+
self._request_manager = request_manager
|
|
933
|
+
self.user_faults = Faults.UserFaults(request_manager)
|
|
934
|
+
|
|
935
|
+
class General:
|
|
936
|
+
_request_manager: RequestManager
|
|
937
|
+
class BotIdentity:
|
|
938
|
+
def __init__(self, request_manager: RequestManager):
|
|
939
|
+
self._request_manager = request_manager
|
|
940
|
+
|
|
941
|
+
|
|
942
|
+
def bot_identity(
|
|
943
|
+
self,
|
|
944
|
+
) -> Response[
|
|
945
|
+
Union[
|
|
946
|
+
models.BotIdentityData,
|
|
947
|
+
models.ErrorResponse,
|
|
948
|
+
None
|
|
949
|
+
],
|
|
950
|
+
models.BotIdentityData
|
|
951
|
+
]:
|
|
952
|
+
"""
|
|
953
|
+
Get information about the robot's identity.
|
|
954
|
+
"""
|
|
955
|
+
path = "/api/v1/identity/bot_identity"
|
|
956
|
+
try:
|
|
957
|
+
response = self._request_manager.request(
|
|
958
|
+
"GET",
|
|
959
|
+
path,
|
|
960
|
+
headers=self._request_manager.json_headers(),
|
|
961
|
+
)
|
|
962
|
+
parsed = None
|
|
963
|
+
if response.status == 200:
|
|
964
|
+
parsed = models.parse_bot_identity_data(json.loads(response.data))
|
|
965
|
+
|
|
966
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
967
|
+
is_unavailable = response.status == 503
|
|
968
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
969
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
970
|
+
|
|
971
|
+
return Response(
|
|
972
|
+
parsed,
|
|
973
|
+
response.status,
|
|
974
|
+
response
|
|
975
|
+
)
|
|
976
|
+
except urllib3.exceptions.MaxRetryError:
|
|
977
|
+
return Response(
|
|
978
|
+
models.ErrorResponse(
|
|
979
|
+
error=models.ErrorEnum.InternalServerError,
|
|
980
|
+
message="Connection Refused"
|
|
981
|
+
),
|
|
982
|
+
503,
|
|
983
|
+
None
|
|
984
|
+
)
|
|
985
|
+
class Joints:
|
|
986
|
+
def __init__(self, request_manager: RequestManager):
|
|
987
|
+
self._request_manager = request_manager
|
|
988
|
+
|
|
989
|
+
|
|
990
|
+
def get_joints_state(
|
|
991
|
+
self,
|
|
992
|
+
) -> Response[
|
|
993
|
+
Union[
|
|
994
|
+
models.JointsStateResponse,
|
|
995
|
+
models.ErrorResponse,
|
|
996
|
+
None
|
|
997
|
+
],
|
|
998
|
+
models.JointsStateResponse
|
|
999
|
+
]:
|
|
1000
|
+
"""
|
|
1001
|
+
Retrieves information about the state of each joint
|
|
1002
|
+
"""
|
|
1003
|
+
path = "/api/v1/joints"
|
|
1004
|
+
try:
|
|
1005
|
+
response = self._request_manager.request(
|
|
1006
|
+
"GET",
|
|
1007
|
+
path,
|
|
1008
|
+
headers=self._request_manager.json_headers(),
|
|
1009
|
+
)
|
|
1010
|
+
parsed = None
|
|
1011
|
+
if response.status == 200:
|
|
1012
|
+
parsed = models.parse_joints_state_response(json.loads(response.data))
|
|
1013
|
+
|
|
1014
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
1015
|
+
is_unavailable = response.status == 503
|
|
1016
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
1017
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1018
|
+
|
|
1019
|
+
return Response(
|
|
1020
|
+
parsed,
|
|
1021
|
+
response.status,
|
|
1022
|
+
response
|
|
1023
|
+
)
|
|
1024
|
+
except urllib3.exceptions.MaxRetryError:
|
|
1025
|
+
return Response(
|
|
1026
|
+
models.ErrorResponse(
|
|
1027
|
+
error=models.ErrorEnum.InternalServerError,
|
|
1028
|
+
message="Connection Refused"
|
|
1029
|
+
),
|
|
1030
|
+
503,
|
|
1031
|
+
None
|
|
1032
|
+
)
|
|
1033
|
+
|
|
1034
|
+
bot_identity: BotIdentity
|
|
1035
|
+
joints: Joints
|
|
527
1036
|
|
|
528
|
-
class RoutineEditor:
|
|
529
|
-
_request_manager: RequestManager
|
|
530
|
-
class Routines:
|
|
531
1037
|
def __init__(self, request_manager: RequestManager):
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
def list(
|
|
626
|
-
self,
|
|
627
|
-
limit: int,
|
|
628
|
-
offset: int,
|
|
629
|
-
) -> Response[
|
|
630
|
-
Union[
|
|
631
|
-
models.RoutinesPaginatedResponse,
|
|
632
|
-
models.ErrorResponse,
|
|
633
|
-
None
|
|
634
|
-
],
|
|
635
|
-
models.RoutinesPaginatedResponse
|
|
636
|
-
]:
|
|
637
|
-
"""
|
|
638
|
-
List routines defined in Routine Editor UI
|
|
639
|
-
"""
|
|
640
|
-
path = "/api/v1/routine-editor/routines"
|
|
641
|
-
response = self._request_manager.request(
|
|
642
|
-
"GET",
|
|
643
|
-
path,
|
|
644
|
-
headers=self._request_manager.json_headers(),
|
|
645
|
-
fields={
|
|
646
|
-
"limit": models.serialize_i_64(limit),
|
|
647
|
-
"offset": models.serialize_i_64(offset),
|
|
648
|
-
}
|
|
649
|
-
)
|
|
650
|
-
parsed = None
|
|
651
|
-
if response.status == 200:
|
|
652
|
-
parsed = models.parse_routines_paginated_response(json.loads(response.data))
|
|
653
|
-
|
|
654
|
-
is_user_error = response.status >= 400 and response.status < 500
|
|
655
|
-
is_unavailable = response.status == 503
|
|
656
|
-
if parsed is None and (is_user_error or is_unavailable):
|
|
657
|
-
parsed = models.parse_error_response(json.loads(response.data))
|
|
658
|
-
|
|
659
|
-
return Response(
|
|
660
|
-
parsed,
|
|
661
|
-
response.status,
|
|
662
|
-
response
|
|
663
|
-
)
|
|
664
|
-
|
|
665
|
-
def load(
|
|
666
|
-
self,
|
|
667
|
-
routine_id: str,
|
|
668
|
-
) -> Response[
|
|
669
|
-
Union[
|
|
670
|
-
models.Routine,
|
|
671
|
-
models.ErrorResponse,
|
|
672
|
-
None
|
|
673
|
-
],
|
|
674
|
-
models.Routine
|
|
675
|
-
]:
|
|
676
|
-
"""
|
|
677
|
-
Get routine data by ID
|
|
678
|
-
"""
|
|
679
|
-
path = "/api/v1/routine-editor/routines/{routine_id}"
|
|
680
|
-
path = path.replace("{routine_id}", str(routine_id))
|
|
681
|
-
response = self._request_manager.request(
|
|
682
|
-
"GET",
|
|
683
|
-
path,
|
|
684
|
-
headers=self._request_manager.json_headers(),
|
|
685
|
-
)
|
|
686
|
-
parsed = None
|
|
687
|
-
if response.status == 200:
|
|
688
|
-
parsed = models.parse_routine(json.loads(response.data))
|
|
689
|
-
|
|
690
|
-
is_user_error = response.status >= 400 and response.status < 500
|
|
691
|
-
is_unavailable = response.status == 503
|
|
692
|
-
if parsed is None and (is_user_error or is_unavailable):
|
|
693
|
-
parsed = models.parse_error_response(json.loads(response.data))
|
|
694
|
-
|
|
695
|
-
return Response(
|
|
696
|
-
parsed,
|
|
697
|
-
response.status,
|
|
698
|
-
response
|
|
699
|
-
)
|
|
700
|
-
|
|
701
|
-
class Variables:
|
|
1038
|
+
self._request_manager = request_manager
|
|
1039
|
+
self.bot_identity = General.BotIdentity(request_manager)
|
|
1040
|
+
self.joints = General.Joints(request_manager)
|
|
1041
|
+
|
|
1042
|
+
class ChatGPT:
|
|
1043
|
+
_request_manager: RequestManager
|
|
1044
|
+
class Data:
|
|
1045
|
+
def __init__(self, request_manager: RequestManager):
|
|
1046
|
+
self._request_manager = request_manager
|
|
1047
|
+
|
|
1048
|
+
|
|
1049
|
+
def speech_to_text(
|
|
1050
|
+
self,
|
|
1051
|
+
body: models.SpeechToTextRequest,
|
|
1052
|
+
) -> Response[
|
|
1053
|
+
None,
|
|
1054
|
+
None
|
|
1055
|
+
]:
|
|
1056
|
+
"""
|
|
1057
|
+
Convert speech to text.
|
|
1058
|
+
"""
|
|
1059
|
+
path = "/api/v1/internal-only/speech-to-text"
|
|
1060
|
+
try:
|
|
1061
|
+
response = self._request_manager.request(
|
|
1062
|
+
"POST",
|
|
1063
|
+
path,
|
|
1064
|
+
headers=self._request_manager.json_headers(),
|
|
1065
|
+
body=json.dumps(models.serialize_speech_to_text_request(body)),
|
|
1066
|
+
)
|
|
1067
|
+
parsed = None
|
|
1068
|
+
|
|
1069
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
1070
|
+
is_unavailable = response.status == 503
|
|
1071
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
1072
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1073
|
+
|
|
1074
|
+
return Response(
|
|
1075
|
+
parsed,
|
|
1076
|
+
response.status,
|
|
1077
|
+
response
|
|
1078
|
+
)
|
|
1079
|
+
except urllib3.exceptions.MaxRetryError:
|
|
1080
|
+
return Response(
|
|
1081
|
+
models.ErrorResponse(
|
|
1082
|
+
error=models.ErrorEnum.InternalServerError,
|
|
1083
|
+
message="Connection Refused"
|
|
1084
|
+
),
|
|
1085
|
+
503,
|
|
1086
|
+
None
|
|
1087
|
+
)
|
|
1088
|
+
def text_to_skill(
|
|
1089
|
+
self,
|
|
1090
|
+
body: models.TextToSkillRequest,
|
|
1091
|
+
) -> Response[
|
|
1092
|
+
None,
|
|
1093
|
+
None
|
|
1094
|
+
]:
|
|
1095
|
+
"""
|
|
1096
|
+
Convert text to a skill.
|
|
1097
|
+
"""
|
|
1098
|
+
path = "/api/v1/internal-only/text-to-skill"
|
|
1099
|
+
try:
|
|
1100
|
+
response = self._request_manager.request(
|
|
1101
|
+
"POST",
|
|
1102
|
+
path,
|
|
1103
|
+
headers=self._request_manager.json_headers(),
|
|
1104
|
+
body=json.dumps(models.serialize_text_to_skill_request(body)),
|
|
1105
|
+
)
|
|
1106
|
+
parsed = None
|
|
1107
|
+
|
|
1108
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
1109
|
+
is_unavailable = response.status == 503
|
|
1110
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
1111
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1112
|
+
|
|
1113
|
+
return Response(
|
|
1114
|
+
parsed,
|
|
1115
|
+
response.status,
|
|
1116
|
+
response
|
|
1117
|
+
)
|
|
1118
|
+
except urllib3.exceptions.MaxRetryError:
|
|
1119
|
+
return Response(
|
|
1120
|
+
models.ErrorResponse(
|
|
1121
|
+
error=models.ErrorEnum.InternalServerError,
|
|
1122
|
+
message="Connection Refused"
|
|
1123
|
+
),
|
|
1124
|
+
503,
|
|
1125
|
+
None
|
|
1126
|
+
)
|
|
1127
|
+
|
|
1128
|
+
data: Data
|
|
1129
|
+
|
|
702
1130
|
def __init__(self, request_manager: RequestManager):
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
1131
|
+
self._request_manager = request_manager
|
|
1132
|
+
self.data = ChatGPT.Data(request_manager)
|
|
1133
|
+
|
|
1134
|
+
class IO:
|
|
1135
|
+
_request_manager: RequestManager
|
|
1136
|
+
class Control:
|
|
1137
|
+
def __init__(self, request_manager: RequestManager):
|
|
1138
|
+
self._request_manager = request_manager
|
|
1139
|
+
|
|
1140
|
+
|
|
1141
|
+
def update_io_state(
|
|
1142
|
+
self,
|
|
1143
|
+
body: models.IOStateUpdateRequest,
|
|
1144
|
+
) -> Response[
|
|
1145
|
+
Union[
|
|
1146
|
+
models.IOStateResponse,
|
|
1147
|
+
models.ErrorResponse,
|
|
1148
|
+
models.ErrorResponse,
|
|
1149
|
+
None
|
|
1150
|
+
],
|
|
1151
|
+
models.IOStateResponse
|
|
1152
|
+
]:
|
|
1153
|
+
"""
|
|
1154
|
+
Updates the state of I/O based on the provided action ('high' or 'low').
|
|
1155
|
+
"""
|
|
1156
|
+
path = "/api/v1/io"
|
|
1157
|
+
try:
|
|
1158
|
+
response = self._request_manager.request(
|
|
1159
|
+
"POST",
|
|
1160
|
+
path,
|
|
1161
|
+
headers=self._request_manager.json_headers(),
|
|
1162
|
+
body=json.dumps(models.serialize_io_state_update_request(body)),
|
|
1163
|
+
)
|
|
1164
|
+
parsed = None
|
|
1165
|
+
if response.status == 200:
|
|
1166
|
+
parsed = models.parse_io_state_response(json.loads(response.data))
|
|
1167
|
+
if response.status == 400:
|
|
1168
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1169
|
+
|
|
1170
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
1171
|
+
is_unavailable = response.status == 503
|
|
1172
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
1173
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1174
|
+
|
|
1175
|
+
return Response(
|
|
1176
|
+
parsed,
|
|
1177
|
+
response.status,
|
|
1178
|
+
response
|
|
1179
|
+
)
|
|
1180
|
+
except urllib3.exceptions.MaxRetryError:
|
|
1181
|
+
return Response(
|
|
1182
|
+
models.ErrorResponse(
|
|
1183
|
+
error=models.ErrorEnum.InternalServerError,
|
|
1184
|
+
message="Connection Refused"
|
|
1185
|
+
),
|
|
1186
|
+
503,
|
|
1187
|
+
None
|
|
1188
|
+
)
|
|
1189
|
+
class Status:
|
|
1190
|
+
def __init__(self, request_manager: RequestManager):
|
|
1191
|
+
self._request_manager = request_manager
|
|
1192
|
+
|
|
1193
|
+
|
|
1194
|
+
def get_io_state(
|
|
1195
|
+
self,
|
|
1196
|
+
) -> Response[
|
|
1197
|
+
Union[
|
|
1198
|
+
models.IOStateResponse,
|
|
1199
|
+
models.ErrorResponse,
|
|
1200
|
+
None
|
|
1201
|
+
],
|
|
1202
|
+
models.IOStateResponse
|
|
1203
|
+
]:
|
|
1204
|
+
"""
|
|
1205
|
+
Retrieves the current state of I/O.
|
|
1206
|
+
"""
|
|
1207
|
+
path = "/api/v1/io"
|
|
1208
|
+
try:
|
|
1209
|
+
response = self._request_manager.request(
|
|
1210
|
+
"GET",
|
|
1211
|
+
path,
|
|
1212
|
+
headers=self._request_manager.json_headers(),
|
|
1213
|
+
)
|
|
1214
|
+
parsed = None
|
|
1215
|
+
if response.status == 200:
|
|
1216
|
+
parsed = models.parse_io_state_response(json.loads(response.data))
|
|
1217
|
+
|
|
1218
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
1219
|
+
is_unavailable = response.status == 503
|
|
1220
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
1221
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1222
|
+
|
|
1223
|
+
return Response(
|
|
1224
|
+
parsed,
|
|
1225
|
+
response.status,
|
|
1226
|
+
response
|
|
1227
|
+
)
|
|
1228
|
+
except urllib3.exceptions.MaxRetryError:
|
|
1229
|
+
return Response(
|
|
1230
|
+
models.ErrorResponse(
|
|
1231
|
+
error=models.ErrorEnum.InternalServerError,
|
|
1232
|
+
message="Connection Refused"
|
|
1233
|
+
),
|
|
1234
|
+
503,
|
|
1235
|
+
None
|
|
1236
|
+
)
|
|
1237
|
+
|
|
1238
|
+
control: Control
|
|
1239
|
+
status: Status
|
|
1240
|
+
|
|
1241
|
+
def __init__(self, request_manager: RequestManager):
|
|
1242
|
+
self._request_manager = request_manager
|
|
1243
|
+
self.control = IO.Control(request_manager)
|
|
1244
|
+
self.status = IO.Status(request_manager)
|
|
1245
|
+
|
|
1246
|
+
class Poses:
|
|
1247
|
+
_request_manager: RequestManager
|
|
1248
|
+
class ConstructPose:
|
|
1249
|
+
def __init__(self, request_manager: RequestManager):
|
|
1250
|
+
self._request_manager = request_manager
|
|
1251
|
+
|
|
1252
|
+
|
|
1253
|
+
def cartesian_pose(
|
|
1254
|
+
self,
|
|
1255
|
+
body: models.CartesianPoseRequest,
|
|
1256
|
+
) -> Response[
|
|
1257
|
+
Union[
|
|
1258
|
+
models.CartesianPoseResponse,
|
|
1259
|
+
models.ErrorResponse,
|
|
1260
|
+
models.ErrorResponse,
|
|
1261
|
+
None
|
|
1262
|
+
],
|
|
1263
|
+
models.CartesianPoseResponse
|
|
1264
|
+
]:
|
|
1265
|
+
"""
|
|
1266
|
+
Retrieve the cartesian pose based on euler angles
|
|
1267
|
+
|
|
1268
|
+
"""
|
|
1269
|
+
path = "/api/v1/poses/cartesian-pose"
|
|
1270
|
+
try:
|
|
1271
|
+
response = self._request_manager.request(
|
|
1272
|
+
"POST",
|
|
1273
|
+
path,
|
|
1274
|
+
headers=self._request_manager.json_headers(),
|
|
1275
|
+
body=json.dumps(models.serialize_cartesian_pose_request(body)),
|
|
1276
|
+
)
|
|
1277
|
+
parsed = None
|
|
1278
|
+
if response.status == 200:
|
|
1279
|
+
parsed = models.parse_cartesian_pose_response(json.loads(response.data))
|
|
1280
|
+
if response.status == 400:
|
|
1281
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1282
|
+
|
|
1283
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
1284
|
+
is_unavailable = response.status == 503
|
|
1285
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
1286
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1287
|
+
|
|
1288
|
+
return Response(
|
|
1289
|
+
parsed,
|
|
1290
|
+
response.status,
|
|
1291
|
+
response
|
|
1292
|
+
)
|
|
1293
|
+
except urllib3.exceptions.MaxRetryError:
|
|
1294
|
+
return Response(
|
|
1295
|
+
models.ErrorResponse(
|
|
1296
|
+
error=models.ErrorEnum.InternalServerError,
|
|
1297
|
+
message="Connection Refused"
|
|
1298
|
+
),
|
|
1299
|
+
503,
|
|
1300
|
+
None
|
|
1301
|
+
)
|
|
1302
|
+
def joint_pose(
|
|
1303
|
+
self,
|
|
1304
|
+
body: models.JointPoseRequest,
|
|
1305
|
+
) -> Response[
|
|
1306
|
+
Union[
|
|
1307
|
+
models.JointPoseResponse,
|
|
1308
|
+
models.ErrorResponse,
|
|
1309
|
+
models.ErrorResponse,
|
|
1310
|
+
None
|
|
1311
|
+
],
|
|
1312
|
+
models.JointPoseResponse
|
|
1313
|
+
]:
|
|
1314
|
+
"""
|
|
1315
|
+
Retrieve the cartesian pose based on joint angles
|
|
1316
|
+
|
|
1317
|
+
"""
|
|
1318
|
+
path = "/api/v1/poses/joint-pose"
|
|
1319
|
+
try:
|
|
1320
|
+
response = self._request_manager.request(
|
|
1321
|
+
"POST",
|
|
1322
|
+
path,
|
|
1323
|
+
headers=self._request_manager.json_headers(),
|
|
1324
|
+
body=json.dumps(models.serialize_joint_pose_request(body)),
|
|
1325
|
+
)
|
|
1326
|
+
parsed = None
|
|
1327
|
+
if response.status == 200:
|
|
1328
|
+
parsed = models.parse_joint_pose_response(json.loads(response.data))
|
|
1329
|
+
if response.status == 400:
|
|
1330
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1331
|
+
|
|
1332
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
1333
|
+
is_unavailable = response.status == 503
|
|
1334
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
1335
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1336
|
+
|
|
1337
|
+
return Response(
|
|
1338
|
+
parsed,
|
|
1339
|
+
response.status,
|
|
1340
|
+
response
|
|
1341
|
+
)
|
|
1342
|
+
except urllib3.exceptions.MaxRetryError:
|
|
1343
|
+
return Response(
|
|
1344
|
+
models.ErrorResponse(
|
|
1345
|
+
error=models.ErrorEnum.InternalServerError,
|
|
1346
|
+
message="Connection Refused"
|
|
1347
|
+
),
|
|
1348
|
+
503,
|
|
1349
|
+
None
|
|
1350
|
+
)
|
|
1351
|
+
class CartesianDistance:
|
|
1352
|
+
def __init__(self, request_manager: RequestManager):
|
|
1353
|
+
self._request_manager = request_manager
|
|
1354
|
+
|
|
1355
|
+
|
|
1356
|
+
def pose_distance(
|
|
1357
|
+
self,
|
|
1358
|
+
body: models.PoseDistanceRequest,
|
|
1359
|
+
) -> Response[
|
|
1360
|
+
Union[
|
|
1361
|
+
models.PoseDistanceResponse,
|
|
1362
|
+
models.ErrorResponse,
|
|
1363
|
+
models.ErrorResponse,
|
|
1364
|
+
None
|
|
1365
|
+
],
|
|
1366
|
+
models.PoseDistanceResponse
|
|
1367
|
+
]:
|
|
1368
|
+
"""
|
|
1369
|
+
Calculate the distance between two cartesian poses
|
|
1370
|
+
|
|
1371
|
+
"""
|
|
1372
|
+
path = "/api/v1/poses/pose-distance"
|
|
1373
|
+
try:
|
|
1374
|
+
response = self._request_manager.request(
|
|
1375
|
+
"POST",
|
|
1376
|
+
path,
|
|
1377
|
+
headers=self._request_manager.json_headers(),
|
|
1378
|
+
body=json.dumps(models.serialize_pose_distance_request(body)),
|
|
1379
|
+
)
|
|
1380
|
+
parsed = None
|
|
1381
|
+
if response.status == 200:
|
|
1382
|
+
parsed = models.parse_pose_distance_response(json.loads(response.data))
|
|
1383
|
+
if response.status == 400:
|
|
1384
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1385
|
+
|
|
1386
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
1387
|
+
is_unavailable = response.status == 503
|
|
1388
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
1389
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1390
|
+
|
|
1391
|
+
return Response(
|
|
1392
|
+
parsed,
|
|
1393
|
+
response.status,
|
|
1394
|
+
response
|
|
1395
|
+
)
|
|
1396
|
+
except urllib3.exceptions.MaxRetryError:
|
|
1397
|
+
return Response(
|
|
1398
|
+
models.ErrorResponse(
|
|
1399
|
+
error=models.ErrorEnum.InternalServerError,
|
|
1400
|
+
message="Connection Refused"
|
|
1401
|
+
),
|
|
1402
|
+
503,
|
|
1403
|
+
None
|
|
1404
|
+
)
|
|
1405
|
+
class PoseOperations:
|
|
1406
|
+
def __init__(self, request_manager: RequestManager):
|
|
1407
|
+
self._request_manager = request_manager
|
|
1408
|
+
|
|
1409
|
+
|
|
1410
|
+
def poses_addition(
|
|
1411
|
+
self,
|
|
1412
|
+
body: models.PoseOperationsRequest,
|
|
1413
|
+
) -> Response[
|
|
1414
|
+
Union[
|
|
1415
|
+
models.PoseOperationsResponse,
|
|
1416
|
+
models.ErrorResponse,
|
|
1417
|
+
models.ErrorResponse,
|
|
1418
|
+
None
|
|
1419
|
+
],
|
|
1420
|
+
models.PoseOperationsResponse
|
|
1421
|
+
]:
|
|
1422
|
+
"""
|
|
1423
|
+
Calculate the addition between two cartesian poses
|
|
1424
|
+
|
|
1425
|
+
"""
|
|
1426
|
+
path = "/api/v1/poses/add"
|
|
1427
|
+
try:
|
|
1428
|
+
response = self._request_manager.request(
|
|
1429
|
+
"POST",
|
|
1430
|
+
path,
|
|
1431
|
+
headers=self._request_manager.json_headers(),
|
|
1432
|
+
body=json.dumps(models.serialize_pose_operations_request(body)),
|
|
1433
|
+
)
|
|
1434
|
+
parsed = None
|
|
1435
|
+
if response.status == 200:
|
|
1436
|
+
parsed = models.parse_pose_operations_response(json.loads(response.data))
|
|
1437
|
+
if response.status == 400:
|
|
1438
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1439
|
+
|
|
1440
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
1441
|
+
is_unavailable = response.status == 503
|
|
1442
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
1443
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1444
|
+
|
|
1445
|
+
return Response(
|
|
1446
|
+
parsed,
|
|
1447
|
+
response.status,
|
|
1448
|
+
response
|
|
1449
|
+
)
|
|
1450
|
+
except urllib3.exceptions.MaxRetryError:
|
|
1451
|
+
return Response(
|
|
1452
|
+
models.ErrorResponse(
|
|
1453
|
+
error=models.ErrorEnum.InternalServerError,
|
|
1454
|
+
message="Connection Refused"
|
|
1455
|
+
),
|
|
1456
|
+
503,
|
|
1457
|
+
None
|
|
1458
|
+
)
|
|
1459
|
+
def poses_subtraction(
|
|
1460
|
+
self,
|
|
1461
|
+
body: models.PoseOperationsRequest,
|
|
1462
|
+
) -> Response[
|
|
1463
|
+
Union[
|
|
1464
|
+
models.PoseOperationsResponse,
|
|
1465
|
+
models.ErrorResponse,
|
|
1466
|
+
models.ErrorResponse,
|
|
1467
|
+
None
|
|
1468
|
+
],
|
|
1469
|
+
models.PoseOperationsResponse
|
|
1470
|
+
]:
|
|
1471
|
+
"""
|
|
1472
|
+
Calculate the subtraction between two cartesian poses
|
|
1473
|
+
|
|
1474
|
+
"""
|
|
1475
|
+
path = "/api/v1/poses/subtract"
|
|
1476
|
+
try:
|
|
1477
|
+
response = self._request_manager.request(
|
|
1478
|
+
"POST",
|
|
1479
|
+
path,
|
|
1480
|
+
headers=self._request_manager.json_headers(),
|
|
1481
|
+
body=json.dumps(models.serialize_pose_operations_request(body)),
|
|
1482
|
+
)
|
|
1483
|
+
parsed = None
|
|
1484
|
+
if response.status == 200:
|
|
1485
|
+
parsed = models.parse_pose_operations_response(json.loads(response.data))
|
|
1486
|
+
if response.status == 400:
|
|
1487
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1488
|
+
|
|
1489
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
1490
|
+
is_unavailable = response.status == 503
|
|
1491
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
1492
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1493
|
+
|
|
1494
|
+
return Response(
|
|
1495
|
+
parsed,
|
|
1496
|
+
response.status,
|
|
1497
|
+
response
|
|
1498
|
+
)
|
|
1499
|
+
except urllib3.exceptions.MaxRetryError:
|
|
1500
|
+
return Response(
|
|
1501
|
+
models.ErrorResponse(
|
|
1502
|
+
error=models.ErrorEnum.InternalServerError,
|
|
1503
|
+
message="Connection Refused"
|
|
1504
|
+
),
|
|
1505
|
+
503,
|
|
1506
|
+
None
|
|
1507
|
+
)
|
|
1508
|
+
def cartesian_offset(
|
|
1509
|
+
self,
|
|
1510
|
+
body: models.CartesianOffsetRequest,
|
|
1511
|
+
) -> Response[
|
|
1512
|
+
Union[
|
|
1513
|
+
models.CartesianOffsetResponse,
|
|
1514
|
+
models.ErrorResponse,
|
|
1515
|
+
models.ErrorResponse,
|
|
1516
|
+
None
|
|
1517
|
+
],
|
|
1518
|
+
models.CartesianOffsetResponse
|
|
1519
|
+
]:
|
|
1520
|
+
"""
|
|
1521
|
+
Determine the robot pose after applying the offset transformation
|
|
1522
|
+
|
|
1523
|
+
"""
|
|
1524
|
+
path = "/api/v1/poses/cartesian-offset"
|
|
1525
|
+
try:
|
|
1526
|
+
response = self._request_manager.request(
|
|
1527
|
+
"POST",
|
|
1528
|
+
path,
|
|
1529
|
+
headers=self._request_manager.json_headers(),
|
|
1530
|
+
body=json.dumps(models.serialize_cartesian_offset_request(body)),
|
|
1531
|
+
)
|
|
1532
|
+
parsed = None
|
|
1533
|
+
if response.status == 200:
|
|
1534
|
+
parsed = models.parse_cartesian_offset_response(json.loads(response.data))
|
|
1535
|
+
if response.status == 400:
|
|
1536
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1537
|
+
|
|
1538
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
1539
|
+
is_unavailable = response.status == 503
|
|
1540
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
1541
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1542
|
+
|
|
1543
|
+
return Response(
|
|
1544
|
+
parsed,
|
|
1545
|
+
response.status,
|
|
1546
|
+
response
|
|
1547
|
+
)
|
|
1548
|
+
except urllib3.exceptions.MaxRetryError:
|
|
1549
|
+
return Response(
|
|
1550
|
+
models.ErrorResponse(
|
|
1551
|
+
error=models.ErrorEnum.InternalServerError,
|
|
1552
|
+
message="Connection Refused"
|
|
1553
|
+
),
|
|
1554
|
+
503,
|
|
1555
|
+
None
|
|
1556
|
+
)
|
|
1557
|
+
class PoseRetrieval:
|
|
1558
|
+
def __init__(self, request_manager: RequestManager):
|
|
1559
|
+
self._request_manager = request_manager
|
|
1560
|
+
|
|
1561
|
+
|
|
1562
|
+
def get_joints_position(
|
|
1563
|
+
self,
|
|
1564
|
+
) -> Response[
|
|
1565
|
+
Union[
|
|
1566
|
+
models.JointsPositionResponse,
|
|
1567
|
+
models.ErrorResponse,
|
|
1568
|
+
None
|
|
1569
|
+
],
|
|
1570
|
+
models.JointsPositionResponse
|
|
1571
|
+
]:
|
|
1572
|
+
"""
|
|
1573
|
+
Get the joints position of the robot
|
|
1574
|
+
"""
|
|
1575
|
+
path = "/api/v1/poses/joints-position"
|
|
1576
|
+
try:
|
|
1577
|
+
response = self._request_manager.request(
|
|
1578
|
+
"GET",
|
|
1579
|
+
path,
|
|
1580
|
+
headers=self._request_manager.json_headers(),
|
|
1581
|
+
)
|
|
1582
|
+
parsed = None
|
|
1583
|
+
if response.status == 200:
|
|
1584
|
+
parsed = models.parse_joints_position_response(json.loads(response.data))
|
|
1585
|
+
|
|
1586
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
1587
|
+
is_unavailable = response.status == 503
|
|
1588
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
1589
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1590
|
+
|
|
1591
|
+
return Response(
|
|
1592
|
+
parsed,
|
|
1593
|
+
response.status,
|
|
1594
|
+
response
|
|
1595
|
+
)
|
|
1596
|
+
except urllib3.exceptions.MaxRetryError:
|
|
1597
|
+
return Response(
|
|
1598
|
+
models.ErrorResponse(
|
|
1599
|
+
error=models.ErrorEnum.InternalServerError,
|
|
1600
|
+
message="Connection Refused"
|
|
1601
|
+
),
|
|
1602
|
+
503,
|
|
1603
|
+
None
|
|
1604
|
+
)
|
|
1605
|
+
def get_tooltip_position(
|
|
1606
|
+
self,
|
|
1607
|
+
) -> Response[
|
|
1608
|
+
Union[
|
|
1609
|
+
models.TooltipPositionResponse,
|
|
1610
|
+
models.ErrorResponse,
|
|
1611
|
+
None
|
|
1612
|
+
],
|
|
1613
|
+
models.TooltipPositionResponse
|
|
1614
|
+
]:
|
|
1615
|
+
"""
|
|
1616
|
+
Get the tooltip position of the robot
|
|
1617
|
+
"""
|
|
1618
|
+
path = "/api/v1/poses/tooltip-position"
|
|
1619
|
+
try:
|
|
1620
|
+
response = self._request_manager.request(
|
|
1621
|
+
"GET",
|
|
1622
|
+
path,
|
|
1623
|
+
headers=self._request_manager.json_headers(),
|
|
1624
|
+
)
|
|
1625
|
+
parsed = None
|
|
1626
|
+
if response.status == 200:
|
|
1627
|
+
parsed = models.parse_tooltip_position_response(json.loads(response.data))
|
|
1628
|
+
|
|
1629
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
1630
|
+
is_unavailable = response.status == 503
|
|
1631
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
1632
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1633
|
+
|
|
1634
|
+
return Response(
|
|
1635
|
+
parsed,
|
|
1636
|
+
response.status,
|
|
1637
|
+
response
|
|
1638
|
+
)
|
|
1639
|
+
except urllib3.exceptions.MaxRetryError:
|
|
1640
|
+
return Response(
|
|
1641
|
+
models.ErrorResponse(
|
|
1642
|
+
error=models.ErrorEnum.InternalServerError,
|
|
1643
|
+
message="Connection Refused"
|
|
1644
|
+
),
|
|
1645
|
+
503,
|
|
1646
|
+
None
|
|
1647
|
+
)
|
|
1648
|
+
def get_flange_position(
|
|
1649
|
+
self,
|
|
1650
|
+
) -> Response[
|
|
1651
|
+
Union[
|
|
1652
|
+
models.FlangePositionResponse,
|
|
1653
|
+
models.ErrorResponse,
|
|
1654
|
+
None
|
|
1655
|
+
],
|
|
1656
|
+
models.FlangePositionResponse
|
|
1657
|
+
]:
|
|
1658
|
+
"""
|
|
1659
|
+
Get the flange position of the robot
|
|
1660
|
+
"""
|
|
1661
|
+
path = "/api/v1/poses/flange-position"
|
|
1662
|
+
try:
|
|
1663
|
+
response = self._request_manager.request(
|
|
1664
|
+
"GET",
|
|
1665
|
+
path,
|
|
1666
|
+
headers=self._request_manager.json_headers(),
|
|
1667
|
+
)
|
|
1668
|
+
parsed = None
|
|
1669
|
+
if response.status == 200:
|
|
1670
|
+
parsed = models.parse_flange_position_response(json.loads(response.data))
|
|
1671
|
+
|
|
1672
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
1673
|
+
is_unavailable = response.status == 503
|
|
1674
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
1675
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1676
|
+
|
|
1677
|
+
return Response(
|
|
1678
|
+
parsed,
|
|
1679
|
+
response.status,
|
|
1680
|
+
response
|
|
1681
|
+
)
|
|
1682
|
+
except urllib3.exceptions.MaxRetryError:
|
|
1683
|
+
return Response(
|
|
1684
|
+
models.ErrorResponse(
|
|
1685
|
+
error=models.ErrorEnum.InternalServerError,
|
|
1686
|
+
message="Connection Refused"
|
|
1687
|
+
),
|
|
1688
|
+
503,
|
|
1689
|
+
None
|
|
1690
|
+
)
|
|
1691
|
+
|
|
1692
|
+
construct_pose: ConstructPose
|
|
1693
|
+
cartesian_distance: CartesianDistance
|
|
1694
|
+
pose_operations: PoseOperations
|
|
1695
|
+
pose_retrieval: PoseRetrieval
|
|
787
1696
|
|
|
788
|
-
class Status:
|
|
789
|
-
_request_manager: RequestManager
|
|
790
|
-
class Control:
|
|
791
1697
|
def __init__(self, request_manager: RequestManager):
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
1698
|
+
self._request_manager = request_manager
|
|
1699
|
+
self.construct_pose = Poses.ConstructPose(request_manager)
|
|
1700
|
+
self.cartesian_distance = Poses.CartesianDistance(request_manager)
|
|
1701
|
+
self.pose_operations = Poses.PoseOperations(request_manager)
|
|
1702
|
+
self.pose_retrieval = Poses.PoseRetrieval(request_manager)
|
|
1703
|
+
|
|
1704
|
+
class Recovery:
|
|
1705
|
+
_request_manager: RequestManager
|
|
1706
|
+
class Recover:
|
|
1707
|
+
def __init__(self, request_manager: RequestManager):
|
|
1708
|
+
self._request_manager = request_manager
|
|
1709
|
+
|
|
1710
|
+
|
|
1711
|
+
def recover(
|
|
1712
|
+
self,
|
|
1713
|
+
) -> Response[
|
|
1714
|
+
Union[
|
|
1715
|
+
models.FailureStateResponse,
|
|
1716
|
+
models.ErrorResponse,
|
|
1717
|
+
models.ErrorResponse,
|
|
1718
|
+
None
|
|
1719
|
+
],
|
|
1720
|
+
models.FailureStateResponse
|
|
1721
|
+
]:
|
|
1722
|
+
"""
|
|
1723
|
+
Attempts to recover the robot from a fault state. Inspect the response to determine if additional recovery actions are required.
|
|
1724
|
+
|
|
1725
|
+
"""
|
|
1726
|
+
path = "/api/v1/recovery/recover"
|
|
1727
|
+
try:
|
|
1728
|
+
response = self._request_manager.request(
|
|
1729
|
+
"POST",
|
|
1730
|
+
path,
|
|
1731
|
+
headers=self._request_manager.json_headers(),
|
|
1732
|
+
)
|
|
1733
|
+
parsed = None
|
|
1734
|
+
if response.status == 200:
|
|
1735
|
+
parsed = models.parse_failure_state_response(json.loads(response.data))
|
|
1736
|
+
if response.status == 400:
|
|
1737
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1738
|
+
|
|
1739
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
1740
|
+
is_unavailable = response.status == 503
|
|
1741
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
1742
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1743
|
+
|
|
1744
|
+
return Response(
|
|
1745
|
+
parsed,
|
|
1746
|
+
response.status,
|
|
1747
|
+
response
|
|
1748
|
+
)
|
|
1749
|
+
except urllib3.exceptions.MaxRetryError:
|
|
1750
|
+
return Response(
|
|
1751
|
+
models.ErrorResponse(
|
|
1752
|
+
error=models.ErrorEnum.InternalServerError,
|
|
1753
|
+
message="Connection Refused"
|
|
1754
|
+
),
|
|
1755
|
+
503,
|
|
1756
|
+
None
|
|
1757
|
+
)
|
|
1758
|
+
def get_status(
|
|
1759
|
+
self,
|
|
1760
|
+
) -> Response[
|
|
1761
|
+
Union[
|
|
1762
|
+
models.FailureStateResponse,
|
|
1763
|
+
models.ErrorResponse,
|
|
1764
|
+
None
|
|
1765
|
+
],
|
|
1766
|
+
models.FailureStateResponse
|
|
1767
|
+
]:
|
|
1768
|
+
"""
|
|
1769
|
+
Get the robot's recovery status.
|
|
1770
|
+
|
|
1771
|
+
"""
|
|
1772
|
+
path = "/api/v1/recovery/status"
|
|
1773
|
+
try:
|
|
1774
|
+
response = self._request_manager.request(
|
|
1775
|
+
"GET",
|
|
1776
|
+
path,
|
|
1777
|
+
headers=self._request_manager.json_headers(),
|
|
1778
|
+
)
|
|
1779
|
+
parsed = None
|
|
1780
|
+
if response.status == 200:
|
|
1781
|
+
parsed = models.parse_failure_state_response(json.loads(response.data))
|
|
1782
|
+
|
|
1783
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
1784
|
+
is_unavailable = response.status == 503
|
|
1785
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
1786
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1787
|
+
|
|
1788
|
+
return Response(
|
|
1789
|
+
parsed,
|
|
1790
|
+
response.status,
|
|
1791
|
+
response
|
|
1792
|
+
)
|
|
1793
|
+
except urllib3.exceptions.MaxRetryError:
|
|
1794
|
+
return Response(
|
|
1795
|
+
models.ErrorResponse(
|
|
1796
|
+
error=models.ErrorEnum.InternalServerError,
|
|
1797
|
+
message="Connection Refused"
|
|
1798
|
+
),
|
|
1799
|
+
503,
|
|
1800
|
+
None
|
|
1801
|
+
)
|
|
1802
|
+
|
|
1803
|
+
recover: Recover
|
|
1804
|
+
|
|
866
1805
|
def __init__(self, request_manager: RequestManager):
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
1806
|
+
self._request_manager = request_manager
|
|
1807
|
+
self.recover = Recovery.Recover(request_manager)
|
|
1808
|
+
|
|
1809
|
+
class ROS:
|
|
1810
|
+
_request_manager: RequestManager
|
|
1811
|
+
class Control:
|
|
1812
|
+
def __init__(self, request_manager: RequestManager):
|
|
1813
|
+
self._request_manager = request_manager
|
|
1814
|
+
|
|
1815
|
+
|
|
1816
|
+
def update_ros_control_state(
|
|
1817
|
+
self,
|
|
1818
|
+
body: models.ROSControlUpdateRequest,
|
|
1819
|
+
) -> Response[
|
|
1820
|
+
Union[
|
|
1821
|
+
models.ROSControlStateResponse,
|
|
1822
|
+
models.ErrorResponse,
|
|
1823
|
+
None
|
|
1824
|
+
],
|
|
1825
|
+
models.ROSControlStateResponse
|
|
1826
|
+
]:
|
|
1827
|
+
"""
|
|
1828
|
+
Updates the state of ROS control based on the provided action ('enable' or 'disable').
|
|
1829
|
+
"""
|
|
1830
|
+
path = "/api/v1/movement/ros/state"
|
|
1831
|
+
try:
|
|
1832
|
+
response = self._request_manager.request(
|
|
1833
|
+
"POST",
|
|
1834
|
+
path,
|
|
1835
|
+
headers=self._request_manager.json_headers(),
|
|
1836
|
+
body=json.dumps(models.serialize_ros_control_update_request(body)),
|
|
1837
|
+
)
|
|
1838
|
+
parsed = None
|
|
1839
|
+
if response.status == 200:
|
|
1840
|
+
parsed = models.parse_ros_control_state_response(json.loads(response.data))
|
|
1841
|
+
|
|
1842
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
1843
|
+
is_unavailable = response.status == 503
|
|
1844
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
1845
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1846
|
+
|
|
1847
|
+
return Response(
|
|
1848
|
+
parsed,
|
|
1849
|
+
response.status,
|
|
1850
|
+
response
|
|
1851
|
+
)
|
|
1852
|
+
except urllib3.exceptions.MaxRetryError:
|
|
1853
|
+
return Response(
|
|
1854
|
+
models.ErrorResponse(
|
|
1855
|
+
error=models.ErrorEnum.InternalServerError,
|
|
1856
|
+
message="Connection Refused"
|
|
1857
|
+
),
|
|
1858
|
+
503,
|
|
1859
|
+
None
|
|
1860
|
+
)
|
|
1861
|
+
class Status:
|
|
1862
|
+
def __init__(self, request_manager: RequestManager):
|
|
1863
|
+
self._request_manager = request_manager
|
|
1864
|
+
|
|
1865
|
+
|
|
1866
|
+
def get_ros_control_state(
|
|
1867
|
+
self,
|
|
1868
|
+
) -> Response[
|
|
1869
|
+
Union[
|
|
1870
|
+
models.ROSControlStateResponse,
|
|
1871
|
+
models.ErrorResponse,
|
|
1872
|
+
None
|
|
1873
|
+
],
|
|
1874
|
+
models.ROSControlStateResponse
|
|
1875
|
+
]:
|
|
1876
|
+
"""
|
|
1877
|
+
Retrieves the current state of ROS control.
|
|
1878
|
+
"""
|
|
1879
|
+
path = "/api/v1/movement/ros/state"
|
|
1880
|
+
try:
|
|
1881
|
+
response = self._request_manager.request(
|
|
1882
|
+
"GET",
|
|
1883
|
+
path,
|
|
1884
|
+
headers=self._request_manager.json_headers(),
|
|
1885
|
+
)
|
|
1886
|
+
parsed = None
|
|
1887
|
+
if response.status == 200:
|
|
1888
|
+
parsed = models.parse_ros_control_state_response(json.loads(response.data))
|
|
1889
|
+
|
|
1890
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
1891
|
+
is_unavailable = response.status == 503
|
|
1892
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
1893
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1894
|
+
|
|
1895
|
+
return Response(
|
|
1896
|
+
parsed,
|
|
1897
|
+
response.status,
|
|
1898
|
+
response
|
|
1899
|
+
)
|
|
1900
|
+
except urllib3.exceptions.MaxRetryError:
|
|
1901
|
+
return Response(
|
|
1902
|
+
models.ErrorResponse(
|
|
1903
|
+
error=models.ErrorEnum.InternalServerError,
|
|
1904
|
+
message="Connection Refused"
|
|
1905
|
+
),
|
|
1906
|
+
503,
|
|
1907
|
+
None
|
|
1908
|
+
)
|
|
1909
|
+
|
|
1910
|
+
control: Control
|
|
1911
|
+
status: Status
|
|
911
1912
|
|
|
1913
|
+
def __init__(self, request_manager: RequestManager):
|
|
1914
|
+
self._request_manager = request_manager
|
|
1915
|
+
self.control = ROS.Control(request_manager)
|
|
1916
|
+
self.status = ROS.Status(request_manager)
|
|
912
1917
|
|
|
1918
|
+
class RoutineEditor:
|
|
1919
|
+
_request_manager: RequestManager
|
|
1920
|
+
class Routines:
|
|
1921
|
+
def __init__(self, request_manager: RequestManager):
|
|
1922
|
+
self._request_manager = request_manager
|
|
1923
|
+
|
|
1924
|
+
|
|
1925
|
+
def play(
|
|
1926
|
+
self,
|
|
1927
|
+
body: models.PlayRoutineRequest,
|
|
1928
|
+
routine_id: str,
|
|
1929
|
+
) -> Response[
|
|
1930
|
+
None,
|
|
1931
|
+
None
|
|
1932
|
+
]:
|
|
1933
|
+
"""
|
|
1934
|
+
Play a routine
|
|
1935
|
+
"""
|
|
1936
|
+
path = "/api/v1/routine-editor/routines/{routine_id}/play"
|
|
1937
|
+
path = path.replace("{routine_id}", str(routine_id))
|
|
1938
|
+
try:
|
|
1939
|
+
response = self._request_manager.request(
|
|
1940
|
+
"POST",
|
|
1941
|
+
path,
|
|
1942
|
+
headers=self._request_manager.json_headers(),
|
|
1943
|
+
body=json.dumps(models.serialize_play_routine_request(body)),
|
|
1944
|
+
)
|
|
1945
|
+
parsed = None
|
|
1946
|
+
|
|
1947
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
1948
|
+
is_unavailable = response.status == 503
|
|
1949
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
1950
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1951
|
+
|
|
1952
|
+
return Response(
|
|
1953
|
+
parsed,
|
|
1954
|
+
response.status,
|
|
1955
|
+
response
|
|
1956
|
+
)
|
|
1957
|
+
except urllib3.exceptions.MaxRetryError:
|
|
1958
|
+
return Response(
|
|
1959
|
+
models.ErrorResponse(
|
|
1960
|
+
error=models.ErrorEnum.InternalServerError,
|
|
1961
|
+
message="Connection Refused"
|
|
1962
|
+
),
|
|
1963
|
+
503,
|
|
1964
|
+
None
|
|
1965
|
+
)
|
|
1966
|
+
def pause(
|
|
1967
|
+
self,
|
|
1968
|
+
routine_id: str,
|
|
1969
|
+
) -> Response[
|
|
1970
|
+
None,
|
|
1971
|
+
None
|
|
1972
|
+
]:
|
|
1973
|
+
"""
|
|
1974
|
+
Pause a routine
|
|
1975
|
+
"""
|
|
1976
|
+
path = "/api/v1/routine-editor/routines/{routine_id}/pause"
|
|
1977
|
+
path = path.replace("{routine_id}", str(routine_id))
|
|
1978
|
+
try:
|
|
1979
|
+
response = self._request_manager.request(
|
|
1980
|
+
"POST",
|
|
1981
|
+
path,
|
|
1982
|
+
headers=self._request_manager.json_headers(),
|
|
1983
|
+
)
|
|
1984
|
+
parsed = None
|
|
1985
|
+
|
|
1986
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
1987
|
+
is_unavailable = response.status == 503
|
|
1988
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
1989
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1990
|
+
|
|
1991
|
+
return Response(
|
|
1992
|
+
parsed,
|
|
1993
|
+
response.status,
|
|
1994
|
+
response
|
|
1995
|
+
)
|
|
1996
|
+
except urllib3.exceptions.MaxRetryError:
|
|
1997
|
+
return Response(
|
|
1998
|
+
models.ErrorResponse(
|
|
1999
|
+
error=models.ErrorEnum.InternalServerError,
|
|
2000
|
+
message="Connection Refused"
|
|
2001
|
+
),
|
|
2002
|
+
503,
|
|
2003
|
+
None
|
|
2004
|
+
)
|
|
2005
|
+
def stop(
|
|
2006
|
+
self,
|
|
2007
|
+
) -> Response[
|
|
2008
|
+
None,
|
|
2009
|
+
None
|
|
2010
|
+
]:
|
|
2011
|
+
"""
|
|
2012
|
+
Stop running routine and all ongoing motions
|
|
2013
|
+
"""
|
|
2014
|
+
path = "/api/v1/routine-editor/stop"
|
|
2015
|
+
try:
|
|
2016
|
+
response = self._request_manager.request(
|
|
2017
|
+
"POST",
|
|
2018
|
+
path,
|
|
2019
|
+
headers=self._request_manager.json_headers(),
|
|
2020
|
+
)
|
|
2021
|
+
parsed = None
|
|
2022
|
+
|
|
2023
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
2024
|
+
is_unavailable = response.status == 503
|
|
2025
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
2026
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
2027
|
+
|
|
2028
|
+
return Response(
|
|
2029
|
+
parsed,
|
|
2030
|
+
response.status,
|
|
2031
|
+
response
|
|
2032
|
+
)
|
|
2033
|
+
except urllib3.exceptions.MaxRetryError:
|
|
2034
|
+
return Response(
|
|
2035
|
+
models.ErrorResponse(
|
|
2036
|
+
error=models.ErrorEnum.InternalServerError,
|
|
2037
|
+
message="Connection Refused"
|
|
2038
|
+
),
|
|
2039
|
+
503,
|
|
2040
|
+
None
|
|
2041
|
+
)
|
|
2042
|
+
def list(
|
|
2043
|
+
self,
|
|
2044
|
+
limit: int,
|
|
2045
|
+
offset: int,
|
|
2046
|
+
) -> Response[
|
|
2047
|
+
Union[
|
|
2048
|
+
models.RoutinesPaginatedResponse,
|
|
2049
|
+
models.ErrorResponse,
|
|
2050
|
+
None
|
|
2051
|
+
],
|
|
2052
|
+
models.RoutinesPaginatedResponse
|
|
2053
|
+
]:
|
|
2054
|
+
"""
|
|
2055
|
+
List routines defined in Routine Editor UI
|
|
2056
|
+
"""
|
|
2057
|
+
path = "/api/v1/routine-editor/routines"
|
|
2058
|
+
try:
|
|
2059
|
+
response = self._request_manager.request(
|
|
2060
|
+
"GET",
|
|
2061
|
+
path,
|
|
2062
|
+
headers=self._request_manager.json_headers(),
|
|
2063
|
+
fields={
|
|
2064
|
+
"limit": models.serialize_i_64(limit),
|
|
2065
|
+
"offset": models.serialize_i_64(offset),
|
|
2066
|
+
}
|
|
2067
|
+
)
|
|
2068
|
+
parsed = None
|
|
2069
|
+
if response.status == 200:
|
|
2070
|
+
parsed = models.parse_routines_paginated_response(json.loads(response.data))
|
|
2071
|
+
|
|
2072
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
2073
|
+
is_unavailable = response.status == 503
|
|
2074
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
2075
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
2076
|
+
|
|
2077
|
+
return Response(
|
|
2078
|
+
parsed,
|
|
2079
|
+
response.status,
|
|
2080
|
+
response
|
|
2081
|
+
)
|
|
2082
|
+
except urllib3.exceptions.MaxRetryError:
|
|
2083
|
+
return Response(
|
|
2084
|
+
models.ErrorResponse(
|
|
2085
|
+
error=models.ErrorEnum.InternalServerError,
|
|
2086
|
+
message="Connection Refused"
|
|
2087
|
+
),
|
|
2088
|
+
503,
|
|
2089
|
+
None
|
|
2090
|
+
)
|
|
2091
|
+
def load(
|
|
2092
|
+
self,
|
|
2093
|
+
routine_id: str,
|
|
2094
|
+
) -> Response[
|
|
2095
|
+
Union[
|
|
2096
|
+
models.Routine,
|
|
2097
|
+
models.ErrorResponse,
|
|
2098
|
+
None
|
|
2099
|
+
],
|
|
2100
|
+
models.Routine
|
|
2101
|
+
]:
|
|
2102
|
+
"""
|
|
2103
|
+
Get routine data by ID
|
|
2104
|
+
"""
|
|
2105
|
+
path = "/api/v1/routine-editor/routines/{routine_id}"
|
|
2106
|
+
path = path.replace("{routine_id}", str(routine_id))
|
|
2107
|
+
try:
|
|
2108
|
+
response = self._request_manager.request(
|
|
2109
|
+
"GET",
|
|
2110
|
+
path,
|
|
2111
|
+
headers=self._request_manager.json_headers(),
|
|
2112
|
+
)
|
|
2113
|
+
parsed = None
|
|
2114
|
+
if response.status == 200:
|
|
2115
|
+
parsed = models.parse_routine(json.loads(response.data))
|
|
2116
|
+
|
|
2117
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
2118
|
+
is_unavailable = response.status == 503
|
|
2119
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
2120
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
2121
|
+
|
|
2122
|
+
return Response(
|
|
2123
|
+
parsed,
|
|
2124
|
+
response.status,
|
|
2125
|
+
response
|
|
2126
|
+
)
|
|
2127
|
+
except urllib3.exceptions.MaxRetryError:
|
|
2128
|
+
return Response(
|
|
2129
|
+
models.ErrorResponse(
|
|
2130
|
+
error=models.ErrorEnum.InternalServerError,
|
|
2131
|
+
message="Connection Refused"
|
|
2132
|
+
),
|
|
2133
|
+
503,
|
|
2134
|
+
None
|
|
2135
|
+
)
|
|
2136
|
+
def list_spaces(
|
|
2137
|
+
self,
|
|
2138
|
+
routine_id: str,
|
|
2139
|
+
exclude_global_spaces: bool,
|
|
2140
|
+
) -> Response[
|
|
2141
|
+
Union[
|
|
2142
|
+
models.SpacesPaginatedResponse,
|
|
2143
|
+
models.ErrorResponse,
|
|
2144
|
+
None
|
|
2145
|
+
],
|
|
2146
|
+
models.SpacesPaginatedResponse
|
|
2147
|
+
]:
|
|
2148
|
+
"""
|
|
2149
|
+
List spaces from routine
|
|
2150
|
+
"""
|
|
2151
|
+
path = "/api/v1/routine-editor/routines/{routine_id}/spaces"
|
|
2152
|
+
path = path.replace("{routine_id}", str(routine_id))
|
|
2153
|
+
try:
|
|
2154
|
+
response = self._request_manager.request(
|
|
2155
|
+
"GET",
|
|
2156
|
+
path,
|
|
2157
|
+
headers=self._request_manager.json_headers(),
|
|
2158
|
+
fields={
|
|
2159
|
+
"exclude_global_spaces": models.serialize_bool(exclude_global_spaces),
|
|
2160
|
+
}
|
|
2161
|
+
)
|
|
2162
|
+
parsed = None
|
|
2163
|
+
if response.status == 200:
|
|
2164
|
+
parsed = models.parse_spaces_paginated_response(json.loads(response.data))
|
|
2165
|
+
|
|
2166
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
2167
|
+
is_unavailable = response.status == 503
|
|
2168
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
2169
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
2170
|
+
|
|
2171
|
+
return Response(
|
|
2172
|
+
parsed,
|
|
2173
|
+
response.status,
|
|
2174
|
+
response
|
|
2175
|
+
)
|
|
2176
|
+
except urllib3.exceptions.MaxRetryError:
|
|
2177
|
+
return Response(
|
|
2178
|
+
models.ErrorResponse(
|
|
2179
|
+
error=models.ErrorEnum.InternalServerError,
|
|
2180
|
+
message="Connection Refused"
|
|
2181
|
+
),
|
|
2182
|
+
503,
|
|
2183
|
+
None
|
|
2184
|
+
)
|
|
2185
|
+
def get_step_variables(
|
|
2186
|
+
self,
|
|
2187
|
+
routine_id: str,
|
|
2188
|
+
step_id_map: bool,
|
|
2189
|
+
) -> Response[
|
|
2190
|
+
Union[
|
|
2191
|
+
models.RoutineStepVariablesResponse,
|
|
2192
|
+
models.ErrorResponse,
|
|
2193
|
+
None
|
|
2194
|
+
],
|
|
2195
|
+
models.RoutineStepVariablesResponse
|
|
2196
|
+
]:
|
|
2197
|
+
"""
|
|
2198
|
+
Get all step variables from a running routine.
|
|
2199
|
+
"""
|
|
2200
|
+
path = "/api/v1/routine-editor/routines/{routine_id}/step-variables"
|
|
2201
|
+
path = path.replace("{routine_id}", str(routine_id))
|
|
2202
|
+
try:
|
|
2203
|
+
response = self._request_manager.request(
|
|
2204
|
+
"GET",
|
|
2205
|
+
path,
|
|
2206
|
+
headers=self._request_manager.json_headers(),
|
|
2207
|
+
fields={
|
|
2208
|
+
"step_id_map": models.serialize_bool(step_id_map),
|
|
2209
|
+
}
|
|
2210
|
+
)
|
|
2211
|
+
parsed = None
|
|
2212
|
+
if response.status == 200:
|
|
2213
|
+
parsed = models.parse_routine_step_variables_response(json.loads(response.data))
|
|
2214
|
+
|
|
2215
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
2216
|
+
is_unavailable = response.status == 503
|
|
2217
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
2218
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
2219
|
+
|
|
2220
|
+
return Response(
|
|
2221
|
+
parsed,
|
|
2222
|
+
response.status,
|
|
2223
|
+
response
|
|
2224
|
+
)
|
|
2225
|
+
except urllib3.exceptions.MaxRetryError:
|
|
2226
|
+
return Response(
|
|
2227
|
+
models.ErrorResponse(
|
|
2228
|
+
error=models.ErrorEnum.InternalServerError,
|
|
2229
|
+
message="Connection Refused"
|
|
2230
|
+
),
|
|
2231
|
+
503,
|
|
2232
|
+
None
|
|
2233
|
+
)
|
|
2234
|
+
def get_state(
|
|
2235
|
+
self,
|
|
2236
|
+
routine_id: str,
|
|
2237
|
+
) -> Response[
|
|
2238
|
+
Union[
|
|
2239
|
+
models.RoutineStateResponse,
|
|
2240
|
+
models.ErrorResponse,
|
|
2241
|
+
None
|
|
2242
|
+
],
|
|
2243
|
+
models.RoutineStateResponse
|
|
2244
|
+
]:
|
|
2245
|
+
"""
|
|
2246
|
+
Get the state from a running routine.
|
|
2247
|
+
"""
|
|
2248
|
+
path = "/api/v1/routine-editor/routines/{routine_id}/state"
|
|
2249
|
+
path = path.replace("{routine_id}", str(routine_id))
|
|
2250
|
+
try:
|
|
2251
|
+
response = self._request_manager.request(
|
|
2252
|
+
"GET",
|
|
2253
|
+
path,
|
|
2254
|
+
headers=self._request_manager.json_headers(),
|
|
2255
|
+
)
|
|
2256
|
+
parsed = None
|
|
2257
|
+
if response.status == 200:
|
|
2258
|
+
parsed = models.parse_routine_state_response(json.loads(response.data))
|
|
2259
|
+
|
|
2260
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
2261
|
+
is_unavailable = response.status == 503
|
|
2262
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
2263
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
2264
|
+
|
|
2265
|
+
return Response(
|
|
2266
|
+
parsed,
|
|
2267
|
+
response.status,
|
|
2268
|
+
response
|
|
2269
|
+
)
|
|
2270
|
+
except urllib3.exceptions.MaxRetryError:
|
|
2271
|
+
return Response(
|
|
2272
|
+
models.ErrorResponse(
|
|
2273
|
+
error=models.ErrorEnum.InternalServerError,
|
|
2274
|
+
message="Connection Refused"
|
|
2275
|
+
),
|
|
2276
|
+
503,
|
|
2277
|
+
None
|
|
2278
|
+
)
|
|
2279
|
+
class Variables:
|
|
2280
|
+
def __init__(self, request_manager: RequestManager):
|
|
2281
|
+
self._request_manager = request_manager
|
|
2282
|
+
|
|
2283
|
+
|
|
2284
|
+
def load(
|
|
2285
|
+
self,
|
|
2286
|
+
variable_name: str,
|
|
2287
|
+
) -> Response[
|
|
2288
|
+
Union[
|
|
2289
|
+
models.RuntimeVariable,
|
|
2290
|
+
models.ErrorResponse,
|
|
2291
|
+
None
|
|
2292
|
+
],
|
|
2293
|
+
models.RuntimeVariable
|
|
2294
|
+
]:
|
|
2295
|
+
"""
|
|
2296
|
+
Returns current state of a variable
|
|
2297
|
+
"""
|
|
2298
|
+
path = "/api/v1/routine-editor/variables/{variable_name}"
|
|
2299
|
+
path = path.replace("{variable_name}", str(variable_name))
|
|
2300
|
+
try:
|
|
2301
|
+
response = self._request_manager.request(
|
|
2302
|
+
"GET",
|
|
2303
|
+
path,
|
|
2304
|
+
headers=self._request_manager.json_headers(),
|
|
2305
|
+
)
|
|
2306
|
+
parsed = None
|
|
2307
|
+
if response.status == 200:
|
|
2308
|
+
parsed = models.parse_runtime_variable(json.loads(response.data))
|
|
2309
|
+
|
|
2310
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
2311
|
+
is_unavailable = response.status == 503
|
|
2312
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
2313
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
2314
|
+
|
|
2315
|
+
return Response(
|
|
2316
|
+
parsed,
|
|
2317
|
+
response.status,
|
|
2318
|
+
response
|
|
2319
|
+
)
|
|
2320
|
+
except urllib3.exceptions.MaxRetryError:
|
|
2321
|
+
return Response(
|
|
2322
|
+
models.ErrorResponse(
|
|
2323
|
+
error=models.ErrorEnum.InternalServerError,
|
|
2324
|
+
message="Connection Refused"
|
|
2325
|
+
),
|
|
2326
|
+
503,
|
|
2327
|
+
None
|
|
2328
|
+
)
|
|
2329
|
+
def update(
|
|
2330
|
+
self,
|
|
2331
|
+
body: models.RuntimeVariable,
|
|
2332
|
+
variable_name: str,
|
|
2333
|
+
) -> Response[
|
|
2334
|
+
Union[
|
|
2335
|
+
models.RuntimeVariable,
|
|
2336
|
+
models.ErrorResponse,
|
|
2337
|
+
None
|
|
2338
|
+
],
|
|
2339
|
+
models.RuntimeVariable
|
|
2340
|
+
]:
|
|
2341
|
+
"""
|
|
2342
|
+
Update the value of a variable
|
|
2343
|
+
"""
|
|
2344
|
+
path = "/api/v1/routine-editor/variables/{variable_name}"
|
|
2345
|
+
path = path.replace("{variable_name}", str(variable_name))
|
|
2346
|
+
try:
|
|
2347
|
+
response = self._request_manager.request(
|
|
2348
|
+
"POST",
|
|
2349
|
+
path,
|
|
2350
|
+
headers=self._request_manager.json_headers(),
|
|
2351
|
+
body=json.dumps(models.serialize_runtime_variable(body)),
|
|
2352
|
+
)
|
|
2353
|
+
parsed = None
|
|
2354
|
+
if response.status == 200:
|
|
2355
|
+
parsed = models.parse_runtime_variable(json.loads(response.data))
|
|
2356
|
+
|
|
2357
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
2358
|
+
is_unavailable = response.status == 503
|
|
2359
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
2360
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
2361
|
+
|
|
2362
|
+
return Response(
|
|
2363
|
+
parsed,
|
|
2364
|
+
response.status,
|
|
2365
|
+
response
|
|
2366
|
+
)
|
|
2367
|
+
except urllib3.exceptions.MaxRetryError:
|
|
2368
|
+
return Response(
|
|
2369
|
+
models.ErrorResponse(
|
|
2370
|
+
error=models.ErrorEnum.InternalServerError,
|
|
2371
|
+
message="Connection Refused"
|
|
2372
|
+
),
|
|
2373
|
+
503,
|
|
2374
|
+
None
|
|
2375
|
+
)
|
|
2376
|
+
|
|
2377
|
+
routines: Routines
|
|
2378
|
+
variables: Variables
|
|
913
2379
|
|
|
2380
|
+
def __init__(self, request_manager: RequestManager):
|
|
2381
|
+
self._request_manager = request_manager
|
|
2382
|
+
self.routines = RoutineEditor.Routines(request_manager)
|
|
2383
|
+
self.variables = RoutineEditor.Variables(request_manager)
|
|
914
2384
|
|
|
915
|
-
class
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
2385
|
+
class Status:
|
|
2386
|
+
_request_manager: RequestManager
|
|
2387
|
+
class Control:
|
|
2388
|
+
def __init__(self, request_manager: RequestManager):
|
|
2389
|
+
self._request_manager = request_manager
|
|
2390
|
+
|
|
2391
|
+
|
|
2392
|
+
def set_configuration_control_state(
|
|
2393
|
+
self,
|
|
2394
|
+
body: models.RobotControlMode,
|
|
2395
|
+
) -> Response[
|
|
2396
|
+
Union[
|
|
2397
|
+
models.RobotControlMode,
|
|
2398
|
+
models.ErrorResponse,
|
|
2399
|
+
None
|
|
2400
|
+
],
|
|
2401
|
+
models.RobotControlMode
|
|
2402
|
+
]:
|
|
2403
|
+
"""
|
|
2404
|
+
Set the system which is controlling the robot
|
|
2405
|
+
"""
|
|
2406
|
+
path = "/api/v1/status/control-mode"
|
|
2407
|
+
try:
|
|
2408
|
+
response = self._request_manager.request(
|
|
2409
|
+
"POST",
|
|
2410
|
+
path,
|
|
2411
|
+
headers=self._request_manager.json_headers(),
|
|
2412
|
+
body=json.dumps(models.serialize_robot_control_mode(body)),
|
|
2413
|
+
)
|
|
2414
|
+
parsed = None
|
|
2415
|
+
if response.status == 200:
|
|
2416
|
+
parsed = models.parse_robot_control_mode(json.loads(response.data))
|
|
2417
|
+
|
|
2418
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
2419
|
+
is_unavailable = response.status == 503
|
|
2420
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
2421
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
2422
|
+
|
|
2423
|
+
return Response(
|
|
2424
|
+
parsed,
|
|
2425
|
+
response.status,
|
|
2426
|
+
response
|
|
2427
|
+
)
|
|
2428
|
+
except urllib3.exceptions.MaxRetryError:
|
|
2429
|
+
return Response(
|
|
2430
|
+
models.ErrorResponse(
|
|
2431
|
+
error=models.ErrorEnum.InternalServerError,
|
|
2432
|
+
message="Connection Refused"
|
|
2433
|
+
),
|
|
2434
|
+
503,
|
|
2435
|
+
None
|
|
2436
|
+
)
|
|
2437
|
+
def get_configuration_state_control(
|
|
2438
|
+
self,
|
|
2439
|
+
) -> Response[
|
|
2440
|
+
Union[
|
|
2441
|
+
models.RobotControlMode,
|
|
2442
|
+
models.ErrorResponse,
|
|
2443
|
+
None
|
|
2444
|
+
],
|
|
2445
|
+
models.RobotControlMode
|
|
2446
|
+
]:
|
|
2447
|
+
"""
|
|
2448
|
+
Get the system which is controlling the robot
|
|
2449
|
+
"""
|
|
2450
|
+
path = "/api/v1/status/control-mode"
|
|
2451
|
+
try:
|
|
2452
|
+
response = self._request_manager.request(
|
|
2453
|
+
"GET",
|
|
2454
|
+
path,
|
|
2455
|
+
headers=self._request_manager.json_headers(),
|
|
2456
|
+
)
|
|
2457
|
+
parsed = None
|
|
2458
|
+
if response.status == 200:
|
|
2459
|
+
parsed = models.parse_robot_control_mode(json.loads(response.data))
|
|
2460
|
+
|
|
2461
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
2462
|
+
is_unavailable = response.status == 503
|
|
2463
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
2464
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
2465
|
+
|
|
2466
|
+
return Response(
|
|
2467
|
+
parsed,
|
|
2468
|
+
response.status,
|
|
2469
|
+
response
|
|
2470
|
+
)
|
|
2471
|
+
except urllib3.exceptions.MaxRetryError:
|
|
2472
|
+
return Response(
|
|
2473
|
+
models.ErrorResponse(
|
|
2474
|
+
error=models.ErrorEnum.InternalServerError,
|
|
2475
|
+
message="Connection Refused"
|
|
2476
|
+
),
|
|
2477
|
+
503,
|
|
2478
|
+
None
|
|
2479
|
+
)
|
|
2480
|
+
class Health:
|
|
2481
|
+
def __init__(self, request_manager: RequestManager):
|
|
2482
|
+
self._request_manager = request_manager
|
|
2483
|
+
|
|
2484
|
+
|
|
2485
|
+
def get_health(
|
|
2486
|
+
self,
|
|
2487
|
+
) -> Response[
|
|
2488
|
+
Union[
|
|
2489
|
+
models.StatusHealthResponse,
|
|
2490
|
+
models.ErrorResponse,
|
|
2491
|
+
None
|
|
2492
|
+
],
|
|
2493
|
+
models.StatusHealthResponse
|
|
2494
|
+
]:
|
|
2495
|
+
"""
|
|
2496
|
+
Get the current health of the robot
|
|
2497
|
+
"""
|
|
2498
|
+
path = "/api/v1/status/health"
|
|
2499
|
+
try:
|
|
2500
|
+
response = self._request_manager.request(
|
|
2501
|
+
"GET",
|
|
2502
|
+
path,
|
|
2503
|
+
headers=self._request_manager.json_headers(),
|
|
2504
|
+
)
|
|
2505
|
+
parsed = None
|
|
2506
|
+
if response.status == 200:
|
|
2507
|
+
parsed = models.parse_status_health_response(json.loads(response.data))
|
|
2508
|
+
|
|
2509
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
2510
|
+
is_unavailable = response.status == 503
|
|
2511
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
2512
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
2513
|
+
|
|
2514
|
+
return Response(
|
|
2515
|
+
parsed,
|
|
2516
|
+
response.status,
|
|
2517
|
+
response
|
|
2518
|
+
)
|
|
2519
|
+
except urllib3.exceptions.MaxRetryError:
|
|
2520
|
+
return Response(
|
|
2521
|
+
models.ErrorResponse(
|
|
2522
|
+
error=models.ErrorEnum.InternalServerError,
|
|
2523
|
+
message="Connection Refused"
|
|
2524
|
+
),
|
|
2525
|
+
503,
|
|
2526
|
+
None
|
|
2527
|
+
)
|
|
2528
|
+
|
|
2529
|
+
control: Control
|
|
2530
|
+
health: Health
|
|
942
2531
|
|
|
2532
|
+
def __init__(self, request_manager: RequestManager):
|
|
2533
|
+
self._request_manager = request_manager
|
|
2534
|
+
self.control = Status.Control(request_manager)
|
|
2535
|
+
self.health = Status.Health(request_manager)
|
|
2536
|
+
|
|
2537
|
+
|
|
2538
|
+
|
|
2539
|
+
|
|
2540
|
+
class StandardBotsRobot(Default):
|
|
2541
|
+
RobotKind = RobotKind
|
|
2542
|
+
|
|
2543
|
+
movement: Movement
|
|
2544
|
+
camera: Camera
|
|
2545
|
+
faults: Faults
|
|
2546
|
+
general: General
|
|
2547
|
+
chat_gpt: ChatGPT
|
|
2548
|
+
io: IO
|
|
2549
|
+
poses: Poses
|
|
2550
|
+
recovery: Recovery
|
|
2551
|
+
ros: ROS
|
|
2552
|
+
routine_editor: RoutineEditor
|
|
2553
|
+
status: Status
|
|
2554
|
+
def __init__(
|
|
2555
|
+
self,
|
|
2556
|
+
url: str,
|
|
2557
|
+
token: str,
|
|
2558
|
+
robot_kind: Union[RobotKind, str] = RobotKind.Live,
|
|
2559
|
+
pools: int = 10
|
|
2560
|
+
):
|
|
2561
|
+
super().__init__(RequestManager(
|
|
2562
|
+
urllib3.PoolManager(num_pools=2),
|
|
2563
|
+
token=token,
|
|
2564
|
+
host=url,
|
|
2565
|
+
robot_kind=RobotKind(robot_kind),
|
|
2566
|
+
))
|
|
2567
|
+
self.movement = Movement(self._request_manager)
|
|
2568
|
+
self.camera = Camera(self._request_manager)
|
|
2569
|
+
self.faults = Faults(self._request_manager)
|
|
2570
|
+
self.general = General(self._request_manager)
|
|
2571
|
+
self.chat_gpt = ChatGPT(self._request_manager)
|
|
2572
|
+
self.io = IO(self._request_manager)
|
|
2573
|
+
self.poses = Poses(self._request_manager)
|
|
2574
|
+
self.recovery = Recovery(self._request_manager)
|
|
2575
|
+
self.ros = ROS(self._request_manager)
|
|
2576
|
+
self.routine_editor = RoutineEditor(self._request_manager)
|
|
2577
|
+
self.status = Status(self._request_manager)
|
|
2578
|
+
|
|
2579
|
+
@contextmanager
|
|
2580
|
+
def connection(self):
|
|
2581
|
+
yield
|
|
2582
|
+
self._request_manager.close()
|