Skip to content

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

MotionAPI(client: RSIClient)

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(**kwargs: float) -> None

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_joints(**kwargs: float) -> None

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_pose() -> Dict[str, float]

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_joints() -> Dict[str, float]

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

correct_position(correction_type: str, axis: str, value: float) -> str

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

move_external_axis(axis: str, value: float) -> str

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_speed(tech_param: str, value: float) -> str

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)

cancel_trajectory

cancel_trajectory() -> None

Cancel a running trajectory execution.

exit_movecorr

exit_movecorr(variable: str = 'MoveStop', hold: float = 0.1) -> str

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_queued_trajectories() -> None

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_queue() -> None

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_queue() -> List[Dict[str, Any]]

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.