Hello Guest it is May 16, 2021, 05:00:23 AM

Author Topic: Real G93 Gcode anyone  (Read 5668 times)

0 Members and 1 Guest are viewing this topic.

Offline Mauri

*
  •  327 327
    • View Profile
Real G93 Gcode anyone
« on: January 28, 2018, 05:01:24 PM »
Hi,
Does anyone have a Real G93 4 Axis Gcode output from a CAD/CAM program?
Regards,
Mauri.

Offline dude1

*
  •  1,253 1,253
    • View Profile
Re: Real G93 Gcode anyone
« Reply #1 on: January 28, 2018, 06:07:02 PM »
Here you go a fanuc one

Offline Mauri

*
  •  327 327
    • View Profile
Re: Real G93 Gcode anyone
« Reply #2 on: January 28, 2018, 06:17:06 PM »
Dude1,
Thank you.
Regards,
Mauri.

Offline Mauri

*
  •  327 327
    • View Profile
Re: Real G93 Gcode anyone
« Reply #3 on: January 30, 2018, 12:02:14 AM »
Question,
Why do CAM Posts that process G93 Code apply them to both Arc movement and Linear Movements?
These F Speeds become inaccurate when machining in Simultaneous mode (i.e.) not all are similar movements.
Why do they not just apply them to the Arc Movements since they are the ones with the incorrect F speed?
All it would mean is that the G-code would have G93 on for example on all Arc A Axis movements with its calculate F speed  and G94 on All X/Y/Z Linear movements with its user preset F Speed.
This would cover every type of multiple Axis shape and be able to do both normal and Simultaneous CNC machining with Accurate Fspeeds.
Can anyone shed any light on this?
Regards,
Mauri.
Re: Real G93 Gcode anyone
« Reply #4 on: January 30, 2018, 02:30:46 AM »
Hi Mauri,
I've never used G93. Found this video and it explained quite a bit:

https://www.ganotechnologies.com/cnc/rapidrotary/

The converter has the option of processing both the linear and rotary moves or just the rotary moves only, although I have no idea how that would work, in fact by my
reasoning it can't work.

My question is: what happens when you have a coordinated move which includes a linear and a rotary component?

The simplest I can think of is
G1 X50 A180,       my expectation would be that the X axis would drive 50mm while the A axis rotated 1/2 a turn. If the current feedrate is 180 and is conventionally
interpreted the move would take 1 minute.
If the feedrate were 4 and it were interpreted as inverse time mode then the move would take 15 secs (1/4 minute).

You ask why the G93 interpretation is applied to the linear component of the move.....how else can you interpret it? If you wish the rotary move to complete in 15 secs
then for the linear component to be coordinated it must also complete its move in 15 secs. The F word for the linear move would have to be 200mm/min whereas the
conventionally interpreted F word for the rotary component would be 1440 deg/min. The two F words don't match up. I argue therefore that if a move combines rotary and
linear components then both components must be treated the same way or the move will break, that is NOT be coordinated.

Where a move is solely linear or solely rotary then I could see that differing feed interpretations would work.
Imagine a move G1 X50 Y50 Z50 F86. I expect the controlled point to move 50mm in the X direction, 50mm in the Y direction and 50mm in the Z direction. The 3D distance
is 86mm and with a feedrate of 86mm/min the coordinated move would take 1 minute to complete, easy, normal interpretation.
The same move but inverse time mode would be G1 X50 Y50 Z50 F1. The move would still complete in 1 minute.
Quote
These F Speeds become inaccurate when machining in Simultaneous mode (i.e.) not all are similar movements.
I'm not sure how you come to this conclusion...this example suggests that the coordinated move completes in the same time with the same trajectory and
I see no inaccuracy in it.

Craig
My wife left with my best friend...
     and I miss him!

Offline Mauri

*
  •  327 327
    • View Profile
Re: Real G93 Gcode anyone
« Reply #5 on: January 30, 2018, 05:15:23 AM »
Craig,
my question is as to why the CAM G93 programmers decided to use the average method and not a precise one.
I have been working with this for a short time, but have done all the calculations and have found that none of the CAM G93 generating programs are accurate especially then all axis are one the same line.
If for example you use the program from the website but you have X/Y/Z on the same G-Code line, but have all the A Axis on a seperate line you will get a different answer, but closer to the correct one.
I am working with the writer of that program from the web you posted to come up with a better solution.
Just to let you know I posted the same website on another post.
I you use the program make sure that you keep the setting in Inch (with G-Code using inch or mm) as mm will produce an incorrect result.
The G93 is supposed the make all moves maintain the user set Fspeed, but when used on the same line with all the axis move it cannot do so.
The G93 formula for Linear is different to the Arc move and taking an average will only make it close if all moves move a similar distance.
Calculating each individually especially when the move differ proves this point mathematically.
The real importance of G93 is to ensure all surface speeds are the same.
So Fspeed X/Y/Z are user set under G94 but A is not a linear move under G94 so to make this A axis do the same as X/Y/Z then it must be converted to produce the same Fspeed using G93.
This then means since X/Y/Z allready moves at the correct Fspeed, all you need is to move the A axis the same way using G93.
The becomes more evidant with 4 Axis simultaneous of a statue for example that has many part offset for center.
Here are the formulaes for Linear and Arc moves converted to G93.
For linear
Let’s say
G1 X0.000 Z1.000 F400
G1 X0.100
Then
G93 F speed = 400/.1 = 4000 G93 Fspeed for that move.
 
