standardbots 2.0.0.dev1760378411__tar.gz → 2.0.0.dev1763152552__tar.gz
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.
- {standardbots-2.0.0.dev1760378411 → standardbots-2.0.0.dev1763152552}/PKG-INFO +1 -1
- {standardbots-2.0.0.dev1760378411 → standardbots-2.0.0.dev1763152552}/setup.py +1 -1
- {standardbots-2.0.0.dev1760378411 → standardbots-2.0.0.dev1763152552}/standardbots/auto_generated/apis.py +134 -1
- {standardbots-2.0.0.dev1760378411 → standardbots-2.0.0.dev1763152552}/standardbots/auto_generated/models.py +391 -37
- {standardbots-2.0.0.dev1760378411 → standardbots-2.0.0.dev1763152552}/standardbots.egg-info/PKG-INFO +1 -1
- {standardbots-2.0.0.dev1760378411 → standardbots-2.0.0.dev1763152552}/tests/test_apis.py +30 -11
- {standardbots-2.0.0.dev1760378411 → standardbots-2.0.0.dev1763152552}/README.md +0 -0
- {standardbots-2.0.0.dev1760378411 → standardbots-2.0.0.dev1763152552}/setup.cfg +0 -0
- {standardbots-2.0.0.dev1760378411 → standardbots-2.0.0.dev1763152552}/standardbots/__init__.py +0 -0
- {standardbots-2.0.0.dev1760378411 → standardbots-2.0.0.dev1763152552}/standardbots/auto_generated/__init__.py +0 -0
- {standardbots-2.0.0.dev1760378411 → standardbots-2.0.0.dev1763152552}/standardbots.egg-info/SOURCES.txt +0 -0
- {standardbots-2.0.0.dev1760378411 → standardbots-2.0.0.dev1763152552}/standardbots.egg-info/dependency_links.txt +0 -0
- {standardbots-2.0.0.dev1760378411 → standardbots-2.0.0.dev1763152552}/standardbots.egg-info/requires.txt +0 -0
- {standardbots-2.0.0.dev1760378411 → standardbots-2.0.0.dev1763152552}/standardbots.egg-info/top_level.txt +0 -0
- {standardbots-2.0.0.dev1760378411 → standardbots-2.0.0.dev1763152552}/tests/fixtures/__init__.py +0 -0
- {standardbots-2.0.0.dev1760378411 → standardbots-2.0.0.dev1763152552}/tests/fixtures/client_fixt.py +0 -0
- {standardbots-2.0.0.dev1760378411 → standardbots-2.0.0.dev1763152552}/tests/fixtures/robot_fixt.py +0 -0
- {standardbots-2.0.0.dev1760378411 → standardbots-2.0.0.dev1763152552}/tests/fixtures/routines_fixt.py +0 -0
|
@@ -833,6 +833,49 @@ class Default:
|
|
|
833
833
|
self._request_manager = request_manager
|
|
834
834
|
|
|
835
835
|
|
|
836
|
+
def list_global_spaces(
|
|
837
|
+
self,
|
|
838
|
+
) -> Response[
|
|
839
|
+
Union[
|
|
840
|
+
models.SpacesPaginatedResponse,
|
|
841
|
+
models.ErrorResponse,
|
|
842
|
+
None
|
|
843
|
+
],
|
|
844
|
+
models.SpacesPaginatedResponse
|
|
845
|
+
]:
|
|
846
|
+
"""
|
|
847
|
+
List Global Spaces
|
|
848
|
+
"""
|
|
849
|
+
path = "/api/v1/space/globals"
|
|
850
|
+
try:
|
|
851
|
+
response = self._request_manager.request(
|
|
852
|
+
"GET",
|
|
853
|
+
path,
|
|
854
|
+
headers=self._request_manager.json_headers(),
|
|
855
|
+
)
|
|
856
|
+
parsed = None
|
|
857
|
+
if response.status == 200:
|
|
858
|
+
parsed = models.parse_spaces_paginated_response(json.loads(response.data))
|
|
859
|
+
|
|
860
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
861
|
+
is_unavailable = response.status == 503
|
|
862
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
863
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
864
|
+
|
|
865
|
+
return Response(
|
|
866
|
+
parsed,
|
|
867
|
+
response.status,
|
|
868
|
+
response
|
|
869
|
+
)
|
|
870
|
+
except urllib3.exceptions.MaxRetryError:
|
|
871
|
+
return Response(
|
|
872
|
+
models.ErrorResponse(
|
|
873
|
+
error=models.ErrorEnum.InternalServerError,
|
|
874
|
+
message="Connection Refused"
|
|
875
|
+
),
|
|
876
|
+
503,
|
|
877
|
+
None
|
|
878
|
+
)
|
|
836
879
|
def list_planes(
|
|
837
880
|
self,
|
|
838
881
|
limit: int,
|
|
@@ -1118,7 +1161,7 @@ class Default:
|
|
|
1118
1161
|
models.TeleopState
|
|
1119
1162
|
]:
|
|
1120
1163
|
"""
|
|
1121
|
-
Set ratio control parameters
|
|
1164
|
+
Set ratio control parameters for movement and rotation
|
|
1122
1165
|
"""
|
|
1123
1166
|
path = "/api/v1/teleop/set-ratio-control"
|
|
1124
1167
|
try:
|
|
@@ -1137,6 +1180,96 @@ class Default:
|
|
|
1137
1180
|
if parsed is None and (is_user_error or is_unavailable):
|
|
1138
1181
|
parsed = models.parse_error_response(json.loads(response.data))
|
|
1139
1182
|
|
|
1183
|
+
return Response(
|
|
1184
|
+
parsed,
|
|
1185
|
+
response.status,
|
|
1186
|
+
response
|
|
1187
|
+
)
|
|
1188
|
+
except urllib3.exceptions.MaxRetryError:
|
|
1189
|
+
return Response(
|
|
1190
|
+
models.ErrorResponse(
|
|
1191
|
+
error=models.ErrorEnum.InternalServerError,
|
|
1192
|
+
message="Connection Refused"
|
|
1193
|
+
),
|
|
1194
|
+
503,
|
|
1195
|
+
None
|
|
1196
|
+
)
|
|
1197
|
+
def set_gripper_bounds(
|
|
1198
|
+
self,
|
|
1199
|
+
body: models.SetGripperBoundsRequest,
|
|
1200
|
+
) -> Response[
|
|
1201
|
+
Union[
|
|
1202
|
+
models.TeleopState,
|
|
1203
|
+
models.ErrorResponse,
|
|
1204
|
+
None
|
|
1205
|
+
],
|
|
1206
|
+
models.TeleopState
|
|
1207
|
+
]:
|
|
1208
|
+
"""
|
|
1209
|
+
Set gripper bounds for primary and secondary bots
|
|
1210
|
+
"""
|
|
1211
|
+
path = "/api/v1/teleop/set-gripper-bounds"
|
|
1212
|
+
try:
|
|
1213
|
+
response = self._request_manager.request(
|
|
1214
|
+
"POST",
|
|
1215
|
+
path,
|
|
1216
|
+
headers=self._request_manager.json_headers(),
|
|
1217
|
+
body=json.dumps(models.serialize_set_gripper_bounds_request(body)),
|
|
1218
|
+
)
|
|
1219
|
+
parsed = None
|
|
1220
|
+
if response.status == 200:
|
|
1221
|
+
parsed = models.parse_teleop_state(json.loads(response.data))
|
|
1222
|
+
|
|
1223
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
1224
|
+
is_unavailable = response.status == 503
|
|
1225
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
1226
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1227
|
+
|
|
1228
|
+
return Response(
|
|
1229
|
+
parsed,
|
|
1230
|
+
response.status,
|
|
1231
|
+
response
|
|
1232
|
+
)
|
|
1233
|
+
except urllib3.exceptions.MaxRetryError:
|
|
1234
|
+
return Response(
|
|
1235
|
+
models.ErrorResponse(
|
|
1236
|
+
error=models.ErrorEnum.InternalServerError,
|
|
1237
|
+
message="Connection Refused"
|
|
1238
|
+
),
|
|
1239
|
+
503,
|
|
1240
|
+
None
|
|
1241
|
+
)
|
|
1242
|
+
def set_robot_frame(
|
|
1243
|
+
self,
|
|
1244
|
+
body: models.SetRobotFrameRequest,
|
|
1245
|
+
) -> Response[
|
|
1246
|
+
Union[
|
|
1247
|
+
models.TeleopState,
|
|
1248
|
+
models.ErrorResponse,
|
|
1249
|
+
None
|
|
1250
|
+
],
|
|
1251
|
+
models.TeleopState
|
|
1252
|
+
]:
|
|
1253
|
+
"""
|
|
1254
|
+
Set robot frame
|
|
1255
|
+
"""
|
|
1256
|
+
path = "/api/v1/teleop/set-robot-frame"
|
|
1257
|
+
try:
|
|
1258
|
+
response = self._request_manager.request(
|
|
1259
|
+
"POST",
|
|
1260
|
+
path,
|
|
1261
|
+
headers=self._request_manager.json_headers(),
|
|
1262
|
+
body=json.dumps(models.serialize_set_robot_frame_request(body)),
|
|
1263
|
+
)
|
|
1264
|
+
parsed = None
|
|
1265
|
+
if response.status == 200:
|
|
1266
|
+
parsed = models.parse_teleop_state(json.loads(response.data))
|
|
1267
|
+
|
|
1268
|
+
is_user_error = response.status >= 400 and response.status <= 500
|
|
1269
|
+
is_unavailable = response.status == 503
|
|
1270
|
+
if parsed is None and (is_user_error or is_unavailable):
|
|
1271
|
+
parsed = models.parse_error_response(json.loads(response.data))
|
|
1272
|
+
|
|
1140
1273
|
return Response(
|
|
1141
1274
|
parsed,
|
|
1142
1275
|
response.status,
|
|
@@ -1337,6 +1337,8 @@ class ErrorEnum(Enum):
|
|
|
1337
1337
|
"""Cannot change ROS state"""
|
|
1338
1338
|
IoSafeguardError = "io_safeguard_error"
|
|
1339
1339
|
"""Cannot change IO state because of safeguard"""
|
|
1340
|
+
RobotOutOfComplianceBounds = "robot_out_of_compliance_bounds"
|
|
1341
|
+
"""Cannot initiate compliance control: Robot is outside compliance bounds"""
|
|
1340
1342
|
|
|
1341
1343
|
def parse_error_enum(data: object) -> ErrorEnum:
|
|
1342
1344
|
return ErrorEnum(data)
|
|
@@ -1470,6 +1472,51 @@ def parse_force_unit_kind(data: object) -> ForceUnitKind:
|
|
|
1470
1472
|
def serialize_force_unit_kind(data: Union[ForceUnitKind, str]) -> object:
|
|
1471
1473
|
return ForceUnitKind(data).value
|
|
1472
1474
|
|
|
1475
|
+
@dataclass
|
|
1476
|
+
class GripperBounds:
|
|
1477
|
+
"""Gripper bounds configuration"""
|
|
1478
|
+
min: Union[float, None] = None
|
|
1479
|
+
max: Union[float, None] = None
|
|
1480
|
+
|
|
1481
|
+
def validate_min(self, value: float) -> Tuple[bool, str]:
|
|
1482
|
+
if value is None:
|
|
1483
|
+
return [False, "min is required for GripperBounds"]
|
|
1484
|
+
|
|
1485
|
+
if not isinstance(value, float):
|
|
1486
|
+
return [False, "min must be of type float for GripperBounds, got " + type(value).__name__]
|
|
1487
|
+
|
|
1488
|
+
return [True, ""]
|
|
1489
|
+
|
|
1490
|
+
def validate_max(self, value: float) -> Tuple[bool, str]:
|
|
1491
|
+
if value is None:
|
|
1492
|
+
return [False, "max is required for GripperBounds"]
|
|
1493
|
+
|
|
1494
|
+
if not isinstance(value, float):
|
|
1495
|
+
return [False, "max must be of type float for GripperBounds, got " + type(value).__name__]
|
|
1496
|
+
|
|
1497
|
+
return [True, ""]
|
|
1498
|
+
|
|
1499
|
+
def __post_init__(self):
|
|
1500
|
+
# Type check incoming model - raise error if invalid (required or wrong type)
|
|
1501
|
+
is_valid, error_str = self.validate_min(self.min)
|
|
1502
|
+
if not is_valid:
|
|
1503
|
+
raise TypeError(error_str)
|
|
1504
|
+
is_valid, error_str = self.validate_max(self.max)
|
|
1505
|
+
if not is_valid:
|
|
1506
|
+
raise TypeError(error_str)
|
|
1507
|
+
|
|
1508
|
+
def parse_gripper_bounds(data: object):
|
|
1509
|
+
return GripperBounds(
|
|
1510
|
+
min=parse_f_64(data["min"]) if "min" in data and data.get("min") is not None else None,
|
|
1511
|
+
max=parse_f_64(data["max"]) if "max" in data and data.get("max") is not None else None,
|
|
1512
|
+
)
|
|
1513
|
+
|
|
1514
|
+
def serialize_gripper_bounds(data: GripperBounds) -> object:
|
|
1515
|
+
return {
|
|
1516
|
+
"min": serialize_f_64(data.min),
|
|
1517
|
+
"max": serialize_f_64(data.max),
|
|
1518
|
+
}
|
|
1519
|
+
|
|
1473
1520
|
class GripperKindEnum(Enum):
|
|
1474
1521
|
Onrobot2Fg7 = "onrobot_2fg7"
|
|
1475
1522
|
"""An OnRobot 2FG7 Gripper is connected"""
|
|
@@ -1736,6 +1783,14 @@ def parse_max_joint_speeds(data: object) -> MaxJointSpeeds:
|
|
|
1736
1783
|
def serialize_max_joint_speeds(data: MaxJointSpeeds) -> object:
|
|
1737
1784
|
return [serialize_f_64(data[0]),serialize_f_64(data[1]),serialize_f_64(data[2]),serialize_f_64(data[3]),serialize_f_64(data[4]),serialize_f_64(data[5]),]
|
|
1738
1785
|
|
|
1786
|
+
MaxJointTorques = Tuple[float,float,float,float,float,float,]
|
|
1787
|
+
|
|
1788
|
+
def parse_max_joint_torques(data: object) -> MaxJointTorques:
|
|
1789
|
+
return (parse_f_64(data[0]),parse_f_64(data[1]),parse_f_64(data[2]),parse_f_64(data[3]),parse_f_64(data[4]),parse_f_64(data[5]),)
|
|
1790
|
+
|
|
1791
|
+
def serialize_max_joint_torques(data: MaxJointTorques) -> object:
|
|
1792
|
+
return [serialize_f_64(data[0]),serialize_f_64(data[1]),serialize_f_64(data[2]),serialize_f_64(data[3]),serialize_f_64(data[4]),serialize_f_64(data[5]),]
|
|
1793
|
+
|
|
1739
1794
|
class MovementKindEnum(Enum):
|
|
1740
1795
|
Joint = "joint"
|
|
1741
1796
|
"""Enum Joint = `joint`"""
|
|
@@ -2652,6 +2707,18 @@ def parse_robot_control_mode_enum(data: object) -> RobotControlModeEnum:
|
|
|
2652
2707
|
def serialize_robot_control_mode_enum(data: Union[RobotControlModeEnum, str]) -> object:
|
|
2653
2708
|
return RobotControlModeEnum(data).value
|
|
2654
2709
|
|
|
2710
|
+
class RobotFrame(Enum):
|
|
2711
|
+
World = "world"
|
|
2712
|
+
"""Enum World = `world`"""
|
|
2713
|
+
Tooltip = "tooltip"
|
|
2714
|
+
"""Enum Tooltip = `tooltip`"""
|
|
2715
|
+
|
|
2716
|
+
def parse_robot_frame(data: object) -> RobotFrame:
|
|
2717
|
+
return RobotFrame(data)
|
|
2718
|
+
|
|
2719
|
+
def serialize_robot_frame(data: Union[RobotFrame, str]) -> object:
|
|
2720
|
+
return RobotFrame(data).value
|
|
2721
|
+
|
|
2655
2722
|
class RobotStatusEnum(Enum):
|
|
2656
2723
|
Idle = "Idle"
|
|
2657
2724
|
"""Enum Idle = `Idle`"""
|
|
@@ -3156,7 +3223,8 @@ def serialize_sensor_config(data: SensorConfig) -> object:
|
|
|
3156
3223
|
class SetRatioControlRequest:
|
|
3157
3224
|
"""Request to set ratio control parameters"""
|
|
3158
3225
|
enabled: Union[bool, None] = None
|
|
3159
|
-
|
|
3226
|
+
movementValue: Union[float, None] = None
|
|
3227
|
+
rotationValue: Union[float, None] = None
|
|
3160
3228
|
|
|
3161
3229
|
def validate_enabled(self, value: bool) -> Tuple[bool, str]:
|
|
3162
3230
|
if value is None:
|
|
@@ -3167,12 +3235,21 @@ class SetRatioControlRequest:
|
|
|
3167
3235
|
|
|
3168
3236
|
return [True, ""]
|
|
3169
3237
|
|
|
3170
|
-
def
|
|
3238
|
+
def validate_movementValue(self, value: float) -> Tuple[bool, str]:
|
|
3239
|
+
if value is None:
|
|
3240
|
+
return [True, ""]
|
|
3241
|
+
|
|
3242
|
+
if not isinstance(value, float):
|
|
3243
|
+
return [False, "movementValue must be of type float for SetRatioControlRequest, got " + type(value).__name__]
|
|
3244
|
+
|
|
3245
|
+
return [True, ""]
|
|
3246
|
+
|
|
3247
|
+
def validate_rotationValue(self, value: float) -> Tuple[bool, str]:
|
|
3171
3248
|
if value is None:
|
|
3172
3249
|
return [True, ""]
|
|
3173
3250
|
|
|
3174
3251
|
if not isinstance(value, float):
|
|
3175
|
-
return [False, "
|
|
3252
|
+
return [False, "rotationValue must be of type float for SetRatioControlRequest, got " + type(value).__name__]
|
|
3176
3253
|
|
|
3177
3254
|
return [True, ""]
|
|
3178
3255
|
|
|
@@ -3181,20 +3258,25 @@ class SetRatioControlRequest:
|
|
|
3181
3258
|
is_valid, error_str = self.validate_enabled(self.enabled)
|
|
3182
3259
|
if not is_valid:
|
|
3183
3260
|
raise TypeError(error_str)
|
|
3184
|
-
is_valid, error_str = self.
|
|
3261
|
+
is_valid, error_str = self.validate_movementValue(self.movementValue)
|
|
3262
|
+
if not is_valid:
|
|
3263
|
+
raise TypeError(error_str)
|
|
3264
|
+
is_valid, error_str = self.validate_rotationValue(self.rotationValue)
|
|
3185
3265
|
if not is_valid:
|
|
3186
3266
|
raise TypeError(error_str)
|
|
3187
3267
|
|
|
3188
3268
|
def parse_set_ratio_control_request(data: object):
|
|
3189
3269
|
return SetRatioControlRequest(
|
|
3190
3270
|
enabled=parse_bool(data["enabled"]) if "enabled" in data and data.get("enabled") is not None else None,
|
|
3191
|
-
|
|
3271
|
+
movementValue=parse_f_64(data["movementValue"]) if "movementValue" in data and data.get("movementValue") is not None else None,
|
|
3272
|
+
rotationValue=parse_f_64(data["rotationValue"]) if "rotationValue" in data and data.get("rotationValue") is not None else None,
|
|
3192
3273
|
)
|
|
3193
3274
|
|
|
3194
3275
|
def serialize_set_ratio_control_request(data: SetRatioControlRequest) -> object:
|
|
3195
3276
|
return {
|
|
3196
3277
|
"enabled": None if data.enabled is None else serialize_bool(data.enabled),
|
|
3197
|
-
"
|
|
3278
|
+
"movementValue": None if data.movementValue is None else serialize_f_64(data.movementValue),
|
|
3279
|
+
"rotationValue": None if data.rotationValue is None else serialize_f_64(data.rotationValue),
|
|
3198
3280
|
}
|
|
3199
3281
|
|
|
3200
3282
|
class SignalMessageType(Enum):
|
|
@@ -3318,36 +3400,6 @@ def serialize_status_version_data(data: StatusVersionData) -> object:
|
|
|
3318
3400
|
"name": None if data.name is None else serialize_str(data.name),
|
|
3319
3401
|
}
|
|
3320
3402
|
|
|
3321
|
-
@dataclass
|
|
3322
|
-
class StopRecordingRequest:
|
|
3323
|
-
"""Request to stop recording movement and camera data"""
|
|
3324
|
-
delete: Union[bool, None] = None
|
|
3325
|
-
|
|
3326
|
-
def validate_delete(self, value: bool) -> Tuple[bool, str]:
|
|
3327
|
-
if value is None:
|
|
3328
|
-
return [True, ""]
|
|
3329
|
-
|
|
3330
|
-
if not isinstance(value, bool):
|
|
3331
|
-
return [False, "delete must be of type bool for StopRecordingRequest, got " + type(value).__name__]
|
|
3332
|
-
|
|
3333
|
-
return [True, ""]
|
|
3334
|
-
|
|
3335
|
-
def __post_init__(self):
|
|
3336
|
-
# Type check incoming model - raise error if invalid (required or wrong type)
|
|
3337
|
-
is_valid, error_str = self.validate_delete(self.delete)
|
|
3338
|
-
if not is_valid:
|
|
3339
|
-
raise TypeError(error_str)
|
|
3340
|
-
|
|
3341
|
-
def parse_stop_recording_request(data: object):
|
|
3342
|
-
return StopRecordingRequest(
|
|
3343
|
-
delete=parse_bool(data["delete"]) if "delete" in data and data.get("delete") is not None else None,
|
|
3344
|
-
)
|
|
3345
|
-
|
|
3346
|
-
def serialize_stop_recording_request(data: StopRecordingRequest) -> object:
|
|
3347
|
-
return {
|
|
3348
|
-
"delete": None if data.delete is None else serialize_bool(data.delete),
|
|
3349
|
-
}
|
|
3350
|
-
|
|
3351
3403
|
StringArray = List[str]
|
|
3352
3404
|
|
|
3353
3405
|
def parse_string_array(data: object) -> StringArray:
|
|
@@ -3356,6 +3408,14 @@ def parse_string_array(data: object) -> StringArray:
|
|
|
3356
3408
|
def serialize_string_array(data: StringArray) -> List[object]:
|
|
3357
3409
|
return [serialize_str(item) for item in data]
|
|
3358
3410
|
|
|
3411
|
+
TeleopErrorArray = List[str]
|
|
3412
|
+
|
|
3413
|
+
def parse_teleop_error_array(data: object) -> TeleopErrorArray:
|
|
3414
|
+
return [parse_str(item) for item in data]
|
|
3415
|
+
|
|
3416
|
+
def serialize_teleop_error_array(data: TeleopErrorArray) -> List[object]:
|
|
3417
|
+
return [serialize_str(item) for item in data]
|
|
3418
|
+
|
|
3359
3419
|
class TeleopStatus(Enum):
|
|
3360
3420
|
WaitForTeleop = "wait_for_teleop"
|
|
3361
3421
|
"""Enum WaitForTeleop = `wait_for_teleop`"""
|
|
@@ -4211,7 +4271,7 @@ class ErrorResponse:
|
|
|
4211
4271
|
if value is None:
|
|
4212
4272
|
return [False, "error is required for ErrorResponse"]
|
|
4213
4273
|
|
|
4214
|
-
if not ((isinstance(value, str) and ErrorEnum in ['authorization_required', 'routine_must_be_running', 'api_control_required', 'robot_brakes_disengage_failed', 'robot_brakes_engage_failed', 'request_failed_validation', 'robot_not_idle', 'brakes_must_be_engaged', 'brakes_must_be_disengaged', 'equipment_no_matching', 'service_initializing', 'camera_disconnected', 'settings_validation_error', 'settings_timeout', 'internal_server_error', 'recovery_error', 'not_found', 'invalid_space_specified', 'invalid_parameters', 'routine_does_not_exist', 'cannot_play_routine', 'routine_must_be_playing', 'cannot_change_ros_state', 'io_safeguard_error']) or isinstance(value, ErrorEnum)):
|
|
4274
|
+
if not ((isinstance(value, str) and ErrorEnum in ['authorization_required', 'routine_must_be_running', 'api_control_required', 'robot_brakes_disengage_failed', 'robot_brakes_engage_failed', 'request_failed_validation', 'robot_not_idle', 'brakes_must_be_engaged', 'brakes_must_be_disengaged', 'equipment_no_matching', 'service_initializing', 'camera_disconnected', 'settings_validation_error', 'settings_timeout', 'internal_server_error', 'recovery_error', 'not_found', 'invalid_space_specified', 'invalid_parameters', 'routine_does_not_exist', 'cannot_play_routine', 'routine_must_be_playing', 'cannot_change_ros_state', 'io_safeguard_error', 'robot_out_of_compliance_bounds']) or isinstance(value, ErrorEnum)):
|
|
4215
4275
|
return [False, "error must be of type ErrorEnum for ErrorResponse, got " + type(value).__name__]
|
|
4216
4276
|
|
|
4217
4277
|
return [True, ""]
|
|
@@ -4548,6 +4608,18 @@ def serialize_force_unit(data: ForceUnit) -> object:
|
|
|
4548
4608
|
"value": None if data.value is None else serialize_f_64(data.value),
|
|
4549
4609
|
}
|
|
4550
4610
|
|
|
4611
|
+
SecondaryBotGripperBounds = Dict[str, GripperBounds]
|
|
4612
|
+
|
|
4613
|
+
def parse_secondary_bot_gripper_bounds(data: object) -> SecondaryBotGripperBounds:
|
|
4614
|
+
return {
|
|
4615
|
+
parse_str(key): parse_gripper_bounds(value) for key, value in data.items()
|
|
4616
|
+
}
|
|
4617
|
+
|
|
4618
|
+
def serialize_secondary_bot_gripper_bounds(data: SecondaryBotGripperBounds) -> object:
|
|
4619
|
+
return {
|
|
4620
|
+
serialize_str(key): serialize_gripper_bounds(value) for key, value in data.items()
|
|
4621
|
+
}
|
|
4622
|
+
|
|
4551
4623
|
@dataclass
|
|
4552
4624
|
class IOStateResponse:
|
|
4553
4625
|
"""Response to a query for the current state of I/O."""
|
|
@@ -4901,6 +4973,7 @@ class SpeedProfile:
|
|
|
4901
4973
|
max_joint_speeds: Union[MaxJointSpeeds, None] = None
|
|
4902
4974
|
max_joint_accelerations: Union[MaxJointAcclerations, None] = None
|
|
4903
4975
|
max_tooltip_speed: Union[float, None] = None
|
|
4976
|
+
max_joint_torques: Union[MaxJointTorques, None] = None
|
|
4904
4977
|
base_acceleration_scaling: Union[float, None] = None
|
|
4905
4978
|
base_velocity_scaling: Union[float, None] = None
|
|
4906
4979
|
scaling_factor: Union[float, None] = None
|
|
@@ -4932,6 +5005,15 @@ class SpeedProfile:
|
|
|
4932
5005
|
|
|
4933
5006
|
return [True, ""]
|
|
4934
5007
|
|
|
5008
|
+
def validate_max_joint_torques(self, value: MaxJointTorques) -> Tuple[bool, str]:
|
|
5009
|
+
if value is None:
|
|
5010
|
+
return [True, ""]
|
|
5011
|
+
|
|
5012
|
+
if not (isinstance(value, tuple) and len(value) == 6):
|
|
5013
|
+
return [False, "max_joint_torques must be of type MaxJointTorques for SpeedProfile, got " + type(value).__name__]
|
|
5014
|
+
|
|
5015
|
+
return [True, ""]
|
|
5016
|
+
|
|
4935
5017
|
def validate_base_acceleration_scaling(self, value: float) -> Tuple[bool, str]:
|
|
4936
5018
|
if value is None:
|
|
4937
5019
|
return [True, ""]
|
|
@@ -4968,6 +5050,9 @@ class SpeedProfile:
|
|
|
4968
5050
|
if not is_valid:
|
|
4969
5051
|
raise TypeError(error_str)
|
|
4970
5052
|
is_valid, error_str = self.validate_max_tooltip_speed(self.max_tooltip_speed)
|
|
5053
|
+
if not is_valid:
|
|
5054
|
+
raise TypeError(error_str)
|
|
5055
|
+
is_valid, error_str = self.validate_max_joint_torques(self.max_joint_torques)
|
|
4971
5056
|
if not is_valid:
|
|
4972
5057
|
raise TypeError(error_str)
|
|
4973
5058
|
is_valid, error_str = self.validate_base_acceleration_scaling(self.base_acceleration_scaling)
|
|
@@ -4985,6 +5070,7 @@ def parse_speed_profile(data: object):
|
|
|
4985
5070
|
max_joint_speeds=parse_max_joint_speeds(data["max_joint_speeds"]) if "max_joint_speeds" in data and data.get("max_joint_speeds") is not None else None,
|
|
4986
5071
|
max_joint_accelerations=parse_max_joint_acclerations(data["max_joint_accelerations"]) if "max_joint_accelerations" in data and data.get("max_joint_accelerations") is not None else None,
|
|
4987
5072
|
max_tooltip_speed=parse_f_64(data["max_tooltip_speed"]) if "max_tooltip_speed" in data and data.get("max_tooltip_speed") is not None else None,
|
|
5073
|
+
max_joint_torques=parse_max_joint_torques(data["max_joint_torques"]) if "max_joint_torques" in data and data.get("max_joint_torques") is not None else None,
|
|
4988
5074
|
base_acceleration_scaling=parse_f_64(data["base_acceleration_scaling"]) if "base_acceleration_scaling" in data and data.get("base_acceleration_scaling") is not None else None,
|
|
4989
5075
|
base_velocity_scaling=parse_f_64(data["base_velocity_scaling"]) if "base_velocity_scaling" in data and data.get("base_velocity_scaling") is not None else None,
|
|
4990
5076
|
scaling_factor=parse_f_64(data["scaling_factor"]) if "scaling_factor" in data and data.get("scaling_factor") is not None else None,
|
|
@@ -4995,6 +5081,7 @@ def serialize_speed_profile(data: SpeedProfile) -> object:
|
|
|
4995
5081
|
"max_joint_speeds": None if data.max_joint_speeds is None else serialize_max_joint_speeds(data.max_joint_speeds),
|
|
4996
5082
|
"max_joint_accelerations": None if data.max_joint_accelerations is None else serialize_max_joint_acclerations(data.max_joint_accelerations),
|
|
4997
5083
|
"max_tooltip_speed": None if data.max_tooltip_speed is None else serialize_f_64(data.max_tooltip_speed),
|
|
5084
|
+
"max_joint_torques": None if data.max_joint_torques is None else serialize_max_joint_torques(data.max_joint_torques),
|
|
4998
5085
|
"base_acceleration_scaling": None if data.base_acceleration_scaling is None else serialize_f_64(data.base_acceleration_scaling),
|
|
4999
5086
|
"base_velocity_scaling": None if data.base_velocity_scaling is None else serialize_f_64(data.base_velocity_scaling),
|
|
5000
5087
|
"scaling_factor": None if data.scaling_factor is None else serialize_f_64(data.scaling_factor),
|
|
@@ -6036,6 +6123,18 @@ def serialize_robot_control_mode(data: RobotControlMode) -> object:
|
|
|
6036
6123
|
"kind": None if data.kind is None else serialize_robot_control_mode_enum(data.kind),
|
|
6037
6124
|
}
|
|
6038
6125
|
|
|
6126
|
+
SecondaryBotRobotFrame = Dict[str, RobotFrame]
|
|
6127
|
+
|
|
6128
|
+
def parse_secondary_bot_robot_frame(data: object) -> SecondaryBotRobotFrame:
|
|
6129
|
+
return {
|
|
6130
|
+
parse_str(key): parse_robot_frame(value) for key, value in data.items()
|
|
6131
|
+
}
|
|
6132
|
+
|
|
6133
|
+
def serialize_secondary_bot_robot_frame(data: SecondaryBotRobotFrame) -> object:
|
|
6134
|
+
return {
|
|
6135
|
+
serialize_str(key): serialize_robot_frame(value) for key, value in data.items()
|
|
6136
|
+
}
|
|
6137
|
+
|
|
6039
6138
|
@dataclass
|
|
6040
6139
|
class PlayRoutineResponse:
|
|
6041
6140
|
"""Status response informs user of of robot state"""
|
|
@@ -6547,6 +6646,51 @@ def serialize_save_recording_response(data: SaveRecordingResponse) -> object:
|
|
|
6547
6646
|
"errors": None if data.errors is None else serialize_string_array(data.errors),
|
|
6548
6647
|
}
|
|
6549
6648
|
|
|
6649
|
+
@dataclass
|
|
6650
|
+
class StopRecordingRequest:
|
|
6651
|
+
"""Request to stop recording movement and camera data"""
|
|
6652
|
+
delete: Union[bool, None] = None
|
|
6653
|
+
tags: Union[StringArray, None] = None
|
|
6654
|
+
|
|
6655
|
+
def validate_delete(self, value: bool) -> Tuple[bool, str]:
|
|
6656
|
+
if value is None:
|
|
6657
|
+
return [True, ""]
|
|
6658
|
+
|
|
6659
|
+
if not isinstance(value, bool):
|
|
6660
|
+
return [False, "delete must be of type bool for StopRecordingRequest, got " + type(value).__name__]
|
|
6661
|
+
|
|
6662
|
+
return [True, ""]
|
|
6663
|
+
|
|
6664
|
+
def validate_tags(self, value: StringArray) -> Tuple[bool, str]:
|
|
6665
|
+
if value is None:
|
|
6666
|
+
return [True, ""]
|
|
6667
|
+
|
|
6668
|
+
if not (isinstance(value, list) and all(isinstance(x, str) for x in value)):
|
|
6669
|
+
return [False, "tags must be of type StringArray for StopRecordingRequest, got " + type(value).__name__]
|
|
6670
|
+
|
|
6671
|
+
return [True, ""]
|
|
6672
|
+
|
|
6673
|
+
def __post_init__(self):
|
|
6674
|
+
# Type check incoming model - raise error if invalid (required or wrong type)
|
|
6675
|
+
is_valid, error_str = self.validate_delete(self.delete)
|
|
6676
|
+
if not is_valid:
|
|
6677
|
+
raise TypeError(error_str)
|
|
6678
|
+
is_valid, error_str = self.validate_tags(self.tags)
|
|
6679
|
+
if not is_valid:
|
|
6680
|
+
raise TypeError(error_str)
|
|
6681
|
+
|
|
6682
|
+
def parse_stop_recording_request(data: object):
|
|
6683
|
+
return StopRecordingRequest(
|
|
6684
|
+
delete=parse_bool(data["delete"]) if "delete" in data and data.get("delete") is not None else None,
|
|
6685
|
+
tags=parse_string_array(data["tags"]) if "tags" in data and data.get("tags") is not None else None,
|
|
6686
|
+
)
|
|
6687
|
+
|
|
6688
|
+
def serialize_stop_recording_request(data: StopRecordingRequest) -> object:
|
|
6689
|
+
return {
|
|
6690
|
+
"delete": None if data.delete is None else serialize_bool(data.delete),
|
|
6691
|
+
"tags": None if data.tags is None else serialize_string_array(data.tags),
|
|
6692
|
+
}
|
|
6693
|
+
|
|
6550
6694
|
@dataclass
|
|
6551
6695
|
class BotTeleopDetails:
|
|
6552
6696
|
"""Details of the bot"""
|
|
@@ -6557,6 +6701,9 @@ class BotTeleopDetails:
|
|
|
6557
6701
|
isSecondary: Union[bool, None] = None
|
|
6558
6702
|
isEnabled: Union[bool, None] = None
|
|
6559
6703
|
status: Union[TeleopStatus, None] = None
|
|
6704
|
+
errors: Union[TeleopErrorArray, None] = None
|
|
6705
|
+
gripperBounds: Union[GripperBounds, None] = None
|
|
6706
|
+
robotFrame: Union[RobotFrame, None] = None
|
|
6560
6707
|
|
|
6561
6708
|
def validate_botId(self, value: str) -> Tuple[bool, str]:
|
|
6562
6709
|
if value is None:
|
|
@@ -6621,6 +6768,33 @@ class BotTeleopDetails:
|
|
|
6621
6768
|
|
|
6622
6769
|
return [True, ""]
|
|
6623
6770
|
|
|
6771
|
+
def validate_errors(self, value: TeleopErrorArray) -> Tuple[bool, str]:
|
|
6772
|
+
if value is None:
|
|
6773
|
+
return [True, ""]
|
|
6774
|
+
|
|
6775
|
+
if not (isinstance(value, list) and all(isinstance(x, str) for x in value)):
|
|
6776
|
+
return [False, "errors must be of type TeleopErrorArray for BotTeleopDetails, got " + type(value).__name__]
|
|
6777
|
+
|
|
6778
|
+
return [True, ""]
|
|
6779
|
+
|
|
6780
|
+
def validate_gripperBounds(self, value: GripperBounds) -> Tuple[bool, str]:
|
|
6781
|
+
if value is None:
|
|
6782
|
+
return [True, ""]
|
|
6783
|
+
|
|
6784
|
+
if not isinstance(value, GripperBounds):
|
|
6785
|
+
return [False, "gripperBounds must be of type GripperBounds for BotTeleopDetails, got " + type(value).__name__]
|
|
6786
|
+
|
|
6787
|
+
return [True, ""]
|
|
6788
|
+
|
|
6789
|
+
def validate_robotFrame(self, value: RobotFrame) -> Tuple[bool, str]:
|
|
6790
|
+
if value is None:
|
|
6791
|
+
return [True, ""]
|
|
6792
|
+
|
|
6793
|
+
if not ((isinstance(value, str) and RobotFrame in ['world', 'tooltip']) or isinstance(value, RobotFrame)):
|
|
6794
|
+
return [False, "robotFrame must be of type RobotFrame for BotTeleopDetails, got " + type(value).__name__]
|
|
6795
|
+
|
|
6796
|
+
return [True, ""]
|
|
6797
|
+
|
|
6624
6798
|
def __post_init__(self):
|
|
6625
6799
|
# Type check incoming model - raise error if invalid (required or wrong type)
|
|
6626
6800
|
is_valid, error_str = self.validate_botId(self.botId)
|
|
@@ -6644,6 +6818,15 @@ class BotTeleopDetails:
|
|
|
6644
6818
|
is_valid, error_str = self.validate_status(self.status)
|
|
6645
6819
|
if not is_valid:
|
|
6646
6820
|
raise TypeError(error_str)
|
|
6821
|
+
is_valid, error_str = self.validate_errors(self.errors)
|
|
6822
|
+
if not is_valid:
|
|
6823
|
+
raise TypeError(error_str)
|
|
6824
|
+
is_valid, error_str = self.validate_gripperBounds(self.gripperBounds)
|
|
6825
|
+
if not is_valid:
|
|
6826
|
+
raise TypeError(error_str)
|
|
6827
|
+
is_valid, error_str = self.validate_robotFrame(self.robotFrame)
|
|
6828
|
+
if not is_valid:
|
|
6829
|
+
raise TypeError(error_str)
|
|
6647
6830
|
|
|
6648
6831
|
def parse_bot_teleop_details(data: object):
|
|
6649
6832
|
return BotTeleopDetails(
|
|
@@ -6654,6 +6837,9 @@ def parse_bot_teleop_details(data: object):
|
|
|
6654
6837
|
isSecondary=parse_bool(data["isSecondary"]) if "isSecondary" in data and data.get("isSecondary") is not None else None,
|
|
6655
6838
|
isEnabled=parse_bool(data["isEnabled"]) if "isEnabled" in data and data.get("isEnabled") is not None else None,
|
|
6656
6839
|
status=parse_teleop_status(data["status"]) if "status" in data and data.get("status") is not None else None,
|
|
6840
|
+
errors=parse_teleop_error_array(data["errors"]) if "errors" in data and data.get("errors") is not None else None,
|
|
6841
|
+
gripperBounds=parse_gripper_bounds(data["gripperBounds"]) if "gripperBounds" in data and data.get("gripperBounds") is not None else None,
|
|
6842
|
+
robotFrame=parse_robot_frame(data["robotFrame"]) if "robotFrame" in data and data.get("robotFrame") is not None else None,
|
|
6657
6843
|
)
|
|
6658
6844
|
|
|
6659
6845
|
def serialize_bot_teleop_details(data: BotTeleopDetails) -> object:
|
|
@@ -6665,6 +6851,9 @@ def serialize_bot_teleop_details(data: BotTeleopDetails) -> object:
|
|
|
6665
6851
|
"isSecondary": None if data.isSecondary is None else serialize_bool(data.isSecondary),
|
|
6666
6852
|
"isEnabled": None if data.isEnabled is None else serialize_bool(data.isEnabled),
|
|
6667
6853
|
"status": None if data.status is None else serialize_teleop_status(data.status),
|
|
6854
|
+
"errors": None if data.errors is None else serialize_teleop_error_array(data.errors),
|
|
6855
|
+
"gripperBounds": None if data.gripperBounds is None else serialize_gripper_bounds(data.gripperBounds),
|
|
6856
|
+
"robotFrame": None if data.robotFrame is None else serialize_robot_frame(data.robotFrame),
|
|
6668
6857
|
}
|
|
6669
6858
|
|
|
6670
6859
|
@dataclass
|
|
@@ -6857,6 +7046,51 @@ def serialize_calibration_data(data: CalibrationData) -> object:
|
|
|
6857
7046
|
"urdfParameters": serialize_urdf_parameters(data.urdfParameters),
|
|
6858
7047
|
}
|
|
6859
7048
|
|
|
7049
|
+
@dataclass
|
|
7050
|
+
class SetGripperBoundsRequest:
|
|
7051
|
+
"""Request to set gripper bounds for primary and secondary bots"""
|
|
7052
|
+
primary: Union[GripperBounds, None] = None
|
|
7053
|
+
secondary: Union[SecondaryBotGripperBounds, None] = None
|
|
7054
|
+
|
|
7055
|
+
def validate_primary(self, value: GripperBounds) -> Tuple[bool, str]:
|
|
7056
|
+
if value is None:
|
|
7057
|
+
return [False, "primary is required for SetGripperBoundsRequest"]
|
|
7058
|
+
|
|
7059
|
+
if not isinstance(value, GripperBounds):
|
|
7060
|
+
return [False, "primary must be of type GripperBounds for SetGripperBoundsRequest, got " + type(value).__name__]
|
|
7061
|
+
|
|
7062
|
+
return [True, ""]
|
|
7063
|
+
|
|
7064
|
+
def validate_secondary(self, value: SecondaryBotGripperBounds) -> Tuple[bool, str]:
|
|
7065
|
+
if value is None:
|
|
7066
|
+
return [True, ""]
|
|
7067
|
+
|
|
7068
|
+
if not (isinstance(value, dict) and all((isinstance(k, str) and isinstance(val, GripperBounds)) for k, val in value.items())):
|
|
7069
|
+
return [False, "secondary must be of type SecondaryBotGripperBounds for SetGripperBoundsRequest, got " + type(value).__name__]
|
|
7070
|
+
|
|
7071
|
+
return [True, ""]
|
|
7072
|
+
|
|
7073
|
+
def __post_init__(self):
|
|
7074
|
+
# Type check incoming model - raise error if invalid (required or wrong type)
|
|
7075
|
+
is_valid, error_str = self.validate_primary(self.primary)
|
|
7076
|
+
if not is_valid:
|
|
7077
|
+
raise TypeError(error_str)
|
|
7078
|
+
is_valid, error_str = self.validate_secondary(self.secondary)
|
|
7079
|
+
if not is_valid:
|
|
7080
|
+
raise TypeError(error_str)
|
|
7081
|
+
|
|
7082
|
+
def parse_set_gripper_bounds_request(data: object):
|
|
7083
|
+
return SetGripperBoundsRequest(
|
|
7084
|
+
primary=parse_gripper_bounds(data["primary"]) if "primary" in data and data.get("primary") is not None else None,
|
|
7085
|
+
secondary=parse_secondary_bot_gripper_bounds(data["secondary"]) if "secondary" in data and data.get("secondary") is not None else None,
|
|
7086
|
+
)
|
|
7087
|
+
|
|
7088
|
+
def serialize_set_gripper_bounds_request(data: SetGripperBoundsRequest) -> object:
|
|
7089
|
+
return {
|
|
7090
|
+
"primary": serialize_gripper_bounds(data.primary),
|
|
7091
|
+
"secondary": None if data.secondary is None else serialize_secondary_bot_gripper_bounds(data.secondary),
|
|
7092
|
+
}
|
|
7093
|
+
|
|
6860
7094
|
ArmJointRotationsList = List[ArmJointRotations]
|
|
6861
7095
|
|
|
6862
7096
|
def parse_arm_joint_rotations_list(data: object) -> ArmJointRotationsList:
|
|
@@ -7627,6 +7861,51 @@ def serialize_failure_state_response(data: FailureStateResponse) -> object:
|
|
|
7627
7861
|
"failure": None if data.failure is None else serialize_failure_state_details(data.failure),
|
|
7628
7862
|
}
|
|
7629
7863
|
|
|
7864
|
+
@dataclass
|
|
7865
|
+
class SetRobotFrameRequest:
|
|
7866
|
+
"""Request to set robot frame"""
|
|
7867
|
+
primary: Union[RobotFrame, None] = None
|
|
7868
|
+
secondary: Union[SecondaryBotRobotFrame, None] = None
|
|
7869
|
+
|
|
7870
|
+
def validate_primary(self, value: RobotFrame) -> Tuple[bool, str]:
|
|
7871
|
+
if value is None:
|
|
7872
|
+
return [False, "primary is required for SetRobotFrameRequest"]
|
|
7873
|
+
|
|
7874
|
+
if not ((isinstance(value, str) and RobotFrame in ['world', 'tooltip']) or isinstance(value, RobotFrame)):
|
|
7875
|
+
return [False, "primary must be of type RobotFrame for SetRobotFrameRequest, got " + type(value).__name__]
|
|
7876
|
+
|
|
7877
|
+
return [True, ""]
|
|
7878
|
+
|
|
7879
|
+
def validate_secondary(self, value: SecondaryBotRobotFrame) -> Tuple[bool, str]:
|
|
7880
|
+
if value is None:
|
|
7881
|
+
return [True, ""]
|
|
7882
|
+
|
|
7883
|
+
if not (isinstance(value, dict) and all((isinstance(k, str) and ((isinstance(val, str) and RobotFrame in ['world', 'tooltip']) or isinstance(val, RobotFrame))) for k, val in value.items())):
|
|
7884
|
+
return [False, "secondary must be of type SecondaryBotRobotFrame for SetRobotFrameRequest, got " + type(value).__name__]
|
|
7885
|
+
|
|
7886
|
+
return [True, ""]
|
|
7887
|
+
|
|
7888
|
+
def __post_init__(self):
|
|
7889
|
+
# Type check incoming model - raise error if invalid (required or wrong type)
|
|
7890
|
+
is_valid, error_str = self.validate_primary(self.primary)
|
|
7891
|
+
if not is_valid:
|
|
7892
|
+
raise TypeError(error_str)
|
|
7893
|
+
is_valid, error_str = self.validate_secondary(self.secondary)
|
|
7894
|
+
if not is_valid:
|
|
7895
|
+
raise TypeError(error_str)
|
|
7896
|
+
|
|
7897
|
+
def parse_set_robot_frame_request(data: object):
|
|
7898
|
+
return SetRobotFrameRequest(
|
|
7899
|
+
primary=parse_robot_frame(data["primary"]) if "primary" in data and data.get("primary") is not None else None,
|
|
7900
|
+
secondary=parse_secondary_bot_robot_frame(data["secondary"]) if "secondary" in data and data.get("secondary") is not None else None,
|
|
7901
|
+
)
|
|
7902
|
+
|
|
7903
|
+
def serialize_set_robot_frame_request(data: SetRobotFrameRequest) -> object:
|
|
7904
|
+
return {
|
|
7905
|
+
"primary": serialize_robot_frame(data.primary),
|
|
7906
|
+
"secondary": None if data.secondary is None else serialize_secondary_bot_robot_frame(data.secondary),
|
|
7907
|
+
}
|
|
7908
|
+
|
|
7630
7909
|
@dataclass
|
|
7631
7910
|
class SensorsConfiguration:
|
|
7632
7911
|
"""Configuration of all sensors defined in custom equipment"""
|
|
@@ -8189,6 +8468,7 @@ class RecorderConfig:
|
|
|
8189
8468
|
offset: Union[OffsetConfig, None] = None
|
|
8190
8469
|
sensors: Union[SensorConfigList, None] = None
|
|
8191
8470
|
equipmentKeyAssignments: Union[EquipmentKeyAssignments, None] = None
|
|
8471
|
+
tags: Union[StringArray, None] = None
|
|
8192
8472
|
|
|
8193
8473
|
def validate_isSecondary(self, value: bool) -> Tuple[bool, str]:
|
|
8194
8474
|
if value is None:
|
|
@@ -8253,6 +8533,15 @@ class RecorderConfig:
|
|
|
8253
8533
|
|
|
8254
8534
|
return [True, ""]
|
|
8255
8535
|
|
|
8536
|
+
def validate_tags(self, value: StringArray) -> Tuple[bool, str]:
|
|
8537
|
+
if value is None:
|
|
8538
|
+
return [True, ""]
|
|
8539
|
+
|
|
8540
|
+
if not (isinstance(value, list) and all(isinstance(x, str) for x in value)):
|
|
8541
|
+
return [False, "tags must be of type StringArray for RecorderConfig, got " + type(value).__name__]
|
|
8542
|
+
|
|
8543
|
+
return [True, ""]
|
|
8544
|
+
|
|
8256
8545
|
def __post_init__(self):
|
|
8257
8546
|
# Type check incoming model - raise error if invalid (required or wrong type)
|
|
8258
8547
|
is_valid, error_str = self.validate_isSecondary(self.isSecondary)
|
|
@@ -8276,6 +8565,9 @@ class RecorderConfig:
|
|
|
8276
8565
|
is_valid, error_str = self.validate_equipmentKeyAssignments(self.equipmentKeyAssignments)
|
|
8277
8566
|
if not is_valid:
|
|
8278
8567
|
raise TypeError(error_str)
|
|
8568
|
+
is_valid, error_str = self.validate_tags(self.tags)
|
|
8569
|
+
if not is_valid:
|
|
8570
|
+
raise TypeError(error_str)
|
|
8279
8571
|
|
|
8280
8572
|
def parse_recorder_config(data: object):
|
|
8281
8573
|
return RecorderConfig(
|
|
@@ -8286,6 +8578,7 @@ def parse_recorder_config(data: object):
|
|
|
8286
8578
|
offset=parse_offset_config(data["offset"]) if "offset" in data and data.get("offset") is not None else None,
|
|
8287
8579
|
sensors=parse_sensor_config_list(data["sensors"]) if "sensors" in data and data.get("sensors") is not None else None,
|
|
8288
8580
|
equipmentKeyAssignments=parse_equipment_key_assignments(data["equipmentKeyAssignments"]) if "equipmentKeyAssignments" in data and data.get("equipmentKeyAssignments") is not None else None,
|
|
8581
|
+
tags=parse_string_array(data["tags"]) if "tags" in data and data.get("tags") is not None else None,
|
|
8289
8582
|
)
|
|
8290
8583
|
|
|
8291
8584
|
def serialize_recorder_config(data: RecorderConfig) -> object:
|
|
@@ -8297,6 +8590,7 @@ def serialize_recorder_config(data: RecorderConfig) -> object:
|
|
|
8297
8590
|
"offset": None if data.offset is None else serialize_offset_config(data.offset),
|
|
8298
8591
|
"sensors": None if data.sensors is None else serialize_sensor_config_list(data.sensors),
|
|
8299
8592
|
"equipmentKeyAssignments": None if data.equipmentKeyAssignments is None else serialize_equipment_key_assignments(data.equipmentKeyAssignments),
|
|
8593
|
+
"tags": None if data.tags is None else serialize_string_array(data.tags),
|
|
8300
8594
|
}
|
|
8301
8595
|
|
|
8302
8596
|
@dataclass
|
|
@@ -8838,6 +9132,9 @@ class TeleopState:
|
|
|
8838
9132
|
config: Union[TeleopConfig, None] = None
|
|
8839
9133
|
status: Union[TeleopStatus, None] = None
|
|
8840
9134
|
botsInSync: Union[bool, None] = None
|
|
9135
|
+
errors: Union[TeleopErrorArray, None] = None
|
|
9136
|
+
gripperBounds: Union[GripperBounds, None] = None
|
|
9137
|
+
robotFrame: Union[RobotFrame, None] = None
|
|
8841
9138
|
|
|
8842
9139
|
def validate_config(self, value: TeleopConfig) -> Tuple[bool, str]:
|
|
8843
9140
|
if value is None:
|
|
@@ -8866,6 +9163,33 @@ class TeleopState:
|
|
|
8866
9163
|
|
|
8867
9164
|
return [True, ""]
|
|
8868
9165
|
|
|
9166
|
+
def validate_errors(self, value: TeleopErrorArray) -> Tuple[bool, str]:
|
|
9167
|
+
if value is None:
|
|
9168
|
+
return [True, ""]
|
|
9169
|
+
|
|
9170
|
+
if not (isinstance(value, list) and all(isinstance(x, str) for x in value)):
|
|
9171
|
+
return [False, "errors must be of type TeleopErrorArray for TeleopState, got " + type(value).__name__]
|
|
9172
|
+
|
|
9173
|
+
return [True, ""]
|
|
9174
|
+
|
|
9175
|
+
def validate_gripperBounds(self, value: GripperBounds) -> Tuple[bool, str]:
|
|
9176
|
+
if value is None:
|
|
9177
|
+
return [True, ""]
|
|
9178
|
+
|
|
9179
|
+
if not isinstance(value, GripperBounds):
|
|
9180
|
+
return [False, "gripperBounds must be of type GripperBounds for TeleopState, got " + type(value).__name__]
|
|
9181
|
+
|
|
9182
|
+
return [True, ""]
|
|
9183
|
+
|
|
9184
|
+
def validate_robotFrame(self, value: RobotFrame) -> Tuple[bool, str]:
|
|
9185
|
+
if value is None:
|
|
9186
|
+
return [True, ""]
|
|
9187
|
+
|
|
9188
|
+
if not ((isinstance(value, str) and RobotFrame in ['world', 'tooltip']) or isinstance(value, RobotFrame)):
|
|
9189
|
+
return [False, "robotFrame must be of type RobotFrame for TeleopState, got " + type(value).__name__]
|
|
9190
|
+
|
|
9191
|
+
return [True, ""]
|
|
9192
|
+
|
|
8869
9193
|
def __post_init__(self):
|
|
8870
9194
|
# Type check incoming model - raise error if invalid (required or wrong type)
|
|
8871
9195
|
is_valid, error_str = self.validate_config(self.config)
|
|
@@ -8877,12 +9201,24 @@ class TeleopState:
|
|
|
8877
9201
|
is_valid, error_str = self.validate_botsInSync(self.botsInSync)
|
|
8878
9202
|
if not is_valid:
|
|
8879
9203
|
raise TypeError(error_str)
|
|
9204
|
+
is_valid, error_str = self.validate_errors(self.errors)
|
|
9205
|
+
if not is_valid:
|
|
9206
|
+
raise TypeError(error_str)
|
|
9207
|
+
is_valid, error_str = self.validate_gripperBounds(self.gripperBounds)
|
|
9208
|
+
if not is_valid:
|
|
9209
|
+
raise TypeError(error_str)
|
|
9210
|
+
is_valid, error_str = self.validate_robotFrame(self.robotFrame)
|
|
9211
|
+
if not is_valid:
|
|
9212
|
+
raise TypeError(error_str)
|
|
8880
9213
|
|
|
8881
9214
|
def parse_teleop_state(data: object):
|
|
8882
9215
|
return TeleopState(
|
|
8883
9216
|
config=parse_teleop_config(data["config"]) if "config" in data and data.get("config") is not None else None,
|
|
8884
9217
|
status=parse_teleop_status(data["status"]) if "status" in data and data.get("status") is not None else None,
|
|
8885
9218
|
botsInSync=parse_bool(data["botsInSync"]) if "botsInSync" in data and data.get("botsInSync") is not None else None,
|
|
9219
|
+
errors=parse_teleop_error_array(data["errors"]) if "errors" in data and data.get("errors") is not None else None,
|
|
9220
|
+
gripperBounds=parse_gripper_bounds(data["gripperBounds"]) if "gripperBounds" in data and data.get("gripperBounds") is not None else None,
|
|
9221
|
+
robotFrame=parse_robot_frame(data["robotFrame"]) if "robotFrame" in data and data.get("robotFrame") is not None else None,
|
|
8886
9222
|
)
|
|
8887
9223
|
|
|
8888
9224
|
def serialize_teleop_state(data: TeleopState) -> object:
|
|
@@ -8890,6 +9226,9 @@ def serialize_teleop_state(data: TeleopState) -> object:
|
|
|
8890
9226
|
"config": None if data.config is None else serialize_teleop_config(data.config),
|
|
8891
9227
|
"status": None if data.status is None else serialize_teleop_status(data.status),
|
|
8892
9228
|
"botsInSync": None if data.botsInSync is None else serialize_bool(data.botsInSync),
|
|
9229
|
+
"errors": None if data.errors is None else serialize_teleop_error_array(data.errors),
|
|
9230
|
+
"gripperBounds": None if data.gripperBounds is None else serialize_gripper_bounds(data.gripperBounds),
|
|
9231
|
+
"robotFrame": None if data.robotFrame is None else serialize_robot_frame(data.robotFrame),
|
|
8893
9232
|
}
|
|
8894
9233
|
|
|
8895
9234
|
@dataclass
|
|
@@ -9071,6 +9410,7 @@ class StopRecordingResponse:
|
|
|
9071
9410
|
state: Union[RecorderState, None] = None
|
|
9072
9411
|
startTimestamp: Union[str, None] = None
|
|
9073
9412
|
endTimestamp: Union[str, None] = None
|
|
9413
|
+
status: Union[RecorderStatus, None] = None
|
|
9074
9414
|
|
|
9075
9415
|
def validate_state(self, value: RecorderState) -> Tuple[bool, str]:
|
|
9076
9416
|
if value is None:
|
|
@@ -9099,6 +9439,15 @@ class StopRecordingResponse:
|
|
|
9099
9439
|
|
|
9100
9440
|
return [True, ""]
|
|
9101
9441
|
|
|
9442
|
+
def validate_status(self, value: RecorderStatus) -> Tuple[bool, str]:
|
|
9443
|
+
if value is None:
|
|
9444
|
+
return [True, ""]
|
|
9445
|
+
|
|
9446
|
+
if not ((isinstance(value, str) and RecorderStatus in ['not_recording', 'recording', 'error', 'complete', 'initializing']) or isinstance(value, RecorderStatus)):
|
|
9447
|
+
return [False, "status must be of type RecorderStatus for StopRecordingResponse, got " + type(value).__name__]
|
|
9448
|
+
|
|
9449
|
+
return [True, ""]
|
|
9450
|
+
|
|
9102
9451
|
def __post_init__(self):
|
|
9103
9452
|
# Type check incoming model - raise error if invalid (required or wrong type)
|
|
9104
9453
|
is_valid, error_str = self.validate_state(self.state)
|
|
@@ -9110,12 +9459,16 @@ class StopRecordingResponse:
|
|
|
9110
9459
|
is_valid, error_str = self.validate_endTimestamp(self.endTimestamp)
|
|
9111
9460
|
if not is_valid:
|
|
9112
9461
|
raise TypeError(error_str)
|
|
9462
|
+
is_valid, error_str = self.validate_status(self.status)
|
|
9463
|
+
if not is_valid:
|
|
9464
|
+
raise TypeError(error_str)
|
|
9113
9465
|
|
|
9114
9466
|
def parse_stop_recording_response(data: object):
|
|
9115
9467
|
return StopRecordingResponse(
|
|
9116
9468
|
state=parse_recorder_state(data["state"]) if "state" in data and data.get("state") is not None else None,
|
|
9117
9469
|
startTimestamp=parse_str(data["startTimestamp"]) if "startTimestamp" in data and data.get("startTimestamp") is not None else None,
|
|
9118
9470
|
endTimestamp=parse_str(data["endTimestamp"]) if "endTimestamp" in data and data.get("endTimestamp") is not None else None,
|
|
9471
|
+
status=parse_recorder_status(data["status"]) if "status" in data and data.get("status") is not None else None,
|
|
9119
9472
|
)
|
|
9120
9473
|
|
|
9121
9474
|
def serialize_stop_recording_response(data: StopRecordingResponse) -> object:
|
|
@@ -9123,6 +9476,7 @@ def serialize_stop_recording_response(data: StopRecordingResponse) -> object:
|
|
|
9123
9476
|
"state": None if data.state is None else serialize_recorder_state(data.state),
|
|
9124
9477
|
"startTimestamp": None if data.startTimestamp is None else serialize_str(data.startTimestamp),
|
|
9125
9478
|
"endTimestamp": None if data.endTimestamp is None else serialize_str(data.endTimestamp),
|
|
9479
|
+
"status": None if data.status is None else serialize_recorder_status(data.status),
|
|
9126
9480
|
}
|
|
9127
9481
|
|
|
9128
9482
|
@dataclass
|
|
@@ -1231,7 +1231,7 @@ class TestPostMovementPositionArm:
|
|
|
1231
1231
|
|
|
1232
1232
|
target_position_res = client.movement.position.get_arm_position()
|
|
1233
1233
|
target_joint_pose_rounded = tuple(
|
|
1234
|
-
round(val,
|
|
1234
|
+
round(val, 2) for val in target_position_res.data.joint_rotations
|
|
1235
1235
|
)
|
|
1236
1236
|
|
|
1237
1237
|
# check if robot successfully moved to target pose
|
|
@@ -1246,7 +1246,7 @@ class TestPostMovementPositionArm:
|
|
|
1246
1246
|
initial_position_res = client.movement.position.get_arm_position()
|
|
1247
1247
|
|
|
1248
1248
|
initial_joint_pose_rounded = tuple(
|
|
1249
|
-
round(val,
|
|
1249
|
+
round(val, 2) for val in initial_position_res.data.joint_rotations
|
|
1250
1250
|
)
|
|
1251
1251
|
# check if pose correctly moved to initial pose
|
|
1252
1252
|
assert initial_joint_pose_rounded == initial_position
|
|
@@ -1266,7 +1266,7 @@ class TestPostMovementPositionArm:
|
|
|
1266
1266
|
initial_position = (0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
|
|
1267
1267
|
pose_res = client.movement.position.get_arm_position()
|
|
1268
1268
|
initial_joint_pose_rounded = tuple(
|
|
1269
|
-
round(val,
|
|
1269
|
+
round(val, 2) for val in pose_res.data.joint_rotations
|
|
1270
1270
|
)
|
|
1271
1271
|
|
|
1272
1272
|
# if robot is not in initial position, move it to initial position
|
|
@@ -1298,7 +1298,7 @@ class TestPostMovementPositionArm:
|
|
|
1298
1298
|
|
|
1299
1299
|
pose_res = client.movement.position.get_arm_position()
|
|
1300
1300
|
joint_pose_rounded = tuple(
|
|
1301
|
-
round(val,
|
|
1301
|
+
round(val, 2) for val in pose_res.data.joint_rotations
|
|
1302
1302
|
)
|
|
1303
1303
|
|
|
1304
1304
|
# check if robot successfully moved into initial pose
|
|
@@ -1346,9 +1346,9 @@ class TestPostMovementPositionArm:
|
|
|
1346
1346
|
pose_res = client.movement.position.get_arm_position()
|
|
1347
1347
|
target_tooltip = pose_res.data.tooltip_position.position
|
|
1348
1348
|
|
|
1349
|
-
assert approx_equal(target_tooltip.x, target_tooltip_position.x)
|
|
1350
|
-
assert approx_equal(target_tooltip.y, target_tooltip_position.y)
|
|
1351
|
-
assert approx_equal(target_tooltip.z, target_tooltip_position.z)
|
|
1349
|
+
assert approx_equal(target_tooltip.x, target_tooltip_position.x, 2)
|
|
1350
|
+
assert approx_equal(target_tooltip.y, target_tooltip_position.y, 2)
|
|
1351
|
+
assert approx_equal(target_tooltip.z, target_tooltip_position.z, 2)
|
|
1352
1352
|
|
|
1353
1353
|
pose_body = models.ArmPositionUpdateRequest(
|
|
1354
1354
|
kind=models.ArmPositionUpdateRequestKindEnum.TooltipPosition,
|
|
@@ -1369,9 +1369,9 @@ class TestPostMovementPositionArm:
|
|
|
1369
1369
|
pose_res = client.movement.position.get_arm_position()
|
|
1370
1370
|
tooltip_position = pose_res.data.tooltip_position.position
|
|
1371
1371
|
|
|
1372
|
-
assert approx_equal(tooltip_position.x, initial_tooltip_position.x)
|
|
1373
|
-
assert approx_equal(tooltip_position.y, initial_tooltip_position.y)
|
|
1374
|
-
assert approx_equal(tooltip_position.z, initial_tooltip_position.z)
|
|
1372
|
+
assert approx_equal(tooltip_position.x, initial_tooltip_position.x, 2)
|
|
1373
|
+
assert approx_equal(tooltip_position.y, initial_tooltip_position.y, 2)
|
|
1374
|
+
assert approx_equal(tooltip_position.z, initial_tooltip_position.z, 2)
|
|
1375
1375
|
|
|
1376
1376
|
def test_tooltip_positions_to_target_and_back(
|
|
1377
1377
|
self, client_live: StandardBotsRobot
|
|
@@ -2442,6 +2442,21 @@ class TestGetStatusHealthHealth:
|
|
|
2442
2442
|
assert res.health == models.StatusHealthEnum.Ok
|
|
2443
2443
|
|
|
2444
2444
|
|
|
2445
|
+
class TestGetSpaceGlobalSpaces:
|
|
2446
|
+
"""Tests: [GET] `/api/v1/space/globals`"""
|
|
2447
|
+
|
|
2448
|
+
def test_basic(self, client_live: StandardBotsRobot) -> None:
|
|
2449
|
+
"""Basic test"""
|
|
2450
|
+
client = client_live
|
|
2451
|
+
with client.connection():
|
|
2452
|
+
res = client.space.list_global_spaces()
|
|
2453
|
+
assert not res.isNotOk()
|
|
2454
|
+
data = res.data
|
|
2455
|
+
assert isinstance(data, models.SpacesPaginatedResponse)
|
|
2456
|
+
# Implied by test bed requirements
|
|
2457
|
+
assert len(data.items) >= 0
|
|
2458
|
+
|
|
2459
|
+
|
|
2445
2460
|
class TestGetSpacePlanes:
|
|
2446
2461
|
"""Tests: [GET] `/api/v1/space/planes`"""
|
|
2447
2462
|
|
|
@@ -3317,12 +3332,16 @@ class TestPostMovementPositionArmControlled:
|
|
|
3317
3332
|
assert not approx_equal(joint, target_position[i], 2), (
|
|
3318
3333
|
f"Joint {i} is approximately equal to target position (should not reach goal) (actual={joint}, expected={target_position[i]})"
|
|
3319
3334
|
)
|
|
3335
|
+
time.sleep(2)
|
|
3320
3336
|
|
|
3321
3337
|
# Now retrieve the failure
|
|
3322
3338
|
assert heartbeat_data.event is not None
|
|
3323
3339
|
assert heartbeat_data.event.kind == models.ArmPositionUpdateKindEnum.Failure
|
|
3324
3340
|
assert heartbeat_data.event.failure is not None
|
|
3325
|
-
assert
|
|
3341
|
+
assert (
|
|
3342
|
+
heartbeat_data.event.failure.reason
|
|
3343
|
+
== "Failed to generate a motion plan"
|
|
3344
|
+
)
|
|
3326
3345
|
|
|
3327
3346
|
def test_move_then_stop_heartbeat(
|
|
3328
3347
|
self,
|
|
File without changes
|
|
File without changes
|
{standardbots-2.0.0.dev1760378411 → standardbots-2.0.0.dev1763152552}/standardbots/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{standardbots-2.0.0.dev1760378411 → standardbots-2.0.0.dev1763152552}/tests/fixtures/__init__.py
RENAMED
|
File without changes
|
{standardbots-2.0.0.dev1760378411 → standardbots-2.0.0.dev1763152552}/tests/fixtures/client_fixt.py
RENAMED
|
File without changes
|
{standardbots-2.0.0.dev1760378411 → standardbots-2.0.0.dev1763152552}/tests/fixtures/robot_fixt.py
RENAMED
|
File without changes
|
|
File without changes
|