gcode_reader.emulate.motion

Classes

ConstantVelocity

Constant Velocity motion profile

LinearRamp

Linear Velocity motion profile

MotionProfile

Factory for generating MotionSegment objects from process data.

MotionSegment

Base class for all motion profiles

SCurve

Models an S-curve motion profile for a linear segment.

Trapezoid

Models a trapezoidal motion profile for a linear segment.

Functions

extract_motion_scalars(→ dict)

Extract per-segment velocity scalars from a processed operation.

Module Contents

class gcode_reader.emulate.motion.ConstantVelocity(initial_position: tuple, final_position: tuple, target_velocity: float, **_)[source]

Bases: MotionSegment

Constant Velocity motion profile

acceleration(t: float)[source]

Instantaneous acceleration at a time (t) on the line segment initial_position, final_position

calculate()[source]
position(t)[source]

Instantaneous position at a time (t) on the line segment initial_position, final_position

velocity(t: float)[source]

Instantaneous velocity at a time (t) on the line segment initial_position, final_position

property elapsed_time

Elapsed time required to travel the line segment initial_position, final_position

v
class gcode_reader.emulate.motion.LinearRamp(initial_position: tuple, final_position: tuple, initial_velocity: float, final_velocity: float, max_acceleration: float = None, _distance: float = None, **_)[source]

Bases: MotionSegment

Linear Velocity motion profile

acceleration(t: float)[source]

Instantaneous acceleration at a time (t) on the line segment initial_position, final_position

calculate()[source]
position(t)[source]

Instantaneous position at a time (t) on the line segment initial_position, final_position

velocity(t: float)[source]

Instantaneous velocity at a time (t) on the line segment initial_position, final_position

property elapsed_time

Elapsed time required to travel the line segment initial_position, final_position

final_velocity
initial_velocity
max_acceleration = None
class gcode_reader.emulate.motion.MotionProfile(max_jerk: float = None, max_accleration: float = None, max_velocity: float = None, junction_deviation: float = 0.05)[source]

Factory for generating MotionSegment objects from process data.

Holds machine-wide kinematic constraints and orchestrates a two-pass (GRBL-style) velocity planning algorithm: junction-deviation corner limiting followed by forward and backward kinematic propagation.

Parameters:
  • max_jerk (float, optional) – Maximum allowed jerk (units/s³). Used only by SCurve segments. Defaults to None.

  • max_accleration (float, optional) – Maximum allowed acceleration (units/s²). Defaults to None.

  • max_velocity (float, optional) – Ceiling on all target velocities (units/s). Defaults to None.

  • junction_deviation (float, optional) – Junction-deviation parameter (same length units as positions). Larger values permit higher corner velocities. Defaults to 0.05.

feed_rate_time_base_s

Divisor applied to feed-rate values to convert them from units/minute to units/second. Defaults to 60.0.

Type:

float

from_operation(operation: gcode_reader.emulate.operations.Operation, home=(0, 0, 0))[source]

Convenience wrapper around from_process_data that attaches the resulting profile directly to an Operation.

Mutates operation in place: sets operation.motion_profile to the list of segments and writes elapsed_time back onto each corresponding ProcessData entry. Returns the same object so the call can be chained.

Example:

planner = MotionProfile(max_accleration=500.0, max_velocity=50.0)
operation = planner.from_operation(operation)

total_time = sum(
    pd.elapsed_time for pd in operation.process_data
)
Parameters:
  • operation – The Operation to profile. Mutated in place.

  • home – Machine position before the first move. Defaults to (0, 0, 0).

Returns:

The same Operation, with motion_profile and elapsed_time populated.

from_process_data(process_data, home=(0, 0, 0))[source]

Convert process data into a timed motion profile.

Accepts either a List[ProcessData] or a ProcessDataArrays. Zero-length moves (duplicate waypoints) yield None.

Example:

planner = MotionProfile(max_accleration=500.0, max_velocity=50.0)

segments = list(planner.from_process_data(operation.process_data))
segments = [s for s in segments if s is not None]
total_time = sum(s.elapsed_time for s in segments)
Parameters:
  • process_data – Move data as a list of ProcessData objects or a pre-built ProcessDataArrays.

  • home – Machine position before the first move. Defaults to (0, 0, 0).

Yields:

A MotionSegment for each move, or None for zero-length moves.

feed_rate_time_base_s = 60.0
junction_deviation = 0.05
max_acceleration = None
max_jerk = None
max_velocity = None
property profile_type
class gcode_reader.emulate.motion.MotionSegment(initial_position: tuple, final_position: tuple, _distance: float = None, **_)[source]

Base class for all motion profiles

Parameters:
  • initial_position (tuple) – Initial position

  • final_position (tuple) – Final position

  • _distance (float, optional) – Precomputed distance to skip np.linalg.norm.

acceleration(t: float)[source]

Instantaneous acceleration at a time (t) on the line segment initial_position, final_position

calculate()[source]
jerk(t: float)[source]

Instantaneous jerk (da/dt) at a time (t) on the line segment initial_position, final_position

position(t: float)[source]

Instantaneous position at a time (t) on the line segment initial_position, final_position

