toolhead: Change variables to use suffix "_v2" instead of prefix "junction_"

The junction speeds are tracked in velocity squared - introduce the
common suffix "_v2" to track that instead of using a prefix of
"junction_".

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2017-01-14 13:35:27 -05:00
parent 064e8bdd84
commit fc6a31eac8
2 changed files with 42 additions and 46 deletions

View File

@ -83,12 +83,12 @@ class PrinterExtruder:
prev_pressure_d += extra_accel_d prev_pressure_d += extra_accel_d
# Update decel and retract parameters when decelerating # Update decel and retract parameters when decelerating
if decel_t: if decel_t:
if move.corner_min: if move.min_corner_v:
npd = move.corner_max*move_extrude_r * self.pressure_advance npd = move.max_corner_v*move_extrude_r*self.pressure_advance
extra_decel_d = prev_pressure_d - npd extra_decel_d = prev_pressure_d - npd
if move.end_v > move.corner_min: if move.end_v > move.min_corner_v:
extra_decel_d *= ((move.cruise_v - move.end_v) extra_decel_d *= ((move.cruise_v - move.end_v)
/ (move.cruise_v - move.corner_min)) / (move.cruise_v - move.min_corner_v))
else: else:
npd = move.end_v * move_extrude_r * self.pressure_advance npd = move.end_v * move_extrude_r * self.pressure_advance
extra_decel_d = prev_pressure_d - npd extra_decel_d = prev_pressure_d - npd

View File