For Angular
Let’s say
G1 X0.000 Z1.000 F400
G1 X0.100
G1 A5.000
Then
G93 F speed = 400/(2 x Pi() x Z1.000 x A5.000/360) = 400/(2 x 3.141592654 x 1 x 5/360 = 400/0.087266463 = 4583.662361 G93 Fspeed for that move.
This would apply for every A axis move.
Or a simpler method
G93 F speed = 400/ (Degree arc move in radians/Z) = 400/(0.087266463/1) = 4583.662361 G93 Fspeed for that move.

The program writer is reviewing his program on how to correct it amd make it better us the many examples I have sent him.
Will let you know what we come up with.
Regards,
Mauri.

Offline RICH

*
  • *
  •  7,419 7,419
    • View Profile
Re: Real G93 Gcode anyone
« Reply #6 on: January 30, 2018, 08:07:43 AM »
Good thread guys,

Never used the inverse time mode, so I spent time researching G93, unfortunately never finished doing it.
You won't find much info on G93 and you need to get into the math that is involved to get a good feel for what needs to be accomplished by the controller.
The statement that you start at some point and finish at some point all in a given time frame for axes involved
is ok for making something complex easy to grasp, BUT, what is truely involved to precisely machine something  using  complex motion say 3+2 is a different story.

RICH
Re: Real G93 Gcode anyone
« Reply #7 on: January 30, 2018, 09:53:31 AM »
Hi Mauri,
I think the difference here is between inverse time mode and constant surface speed.

in my example
G94
G1 X50 Y50 Z50 F86  completes in 1 minute with a cut speed of 1mm/sec

G93
G1 X50 Y50 Z50 F1    completes in 1 minute, same trajectory, same time to completion, therefore same cut speed ie 1mm/sec

This is straight inverse time mode and it works just fine. What you want is a rotary move subsequent to the linear move to have the same cut speed as the linear move:
G93
G1 X50 Y50 Z50 F1       cut speed=1mm/s
G1 A5 F=nnnnn

where nnnn is such that the cut speed is still 1mm/sec
The cut distance = (5/360)*PI*2*radius and radius is Z=50
      cut distance =4.363mm
      time to complete at a desired cut speed of 1mm/sec is 4.363 sec
      Fnnnn= 60/4.363 =13.75

This is a constant cut speed expressed as inverse time mode but requires the radius for the calculation to be made. The two are fundamentally different.

Craig
My wife left with my best friend...
     and I miss him!

Offline dude1

*
  •  1,253 1,253
    • View Profile
Re: Real G93 Gcode anyone
« Reply #8 on: January 30, 2018, 02:39:04 PM »
Code: [Select]
Just for fun heres the code for it.

[code// Start of multi-axis feedrate logic
/***** Be sure to add 'useInverseTime' to post properties if necessary. *****/
/***** 'inverseTimeOutput' must be defined. *****/
/***** 'headOffset' should be defined when a head rotary axis is defined. *****/
/***** The feedrate mode must be included in motion block output (linear, circular, etc. *****/
var dpmBPW = 0.1; // ratio of rotary accuracy to linear accuracy for DPM calculations
var inverseTimeUnits = 1.0; // 1.0 = minutes, 60.0 = seconds
var maxInverseTime = 9999; // maximum value to output for Inverse Time feeds

/** Calculate the multi-axis feedrate number. */
function getMultiaxisFeed(_x, _y, _z, _a, _b, _c, feed) {
  var f = {frn:0, fmode:0};
  if (feed <= 0) {
    error(localize("Feedrate is less than or equal to 0."));
    return f;
  }

  var length = getMoveLength(_x, _y, _z, _a, _b, _c);

  if (true) { // inverse time
    f.frn = inverseTimeOutput.format(getInverseTime(length[0], feed));
    f.fmode = 93;
    feedOutput.reset();
  } else { // degrees per minute
    f.frn = feedOutput.format(getFeedDPM(length, feed));
    f.fmode = 94;
  }
  return f;
}

/** Calculate the DPM feedrate number. */
function getFeedDPM(_moveLength, _feed) {
  // moveLength[0] = Tool tip, [1] = XYZ, [2] = ABC

  if (false) { // TCP mode is supported, output feed as FPM
    return feed;
  } else { // DPM feedrate calculation
    var moveTime = ((_moveLength[0] < 1.e-6) ? 0.001 : _moveLength[0]) / _feed;
    var length = Math.sqrt(Math.pow(_moveLength[1], 2.0) + Math.pow((toDeg(_moveLength[2]) * dpmBPW), 2.0));
    return length / moveTime;
  }
}

/** Calculate the Inverse time feedrate number. */
function getInverseTime(_length, _feed) {
  var inverseTime;
  if (_length < 1.e-6) { // tool doesn't move
    if (typeof maxInverseTime === "number") {
      inverseTime = maxInverseTime;
    } else {
      inverseTime = 999999;
    }
  } else {
    inverseTime = _feed / _length / inverseTimeUnits;
    if (typeof maxInverseTime === "number") {
      if (inverseTime > maxInverseTime) {
        inverseTime = maxInverseTime;
      }
    }
  }
  return inverseTime;
}

/** Calculate the distance of the tool position to the center of a rotary axis. */
function getRotaryRadius(center, direction, toolPosition) {
  var normal = direction.getNormalized();
  var d1 = toolPosition.x - center.x;
  var d2 = toolPosition.y - center.y;
  var d3 = toolPosition.z - center.z;
  var radius = Math.sqrt(
    Math.pow((d1 * normal.y) - (d2 * normal.x), 2.0) +
    Math.pow((d2 * normal.z) - (d3 * normal.y), 2.0) +
    Math.pow((d3 * normal.x) - (d1 * normal.z), 2.0)
   );
  return radius;
}

/** Calculate the linear distance based on the rotation of a rotary axis. */
function getRadialDistance(axis, startTool, endTool, startABC, endABC) {
  // rotary axis does not exist
  if (!axis.isEnabled()) {
    return 0.0;
  }

  // calculate the rotary center based on head/table
  var center;
  if (axis.isHead()) {
    var pivot;
    if (typeof headOffset === "number") {
      pivot = headOffset;
    } else {
      pivot = tool.getBodyLength();
    }
    center = Vector.sum(startTool, Vector.product(machineConfiguration.getSpindleAxis(), pivot));
    center = Vector.sum(center, axis.getOffset());
  } else {
    center = axis.getOffset();
  }

  // calculate the radius of the tool end point compared to the rotary center
  var startRadius = getRotaryRadius(center, axis.getEffectiveAxis(), startTool);
  var endRadius = getRotaryRadius(center, axis.getEffectiveAxis(), endTool);

  // calculate length of radial move
  var radius = Math.max(startRadius, endRadius);
  var delta = Math.abs(endABC.getCoordinate(axis.getCoordinate()) - startABC.getCoordinate(axis.getCoordinate()));
  if (delta > Math.PI) {
    delta = 2 * Math.PI - delta;
  }
  var radialLength = (2 * Math.PI * radius) * (delta / (2 * Math.PI));
  return radialLength;
}

/** Calculate tooltip, XYZ, and rotary move lengths. */
function getMoveLength(_x, _y, _z, _a, _b, _c) {
  // get starting and ending positions
  var moveLength = new Array();
  var startTool;
  var endTool;
  var startXYZ;
  var endXYZ;
  var startABC = getCurrentDirection();
  var endABC = new Vector(_a, _b, _c);
 
  if (currentSection.getOptimizedTCPMode() == 0) {
    startTool = getCurrentPosition();
    endTool = new Vector(_x, _y, _z);
    startXYZ = machineConfiguration.getOrientation(startABC).getTransposed().multiply(startTool);
    endXYZ = machineConfiguration.getOrientation(endABC).getTransposed().multiply(endTool);
  } else {
    startXYZ = getCurrentPosition();
    endXYZ = new Vector(_x, _y, _z);
    startTool = machineConfiguration.getOrientation(startABC).multiply(startXYZ);
    endTool = machineConfiguration.getOrientation(endABC).multiply(endXYZ);
  }

  // calculate the radial portion of the move
  var radialLength = Math.sqrt(
    Math.pow(getRadialDistance(machineConfiguration.getAxisU(), startTool, endTool, startABC, endABC), 2.0) +
    Math.pow(getRadialDistance(machineConfiguration.getAxisV(), startTool, endTool, startABC, endABC), 2.0) +
    Math.pow(getRadialDistance(machineConfiguration.getAxisW(), startTool, endTool, startABC, endABC), 2.0)
  );

  // calculate the lengths of move
  // tool tip distance is the move distance based on a combination of linear and rotary axes movement
  var linearLength = Vector.diff(endXYZ, startXYZ).length;
  moveLength[0] = linearLength + radialLength;
  moveLength[1] = Vector.diff(endXYZ, startXYZ).length;
  moveLength[2] = 0;
  for (var i = 0; i < 3; ++i) {
    var delta = Math.abs(endABC[i] - startABC[i]);
    if (delta > Math.PI) {
      delta = 2 * Math.PI - delta;
    }
    moveLength[2] += Math.pow(delta, 2.0);
  }
  moveLength[2] = Math.sqrt(moveLength[2]);
  return moveLength;
}
// End of multi-axis feedrate logic]

Offline Mauri

*
  •  327 327
    • View Profile
Re: Real G93 Gcode anyone
« Reply #9 on: January 30, 2018, 03:13:45 PM »
Dude1,
Thank you for the code.
What program language is it for?

Below are two examples.
The both produce a Step Circle on a Rotary Axis.
CircleStepTest1/2
Have X/Z/A on the same line
CircleStepTestx
Has A on a separate Line.
The G93 is the result.
I will send the rest on the next post reply.
Regards,
Mauri.