199 lines
6.7 KiB
Plaintext
199 lines
6.7 KiB
Plaintext
/*
|
|
* G-code meta compiler
|
|
*
|
|
* Copyright (C) 2014 B. Stultiens
|
|
*
|
|
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
* Trochoidal example
|
|
* ------------------
|
|
* Trochoidal movement for high-speed milling. A path is followed in a circular
|
|
* pattern with given radius and increment. Afterwards, a clean cut is
|
|
* performed to remove the residuals.
|
|
*
|
|
* NOTE: To take full advantage of trochoidal milling, you need to have a CNC
|
|
* program that can look ahead to keep the speed high. For LinuxCNC that means
|
|
* you will need the git version on branch circular-blend-arc-rc3 (or any later
|
|
* branch thereof, until it is merges into the master branch).
|
|
*
|
|
* @@@--svg-toolwidth 0.5 --svg-opacity 0.25@@@
|
|
*/
|
|
|
|
/*
|
|
* Trochoidal point calculation.
|
|
* See: https://en.wikipedia.org/wiki/Trochoid
|
|
*/
|
|
function trochoid_point(ang, a, b)
|
|
{
|
|
ang = to_rad(ang); // Trochoids are defined in radians
|
|
// The first part is the trochoid, the second part moves the first 180
|
|
// degree point at a relative "0, 0" location so we can scale in any
|
|
// way without having to do hard math
|
|
return [ a * to_none(ang) - b * sin(ang), b - b * cos(ang) ] - [a*pi(), 2.0*b];
|
|
}
|
|
|
|
/*
|
|
* Perform a move from startpoint to endpoint using a trochoidal path.
|
|
* - Cutting at depth cutz (returns to old Z)
|
|
* - Trochoid radius as specified
|
|
* - Increment for each turn as specified
|
|
*/
|
|
function trochoid_move(startpoint, endpoint, cutz, radius, increment)
|
|
{
|
|
local min_ainc = .1deg; // avoid too long compute times (and log( value<=1))
|
|
local min_rotations = 5; // avoid confusing appearance if too small
|
|
local i;
|
|
local a = increment/(2.0*pi()); // Trochoid step parameter
|
|
local ainc = log10(to_mm(radius)) * 5.0deg; // Steps are logarithmic based on the radius to reduce small steps
|
|
local oldz = position()[2];
|
|
local vec = endpoint - startpoint; // Vector denoting path to move
|
|
|
|
if (ainc < min_ainc) {
|
|
error("ainc too small: ",ainc," (try: increase trochoid radius)");
|
|
return;
|
|
}
|
|
|
|
// If we are not moving, it is an error
|
|
if(length(vec) <= zero) {
|
|
error("trochoid move is not going anywhere");
|
|
return;
|
|
}
|
|
|
|
comment("-- trochoid_move at ", cutz, " from ", startpoint, " to ", endpoint, " radius=", radius, " increment=", increment, " --");
|
|
// Calculate the number of *whole* rotations, rounded up, we need to make
|
|
local n = 2.0rad * pi() * to_none(ceil(length(vec) / increment));
|
|
local nrotations = n/(2.0rad * pi());
|
|
if (nrotations < min_rotations) {
|
|
error("too few rotations= ",nrotations," (try: decrease trochoid increment)");
|
|
return;
|
|
}
|
|
if (verbose) {
|
|
comment("debug, rotations= ",nrotations);
|
|
comment("debug, ainc= ",ainc);
|
|
}
|
|
|
|
// The path may be arbitrary angled, get the angle for rotating the trochoid
|
|
local rot = atan(vec[1], vec[0]);
|
|
|
|
// Go to the trochoid entry-point and move to cutting deph
|
|
goto(startpoint + rotate_xy(trochoid_point(0.0rad, a, radius), rot));
|
|
move([-, -, cutz]);
|
|
|
|
// Calculate each next point of the trochoid until we traversed the whole path to the endpoint
|
|
for(i = 0.0deg; i < n; i += ainc) {
|
|
move(startpoint + rotate_xy(trochoid_point(i, a, radius), rot));
|
|
}
|
|
|
|
// Return to old Z so we will not bump into stuff
|
|
goto([-, -, oldz]);
|
|
comment("-- trochoid_move end --");
|
|
}
|
|
|
|
/* -------------------- Main Program -------------------- */
|
|
//ngcgui: info: troichoid-path example (mm or inch per parm#1 (units) setting, !! DEFAULTS are in mm !!)
|
|
//ngcgui: umode = 1; //, units: 1:mm, 0:inch
|
|
//ngcgui: trochoid_r = 5; //, trochoidal radius
|
|
//ngcgui: trochoid_incr = 2; //, trochoidal increment
|
|
//ngcgui: path_scale = 25; //, path scale (all xi,yi)
|
|
//ngcgui: xoffset = 0; //, path x offset
|
|
//ngcgui: yoffset = 0; //, path y offset
|
|
//ngcgui: x0 = 0; //, path x0
|
|
//ngcgui: y0 = 1; //, path y0
|
|
//ngcgui: x1 = 2; //, path x1
|
|
//ngcgui: y1 = 2; //, path y1
|
|
//ngcgui: x2 = 0; //, path x2
|
|
//ngcgui: y2 = 4; //, path y2
|
|
//ngcgui: x3 = -1; //, path x3
|
|
//ngcgui: y3 = 2; //, path y3
|
|
//ngcgui: cutdepth = -1; //
|
|
//ngcgui: safez = 5; // z safe
|
|
//ngcgui: x_return = 0; // x return
|
|
//ngcgui: y_return = 0; // y return
|
|
//ngcgui: fnormal = 300; //, feed normal
|
|
//ngcgui: fslow = 150; //, feed slow
|
|
//ngcgui: ffast = 3000; //, feed fast
|
|
//ngcgui: verbose = 1;
|
|
|
|
include("ensure_units.gcmc"); //avoid preamble conflict
|
|
if (umode == 1) {
|
|
zero = 0.0mm;
|
|
} else {
|
|
zero = 0.0in;
|
|
}
|
|
// ngcgui entries are unitless so these additions are used
|
|
// to ensure 1) floatingpoint and 2) units per umode setting
|
|
trochoid_r = zero + trochoid_r;
|
|
trochoid_incr = zero + trochoid_incr;
|
|
xoffset = zero + xoffset;
|
|
yoffset = zero + yoffset;
|
|
x0 = zero + x0;
|
|
y0 = zero + y0;
|
|
x1 = zero + x1;
|
|
y1 = zero + y1;
|
|
x2 = zero + x2;
|
|
y2 = zero + y2;
|
|
x3 = zero + x3;
|
|
y3 = zero + y3;
|
|
cutdepth = zero + cutdepth;
|
|
safez = zero + safez;
|
|
x_return = zero + x_return;
|
|
y_return = zero + y_return;
|
|
fnormal = zero + fnormal;
|
|
fslow = zero + fslow;
|
|
ffast = zero + ffast;
|
|
|
|
CUTZ = cutdepth;
|
|
SAFEZ = safez;
|
|
HOME = [x_return, y_return, safez];
|
|
|
|
path = { [xoffset + x0, yoffset + y0],
|
|
[xoffset + x1, yoffset + y1],
|
|
[xoffset + x2, yoffset + y2],
|
|
[xoffset + x3, yoffset + y3] };
|
|
path *= path_scale; //path_scale is dimensionless
|
|
|
|
feedrate(fnormal);
|
|
if (verbose) {
|
|
comment("debug, feed normal= ",fnormal);
|
|
}
|
|
goto([-, -, SAFEZ]);
|
|
move([-, -, SAFEZ]);
|
|
goto(HOME);
|
|
|
|
/* Trochoidal high-speed milling of the outline */
|
|
if (verbose) {
|
|
comment("debug, feed fast= ",ffast);
|
|
}
|
|
feedrate(ffast); // *Really* high-speed milling
|
|
repeat(count(path); i) {
|
|
trochoid_move(path[i-2], path[i-1], CUTZ, trochoid_r, trochoid_incr);
|
|
|
|
}
|
|
|
|
/* Clean-cutting the object */
|
|
if (verbose) {
|
|
comment("debug, feed slow= ",fslow);
|
|
}
|
|
feedrate(fslow); // "Finishing the edge" speed
|
|
pathmode(1); // Exact path mode so we hit the corners exactly
|
|
move([-, -, CUTZ]); // We are at the "outside" of the path, reenter cutting depth
|
|
move(path[-1]); // The first corner
|
|
foreach(path; v) {
|
|
move(v); // Trace the object
|
|
}
|
|
|
|
goto([-, -, SAFEZ]);
|
|
goto(HOME);
|