Instead of defaulting the pressure advance lookahead time to be the
same as the pressure_advance variable, allow it to be configured.
Default the new config setting (pressure_advance_lookahead_time) to
10ms.
Also, make the setting more accurate if a future move is accelerating
in the middle of the lookahead window.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Simplify the mechanism for limiting stepper speed (introduced in
commit bdfdf7ef) - split the extreme end of the build envelope into
two zones and use the same speeds for all moves that traverse any part
of one of those zones.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Commit c24b7a7e reworked the way lookahead was done and it introduced
a bug when a full acceleration move is immiedietly followed by a full
deceleration move. In that situation, depending on when the lookahead
queue was flushed, it was possible to call move.move() without calling
move.set_junction(). This resulted in a "Move instance has no
attribute 'accel_t'" internal error.
Simplify and fix the logic for checking full accel moves followed by
full decel moves.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
There's no reason for the user to specify position_max - it can be
inferred on deltas from the endstop positions.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Some XY moves at the extreme end of the build envelope could cause
excessive axis stepper movement. Check for any moves that could
possibly result in a stepper movement of more than 3 times the XY
movement and cap the move's acceleration and speed.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Calculate and store the maximum xy2 value for the given z level each
time the head moves to a new z level. This simplifies the boundary
check for common XY moves.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Report in the log the host CPU type and count. This helps distinguish
between different rpi versions when debugging the log from a problem
report.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
If the user requests a restart and the machine appears to be otherwise
functioning normally, then attempt to stop the heaters and fans prior
to restarting the host. This prevents the firmware from going into a
shutdown state when the heater is on and the host restarts.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Change the lookahead queue so that it attempts to buffer at least
buffer_time_high amount of moves when first starting a print. This
helps ensure the buffer is normally always full.
If the buffer falls below buffer_time_low then it is either due to the
end of a print or because octoprint/klippy is unable to keep up.
Change the code so that in this case the lookahead queue will attempt
to gather buffer_time_high amount of moves before restarting movement.
Update the default buffer_time_low to 1 second and buffer_time_high to
2 seconds. With the above changes a smaller buffer_time_high and a
larger buffer_time_low are more practical.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Use a minimum time window as a heuristic for determining when to try
to lazily flush the lookahead buffer. In the common case this will
result in more moves processed for each flush and thus reduce the
overall cost of the lookahead processing.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Do a better job of calculating the maximum halt velocity for the
stepper motors. The maximum cornering velocity is related to both the
maximum acceleration and the junction_deviation, so both should be in
the formula. Tests show that "math.sqrt(8. * self.junction_deviation
* self.max_accel)" very closely fits the maximum on cartesian robots.
This fixes potential "no next step" shutdowns that could occur on
some print moves.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
The normal system clock can have sudden jumps if the system clock is
changed. Use the system monotonic clock to avoid these sudden changes
in time.
It appears the Raspbian OS (which is used by OctoPi) is setup to
update the system clock upon network connectivity. This could cause
sudden system clock changes which could lead to Klippy processing
errors. Using the monotonic clock eliminates these issues.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Update the lookahead code to track both normal toolhead acceleration
as well as a pseudo acceleration to the point of deceleration. This
reduces the top speed of small zig-zag moves and it reduces printer
vibration during these moves.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
It is not necessary to track the do_calc_junction flag as it can just
as easily be determined at the top of the calc_junction() method.
This simplifies the code.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
When calculating the extruder lookahead, determine how far to
lookahead by the amount of elapsed time each move takes. This makes
the extruder lookahead code more flexible as it is no longer limited
to the next immediate cornering moves.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Instead of calculating min/max_corner_v in the toolhead class,
calculate it in the extruder class. This keeps the extruder specific
code together.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
When testing via a gcode input file, it's easier to debug problems if
the program exits upon the first exception.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Make sure max_corner_v2 is fully calculated before proactively
flushing moves from the lookahead queue. Without this, some moves
would do unnecessary pressure advance during cornering.
Also, handle the min/max_corner_v2 calculations correctly in the rare
case where a move that does only acceleration is immediately followed
by a move that does only deceleration.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
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>
Continue to resend the pwm value even if the last value was zero -
this extends the debugging info.
Also, add the target temperature to the pwm debugging.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Fix a bug causing timers to be delayed when pause() is called from a
fd event. The eventtime needs to be reloaded when an old greenlet is
reactivated.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Check for msgproto.error and warn the user about version firmware
version mismatch. Raise msgproto.error when extracting firmware
constants.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Use a base of 256 instead of 65536 when calculating the sum of the
square of the clock differences in the stats. This makes the
calculation more accurate. Export the new base via DECL_CONSTANT for
the host to access. Use DIV_ROUND_UP() when adjusting for the base to
ensure no lost ticks. Do the division after multiplication in the
common case where the time between stats_task() invocations is less
than 64K ticks.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Instead of requiring the user enter velocity and accel parameters for
extrude only moves, calculate sane defaults from the printer's maximum
velocity and accel.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
It's possible for a printer with very fine resolution to require a
large number of steps for a homing operation. Instead of storing all
of those steps in memory, periodically flush the queue should more
than 64K steps be present. This keeps a reasonable limit on the
amount of ram needed to store steps.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
The serialqueue_flush_ready() code was used to flush queue_step
commands during a homing operation. It's no longer necessary now that
moves during a homing operation use the normal message priority
system.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
The endstop homing system requires all queue_step commands be in the
MCU's 'move queue' before endstop checking starts. Use the normal
message priority system to request that stepper queue_step commands
are received prior to the start of the end_stop_home command. This
simplifies the code and removes the need for special serial queue
flushing.
This also fixes a bug in homing operations that take longer than 2^31
clock ticks.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Add a is_kinematic_move flag to the Move class and clear it on extrude
only moves. Don't call the kinematic check_move() or move() methods
for extrude only moves.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Change the default compression error window (max_error) from 50us to
25us - it's common for stepper motor drivers to have 30us for their
"pwm fixed off time" and it would be good for the steps to be
scheduled within that time.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Revert 4a16053c and avoid integer overflows in the addfactor
calculation by exiting the loop early if count > 0x200. This provides
stronger protection against overflows.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Log the constants reported by the MCU and log the number of move items
allocated after configuration.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Commit a217c0f3 changed the way the "addfactor" was calculated.
Unfortunately, it was possible for the updated method to cause an
integer overflow and have a negative addfactor. Fix this by
explicitly casting the addfactor calculation to uint32_t.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Some motors have very small step distances and they can generate over
a million steps during a homing operation. Increase the maximum count
to ten million to avoid triggering the internal sanity check.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Don't assume the hardware ADC has 10bit resultion - instead have the
firmware define a constant and read that constant in the host.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Add a DECL_CONSTANT macro to allow the firmware to define constants
that are to be exported to the host during the "identify" phase. This
replaces the existing hardcoded mechanism of scanning the Kconfig
header file for certain constants.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
It is possible to restart the host software with a RESTART command
after manually resetting the micro-controller.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Instead of splitting the available "add range" in half, try for add
values closer to the higher end of the range. This heuristic seems to
result in better choices.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Change the min/maxadd variables to use an inclusive range instead of
exclusive. This better matches min/maxinterval.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Make it clear which variables refer to the best verified point found
so far, and which variables deal with the next (not yet verified)
point.
Also, remove checked_count as bestcount serves the same purpose.
Also, allow minmax_point to be inlined.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
The arduino style serial port interfaces can reset the MCU when the
serial port is opened. Clearing the HUPCL flag makes this less
likely.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
If a speed is never specified then default to 25mm/s (up from 1 mm/s).
If a user accidentally issues a move without setting the speed, the
default speed shouldn't be so slow that it takes minutes to finish the
move.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Most moves are on the XY plane - avoid a few multiplications in the
inner loop in this case. When there is a Z move, it is almost always
entirely a Z move - avoid the sqrt() call in the inner loop in this
case.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Taking the inverse of the XY move distance can lead to extremely large
values when the XY distance is very small. This can lead to
saturation of the double precision variables and incorrect results.
Rework the delta kinematic math to avoid using this inverse. Pass the
closestxy_d value directly to the C functions so that the C code can
calculate its intermediate constants.
After this change the move_z special case is no longer necessary as
the regular delta functions now work with movexy_r=0 and movez_r=1.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
The head may be far away from an axis at the start of a home, and that
axis must then traverse more than just the distance from zero height
to the endstop position. Add in additional distance to account for
this.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
On a delta printer, z moves require the mcu to support the greatest
number of steps per second. However, z moves are rare, so it makes
sense to limit the velocity of z moves separately from the velocity of
normal xy moves.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Change the config file so the maximum accel and velocity are specified
in the "printer" section instead of the individual "stepper" sections.
The underlying code limits the velocity and accel of the toolhead
relative to the print object, so it makes sense to configure the
system that was as well.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Add a "restart" gcode command that will cause the host "klippy"
software to reload its config and restart.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Support human readable commands (eg, "help"). Add a "help" command to
list these extended commands.
Also, add support for declaring command aliases, command help, and
command availability next to the handlers themselves.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Commit 1e1364c3 moved the storage of the stepper position to the
mcu_stepper class. The initializing of that position needs to be
pushed back until after the mcu_stepper class is instantiated.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
The set_printer_ready() method can be called from a background thread.
Have the main Printer class call a new dump_debug() method in the main
thread on a shutdown event.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Check that all options specified in the config file are valid. This
catches possible typos and spelling errors in variable names that have
a default.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Add helper function that ensures a config option is one of several
choices. This helps ensure that a proper error is raised if an
invalid choice is made.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Instead of writing error messages to stderr, route them into the
python code and use the standard python logging system.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Use the greenlet mechanism to wait for the response directly in the
send_with_response() method. This simplifies the calling code.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Use the greenlet mechanism to wait for the connection to come up in
the serial connect() method. This simplifies the calling code.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Setup the reactor and run the MCU connection code as a timer within
the reactor. The connection code will make use of reactor greenlets
so that it can wait for events during the connection phase.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Add support for greenlets - a mechanism for tasks that can pause while
still allowing regular reactor events to occur.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Wake the background thread up when exiting - as this makes the exit
complete faster (and have more predictable timing).
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Don't expose the ADC initialization to the gcode and heater code -
instead, register a callback within the MCU_adc class and call it
directly from the MCU class after configuration completes.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Instead of checking the endstop trigger directly after a retract move,
verify some distance is traveled during the following homing
operation. This reduces the amount of synchronization between mcu and
host during homing.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Move the storage of the stepper location from the kinematic classes to
the low-level mcu_stepper class.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Should a homing move complete without hitting the endstop, then
disable motors, disable the endstop checking, and report the error to
the user.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Allow an EndstopError to be raised without a destination position.
Introduce EndstopMoveError wrapper so that current callers can
continue to pass in a move destination.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Change the scheduling of the final homed position (which takes into
account the stepper phases) so that it is scheduled from the kinematic
classes instead of from the toolhead class.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Create the Homing class in the gcode handler instead of in the
kinematic classes. This will make it easier to pass error messages
back to the user.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Create the QueryEndstops in the gcode handler instead of in the
kinematic classes. This simplifies the gcode handler as it can
directly register its response callback.
Also, store the stepper name in the stepper class. Also, propagate
the print_time of the query request to the mcu_endstop class.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Automatically reset the next step time to zero on a stepper_stop()
call. This makes the host code simpler as it no longer needs to
schedule an explicit reset_step_clock command on the step after a
homing operation.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Commits f0cefebf and 8f331f08 changed the way the code determined what
steps to take on fractional steps. Unfortunately, it was possible in
some situations for the C code to round differently from the python
code which could result in warnings and lost steps.
Change the code so that all fractional step handling is done in the C
code. Implementing the step rounding logic in one location avoids any
conflicts.
In order to efficiently handle the step rounding in the C code, the C
code has also been extended to directly send the "set_next_step_dir"
command.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Move flush() and check_expand() code to a new location so that the
stepcompress_push_X() functions can flush.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Writing to the debug log can cause an unbounded delay due to disk IO.
This is particularly so on embedded machines such as the Raspberry Pi
that run on SD cards. These log writing delays can cause problems for
the main processing threads.
The new "queuelogger" code forwards all the main thread log messages
to a queue, and a background thread writes the log messages from the
queue to the destination file. This eliminates the IO delay from the
main threads.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Invert the default meaning of the stepper direction pin. Instead of
treating a low value as position motion, treat a high value as
positive motion. This matches what other firmwares do, and it matches
what common stepper motor drivers document.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
A pullup setting on an input pin (ie, '^') should enable the hardware
pullup resistor, but it should not invert the trigger level (ie, it
should remain trigger on high). Those that need to change the trigger
level (ie, trigger on low) must now do that explicitly (ie, '^!').
This makes the code match what other firmwares do.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Only disable the extruder if the last measured temperature is below
the minimum extrude temperature setting. Verifying the target
temperature is not necessary, and it can incorrectly prevent some
valid moves. It's not uncommon for scripts to retract filament
immiedietly after setting the extruder temperature to zero.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Due to the lookahead, small changes in the direction of the toolhead
cause minor changes in toolhead velocity. These "cornering" velocity
changes cause the current extruder code to trigger pressure advance
and its associated pressure retract. This causes the extruder to
rapidly "jerk" the filament.
This code change updates the extruder to detect velocity changes due
solely to cornering and avoid pressure advance.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Due to minor differences in the extrude ratio, the last end velocity
of the filament may not exactly match the next move's start velocity
of the filament. Implement more precise calculations for pressure
advance to take this into account.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Avoid mixing the travel distance of the head (and its associated
velocity and acceleration) with the distance the filament moves.
Instead, use the filament travel distance.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Calculate the next "cornering" minimum and maximum for each move. The
"cornering minimum" is the lowest speed the head will reach
immediately after this move (with no interleaving acceleration or
cruising). The "cornering maximum" is the maximum speed the head will
reach after the cornering minimum (with no interleaving deceleration
or cruising).
These cornering calculations will be helpful in the extruder "pressure
advance" code.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Take into account the maximum possible start speed of a move when
calculating junction_start_max. This simplifies the lookahead logic.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Update the stepcompress C code to check for integer overflow so that
the python code does not need to. The new checks also handle the
possibility of a single move lasting long enough to cause an overflow.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Use a non-zero qm->min_clock value to indicate that the command uses
the move queue and to also store the clock of when that move queue
item will be released.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
The existing code calculates the number of steps in a move and then
spreads them out evenly throughout that move. Change the code so that
step timing is based on where the head is commanded to be relative to
the stepper step locations. This makes the timing more accurate - in
particular the stepper velocities will be more accurate during
cornering introduced by the lookahead code. It also results in
slightly smoother stepper motion which results in better step
compression.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
The existing code calculates the number of steps in a move and then
spreads them out evenly throughout that move. Change the code so that
step timing is based on where the head is commanded to be relative to
the axis step locations. This makes the timing more accurate - in
particular the axis velocities will be more accurate during cornering
introduced by the lookahead code. It also results in slightly
smoother stepper motion which results in better step compression.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Don't use step_dist for the "distance along the line of movement per
step" as it's too similar to the stepper.step_dist variable. Use the
name "move_step_d" instead.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Store the start position (in addition to the existing end position) in
the Move class. The start position can be useful to the kinematic
classes.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Rename get_homed_position() to get_homed_offset() and return the
endstop position delta in steps instead of an absolute position
relative to position_endstop. The conversion to absolute positions
can be dependent on the type of kinematics in use, so is inappropriate
to do in the low level stepper.py code.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>