@@ -107,8 +107,9 @@ def handle_batch(msg):
107107 move (next_pos , move_speed )
108108 # Note sample timing
109109 start_query_time = toolhead .get_last_move_time () + 0.050
110- end_query_time = start_query_time + 0.100
111- toolhead .dwell (0.200 )
110+ # Gather ~36 samples
111+ end_query_time = start_query_time + 0.150
112+ toolhead .dwell (0.250 )
112113 # Find Z position based on actual commanded stepper position
113114 toolhead .flush_step_generation ()
114115 kin_spos = {s .get_name (): s .get_commanded_position ()
@@ -134,16 +135,21 @@ def handle_batch(msg):
134135 raise self .printer .command_error (
135136 "Failed calibration - incomplete sensor data" )
136137 return cal
138+
139+ def _median (self , values ):
140+ values = sorted (values )
141+ n = len (values )
142+ if n % 2 == 0 :
143+ return (values [n // 2 - 1 ] + values [n // 2 ]) / 2.0
144+ return values [n // 2 ]
137145 def calc_freqs (self , meas ):
138- total_count = total_variance = 0
139146 positions = {}
140147 for pos , freqs in meas .items ():
141- count = len (freqs )
142- freq_avg = float (sum (freqs )) / count
143- positions [pos ] = freq_avg
144- total_count += count
145- total_variance += sum ([(f - freq_avg )** 2 for f in freqs ])
146- return positions , math .sqrt (total_variance / total_count ), total_count
148+ freq_median = self ._median (freqs )
149+ mads = [abs (f - freq_median ) for f in freqs ]
150+ mad = self ._median (mads )
151+ positions [pos ] = (freq_median , mad , len (freqs ))
152+ return positions
147153 def post_manual_probe (self , kin_pos ):
148154 if kin_pos is None :
149155 # Manual Probe was aborted
@@ -166,24 +172,52 @@ def post_manual_probe(self, kin_pos):
166172 # Perform calibration movement and capture
167173 cal = self .do_calibration_moves (self .probe_speed )
168174 # Calculate each sample position average and variance
169- positions , std , total = self .calc_freqs (cal )
170- last_freq = 0.
171- for pos , freq in reversed (sorted (positions .items ())):
172- if freq <= last_freq :
173- raise self .printer .command_error (
174- "Failed calibration - frequency not increasing each step" )
175- last_freq = freq
175+ positions = self .calc_freqs (cal )
176+ last_freq = 40000000.
177+ last_pos = last_mad = .0
176178 gcode = self .printer .lookup_object ("gcode" )
179+ filtered = []
180+ total_mad = []
181+ total_mad_mm = []
182+ total = 0
183+ for pos , (freq_median , mad , count ) in sorted (positions .items ()):
184+ if freq_median > last_freq :
185+ gcode .respond_info (
186+ "Frequency stops decreasing at step %.3f" % (pos ))
187+ break
188+ diff_mad = math .sqrt (last_mad ** 2 + mad ** 2 )
189+ # Calculate if samples have a significant difference
190+ freq_diff = last_freq - freq_median
191+ if freq_diff < 2.5 * diff_mad :
192+ gcode .respond_info (
193+ "Frequency too noisy at step %.3f" % (pos ))
194+ break
195+ distance = pos - last_pos
196+ sensitivity = freq_diff / distance
197+ mad_mm = mad / sensitivity
198+ filtered .append ((pos , freq_median ))
199+ total_mad .append (mad )
200+ total_mad_mm .append (mad_mm )
201+ total += count
202+ last_freq = freq_median
203+ last_mad = mad
204+ last_pos = pos
205+ if len (filtered ) <= 1 :
206+ raise self .printer .command_error (
207+ "Failed calibration - No usable data" )
208+ avg_mad = sum (total_mad )/ len (total_mad )
209+ avg_mad_mm = sum (total_mad_mm )/ len (total_mad_mm )
177210 gcode .respond_info (
178- "probe_eddy_current: stddev =%.3f in %d queries\n "
211+ "probe_eddy_current: MAD =%.3fHz ~ %.4fmm in %d queries\n "
179212 "The SAVE_CONFIG command will update the printer config file\n "
180- "and restart the printer." % (std , total ))
213+ "and restart the printer." % (avg_mad , avg_mad_mm , total ))
181214 # Save results
182215 cal_contents = []
183- for i , (pos , freq ) in enumerate (sorted ( positions . items ()) ):
216+ for i , (pos , freq ) in enumerate (filtered ):
184217 if not i % 3 :
185218 cal_contents .append ('\n ' )
186- cal_contents .append ("%.6f:%.3f" % (pos - probe_calibrate_z , freq ))
219+ z_height = round (pos - probe_calibrate_z , 3 )
220+ cal_contents .append ("%.3f:%.3f" % (z_height , freq ))
187221 cal_contents .append (',' )
188222 cal_contents .pop ()
189223 configfile = self .printer .lookup_object ('configfile' )
0 commit comments