nova.types
1from typing import AsyncIterator, Callable 2 3from nova import api 4from nova.types.motion_settings import MotionSettings 5from nova.types.pose import Pose 6from nova.types.state import MotionState, RobotState 7from nova.types.vector3d import Vector3d 8 9LoadPlanResponse = api.models.PlanSuccessfulResponse 10InitialMovementStream = AsyncIterator[api.models.StreamMoveResponse] 11InitialMovementConsumer = Callable[[api.models.StreamMoveResponse], None] 12MovementResponse = api.models.ExecuteTrajectoryResponse | api.models.StreamMoveResponse 13ExecuteTrajectoryRequestStream = AsyncIterator[api.models.ExecuteTrajectoryRequest] 14ExecuteTrajectoryResponseStream = AsyncIterator[api.models.ExecuteTrajectoryResponse] 15MovementControllerFunction = Callable[ 16 [ExecuteTrajectoryResponseStream], ExecuteTrajectoryRequestStream 17] 18 19__all__ = [ 20 "Vector3d", 21 "Pose", 22 "CollisionScene", 23 "LoadPlanResponse", 24 "InitialMovementStream", 25 "InitialMovementConsumer", 26 "MovementResponse", 27 "MotionState", 28 "RobotState", 29 "MotionSettings", 30 "ExecuteTrajectoryRequestStream", 31 "ExecuteTrajectoryResponseStream", 32 "MovementControllerFunction", 33]
class
Vector3d(pydantic.main.BaseModel):
11class Vector3d(pydantic.BaseModel): 12 """A vector 3d class 13 Examples: 14 >>> Vector3d(x=10, y=20, z=30) 15 Vector3d(x=10, y=20, z=30) 16 """ 17 18 x: float | int 19 y: float | int 20 z: float | int 21 22 def __eq__(self, other): 23 if not isinstance(other, Vector3d): 24 return NotImplemented 25 return self.x == other.x and self.y == other.y and self.z == other.z 26 27 def __neg__(self) -> Vector3d: 28 return type(self)(x=-self.x, y=-self.y, z=-self.z) 29 30 def __add__(self, other: Any) -> Vector3d: 31 if isinstance(other, (float, int)): 32 return type(self)(x=self.x + other, y=self.y + other, z=self.z + other) 33 if isinstance(other, Vector3d): 34 return type(self)(x=self.x + other.x, y=self.y + other.y, z=self.z + other.z) 35 return NotImplemented 36 37 def __radd__(self, other: Any) -> Vector3d: 38 return self.__add__(other) 39 40 def __sub__(self, other: Any) -> Vector3d: 41 return self.__add__(-other) 42 43 def __rsub__(self, other: Any) -> Vector3d: 44 if isinstance(other, (float, int)): 45 return type(self)(x=other - self.x, y=other - self.y, z=other - self.z) 46 if isinstance(other, Vector3d): 47 return type(self)(x=other.x - self.x, y=other.y - self.y, z=other.z - self.z) 48 return NotImplemented 49 50 def __mul__(self, other: Any) -> Vector3d: 51 if isinstance(other, (float, int)): 52 return type(self)(x=other * self.x, y=other * self.y, z=other * self.z) 53 return NotImplemented 54 55 def __rmul__(self, other: Any) -> Vector3d: 56 return self * other 57 58 def __truediv__(self, other: Any) -> Vector3d: 59 if not isinstance(other, (float, int)): 60 return NotImplemented 61 return (1 / other) * self 62 63 def __len__(self): 64 return 3 65 66 def __iter__(self): 67 """Iterate over the vector 68 69 Examples: 70 >>> v = Vector3d(x=1, y=2, z=3) 71 >>> list(v) 72 [1, 2, 3] 73 >>> tuple(v) 74 (1, 2, 3) 75 """ 76 return iter(self.to_tuple()) 77 78 def __getitem__(self, item): 79 return self.to_tuple()[item] 80 81 @classmethod 82 def from_tuple(cls, value: tuple[float, float, float]) -> Vector3d: 83 """Create a new Vector3d from tuple 84 85 Examples: 86 >>> Vector3d.from_tuple((10, 20, 30)) 87 Vector3d(x=10, y=20, z=30) 88 >>> Vector3d.from_tuple((10.0, 20.5, 30.2)) 89 Vector3d(x=10.0, y=20.5, z=30.2) 90 """ 91 return cls(x=value[0], y=value[1], z=value[2]) 92 93 def to_tuple(self) -> tuple[float, float, float]: 94 """Return the vector as a tuple 95 96 Examples: 97 >>> Vector3d(x=10, y=20, z=30).to_tuple() 98 (10, 20, 30) 99 >>> Vector3d(x=10.0, y=20.5, z=30.2).to_tuple() 100 (10.0, 20.5, 30.2) 101 """ 102 return self.x, self.y, self.z 103 104 def __array__(self, dtype=None): 105 """Allows numpy to automatically convert Vector3d to a numeric array. 106 107 Examples: 108 >>> v1 = Vector3d(x=1.0, y=2.0, z=3.0) 109 >>> v2 = Vector3d(x=1.001, y=2.0, z=3.0) 110 >>> np.isclose(v1, v2, atol=1e-3) 111 array([ True, True, True]) 112 """ 113 return np.array(self.to_tuple(), dtype=dtype) 114 115 def to_quaternion(self): 116 """Interpret the object as a rotation vector and convert it to a quaternion""" 117 values = np.asarray(self) 118 half_angle = np.linalg.norm(values) / 2 119 return np.concatenate([np.cos(half_angle)[None], values * np.sinc(half_angle / np.pi) / 2]) 120 121 @pydantic.model_serializer 122 def serialize_model(self) -> wb.models.Vector3d: 123 """ 124 Examples: 125 >>> Vector3d.from_tuple((1, 2, 3)).model_dump() 126 {'x': 1, 'y': 2, 'z': 3} 127 """ 128 return wb.models.Vector3d(x=self.x, y=self.y, z=self.z)
A vector 3d class Examples:
>>> Vector3d(x=10, y=20, z=30)
Vector3d(x=10, y=20, z=30)
81 @classmethod 82 def from_tuple(cls, value: tuple[float, float, float]) -> Vector3d: 83 """Create a new Vector3d from tuple 84 85 Examples: 86 >>> Vector3d.from_tuple((10, 20, 30)) 87 Vector3d(x=10, y=20, z=30) 88 >>> Vector3d.from_tuple((10.0, 20.5, 30.2)) 89 Vector3d(x=10.0, y=20.5, z=30.2) 90 """ 91 return cls(x=value[0], y=value[1], z=value[2])
Create a new Vector3d from tuple
Examples:
>>> Vector3d.from_tuple((10, 20, 30))
Vector3d(x=10, y=20, z=30)
>>> Vector3d.from_tuple((10.0, 20.5, 30.2))
Vector3d(x=10.0, y=20.5, z=30.2)
def
to_tuple(self) -> tuple[float, float, float]:
93 def to_tuple(self) -> tuple[float, float, float]: 94 """Return the vector as a tuple 95 96 Examples: 97 >>> Vector3d(x=10, y=20, z=30).to_tuple() 98 (10, 20, 30) 99 >>> Vector3d(x=10.0, y=20.5, z=30.2).to_tuple() 100 (10.0, 20.5, 30.2) 101 """ 102 return self.x, self.y, self.z
Return the vector as a tuple
Examples:
>>> Vector3d(x=10, y=20, z=30).to_tuple()
(10, 20, 30)
>>> Vector3d(x=10.0, y=20.5, z=30.2).to_tuple()
(10.0, 20.5, 30.2)
def
to_quaternion(self):
115 def to_quaternion(self): 116 """Interpret the object as a rotation vector and convert it to a quaternion""" 117 values = np.asarray(self) 118 half_angle = np.linalg.norm(values) / 2 119 return np.concatenate([np.cos(half_angle)[None], values * np.sinc(half_angle / np.pi) / 2])
Interpret the object as a rotation vector and convert it to a quaternion
@pydantic.model_serializer
def
serialize_model(self) -> wandelbots_api_client.models.vector3d.Vector3d:
121 @pydantic.model_serializer 122 def serialize_model(self) -> wb.models.Vector3d: 123 """ 124 Examples: 125 >>> Vector3d.from_tuple((1, 2, 3)).model_dump() 126 {'x': 1, 'y': 2, 'z': 3} 127 """ 128 return wb.models.Vector3d(x=self.x, y=self.y, z=self.z)
Examples:
>>> Vector3d.from_tuple((1, 2, 3)).model_dump()
{'x': 1, 'y': 2, 'z': 3}
class
Pose(pydantic.main.BaseModel, typing.Sized):
40class Pose(pydantic.BaseModel, Sized): 41 """A pose (position and orientation) 42 43 Example: 44 >>> Pose(position=Vector3d(x=10, y=20, z=30), orientation=Vector3d(x=1, y=2, z=3)) 45 Pose(position=Vector3d(x=10, y=20, z=30), orientation=Vector3d(x=1, y=2, z=3)) 46 """ 47 48 position: Vector3d 49 orientation: Vector3d 50 51 def __init__(self, *args, **kwargs): 52 """Parse a tuple into a dict 53 54 Examples: 55 >>> Pose((1, 2, 3, 4, 5, 6)) 56 Pose(position=Vector3d(x=1, y=2, z=3), orientation=Vector3d(x=4, y=5, z=6)) 57 >>> Pose((1, 2, 3)) 58 Pose(position=Vector3d(x=1, y=2, z=3), orientation=Vector3d(x=0, y=0, z=0)) 59 >>> Pose(wb.models.Pose(position=wb.models.Vector3d(x=1, y=2, z=3), orientation=wb.models.Vector3d(x=4, y=5, z=6))) 60 Pose(position=Vector3d(x=1, y=2, z=3), orientation=Vector3d(x=4, y=5, z=6)) 61 >>> Pose(wb.models.TcpPose(position=wb.models.Vector3d(x=1, y=2, z=3), orientation=wb.models.Vector3d(x=4, y=5, z=6), coordinate_system=None, tcp='Flange')) 62 Pose(position=Vector3d(x=1, y=2, z=3), orientation=Vector3d(x=4, y=5, z=6)) 63 >>> Pose(wb.models.Pose2(position=[1, 2, 3], orientation=[4, 5, 6])) 64 Pose(position=Vector3d(x=1, y=2, z=3), orientation=Vector3d(x=4, y=5, z=6)) 65 >>> pose = Pose((1, 2, 3, 4, 5, 6)) 66 >>> new_pose = Pose.model_validate(pose.model_dump()) 67 >>> pose == new_pose 68 True 69 70 """ 71 if args: 72 values = _parse_args(*args) 73 super().__init__(**values) 74 else: 75 super().__init__(**kwargs) 76 77 def __str__(self): 78 return str(round(self).to_tuple()) 79 80 def __eq__(self, other): 81 if not isinstance(other, Pose): 82 return NotImplemented 83 return self.position == other.position and self.orientation == other.orientation 84 85 def __round__(self, n=None): 86 if n is not None: 87 raise NotImplementedError("Setting precision is not supported yet") 88 pos_and_rot_vector = self.to_tuple() 89 return Pose( 90 tuple( 91 [round(a, 1) for a in pos_and_rot_vector[:3]] 92 + [round(a, 3) for a in pos_and_rot_vector[3:]] 93 ) 94 ) 95 96 def __len__(self): 97 return 6 98 99 def __iter__(self): 100 """Iterate over the pose 101 102 Examples: 103 >>> p = Pose((1, 2, 3, 0, 0, 0)) 104 >>> list(p) 105 [1, 2, 3, 0, 0, 0] 106 >>> tuple(p) 107 (1, 2, 3, 0, 0, 0) 108 """ 109 return iter(self.to_tuple()) 110 111 def __invert__(self) -> Pose: 112 """ 113 Return the inverse of this pose. 114 In terms of 4x4 homogeneous matrices, this is T^-1 where T = R|p 115 0|1 116 i.e. T^-1 = R^T | -R^T p 117 0 | 1 118 119 Returns: 120 Pose: the inverse of the current pose 121 122 Examples: 123 >>> p = Pose((1, 2, 3, 0, 0, np.pi/2)) # rotate 90° about Z 124 >>> inv_p = ~p 125 >>> identity_approx = p @ inv_p 126 >>> np.allclose(identity_approx.position.to_tuple(), (0, 0, 0), atol=1e-7) 127 True 128 """ 129 # Invert the homogeneous transformation matrix 130 inv_matrix = np.linalg.inv(self.matrix) 131 # Convert back to a Pose 132 return self._matrix_to_pose(inv_matrix) 133 134 def to_tuple(self) -> tuple[float, float, float, float, float, float]: 135 """Return the pose as a tuple 136 137 Example: 138 >>> Pose(position=Vector3d(x=10, y=20, z=30), orientation=Vector3d(x=1, y=2, z=3)).to_tuple() 139 (10, 20, 30, 1, 2, 3) 140 """ 141 return self.position.to_tuple() + self.orientation.to_tuple() 142 143 def __getitem__(self, item): 144 return self.to_tuple()[item] 145 146 def __matmul__(self, other): 147 """ 148 Pose concatenation combines two poses into a single pose that represents the cumulative effect of both 149 transformations applied sequentially. 150 151 Args: 152 other: can be a Pose, or an iterable with 6 elements 153 154 Returns: 155 Pose: the result of the concatenation 156 157 Examples: 158 >>> Pose((1, 2, 3, 0, 0, 0)) @ Pose((1, 2, 3, 0, 0, 0)) 159 Pose(position=Vector3d(x=2.0, y=4.0, z=6.0), orientation=Vector3d(x=0.0, y=0.0, z=0.0)) 160 >>> Pose((1, 2, 3, 0, 0, 0)) @ [1, 2, 3, 0, 0, 0] 161 Pose(position=Vector3d(x=2.0, y=4.0, z=6.0), orientation=Vector3d(x=0.0, y=0.0, z=0.0)) 162 >>> Pose((1, 2, 3, 0, 0, 0)) @ (1, 2, 3, 0, 0, 0) 163 Pose(position=Vector3d(x=2.0, y=4.0, z=6.0), orientation=Vector3d(x=0.0, y=0.0, z=0.0)) 164 >>> def as_iterator(data): 165 ... for d in data: 166 ... yield d 167 >>> Pose((1, 2, 3, 0, 0, 0)) @ as_iterator([1, 2, 3, 0, 0, 0]) 168 Pose(position=Vector3d(x=2.0, y=4.0, z=6.0), orientation=Vector3d(x=0.0, y=0.0, z=0.0)) 169 >>> Pose((1, 2, 3, 0, 0, 0)) @ Vector3d.from_tuple((1, 2, 3)) 170 Pose(position=Vector3d(x=2.0, y=4.0, z=6.0), orientation=Vector3d(x=0.0, y=0.0, z=0.0)) 171 """ 172 if isinstance(other, Pose): 173 transformed_matrix = np.dot(self.matrix, other.matrix) 174 return self._matrix_to_pose(transformed_matrix) 175 if isinstance(other, Iterable): 176 seq = tuple(other) 177 return self.__matmul__(Pose(seq)) 178 179 raise ValueError(f"Cannot multiply Pose with {type(other)}") 180 181 def __array__(self, dtype=None): 182 """Convert Pose to a 6-element numpy array: [pos.x, pos.y, pos.z, ori.x, ori.y, ori.z]. 183 184 Examples: 185 >>> p1 = Pose((1.0, 2.0, 3.0, 4.0, 5.0, 6.0)) 186 >>> p2 = Pose((1.001, 2.0, 3.0, 3.9995, 5.0, 6.0)) 187 >>> np.isclose(p1, p2, atol=1e-3) 188 array([ True, True, True, True, True, True]) 189 """ 190 # The `to_tuple()` method already returns (x, y, z, rx, ry, rz) 191 return np.array(self.to_tuple(), dtype=dtype) 192 193 def transform(self, other) -> Pose: 194 return self @ other 195 196 def _to_wb_pose(self) -> wb.models.Pose: 197 """Convert to wandelbots_api_client Pose 198 199 Examples: 200 >>> Pose(position=Vector3d(x=10, y=20, z=30), orientation=Vector3d(x=1, y=2, z=3))._to_wb_pose() 201 Pose(position=Vector3d(x=10, y=20, z=30), orientation=Vector3d(x=1, y=2, z=3), coordinate_system=None) 202 """ 203 return wb.models.Pose( 204 position=wb.models.Vector3d(**self.position.model_dump()), 205 orientation=wb.models.Vector3d(**self.orientation.model_dump()), 206 ) 207 208 def _to_wb_pose2(self) -> wb.models.Pose2: 209 """Convert to wandelbots_api_client Pose 210 211 Examples: 212 >>> Pose(position=Vector3d(x=10, y=20, z=30), orientation=Vector3d(x=1, y=2, z=3))._to_wb_pose2() 213 Pose2(position=[10, 20, 30], orientation=[1, 2, 3]) 214 """ 215 return wb.models.Pose2( 216 position=list(self.position.to_tuple()), orientation=list(self.orientation.to_tuple()) 217 ) 218 219 @pydantic.model_serializer 220 def serialize_model(self): 221 """ 222 Examples: 223 >>> Pose(position=Vector3d(x=10, y=20, z=30), orientation=Vector3d(x=1, y=2, z=3)).model_dump() 224 {'position': [10, 20, 30], 'orientation': [1, 2, 3]} 225 """ 226 return self._to_wb_pose2().model_dump() 227 228 @pydantic.model_validator(mode="before") 229 @classmethod 230 def model_validator(cls, data): 231 """Transform the data that is passed into model validator to match what we return in the model_dump""" 232 if not isinstance(data, dict): 233 raise ValueError("model_validator only accepts dicts") 234 pos = data["position"] 235 ori = data["orientation"] 236 return { 237 "position": Vector3d(x=pos[0], y=pos[1], z=pos[2]), 238 "orientation": Vector3d(x=ori[0], y=ori[1], z=ori[2]), 239 } 240 241 def _to_homogenous_transformation_matrix(self): 242 """Converts the pose (position and rotation vector) to a 4x4 homogeneous transformation matrix.""" 243 rotation_vec = [self.orientation.x, self.orientation.y, self.orientation.z] 244 rotation_matrix = Rotation.from_rotvec(rotation_vec).as_matrix() 245 mat = np.eye(4) 246 mat[:3, :3] = rotation_matrix 247 mat[:3, 3] = [self.position.x, self.position.y, self.position.z] 248 return mat 249 250 def _matrix_to_pose(self, matrix: np.ndarray) -> Pose: 251 """Converts a homogeneous transformation matrix to a Pose.""" 252 rotation_matrix = matrix[:3, :3] 253 position = matrix[:3, 3] 254 rotation_vec = Rotation.from_matrix(rotation_matrix).as_rotvec() 255 return Pose( 256 ( 257 position[0], 258 position[1], 259 position[2], 260 rotation_vec[0], 261 rotation_vec[1], 262 rotation_vec[2], 263 ) 264 ) 265 266 def orientation_to_quaternion(self): 267 values = np.asarray(self.orientation) 268 half_angle = np.linalg.norm(values) / 2 269 return np.concatenate([np.cos(half_angle)[None], values * np.sinc(half_angle / np.pi) / 2]) 270 271 @property 272 def matrix(self) -> np.ndarray: 273 """Returns the homogeneous transformation matrix.""" 274 return self._to_homogenous_transformation_matrix()
A pose (position and orientation)
Example:
>>> Pose(position=Vector3d(x=10, y=20, z=30), orientation=Vector3d(x=1, y=2, z=3))
Pose(position=Vector3d(x=10, y=20, z=30), orientation=Vector3d(x=1, y=2, z=3))
position: Vector3d
orientation: Vector3d
def
to_tuple(self) -> tuple[float, float, float, float, float, float]:
134 def to_tuple(self) -> tuple[float, float, float, float, float, float]: 135 """Return the pose as a tuple 136 137 Example: 138 >>> Pose(position=Vector3d(x=10, y=20, z=30), orientation=Vector3d(x=1, y=2, z=3)).to_tuple() 139 (10, 20, 30, 1, 2, 3) 140 """ 141 return self.position.to_tuple() + self.orientation.to_tuple()
Return the pose as a tuple
Example:
>>> Pose(position=Vector3d(x=10, y=20, z=30), orientation=Vector3d(x=1, y=2, z=3)).to_tuple()
(10, 20, 30, 1, 2, 3)
@pydantic.model_serializer
def
serialize_model(self):
219 @pydantic.model_serializer 220 def serialize_model(self): 221 """ 222 Examples: 223 >>> Pose(position=Vector3d(x=10, y=20, z=30), orientation=Vector3d(x=1, y=2, z=3)).model_dump() 224 {'position': [10, 20, 30], 'orientation': [1, 2, 3]} 225 """ 226 return self._to_wb_pose2().model_dump()
Examples:
>>> Pose(position=Vector3d(x=10, y=20, z=30), orientation=Vector3d(x=1, y=2, z=3)).model_dump()
{'position': [10, 20, 30], 'orientation': [1, 2, 3]}
@pydantic.model_validator(mode='before')
@classmethod
def
model_validator(cls, data):
228 @pydantic.model_validator(mode="before") 229 @classmethod 230 def model_validator(cls, data): 231 """Transform the data that is passed into model validator to match what we return in the model_dump""" 232 if not isinstance(data, dict): 233 raise ValueError("model_validator only accepts dicts") 234 pos = data["position"] 235 ori = data["orientation"] 236 return { 237 "position": Vector3d(x=pos[0], y=pos[1], z=pos[2]), 238 "orientation": Vector3d(x=ori[0], y=ori[1], z=ori[2]), 239 }
Transform the data that is passed into model validator to match what we return in the model_dump
CollisionScene
LoadPlanResponse =
<class 'wandelbots_api_client.models.plan_successful_response.PlanSuccessfulResponse'>
InitialMovementStream =
typing.AsyncIterator[wandelbots_api_client.models.stream_move_response.StreamMoveResponse]
InitialMovementConsumer =
typing.Callable[[wandelbots_api_client.models.stream_move_response.StreamMoveResponse], NoneType]
MovementResponse =
wandelbots_api_client.models.execute_trajectory_response.ExecuteTrajectoryResponse | wandelbots_api_client.models.stream_move_response.StreamMoveResponse
class
MotionState(pydantic.main.BaseModel):
14class MotionState(pydantic.BaseModel): 15 """Collection of information on the current state of the robot""" 16 17 motion_group_id: str 18 path_parameter: float 19 state: RobotState
Collection of information on the current state of the robot
state: RobotState
class
RobotState(pydantic.main.BaseModel):
7class RobotState(pydantic.BaseModel): 8 """Collection of information on the current state of the robot""" 9 10 pose: Pose 11 joints: tuple[float, ...] | None = None
Collection of information on the current state of the robot
pose: Pose
class
MotionSettings(pydantic.main.BaseModel):
6class MotionSettings(pydantic.BaseModel): 7 """ 8 Settings for an action. This is closely related to the `MotionCommand` in the API. 9 See planTrajectory.motion_commands for more information. 10 11 Motion settings are immutable; if you need to change a setting, create a copy and update the new object. 12 13 Attributes: 14 min_blending_velocity: 15 A minimum velocity for blending, in percent. Cannot be used if `blending` is set. 16 17 position_zone_radius: 18 Defines the position zone radius. 19 20 joint_velocity_limits: 21 Maximum joint velocities 22 23 joint_acceleration_limits: 24 Maximum joint accelerations 25 26 tcp_velocity_limit: 27 Maximum TCP velocity 28 29 tcp_acceleration_limit: 30 Maximum TCP acceleration 31 32 tcp_orientation_velocity_limit: 33 Maximum TCP orientation velocity 34 35 tcp_orientation_acceleration_limit: 36 Maximum TCP orientation acceleration 37 """ 38 39 min_blending_velocity: int | None = pydantic.Field(default=None) 40 position_zone_radius: float | None = pydantic.Field(default=None) 41 joint_velocity_limits: tuple[float, ...] | None = pydantic.Field(default=None) 42 joint_acceleration_limits: tuple[float, ...] | None = pydantic.Field(default=None) 43 tcp_velocity_limit: float | None = pydantic.Field(default=50) 44 tcp_acceleration_limit: float | None = pydantic.Field(default=None) 45 tcp_orientation_velocity_limit: float | None = pydantic.Field(default=None) 46 tcp_orientation_acceleration_limit: float | None = pydantic.Field(default=None) 47 48 class Config: 49 frozen = True 50 51 @classmethod 52 def field_to_varname(cls, field): 53 return f"__ms_{field}" 54 55 @pydantic.model_validator(mode="after") 56 def validate_blending_settings(self) -> "MotionSettings": 57 if self.min_blending_velocity and self.position_zone_radius: 58 raise ValueError("Can't set both min_blending_velocity and blending") 59 return self 60 61 def has_blending_settings(self) -> bool: 62 return any([self.min_blending_velocity, self.position_zone_radius]) 63 64 def has_limits_override(self) -> bool: 65 return any( 66 [ 67 self.tcp_velocity_limit, 68 self.tcp_acceleration_limit, 69 self.tcp_orientation_velocity_limit, 70 self.tcp_orientation_acceleration_limit, 71 self.joint_velocity_limits, 72 self.joint_acceleration_limits, 73 ] 74 ) 75 76 def as_limits_settings(self) -> wb.models.LimitsOverride: 77 return wb.models.LimitsOverride( 78 joint_velocity_limits=wb.models.Joints(joints=self.joint_velocity_limits) # type: ignore 79 if self.joint_velocity_limits 80 else None, 81 joint_acceleration_limits=wb.models.Joints(joints=self.joint_acceleration_limits) # type: ignore 82 if self.joint_acceleration_limits 83 else None, 84 tcp_velocity_limit=self.tcp_velocity_limit, 85 tcp_acceleration_limit=self.tcp_acceleration_limit, 86 tcp_orientation_velocity_limit=self.tcp_orientation_velocity_limit, 87 tcp_orientation_acceleration_limit=self.tcp_orientation_acceleration_limit, 88 ) 89 90 def as_blending_setting(self) -> wb.models.MotionCommandBlending: 91 if self.position_zone_radius: 92 return wb.models.MotionCommandBlending( 93 wb.models.BlendingPosition( 94 position_zone_radius=self.position_zone_radius, blending_name="BlendingPosition" 95 ) 96 ) 97 return wb.models.MotionCommandBlending( 98 wb.models.BlendingAuto( 99 min_velocity_in_percent=self.min_blending_velocity, blending_name="BlendingAuto" 100 ) 101 )
Settings for an action. This is closely related to the MotionCommand
in the API.
See planTrajectory.motion_commands for more information.
Motion settings are immutable; if you need to change a setting, create a copy and update the new object.
Attributes:
- min_blending_velocity: A minimum velocity for blending, in percent. Cannot be used if
blending
is set. - position_zone_radius: Defines the position zone radius.
- joint_velocity_limits: Maximum joint velocities
- joint_acceleration_limits: Maximum joint accelerations
- tcp_velocity_limit: Maximum TCP velocity
- tcp_acceleration_limit: Maximum TCP acceleration
- tcp_orientation_velocity_limit: Maximum TCP orientation velocity
- tcp_orientation_acceleration_limit: Maximum TCP orientation acceleration
def
as_limits_settings(self) -> wandelbots_api_client.models.limits_override.LimitsOverride:
76 def as_limits_settings(self) -> wb.models.LimitsOverride: 77 return wb.models.LimitsOverride( 78 joint_velocity_limits=wb.models.Joints(joints=self.joint_velocity_limits) # type: ignore 79 if self.joint_velocity_limits 80 else None, 81 joint_acceleration_limits=wb.models.Joints(joints=self.joint_acceleration_limits) # type: ignore 82 if self.joint_acceleration_limits 83 else None, 84 tcp_velocity_limit=self.tcp_velocity_limit, 85 tcp_acceleration_limit=self.tcp_acceleration_limit, 86 tcp_orientation_velocity_limit=self.tcp_orientation_velocity_limit, 87 tcp_orientation_acceleration_limit=self.tcp_orientation_acceleration_limit, 88 )
def
as_blending_setting( self) -> wandelbots_api_client.models.motion_command_blending.MotionCommandBlending:
90 def as_blending_setting(self) -> wb.models.MotionCommandBlending: 91 if self.position_zone_radius: 92 return wb.models.MotionCommandBlending( 93 wb.models.BlendingPosition( 94 position_zone_radius=self.position_zone_radius, blending_name="BlendingPosition" 95 ) 96 ) 97 return wb.models.MotionCommandBlending( 98 wb.models.BlendingAuto( 99 min_velocity_in_percent=self.min_blending_velocity, blending_name="BlendingAuto" 100 ) 101 )
class
MotionSettings.Config:
ExecuteTrajectoryRequestStream =
typing.AsyncIterator[wandelbots_api_client.models.execute_trajectory_request.ExecuteTrajectoryRequest]
ExecuteTrajectoryResponseStream =
typing.AsyncIterator[wandelbots_api_client.models.execute_trajectory_response.ExecuteTrajectoryResponse]
MovementControllerFunction =
typing.Callable[[typing.AsyncIterator[wandelbots_api_client.models.execute_trajectory_response.ExecuteTrajectoryResponse]], typing.AsyncIterator[wandelbots_api_client.models.execute_trajectory_request.ExecuteTrajectoryRequest]]