Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions docs/src/config/ini-config.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -935,12 +935,19 @@ Finally, no amount of tweaking will speed up a tool path with lots of small, tig
For the common 'trivkins kinematics', joint numbers are assigned in sequence according to the trivkins parameter 'coordinates='.
So, for trivkins 'coordinates=xz', joint0 corresponds to X and joint1 corresponds to Z.
See the kinematics man page ('$ man kins') for information on trivkins and other kinematics modules.
* `FEED_AXES = X Y Z` - (((FEED AXES))) The axes the programmed feed rate F is measured along.
All of them must be `LINEAR` axes; the default is X Y Z.
A move goes at F along the straight line through the feed axes that move, and every other axis in the move arrives at the same time.
A move in which no feed axis moves goes at F along the other linear axes that move, and a move of angular axes only goes at F in degrees per minute.
With the defaults this is the RS274NGC rule: X Y Z, else U V W, else A B C.
With `FEED_AXES = X Y Z U`, for example, a move of X and U together goes at F along the line through both.
The maximum velocity slider of the GUIs caps the rate along that same line, and does not cap a move of angular axes only.
* `LINEAR_UNITS =` <units>_ - (((LINEAR UNITS))) Specifies the 'machine units' for linear axes.
Possible choices are mm or inch.
This does not affect the linear units in NC code (the G20 and G21 words do this).
* `ANGULAR_UNITS =` _<units>_ - (((ANGULAR UNITS))) Specifies the 'machine units' for rotational axes.
Possible choices are 'deg', 'degree' (360 per circle), 'rad', 'radian' (2*π per circle), 'grad', or 'gon' (400 per circle).
This does not affect the angular units of NC code. In RS274NGC, A-, B- and C- words are always expressed in degrees.
This does not affect the angular units of NC code. In RS274NGC, the words of an `ANGULAR` axis, A, B and C by default, are always expressed in degrees.
* `DEFAULT_LINEAR_VELOCITY = 0.0167` - The initial rate for jogs of linear axes, in machine units per second.
The value shown in 'AXIS' equals machine units per minute.
* `DEFAULT_LINEAR_ACCELERATION = 2.0` - In machines with nontrivial kinematics, the acceleration used for "teleop" (Cartesian space) jogs, in 'machine units' per second per second.
Expand Down Expand Up @@ -1022,8 +1029,11 @@ The _<letter>_ specifies one of: X Y Z A B C U V W
* `TYPE = LINEAR` - (enum) The type of this axis, either `LINEAR` or `ANGULAR`.
Required if this axis is not a default axis type.
The default axis types are X,Y,Z,U,V,W = LINEAR and A,B,C = ANGULAR.
This setting is effective with the AXIS GUI but note that other
GUI's may handle things differently.
X, Y and Z are always `LINEAR`.
A `LINEAR` axis is a length: its words, offsets, stored positions and tool offsets follow G20 and G21 and `[TRAJ]LINEAR_UNITS`.
An `ANGULAR` axis is an angle in degrees whatever G20 or G21 says, in `[TRAJ]ANGULAR_UNITS` for the machine, and may be a `WRAPPED_ROTARY` or have a `LOCKING_INDEXER_JOINT`.
The feed of a move depends on the type too, see `FEED_AXES` in the <<sub:ini:sec:traj,[TRAJ] section>>.
The AXIS GUI shows the axis in the units of its type; other GUIs may not.
* `MAX_VELOCITY = 1.2` - (real) Maximum velocity for this axis in <<sub:ini:sec:traj,machine units>> per second.
* `MAX_ACCELERATION = 20.0` - (real) Maximum acceleration for this axis in machine units per second squared.
* `MAX_JERK = 0.0` - (real) Maximum jerk for this axis in machine units per second cubed.
Expand All @@ -1039,11 +1049,12 @@ The _<letter>_ specifies one of: X Y Z A B C U V W
For a rotary axis (A,B,C typ) with unlimited rotation having no `MAX_LIMIT` for that axis in the `[AXIS_`<letter>`]` section a value of 1e99 is used.
* `WRAPPED_ROTARY = 1` - (bool) When this is set to 1 for an ANGULAR axis the axis will move 0-359.999 degrees.
Positive Numbers will move the axis in a positive direction and negative numbers will move the axis in the negative direction.
It is ignored on a `LINEAR` axis.
Mutually exclusive with `ROTARY_MODULO` (only one of the two can be set in a configuration).
* `ROTARY_MODULO = 1` - (bool) Continuous-modulo rotary mode.
* `ROTARY_MODULO = 1` - (bool) Continuous-modulo rotary mode for an ANGULAR axis, ignored on a `LINEAR` one.
Absolute moves on this axis take the shortest path: a `G0 A0` from a current position of A=50000 moves only the residual angle (40 deg in this example), not 138 full revolutions.
G-code may use absolute values of any magnitude (e.g. `A=200000` for helical-spiral CAM output) without the +/-360 limit imposed by `WRAPPED_ROTARY`.
System parameters `#5423`/`#5424`/`#5425` (and the named equivalents `#<_a>`/`#<_b>`/`#<_c>`, `#<_abs_a>`/`#<_abs_b>`/`#<_abs_c>`) report position wrapped to the range 0 up to but not including 360 degrees; probing parameters `#5064`/`#5065`/`#5066` likewise.
The axis's current position parameter (`#5423` to `#5428`, and the named equivalents `#<_a>` to `#<_w>` and `#<_abs_a>` to `#<_abs_w>`) reports position wrapped to the range 0 up to but not including 360 degrees; its probing parameter (`#5064` to `#5069`) likewise.
Internal commanded position and motion-side `motion.traj.position`/`joint.<n>.pos-fb` HAL pins remain accumulated to keep stepgens, encoders and PID loops consistent (no phantom unwind on wrap).
The accumulated physical position can still be read into G-code from the HAL pin via the `#<_hal[...]>` syntax (see <<sub:numbered-parameters,Numbered Parameters>> and the `HAL_PIN_VARS` setting in <<sub:ini:sec:rs274ngc,[RS274NGC] Section>>); for example `#<_hal[joint.3.pos-fb]>` returns the unwrapped joint position.
Threading (`G33`, `G33.1`, `G76`) is rejected with an error if the modulo axis word is present in the block.
Expand All @@ -1057,6 +1068,7 @@ The _<letter>_ specifies one of: X Y Z A B C U V W
When set, a G0 move for this axis will initiate an unlock with the `joint.4.unlock pin` then wait for the `joint.4.is-unlocked` pin then move the joint at the rapid rate for that joint.
After the move the `joint.4.unlock` will be false and motion will wait for `joint.4.is-unlocked` to go false.
Moving with other joints is not allowed when moving a locked rotary joint.
It is ignored on a `LINEAR` axis.
To create the unlock pins, use the motmod parameter:
+
[source,ini]
Expand Down
30 changes: 18 additions & 12 deletions docs/src/gcode/machining-center.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -179,14 +179,17 @@ rate is interpreted as follows (unless 'inverse time feed' or 'feed
per revolution' modes are being used, in which case see section
<<gcode:g93-g94-g95,G93-G94-G95-Mode,G93 G94 G95>>).

