-
-
Notifications
You must be signed in to change notification settings - Fork 5.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
firmware_retraction: Support nozzle lifting on G10 #6239
Conversation
Enables nozzle lifting (zhop) when retracting using G10 command. Introduces three different zhop movement styles (standard, ramp and helix) suitable for different use cases. Clears retraction reliably to prevent nozzle crashes and other unwanted behavior. Signed-off-by: Florian-Patrice Nagel <flopana77@gmail.com>
Added safe unretract method Added G1 toggle flag Added max zhop method limited to cartesians Changed from home_rail to homing_move event to detect homing & bed mesh
|
Hi Matszwe02. Thanks for your comment. Could you elaborate please. I am not sure if I understand correctly, given that the upper and lower case in the files is consistent from what I see. BR Florian |
Here I marked the text. Not significant, but I had to think a bit before setting it to helix. Also, I made a simple fix for retraction at bed edges, you could check my PR :) |
I see. Good catch. Will fix it now. Regarding PR, see you over on my repo :) |
I have one question/idea: |
Hi Zeanon. Thanks for your feedback. I am not quite sure what you mean by "code(ing) the retraction moves directly". Looking at the G2 and G3 command implementation, the same approach was taken, meaning G1 commands are called. This has the benefit that all the safety features built into Klipper are kept working. Hence, I believe that the Maintainers would likely consider a direct coding approach as less safe. |
Thanks for your in depth reply, that makes sense of course |
I am happy about any Likes you leave :p |
Alas, I left a review last week, but it seems github lost my comments. :-( I'll try again. I have a few high level comments on this PR:
To elaborate on simplification of I think it would help if there was a high-level description of what the G10 and G11 commands are "supposed to do", along with a summary of the various situations where those commands can't reasonably perform the requested action. I think that would help me review, and I think it would be ultimately helpful for users as well. As above, if these command can't perform their intended action then I think the code needs to report an error. Ultimately, if we conclude that G10/G11 would raise too many cryptic errors to be useful, then we may need to consider that z hop is better implemented in a slicer. To elaborate on the "module rewrite" - in my experience, code "rewrites" tend to increase the risks of introducing a regression. It also increases maintenance work should a regression be introduced as it is harder to identify the specific change using I think the I also have a few minor comments. My main focus is on my comments above however. In no particular order: I appreciate your detailed print tests. It's not clear to me if you are reporting that Klipper based z hop is improving quality in a way that a slicer could not reasonable accomplish? Or, perhaps you are reporting that not all slicers implement helix/ramp z hop, or not all slicers have z hop enabled? In the latter cases, an alternative to firmware z hop may be to expand z hop in slicers. I don't think we should add "debugging options" ( It isn't clear to me what the I think it would be preferable to add an option to the existing I don't think we should add Thanks for working on this, |
Hi Kevin. Thank you for taking the time to review this PR! Please find my comments/answers/thoughts below:
On a G10 command, the Z height is raised by the value specified for the z_hop_height parameter of the module in the Config.
The PR is indeed a complete rewrite with little to nothing left of the previous code. Splitting up the PR is somewhat tricky. Having "ramp" and "helix" zhop move functionality separated out is doable. All additional safety measures over and above reliably clearing retraction on start, finish and cancel prints (e.g. not fully raising toolhead if the move would go out if range) can also be submitted separately.
The code raises the toolhead immediately to the specified value except for the following two cases:
Hence, from my perspective, the behavior is 100% predictable and does not make guesses about user wants.
I absolutely agree that a more detailed description of the functionality including exception and safety features would make a lot of sense. I'll gladly write up a document, including pictures to ensure the user fully understands the functionality of the code. The reason I didn't do it yet was because I wasn't sure if adding a separate document to Klipper's documentation, dealing with retraction and zhop, would be acceptable/encouraged.
I am happy to raise an error to make the user aware of any situation were a zhop move could not be performed as intended. However, such error should not stop an ongoing print as this would defeat the purpose of adding the code to prevent out-of-range moves, which actually do stop ongoing prints.
So far during my usages, the number of situations in which an error would have been raised was cero (hence, I may have been overcautious regarding all sorts of edge cases...but then again, better safe than sorry). Regarding the implementation in the slicer (as is standard now), I would like to make a general comment and maybe spawn a wider discussion. As per my view, the 3D printing workflow involves three software tools in general: 3D CAD software, Slicer and Firmware. Each of these tools has "natural" access to certain information:
Especially the last point is where the workflow is currently flawed. If the user fails to provide the slicer with the correct properties the printer will have at the time of printing (e.g. loaded filament, installed nozzle), the print will likely fail. This is because currently the interface between the slicer and the printer is managed by the user and not automatically. There are two ways to address this issue:
Following this logic, retraction, zhop, wiping, thresholds when retraction is done, is nothing else than a compensation mechanism for oozing. Hence, just like bed mesh, pressure advance and input shaping, I see this functionality best located in the firmware, given that the information which filament is loaded and what printer is executing the generated gcode is only known with certainty once the "print" button is pushed. The same goes for extrusion, bed and chamber temperatures, maximum extrusion rates, minimum layer time, fan speeds, etc. To implement this, the firmware needs to know what kind of moves it is doing, which is information that the slicer must (and can) provide. This also involves some additional computations of the firmware at runtime and is therefore not easy to achieve if we want to ensure that Klipper remains the fastest firmware out there (I am working on parallelizing the gcode reading and the command execution to achieve exactly that). With enough time at hand, and sufficient information passed from the slicer, pretty much all filament and printer characteristics-related settings can be moved from the slicer to the firmware, thus eliminating the need to synchronize information between those two tools. I am curious about your and the community's thoughts on this.
I understand that incremental, smaller changes to the codebase might be preferable to a complete rewrite, because they are easier to manage, debug, and revert if necessary. This approach is definitely less disruptive for end users as well. Therefore, I believe that splitting out the zhop functionality in a separate module would probably be the best solution. Your guidance on this is highly appreciated. In any case, I paid a lot of attention to ensure that the module behaves exactly the same as the previous code as long as the user does not deliberately change his config.
"helix" and "ramp" zhop move styles are available in Orca Slicer and BambuStudio. "helix" (called "Spiral" in mentioned slicers) is slightly slower than standard zhop but prevents stringing quite effectively. For CoreXY printers, this is the way to go in my opinion. "ramp" (called "Slope" in mentioned slicers), is faster than standard zhop and also reduces stringing compared to standard, however less than "helix". This is the way to go for bed slingers imo. Neither of those zhop styles is considered experimental in the slicers and I therefore believe that firmware zhop should include these options. In fact, I'd rather see standard zhop excluded because it is definitely the inferior option to "ramp" and "helix".
Yes, that was a lot of fun. My daughter loves the lattice cubes torture test :) To some extent, your conclusion is right. AFAIK, current slicer implementations do not change acceleration settings for the retraction and zhop moves. Having access to the maximum values allowed on the printer, I included the change of these settings for the firmware retraction moves. That's why the results with FW retraction are (slightly) better than with slicer retraction. Of course, this could be implemented on the slicer. However, this would require the user to input the correct allowed accelerations in the slicer...And then we end up with above discussion again: which settings should be on the slicer and which ones on the firmware.
This is correct, Currently only BambuStudio and Orca Slicer offer helix and ramp. For the reasons mentioned above, I think the firmware is the best place to offer this functionality to the user.
Understood. In many cases, the verbose setting issues messages to the user, which should be changed to errors anyways. I am happy to change this accordingly.
The user may change retraction settings at runtime during a print. If the retract state is cleared (e.g. at the end of a print or after canceling a print), the question arises whether or not the changes made at runtime, using the SET_RETRACTION command, shall be kept for the next print or not. If the config_params_on_clear is set to FALSE, changes are kept and vice versa. The Standard value is TRUE. I believe that the user should have the possibility to make this choice himself.
I volunteer to implement this :)
No issue, this is in fact a perfect case to use Macros. I'll remove accordingly.
It is my sincere honor. Klipper is a great firmware and project. I have used Klipper pretty much since my first day in the 3D printing. The potential of the architecture is tremendous, and I really believe that we should make full use of it. Ultimately, it is this great architecture which can enable really smart printers. My contribution is a push in this direction, and I therefore hope that if finds your and the community's approval. Cheers, |
For what it is worth, from a user perspective I think there would ideally be only two pieces of software: the cad software, and the 3d printer. From a user perspective I think having a separate "slicer" step is rather bizarre. Consider a 2d-printer, would it make sense for users to open a file in a word processor, then save it to some intermediate file, open it in some "page layout program", and then send it to their ink printer as the final step? I much prefer just hitting "print" and getting a nice printout of what was on my screen. Alas, we have the separate "slicer" step as a legacy of 3d printing. From a developer point of view, to me, the "slicer" is the software that represents the "planning" stage. (It would have been preferable if that software was a "library" of sorts, or otherwise hidden from the overall user experience, but the "planning" software is still needed.) That "slicing" software takes an object and produces a series of discrete steps, that in total will result in the creation of the requested object. The 3d printer firmware (Klipper) is tasked with executing each of those individual steps reliably. That is, in general, Klipper doesn't know the "why" of each step, nor what the future steps will be, nor what all the past steps were - it primarily focuses on performing each discrete step, mainly one step at a time. That is why it is important that Klipper always execute each step faithfully, or report an error. It can't make guesses on what actions to take on each step, because failure to follow the steps will throw off the whole plan. Beyond the philosophical, in practice it leads to terrible results. Users trying to figure out why their prints are coming out with low quality and no clues to explain why the printer is behaving erratic.
I see bed_mesh implemented in Klipper because it improves its ability to faithfully move from one coordinate to anther coordinate. The slicer is not tasked with moving each motor - it's tasked with specifying a move from location to another in cartesian coordinates (relative to the bed). We know that in some setups the bed is not flat, so the firmware can compensate for that and better accomplish the requested movement step. That is, it can faithfully move the toolhead horizontally (relative to the bed) as it was requested to do. Similarly with pressure advance - the slicer is requesting a move with a particular volume (or cross sectional area) of filament. Klipper implements pressure advance so that it can better accomplish each extrusion step. That is, it can adjust the extruder stepper motor signals so that there is a more consistent volume at each point along the requested extrusion movement.
That case seems to me to be "guessing what the user really wants". It is important to me that Klipper not do that. If the user made a request to take a particular action then Klipper should either take that action or report an error.
For what it is worth, this seems quirky to me. If I understand you correctly it would set a state in Klipper such that it would change the behavior of future movement commands. That seems like it could lead to a lot of confusion and I'm not sure it is a good fit for Klipper. Thanks again for working on this. As high-level feedback, though, I think it is worth pointing out that I don't personally think of z hop as a particularly compelling feature. I don't use z hop on any of my printers. If I give advice to new users, my advice is to not enable z hop. I've found it leads to blobbing, zits, increased ooze, and longer print times. With good retraction and pressure advance, I've found that z hop isn't needed on my printers. I'm also not aware of users clamouring for improved z hop support. I understand every printer is different, some exotic filaments need particular settings, and there are certainly good optimizations I'm not aware of. I only point this out because we seem to be having some pretty lengthy high-level discussions on what I would consider a "niche feature". I'll try to give some thought on how we could improve Klipper so that more features like the above could be implemented without having to go through a lengthy code review process. It's clear that z hop is too complex for macros, but maybe Klipper could be enhanced in some other way to make it more modular. I'll give it some thought. Thanks again. I appreciate your contributions. |
Personally, I do see value in z-hop, especially in slower printers as it avoids scarring of surfaces while the hot nozzle moves above them. I normally use a 0.2 or 0.4 z-hop as I found that to be enough to get a perfect smooth print surface. |
Please let my add my 2ct from my very personal user perspective. Since changing over from Marlin, I've learned to value most of Klippers functionality and the versatility of the macro language, but the one thing I was always missing is a decent implementation of z-hop. I've tested and quickly abandoned some of the publicly available attempts to implement this in macros for basically the same reasons @flopana77 mentions in their motivation to create this PR in the first place. I understand that there are reasons not to use z-hop, and there may be combinations of printers, materials and slicing skills that can do perfectly without. But then, the same may hold true for a number of other Klipper features that are highly valued by the part of the community that needs them. Personally, I see the value in z-hop as a firmware feature and I'd highly appreciate this PR to be accepted rather sooner than later. My personal philosophy -and I'm far from getting there- is to let the slicer produce gcode that can work with different types of materials - some of which may require z-hop, maybe depending on their age. Also, being able to dial in the z-hop settings with the calibration capabilities of Klipper or changing them midprint where necessary would be a huge benefit. Regarding the different styles of z-hop as proposed by this PR: I'm not quite seeing the point as to how there would be any guessing involved: As the user, I decide if I want the head to raise immediately (traditional z-hop) or avoid the chances for blobs by raising and lowering while moving to the new position (z-hop with ramp). In both cases, by choosing the z-hop mode, I know how the printer will move, even when I tell Klipper to not move directly from the position of retract to the next position, by choosing spiral mode. For me as a user, this while affair appears to be no more quirky (as in "not quirky at all") than the firmware modulating extruder moves to perform pressure-advance, or axis moves to perform skew correction or input shaping. If the printer ran into physical limits triggering an error and shutting down the firmware, ruining an otherwise perfect print, I'd find that rather annoying, well knowing that I should have reduced the available print volume in the slicer just because I might decide later to run the print with z-hop enabled. From a user perspective, I find it reassuring to know that the z-hop implementation will rather limit z-hop moves to stay within the physical print volume than provoking that error. Actually, I'd expect that kind of safe-guard. Remembering my first attempts at macros, I found it quite questionable, how a stupid mistake on my part, that would move the head outside the bed area, would provoke an error of the same severity as a thermal runaway, leading to firmware shutdown, loss of hotend cooling and eventually heat creep if not restarted promptly. Or that the same shutdown occurs just by saving a setting. But that is another high level discussion 😃 |
Hi Kevin. I agree that the slicer step is somewhat quirky and that an integration of it in the firmware would be the way to go. Re: standard, helix and ramp zhop --> Standard and helix lift the nozzle vertically after retracting the filament and before the upcoming travel move. Ramp retracts the filament and combines the vertical zhop move with the upcoming travel move. Above and below figures should make this better understandable. After the zhop height is reached, all three styles behave exactly the same, executing all moves with the zhop offset considered until unretracted. Re: raising an error if the slicer has issued an illegal command versus Klipper being smart enough to figure this out and making sure the print is executed as the user intended --> I believe the majority of users would go for the latter. Please don't misunderstand this statement. I fully agree that Klipper should NEVER alter moves if those can be executed without altering the printed object and without damaging the printer. Travel moves in Z direction, like zhop, do not impact the printed object and hence, checking if those travel moves would go out of range prevents otherwise unnecessarily failed or stopped prints IMHO. Re philosophical discussions --> I certainly did not intend to question the place of bed mesh leveling, pressure advance, input shaping and all the other great features in Klipper that make it the best firmware around! Rather than that, I wanted to point out that firmware retraction, zhop, wiping, etc. aim at improving print quality and reliability and therefore also belong into the firmware. Preventing oozing and saving curly prints are not actions a user typically choses to do but rather has to do to get a good print. Thus, I admit that zhop is not a convenience feature like bed mesh but rather a safety feature that allows increasing the success rate of difficult prints. Re users clamouring for improved z hop support --> Before I started working on this, I read the contribution guidelines. Those mention that contributions should have a real life impact of at least 100 users. Consodering a few conversations I followed on reddit in te past, counting the likes the PR has received so far, plus looking at reactions I saw only on teachingTechs video on Firmware retraction (see below on comments directed at Klipper), the user base that actively voiced their desire for this feature stands around 50 now. I believe that it is safe to assume that the grey number is considerably higher and thus the threshold is easily surpassed. I guess @pedrolamas and @gandy92 point in a similar direction. Finally, I would appreciate your advice on how to proceed. I am happy to restructure the PR, strip features or close the PR altogether. I am a huge fan of your work and trust that you will give it due consideration. Cheers PS: Sorry, I'm not good at writing short stuff it seems :) |
This is a perfect example of how user perspectives might vary: |
I think there are 2 possible solutions
From user experience, this z hop feature works great, I've been printing with helix pretty much since the PR on my voron v0. |
Hi Sineos.
I would hate this as well and admit that my PR is incomplete in this point. I guess the key issue here is maintaining predictability for the user. My approach here would be to provide the user with a warning in case the printer did not perform a requested action. If the user considers this an undesired behavior, because he prefers the printer to perform commands no matter if they may stop a print, then the user can choose to disable these safeguards. This is exactly what the car industry is doing with all the driving aids. They are enabled by default, issue a warning if the behavior of the car is altered by the driving aid and can be turned off if the driver if he chooses to do so (most manufacturers allow turning off safety features..not all). This is easy to implement and follows Matszwe02's suggestion. That said, @Matszwe02, I am happy to read that the code works well for you. As I mentioned over in my repo, I worked on preventing helix moves throwing an error when moving out of the build volume. Given the discussion we are having here on whether such features are in-line with Klipper's overall philosophy, I'll start a separate branch where you can get access to the state of this work if you are interested =) Cheers |
My 2ct:
I have seen too many processes in my professional life that work by a "shit in / shit out, but who cares" philosophy. This and also my support activities here have taught me a number of things:
And sorry to say, I do not agree with your automotive example: They allow you to turn off functions that have an "assistance" or "comfort" character, but they do not allow you to turn off core safety features. And lastly: I really do not understand this widespread notion to allow apparently faulty input and expect the software to magically heal this. |
Hi Sineos. I share your point of view, especially regarding errors and users not fixing the root cause, and I additionally believe that user errors, which can be fixed by the firmware, should be fixed with a warning. Plastic and user time are money. Hence, if the firmware aborts a print, that could also have completed successfully with a warning, the firmware basically wastes user money. |
I get both of your sides so I would propose a compromise: |
Thanks. I agree that z hop seems like a useful feature to add to Klipper's firmware_retract module. I apologize if my comments came across as negative or dismissive. I did want to make it clear though that there is a challenge in me reviewing z hop as I don't use the feature. I also think that the Klipper development process could be improved - in particular it may be preferable to have some type of system where these kinds of features could be reasonably added to Klipper without a lengthy code review. I'm not sure the best way to proceed on that, and I will continue to give it thought.
If you are looking to merge in the short term, my advice would be to simplify the initial implementation - simple vertical z hop, no "smart" error avoidance, minimal unrelated code changes (eg, avoid calling SET_VELOCITY_LIMIT). If you feel other features are mandatory then I suspect we're looking at a longer time frame (likely months out). As I think we (Klipper community) may need to figure out how we'll handle the growing range of features over the long term.
My main comments on this PR are above. I'm expanding on my comments on "raise errors vs try to proceed anyway" to provide some additional context on my thoughts on this topic.
I understand. I can certainly see where some users would want that. I, however, definitely do not want this behavior on my printers. I've been "scarred" by software "trying to guess what I really want" too many times. It was one of the core reasons why I decided to write my own 3d printer firmware. The main issue is that the programmers consistently guessed wrong. They thought the circumstances leading to the error were trivial, but too often they were actually due to some other fundamental problem (for example, some other incorrect code placed the toolhead too close to a boundary). The "guessing about errors" code then magnified the problem. Ultimately I was left with "spaghetti" and no reasonable way to figure out how I got into that crazy state. If I had just been told there was a problem, I could have easily fixed it and then gone on to enjoy hundreds of hours of excellent quality prints. The inverse approach led me to lose massive amounts of lost time trying to "guess what other people guessed" so I could "guess how to avoid those guesses".. As I said above, I've been "scarred" by "error avoidance". I do not claim that my approach (raise an error on an invalid request) is definitely the "right way" or even the "best way". It will, however, continue to be my approach.
Z hop definitely does impact the printed object. If it didn't impact the printed objects we wouldn't consider adding it to Klipper.
My comments on "guessing" are about "error avoidance". The act of determining a well formed user request is not valid and commanding some other action in its place (or no action at all) to avoid presenting the user with an error. My comments on the type of z hop (spiral, vertical, ramp) is not related.
This is what Klipper does today in practice. An error raised by a g-code command will cause the virtual_sdcard system to halt reading of future commands. The toolhead will stop moving. The frontends will alert the user of an issue. The heaters and motors remain active. A user can take an action and proceed if they so choose. Admittedly, it would be challenging for a user to meaningfully proceed after such an error (if they are even immediately present to address it). There does seems to be some confusion on Klipper's error handling though. Klipper has two distinct error handling systems - an error and a shutdown. The shutdown system is intended for safety issues (a notable increase in the risk to the printer hardware, its environment, or its users). A shutdown is designed to rapidly turn off all heaters and motors. A typical g-code error does not invoke a shutdown event. It is propagated up to the higher layers with the intent of stopping the "scheduled plan" to alert the user that the scheduled events could not be completed as requested. Cheers, |
Hi Kevin
Thank you and certainly no apology needed. Maybe it is time for you to start using zhop once available in Klipper :p
Thank you for your advice! I will condense the PR to submit a "minimum viable product" version with the following features:
Please confirm if this is all ok for a short-term merge or what else I shall change. Also, should I remove the extensive commenting?
This is well understood. I would suggest including a section in the "Developer Documentation" document which clearly outlines the design philosophy of Klipper, let's call it "Design Requirements for Submissions". The section would states principles like:
For what it is worth, after all the (hopefully fruitful and at least somewhat enjoyable) conversations above, this may then just be the most valuable part of this whole PR :p
Sorry, bad formulation from my side. I meant that zhop moves do not impact the shape of the printed object given that zhop are travel moves and not extrusion moves. What I wanted to express was that changing extrusion moves is a NoGo even for me...
Would it be acceptable to save the gcode state upon error occurrence (including the virtual SD card line is applicable) so that the user has the possibility of resuming a print that was stopped due to an error? Also, to ensure that the print is not ruined with blobs when the printer runs into an error, would it be acceptable to raise the nozzle and have the toolhead go to homing position? If so, I may look into this... Cheers and thanks for taking the time to comment in detail :) |
Thanks. A minimum version I think would help me review the code and get it merged. I'm struggling to comment on your list of proposed changes though, largely because the list seems to be relative to the current PR, which I don't have a good understanding of. That said, the list seems a bit expansive to me. I think a good first step would be to target a minimal implementation of z hop on retract - a vertical raise of the toolhead on Cheers, |
Hi Kevin
Sorry for that. No issue, I'll follow your guideline and work on this minimalistic version asap.
BTW, I didn't mean to comment my last post in detail but actually the entire discussion ;) Once I have a minimalistic version of the PR available, I'll close this one and start a new one. Cheers |
Hi Florian, I found a critical bug in your |
Hi Matszwe02. Thanks for pointing this out. I was working on some new stuff on the dev branch and stopped midway because I decided getting my CR10S Pro back to life. Can you check if the error occurs on my master branch also? As far as the initial code goes, the error you describe should not happen. Hence, this is probably an artefact from my half-started, half-finished experiment on the dev branch. In any case, please send me the offending gcode to have a look. Cheers. Florian |
Hi All. Sorry for the delay. I am still busy with real-world stuff at the moment. I hope to get to coding the spec'ed down version in the coming week. Cheers, Florian |
klippy/extras/_ToDos | ||
klippy/extras/tmc.py | ||
klippy/extras/gcode_shell_command.py | ||
.vscode |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not think that these are valid changes. E.g. gcode_shell_command.py
is an unofficial "extra" and not part of Klipper main-line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct. Forget about these changes, they are not meant for merging. I am testing the minimal version of the zhop code at the moment. Once it is working, this PR will be closed, and a "clean" PR will be submitted. Cheers. Florian
Dear All. As previously mentioned, I am closing this PR in favor of the minimalistic zhop code as per PR #6311 . Cheers, Florian |
Summary of this Pull request
Following popular demand, this submission finally brings reliable Z-Hop to Klipper :)
It enables nozzle lifting (zhop) when retracting using G10 command; fully configurable at runtime; in absolute or relative mode.
In addition, the submission introduces three different zhop movement styles (standard, ramp and helix) suitable for different use cases, see below. Clears retraction reliably to prevent nozzle crashes and other unwanted behavior after changes of the printing state (start, cancel or finish prints from virtual SD Card as well as via GCode streaming).
As addon, if also fixes a bug in the implementation as described below.
Below explanation and description is intended to be as complete as possible to facilitate the review process.
I did a self-review of this submission according to the steps in the CONTRIBUTING document and everything looks good to me. The code was also tested intensively, see below, without any issues.
Note: Apologies for the 5 follow up commits. Will do debugging on my dev branch in future :)
Is the submission free of defects and is it ready to be widely deployed?
The following safeguards were implemented, and tests were performed prior to this submission:
The code was tested intensively using a test macro with a plethora of edge cases (included in the submission):
Real-world test prints were performed including:
The previously identified main failure cases concerning z_hop functionality have been addressed as follows:
Additional failure cases concerning z_hop functionality that had not been identified so far have been addressed as follows:
Additional failure cases concerning extruder moves that had not been identified so far have been addressed as follows:
The code is fully commented to allow easy understanding and review. Comments can be removed before merge, if required.
Besides Python modules (firmware_retraction.py and print_stats.py), Status_Reference.md, G-Codes.md and Config_Reference.md were revised to account for the additional functionality and make it easily accessible to the User.
No code is commented out, all to-do references and comments on past implementations have been removed.
Regression test macros and configs were included (therefore the additional commits...) to test behavior with and without Virtual SD Card module.
Does the submission provide a “high impact” benefit to real-world users performing real-world tasks?
Who is the target audience and what size does it have?
What is the benefit of the contribution to the community?
SAFER PRINTING USING FIRMWARE RETRACTION WITH ZHOP
As a result of this unsatisfied user need, macro implementations of zhop are being used by the community. These are prone to cause unwanted behavior, which may damage printers running Klipper firmware, even though the Klipper firmware is not to blame:
LESS RESOURCE INTENSIVE THAN MACRO IMPLEMENTATIONS PREVENTS UNNECESSARY CPU LOAD
THIS PULL REQUEST INCLUDES NEW Z_HOP MOVE STYLES, NAMELY RAMP ZHOP AND HELIX ZHOP AS WELL AS M101 AND M103 ALIASES USED BY SIMPLIFY3D
FIRMWARE RETRACTION INCLUDING ZHOP SIMPLIFIES THE OVERALL WORKFLOW
FLEXIBILITY TO CHANGE NOT ONLY RETRACTION PARAMETERS BUT ALSO ZHOP HEIGHT AND ZHOP STYLE AT RUNTIME
REAL-WORLD PRINTS SHOWED PERFORMANCE BENEFITS USING FIRMWARE RETRACTION WITH Z_HOP RATHER THAN SLICER RETRACTION
Note that all prints were carried out with a bowder extruder with long tube (over 600mm) to amplify stringing issues.
Retraction tower:
Slicer retraction: Minimum retraction 3mm, above the minimum retraction stringing reoccurred, time to print was 21:17 minutes.
FW Retraction “Standard”: Minimum retraction 3mm, above the minimum retraction stringing reoccurred but less than with slicer retraction due to higher acceleration set, time to print was 21:15 minutes.
FW Retraction “Ramp”: Minimum retraction 3mm, above the minimum retraction stringing reoccurred but considerably less than with slicer retraction due to higher acceleration set and diagonal move that prevents string formation during vertical movement before the horizontal travel move, time to print was 21:05 minutes.
FW Retraction “Helix”: Minimum retraction 2.5mm and hence less than all others, above the minimum retraction stringing did not reoccur, time to print was 22:11 minutes.
It is concluded that the FW Retraction with “Standard” and “Ramp” move is faster to print in most cases with slightly improved stringing. FW Retraction with “Helix” move is slightly slower but delivers superior stringing behavior. The shorter filament retraction moves further helps the longevity of the extruder, bowden tubes and couplings.
The Impossible print:
Slicer retraction: The print failed on several objects shortly before completion. Setting the optimal 3mm retraction length still resulted in visible stringing.
FW Retraction “Ramp”: The print failed on only one object shortly before completion. Setting the optimal 3mm retraction length resulted in noticeably less visible stringing compared to Slicer retraction.
It is concluded that FW Retraction with “Ramp” may be less prone to knocking prints off the build plate than Slicer retraction at comparable print times (sorry, my timer died in the middle of the ramp print…from Mainsail history, the print times are 20 sec apart, however they started at different bed temperatures).
Benchy (not super high speed…):
Slicer retraction: Print completed successfully. With optimal retraction length, limited stringing is visible. Print time was 38:55 minutes.
FW Retraction “Standard”: Print completed successfully. With optimal retraction length, limited stringing is visible, slightly less than Slicer retraction. Print time was 38:40 minutes.
It is concluded that FW Retraction slightly improves print times at the same quality as slicer retraction.
Lattice Cube:
Slicer retraction: Print completed successfully. With the optimal retraction length of 3mm, noticeable fine stringing is visible. Print time was 3 hours and 36:10 minutes.
FW Retraction “Helix”: Over 11800 retraction and zhop moves were performed by the firmware without issues. These include 571 retraction moves on layer change, which were previously the root cause of Failure Case 1. With the optimal retraction length of 2.5mm, fine stringing is still visible, however to a much lesser extent than with slicer retraction making for noticeably improved print quality. Print time was 3 hours and 38:11 minutes and thus comparable.
It is concluded that FW retraction with Helix move zhop improves print quality at the cost of minimal print time increase. A potential future improvement could be to combine helix and ramp movement to achieve better print quality without incurring minimally increased print times.
Does the submission burden users with options they cannot reasonably configure?
Is the copyright of the submission clear, non-gratuitous, and compatible?
Yes. Copyright was declared on the firmware_retraction.py file due to a basically complete re-write. No code was taken from 3rd party sources. The submission is signed-off as required.
Does the submission follow guidelines specified in the Klipper documentation?
Yes, the guidelines established in the Code_Overview.md regarding adding a host module have been followed.
Is the Klipper documentation updated to reflect new changes?
Yes:
I hope you find this contribution worthy to get merged and look forward to any questions that may arise :)