Motion¶
Cartesian and joint corrections, trajectories, queues, geometric primitives, velocity profiles, blending and frame transforms.
Basics¶
# Cartesian corrections (RKorr) -- mm for XYZ, degrees for ABC
api.motion.update_cartesian(X=10.0, Y=-5.0, Z=0.0)
api.motion.update_cartesian(A=2.5, B=0.0, C=0.0)
# Joint corrections (AKorr) -- degrees
api.motion.update_joints(A1=5.0, A2=-3.0)
# Read current state
pose = api.motion.get_current_pose() # {X, Y, Z, A, B, C}
joints = api.motion.get_current_joints() # {A1, A2, A3, A4, A5, A6}
# External axes (value is a per-cycle delta under rsi_mode="relative" -- see Core Lifecycle)
api.motion.move_external_axis("E1", 2.5)
# Tech parameters (runtime motion adjustment)
api.motion.adjust_speed("Tech.T21", 0.5)
Trajectories¶
# Generate linear trajectory
traj = api.motion.generate_trajectory(
start={"X": 0, "Y": 0, "Z": 500},
end={"X": 100, "Y": 0, "Z": 500},
steps=50,
space="cartesian"
)
# Execute (blocking). cycles_per_step paces one waypoint per N robot cycles
# (3 * 4ms default cycle_time = one waypoint every 12ms here); in relative
# mode each waypoint's delta is spread evenly over those N cycles, so a slow
# move is smooth rather than a burst-and-pause. `rate=` (seconds/waypoint)
# still works but is deprecated in favor of cycles_per_step.
api.motion.execute_trajectory(traj, space="cartesian", cycles_per_step=3)
# Or generate + execute in one call (end_pose first, start_pose defaults to current position)
api.motion.move_cartesian_trajectory(
end_pose={"X": 100, "Y": 0, "Z": 500},
start_pose={"X": 0, "Y": 0, "Z": 500},
steps=50, cycles_per_step=5
)
api.motion.move_joint_trajectory(
end_joints={"A1": 30, "A2": -15, "A3": 45, "A4": 0, "A5": 30, "A6": 0},
start_joints={"A1": 0, "A2": 0, "A3": 0, "A4": 0, "A5": 0, "A6": 0},
steps=100, cycles_per_step=100
)
# Cancel a running trajectory from another thread
api.motion.cancel_trajectory()
Trajectory Queue¶
# Each leg is paced in robot cycles per waypoint, like execute_trajectory
# (50 steps x 10 cycles x 4 ms = 2 s). rate= still works but is deprecated.
api.motion.queue_cartesian_trajectory(p0, p1, steps=50, cycles_per_step=10)
api.motion.queue_cartesian_trajectory(p1, p2, steps=50, cycles_per_step=10)
api.motion.queue_joint_trajectory(j0, j1, steps=30, cycles_per_step=25)
print(api.motion.get_queue()) # [{space, steps, cycles_per_step, rate}, ...]
api.motion.execute_queued_trajectories() # Run all in sequence, then clear
api.motion.cancel_trajectory() # From another thread: stops the current leg
api.motion.clear_queue() # Discard without executing
Geometric Primitives¶
# Circular arc
arc = api.motion.generate_arc(
center={"X": 100, "Y": 0, "Z": 500},
radius=50.0,
start_angle=0, end_angle=90,
steps=50, plane="XY"
)
# Full circle
circle = api.motion.generate_circle(
center={"X": 100, "Y": 0, "Z": 500},
radius=50.0, steps=100, plane="XY"
)
# Spiral
spiral = api.motion.generate_spiral(
center={"X": 100, "Y": 0, "Z": 500},
start_radius=10.0, end_radius=50.0,
pitch=5.0, revolutions=5,
steps=200, plane="XY", axis="Z"
)
api.motion.execute_trajectory(arc, space="cartesian")
Velocity Profiles¶
traj = api.motion.generate_trajectory(p0, p1, steps=100)
# Trapezoidal (bang-bang acceleration)
profiled = api.motion.generate_velocity_profile(
traj, max_velocity=200.0, max_acceleration=500.0,
profile="trapezoidal"
)
# S-curve (jerk-limited, smoother)
profiled = api.motion.generate_velocity_profile(
traj, max_velocity=200.0, max_acceleration=500.0,
profile="s-curve"
)
# Each element is (waypoint_dict, velocity_float)
for waypoint, velocity in profiled:
print(f"Velocity: {velocity:.2f} mm/s")
Path Blending¶
traj1 = api.motion.generate_trajectory(p0, p1, 50)
traj2 = api.motion.generate_trajectory(p1, p2, 50)
blended = api.motion.blend_trajectories(
traj1, traj2,
blend_radius=10.0, # mm from junction
blend_steps=20
)
api.motion.execute_trajectory(blended)
Coordinate Transforms¶
world_pose = api.motion.transform_coordinates(
pose={"X": 100, "Y": 0, "Z": 500},
from_frame="BASE", to_frame="WORLD",
frame_offset={"X": 500, "Y": 200, "Z": 0}
)
Reference¶
MotionAPI
¶
Motion control interface for KUKA RSI robot control.
Provides Cartesian and joint-space motion commands, trajectory generation, execution, and queueing capabilities. All motion commands go through the SafetyManager validation layer.
Initialize MotionAPI namespace.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
RSIClient
|
RSIClient instance for variable access and safety management |
required |
update_cartesian
¶
Update Cartesian correction values (RKorr).
Applies corrections to TCP position in world coordinates. Values are added to the programmed path positions in the KRL program.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
**kwargs
|
float
|
Axis corrections in mm/degrees: - X, Y, Z: Position corrections (mm) - A, B, C: Orientation corrections (degrees) |
{}
|
Raises:
| Type | Description |
|---|---|
RSISafetyViolation
|
If corrections exceed configured limits |
Example
Move TCP 10mm in X direction¶
api.motion.update_cartesian(X=10.0)
Move in XYZ¶
api.motion.update_cartesian(X=5.0, Y=-3.0, Z=12.5)
Full 6-axis correction¶
api.motion.update_cartesian(X=10, Y=5, Z=0, A=0, B=0, C=2.5)
Note
RKorr must be configured in the RSI config file and enabled in KRL using RSI_MOVECORR() for corrections to take effect.
update_joints
¶
Update joint correction values (AKorr).
Applies corrections to individual joint angles. Values are added to the programmed joint positions in the KRL program.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
**kwargs
|
float
|
Joint corrections in degrees: - A1, A2, A3, A4, A5, A6: Joint angle corrections |
{}
|
Raises:
| Type | Description |
|---|---|
RSISafetyViolation
|
If corrections exceed configured limits |
Example
Adjust joint 1 by 5 degrees¶
api.motion.update_joints(A1=5.0)
Multi-axis correction¶
api.motion.update_joints(A1=10.0, A2=-5.0, A3=2.5)
Note
AKorr must be configured in the RSI config file and enabled in KRL using RSI_MOVECORR() for corrections to take effect.
get_current_pose
¶
Get current TCP position from robot.
Returns:
| Type | Description |
|---|---|
Dict[str, float]
|
Dict with X, Y, Z (mm) and A, B, C (degrees) |
get_current_joints
¶
Get current joint positions from robot.
Prefers AIPos (axis ACTUAL), mirroring get_current_pose()'s use of RIst rather than RSol. Verified on hardware: while RSI corrections are applied, ASPos holds the programmed setpoint and never reflects them, so a joint move computed from ASPos measures nothing and repeats its own delta. ASPos is only a fallback for configs that declare it alone.
Returns:
| Type | Description |
|---|---|
Dict[str, float]
|
Dict with A1-A6 in degrees |
correct_position
¶
Apply a single correction to RKorr or AKorr.
Lower-level method for explicit correction type and axis specification. Most users should use update_cartesian() or update_joints() instead.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
correction_type
|
str
|
'RKorr' or 'AKorr' |
required |
axis
|
str
|
Axis name (e.g., 'X', 'Y', 'Z' for RKorr; 'A1'-'A6' for AKorr) |
required |
value
|
float
|
Correction value |
required |
Returns:
| Type | Description |
|---|---|
str
|
Status message |
Raises:
| Type | Description |
|---|---|
RSISafetyViolation
|
If correction exceeds configured limits |
Example
api.motion.correct_position('RKorr', 'X', 10.0) 'Updated RKorr.X to 10.0' api.motion.correct_position('AKorr', 'A1', 5.0) 'Updated AKorr.A1 to 5.0'
move_external_axis
¶
Apply an external-axis correction (EKorr).
Controls additional axes beyond the standard 6 robot axes, such as positioners, linear tracks, or tool changers. Corrections are applied by the AXISCORREXT object in the RSI context; semantics follow the client's rsi_mode (per-cycle delta in relative, offset in absolute).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
axis
|
str
|
External axis name ('E1'..'E6') |
required |
value
|
float
|
Correction value (mm or degrees per axis configuration) |
required |
Returns:
| Type | Description |
|---|---|
str
|
Status message |
Raises:
| Type | Description |
|---|---|
RSIVariableError
|
If EKorr is not declared in the config's RECEIVE section (use the Full config/context) |
RSISafetyViolation
|
If value exceeds configured limits |
Example
api.motion.move_external_axis('E1', 2.5) 'Updated EKorr.E1 to 2.5'
adjust_speed
¶
Adjust motion parameters via Tech variables.
Tech variables allow runtime adjustment of motion parameters like velocity scaling, acceleration limits, or custom user parameters.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tech_param
|
str
|
Tech variable path (e.g., 'Tech.T21', 'Tech.C15') |
required |
value
|
float
|
Parameter value |
required |
Returns:
| Type | Description |
|---|---|
str
|
Status message |
Example
Adjust velocity override via Tech.T21¶
api.motion.adjust_speed('Tech.T21', 0.5) # 50% velocity 'Updated Tech.T21 to 0.5'
Note
Tech variable meanings depend on your KRL program implementation. Coordinate with your KRL developer on parameter assignments.
generate_trajectory
staticmethod
¶
generate_trajectory(start: Dict[str, float], end: Dict[str, float], steps: int = 100, space: str = 'cartesian', mode: str = 'absolute', include_resets: bool = False) -> List[Dict[str, float]]
Generate linear interpolated trajectory between two poses.
Creates a list of waypoints linearly interpolated between start and end positions. Supports both Cartesian and joint space.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start
|
Dict[str, float]
|
Starting pose (e.g., {"X":0, "Y":0, "Z":500}) |
required |
end
|
Dict[str, float]
|
Ending pose (e.g., {"X":100, "Y":0, "Z":500}) |
required |
steps
|
int
|
Number of interpolation points (default: 100) |
100
|
space
|
str
|
'cartesian' or 'joint' |
'cartesian'
|
mode
|
str
|
'absolute' → waypoints are full interpolated poses; 'relative' → waypoints are per-step deltas (execute with points='delta') |
'absolute'
|
include_resets
|
bool
|
Whether to reset to zero at end (default: False) |
False
|
Returns:
| Type | Description |
|---|---|
List[Dict[str, float]]
|
List of waypoint dictionaries |
Example
Cartesian trajectory¶
traj = api.motion.generate_trajectory( ... {"X":0, "Y":0, "Z":500}, ... {"X":100, "Y":0, "Z":500}, ... steps=50 ... ) len(traj) 50
Joint trajectory¶
traj = api.motion.generate_trajectory( ... {"A1":0, "A2":0, "A3":0}, ... {"A1":30, "A2":-15, "A3":45}, ... steps=100, ... space="joint" ... )
Note
This uses simple linear interpolation. For velocity-profiled trajectories, see Phase 4 enhancements (trapezoidal/S-curve).
execute_trajectory
¶
execute_trajectory(trajectory: List[Dict[str, float]], space: str = 'cartesian', rate: Optional[float] = None, cycles_per_step: int = 1, points: str = 'world') -> None
Execute a trajectory, blocking until complete.
Waypoints are paced against the robot's IPOC clock (one waypoint per
cycles_per_step robot cycles) — never wall-clock sleeps, which
cannot align with the 4ms/12ms cycle. Can be cancelled via
cancel_trajectory().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
trajectory
|
List[Dict[str, float]]
|
List of waypoint dictionaries |
required |
space
|
str
|
'cartesian' or 'joint' |
'cartesian'
|
rate
|
Optional[float]
|
DEPRECATED seconds-per-waypoint; mapped to cycles_per_step |
None
|
cycles_per_step
|
int
|
Robot cycles per waypoint (default 1) |
1
|
points
|
str
|
'world' (full poses, converted per rsi_mode) or 'delta' (per-cycle deltas from generate_trajectory(mode='relative'); requires rsi_mode='relative') |
'world'
|
Raises:
| Type | Description |
|---|---|
RSITrajectoryError
|
On invalid arguments or when a waypoint is not acknowledged (robot silent / E-stop / reconnect). |
execute_profiled_trajectory
¶
execute_profiled_trajectory(profiled: List[Tuple[Dict[str, float], float]], space: str = 'cartesian') -> None
Execute a velocity-profiled trajectory from generate_velocity_profile().
Converts (waypoint, velocity mm/s or deg/s) tuples into per-cycle waypoints — each segment's duration is distance/avg_velocity, resampled at the robot cycle time — then executes with IPOC-synchronized pacing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
profiled
|
List[Tuple[Dict[str, float], float]]
|
Output of generate_velocity_profile() |
required |
space
|
str
|
'cartesian' or 'joint' |
'cartesian'
|
Example
traj = api.motion.generate_trajectory(p0, p1, 100) profiled = api.motion.generate_velocity_profile( ... traj, max_velocity=200.0, max_acceleration=500.0) api.motion.execute_profiled_trajectory(profiled)
exit_movecorr
¶
End a sensor-guided RSI_MOVECORR() motion on the robot.
RSI_MOVECORR() blocks the KRL program: the robot is driven purely
by corrections and never reaches an end point, so without this the
program only continues when an operator cancels it. The shipped
contexts wire a STOP object (Mode=ExitMoveCorr) to a BOOL RECEIVE
channel; STOP triggers on a POSITIVE EDGE, so this sets the channel,
holds it briefly, then clears it ready for the next use.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
variable
|
str
|
RECEIVE variable wired to the STOP object |
'MoveStop'
|
hold
|
float
|
seconds to hold the signal (must span several robot cycles) |
0.1
|
Returns:
| Type | Description |
|---|---|
str
|
Status message |
Raises:
| Type | Description |
|---|---|
RSIVariableError
|
If the config declares no such variable — the context needs a STOP object (see controller/README.md) |
Example
api.motion.update_cartesian(X=0.0) # stop correcting first api.motion.exit_movecorr() 'RSI_MOVECORR cancelled via MoveStop'
move_cartesian_trajectory
¶
move_cartesian_trajectory(end_pose: Dict[str, float], start_pose: Optional[Dict[str, float]] = None, steps: int = 50, rate: Optional[float] = None, cycles_per_step: int = 1) -> None
Generate and execute Cartesian trajectory in one call.
Waypoints are generated in world space and converted to RKorr corrections per the client's rsi_mode (offsets from the programmed path in absolute mode; per-cycle deltas in relative mode) — world poses are never written into RKorr directly.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
end_pose
|
Dict[str, float]
|
Target Cartesian pose |
required |
start_pose
|
Optional[Dict[str, float]]
|
Starting pose (default: current robot position) |
None
|
steps
|
int
|
Number of waypoints (default: 50) |
50
|
rate
|
Optional[float]
|
DEPRECATED seconds-per-waypoint; mapped to cycles_per_step |
None
|
cycles_per_step
|
int
|
Robot cycles per waypoint (default 1) |
1
|
Example
Move to target from current position¶
api.motion.move_cartesian_trajectory({"X":100, "Y":0, "Z":500})
move_joint_trajectory
¶
move_joint_trajectory(end_joints: Dict[str, float], start_joints: Optional[Dict[str, float]] = None, steps: int = 50, rate: Optional[float] = None, cycles_per_step: int = 25) -> None
Generate and execute joint-space trajectory in one call.
Waypoints are generated in joint space and converted to AKorr corrections per the client's rsi_mode — absolute joint values are never written into AKorr directly.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
end_joints
|
Dict[str, float]
|
Target joint configuration |
required |
start_joints
|
Optional[Dict[str, float]]
|
Starting joints (default: current robot joints) |
None
|
steps
|
int
|
Number of waypoints (default: 50) |
50
|
rate
|
Optional[float]
|
DEPRECATED seconds-per-waypoint; mapped to cycles_per_step |
None
|
cycles_per_step
|
int
|
Robot cycles per waypoint (default 25 = 100ms per waypoint at 4ms cycles - joints move slower than TCP) |
25
|
Example
api.motion.move_joint_trajectory({"A1":30, "A2":-15, "A3":45})
queue_trajectory
¶
queue_trajectory(trajectory: List[Dict[str, float]], space: str = 'cartesian', rate: Optional[float] = None, cycles_per_step: Optional[int] = None) -> None
Add trajectory to execution queue without immediate execution.
Allows building up a sequence of trajectories that can be executed together via execute_queued_trajectories().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
trajectory
|
List[Dict[str, float]]
|
List of waypoint dictionaries |
required |
space
|
str
|
'cartesian' or 'joint' |
'cartesian'
|
rate
|
Optional[float]
|
DEPRECATED seconds-per-waypoint; mapped to cycles_per_step |
None
|
cycles_per_step
|
Optional[int]
|
Robot cycles per waypoint (default 3, the old 0.012 s at a 4 ms cycle) |
None
|
Example
Queue multiple trajectories¶
traj1 = api.motion.generate_trajectory(p0, p1, 50) traj2 = api.motion.generate_trajectory(p1, p2, 50) api.motion.queue_trajectory(traj1) api.motion.queue_trajectory(traj2) api.motion.execute_queued_trajectories()
queue_cartesian_trajectory
¶
queue_cartesian_trajectory(start_pose: Dict[str, float], end_pose: Dict[str, float], steps: int = 50, rate: Optional[float] = None, cycles_per_step: Optional[int] = None) -> None
Generate and queue Cartesian trajectory.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_pose
|
Dict[str, float]
|
Starting Cartesian pose |
required |
end_pose
|
Dict[str, float]
|
Ending Cartesian pose |
required |
steps
|
int
|
Number of waypoints |
50
|
rate
|
Optional[float]
|
DEPRECATED seconds-per-waypoint; mapped to cycles_per_step |
None
|
cycles_per_step
|
Optional[int]
|
Robot cycles per waypoint (default 3) |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If poses are invalid or parameters out of range |
Example
api.motion.queue_cartesian_trajectory( ... {"X":0, "Y":0, "Z":500}, ... {"X":100, "Y":0, "Z":500} ... )
queue_joint_trajectory
¶
queue_joint_trajectory(start_joints: Dict[str, float], end_joints: Dict[str, float], steps: int = 50, rate: Optional[float] = None, cycles_per_step: Optional[int] = None) -> None
Generate and queue joint-space trajectory.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_joints
|
Dict[str, float]
|
Starting joint configuration |
required |
end_joints
|
Dict[str, float]
|
Ending joint configuration |
required |
steps
|
int
|
Number of waypoints |
50
|
rate
|
Optional[float]
|
DEPRECATED seconds-per-waypoint; mapped to cycles_per_step |
None
|
cycles_per_step
|
Optional[int]
|
Robot cycles per waypoint (default 100, the old 0.4 s at a 4 ms cycle - joints move slower than the TCP) |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If joints are invalid or parameters out of range |
Example
api.motion.queue_joint_trajectory( ... {"A1":0, "A2":0, "A3":0}, ... {"A1":30, "A2":-15, "A3":45} ... )
execute_queued_trajectories
¶
Execute all queued trajectories in sequence.
Processes the trajectory queue in FIFO order, executing each with its configured space and rate. Clears the queue after execution.
Example
api.motion.queue_cartesian_trajectory(p0, p1, 50) api.motion.queue_cartesian_trajectory(p1, p2, 50) api.motion.execute_queued_trajectories()
Both trajectories executed sequentially¶
clear_queue
¶
Clear all queued trajectories without execution.
Example
api.motion.queue_cartesian_trajectory(p0, p1, 50) api.motion.clear_queue() # Discard without executing
get_queue
¶
Get metadata about queued trajectories.
Returns summary information (space, step count, cycles_per_step and the equivalent seconds-per-waypoint as rate) without the full trajectory data.
Returns:
| Type | Description |
|---|---|
List[Dict[str, Any]]
|
List of trajectory metadata dictionaries |
Example
api.motion.queue_cartesian_trajectory(p0, p1, 50) api.motion.queue_cartesian_trajectory(p1, p2, 100) queue = api.motion.get_queue() for item in queue: ... print(f"{item['space']}: {item['steps']} steps, {item['cycles_per_step']} cycles each") cartesian: 50 steps, 3 cycles each cartesian: 100 steps, 3 cycles each
generate_velocity_profile
staticmethod
¶
generate_velocity_profile(trajectory: List[Dict[str, float]], max_velocity: float = 1.0, max_acceleration: float = 2.0, profile: str = 'trapezoidal') -> List[Tuple[Dict[str, float], float]]
Apply velocity profiling to trajectory waypoints.
Generates time-optimal velocity profiles that respect velocity and acceleration limits. Returns trajectory with timing information.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
trajectory
|
List[Dict[str, float]]
|
List of waypoint dictionaries |
required |
max_velocity
|
float
|
Maximum velocity (units/s) |
1.0
|
max_acceleration
|
float
|
Maximum acceleration (units/s²) |
2.0
|
profile
|
str
|
Velocity profile type - 'trapezoidal' or 's-curve' |
'trapezoidal'
|
Returns:
| Type | Description |
|---|---|
List[Tuple[Dict[str, float], float]]
|
List of tuples (waypoint, velocity) for each point |
Example
traj = api.motion.generate_trajectory(p0, p1, 100) profiled = api.motion.generate_velocity_profile( ... traj, ... max_velocity=200.0, # mm/s ... max_acceleration=500.0, # mm/s² ... profile='trapezoidal' ... ) for waypoint, velocity in profiled: ... print(f"Point: {waypoint}, Velocity: {velocity:.2f} mm/s")
Note
Trapezoidal profiles have sharp velocity transitions (bang-bang control). S-curve profiles have smooth velocity transitions (jerk-limited). S-curve is recommended for sensitive applications requiring smooth motion.
generate_arc
staticmethod
¶
generate_arc(center: Dict[str, float], radius: float, start_angle: float, end_angle: float, steps: int = 100, plane: str = 'XY') -> List[Dict[str, float]]
Generate circular arc trajectory.
Creates waypoints along a circular arc in the specified plane.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
center
|
Dict[str, float]
|
Arc center point (e.g., {"X": 100, "Y": 0, "Z": 500}) |
required |
radius
|
float
|
Arc radius in mm |
required |
start_angle
|
float
|
Starting angle in degrees |
required |
end_angle
|
float
|
Ending angle in degrees |
required |
steps
|
int
|
Number of waypoints along arc |
100
|
plane
|
str
|
Plane for arc - 'XY', 'XZ', or 'YZ' (default: 'XY') |
'XY'
|
Returns:
| Type | Description |
|---|---|
List[Dict[str, float]]
|
List of Cartesian waypoints along the arc |
Example
90-degree arc in XY plane¶
arc = api.motion.generate_arc( ... center={"X": 100, "Y": 0, "Z": 500}, ... radius=50.0, ... start_angle=0, ... end_angle=90, ... steps=50 ... ) api.motion.execute_trajectory(arc, space='cartesian')
Note
Angles are measured counterclockwise from the positive X/Y/Z axis depending on the plane. Arc direction follows right-hand rule.
generate_circle
staticmethod
¶
generate_circle(center: Dict[str, float], radius: float, steps: int = 100, plane: str = 'XY') -> List[Dict[str, float]]
Generate complete circle trajectory.
Creates waypoints for a full 360-degree circular path.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
center
|
Dict[str, float]
|
Circle center point |
required |
radius
|
float
|
Circle radius in mm |
required |
steps
|
int
|
Number of waypoints around circle |
100
|
plane
|
str
|
Plane for circle - 'XY', 'XZ', or 'YZ' |
'XY'
|
Returns:
| Type | Description |
|---|---|
List[Dict[str, float]]
|
List of Cartesian waypoints around the circle |
Example
Full circle in XY plane¶
circle = api.motion.generate_circle( ... center={"X": 100, "Y": 0, "Z": 500}, ... radius=50.0, ... steps=100 ... ) api.motion.execute_trajectory(circle, space='cartesian')
generate_spiral
staticmethod
¶
generate_spiral(center: Dict[str, float], start_radius: float, end_radius: float, pitch: float, revolutions: float = 1.0, steps: int = 100, plane: str = 'XY', axis: str = 'Z') -> List[Dict[str, float]]
Generate spiral trajectory.
Creates waypoints for a spiral path with changing radius and height.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
center
|
Dict[str, float]
|
Spiral center/start point |
required |
start_radius
|
float
|
Starting radius in mm |
required |
end_radius
|
float
|
Ending radius in mm |
required |
pitch
|
float
|
Height change per revolution in mm |
required |
revolutions
|
float
|
Number of complete rotations |
1.0
|
steps
|
int
|
Number of waypoints |
100
|
plane
|
str
|
Planar motion plane - 'XY', 'XZ', or 'YZ' |
'XY'
|
axis
|
str
|
Axis for pitch motion - 'X', 'Y', or 'Z' |
'Z'
|
Returns:
| Type | Description |
|---|---|
List[Dict[str, float]]
|
List of Cartesian waypoints along spiral |
Example
Expanding spiral (drilling out)¶
spiral = api.motion.generate_spiral( ... center={"X": 100, "Y": 0, "Z": 500}, ... start_radius=10.0, ... end_radius=50.0, ... pitch=5.0, # 5mm per revolution ... revolutions=5, ... steps=200 ... )
Contracting spiral (retracting)¶
spiral = api.motion.generate_spiral( ... center={"X": 100, "Y": 0, "Z": 500}, ... start_radius=50.0, ... end_radius=10.0, ... pitch=-5.0, # Descending ... revolutions=5 ... )
blend_trajectories
staticmethod
¶
blend_trajectories(traj1: List[Dict[str, float]], traj2: List[Dict[str, float]], blend_radius: float, blend_steps: int = 20) -> List[Dict[str, float]]
Create smooth transition between two trajectories.
Generates a blended zone between trajectory endpoints using cubic interpolation for smooth velocity transitions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
traj1
|
List[Dict[str, float]]
|
First trajectory |
required |
traj2
|
List[Dict[str, float]]
|
Second trajectory |
required |
blend_radius
|
float
|
Blend zone radius in mm (distance from junction point) |
required |
blend_steps
|
int
|
Number of waypoints in blend zone |
20
|
Returns:
| Type | Description |
|---|---|
List[Dict[str, float]]
|
Combined trajectory with smooth blend |
Example
Create two straight-line trajectories¶
traj1 = api.motion.generate_trajectory(p0, p1, 50) traj2 = api.motion.generate_trajectory(p1, p2, 50)
Blend with 10mm radius¶
blended = api.motion.blend_trajectories( ... traj1, traj2, ... blend_radius=10.0, ... blend_steps=20 ... ) api.motion.execute_trajectory(blended)
Note
Blend radius should be smaller than the length of either trajectory. Larger radii create smoother blends but deviate more from original path.
transform_coordinates
staticmethod
¶
transform_coordinates(pose: Dict[str, float], from_frame: str = 'BASE', to_frame: str = 'WORLD', frame_offset: Optional[Dict[str, float]] = None) -> Dict[str, float]
Transform pose between coordinate frames.
Converts Cartesian coordinates between different reference frames (BASE, TOOL, WORLD, ROBROOT).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pose
|
Dict[str, float]
|
Cartesian pose to transform |
required |
from_frame
|
str
|
Source coordinate frame |
'BASE'
|
to_frame
|
str
|
Target coordinate frame |
'WORLD'
|
frame_offset
|
Optional[Dict[str, float]]
|
Optional frame transformation (X, Y, Z, A, B, C) |
None
|
Returns:
| Type | Description |
|---|---|
Dict[str, float]
|
Transformed pose in target frame |
Example
Transform from BASE to WORLD frame¶
world_pose = api.motion.transform_coordinates( ... pose={"X": 100, "Y": 0, "Z": 500}, ... from_frame='BASE', ... to_frame='WORLD', ... frame_offset={"X": 500, "Y": 200, "Z": 0} ... ) print(world_pose)
Note
For full 6-DOF transformations with rotations, use rotation matrices or quaternions. This implementation handles simple translational offsets and is suitable for most RSI applications.