. If any of XYZ are moving, F is in units per minute in the XYZ
cartesian system, and all other axes (ABCUVW) move so as to start and
stop in coordinated fashion.
. Otherwise, if any of UVW are moving, F is in units per minute in the
UVW cartesian system, and all other axes (ABC) move so as to start and
stop in coordinated fashion.
. If any of the feed axes are moving, F is in units per minute in the
cartesian system of the feed axes, and all other axes move so as to
start and stop in coordinated fashion. The feed axes are X Y Z unless
`[TRAJ]FEED_AXES` in the INI file names others.
. Otherwise, if any of the other linear axes are moving, F is in units
per minute in their cartesian system, and the angular axes move so as
to start and stop in coordinated fashion. These are U V W unless
`[AXIS_<letter>]TYPE` in the INI file says otherwise.
. Otherwise, the move is pure rotary motion and the F word is in rotary
units in the ABC 'pseudo-cartesian' system.
units in the 'pseudo-cartesian' system of the angular axes, A B C
unless `[AXIS_<letter>]TYPE` says otherwise.

=== Cooling

Expand All @@ -208,11 +211,14 @@ the previous programmed move, as though it was in exact path mode.
=== Units

(((units)))
Units used for distances along the X, Y, and Z axes may be measured in
millimeters or inches. Units for all other quantities involved in
machine control cannot be changed. Different quantities use different
specific units. Spindle speed is measured in revolutions per minute.
The positions of rotational axes are measured in degrees. Feed rates
Units used for distances along the X, Y, and Z axes, and along any other
linear axis, may be measured in millimeters or inches. Units for all
other quantities involved in machine control cannot be changed.
Different quantities use different specific units. Spindle speed is
measured in revolutions per minute. The positions of rotational axes are
measured in degrees. An axis is linear or rotational as
`[AXIS_<letter>]TYPE` in the INI file says: U V W linear and A B C
rotational unless it says otherwise. Feed rates
are expressed in current length units per minute, or degrees per
minute, or length units per spindle revolution, as described in section
<<gcode:g93-g94-g95,G93 G94 G95>>.
Expand Down
2 changes: 1 addition & 1 deletion docs/src/gui/axis.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,7 @@ This slider sets the jog rate for the rotary axes (A, B and C).

