Path: Adaptive - improvements and bug fixes

- more accurate path smoothing
- fix for missing helix lead-in in some cases
- fix for cleaning of helix center point
- increased max allowed step-over to 75%
This commit is contained in:
kreso-t
2018-09-26 18:41:27 +02:00
committed by wmayer
parent 96ea2d470e
commit a9dfb16998
3 changed files with 84 additions and 50 deletions

View File

@@ -85,9 +85,13 @@ def GenerateGCode(op,obj,adaptiveResults, helixDiameter):
return
minLiftDistance = op.tool.Diameter
p1 = adaptiveResults[0]["HelixCenterPoint"]
p2 = adaptiveResults[0]["StartPoint"]
helixRadius =math.sqrt((p1[0]-p2[0]) * (p1[0]-p2[0]) + (p1[1]-p2[1]) * (p1[1]-p2[1]))
helixRadius=0
for region in adaptiveResults:
p1 = region["HelixCenterPoint"]
p2 = region["StartPoint"]
r =math.sqrt((p1[0]-p2[0]) * (p1[0]-p2[0]) + (p1[1]-p2[1]) * (p1[1]-p2[1]))
if r>helixRadius: helixRadius=r
stepDown = obj.StepDown.Value
passStartDepth=obj.StartDepth.Value
if stepDown<0.1 : stepDown=0.1
@@ -116,6 +120,9 @@ def GenerateGCode(op,obj,adaptiveResults, helixDiameter):
passDepth = (passStartDepth - passEndDepth)
p1 = region["HelixCenterPoint"]
p2 = region["StartPoint"]
helixRadius =math.sqrt((p1[0]-p2[0]) * (p1[0]-p2[0]) + (p1[1]-p2[1]) * (p1[1]-p2[1]))
#helix ramp
if helixRadius>0.0001:
@@ -146,6 +153,16 @@ def GenerateGCode(op,obj,adaptiveResults, helixDiameter):
lx=x
ly=y
fi=fi+math.pi/16
# one more circle at target depth to make sure center is cleared
maxfi=maxfi+2*math.pi
while fi<maxfi:
x = region["HelixCenterPoint"][0] + r * math.cos(fi+offsetFi)
y = region["HelixCenterPoint"][1] + r * math.sin(fi+offsetFi)
z = passEndDepth
op.commandlist.append(Path.Command("G1", { "X": x, "Y":y, "Z":z, "F": op.horizFeed}))
lx=x
ly=y
fi=fi+math.pi/16
else: # no helix entry
op.commandlist.append(Path.Command(
"G0", {"X": region["StartPoint"][0], "Y": region["StartPoint"][1], "Z": obj.ClearanceHeight.Value}))
@@ -216,10 +233,8 @@ def Execute(op,obj):
FreeCADGui.updateGui()
try:
Console.PrintMessage("Tool diam: %f \n"%op.tool.Diameter)
helixDiameter = min(op.tool.Diameter,1000.0 if obj.HelixDiameterLimit.Value==0.0 else obj.HelixDiameterLimit.Value )
helixDiameter =obj.HelixDiameterLimit.Value
topZ=op.stock.Shape.BoundBox.ZMax
obj.Stopped = False
obj.StopProcessing = False
if obj.Tolerance<0.001: obj.Tolerance=0.001

View File

@@ -61,7 +61,7 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage):
#step over
form.StepOver = QtGui.QSpinBox()
form.StepOver.setMinimum(15)
form.StepOver.setMaximum(50)
form.StepOver.setMaximum(75)
form.StepOver.setSingleStep(1)
form.StepOver.setValue(25)
form.StepOver.setToolTip("Optimal value for tool stepover")
@@ -92,7 +92,7 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage):
form.HelixDiameterLimit.setMaximum(90)
form.HelixDiameterLimit.setSingleStep(0.1)
form.HelixDiameterLimit.setValue(0)
form.HelixDiameterLimit.setToolTip("If >0 it limits the helix ramp diameter\notherwise the tool diameter is used as helix diameter")
form.HelixDiameterLimit.setToolTip("If >0 it limits the helix ramp diameter\notherwise the 75 percent of tool diameter is used as helix diameter")
formLayout.addRow(QtGui.QLabel("Helix Max Diameter"),form.HelixDiameterLimit)
#lift distance

View File

