Friday 15 October 2021

G28 vs G53 and LinuxCNC lathe vs Fusion 360?!

The bloody Fusion 360 post processor is posting U and W moves instead of X and Z when asking for G28 retracts between tool changes / at the end of the program. Like this:

 %
(1200)
(M8 ROUGH AND THREAD)
N10 G7
N20 G18
N30 G90
N40 G21
N50 G28 U0.

(PROFILE ROUGHING1)
N60 T4 M6
N80 G54
N90 M8
N100 G97 S1947 M3
N110 G95
N120 G90 G0 X32.7 Z0.
N130 G96 D2000 S200 M3
N140 G0 Z0.25
N150 X11.7
N160 G1 Z-17.4 F0.1
..... etc

N460 G97 S1947 M3
N470 M9
N480 G28 U0.

(THREAD1)
N490 M5
N500 M1
N510 T6 M6
.... etc

N800 G33 Z-14. K1.25
N810 X7.866 Z-15. K1.768
N820 G0 X18.7
N830 Z0.

N840 M9
N850 M5
N860 G28 U0.
N870 M30
%

This isn't recognised as legal tender by LinuxCNC which won't run the file. It seems the Fusion team have fucked up the post processor. If LinuxCNC sees a reference to a U or W move, it assumes this refers to a rotational axis, whereas the Fusion team expect it be to seen as a relative move in X or Z, as used by some machines (not LinuxCNC though).

Alkabal raised this on the Fusion forum and Andy Pugh also piled in. Alkabal also posted on the LinuxCNC forum at the same time. I'd also previously posted about this myself not long before.

Looking at the post processor code, it looks pretty messy and, for the sake of avoiding this relatively simple issue, I can't be arsed to edit my post, as the content is sprayed all over this lump of Javascript:

/** Output block to do safe retract and/or move to home position. */
var XZ = 4;
function writeRetract() {
  var words = []; // store all retracted axes in an array
  var singleLineRetract = false;
  var retractAxes = []; // axes to retract
  var method = getProperty("safePositionMethod");
  // define home positions
  var _xHome;
  var _yHome;
  var _zHome;
  if (method == "G28") {
    _xHome = toPreciseUnit(0, MM);
    _yHome = toPreciseUnit(0, MM);
    _zHome = toPreciseUnit(0, MM);
  } else {
    _xHome = machineConfiguration.hasHomePositionX() ? machineConfiguration.getHomePositionX() : getProperty("g53HomePositionX");
    _yHome = machineConfiguration.hasHomePositionY() ? machineConfiguration.getHomePositionY() : toPreciseUnit(0, MM);
    _zHome = machineConfiguration.getRetractPlane() != 0 ? machineConfiguration.getRetractPlane() : getProperty("g53HomePositionZ");
  }
  if (arguments.length > 0) {
    for (var i in arguments) {
      retractAxes.push(arguments[i]);
      singleLineRetract = arguments[i] == XZ ? true : singleLineRetract;
    }
  } else {
    switch (getProperty("safePositionStyle")) {
    case "X":
      retractAxes.push(X);
      break;
    case "Z":
      retractAxes.push(Z);
      break;
    case "XZ":
      retractAxes.push(X, Z);
      break;
    case "ZX":
      retractAxes.push(Z, X);
      break;
    case "singleLineXZ":
      singleLineRetract = true;
      retractAxes.push(X, Z);
      break;
    }
  }
  // format home positions
  for (var i = 0; i < retractAxes.length; ++i) {
    switch (retractAxes[i]) {
    case X:
      words.push((method == "G28" ? "U" : "X") + xFormat.format(_xHome));
      retracted[X] = true;
      xOutput.reset();
      break;
    case Y:
      if (yOutput.isEnabled()) {
        words.push((method == "G28" ? "V" : "Y") + yFormat.format(_yHome));
        yOutput.reset();
      }
      break;
    case Z:
      words.push((method == "G28" ? "W" : "Z") + zFormat.format(_zHome));
      retracted[Z] = true;
      zOutput.reset();
      break;
    case XZ:
      words.push((method == "G28" ? "U" : "X") + xFormat.format(_xHome));
      words.push((method == "G28" ? "W" : "Z") + zFormat.format(_zHome));
      retracted[X] = true;
      retracted[Z] = true;
      xOutput.reset();
      zOutput.reset();
      break;
    default:
      error(localize("Unsupported axis specified for writeRetract()."));
      return;
    }
  }
  for (var i = 0; i < words.length; ++i) {
    switch (method) {
    case "G28":
      writeBlock(gFormat.format(28), singleLineRetract ? words : words[i]);
      break;
    case "G53":
      gMotionModal.reset();
      writeBlock(gFormat.format(53), gMotionModal.format(0), singleLineRetract ? words : words[i]);
      break;
    default:
      error(localize("Unsupported safe position method."));
      return;
    }
    if (singleLineRetract) {
      break;
    }
  }
  singleLineRetract = false; // singleLineRetract reset
}
function onClose() {
  writeln("");
  optionalSection = false;
  onCommand(COMMAND_COOLANT_OFF);
  onCommand(COMMAND_STOP_SPINDLE);
  // we might want to retract in Z before X
  // writeBlock(gFormat.format(30), "Z#5422"); // retract/park
  forceXYZ();
  writeRetract();// change this to writeRetract(XZ) to force retract in XZ at the end of the program as a default
  onImpliedCommand(COMMAND_END);
  onImpliedCommand(COMMAND_STOP_SPINDLE);
  writeBlock(mFormat.format(30)); // stop program, spindle stop, coolant off
  writeln("%");
}

The answer is quite simple:

  1. Don't select G28
  2. If you want to retract in X (retract the cross slide), choose the "G53 / X only" option in the post processor
  3. If you want to also retract in Z (retract toward the tailstock end), choose the "G53 X and Y" option.

If it weren't for this fuckup, you'd define the required G28 position by positioning the tool where you want the G28 to end up and issue a G28.1 command in MDI. This saves the current coords as system variables 5161 (for X) and 5163 (for Z). Next time you issue G28, it will retract to those coords. But I won't be needing that...



No comments:

Post a Comment

Final assembly and test of the spindle nose adaptor - RESULT!!

After the recent distraction caused by the 3D scanner, resurrecting the 3D printer and buggering about with the throttle bodies for my Honda...