By moving this slider, the maximum velocity can be set. This caps the
maximum velocity for all programmed moves except spindle-synchronized
moves.
moves and moves of angular axes only.

== Keyboard Controls

Expand Down
1 change: 1 addition & 0 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,7 @@ SRCHEADERS := \
emc/linuxcnc.h \
emc/kinematics/kinematics.h \
emc/nml_intf/emcmotcfg.h \
emc/ini/axis_kinds.hh \
emc/ini/inifile.hh \
emc/ini/inifile.h \
emc/nml_intf/emcpos.h \
Expand Down
121 changes: 121 additions & 0 deletions src/emc/ini/axis_kinds.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/********************************************************************
* Description: axis_kinds.hh
* Which of the nine axes are lengths and which are angles, and which
* axes the programmed feed is measured along, as the INI file says.
* The interpreter and canon both read it, so that they measure a move
* the same way.
*
* License: GPL Version 2
********************************************************************/
#ifndef AXIS_KINDS_HH
#define AXIS_KINDS_HH

#include <ctype.h>
#include <math.h>
#include <string.h>
#include <string>
#include <inifile.hh>

/* Axis numbers, the bit of each axis in the masks below */
enum AxisIndex {
AXIS_X, AXIS_Y, AXIS_Z,
AXIS_A, AXIS_B, AXIS_C,
AXIS_U, AXIS_V, AXIS_W,
};

#define AXIS_KINDS_ALL 0x1ffu /* X Y Z A B C U V W, bit 0 is X */
#define AXIS_KINDS_ABC 0x038u /* angular unless the INI says otherwise */
#define AXIS_KINDS_XYZ 0x007u /* the feed group unless the INI says otherwise */

struct AxisKinds {
unsigned angular; /* a bit per axis whose [AXIS_<letter>] TYPE is ANGULAR */
unsigned feed; /* a bit per axis in [TRAJ] FEED_AXES */
};

static inline AxisKinds axisKindsDefault()
{
return AxisKinds{AXIS_KINDS_ABC, AXIS_KINDS_XYZ};
}

static inline bool axisKindsAngular(const AxisKinds &k, int axis)
{
return (k.angular >> axis) & 1;
}

/* Read [AXIS_<letter>] TYPE (default: A B C angular) and [TRAJ] FEED_AXES
(default XYZ). X Y Z must be linear. Returns 0, or -1 with *err set. */
static inline int axisKindsRead(const linuxcnc::IniFile &ini, AxisKinds *k, std::string *err)
{
*k = axisKindsDefault();
for (int i = 0; i < 9; i++) {
char section[] = "AXIS_X";
section[5] = "XYZABCUVW"[i];
auto type = ini.findString("TYPE", section);
if (!type) { continue; }
if (*type == "ANGULAR") {
k->angular |= 1u << i;
} else if (*type == "LINEAR") {
k->angular &= ~(1u << i);
} else {
*err = "[" + std::string(section) + "] TYPE must be LINEAR or ANGULAR, not " + *type;
return -1;
}
}
if (k->angular & AXIS_KINDS_XYZ) {
*err = "[AXIS_X], [AXIS_Y] and [AXIS_Z] TYPE must be LINEAR";
return -1;
}
auto feed = ini.findString("FEED_AXES", "TRAJ");
if (!feed) { return 0; }
k->feed = 0;
const char *letters = "XYZABCUVW";
for (char ch : *feed) {
if (ch == ' ' || ch == '\t') { continue; }
const char *at = strchr(letters, toupper((unsigned char)ch));
if (!at || !*at) {
*err = std::string("[TRAJ] FEED_AXES: ") + ch + " is not an axis letter";
return -1;
}
int i = at - letters;
if (axisKindsAngular(*k, i)) {
*err = std::string("[TRAJ] FEED_AXES: ") + letters[i] + " is an ANGULAR axis; the feed group holds linear axes only";
return -1;
}
k->feed |= 1u << i;
}
if (!k->feed) {
*err = "[TRAJ] FEED_AXES names no axis";
return -1;
}
return 0;
}

