Can a component know the diameter of an arc its cutting

More
16 Feb 2019 12:32 #126607 by rodw
According to the docs motion.motion−type can tell us when we are traversing an arc.
Is it possible for a Hal component to find out the diameter of that arc?
If not, would that info be in the state-tags branch if it is ever released?
I'd like Hal to be able to slow the feedrate if an arc is less then a threshold diameter without resorting to gcode.

Please Log in or Create an account to join the conversation.

More
16 Feb 2019 14:39 #126609 by tommylight
That is normally done in CAM, but i get the idea, although i do not like cramming everything under the sun in one app.
Then again, Linuxcnc is so modular so adding that as another module would make life a bit easier for us.
I assume you need this for plasma cutting as the radius cut ends up worse than the rest of the cuts, and slowing down is just one of the options, mind you, the only viable one.

Please Log in or Create an account to join the conversation.

More
16 Feb 2019 17:10 #126615 by nkp
You can read file_gcode in load_time,
determine line numbers that contain arcs, calculate the radius and write it into a separate file,
and then pass them to the real-time component using streamer-halstreamer.
something like that I did before:
/* sudo halcompile --install kl.comp */
component kl "syringe confectioner";

pin in  float velxy ;     // motion.current-vel
pin in  float overall ;   // pyvcp.scale

pin out float out ;       // stepgen.3.velocity-cmd
pin in  s32 line ;         // stepgen.3.count 

pin in  s32 line ;         // motion.program-line

pin in  float dtg ;       //  motion.distance-to-go
                         
pin in  s32    instr ;     //streamer.0.pin.0  (s32)
pin in  float indtg ;     //streamer.0.pin.1  (float) 
                             
pin in  s32 type ;         // motion.motion-type  1:Traverse
pin in  bit offon ;        // pyvcp.button

 pin in  s32 cdepth ;       //streamer.0.curr-depth s32 output

pin out s32  override ;     //halui.feed-override.counts   (100 - (6.6667/(requestedvel/100)))*-0.1
   
pin in  float requestedvel ;            //motion.requested-vel

pin in   bit empty ;         //streamer.0.empty 
pin out  bit clock ;         //streamer.0.clock

pin in  float k;         // (k * out) stepgen-velocity index
pin in  float kss;       // (kss * out) stepgen-velocity for start-stop line

param rw float addline;   // start-stop lines length

variable int  type_indicator = 0;
variable double timer;
variable float pathxy = 0;
variable int  i = 0;
variable unsigned  tt = 0;
variable int  q = 0;
variable int  all_string = 0;

variable int   enable_increment = 0;
variable int   repeat = 0;

variable int   oldline = 0;

variable float rvel;
function _;
license "GPL";

;;
#include "rtapi_math.h"

FUNCTION(_) {

    static int arr_line[100];
    static float arr_dtg[100];
    
    //if we interrupt the program(Gcode)
    if ((oldline - line) > 2) {
        q=0;
        enable_increment = 0;
        all_string = 0;
    }
    if (offon) {
        if (type == 1) {  //G0
            type_indicator = 1;
            out = 0;
            all_string = 0;
        } else {  // G1 G2 G3
            if (type_indicator == 1) {
                out = ((velxy/6.66667)*kss + overall);
                //override feed
                override = -6;
                //integrator
                if (velxy >= 0.0) { 
                    pathxy = pathxy + velxy * fperiod;
                } else {
                    pathxy = pathxy - velxy * fperiod;
                }
                if (pathxy >= addline) {
                    pathxy =  0.0; type_indicator = 0; override = 0;
                }
            } else {
                if (all_string) {
                out = (-(velxy/6.66667) * kss + overall);
                override = -6;
                } else {
                    if (line == arr_line[q] && arr_line[q] != 0) {
                        enable_increment = 1;
                        oldline = line;
                        if (dtg <= arr_dtg[q]){
                            out = (-(velxy/6.66667) * kss + overall);
                            //override feed
                            override = -6;
                            all_string = 1;
                        } else {
                            out = ((velxy/16.66667)*k + overall);
                            override = 0;
                        }
                    } else {
                        if (enable_increment) { 
                            if (q==repeat) {
                                q=0;
                            } else {
                                q++;
                            }
                        }
                        enable_increment = 0;
                        out = ((velxy/16.66667)*k + overall);
                        override = 0;
                    }
                }
            }
        }
    } else {
        out = 0;
        //override = 0;
    }
    if (empty == 0) {       //streamer.0.empty 
        if (tt % 2 != 0) { 
            clock = 0;     //streamer.0.clock (streamer.0.clock-mode 2)
            arr_line[i] = instr;  //streamer.0.pin.0
            arr_dtg[i] = indtg;
            i++;
        } else {
            clock = 1;
        }
        tt++;
        if (i) {
        repeat = i-1;
        }
    }
    else {
        i=0;
    }
}

























Please Log in or Create an account to join the conversation.

