Wägezellen/DMS Unterstützung verbessern
Verfasst: Sa 23. Apr 2022, 18:09
So, nun hat es auf Github einiges an Diskussion zum Thema Unterstützung der Wägezellen/DMS bei Klipper mit dem Maintainer gegeben. Wer das im Detail nachlesen will, findet es (auf Englisch) hier: https://github.com/Klipper3d/klipper/pull/4738
Kurz zusammengefasst gibt es einige Änderungswünsche/Verbesserungsvorschläge. Die machen auch wirklich Sinn, vor allem, wenn man bedenkt, dass das Modul nicht nur von RFx000-Nutzern benutzt werden kann. Zunächst mal sollte ich das Ganze in kleinere Häppchen unterteilen, also für jeden Teilaspekt einen eigenen Pull Request. Das ist kein Problem und werde ich demnächst mal angehen.
Wichtiger ist aber, dass die Zahl der Parameter, die der Benutzer im Config-File einstellen kann (bzw. muss), zu hoch ist, und dass die Parameter teilweise nicht leicht zu verstehen sind. Die Idee ist, einige der Parameter in feste Konstanten im Python-Code umzuwandeln, sowie einige Parameter möglichst aus anderen Parametern abzuleiten. Das macht zwar die Nutzung etwas weniger flexibel, dafür ist es am Ende leichter zu verstehen (was ansonsten womöglich ein Hinderungsgrund ist, das überhaupt einzusetzen).
Es hat sich am Ende folgende Idee herauskristallisiert (teilweise auch noch in meinem Kopf nach der Diskussion ), die ich gerne mit euch besprechen würde. Das Ganze geht einher damit, dass es eine klare Beschreibung geben wird, wie die Parameter bei einem unbekannten Drucker-Modell einzustellen sind:
1. Kraftmessung in physikalische Einheit konvertieren.
2. Festlegen der größten Kraft, die man für sicher befindet.
3. Bestimmung der "Federkonstante" bzw. "Steifheit" der DMS (bzw. des Gesamtsystems), also Kraft in Abhängigkeit des Weges
4. Daraus wird automatisch die Schrittweite für die schnelle Annäherung bestimmt.
5. Ebenfalls automatisch wird die Schrittweite für die genaue Messung mit der linearen Regression bestimmt.
6. Alle weiteren Parameter werden als Konstanten in Python festgelegt.
Im Detail bedeutet das:
1. Kraftmessung: Man legt ein bekanntes Gewicht von wenigen 100g auf den/die DMS und liest die Änderung des Messwertes ab. Vielleicht kann man der Bequemlichkeit halber sogar beide Werte (tatsächliches Gewicht und Änderung des Messwertes) als Parameter angeben, dann muss der Nutzer das nicht selbst dividieren. Anschließend bekommt man die Kraft in Gramm angezeigt (für spitzfindige Leute: nicht Gramm sondern Zentinewton). Wer mag, kann sich auch eine andere Gewichtseinheit aussuchen - es kommt im Grunde gar nicht auf die Kalibration an. Wichtig ist sie nur, dass man alle Messwerte und Parameter besser verstehen kann.
2. Maximale Kraft: Eine solche Angabe haben wir bereits (nur halt in Digits). Sie wird z.Z. lediglich als Sicherheits-Limit benutzt, so dass bei Überschreitung sofort abgebrochen wird. Ich würde dies noch zusätzlich durch eine Python-Konstante teilen (z.B. 5), um einen Sicherheitsabstand zu realisieren. Dieses reduzierte Limit kann dann als Richtwert im Folgenden genutzt werden. Nennen wir diese Kraft mal F0.
3. "Federkonstante": Ich würde zur Bestimmung einen G-Code-Befehl anbieten. Der Nutzer muss zunächst die Düse in z-Richtung so positionieren, dass sie das Bett gerade eben berührt (d.h. Änderung der Kraft ist bereits messbar). Der G-Code-Befehl fährt dann in kleinen Schritten (ich würde Vollschritte der Z-Achse benutzen), bis F0 erreicht ist. Das kann eine Weile dauern, macht man aber nur einmal. Vielleicht sollte das anschließend noch ein paar mal wiederholt werden, dann aber mit größeren Schritten, z.B. so dass F0 in 4 Schritten erreicht wird. Schließlich wird dann der Mittelwert gebildet aus dem Verhältnis Kraft pro Strecke. Nennen wir dieses mal D (in Anlehnung an die Federkonstante aus der Physik, das ist ja im Grunde genau das gleiche). Ich würde noch empfehlen, diese Messung möglichst ohne Druckbettauflagen/Tape etc. durchzuführen, oder eine großflächige, biege-steife und harte Platte unterzulegen. Dadurch wird sichergestellt, dass wirklich die Federkonstante der DMS gemessen wird und nicht womöglich die einer schlecht aufliegenden Dauerdruckplatte (was dann an jedem Ort ein anderes Ergebnis geben würde). Es kommt am Ende hier aber auch nicht wirklich auf einen Faktor 2 an...
4. Schrittweite für schnelle Annäherung: Jetzt können wir ausrechnen, mit welcher Schrittweite der Drucker fahren kann, ohne dass F0 überschritten wird. Das ist nämlich einfach F0/D. In der Praxis würde ich natürlich nicht meine Hand dafür ins Feuer legen, dass so nie F0 überschritten wird, aber deshalb haben wir ja F0 deutlich kleiner als die maximale Kraft gewählt.
5. Schrittweite für Regression: Für die Regression ist es wichtig, eine recht geringe Schrittweite zu wählen. Wenn nämlich die Druckbettoberfläche nicht perfekt aufliegt und selbst nachgeben kann (siehe oben), wollen wir idealerweise die Auflage nicht ganz bis auf das eigentliche Bett hinunterdrücken (denn dann ändert sich die tatsächliche Federkonstante während der Messung und die Beziehung ist nicht mehr linear). Umgekehrt darf die Schrittweite auch nicht zu klein sein, denn wir wollen eine messbare Kraftänderung zwischen den Schritten, außerdem wollen wir nicht unter einen Vollschritt der Z-Achse gehen, da Teilschritte nicht so exakt sind. Ich denke, das kann man ebenfalls automatisch bestimmen. Evtl. kann der in Punkt 3 genannte G-Code-Befehl gleich noch das "Rauschen" der Messwerte mitbestimmen (-> signifikante Kraftänderung muss größer sein). Die Vollschrittgröße sollte sich ebenfalls herausfinden lassen aus der Konfiguration.
6. Weiter Parameter: Alle weitere muss vermutlich tatsächlich gar nicht geändert werden, wenn man einen anderen Drucker hat. Sollte sich später herausstellen, dass andere Hardware da doch mehr Flexibilität braucht, kann man Python-Konstanten immer noch in Konfigurations-Parameter umwandeln. Einzig bei den ADC-Mittelungen bin ich mir aktuell unsicher. Ich spiele mit dem Gedanken, die komplett herauszuwerfen. Mein Gefühl ist, dass man die eher gar nicht mehr braucht. Sie sind eigentlich nur noch wichtig, um instabile Messwerte zu erkennen - das passiert aber eigentlich nur, wenn man den Drucker anfasst. Und selbst wenn das mal schief geht, würde der Drucker immer noch die Messung erst verifizieren mit einer neuen Offset-Kompensation. Ich werde deshalb demnächst mal testen, in wie weit man darauf verzichten kann.
Was haltet ihr von der Idee? Habt ihr noch weitere Verbesserungsideen? Oder denke ich irgendwo in die falsche Richtung?
Kurz zusammengefasst gibt es einige Änderungswünsche/Verbesserungsvorschläge. Die machen auch wirklich Sinn, vor allem, wenn man bedenkt, dass das Modul nicht nur von RFx000-Nutzern benutzt werden kann. Zunächst mal sollte ich das Ganze in kleinere Häppchen unterteilen, also für jeden Teilaspekt einen eigenen Pull Request. Das ist kein Problem und werde ich demnächst mal angehen.
Wichtiger ist aber, dass die Zahl der Parameter, die der Benutzer im Config-File einstellen kann (bzw. muss), zu hoch ist, und dass die Parameter teilweise nicht leicht zu verstehen sind. Die Idee ist, einige der Parameter in feste Konstanten im Python-Code umzuwandeln, sowie einige Parameter möglichst aus anderen Parametern abzuleiten. Das macht zwar die Nutzung etwas weniger flexibel, dafür ist es am Ende leichter zu verstehen (was ansonsten womöglich ein Hinderungsgrund ist, das überhaupt einzusetzen).
Es hat sich am Ende folgende Idee herauskristallisiert (teilweise auch noch in meinem Kopf nach der Diskussion ), die ich gerne mit euch besprechen würde. Das Ganze geht einher damit, dass es eine klare Beschreibung geben wird, wie die Parameter bei einem unbekannten Drucker-Modell einzustellen sind:
1. Kraftmessung in physikalische Einheit konvertieren.
2. Festlegen der größten Kraft, die man für sicher befindet.
3. Bestimmung der "Federkonstante" bzw. "Steifheit" der DMS (bzw. des Gesamtsystems), also Kraft in Abhängigkeit des Weges
4. Daraus wird automatisch die Schrittweite für die schnelle Annäherung bestimmt.
5. Ebenfalls automatisch wird die Schrittweite für die genaue Messung mit der linearen Regression bestimmt.
6. Alle weiteren Parameter werden als Konstanten in Python festgelegt.
Im Detail bedeutet das:
1. Kraftmessung: Man legt ein bekanntes Gewicht von wenigen 100g auf den/die DMS und liest die Änderung des Messwertes ab. Vielleicht kann man der Bequemlichkeit halber sogar beide Werte (tatsächliches Gewicht und Änderung des Messwertes) als Parameter angeben, dann muss der Nutzer das nicht selbst dividieren. Anschließend bekommt man die Kraft in Gramm angezeigt (für spitzfindige Leute: nicht Gramm sondern Zentinewton). Wer mag, kann sich auch eine andere Gewichtseinheit aussuchen - es kommt im Grunde gar nicht auf die Kalibration an. Wichtig ist sie nur, dass man alle Messwerte und Parameter besser verstehen kann.
2. Maximale Kraft: Eine solche Angabe haben wir bereits (nur halt in Digits). Sie wird z.Z. lediglich als Sicherheits-Limit benutzt, so dass bei Überschreitung sofort abgebrochen wird. Ich würde dies noch zusätzlich durch eine Python-Konstante teilen (z.B. 5), um einen Sicherheitsabstand zu realisieren. Dieses reduzierte Limit kann dann als Richtwert im Folgenden genutzt werden. Nennen wir diese Kraft mal F0.
3. "Federkonstante": Ich würde zur Bestimmung einen G-Code-Befehl anbieten. Der Nutzer muss zunächst die Düse in z-Richtung so positionieren, dass sie das Bett gerade eben berührt (d.h. Änderung der Kraft ist bereits messbar). Der G-Code-Befehl fährt dann in kleinen Schritten (ich würde Vollschritte der Z-Achse benutzen), bis F0 erreicht ist. Das kann eine Weile dauern, macht man aber nur einmal. Vielleicht sollte das anschließend noch ein paar mal wiederholt werden, dann aber mit größeren Schritten, z.B. so dass F0 in 4 Schritten erreicht wird. Schließlich wird dann der Mittelwert gebildet aus dem Verhältnis Kraft pro Strecke. Nennen wir dieses mal D (in Anlehnung an die Federkonstante aus der Physik, das ist ja im Grunde genau das gleiche). Ich würde noch empfehlen, diese Messung möglichst ohne Druckbettauflagen/Tape etc. durchzuführen, oder eine großflächige, biege-steife und harte Platte unterzulegen. Dadurch wird sichergestellt, dass wirklich die Federkonstante der DMS gemessen wird und nicht womöglich die einer schlecht aufliegenden Dauerdruckplatte (was dann an jedem Ort ein anderes Ergebnis geben würde). Es kommt am Ende hier aber auch nicht wirklich auf einen Faktor 2 an...
4. Schrittweite für schnelle Annäherung: Jetzt können wir ausrechnen, mit welcher Schrittweite der Drucker fahren kann, ohne dass F0 überschritten wird. Das ist nämlich einfach F0/D. In der Praxis würde ich natürlich nicht meine Hand dafür ins Feuer legen, dass so nie F0 überschritten wird, aber deshalb haben wir ja F0 deutlich kleiner als die maximale Kraft gewählt.
5. Schrittweite für Regression: Für die Regression ist es wichtig, eine recht geringe Schrittweite zu wählen. Wenn nämlich die Druckbettoberfläche nicht perfekt aufliegt und selbst nachgeben kann (siehe oben), wollen wir idealerweise die Auflage nicht ganz bis auf das eigentliche Bett hinunterdrücken (denn dann ändert sich die tatsächliche Federkonstante während der Messung und die Beziehung ist nicht mehr linear). Umgekehrt darf die Schrittweite auch nicht zu klein sein, denn wir wollen eine messbare Kraftänderung zwischen den Schritten, außerdem wollen wir nicht unter einen Vollschritt der Z-Achse gehen, da Teilschritte nicht so exakt sind. Ich denke, das kann man ebenfalls automatisch bestimmen. Evtl. kann der in Punkt 3 genannte G-Code-Befehl gleich noch das "Rauschen" der Messwerte mitbestimmen (-> signifikante Kraftänderung muss größer sein). Die Vollschrittgröße sollte sich ebenfalls herausfinden lassen aus der Konfiguration.
6. Weiter Parameter: Alle weitere muss vermutlich tatsächlich gar nicht geändert werden, wenn man einen anderen Drucker hat. Sollte sich später herausstellen, dass andere Hardware da doch mehr Flexibilität braucht, kann man Python-Konstanten immer noch in Konfigurations-Parameter umwandeln. Einzig bei den ADC-Mittelungen bin ich mir aktuell unsicher. Ich spiele mit dem Gedanken, die komplett herauszuwerfen. Mein Gefühl ist, dass man die eher gar nicht mehr braucht. Sie sind eigentlich nur noch wichtig, um instabile Messwerte zu erkennen - das passiert aber eigentlich nur, wenn man den Drucker anfasst. Und selbst wenn das mal schief geht, würde der Drucker immer noch die Messung erst verifizieren mit einer neuen Offset-Kompensation. Ich werde deshalb demnächst mal testen, in wie weit man darauf verzichten kann.
Was haltet ihr von der Idee? Habt ihr noch weitere Verbesserungsideen? Oder denke ich irgendwo in die falsche Richtung?