/* The axes a move is measured along: the feed group if any of it moves,
else the other linear axes, else the angular ones. By default XYZ, else
UVW, else ABC. */
static inline unsigned axisKindsMeasured(const AxisKinds &k, unsigned moving)
{
unsigned linear = ~k.angular & ~k.feed & AXIS_KINDS_ALL;
if (moving & k.feed) { return k.feed; }
if (moving & linear) { return linear; }
return k.angular & ~k.feed & AXIS_KINDS_ALL;
}

/* Whether a set from axisKindsMeasured() is angles. */
static inline bool axisKindsMeasuredAngular(const AxisKinds &k, unsigned set)
{
return (set & k.angular) != 0;
}

/* The Euclidean length of the deltas d over the axes of set, summed in
axis order. */
static inline double axisKindsLength(unsigned set, const double d[9])
{
double sum = 0.0;
for (int i = 0; i < 9; i++) {
if (set & (1u << i)) { sum += d[i] * d[i]; }
}
return sqrt(sum);
}

#endif
7 changes: 5 additions & 2 deletions src/emc/motion/command.c
Original file line number Diff line number Diff line change
Expand Up @@ -1098,7 +1098,8 @@ void emcmotCommandHandler_locked(void *arg, long servo_period)
emcmotCommand->vel,
emcmotCommand->ini_maxvel,
emcmotCommand->acc,
emcmotCommand->ini_maxjerk,
emcmotCommand->ini_maxjerk,
emcmotCommand->vlimit_scale,
emcmotStatus->enables_new,
issue_atspeed,
emcmotCommand->turn,
Expand Down Expand Up @@ -1158,7 +1159,8 @@ void emcmotCommandHandler_locked(void *arg, long servo_period)
emcmotCommand->center, emcmotCommand->normal,
emcmotCommand->turn, emcmotCommand->motion_type,
emcmotCommand->vel, emcmotCommand->ini_maxvel,
emcmotCommand->acc, emcmotCommand->ini_maxjerk, emcmotStatus->enables_new,
emcmotCommand->acc, emcmotCommand->ini_maxjerk,
emcmotCommand->vlimit_scale, emcmotStatus->enables_new,
issue_atspeed, emcmotCommand->tag);
if (res_addcircle < 0) {
reportError(_("can't add circular move at line %d, error code %d"),
Expand Down Expand Up @@ -1637,6 +1639,7 @@ void emcmotCommandHandler_locked(void *arg, long servo_period)
emcmotCommand->ini_maxvel,
emcmotCommand->acc,
emcmotCommand->ini_maxjerk,
emcmotCommand->vlimit_scale,
emcmotStatus->enables_new,
issue_atspeed,
-1,
Expand Down
1 change: 1 addition & 0 deletions src/emc/motion/motion.h
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ extern "C" {
double acc; /* max acceleration */
double jerk; /* jerk for traj */
double ini_maxjerk;
double vlimit_scale; /* limitVel scale for this move, 0 no limit */
int planner_type; /* planner type: 0 = trapezoidal, 1 = S-curve */
double scurve_peak_scale; /* S-curve rest-to-rest peak scale (0.5=faithful..1.0=full) */
double backlash; /* amount of backlash */
Expand Down
3 changes: 3 additions & 0 deletions src/emc/nml_intf/emc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1072,6 +1072,7 @@ void EMC_TRAJ_LINEAR_MOVE::update(CMS * cms)
cms->update(ini_maxvel);
cms->update(ini_maxjerk);
cms->update(acc);
cms->update(vlimit_scale);
cms->update(feed_mode);
cms->update(indexer_jnum);
}
Expand All @@ -1096,6 +1097,7 @@ void EMC_TRAJ_CIRCULAR_MOVE::update(CMS * cms)
cms->update(ini_maxvel);
cms->update(ini_maxjerk);
cms->update(acc);
cms->update(vlimit_scale);
cms->update(feed_mode);
}

Expand Down Expand Up @@ -2090,6 +2092,7 @@ void EMC_TRAJ_PROBE::update(CMS * cms)
cms->update(ini_maxvel);
cms->update(ini_maxjerk);
cms->update(acc);
cms->update(vlimit_scale);
cms->update(probe_type);
}