velocity(t: float)[source]

Instantaneous velocity at a time (t) on the line segment initial_position, final_position

direction
distance = None
property elapsed_time

Elapsed time required to travel the line segment initial_position, final_position

final_position
initial_position
class gcode_reader.emulate.motion.SCurve(initial_position: tuple, final_position: tuple, initial_velocity: float, target_velocity: float, final_velocity: float = None, max_acceleration: float = None, max_jerk: float = None, **_)[source]

Bases: MotionSegment

Models an S-curve motion profile for a linear segment.

The acceleration profile is trapezoidal (rather than step-wise), giving continuous acceleration and bounded jerk. The profile has up to seven phases: three for ramp-up, a constant-velocity cruise, and three for ramp-down.

The profile operates in one of two modes: - Distance-Limited: If max_jerk is not provided, ramp-up and

ramp-down each occupy one-third of the total move distance, and the required accelerations are derived from that constraint.

  • Jerk-Limited: If max_jerk is provided, it governs the acceleration shape. If max_acceleration is also supplied it acts as a ceiling on the jerk-derived acceleration. The target_velocity is reduced automatically when the move is too short for the requested velocity (triangular case).

Parameters:
  • initial_position (tuple) – The starting coordinate of the move.

  • final_position (tuple) – The ending coordinate of the move.

  • initial_velocity (float) – The velocity at the start of the move.

  • target_velocity (float) – The target cruising velocity.

  • final_velocity (float, optional) – The velocity at the end of the move. If None, defaults to initial_velocity.

  • max_acceleration (float, optional) – Acceleration ceiling used only in jerk-limited mode. Ignored in distance-limited mode.

  • max_jerk (float, optional) – Maximum jerk. If provided the profile is jerk-limited; if None it is distance-limited.

acceleration(t)[source]

Instantaneous acceleration at a time (t) on the line segment initial_position, final_position

calculate()[source]

Builds s_space and t_space from the ramp accelerations.

jerk(t)[source]

Instantaneous jerk (da/dt) at a time (t) on the line segment initial_position, final_position

position(t)[source]

Instantaneous position at a time (t) on the line segment initial_position, final_position

velocity(t)[source]

Instantaneous velocity at a time (t) on the line segment initial_position, final_position

final_velocity = None
initial_velocity
max_acceleration = None
max_jerk = None
s_space = ()
t_space = ()
target_velocity
class gcode_reader.emulate.motion.Trapezoid(initial_position: tuple, final_position: tuple, initial_velocity: float, target_velocity: float, final_velocity: float = None, max_acceleration: float = None, _distance: float = None, **_)[source]

Bases: MotionSegment

Models a trapezoidal motion profile for a linear segment.

This profile consists of three phases: 1. A constant acceleration phase to ramp up to a maximum velocity. 2. A constant velocity phase. 3. A constant deceleration phase to ramp down to a final velocity.

The profile operates in one of two modes: - Distance-Limited: If max_acceleration is not provided, the profile shape is determined by assuming the ramp-up and ramp-down phases each occupy one-third of the total move distance. - Acceleration-Limited: If max_acceleration is provided, this limit is enforced. This may result in a “triangular” or “linear ramp” profile if the move is too short to reach the requested maximum velocity.

Parameters:
  • initial_position (tuple) – The starting coordinate of the move.

  • final_position (tuple) – The ending coordinate of the move.

  • initial_velocity (float) – The velocity at the start of the move.

  • target_velocity (float) – The target cruising velocity for the move.

  • final_velocity (float, optional) – The velocity at the end of the move. If None, defaults to initial_velocity.

  • max_acceleration (float, optional) – The maximum allowed acceleration and deceleration. If None, the profile is distance-limited.

acceleration(t: float)[source]

Instantaneous acceleration at a time (t) on the line segment initial_position, final_position

calculate()[source]

Calculates the final position and time frames for the profile.

This method uses the finalized ramp distances (self._ramp) and the calculated accelerations to determine the duration of each motion phase. It populates the s_space (position) and t_space (time) tuples that define the boundaries of the three motion phases.

position(t)[source]

Instantaneous position at a time (t) on the line segment initial_position, final_position

velocity(t: float)[source]

Instantaneous velocity at a time (t) on the line segment initial_position, final_position

final_velocity = None
initial_velocity
max_acceleration = None
s_space = ()
t_space = ()
target_velocity
gcode_reader.emulate.motion.extract_motion_scalars(operation) dict[source]

Extract per-segment velocity scalars from a processed operation.

Returns three numpy arrays aligned 1:1 with operation.process_data:

  • initial_velocity — entry speed into the segment (units/s).

  • target_velocity — commanded cruise ceiling (units/s).

  • final_velocity — exit speed from the segment (units/s).

None entries in motion_profile (zero-length moves) produce NaN. ConstantVelocity segments, which have no separate target/final velocity, use their single v attribute for all three fields.

Parameters:

operation – A processed Operation whose motion_profile list has been populated by MotionProfile.from_operation().

Returns:

Dict with keys "initial_velocity", "target_velocity", "final_velocity", each a shape (N,) float64 array.

Raises:

ValueError – If operation.motion_profile is empty or not set.