More
16 Feb 2019 21:55 - 16 Feb 2019 22:02 #126624 by rodw

That is normally done in CAM, but i get the idea, although i do not like cramming everything under the sun in one app.
Then again, Linuxcnc is so modular so adding that as another module would make life a bit easier for us.
I assume you need this for plasma cutting as the radius cut ends up worse than the rest of the cuts, and slowing down is just one of the options, mind you, the only viable one.


Tommy you guessed it. I've played around with sheetcam cutting rules but had troubles where I had chaincut into a hole to avoid a pierce. But I could not make them work so that it would ignore say a 3mm fillet on a corner that was there to help the Trajectory planner out and activate on a 12mm hole with an opening one side. The Sheetcam OnArc() function can calculate the radius so it can be done there.

The trajectory planner short segment slow downs combined with THC velocity hold disabling does go a long way to fixing most problems but sometimes it does not slow the cut down enough. If I knew the arc radius in real time, I could just use a limit component to limit velocity.

You can read file_gcode in load_time,
determine line numbers that contain arcs, calculate the radius and write it into a separate file,
and then pass them to the real-time component using streamer-halstreamer.


nkp, thanks for that idea. I have played around with streamer/halstreamer. I never thought of using it like that. I think though that SheetCAM is probably a better place for this one.

From what I know its not possible to do in Hal, but I was hoping somebody might know a bit more or possibly even know something about the statetags branch which might support it. It would be good if it could become a trajectory planner feature for us plasma nerds.
Last edit: 16 Feb 2019 22:02 by rodw.
The following user(s) said Thank You: tommylight

Please Log in or Create an account to join the conversation.

More
25 Feb 2019 22:40 #127125 by andypugh

Is it possible for a Hal component to find out the diameter of that arc?


It can be calculated from the X and Y positions inside a custom component.
Then output that to a lincurve and put the lincurve into the adaptive feed pin.

1) Compare the new positions to the old to get a dx and dy
2) use atan2 to get the "heading"
3) compare the rate of change of heading to the absolute velocity to determine the radius.
4) Make Profit.
The following user(s) said Thank You: rodw

Please Log in or Create an account to join the conversation.

More
26 Feb 2019 10:14 #127150 by rodw

Is it possible for a Hal component to find out the diameter of that arc?


It can be calculated from the X and Y positions inside a custom component.
Then output that to a lincurve and put the lincurve into the adaptive feed pin.

1) Compare the new positions to the old to get a dx and dy
2) use atan2 to get the "heading"
3) compare the rate of change of heading to the absolute velocity to determine the radius.
4) Make Profit.


Andy very interesting approach so thank you. I don't understand item 3. Could you elaborate on this?

To me rate of change of heading is
heading_rate = (this_heading - last_heading)/fperiod;

Are you saying just find the difference between heading_rate and current_velocity? How does that work?

Please Log in or Create an account to join the conversation.

More
26 Feb 2019 12:24 - 26 Feb 2019 12:26 #127154 by rodw
Well, I've been studying this and its an exercise in circular motion. I don't ever remember studying this...
I think we we had calculated omega (w) eg. heading_rate = w (in radians per second)
and LinuxCNC always knows absolute velocity (motion.current_velocity)
So from the formula
w = heading_rate
v = motion.current_velocity
vw = (w^2)r
so:
r =  vw /(w^2)
r = v/w   //  radius  = motion.current_velocity /  heading_rate

Can someone confirm this is correct?

So then we can use lincurve or our own algorithm to set motion.adaptive−feed to slow down on a radius.

Very very cool, thanks Andy!
Last edit: 26 Feb 2019 12:26 by rodw.

Please Log in or Create an account to join the conversation.

More
26 Feb 2019 13:25 #127156 by andypugh
The equation is a little simpler than you have written it:

v = rw

(vw = w^2.r simplifies to this if you just divide by w)

So r = v/w as you concluded.
The following user(s) said Thank You: rodw

Please Log in or Create an account to join the conversation.

More
26 Feb 2019 19:29 #127179 by rodw
Andy, thanks so much. I think this is going to be a very useful component once I get it written.

Please Log in or Create an account to join the conversation.

More
28 Feb 2019 10:57 - 28 Feb 2019 10:57 #127318 by rodw
I had a go at this and need a bit of help.
The logic is right, the arc is identified, the slope/heading/tangent is correctly calculated. I added a heap of debug pins including converting radius to degrees which is easier to understand. If you cut a circle , In halshow you can see the heading increase from 0 to 180 degrees, then change sign and go back to 0. Watching the cut in a sim, and visualising where the tangent intersects the circle, this is exactly what should be happening.

But, the calculated radius varies significantly.

I've attached the component if somebody (maybe even Andy :) ) could have a look at it, it would be appreciated.
Attachments:
Last edit: 28 Feb 2019 10:57 by rodw.

Please Log in or Create an account to join the conversation.

Time to create page: 0.076 seconds
Powered by Kunena Forum