DEV Community

Orion Jiang
Orion Jiang

Posted on

Build a Linear Actuator Cycle-Time Calculator in Python

When estimating the output of an automated machine, actuator speed alone does not tell the whole story.

A reciprocating axis normally needs to:

Move from home to the working position
Wait while an operation is performed
Return to home
Wait for the next cycle

These small delays can have a surprisingly large effect on hourly throughput.

Let’s build a simple Python calculator for estimating cycle time, motion duty cycle, and theoretical cycles per hour.

The Calculation

For a basic reciprocating axis:

outbound time = stroke / outbound speed
return time = stroke / return speed

motion time = outbound time + return time
cycle time = motion time + dwell times

The following script turns those calculations into a reusable class.

from dataclasses import dataclass

@dataclass(frozen=True)
class LinearAxisCycle:
stroke_mm: float
outbound_speed_mm_s: float
return_speed_mm_s: float
dwell_at_end_s: float = 0.0
dwell_at_home_s: float = 0.0

def calculate(self) -> dict[str, float]:
    if self.stroke_mm <= 0:
        raise ValueError("Stroke must be greater than zero.")

    if self.outbound_speed_mm_s <= 0:
        raise ValueError("Outbound speed must be greater than zero.")

    if self.return_speed_mm_s <= 0:
        raise ValueError("Return speed must be greater than zero.")

    if self.dwell_at_end_s < 0 or self.dwell_at_home_s < 0:
        raise ValueError("Dwell times cannot be negative.")

    outbound_time_s = (
        self.stroke_mm / self.outbound_speed_mm_s
    )

    return_time_s = (
        self.stroke_mm / self.return_speed_mm_s
    )

    motion_time_s = outbound_time_s + return_time_s

    cycle_time_s = (
        motion_time_s
        + self.dwell_at_end_s
        + self.dwell_at_home_s
    )

    motion_duty_cycle_pct = (
        motion_time_s / cycle_time_s
    ) * 100

    cycles_per_hour = 3600 / cycle_time_s

    return {
        "outbound_time_s": outbound_time_s,
        "return_time_s": return_time_s,
        "motion_time_s": motion_time_s,
        "cycle_time_s": cycle_time_s,
        "motion_duty_cycle_pct": motion_duty_cycle_pct,
        "cycles_per_hour": cycles_per_hour,
    }
Enter fullscreen mode Exit fullscreen mode

cycle = LinearAxisCycle(
stroke_mm=300,
outbound_speed_mm_s=250,
return_speed_mm_s=400,
dwell_at_end_s=0.4,
dwell_at_home_s=0.2,
)

results = cycle.calculate()

for name, value in results.items():
print(f"{name}: {value:.2f}")

The output is:

outbound_time_s: 1.20
return_time_s: 0.75
motion_time_s: 1.95
cycle_time_s: 2.55
motion_duty_cycle_pct: 76.47
cycles_per_hour: 1411.76
What This Number Does Not Include

This is an ideal constant-speed estimate. A real axis also requires time for acceleration, deceleration, controller communication, sensor confirmation, mechanical settling, and safety interlocks.

The result should therefore be treated as an early engineering estimate—not a guaranteed production rate.

The calculated motion duty cycle is also different from the manufacturer’s thermal duty-cycle rating. Powered holding, motor current, load, orientation, acceleration, and ambient temperature can all affect thermal performance.

From Timing to Hardware Selection

Once the required cycle time is understood, the next step is selecting suitable hardware.

Stroke length and nominal speed are only the beginning. Load, screw lead, repeatability, mounting orientation, motor interface, environmental protection, and allowable moments also matter.

These single-axis linear actuator configurations show examples of different module sizes and motor-mounting arrangements that can be compared during early design work.

A ten-line calculation will not select the entire motion system, but it can quickly expose unrealistic throughput assumptions—before they become expensive hardware decisions.

Top comments (0)