Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FR] rotational axes with feedrate calculation like in NIST RS274 NGC Interpreter - version 3 #23116

Closed
DerAndere1 opened this issue Nov 12, 2021 · 10 comments
Labels
C: Motion T: Feature Request Features requested by users.

Comments

@DerAndere1
Copy link
Contributor

DerAndere1 commented Nov 12, 2021

Is your feature request related to a problem? Please describe.

Currently, all axes are treated as linear axes. To support rotational axes, we should follow some standard. A relevant document is the documentation of the NIST RS274 NGC interpreter - version 3 (freely available at https://www.nist.gov/publications/nist-rs274ngc-interpreter-version-3 ). This reference is also used by other projects (LinuxCNC, synthetos/TinyG, synthetos/g2 (g2core) firmware). the NIST RS274 NGC interpreter that LinuxCNC is based on has two FEED_REFERENCE modes: CANON_XYZ and CANON_WORKPIECE. For the default CANON_XYZ mode, Interpretation of feedrate is specified in section "2.1.2.5 Feed Rate"

Are you looking for hardware support?

no

Describe the feature you want

We should change the code at

block->millimeters = SQRT(
and following lines to comply with RS274 NGC Gcode dialect as described in section "2.1.2.5 Feed Rate". I understand that section like this:

if one or more linear axis move, regardless of moves of rotational axes:
  feedrate is length of XYZ path (ignore rotational axes) in legth units per minute. 
  To incorporate secondary linear axes, We should probably do this (EDIT: Changed to do the same as LinuxCNC):
  feedrate = distance D in length units per minute. 
  if (dX || dY || dZ) {
    D = sqrt(dX^2 + dY^2 + dZ^2);
  else {
     D = sqrt(dU^2 + dV^2 + dW^2);
  }  
if only a rotational axis and no linear axis is moved:
   rotation of the rotational axis in degrees per minute (length unit ignored)

if two or three rotational axes but no linear axes are moving:
  total angular motion distance D = sqrt(dA^2 + dB^2 + dC^2). Let T be the amount of
  time required to move through D degrees at the current feed rate in degrees
  per minute. The rotational axes should be moved in coordinated linear motion
  so that the elapsed time from the start to the end of the motion is T plus
  any time required for acceleration or deceleration.

the implementation in the EMC (part of LinuxCNC) starts here; https://github.com/LinuxCNC/linuxcnc/blob/8a9665315cd96e9da24e08a0885b9a3686f1e7aa/src/emc/task/emccanon.cc#L608

Additional context

No response

@DerAndere1 DerAndere1 added the T: Feature Request Features requested by users. label Nov 12, 2021
@DerAndere1
Copy link
Contributor Author

DerAndere1 commented Nov 21, 2021

Here is my first draft of the implementation (for up to 9 axes).
The feature branch: https://github.com/DerAndere1/Marlin/tree/9axis_RS274NGC_feedrate (unreviewed, untested).
I made the reasonable assumtion that axes I/J/K can be either rotational (AXIS*_NAME 'A' or 'B' or 'C') or linear ((AXIS*_NAME 'U' or 'V' or 'W')). Axes 7-9 can only be linear (axes U, V, W).
Here are the relevant changes:
DerAndere1@07c076d

@DerAndere1
Copy link
Contributor Author

My implementation was tested successfully in a 4 axis machine. for pure rotational moves (only axes 'A', 'B' and 'C' involved) , feedrate is interpreted correctly in degrees per minute, even in inch mode (after G20).

@DerAndere1
Copy link
Contributor Author

This feature is implemented as part of #23112

@krassynesh
Copy link

Hello, DerAndere1
I'm using Mega 2560 R3 + 12864Display and ramps 1.4 ( https://a.aliexpress.com/_mLEF23E ) I like to use Marlin to control 4 axis + 4 home switches, 3 Servos and Exits D8, D9 and D10
Please help in this matter
Best regards

@DerAndere1
Copy link
Contributor Author

DerAndere1 commented Feb 15, 2022

@i-make-robots : To answer the questions raised in the discord channel:

Why discount the rotation from the distance?

Meaningful concepts for the feedrate exist only in the cartesian space. Also it is what NIST RS274NGC v.3 (and by extension LinuxCNC) Gcode specification says for the default feed reference mode (CANON_XYZ). Extra axes movement will be ignored for the calculation of motor speeds. Still, ALL axes move to the specified destination for each G1.

Don’t want to miss steps on those rotations just because the linear was very small.

In a move like G1 X1 U350 F1000 the firmware will first try to move the motors so that t=SQRT(1mm^2)/1000(mm/min)). But it will limit the speed so that the maximum allowed acceleration and speed for any axis is never exceeded. In all cases it will move the axis that must move a shorter distance so slow that that all motors finish at the same time.

A separate cap per-motor later would effectively reintroduce the constraint, so… doesn’t change much?

For moves where the maxium allowed speeds of any axis (defined by DEFAULT_MAX_FEEDRATE, overwritten by M203) are reached, the proposed code change woud not change the duration of the move. If the max speed of the axes is not reached during a move involving any XYZ axes AND any UVW axes, the code change increases the speed of axes.

Again:

Why discount the rotation from the distance?

LinuxCNC / NIST RS274NGC also supports CANON_WORKPIECE feed reference mode which probably results in a more intuitive feedrate interpretation where feedrate is defined as the surface speed along the workpiece surface (from the perspective of the workpiece). However that would require built-in multi-axis inverse kinematics in Marlin, if I'm not mistaking

So to continue support for articulated robots without buil-in kinematics, I think we should add a special config option to get the old behaviour:

#define ARTICULATED_ROBOT_ARM

float distance_sqr = (
  #if defined(ARTICULATED_ROBOT_ARM)
    LINEAR_AXIS_GANG(
        sq(steps_dist_mm.x), + sq(steps_dist_mm.y), + sq(steps_dist_mm.z),
      + sq(steps_dist_mm.i), + sq(steps_dist_mm.j), + sq(steps_dist_mm.k),
      + sq(steps_dist_mm.u), + sq(steps_dist_mm.v), + sq(steps_dist_mm.w)
    );
  #elif ...

or maybe, for those robots, feedrate should be the speed of the axis that travels the furthest distance?

#define ARTICULATED_ROBOT_ARM

float distance_sqr = (
  #if defined(ARTICULATED_ROBOT_ARM)
    MAX_(LINEAR_AXIS_GANG(
        sq(steps_dist_mm.x), sq(steps_dist_mm.y), sq(steps_dist_mm.z),
        sq(steps_dist_mm.i), sq(steps_dist_mm.j), sq(steps_dist_mm.k),
        sq(steps_dist_mm.u), sq(steps_dist_mm.v), sq(steps_dist_mm.w)
  ));
  #elif ...

@DerAndere1
Copy link
Contributor Author

DerAndere1 commented Feb 17, 2022

@i-make-robots : I added an option ARTICULATED_ROBOT_ARM to PR #23112 . If enabled, you will get the old feedrate interpretation. As long as we have no inverse kinematics for such robots built in, the old feedrate interpretation is a suitable workaround that is also used by grblHAL/core, synthetos/g2core and Duet3D/RepRapFirmware, IIRC.

@i-make-robots
Copy link
Contributor

i-make-robots commented Feb 17, 2022 via email

@DerAndere1
Copy link
Contributor Author

Regardless of the option name, this needs to be documented. The first place where I will document the option will be https://github.com/DerAndere1/Marlin/blob/Marlin2ForPipetBot/README.md

We might change the name of ARTICULATED_ROBOT_ARM. Some alternatives:
ROBOT_ARM: might not be specific enough because some people might see a SCARA setup and call it a robot arm.
ARTICULATED_ROBOT: technically better but it does not mean anything to people that are not native speakers.
ALL_AXES_FEED_REFERENCE: In analogy to FEED_REFERENCE = CANON_XYZ from LinuxCNC / RS274NGC. Best name if this behavior is also desired for machines other than articulated robots.

@DerAndere1
Copy link
Contributor Author

This feature is part of Marlin bugfix-2.0.x since PR 23112 was merged. I also opened PR 446 in the MarlinDocumentation repo MarlinFirmware/MarlinDocumentation#446 to update the documentation. Detailed information can also be found at https://github.com/DerAndere1/Marlin/wiki

@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked and limited conversation to collaborators Jun 21, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
C: Motion T: Feature Request Features requested by users.
Projects
None yet
Development

No branches or pull requests

4 participants