-
-
Notifications
You must be signed in to change notification settings - Fork 5.2k
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
Add ldc1612 support for "METHOD=scan" probing #6610
Conversation
Hi Kevin, Having done a basic review of the code it looks good to me. I'll do some testing and an in depth review as soon as I am able. With regard to additional options and documentation, I can add that in a follow-up PR that adds "rapid" probing to --- a/klippy/extras/probe_eddy_current.py
+++ b/klippy/extras/probe_eddy_current.py
@@ -346,12 +346,16 @@ class EddyScanningProbe:
self._gather = EddyGatherSamples(printer, sensor_helper,
calibration, z_offset)
self._sample_time_delay = 0.50
- self._sample_time = 0.100
+ self._sample_time = gcmd.get_float("SAMPLE_TIME", 0.100, above=0.0)
+ self._mode = gcmd.get("SCAN_MODE", "detailed")
def run_probe(self, gcmd):
toolhead = self._printer.lookup_object("toolhead")
printtime = toolhead.get_last_move_time()
- toolhead.dwell(self._sample_time_delay + self._sample_time)
- start_time = printtime + self._sample_time_delay
+ if self._mode == "detailed":
+ toolhead.dwell(self._sample_time_delay + self._sample_time)
+ start_time = printtime + self._sample_time_delay
+ else:
+ start_time = printtime - self._sample_time / 2
self._gather.note_probe(start_time, start_time + self._sample_time)
def pull_probed_results(self):
results = self._gather.pull_probed() I believe with this change we can keep the scanning code in |
Yeah, if we can reuse the code, I think that is a good idea. (As an aside, the code will also need to be updated to use What do you think about using Thanks. |
That makes sense, removing the extra parameter is cleaner. Factoring in the need to register the lookahead callback, the new diff should look something like this: diff --git a/klippy/extras/probe_eddy_current.py b/klippy/extras/probe_eddy_current.py
index 4bd4c4224..d47dfc780 100644
--- a/klippy/extras/probe_eddy_current.py
+++ b/klippy/extras/probe_eddy_current.py
@@ -261,9 +261,10 @@ class EddyGatherSamples:
results.append(pos)
del self._probe_times[:]
return results
- def note_probe(self, start_time, end_time):
- toolhead = self._printer.lookup_object("toolhead")
- nom_pos = toolhead.get_position()
+ def note_probe(self, start_time, end_time, nom_pos=None):
+ if nom_pos is None:
+ toolhead = self._printer.lookup_object("toolhead")
+ nom_pos = toolhead.get_position()
self._probe_times.append((start_time, end_time, nom_pos))
# Helper for implementing PROBE style commands (descend until trigger)
@@ -346,14 +347,29 @@ class EddyScanningProbe:
self._gather = EddyGatherSamples(printer, sensor_helper,
calibration, z_offset)
self._sample_time_delay = 0.50
- self._sample_time = 0.100
+ self._sample_time = gcmd.get_float("SAMPLE_TIME", 0.100, above=0.0)
+ self._method = gcmd.get("METHOD", "scan")
+ self._pending_positions = []
def run_probe(self, gcmd):
toolhead = self._printer.lookup_object("toolhead")
- printtime = toolhead.get_last_move_time()
- toolhead.dwell(self._sample_time_delay + self._sample_time)
- start_time = printtime + self._sample_time_delay
- self._gather.note_probe(start_time, start_time + self._sample_time)
+ self._pending_positions.append(toolhead.get_position())
+ toolhead.register_lookahead_callback(self._lookahead_cb)
+ if self._method == "scan":
+ toolhead.dwell(self._sample_time_delay + self._sample_time)
+ def _lookahead_cb(self, printtime):
+ if not self._pending_positions:
+ return
+ pos = self._pending_positions.pop(0)
+ if self._method == "scan":
+ start_time = printtime + self._sample_time_delay
+ else:
+ start_time = printtime - self._sample_time / 2
+ self._gather.note_probe(
+ start_time, start_time + self._sample_time, pos
+ )
def pull_probed_results(self):
+ toolhead = self._printer.lookup_object("toolhead")
+ toolhead.wait_moves()
results = self._gather.pull_probed()
# Allow axis_twist_compensation to update results
for epos in results:
@@ -390,7 +406,7 @@ class PrinterEddyProbe:
return self.cmd_helper.get_status(eventtime)
def start_probe_session(self, gcmd):
method = gcmd.get('METHOD', 'automatic').lower()
- if method == 'scan':
+ if method in ('scan', 'rapid'):
z_offset = self.get_offsets()[2]
return EddyScanningProbe(self.printer, self.sensor_helper,
self.calibration, z_offset, gcmd) I'm not sure if |
Yeah, that should work. I just realized though, that my code has a systemic inaccuracy that should be fixed. The "nominal position" should really be calculated from the stepper motor positions - not the toolhead/trapq positions. For example, if one is using a Z with rotation_distance=8, full_steps_per_rotation=200, and microsteps=16 then there is a step_distance of 0.0025. But, if one were to move to a Z position that isn't an exact multiple of that amount it could result in a systemic bias to the probe results. This wasn't an issue for "descend until trigger" mode because the toolhead position is recalculated at the end of the trigger, but in scan (and rapid scan) modes, the actual stepper Z may deviate from the requested Z. Probably not a huge precision issue on most printers, but could become an issue in some setups. I'll update this branch to calculate the "nominal Z" from the stepper motor positions. The one upside of this change is that we wont have to track the nominal toolhead position upfront - it can be calculated in EddyGatherSamples from the stepper movement history and start/end_times.
Just "thinking out lout", simplest may be to call Cheers, |
aa507c8
to
2ac8242
Compare
I reworked and rebased this branch. Notes:
-Kevin |
testing this branch and found that i'm able to successfully do BED_MESH_CALIBRATE
any ideas here? |
Thanks for testing. If you're using one of the scan modes, you'll need to make sure the horizontal_move_z field is relatively low - try a command like: If that fails, run -Kevin |
@KevinOConnor thanks, that seems to have solved my issue. thank you again for the guidance. |
testing the different methods (scan works great) and got this error: |
I have had a chance to test the latest version if this branch and refactor
@c0psrul3 The
The correct method name is |
@Arksine thank you for correcting me, as i obv did not read the diff close enough. @KevinOConnor rapid_scan immediately gives me error |
According to your log you are on commit aa507c8. The lastest commit in this branch after Kevin's last push is 2ac8242. You likely need to fetch and reset (or checkout detached) to update to the latest code. The |
@Arksine thanks for pointing this out 👍 rapid_scan appears to work, went through the motions, but got error message: |
Thanks for testing and reviewing.
Yeah - the latest code is calculating the x, y, and z position from the stepper motors. There are a few reasons the resulting "stepper position" may deviate from the requested position:
It is possible to return requested XY positions, but it may also be worthwhile to return the actual XY positions. Not sure. Note that, even previously, probe XY positions could deviate slightly from requested positions (due to stepper coarseness - in particular on delta type kinematics).
Unless I'm missing something, there shouldn't be a difference. Calling Cheers, |
I don't think we need to return the requested positions, I have a fix for this in
I think you're right. I noticed that it took longer and assumed it introduced a difference, but after a closer look its likely due to |
2ac8242
to
fa78c91
Compare
Eeks! I must have goofed on one of my rebase jobs. It was intended to be I restored the value to 0.050. I also merged in the backend probe work (PR #6605), merged the 2-byte command id work (PR #6613), and rebased this branch on top of the latest master. -Kevin |
@KevinOConnor thanks for putting some updates.
what i do notice is the output thanks! EDIT: EDIT:
|
@c0psrul3, thanks for testing. |
As indicated at #6610 (comment) , the current bed_mesh code would need changes in order to be used with "rapid_scan". I'll drop the "rapid_scan" part of this PR prior to committing. -Kevin |
I have created PR #6617, adding support for rapid scanning in |
Instead of directly calling axis_twist_compensation, send an event that can perform the necessary updates. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
@KevinOConnor @Arksine thank you again for your efforts. combined, these changes perform excellent with no issues. @KevinOConnor I wanted to point something out which was interesting to me, the map for i am attaching screenshots of the maps (probe_count=30) lmk if i'm off-base here and again, thank you both for the excellent contributions! |
Thanks for testing.
Well, I guess that's what I would have expected - the "scan" mode would produce a more accurate map, and the "rapid_scan" would produce a map with more "noise". That is, rapid_scan runs a little faster but isn't as accurate. Or are you saying you've done some kind of analysis showing that your bed is actually very "crinkly" like the rapid scan shows? Cheers, |
lol, my n00b is showing.
I've not done any analysis and noise didn't occur to me. it is textured,
but that wouldn't show at 30,30. noise would make better sense than
accuracy.
in any case, it all looks good and ready imo
|
Store the results of each probe attempt in a local "results" variable (instead of a class variable) when performing "automatic" probes. This is in preparation for gathering the results in the probing implementation. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Change run_probe() to gather the results locally, and introduce a new pull_probed_results() method that returns the previously probed results. This is in preparation for future probing code that benefits from batching probe results. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Split the sample gathering code out of EddyEndstopWrapper class and into a new EddyGatherSamples class. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Calculate the average frequency from a set of samples, and then calculate the estimated Z height from that frequency. This may improve accuracy, as the frequency to Z height is not linear and averaging after the non-linear transform could bias the results. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Convert samples into probe frequencies as the samples arrive. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
…ition Support calculating the low-level kinematic toolhead position while calculating the probed frequency. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
When probing in "scan" mode, the toolhead will pause at each position, but does not descend. This can notably reduce the total probing time. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
fa78c91
to
fcf064b
Compare
I merged the "scan" mode support in this PR into the main repo. I did not merge the initial "rapid_scan" work previously discussed here - it looks like that can be done in the upcoming PR #6617. -Kevin |
This is an alternate implementation to the "scan" mode introduced in PR #6558 . The main difference is that this PR refactors the internal probe classes with a goal to "flatten" some of those interactions between classes.
This PR is on top of PR #6605 .
@Arksine - the main goal of this PR is to demonstrate a possible internal interface between the classes for the "detailed scan" mode. That is, the toolhead movements still go through ProbePointsHelper, but now
PrinterEddyProbe
can detect a "scan" request and substitute a different probe implementation. Also, the same sample gathering code is used for both "descend until trigger" and "scan probing" modes. I understand your PR had improved user options, improved documentation, and other improvements. Happy to change this PR further, or go with an alternate implementation.Let me know your thoughts.
-Kevin