@@ -316,6 +316,16 @@ double DistancePointToLineSegSquared(const IntPoint &p1, const IntPoint &p2, con
return DX * DX + DY * DY; // return distance squared
}
void ScalePaths(Paths &paths,double scaleFactor) {
for(auto &pth:paths) {
for(auto &pt:pth) {
pt.X= pt.X * scaleFactor;
pt.Y= pt.Y * scaleFactor;
}
}
}
// joins collinear segments (within the tolerance)
void CleanPath(const Path &inp, Path &outp, double tolerance)
{
@@ -560,12 +570,13 @@ bool IntersectionPoint(const Paths &paths, const IntPoint &p1, const IntPoint &p
return false;
}
void SmoothPaths(Paths &paths, double stepSize, int pointCount)
void SmoothPaths(Paths &paths, double stepSize, long pointCount, long iterations)
{
Paths output;
output.clear();
output.resize(paths.size());
double scale=1000;
ScalePaths(paths,scale);
vector<pair<size_t /*path index*/, IntPoint>> points;
for (size_t i = 0; i < paths.size(); i++)
{
@@ -579,29 +590,24 @@ void SmoothPaths(Paths &paths, double stepSize, int pointCount)
IntPoint lastPt = points.back().second;
size_t lastPathIndex = points.back().first;
double dsqr = DistanceSqrd(lastPt, pt);
if (dsqr < SAME_POINT_TOL_SQRD_SCALED)
double l = sqrt(DistanceSqrd(lastPt, pt));
if (l < 0.5*stepSize*scale)
{
points.pop_back();
points.push_back(pair<size_t /*path index*/, IntPoint>(i, pt));
continue;
}
double l = sqrt(dsqr);
if (l < stepSize)
{
points.pop_back();
points.push_back(pair<size_t /*path index*/, IntPoint>(i, pt));
continue;
}
long steps = long(l / stepSize) + 1;
long steps = long(l / (stepSize*scale))+1; // +1 is important!
for (long idx = 0; idx <= steps; idx++)
{
double p = double(idx) / steps;
IntPoint ptx(long(lastPt.X + double(pt.X - lastPt.X) * p),
long(lastPt.Y + double(pt.Y - lastPt.Y) * p));
if(idx==0) {
if(DistanceSqrd(points.back().second,ptx)<scale) points.pop_back();
}
if (p < 0.5)
points.push_back(pair<size_t /*path index*/, IntPoint>(lastPathIndex, ptx));
else
@@ -611,40 +617,48 @@ void SmoothPaths(Paths &paths, double stepSize, int pointCount)
}
if (points.empty())
return;
for (long i = 0; i < (long)points.size(); i++)
{
IntPoint avgPoint(points[i].second);
IntPoint pp = avgPoint;
long cnt = 1;
long ptsToAverage = pointCount;
if (i < ptsToAverage)
ptsToAverage = i;
while (i + ptsToAverage >= long(points.size()))
ptsToAverage--;
long lowLimit = i - ptsToAverage;
long highLimit = i + ptsToAverage;
for (long j = lowLimit; j < highLimit; j++)
long size=long(points.size());
for(long iter=0;iter<iterations; iter++) {
for (long i = 0; i < size; i++)
{
if (j != i)
IntPoint avgPoint(points[i].second);
double cnt = 1;
long ptsToAverage = pointCount;
if (i < ptsToAverage)
ptsToAverage = max(i-1,0L);
while (i + ptsToAverage >= long(points.size()-1))
ptsToAverage--;
for (long j = i-ptsToAverage; j <= i+ptsToAverage; j++)
{
IntPoint &p = points.at(j).second;
avgPoint.X += p.X;
avgPoint.Y += p.Y;
pp = p;
cnt++;
if (j != i)
{
long index=j;
if(index<0) index=0;
if(index>=size) index=size-1;
IntPoint &p = points.at(index).second;
avgPoint.X += p.X;
avgPoint.Y += p.Y;
cnt++;
}
}
avgPoint.X /= cnt;
avgPoint.Y /= cnt;
points[i].second=avgPoint;
}
avgPoint.X /= cnt;
avgPoint.Y /= cnt;
output.at(points[i].first).push_back(avgPoint);
}
for (long i = 0; i < size; i++)
{
output.at(points[i].first).push_back(points[i].second);
}
for (size_t i = 0; i < paths.size(); i++)
{
CleanPath(output[i], paths[i], 4);
CleanPath(output[i], paths[i], scale);
}
ScalePaths(paths,1.0/scale);
}
bool PopPathWithClosestPoint(Paths &paths /*closest path is removed from collection and shifted to start with closest point */
@@ -1630,12 +1644,17 @@ std::list<AdaptiveOutput> Adaptive2d::Execute(const DPaths &stockPaths, const DP
if (scaleFactor > 250)
scaleFactor = 250;
cout << "Tool Diam: " << toolDiameter << endl;
cout << "Accuracy: " << 1000.0/scaleFactor << " um" << endl;
toolRadiusScaled = long(toolDiameter * scaleFactor / 2);
stepOverScaled = toolRadiusScaled * stepOverFactor;
progressCallback = &progressCallbackFn;
lastProgressTime = clock();
stopProcessing = false;
if(helixRampDiameter<NTOL)
helixRampDiameter=0.75*toolDiameter;
if (helixRampDiameter > toolDiameter)
helixRampDiameter = toolDiameter;
if (helixRampDiameter < toolDiameter / 8)
@@ -2397,7 +2416,7 @@ void Adaptive2d::AppendToolPath(TPaths &progressPaths, AdaptiveOutput &output,
linkPath.push_back(leadInPath.front());
}
/* paths smoothhing*/
/* paths smoothing*/
Paths linkPaths;
linkPaths.push_back(leadOutPath);
linkPaths.push_back(linkPath);
@@ -2405,7 +2424,7 @@ void Adaptive2d::AppendToolPath(TPaths &progressPaths, AdaptiveOutput &output,
if (linkType == MotionType::mtLinkClear)
{
SmoothPaths(linkPaths, 0.05 * stepOverScaled, 16);
SmoothPaths(linkPaths, 0.05 * stepOverScaled,4,4);
}
leadOutPath = linkPaths[0];