Mesh compensation which accounts for G10 X&Y tool offsets
-
@fcwilt Here are some videos;
Height map was set at 50 , 0 , 50 to make it really clear for the video
Movement Left printhead; https://photos.app.goo.gl/FJuenGCBoZD6ia7j6
Movement Right printhead; https://photos.app.goo.gl/8H9C4EzgjiuiZuvc7
Movement Mirrored; https://photos.app.goo.gl/6M6dbW1AvHj1x8A36(uploaded like this because of limited upload size)
-
Mesh compensation cannot work for two printheads at the same time - it could adjust the bed for one or the other, but not both.
The video suggests it is applying the entire heightmap twice, once to the left half and again to right half of the bed.
Which, in a way, makes sense since mirroring essentially splits the bed into two equal parts.
However it does no good at all as the heightmap doesn't match either half of the bed.
Seems to me you must turn off mesh compensation when mirroring.
Frederick
-
@fcwilt said in Mesh compensation which accounts for G10 X&Y tool offsets:
If the tool is outside the height map nothing seems to be done.
What should happen is that the compensation is applied based on extrapolating a plane that represents the average of the height map.
-
@dc42 said in Mesh compensation which accounts for G10 X&Y tool offsets:
What should happen is that the compensation is applied based on extrapolating a plane that represents the average of the height map.
I will go back and re-test to see if I can verify that.
I didn't see anything obvious during the first test.
Thanks.
Frederick
-
Mesh compensation cannot work for two printheads at the same time - it could adjust the bed for one or the other, but not both.
The video suggests it is applying the entire heightmap twice, once to the left half and again to right half of the bed.
Which, in a way, makes sense since mirroring essentially splits the bed into two equal parts.
However it does no good at all as the heightmap doesn't match either half of the bed.Theoretically it should not, but yet it does actively apply a mesh. It indeed looks like it is applying the same heatmap twice, but in any case it would be better to keep the mesh origin in the middle, and only use the left side. The physical bed does not move.
In our case it is definitely not ideal, nor perfectly mirrored along X=0, but it definitely is significantly better to compensate more than nothing.
I currently got it working with this code;
G1 X0 Y0 F6000 Z10 ; move to controlled position while G90 G91; set to relative G1 X{-var.dualprintingoffset} ; move X to offset position G92 X0; Force new position to X=0 ; Actual position is now 150mm offset compared to assumed position M557 X{var.printxmin, var.printxmax} Y{var.printymin, var.printymax} P{var.pointsx, var.pointsy} ; Define adaptive mesh area around duplication position G29 ; Measure bed. ; Machine assumes this is around X=0 position, while it is actually measuring offset area G1 X0 Y0 F6000 Z10 ; move back to controlled position G92 X{-var.dualprintingoffset}; set position back to original X=0
-
Yes, it does apply compensation but it is using the heightmap for the entire bed and applying it to each half.
What you need to do is take the heightmap for the entire bed, make a copy, and edit it so the numbers for just the left half constitute a heightmap for the entire bed.
Then when mirror is active at least the left side will get accurate mesh compensation whereas the right will get the same which may or may be of any help.
Frederick
-
@fcwilt Correct,
See the code snippet I sent above; it automatically measures a mesh that is offset by the X value of duplication.
It gives the same result as manually offsetting the CSV file.
This indeed gives a good compensation for left half, and the right half follows, which is not ideal but works better than no compensation.
Ideally, you could also do the compensation with user-defined axis ( we have a microZ which moves the X and U printhead up and down) which could be used for mesh compensation like @dwuk3d also mentioned. I guess that requires a huge overhaul of how printing with 2 printheads works in Duet tho.. We could also integrate it into a slicer (post-processing) to send a G1 X, U, Y, Z, V, and W position. But then the slicer also needs to know the mesh heightmap
-
-
@fcwilt
Yes, in short.The G-code is printing between X-50 and X50. When I measure the adaptive mesh over this area (the middle of the bed) and then print in mirror mode, the firmware applies the mesh data from X-50 to X50, even though the print is shifted to an offset region (e.g., X-150 to X-50 with a 100mm offset).
To fix this, I trick RRF into measuring the offset area (X-150 to X-50) while it believes it's probing around X0. This way, when printing, it applies the heightmap it thinks is from X0, but it's actually from the offset area where the print will take place.
-
@SanderLPFRG I like your idea of inflating the mesh compensation and then doing some automatic measuring to see what happens - will be a really good way to test how effective any slicer, or post processor created 'microZ' based mesh compensation is working.
Thinking about doing the mesh compensation in a post processor, which relies on a reasonably up to date mesh file being available offline, I can think of a couple of strategies to how this could work in practice.
a). Do some sort of auto check like you are doing for a few of the worst sample points before every print - and if they are not within an acceptable range - then stop the print and request that it is re-sliced with an up to date mesh file.
b) Another alternative might be to just do a mesh in every print - and then create in the post processor some code that checks a few points in the mesh file to make sure that they are more or less the same as the offline mesh file used to create the print.
Obviously though the ideal would be for RRF to handle Micro Z lifters - but as mentioned I suspect that would get quite complicated - especially when you start going to 4 tools and beyond.
-
-
@dwuk3d The micro-Z compensation is above my knowledge-grade, but the main difficulty remains that there needs to be a centralized program that knows;
- The XYU coordinates of all printing moves
- The offset amount compared to known slicer movement axis to the new positions of toolheads
- The heightmap of the used area of the printed
Then it would need to look up all X and Y coordinates of the print, offset them to generate a T (Offseted X to T1) and U (Offseted X to T2) coordinage, and then create a V movement parameter for the T/Y coordinate, and then a W movement for the U/U coordinate.
BUT, this assumes you do not want to use a taper height
-
@fcwilt It does work, but ofcourse it assumes the Right side is mirrored to the Left side
my duplication start gcode, if anyone wants to use it;
; Setup variables var lefttemp = 0 var righttemp = 0 var bed = 0 var printxmin = 0 var printxmax = 600 var printymin = 0 var printymax = 500 var sizex = 50 var pointsx = 3 var sizey = 50 var pointsy = 3 var purgelength = 15 var initialtool = 0 var leftused = "false" var rightused = "false" var leftfilament = "none" var rightfilament = "none" var leftnozzlesize = 0 var rightnozzlesize = 0 var dualprintingoffset = 167.5 ; Define variables ; Temperature variables set var.lefttemp = param.A ; Extruder temperature set var.righttemp = param.B ; Extruder temperature set var.bed = param.C ; Bed temperature ; Print variables set var.printxmin = param.D ; Left boundry set var.printxmax = param.E ; Right boundry set var.printymin = param.F ; Front boundry set var.printymax = param.H ; Back boundry set var.sizex = {var.printxmax - var.printxmin} set var.sizey = {var.printymax - var.printymin} ; Machine variables set var.initialtool = param.I ; initial tool set var.leftused = param.J ; is right tool used yes/no set var.rightused = param.K ; is right tool used yes/no set var.leftfilament = param.L ; loaded filament type left set var.rightfilament = param.O ; loaded filament type right set var.leftnozzlesize = param.Q ; nozzle diameter left set var.rightnozzlesize = param.R ; nozzle diameter right ; set probing amount for Y if var.sizex <= 150 ; if sizeX is less than 150mm, set probing X amount to 3 set var.pointsx = 3 elif var.sizex <= 350 ; if sizeX is between 150mm and 350mm, set probing X amount to 5 set var.pointsx = 5 elif var.sizex <= 450 ; if sizeX is between 350mm and 450mm, set probing X amount to 7 set var.pointsx = 7 else ; if sizeX is between 450mm and max, set probing X amount to 9 set var.pointsx = 9 ;endif ; set probing amount for Y if var.sizex <= 100 ; if sizeX is less than 100mm, set probing X amount to 3 set var.pointsx = 3 elif var.sizex <= 300 ; if sizeX is between 100mm and 300mm, set probing X amount to 5 set var.pointsx = 5 elif var.sizex <= 400 ; if sizeX is between 300mm and 400mm, set probing X amount to 7 set var.pointsx = 7 else ; if sizeX is between 400mm and max, set probing X amount to 9 set var.pointsx = 9 ;endif ; General settings; G90 ; set absolute coordinates T0 ; Heat up for probing M104 T0 S150 ; set extruder temp for bed leveling M104 T1 S150 ; set extruder temp for bed leveling M140 P0 S{var.bed} ; set bed temperature zone 2 M140 P1 S{var.bed} ; set bed temperature zone 1M109 T0 S150 ; wait for hotend probing temp M109 T1 S150 ; set extruder temp for bed leveling M190 P0 S{var.bed} ; wait for bed temperature zone 1 M190 P1 S{var.bed} ; wait for bed temperature zone 1; Prepare for automatic calibration M302 S140 ; lower cold extrusion limit to 160C G1 E-2 F2400 ; cold retraction M302 S170 ; restore cold extrusion limit G32 ; home printer ; Start mesh offsetting G1 X0 Y0 F6000 Z10 G91 G1 X{-var.dualprintingoffset} ; move X to offset G92 X0; set position back to original ; Actual position is now 150mm offset compared to assumed position M557 X{var.printxmin, var.printxmax} Y{var.printymin, var.printymax} P{var.pointsx, var.pointsy} ; Define adaptive mesh area around X=0 G29 ; Measure bed. ;G30 Z-9999 ; Machine assumes this is around X=0 position, while it is actually measuring offset area G1 X0 Y0 F6000 Z10 G92 X{-var.dualprintingoffset}; set position back to original ; Heat up for printing G90 ; absolute coordinates G1 X-360 U360 Y-240 Z15 F6000; move to park position T2 M109 S{var.lefttemp}
-
@SanderLPFRG Thinking about this a little more
Rather than relying on an offline copy of the mesh file being available, I think I will explore how hard it would be to code some simple mesh compensation into a Macro first, and also whether running a macro on every move would slow down the printing.
I guess if it is possible to read the mesh file into a 2 dimensional global lookup table is the key to this.
If it is - then with some calculations it should be possible to take each XY coordinate and work out which 4 mesh values in the array need to be referenced to calculate the required micro Z offset (with taper adjustment).
If this is practical then all a post processor would need to do is:
- Segment any long extrusion moves within the taper height to be smaller 'mesh size' chunks
- Convert every G0,G1,G2 and G3 within the taper height into a call to the mesh compensation Macro instead.
- The macro would then do the compensation calculation before then doing the actual G0,G1,G2 or G3 call with the MicroZ adjustment added.
UPDATE: fileread() doesn't like the format of the first line of heightmap.csv - so doing the logic in a macro is probably a non starter unless I can find a way to work around this issue.
-
@dwuk3d
I do think the Macro would not be able to be run during printing.But, if running on SBC-mode, you might be able to write a program to process the mesh?? it should be able to call the ".csv" to use it and pre-process it.
might be interesting to call in on some multi-axes printing guys as well!