Skip to content

Commit f87b769

Browse files
committed
Fix step/time calculations; add accel keys
Fixes inflated time estimates by computing absolute travel distance as |current_physical - target_physical| and then converting to hardware steps (avoids sign/sum errors when axes are inverted). Clarifies that speed and acceleration are already expressed in firmware step units and uses their magnitudes directly (keeps a 20000 steps/s² safe default). Also expose acceleration in motor property output by adding "acceleration" and (misspelled) "acceleleration" keys alongside the existing "accel" for compatibility.
1 parent 23f6b9d commit f87b769

1 file changed

Lines changed: 19 additions & 11 deletions

File tree

uc2rest/motor.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -613,10 +613,15 @@ def move_stepper(self, steps=(0,0,0,0), speed=(1000,1000,1000,1000), is_absolute
613613
if isAbsoluteArray[iMotor]:
614614
# Compare current position (physical) with target (physical, already includes offset)
615615
self.currentDirection[iMotor] = 1 if (self.currentPosition[iMotor] > targetPositionPhysical[iMotor]) else -1
616-
# Calculate distance to travel in HARDWARE STEPS:
617-
# Current position (physical) -> convert to steps, then subtract target (already in steps)
618-
currentPosition_steps = self.currentPosition[iMotor] / stepSizes[iMotor]
619-
absoluteDistances_steps[iMotor] = abs(currentPosition_steps - steps[iMotor])
616+
# Travel distance for the time estimate = |current - target| in
617+
# PHYSICAL units, converted to hardware steps. Computing it in
618+
# physical units keeps it direction-agnostic: the hardware `steps`
619+
# target carries the per-axis direction sign, so subtracting it
620+
# from an unsigned current-in-steps produced a *sum* (not a
621+
# difference) on inverted axes, hugely inflating the estimate.
622+
absoluteDistances_steps[iMotor] = abs(
623+
self.currentPosition[iMotor] - targetPositionPhysical[iMotor]
624+
) / stepSizes[iMotor]
620625
else:
621626
self.currentDirection[iMotor] = np.sign(steps[iMotor])
622627
# For relative motion, steps[iMotor] is already the distance in hardware steps
@@ -629,19 +634,20 @@ def move_stepper(self, steps=(0,0,0,0), speed=(1000,1000,1000,1000), is_absolute
629634
if not isAbsoluteArray[iMotor]:
630635
absoluteDistances_steps[iMotor] = abs(steps[iMotor])
631636

632-
# Convert speed and acceleration from physical units to steps/second
637+
# Speed and acceleration are already in firmware step units (the same raw
638+
# values sent to the device), and absoluteDistances_steps is in hardware
639+
# steps too, so the time estimate is unit-consistent WITHOUT any stepSize
640+
# division — dividing here would desync it from the distance and break the
641+
# estimate. Just take magnitudes.
633642
speed_steps = np.zeros(4)
634643
acceleration_steps = np.zeros(4)
635644
for iMotor in range(4):
636645
if speed[iMotor] != 0:
637-
# Speed: µm/s -> steps/s => divide by stepSize (µm/step)
638-
speed_steps[iMotor] = abs(speed[iMotor]) # TODO: This is actually given in steps/s / stepSizes[iMotor]
646+
speed_steps[iMotor] = abs(speed[iMotor])
639647
if acceleration[iMotor] is not None and acceleration[iMotor] != 0:
640-
# Acceleration: µm/s² -> steps/s² => divide by stepSize
641-
acceleration_steps[iMotor] = abs(acceleration[iMotor]) # TODO: This is actually given in steps/s / stepSizes[iMotor]
648+
acceleration_steps[iMotor] = abs(acceleration[iMotor])
642649
else:
643-
# Default acceleration in steps/s²
644-
acceleration_steps[iMotor] = 20000 # This should also be converted, but we use a safe default
650+
acceleration_steps[iMotor] = 20000 # safe default (firmware steps/s^2)
645651

646652
# Calculate travel time using HARDWARE STEPS and converted speed/acceleration
647653
# Find the axis that will take the longest (limits overall movement time)
@@ -696,8 +702,10 @@ def move_stepper(self, steps=(0,0,0,0), speed=(1000,1000,1000,1000), is_absolute
696702
"redu": int(is_reduced)}
697703
if acceleration[iMotor] is not None:
698704
motorProp["accel"] = int(acceleration[iMotor])
705+
motorProp["acceleration"] = int(acceleration[iMotor])
699706
else:
700707
motorProp["accel"] = self.DEFAULT_ACCELERATION
708+
motorProp["acceleleration"] = self.DEFAULT_ACCELERATION
701709
motorPropList.append(motorProp)
702710
if len(motorPropList)==0:
703711
return "{'return':-1}"

0 commit comments

Comments
 (0)