Height Map Issue
Googling seems to be turning up all sorts of irrelevant results, so I apologize if this is known/fix posted already 100x over. I can't find it.
I made some changes to the delta printer design that's making me recalibrate everything. Just for giggles, before getting things tuned in, I wanted to see the height map. So I did g32 S2 to setup the autoleveling, g0 z5 to get the head close to the bed, and hit measure points in the height map window. I got some frustratingly annoying results. I'll post the relevant log, and the copy results to clipboard output. Its missing a row and a column. All zeros. No reason for it, it measured the points, had valid results, they just didn't make it to the height map window. No, I didn't kill an in process measurement, and I killed repetier host and the printer just to make sure. The odd thing is, disable autoleveling, and it comes out just fine....showing me just how tilted my bed is Yes, I know I should fix that, and I will, but at this point, I can't get the height map working...It did this to me before, but it went away on its own. No idea what happened, why this is happening, how to fix it, etc.
Any help?
Edit: Should also mention, firmware is 0.92.4 and host is 1.5.6
Comments
Hmmm try the data again....
15:56:49.066 : N881 G1 X-53.33 Y-80 Z5 F4800 *13
15:56:50.981 : Z-probe:4.86 X:-99.45 Y:-62.43 zCorr:0.00
15:56:51.202 : N883 G1 X-26.67 Y-80 Z5 F4800 *12
15:56:52.083 : Z-probe:4.78 X:-72.78 Y:-62.43 zCorr:0.00
15:56:52.299 : N885 G1 X0 Y-80 Z5 F4800 *60
15:56:53.180 : Z-probe:4.74 X:-46.12 Y:-62.43 zCorr:0.00
15:56:53.394 : N887 G1 X26.67 Y-80 Z5 F4800 *37
15:56:54.277 : Z-probe:4.81 X:-19.44 Y:-62.43 zCorr:0.00
15:56:54.494 : N889 G1 X53.33 Y-80 Z5 F4800 *40
15:56:55.383 : Z-probe:4.89 X:7.22 Y:-62.43 zCorr:0.00
15:56:55.605 : N891 G1 X80 Y-80 Z5 F4800 *1
15:56:56.506 : Z-probe:5.05 X:33.88 Y:-62.42 zCorr:0.00
15:56:56.737 : N893 G1 X-80 Y-53.33 Z5 F4800 *14
15:56:57.642 : Z-probe:5.15 X:60.55 Y:-62.42 zCorr:0.00
15:56:57.892 : N895 G1 X-53.33 Y-53.33 Z5 F4800 *40
15:57:00.858 : Z-probe:4.90 X:-99.45 Y:-35.76 zCorr:0.00
15:57:01.079 : N897 G1 X-26.67 Y-53.33 Z5 F4800 *41
15:57:01.967 : Z-probe:4.86 X:-72.78 Y:-35.76 zCorr:0.00
15:57:02.187 : N899 G1 X0 Y-53.33 Z5 F4800 *17
15:57:03.074 : Z-probe:4.86 X:-46.12 Y:-35.76 zCorr:0.00
15:57:03.293 : N901 G1 X26.67 Y-53.33 Z5 F4800 *10
15:57:04.181 : Z-probe:4.92 X:-19.45 Y:-35.76 zCorr:0.00
15:57:04.404 : N903 G1 X53.33 Y-53.33 Z5 F4800 *11
15:57:05.296 : Z-probe:4.95 X:7.22 Y:-35.76 zCorr:0.00
15:57:05.521 : N905 G1 X80 Y-53.33 Z5 F4800 *45
15:57:06.428 : Z-probe:5.04 X:33.88 Y:-35.76 zCorr:0.00
15:57:06.658 : N907 G1 X-80 Y-26.67 Z5 F4800 *1
15:57:07.570 : Z-probe:5.20 X:60.54 Y:-35.75 zCorr:0.00
15:57:07.824 : N909 G1 X-53.33 Y-26.67 Z5 F4800 *47
15:57:10.799 : Z-probe:5.05 X:-99.45 Y:-9.10 zCorr:0.00
15:57:11.028 : N911 G1 X-26.67 Y-26.67 Z5 F4800 *37
15:57:11.925 : Z-probe:5.06 X:-72.78 Y:-9.10 zCorr:0.00
15:57:12.154 : N913 G1 X0 Y-26.67 Z5 F4800 *17
15:57:13.051 : Z-probe:5.05 X:-46.12 Y:-9.09 zCorr:0.00
15:57:13.280 : N915 G1 X26.67 Y-26.67 Z5 F4800 *12
15:57:14.179 : Z-probe:5.09 X:-19.45 Y:-9.10 zCorr:0.00
15:57:14.410 : N917 G1 X53.33 Y-26.67 Z5 F4800 *13
15:57:15.309 : Z-probe:5.12 X:7.22 Y:-9.09 zCorr:0.00
15:57:15.542 : N919 G1 X80 Y-26.67 Z5 F4800 *35
15:57:16.447 : Z-probe:5.22 X:33.88 Y:-9.09 zCorr:0.00
15:57:16.687 : N921 G1 X-80 Y0 Z5 F4800 *51
15:57:17.596 : Z-probe:5.28 X:60.54 Y:-9.09 zCorr:0.00
15:57:17.852 : N923 G1 X-53.33 Y0 Z5 F4800 *17
15:57:20.836 : Z-probe:5.28 X:-99.45 Y:17.58 zCorr:0.00
15:57:21.076 : N925 G1 X-26.67 Y0 Z5 F4800 *20
15:57:21.986 : Z-probe:5.34 X:-72.79 Y:17.58 zCorr:0.00
15:57:22.229 : N927 G1 X0 Y0 Z5 F4800 *32
15:57:23.142 : Z-probe:5.39 X:-46.13 Y:17.58 zCorr:0.00
15:57:23.388 : N929 G1 X26.67 Y0 Z5 F4800 *53
15:57:24.298 : Z-probe:5.36 X:-19.45 Y:17.58 zCorr:0.00
15:57:24.543 : N931 G1 X53.33 Y0 Z5 F4800 *63
15:57:25.457 : Z-probe:5.42 X:7.21 Y:17.58 zCorr:0.00
15:57:25.704 : N933 G1 X80 Y0 Z5 F4800 *29
15:57:26.620 : Z-probe:5.44 X:33.87 Y:17.58 zCorr:0.00
15:57:26.869 : N935 G1 X-80 Y26.67 Z5 F4800 *45
15:57:27.790 : Z-probe:5.51 X:60.54 Y:17.58 zCorr:0.00
15:57:28.065 : N937 G1 X-53.33 Y26.67 Z5 F4800 *15
15:57:31.055 : Z-probe:5.38 X:-99.46 Y:44.25 zCorr:0.00
15:57:31.300 : N939 G1 X-26.67 Y26.67 Z5 F4800 *2
15:57:32.228 : Z-probe:5.59 X:-72.79 Y:44.26 zCorr:0.00
15:57:32.484 : N941 G1 X0 Y26.67 Z5 F4800 *59
15:57:33.407 : Z-probe:5.61 X:-46.13 Y:44.25 zCorr:0.00
15:57:33.664 : N943 G1 X26.67 Y26.67 Z5 F4800 *34
15:57:34.589 : Z-probe:5.63 X:-19.46 Y:44.25 zCorr:0.00
15:57:34.847 : N945 G1 X53.33 Y26.67 Z5 F4800 *39
15:57:35.771 : Z-probe:5.64 X:7.21 Y:44.26 zCorr:0.00
15:57:36.029 : N947 G1 X80 Y26.67 Z5 F4800 *5
15:57:36.958 : Z-probe:5.69 X:33.87 Y:44.25 zCorr:0.00
15:57:37.219 : N949 G1 X-80 Y53.33 Z5 F4800 *37
15:57:38.147 : Z-probe:5.70 X:60.54 Y:44.26 zCorr:0.00
15:57:38.423 : N951 G1 X-53.33 Y53.33 Z5 F4800 *12
15:57:41.416 : Z-probe:5.42 X:-99.46 Y:70.91 zCorr:0.00
15:57:41.663 : N953 G1 X-26.67 Y53.33 Z5 F4800 *13
15:57:42.591 : Z-probe:5.68 X:-72.79 Y:70.92 zCorr:0.00
15:57:42.852 : N955 G1 X0 Y53.33 Z5 F4800 *61
15:57:43.789 : Z-probe:5.83 X:-46.14 Y:70.92 zCorr:0.00
15:57:44.057 : N957 G1 X26.67 Y53.33 Z5 F4800 *36
15:57:44.990 : Z-probe:5.80 X:-19.46 Y:70.92 zCorr:0.00
15:57:45.257 : N959 G1 X53.33 Y53.33 Z5 F4800 *41
15:57:46.193 : Z-probe:5.83 X:7.20 Y:70.92 zCorr:0.00
15:57:46.461 : N961 G1 X80 Y53.33 Z5 F4800 *2
15:57:47.397 : Z-probe:5.85 X:33.87 Y:70.92 zCorr:0.00
15:57:47.666 : N963 G1 X-80 Y80 Z5 F4800 *13
15:57:48.605 : Z-probe:5.78 X:60.53 Y:70.92 zCorr:0.00
15:57:48.884 : N965 G1 X-53.33 Y80 Z5 F4800 *43
15:57:51.872 : Z-probe:5.34 X:-99.46 Y:97.58 zCorr:0.00
15:57:52.116 : N967 G1 X-26.67 Y80 Z5 F4800 *42
15:57:53.046 : Z-probe:5.73 X:-72.80 Y:97.59 zCorr:0.00
15:57:53.309 : N969 G1 X0 Y80 Z5 F4800 *18
15:57:54.246 : Z-probe:5.86 X:-46.14 Y:97.59 zCorr:0.00
15:57:54.515 : N971 G1 X26.67 Y80 Z5 F4800 *0
15:57:55.453 : Z-probe:5.86 X:-19.46 Y:97.59 zCorr:0.00
15:57:55.723 : N973 G1 X53.33 Y80 Z5 F4800 *1
15:57:56.663 : Z-probe:5.94 X:7.20 Y:97.59 zCorr:0.00
15:57:56.937 : N975 G1 X80 Y80 Z5 F4800 *39
15:57:57.873 : Z-probe:5.85 X:33.87 Y:97.59 zCorr:0.00
15:57:58.139 : N976 G30 P2 *112
15:57:58.143 : N977 M105 *14
15:57:59.073 : Z-probe:5.69 X:60.54 Y:97.58 zCorr:0.00
15:57:59.328 : N978 M105 *1
X: -80.00 -53.33 -26.67 0.00 26.67 53.33 80.00
y:80.00 5.73 5.86 5.86 5.94 5.85 5.69 0.00
y:53.33 5.59 5.61 5.63 5.64 5.69 5.70 0.00
y:26.67 5.34 5.39 5.36 5.42 5.44 5.51 0.00
y:0.00 5.06 5.05 5.09 5.12 5.22 5.28 0.00
y:-26.67 4.86 4.86 4.92 4.95 5.04 5.20 0.00
y:-53.33 4.78 4.74 4.81 4.89 5.05 5.15 0.00
y:-80.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
#A quick little python script using numpy/scipy/matplotpy libraries (trivial to install)
#to provide a correct height map from repetier logs. For some reason, in the current
#versiom of firmware/host its missing a row and a column when autolevel is enabled.
#
#My example points in the post above show horrible calibration. My bed insulation is a bit
#spongy, and difficult to level. I had changed the printer geometry however, and wanted to see
#if I had horizontal rod radius artifacts, or if I'd managed to get it fairly close. The heightmap
#without autolevel seemed to show only linear errors, so I tried enabling autolevel to see what
#would happen. Now, I've rerun the autoleveling and everythings pretty good. Still a linear error
#but that could be any number of things since I reset all calibration parameters when I reset the
#geometry of the printer. Hope this proves useful to someone else!
#enjoy
#
#oh and just in case there's any question, theres no license on this, its free/public domain/do whatever you
#want and don't give me any credit if you desire. I can't see how this is very useful outside this one use case
#but who knows. Have fun!
from __future__ import print_function
from scipy import *
from pylab import *
from scipy import interpolate
from pylab import rcParams
import sys
import math
rcParams['figure.figsize'] = 15,10 #sets the window to show up bigger initially...
#open the log file
logfile=open(sys.argv[1], 'r')
#parsing variables
xCoord=0.0
yCoord=0.0
zCoord=0.0
xMin=0.0
xMax=0.0
yMin=0.0
yMax=0.0
zMax=0.0;
zMin=1000000000.0
zCenter=0.0
zMedian=0.0
zMedianCounter=0.0
zCount=0.0
xCenter=0.0
yCenter=0.0
xCoords=[]
yCoords=[]
zCoords=[]
#similar to the copy result to clipboard button. I am no python expert, perhaps there is some way to do that
#I'm just outputting the same format to the console window
PrettyConsoleOutput=1
#use this sparingly. The smaller the number, the prettier the graph, but the longer it will take to generate
interpolationSpacing=1;
#start parsing.....
for line in logfile:
#Now we need to parse the log data....
words=line.split(' ')
if (len(words) < 4):
continue
if (words[3]=="G1"): #G1 is the move command to probe....
xCoord=float(words[4].lstrip('X'))
yCoord=float(words[5].lstrip('Y'))
xCoords.append(xCoord)
yCoords.append(yCoord)
#update min/max we don't get x/y min/max for free like repetier host does....
if (xCoord < xMin):
xMin=xCoord
if (xCoord > xMax ):
xMax=xCoord
if (yCoord < yMin):
yMin=yCoord
if (yCoord > yMax ):
yMax=yCoord
continue;
else: #hopefully the z value....
wordsplit=words[2].split(':')
if (len(wordsplit) > 1) & (wordsplit[0]=="Z-probe"): #yup, the Z value
zCoord=float((words[2].split(':')[1]))
zCount+=1
zMedianCounter+=zCoord
zCoords.append(zCoord)
#This could be better....we could interpolate this if its not present. I'm lazy....its best to probe it anyhow!
if ((xCoord==xCenter) & (yCoord==yCenter)):
zCenter=zCoord
if (zCoord < zMin):
zMin=zCoord
if (zCoord > zMax ):
zMax=zCoord
#actually print the data matrix
if PrettyConsoleOutput==1:
numColumns=sqrt(zCount)
inumColumns=int(math.floor(numColumns+.5))
CurrentRow=0;
print("", end='\t')
for i in range(0, inumColumns):
print("{0}".format(xCoords[i]), end='\t')
print("")
for i in range(0, inumColumns):
print("{0}".format(xCoords[i]), end='\t') #not a typo, the first numColumns y woords will be identical because of the order repetier generates the points...
for j in range(0, inumColumns):
print("{0}".format(zCoords[int(floor(i*numColumns+j+.5))]), end='\t')
print("")
#Done loading the points from the log file....
#setup the interpolator. We don't have to do this, but it certainly looks nicer Cubic interpolation is pretty accurate interpolation as well.
f=interpolate.interp2d(xCoords, yCoords, zCoords, 'cubic')
#set up the interpolated points and get the interpolated z data
xnew = np.arange(xMin, xMax, interpolationSpacing)
ynew = np.arange(yMin, yMax, interpolationSpacing)
znew = f(xnew, ynew)
hold(True)
# Create image
imshow(znew, origin='lower', extent=[xMin,xMax,yMin,yMax])
#We setup the plot window similar to repetier host with text on the left side, so we have to adjust the plot left a bit
subplots_adjust(left=.25)
#Be really nice and draw a color bar showing the range of values represented on the graph
colorbar()
#titles...
xlabel('x')
ylabel('y')
title('Printer Height Map')
#this is where we show z min, max, avg, and center.
figtext(0.01, 0.5, "Z Min: {0}\nZ Max {1}\nZ Average: {2:.2f}\nZ Center {3}".format(zMin, zMax, zMedianCounter/zCount, zCenter))
#show the heightmap
show()
#originally the example I had did this....its not necessary, the gui will allow you to do so, but if you want to do it programaticaly
#here you go.
#savefig('heightmap') #creates a file in the directory you ran the script from called heightmap.png
A zip file containing the python script, a sample log file (again showing my horribly unlevel bed, and bad calibration), and a sample png are available at https://www.dropbox.com/s/ivkgobml6zcq18b/heightmap-python.zip?dl=0
Just the PNG output if you're curious can be found at https://www.dropbox.com/s/fp56zt1nxy2y4iz/heightmap.png?dl=0
Some caveats: Originally I tried processing it as grab move coordinates as a "phase 1" then put the next z probe position in place. As it turns out, the log file actually shows move 1st, move 2nd, ZPos 1st, move 3rd, ZPos 2nd.....and so on, so at the end there appears to be a left over z coordinate. I got rid of the phases and just said it will move in order and report the z positions in order, so who cares if we get 49 moves followed by 49 z positions....without the idea of needing to be sequential, everything parses correctly. By that heightmap, I'd say I have one tower that needs some serious adjustment!