Hi vektor_z,
I think that the feed rate should be uniform for the tool, and not for Z axis, but if one of the X-axis will do a straight neckline, the second and third X-axis can slow down or stop, nothing bad will.
That sounds good. Performing feed rate control through XZAB space (where A and B are linear axes) will not be exactly correct but I think reasonable enough. They will all be treated as orthogonal Axes. So for example if both cutters are plunging at the same time (and the other axes are not moving) then they will both move at 0.707 of the commanded feed rate (as if it was an orthogonal XY motion).
I understand the logic of the program, but do not understand the step # 2
# 2 recursively subdivide each line segment until it is very small (ie less than 20um long)
Can you explain more about the dividing line?
You can divide a line segment into two haves by using the midpoint of the beginning and end of the segment. Below is some KFLOP C Code to do this (also attached as a txt file). The code will repeatedly divide the segment into two haves until it is smaller than a specified threshold.
Code:
#include "KMotionDef.h"
#define MAX_POINTS 300000
#define MAX_ALLOWED_LENGTH 0.1
int pindex=0; //point index
double *Xpoints;
double *Zpoints;
// find line segment length
double FindLength(double x0, double z0, double x1, double z1)
{
return sqrt((x1-x0)*(x1-x0)+(z1-z0)*(z1-z0));
}
// compute mid point
double MidPoint(double x0, double z0, double x1, double z1, double *xm, double *zm)
{
*xm = (x0+x1)/2.0;
*zm = (z0+z1)/2.0;
}
// if segment is short just store it, otherwise recursively divide it and store those
// return 0 if saved, return 1 if error
int StoreDividedSegment(double x0, double z0, double x1, double z1)
{
double xm,zm;
if (FindLength(x0,z0,x1,z1) < MAX_ALLOWED_LENGTH) // short?
{
// yes it is short
if (pindex >= MAX_POINTS) // too many segments?
{
printf("Too many segments\n");
return 1; // return error
}
// yes, save it
Xpoints[pindex] = x1;
Zpoints[pindex] = z1;
pindex++;
}
else
{
// no it is long split it
MidPoint(x0,z0,x1,z1,&xm,&zm);
if (StoreDividedSegment(x0,z0,xm,zm)) return 1; // first half
if (StoreDividedSegment(xm,zm,x1,z1)) return 1; // 2nd half
}
return 0;
}
main()
{
int i,result;
Xpoints = gather_buffer;
Zpoints = gather_buffer+MAX_POINTS;
// put starting point
Xpoints[pindex] = 0.5;
Zpoints[pindex] = 0.0;
pindex++;
result = StoreDividedSegment(0.5, 0.0, 1.0, 2.0); // subdivide and store one long segment
if (result==0)
printf("Segment divided successfully total points = %d\n",pindex);
result = StoreDividedSegment(1.0, 2.0, 0.5, 4.0); // subdivide and store one long segment
if (result==0)
printf("Segment divided successfully total points = %d\n",pindex);
for(i=0;i<pindex;i++)
printf("N%d G1 X%f Z%f\n",i,Xpoints[i],Zpoints[i]);
}
Here is the program output:
Code:
Segment divided successfully total points = 33
Segment divided successfully total points = 65
N0 G1 X0.500000 Z0.000000
N1 G1 X0.515625 Z0.062500
N2 G1 X0.531250 Z0.125000
N3 G1 X0.546875 Z0.187500
N4 G1 X0.562500 Z0.250000
N5 G1 X0.578125 Z0.312500
N6 G1 X0.593750 Z0.375000
N7 G1 X0.609375 Z0.437500
N8 G1 X0.625000 Z0.500000
N9 G1 X0.640625 Z0.562500
N10 G1 X0.656250 Z0.625000
N11 G1 X0.671875 Z0.687500
N12 G1 X0.687500 Z0.750000
N13 G1 X0.703125 Z0.812500
N14 G1 X0.718750 Z0.875000
N15 G1 X0.734375 Z0.937500
N16 G1 X0.750000 Z1.000000
N17 G1 X0.765625 Z1.062500
N18 G1 X0.781250 Z1.125000
N19 G1 X0.796875 Z1.187500
N20 G1 X0.812500 Z1.250000
N21 G1 X0.828125 Z1.312500
N22 G1 X0.843750 Z1.375000
N23 G1 X0.859375 Z1.437500
N24 G1 X0.875000 Z1.500000
N25 G1 X0.890625 Z1.562500
N26 G1 X0.906250 Z1.625000
N27 G1 X0.921875 Z1.687500
N28 G1 X0.937500 Z1.750000
N29 G1 X0.953125 Z1.812500
N30 G1 X0.968750 Z1.875000
N31 G1 X0.984375 Z1.937500
N32 G1 X1.000000 Z2.000000
N33 G1 X0.984375 Z2.062500
N34 G1 X0.968750 Z2.125000
N35 G1 X0.953125 Z2.187500
N36 G1 X0.937500 Z2.250000
N37 G1 X0.921875 Z2.312500
N38 G1 X0.906250 Z2.375000
N39 G1 X0.890625 Z2.437500
N40 G1 X0.875000 Z2.500000
N41 G1 X0.859375 Z2.562500
N42 G1 X0.843750 Z2.625000
N43 G1 X0.828125 Z2.687500
N44 G1 X0.812500 Z2.750000
N45 G1 X0.796875 Z2.812500
N46 G1 X0.781250 Z2.875000
N47 G1 X0.765625 Z2.937500
N48 G1 X0.750000 Z3.000000
N49 G1 X0.734375 Z3.062500
N50 G1 X0.718750 Z3.125000
N51 G1 X0.703125 Z3.187500
N52 G1 X0.687500 Z3.250000
N53 G1 X0.671875 Z3.312500
N54 G1 X0.656250 Z3.375000
N55 G1 X0.640625 Z3.437500
N56 G1 X0.625000 Z3.500000
N57 G1 X0.609375 Z3.562500
N58 G1 X0.593750 Z3.625000
N59 G1 X0.578125 Z3.687500
N60 G1 X0.562500 Z3.750000
N61 G1 X0.546875 Z3.812500
N62 G1 X0.531250 Z3.875000
N63 G1 X0.515625 Z3.937500
N64 G1 X0.500000 Z4.000000
HTH
Regards