new Component probefilter to handle "probe tripped ... errors"
20 Apr 2021 07:14 #206504
by freisei
Hi!
With current build of 2.9-pre it is very hard to handle bouncing/flickering probes because linuxcnc stops on every . This is the main thing i want to create a realtime hal component "probefilter".
Problem: probing for a rotating endmill on a laser.
possible solution 1, filter for motion.motion-type 5 does not work.
Even if i create a hal-filtered probe (only active when motion.motion-type is 5) there are a couple of signals going through in around 50ms after first probe-signal.
On a G34.2 move with running spindle for some reason i get three pulses from type-5-probe-pin until linuxcnc decides G34.2 is over.
It seems that the task that turns on watching for probe-interrupts is a little faster - so i get "Probe tripped during non-probe move."
Upper graph is probe-signal that only is active when motion.motion-type == 5. The lower one is dirctly from the probe.
possible solution 2, debounce adds latency.
as far as i see the hal components dbounce and debounce both would add latency to the probe-signal. This is very bad for a probe-signal.
Features
If some you have any suggestions i will see what i can do.
btw. i'm not a pro in c - so maybe a better programmer would have to cleanup/rewrite the component to match quality-criteria to get into official code-repos.
With current build of 2.9-pre it is very hard to handle bouncing/flickering probes because linuxcnc stops on every . This is the main thing i want to create a realtime hal component "probefilter".
Problem: probing for a rotating endmill on a laser.
possible solution 1, filter for motion.motion-type 5 does not work.
Even if i create a hal-filtered probe (only active when motion.motion-type is 5) there are a couple of signals going through in around 50ms after first probe-signal.
On a G34.2 move with running spindle for some reason i get three pulses from type-5-probe-pin until linuxcnc decides G34.2 is over.
It seems that the task that turns on watching for probe-interrupts is a little faster - so i get "Probe tripped during non-probe move."
Upper graph is probe-signal that only is active when motion.motion-type == 5. The lower one is dirctly from the probe.
possible solution 2, debounce adds latency.
as far as i see the hal components dbounce and debounce both would add latency to the probe-signal. This is very bad for a probe-signal.
Features
- a number of probe-inputs, each can be individually enabled/disabled
- filtering/debouncing to match problem 1 without latency
- motion-types configurable per probe
If some you have any suggestions i will see what i can do.
btw. i'm not a pro in c - so maybe a better programmer would have to cleanup/rewrite the component to match quality-criteria to get into official code-repos.
Please Log in or Create an account to join the conversation.
21 Apr 2021 11:10 #206629
by andypugh
Replied by andypugh on topic new Component probefilter to handle "probe tripped ... errors"
Would it be enough to make the motion-type=5 signal longer with a oneshot component?
Please Log in or Create an account to join the conversation.
14 Aug 2021 19:47 #217766
by freisei
Replied by freisei on topic new Component probefilter to handle "probe tripped ... errors"
Hi Andy,
i ve overseen your answer. I´ve already tried it with oneshot. It did not work for me. Because i need a fast reaction when getting into the laser beam and even getting outside. Doing that in complicated hal it resulted in the better way for me to write a small (unfinished) component "probefilter".
github.com/freisei/probefilter/blob/main/probefilter.comp
Greets!
i ve overseen your answer. I´ve already tried it with oneshot. It did not work for me. Because i need a fast reaction when getting into the laser beam and even getting outside. Doing that in complicated hal it resulted in the better way for me to write a small (unfinished) component "probefilter".
github.com/freisei/probefilter/blob/main/probefilter.comp
Greets!
The following user(s) said Thank You: andypugh
Please Log in or Create an account to join the conversation.
15 Aug 2021 09:22 #217796
by rodw
Replied by rodw on topic new Component probefilter to handle "probe tripped ... errors"
When I had this issue I and2'ed the probe signal to a digital output and added m62-m65 to my probe routine so the probe would only trigger if the digital output was true (during probing).
Please Log in or Create an account to join the conversation.
16 Aug 2021 23:44 #217931
by andypugh
Replied by andypugh on topic new Component probefilter to handle "probe tripped ... errors"
The comp here seems to use motion.motion-type so automatically detects a probing move with no further G-code magic.
Please Log in or Create an account to join the conversation.
14 Apr 2023 10:31 #269004
by ok
Replied by ok on topic new Component probefilter to handle "probe tripped ... errors"
Hi everyone,
I am a hobbyist newbie here, still learning lots about linuxcnc and I assert you're doing it all wrong
Seriously though, after trying to get my setup ("CNC6040 converted to linuxcnc from mach3") to probe correctly (using the cheap tool-touches-metal-workpiece approach) and reading several forum threads on this topic as well as the source process_probe_inputs of the probe routine in control.c, I think I have figured out now what goes wrong so often and at least part of why why it is a recurring topic:
If I understand correctly, and contrary to the homing functionality that properly backs off after an axis ran into a limit switch, the G38 probing routine as it goes through linuxcnc simply stops ASAP when it detected a successful probe input.
Unless the probe has better, filtering electronics or a mechanical hysteresis (e.g. micro-switch), this leaves the probe tip just hovering right at the surface (or just dug slightly into the material because of inertia, but you get my point). Decaying mechanical vibrations and the nature of the situation at that point makes this a highly nonlinear system (comparable maybe also to a 'fritter' historically used for radio detection) any any slight change or external input (electrical, mechanical) can and will make the probe state bounce around.
Contrary to what I have seen written somewhere here on this forum, I do not think this is typically due to "badly shielded" probe wires or "electrical noise due to missing shielding of the probing wire".
I think it is just the nature of the setup, using a probe this way is basically creating a very bouncy switch.
I have tried the suggestion of using a digital output from gcode and surrounding the probe G38 with "M64/M65" to feed into an "and2" component to get rid of spurious probe triggers when not probing. Apart from the problem that this might well crash a more expensive probe or tool when using the mill for a more complex probing than just "detect the metal-to-metal contact", it also did not solve the spurious probe errors for me.
I also got several messages of the type "probe tripped during non-probe move" even though the active gcode line shown in Axis was right on the G38.3 statement.
The reason for this is, as far as I understand, that the gcode execution state (informing axis on which statement is currently executed) can differ from the probing state as it is tracked in the process_probe_inputs() function. When the motion planner stops the mill due to the probe triggering, the probe code is still (as it is always) running (albeit with probing=0) but that makes it sensitive to any bouncing of the probe input, even when selecting a G38.3 move to suppress errors. Now I don't think this is necessarily a design bug, as it should work for a well-designed probe...
But this might also create spurious inputs when pulling the tool/probe out of the material (as it might have dug into it when doing a faster probe move), creating further "probe tripped" messages.
I do not like the idea of adding a debouncer to the probe input, as I still think the probe should stop ASAP when touching metal.
The solution that I have now implemented, and so far works very well for me, is to make the probe input sticky for a while but still react immediately, basically introduce a longer deadtime after any change in the probe signal. For this, I made a simple "dsmono" component ("double-sided monoflop" for lack of a better name), in my .hal I have:
loadrt dsmono
setp dsmono.0.deadtime-ns 100000000
addf dsmono.0 servo-thread
net probe-raw-in <= hm2_7i96s.0.inm.00.input-03
net probe-raw-in => dsmono.0.in
net probe-in <= dsmono.0.out
With the dsmono.comp component implemented as follows:
// This is a component for LinuxCNC HAL
// Copyright 2023 The LinuxCNC Project
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
component dsmono "Double-sided monoflop";
// Credits: This is very loosely based on edge.comp by Jeff Epler
pin in bit in "Input signal";
pin out bit out "Filtered output signal, tracking 'in' with a deadtime component";
pin out bit out_invert "Negative of 'out'";
param rw signed deadtime_ns = 0 "Time to be insensitive after an edge on 'in'.";
param r signed time_left_ns = 0 "Time left in this output pulse";
function _ nofp "Filter input with a deadtime component";
license "GPL";
author "ok";
;;
FUNCTION(_){
static char old_in;
if (time_left_ns > 0) {
time_left_ns -= period;
} else if (old_in != in) {
time_left_ns = deadtime_ns;
old_in = in;
out = in;
out_invert = !in;
}
}
I chose a long delay of 100ms here, but I still think this is safe as long as the time from lifting the probe again to touch the next probe point is larger than that. My mill is way too slow to probe points within tenths of seconds. It should also (though I have not tested this yet) basically be a pass-through if I decide to mount a fancier, better probe on my mill and I would not need to change the .hal file for that (unless I somehow get my mill to do crazy high-speed probing).
Now as I said, I am a newbie wrt. linuxcnc still and I might have inadvertently reinvented the wheel and overlooked a component which already does what I do here. I also think the functionality of dsmono.comp can be relatively easily implemented with the already existing components, but IMO that doesn't make the .hal more readable, so I lifted it directly to the C layer.
I am a hobbyist newbie here, still learning lots about linuxcnc and I assert you're doing it all wrong
Seriously though, after trying to get my setup ("CNC6040 converted to linuxcnc from mach3") to probe correctly (using the cheap tool-touches-metal-workpiece approach) and reading several forum threads on this topic as well as the source process_probe_inputs of the probe routine in control.c, I think I have figured out now what goes wrong so often and at least part of why why it is a recurring topic:
If I understand correctly, and contrary to the homing functionality that properly backs off after an axis ran into a limit switch, the G38 probing routine as it goes through linuxcnc simply stops ASAP when it detected a successful probe input.
Unless the probe has better, filtering electronics or a mechanical hysteresis (e.g. micro-switch), this leaves the probe tip just hovering right at the surface (or just dug slightly into the material because of inertia, but you get my point). Decaying mechanical vibrations and the nature of the situation at that point makes this a highly nonlinear system (comparable maybe also to a 'fritter' historically used for radio detection) any any slight change or external input (electrical, mechanical) can and will make the probe state bounce around.
Contrary to what I have seen written somewhere here on this forum, I do not think this is typically due to "badly shielded" probe wires or "electrical noise due to missing shielding of the probing wire".
I think it is just the nature of the setup, using a probe this way is basically creating a very bouncy switch.
I have tried the suggestion of using a digital output from gcode and surrounding the probe G38 with "M64/M65" to feed into an "and2" component to get rid of spurious probe triggers when not probing. Apart from the problem that this might well crash a more expensive probe or tool when using the mill for a more complex probing than just "detect the metal-to-metal contact", it also did not solve the spurious probe errors for me.
I also got several messages of the type "probe tripped during non-probe move" even though the active gcode line shown in Axis was right on the G38.3 statement.
The reason for this is, as far as I understand, that the gcode execution state (informing axis on which statement is currently executed) can differ from the probing state as it is tracked in the process_probe_inputs() function. When the motion planner stops the mill due to the probe triggering, the probe code is still (as it is always) running (albeit with probing=0) but that makes it sensitive to any bouncing of the probe input, even when selecting a G38.3 move to suppress errors. Now I don't think this is necessarily a design bug, as it should work for a well-designed probe...
But this might also create spurious inputs when pulling the tool/probe out of the material (as it might have dug into it when doing a faster probe move), creating further "probe tripped" messages.
I do not like the idea of adding a debouncer to the probe input, as I still think the probe should stop ASAP when touching metal.
The solution that I have now implemented, and so far works very well for me, is to make the probe input sticky for a while but still react immediately, basically introduce a longer deadtime after any change in the probe signal. For this, I made a simple "dsmono" component ("double-sided monoflop" for lack of a better name), in my .hal I have:
loadrt dsmono
setp dsmono.0.deadtime-ns 100000000
addf dsmono.0 servo-thread
net probe-raw-in <= hm2_7i96s.0.inm.00.input-03
net probe-raw-in => dsmono.0.in
net probe-in <= dsmono.0.out
With the dsmono.comp component implemented as follows:
// This is a component for LinuxCNC HAL
// Copyright 2023 The LinuxCNC Project
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
component dsmono "Double-sided monoflop";
// Credits: This is very loosely based on edge.comp by Jeff Epler
pin in bit in "Input signal";
pin out bit out "Filtered output signal, tracking 'in' with a deadtime component";
pin out bit out_invert "Negative of 'out'";
param rw signed deadtime_ns = 0 "Time to be insensitive after an edge on 'in'.";
param r signed time_left_ns = 0 "Time left in this output pulse";
function _ nofp "Filter input with a deadtime component";
license "GPL";
author "ok";
;;
FUNCTION(_){
static char old_in;
if (time_left_ns > 0) {
time_left_ns -= period;
} else if (old_in != in) {
time_left_ns = deadtime_ns;
old_in = in;
out = in;
out_invert = !in;
}
}
I chose a long delay of 100ms here, but I still think this is safe as long as the time from lifting the probe again to touch the next probe point is larger than that. My mill is way too slow to probe points within tenths of seconds. It should also (though I have not tested this yet) basically be a pass-through if I decide to mount a fancier, better probe on my mill and I would not need to change the .hal file for that (unless I somehow get my mill to do crazy high-speed probing).
Now as I said, I am a newbie wrt. linuxcnc still and I might have inadvertently reinvented the wheel and overlooked a component which already does what I do here. I also think the functionality of dsmono.comp can be relatively easily implemented with the already existing components, but IMO that doesn't make the .hal more readable, so I lifted it directly to the C layer.
Please Log in or Create an account to join the conversation.
15 Apr 2023 03:03 #269052
by rodw
Replied by rodw on topic new Component probefilter to handle "probe tripped ... errors"
Its good you have got your hands dirty early in your linuxcnc journey. As always, there are many approaches to solve this problem.
When I faced this, I modified my probing gcode routine to set a digital output true from gcode and false after probing.
Then you can and2 the probe output with the digital output before connecting to motion.probe-input.
Another robust component based approach would be to read motion.motion-type and only output a probe output when it equals 5.
ref: linuxcnc.org/docs/2.9/html/man/man9/motion.9.html#MOTION%20PINS
When I faced this, I modified my probing gcode routine to set a digital output true from gcode and false after probing.
Then you can and2 the probe output with the digital output before connecting to motion.probe-input.
Another robust component based approach would be to read motion.motion-type and only output a probe output when it equals 5.
motion.motion-type OUT S32
These values are from src/emc/nml_intf/motion_types.h.
0: Idle (no motion)
1: Traverse
2: Linear feed
3: Arc feed
4: Tool change
5: Probing
6: Rotary unlock for traverse
ref: linuxcnc.org/docs/2.9/html/man/man9/motion.9.html#MOTION%20PINS
Please Log in or Create an account to join the conversation.
15 Apr 2023 06:45 - 15 Apr 2023 07:44 #269060
by ok
Replied by ok on topic new Component probefilter to handle "probe tripped ... errors"
Do you use the same cheap method of just contacting the tool to the workpiece for probing, or do you use the gated approach with a fancier, better probe?
As I wrote, I saw the probe errors even though I gated the (cheap) probe with and2 as you suggested. And after reading the relevant source, I think that is also to be expected, as the probe status might jiggle around after the probing is done but whilst the motion controller is still in probing mode, as those are two different state flags. This jigging can then trigger an error from the probe routine. I didn't try to check the motion.motion-type method but because of this, I'd expect it to not solve that problem either.
A better probe would solve what I am seeing, or said in another way, hide what I think is a peculiarity of the probing process. Using a 'double-sided monoflop' solves this peculiarity, at least for me.
This is also not something that happened very often - after I tuned it just about every 200th probing move or so. But still often enough to become a major annoyance when probing a grid.
Edit: I wrote above: "I also got several messages of the type "probe tripped during non-probe move" even though the active gcode line shown in Axis was right on the G38.3 statement.". I meant this within the context of having it surrounded by M64/M65 statements gating the probe through the and2. The problem is that this approach does not solve any bouncing of the probe after the probing is done but when the motion controller still executing the G38 command, as the logic within the probe routine is so that it triggers an error on any change of the probe input (to guard against crashing the probe in a normal move) even though the motion planner is still in probing mode.
I think one could fix this code by also checking that the motion controller is not in probing mode before raising an error, in this line in control.c:
} else if (!old_probeVal && emcmotStatus->probeVal) {
// not probing, but we have a rising edge on the probe.
// this could be expensive if we don't stop.
int i;
----
This else path is executed when the "emcMotStatus->probing" status is false. But, again, that is different to the motion planner's status flag "EMCMOT_PROBE" and after the probe has touched the workpiece, the motion planner is still in EMCMOT_PROBE state as far as I can see, while the probing code has reset emcMotStatus->probing to zero. Physically, the probe is close to the workpiece still, and the noise that might be generated can then trigger this else path, leading to the "Probe tripped during non-probe move." - error. I haven't fully debugged nor understood the extra check for that error yet, but as I got the error with the and2-ing (which made the problem noticeable better) and with axis showing the G38.3 line, I must assume that it does not catch all potential problems. My mental model here (which might be wrong) is that the motion planner is still moving as it has to adhere to the acceleration limits even though the probe tripped and that passes this extra check "if (GET_MOTION_INPOS_FLAG() && tpQueueDepth(&emcmotDebug->coord_tp) == 0)".
It could probably be fixed by adding a check for the motion planner status here. Though this would also seem a bit like a breach of abstraction to me. And it would not fix the other potential problem, that the probe might trip repeatedly when pulling out of / away from the workpiece again. For that one would still need to and2-gate the probe. Using the dsmono approach fixes both problems. It simply makes the probe inert for a configurable amount (I chose 100ms) after it trips in any direction. This is IMO less complexity and it is also safer as it should not (but no guarantees!) keep linuxcnc from stopping when doing a normal move with an expensive probe attached.
As I wrote, I saw the probe errors even though I gated the (cheap) probe with and2 as you suggested. And after reading the relevant source, I think that is also to be expected, as the probe status might jiggle around after the probing is done but whilst the motion controller is still in probing mode, as those are two different state flags. This jigging can then trigger an error from the probe routine. I didn't try to check the motion.motion-type method but because of this, I'd expect it to not solve that problem either.
A better probe would solve what I am seeing, or said in another way, hide what I think is a peculiarity of the probing process. Using a 'double-sided monoflop' solves this peculiarity, at least for me.
This is also not something that happened very often - after I tuned it just about every 200th probing move or so. But still often enough to become a major annoyance when probing a grid.
Edit: I wrote above: "I also got several messages of the type "probe tripped during non-probe move" even though the active gcode line shown in Axis was right on the G38.3 statement.". I meant this within the context of having it surrounded by M64/M65 statements gating the probe through the and2. The problem is that this approach does not solve any bouncing of the probe after the probing is done but when the motion controller still executing the G38 command, as the logic within the probe routine is so that it triggers an error on any change of the probe input (to guard against crashing the probe in a normal move) even though the motion planner is still in probing mode.
I think one could fix this code by also checking that the motion controller is not in probing mode before raising an error, in this line in control.c:
} else if (!old_probeVal && emcmotStatus->probeVal) {
// not probing, but we have a rising edge on the probe.
// this could be expensive if we don't stop.
int i;
----
This else path is executed when the "emcMotStatus->probing" status is false. But, again, that is different to the motion planner's status flag "EMCMOT_PROBE" and after the probe has touched the workpiece, the motion planner is still in EMCMOT_PROBE state as far as I can see, while the probing code has reset emcMotStatus->probing to zero. Physically, the probe is close to the workpiece still, and the noise that might be generated can then trigger this else path, leading to the "Probe tripped during non-probe move." - error. I haven't fully debugged nor understood the extra check for that error yet, but as I got the error with the and2-ing (which made the problem noticeable better) and with axis showing the G38.3 line, I must assume that it does not catch all potential problems. My mental model here (which might be wrong) is that the motion planner is still moving as it has to adhere to the acceleration limits even though the probe tripped and that passes this extra check "if (GET_MOTION_INPOS_FLAG() && tpQueueDepth(&emcmotDebug->coord_tp) == 0)".
It could probably be fixed by adding a check for the motion planner status here. Though this would also seem a bit like a breach of abstraction to me. And it would not fix the other potential problem, that the probe might trip repeatedly when pulling out of / away from the workpiece again. For that one would still need to and2-gate the probe. Using the dsmono approach fixes both problems. It simply makes the probe inert for a configurable amount (I chose 100ms) after it trips in any direction. This is IMO less complexity and it is also safer as it should not (but no guarantees!) keep linuxcnc from stopping when doing a normal move with an expensive probe attached.
Last edit: 15 Apr 2023 07:44 by ok.
Please Log in or Create an account to join the conversation.
15 Apr 2023 08:16 #269067
by rodw
Will only be true during a G38 move so it will never trigger while machining...
Replied by rodw on topic new Component probefilter to handle "probe tripped ... errors"
I was using it on a plasma machine for its ohmic probe to sense material height so it was just touching the tool to the workpiece.Do you use the same cheap method of just contacting the tool to the workpiece for probing, or do you use the gated approach with a fancier, better probe?
motion.motion-type == 5
Please Log in or Create an account to join the conversation.
15 Apr 2023 08:35 - 15 Apr 2023 08:43 #269071
by ok
Replied by ok on topic new Component probefilter to handle "probe tripped ... errors"
[Still struggling with the forum code, I just wrote a reply that seems to have disappeared]
I see, yes that makes sense. This would be similar to my suggested fix of making sure that the motion type is correct within the probing code (but when the probing code thinks it is not probing).
However, doing it generally like that would make the probe insensitive also outside of probe moves, which would not prevent expensive crashes.
I want the probe to be also insensitive during a normal move when it retracts from the workpiece and might spuriously trip but I want it to be sensitive when I do a rapid move and prevent me from accidentally crashing.
On a plasma cutter doing sheet metal, I can imagine this is a lot less of a worry than on a mill with complex setups that one might easily crash into.
Does that make sense?
I see, yes that makes sense. This would be similar to my suggested fix of making sure that the motion type is correct within the probing code (but when the probing code thinks it is not probing).
However, doing it generally like that would make the probe insensitive also outside of probe moves, which would not prevent expensive crashes.
I want the probe to be also insensitive during a normal move when it retracts from the workpiece and might spuriously trip but I want it to be sensitive when I do a rapid move and prevent me from accidentally crashing.
On a plasma cutter doing sheet metal, I can imagine this is a lot less of a worry than on a mill with complex setups that one might easily crash into.
Does that make sense?
Last edit: 15 Apr 2023 08:43 by ok.
Please Log in or Create an account to join the conversation.
Time to create page: 0.152 seconds