Expand Down
9 changes: 6 additions & 3 deletions src/emc/nml_intf/emc.hh
Original file line number Diff line number Diff line change
Expand Up @@ -375,16 +375,19 @@ extern int emcTrajStep();
extern int emcTrajResume();
extern int emcTrajDelay(double delay);
extern int emcTrajLinearMove(const EmcPose& end, int type, double vel,
double ini_maxvel, double acc, double ini_maxjerk, int indexer_jnum);
double ini_maxvel, double acc, double ini_maxjerk,
double vlimit_scale, int indexer_jnum);
extern int emcTrajCircularMove(const EmcPose& end, const PM_CARTESIAN& center, const PM_CARTESIAN&
normal, int turn, int type, double vel, double ini_maxvel, double acc, double ini_maxjerk);
normal, int turn, int type, double vel, double ini_maxvel, double acc, double ini_maxjerk,
double vlimit_scale);
extern int emcTrajSetTermCond(int cond, double tolerance);
extern int emcTrajSetSpindleSync(int spindle, double feed_per_revolution, bool wait_for_index);
extern int emcTrajSetOffset(const EmcPose& tool_offset);
extern int emcTrajSetHome(const EmcPose& home);
extern int emcTrajClearProbeTrippedFlag();
extern int emcTrajProbe(const EmcPose& pos, int type, double vel,
double ini_maxvel, double acc, double ini_maxjerk, unsigned char probe_type);
double ini_maxvel, double acc, double ini_maxjerk,
double vlimit_scale, unsigned char probe_type);
extern int emcTrajRigidTap(const EmcPose& pos, double vel, double ini_maxvel, double acc, double ini_maxjerk, double scale);

extern int emcTrajUpdate(EMC_TRAJ_STAT * stat);
Expand Down
6 changes: 6 additions & 0 deletions src/emc/nml_intf/emc_nml.hh
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,7 @@ class EMC_TRAJ_LINEAR_MOVE:public EMC_TRAJ_CMD_MSG {
ini_maxvel(0.0),
acc(0.0),
ini_maxjerk(0.0),
vlimit_scale(1.0),
feed_mode(0),
indexer_jnum(0)
{};
Expand All @@ -753,6 +754,7 @@ class EMC_TRAJ_LINEAR_MOVE:public EMC_TRAJ_CMD_MSG {
int type;
EmcPose end; // end point
double vel, ini_maxvel, acc, ini_maxjerk;
double vlimit_scale; // see emcmot_command_t
int feed_mode;
int indexer_jnum;
};
Expand All @@ -770,6 +772,7 @@ class EMC_TRAJ_CIRCULAR_MOVE:public EMC_TRAJ_CMD_MSG {
ini_maxvel(0.0),
acc(0.0),
ini_maxjerk(0.0),
vlimit_scale(1.0),
feed_mode(0)
{};

Expand All @@ -784,6 +787,7 @@ class EMC_TRAJ_CIRCULAR_MOVE:public EMC_TRAJ_CMD_MSG {
int turn;
int type;
double vel, ini_maxvel, acc, ini_maxjerk;
double vlimit_scale; // see emcmot_command_t
int feed_mode;
};

Expand Down Expand Up @@ -930,6 +934,7 @@ class EMC_TRAJ_PROBE:public EMC_TRAJ_CMD_MSG {
ini_maxvel(0.0),
acc(0.0),
ini_maxjerk(0.0),
vlimit_scale(1.0),
probe_type(0)
{};

Expand All @@ -941,6 +946,7 @@ class EMC_TRAJ_PROBE:public EMC_TRAJ_CMD_MSG {
EmcPose pos;
int type;
double vel, ini_maxvel, acc, ini_maxjerk;
double vlimit_scale; // see emcmot_command_t
unsigned char probe_type;
};

Expand Down
4 changes: 2 additions & 2 deletions src/emc/rs274ngc/interp_check.cc
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ int Interp::check_spindle_sync_feed(setup_pointer settings, //!< pointer to mac

double length = 0.0;
for (int ax = 0; ax < 9; ax++) {
if (ax >= 3 && ax <= 5)
if (axisKindsAngular(settings->axis_kinds, ax))
continue; /* rotary */
length += delta[ax] * delta[ax];
}
Expand All @@ -501,7 +501,7 @@ int Interp::check_spindle_sync_feed(setup_pointer settings, //!< pointer to mac
double required_rate = fabs(pitch) * speed;

for (int ax = 0; ax < 9; ax++) {
if (ax >= 3 && ax <= 5)
if (axisKindsAngular(settings->axis_kinds, ax))
continue;
if (delta[ax] == 0.0)
continue;
Expand Down
Loading
Loading