@ -9,8 +9,8 @@ import cartesian, delta
EXTRUDE_DIFF_IGNORE = 1.02 EXTRUDE_DIFF_IGNORE = 1.02
# Common suffixes: _d is distance (in mm), _v is velocity (in # Common suffixes: _d is distance (in mm), _v is velocity (in
# mm/second), _t is time (in seconds), _r is ratio (scalar between # mm/second), _v2 is velocity squared (mm^2/s^2), _t is time (in
# 0.0 and 1.0) # seconds), _r is ratio (scalar between 0.0 and 1.0)
# Class to track each move request # Class to track each move request
class Move: class Move:
@ -37,22 +37,21 @@ class Move:
self.do_calc_junction = self.is_kinematic_move = False self.do_calc_junction = self.is_kinematic_move = False
self.move_d = move_d self.move_d = move_d
self.extrude_r = axes_d[3] / move_d self.extrude_r = axes_d[3] / move_d
# Junction speeds are velocities squared. The junction_delta # Junction speeds are tracked in velocity squared. The
# is the maximum amount of this squared-velocity that can # delta_v2 is the maximum amount of this squared-velocity that
# change in this move. # can change in this move.
self.junction_max = speed**2 self.max_start_v2 = 0.
self.junction_delta = 2.0 * move_d * self.accel self.max_cruise_v2 = speed**2
self.junction_start_max = 0. self.delta_v2 = 2.0 * move_d * self.accel
def limit_speed(self, speed, accel): def limit_speed(self, speed, accel):
self.junction_max = min(self.junction_max, speed**2) self.max_cruise_v2 = min(self.max_cruise_v2, speed**2)
if accel < self.accel: if accel < self.accel:
self.accel = accel self.accel = accel
self.junction_delta = 2.0 * self.move_d * self.accel self.delta_v2 = 2.0 * self.move_d * self.accel
self.do_calc_junction = False self.do_calc_junction = False
def calc_junction(self, prev_move): def calc_junction(self, prev_move):
if not self.do_calc_junction or not prev_move.do_calc_junction: if not self.do_calc_junction or not prev_move.do_calc_junction:
return return
# Find max junction_start_velocity between two moves
if (self.extrude_r > prev_move.extrude_r * EXTRUDE_DIFF_IGNORE if (self.extrude_r > prev_move.extrude_r * EXTRUDE_DIFF_IGNORE
or prev_move.extrude_r > self.extrude_r * EXTRUDE_DIFF_IGNORE): or prev_move.extrude_r > self.extrude_r * EXTRUDE_DIFF_IGNORE):
# Extrude ratio between moves is too different # Extrude ratio between moves is too different
@ -69,24 +68,21 @@ class Move:
junction_cos_theta = max(junction_cos_theta, -0.999999) junction_cos_theta = max(junction_cos_theta, -0.999999)
sin_theta_d2 = math.sqrt(0.5*(1.0-junction_cos_theta)) sin_theta_d2 = math.sqrt(0.5*(1.0-junction_cos_theta))
R = self.toolhead.junction_deviation * sin_theta_d2 / (1. - sin_theta_d2) R = self.toolhead.junction_deviation * sin_theta_d2 / (1. - sin_theta_d2)
self.junction_start_max = min( self.max_start_v2 = min(
R * self.accel, self.junction_max, prev_move.junction_max R * self.accel, self.max_cruise_v2, prev_move.max_cruise_v2
, prev_move.junction_start_max + prev_move.junction_delta) , prev_move.max_start_v2 + prev_move.delta_v2)
def process(self, junction_start, junction_cruise, junction_end def process(self, start_v2, cruise_v2, end_v2, min_corner_v2, max_corner_v2):
, junction_corner_min, junction_corner_max):
# Determine accel, cruise, and decel portions of the move distance # Determine accel, cruise, and decel portions of the move distance
inv_junction_delta = 1. / self.junction_delta inv_delta_v2 = 1. / self.delta_v2
accel_r = (junction_cruise-junction_start) * inv_junction_delta self.accel_r = accel_r = (cruise_v2 - start_v2) * inv_delta_v2
decel_r = (junction_cruise-junction_end) * inv_junction_delta self.decel_r = decel_r = (cruise_v2 - end_v2) * inv_delta_v2
cruise_r = 1. - accel_r - decel_r self.cruise_r = cruise_r = 1. - accel_r - decel_r
self.accel_r, self.cruise_r, self.decel_r = accel_r, cruise_r, decel_r
# Determine move velocities # Determine move velocities
start_v = math.sqrt(junction_start) self.start_v = start_v = math.sqrt(start_v2)
cruise_v = math.sqrt(junction_cruise) self.cruise_v = cruise_v = math.sqrt(cruise_v2)
end_v = math.sqrt(junction_end) self.end_v = end_v = math.sqrt(end_v2)
self.start_v, self.cruise_v, self.end_v = start_v, cruise_v, end_v self.min_corner_v = math.sqrt(min_corner_v2)
self.corner_min = math.sqrt(junction_corner_min) self.max_corner_v = math.sqrt(max_corner_v2)
self.corner_max = math.sqrt(junction_corner_max)
# Determine time spent in each portion of move (time is the # Determine time spent in each portion of move (time is the
# distance divided by average velocity) # distance divided by average velocity)
accel_t = accel_r * self.move_d / ((start_v + cruise_v) * 0.5) accel_t = accel_r * self.move_d / ((start_v + cruise_v) * 0.5)
@ -115,23 +111,23 @@ class MoveQueue:
# Traverse queue from last to first move and determine maximum # Traverse queue from last to first move and determine maximum
# junction speed assuming the robot comes to a complete stop # junction speed assuming the robot comes to a complete stop
# after the last move. # after the last move.
next_junction_end = junction_corner_min = junction_corner_max = 0. next_end_v2 = min_corner_v2 = max_corner_v2 = 0.
for i in range(flush_count-1, -1, -1): for i in range(flush_count-1, -1, -1):
move = self.queue[i] move = self.queue[i]
reachable_start = next_junction_end + move.junction_delta reachable_start_v2 = next_end_v2 + move.delta_v2
junction_start = min(move.junction_start_max, reachable_start) start_v2 = min(move.max_start_v2, reachable_start_v2)
junction_cruise = min((junction_start + reachable_start) * .5 cruise_v2 = min((start_v2 + reachable_start_v2) * .5
, move.junction_max) , move.max_cruise_v2)
move_info[i] = (junction_start, junction_cruise, next_junction_end move_info[i] = (start_v2, cruise_v2, next_end_v2
, junction_corner_min, junction_corner_max) , min_corner_v2, max_corner_v2)
if reachable_start > junction_start: if reachable_start_v2 > start_v2:
junction_corner_min = junction_start min_corner_v2 = start_v2
if junction_start + move.junction_delta > next_junction_end: if start_v2 + move.delta_v2 > next_end_v2:
junction_corner_max = junction_cruise max_corner_v2 = cruise_v2
if lazy: if lazy:
flush_count = i flush_count = i
lazy = False lazy = False
next_junction_end = junction_start next_end_v2 = start_v2
if lazy: if lazy:
flush_count = 0 flush_count = 0
# Generate step times for all moves ready to be flushed # Generate step times for all moves ready to be flushed
@ -140,14 +136,14 @@ class MoveQueue:
# Remove processed moves from the queue # Remove processed moves from the queue
del self.queue[:flush_count] del self.queue[:flush_count]
if self.queue: if self.queue:
self.junction_flush = 2. * self.queue[-1].junction_max self.junction_flush = 2. * self.queue[-1].max_cruise_v2
def add_move(self, move): def add_move(self, move):
self.queue.append(move) self.queue.append(move)
if len(self.queue) == 1: if len(self.queue) == 1:
self.junction_flush = 2. * move.junction_max self.junction_flush = 2. * move.max_cruise_v2
return return
move.calc_junction(self.queue[-2]) move.calc_junction(self.queue[-2])
self.junction_flush -= move.junction_delta self.junction_flush -= move.delta_v2
if self.junction_flush <= 0.: if self.junction_flush <= 0.:
# There are enough queued moves to return to zero velocity # There are enough queued moves to return to zero velocity
# from the first move's maximum possible velocity, so at # from the first move's maximum possible velocity, so at