Basic Information:
Printer Model: Creality Ender 5
MCU / Printerboard: bigtreetech skr mini e3 v3.0 32 bit mainboard & Creality 3D silent mainboard V4.2.7
Host / SBC: RPI4
klippy.log: klippy.log (1.6 MB)
Hey All,
I’m currently in the process of building a custom printer, and I need help with getting the kinematics right. The setup is as follows:
The System
The system consists of a 5-axis printer (XYZBA) with a rotating convex cylindrical bed: X B and Z are linear movements, where B is generally passive as its only purpose is to keep the nozzle on the center of the spinning bed (it’s the original Y linear axis). Y rotates the print bed, and A rotates the hotend so that its perpendicular to the print surface. Stepper B and A are both manually added steppers. The print bed, or substrate, is actually printed with a polymer as well, so the final print is a product of the substrate and the pattern that is printed on top. I’m printing single line patterns (in vase mode style) on top of the substrate, with a high flow rate (1mm nozzle, approximately 2mm layer thickness).
Up to this point, I have been using cartesian kinematics in my printer config, and basically wrote my own python script to write the gcode in such a way that makes it suitable for the setup of the printer. Here is a quick summary of the current workflow:
- A Rhino Grasshopper script that does two things:
a. Generate pattern and export list array of x,y,z coordinates
b. Generate an array of radii of the substrate (the radius of each layer height (0.2mm)) - The data is then imported into a python script, which does the following things:
a. Generating Gcode: Iterate through the pattern coordinates and convert data into gcode suitable for printing on top of the substrate. The Z coordinates are calculated using the values from the radii array. Additionally, the angle between the different radii is calculated to define the value for A, retrieving a value that ensures that the extruder will always be perpendicular to the current layer.
b. Linear to Angular Velocity and Extrusion mapping: To account for the differences in linear and angular velocity, the program calculates the correct feedrate by looking at the translation of x and y and then calculates the actual movement lenghts across y by using the current radius (and additional z height), using the formula:
actual_y = delta_y * (current_circumference / rotation_distance)
This value is then used to adjust the speed, by comparing the real distance of XY, and commanded distance of XY, and changing the feedrate and exrusion value accordingly. The rotation_distance corresponds to the stepper_Y rotation_distance in the printer configuration, which is set to 40.
The Problem
So far I’ve made good progress in getting the system to work, but I’m currently stuck on a problem that I have trouble resolving. During printing, there is a imperfection that keeps reoccurring in my print. When I try to print rounded corners, the printer keeps over extruding material at the beginning of the corner, and it also tends to over extrude at the end of the corner (see image). I suspect it has to do with the fact that the printer has to slow down before initiating the corner, even though I’m already “manually” trying to accomplish this using the previously mentioned linear to angular velocity logic.
So, here are some things I have tried to resolve the issue:
- Ensure that acceleration and velocity of all axis are the same to reduce dwelling of the nozzle. I reasoned that when the printer initiated the rounded corner, both X and Z axis start to move and their acceleration could cause a delay in the printers path, causing filament to ooze out. But tweaking these settings led to no succes.
- I tried tweaking Pressure Advance ¶ which did influence the imperfection. A high PA value resulted in underextrusion, and a low PA value resulted in overextrusion. However, there was no golden ratio where the imperfection would cease to exist. I also hypothesized later that PA should be turned of anyway, because when gradually converting angular motion to linear motion (or vise versa), and changing the feedrate acordingly, the actual print speed on the surface remains the same (therefore, PA can be turned of right..?).
- I also tried tweaking the square corner velocity. I reasoned this could be the problem, because the domain of the initial G-code height is limited to Y = 0 to Y = 40, which corresponds to the rotation distance of 40. In reality, the gcode Y coordinates are being stretched out on the substrate. So, the initial rounded corner might be small, but is actually bigger when printed. Therefore, I tried tweaking the square corner velocity, suspecting that when it’s the same as the normal velocity there would be no acceleration to deceleration before the corners. In parallel, I also tried different values for the min. cruise ratio, but both inquiries led to no succes.
My Question
My hypothesis is that the problem that I’m currently facing is due to the function mentioned in 2b: Linear to Angular Velocity and Extrusion mapping. Because what I’m essentially doing here is applying the desired kinematics in higher level code, as a workaround for the printers generic cartesian kinematics, and this might be causing some conflicts. The system thinks its slowing down and the extrusion suddenly changes, which I can imagine could be confusing for the underlying machine settings.
Therefore, I think it would probably be sensible to consider making my own kinematics.py file, where I define the correct kinematics in lower level code. However, I’m starting to realize I don’t know enough about kinematics and Klipper’s low-level Python code, which makes this a challenging task. My initial idea was to maybe rewrite parts of the polar.py kinematics, because my system shares some similarities with this configuration. Or maybe I could consider building a kinematics file that uses a cylindrical coordinate system?
I’m hoping that someone can give me some advice on how to tackle this issue. Here are some specific questions that I need help with:
- More general: Is it likely to assume that the current problem I’m facing is due to the aforementioned reason, mainly the mismatch between kinematic/general configuration of the klipper configuration and my own code, and could you elaborate on why and where this problem actually occurs? Or do you think the problem lies elsewhere?
- Could there be another work around that might be worth considering, that could lead to good print results without the need for rewriting low level code?
- If you think writing my own kinematics file is a sensible direction, how should I approach creating this custom configuration? Does it make sense to tweak the polar.py kinematics file, like rewriting it into cylindrical coordinates? And what are elements of the klipper code that would require tweaking? (e.g. elements of kinematics.py / stepper / toolhead.py)?
I’m hoping someone can give me some guidance / advice on this problem. I hope that I’ve shared enough information about the system, but, if needed, I can provide more information.