/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package tgfx.system; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleDoubleProperty; import org.apache.log4j.Logger; import org.json.JSONException; import org.json.JSONObject; import tgfx.Main; import tgfx.tinyg.MnemonicManager; import tgfx.tinyg.TinygDriver; import tgfx.tinyg.responseCommand; /** * [xmp] x_machine_position 0.000 mm [xwp] x_work_position 0.000 mm [xam] * x_axis_mode 1 [standard] [xfr] x_feedrate_maximum 2400.000 mm/min [xvm] * x_velocity_maximum 2400.000 mm/min [xtm] x_travel_maximum 400.000 mm [xjm] * x_jerk_maximum 100000000 mm/min^3 [xjd] x_junction_deviation 0.0500 mm [xsm] * x_switch_mode 1 [0,1] [xht] x_homing_travel 400.000 mm [xhs] * x_homing_search_velocity 2400.000 mm/min [xhl] x_homing_latch_velocity * 100.000 mm/min [xhz] x_homing_zero_offset 5.000 mm [xhw] x_homing_work_offset * 200.000 mm * */ public final class Axis { public enum AXIS_TYPE { LINEAR, ROTATIONAL; } static final Logger logger = Logger.getLogger(TinygDriver.class); private String CURRENT_AXIS_JSON_OBJECT; private AXIS_TYPE axis_type; private SimpleBooleanProperty homed = new SimpleBooleanProperty(false); private float latch_velocity; // private float seek_rate_maximum; private double latch_backoff; private double zero_backoff; private double machine_position; private SimpleDoubleProperty workPosition = new SimpleDoubleProperty(); //This has to be public if we are going to allow it to be updated. private SimpleDoubleProperty machinePosition = new SimpleDoubleProperty(); //This has to be public if we are going to allow it to be updated. private AXIS_MODES axis_mode; private double radius; private double searchVelocity; private double feedRateMaximum; private double velocityMaximum; private SimpleDoubleProperty travel_maximum = new SimpleDoubleProperty(); private SimpleDoubleProperty offset = new SimpleDoubleProperty(); private double jerkMaximum; private double jerkHomingMaximum; private double junction_devation; private SWITCH_MODES max_switch_mode = SWITCH_MODES.DISABLED; private SWITCH_MODES min_switch_mode = SWITCH_MODES.DISABLED; private List allAxis = new ArrayList(); DecimalFormat decimalFormat = new DecimalFormat("#.000"); DecimalFormat decimalFormatjunctionDeviation = new DecimalFormat("0.000000"); DecimalFormat decimalFormatMaximumJerk = new DecimalFormat("################################.############################"); // private float homing_travel; // private float homing_search_velocity; // private float homing_latch_velocity; // private float homing_zero_offset; // private float homing_work_offset; private String axis_name; private List<Motor> motors = new ArrayList<>(); public enum SWITCH_MODES { DISABLED, HOMING_ONLY, LIMIT_ONLY, HOMING_AND_LIMIT, } public String getCURRENT_AXIS_JSON_OBJECT() { return CURRENT_AXIS_JSON_OBJECT; } public void setCURRENT_AXIS_JSON_OBJECT(String CURRENT_AXIS_JSON_OBJECT) { this.CURRENT_AXIS_JSON_OBJECT = CURRENT_AXIS_JSON_OBJECT; } public enum AXIS_MODES { DISABLE, STANDARD, INHIBITED, RADIUS, SLAVE_X, SLAVE_Y, SLAVE_Z, SLAVE_XY, SLAVE_XZ, SLAVE_YZ, SLAVE_XYZ } public enum AXIS { X, Y, Z, A, B, C } // public Axis() { // axis_mode = AXIS_MODES.STANDARD; //// latch_velocity = 0; //// latch_backoff = 0; //// machine_position = 0; //// feed_rate_maximum = 800; //// jerk_maximum = 0; // // } public void setHomed(boolean choice) { homed.set(choice); } public void setAxisCommand(String cmd, String value) { //This is a blind commmand mode... meaning that //if 2 strings (key, val) are passed to the axis class //Then we parse the command and set the value. switch (cmd) { case "am": { int val = Double.valueOf(value.substring(0)).intValue(); //Ugh this was a pain to figure out. String _axisMode = "UNKNOWN"; switch (val) { case 0: { _axisMode = "DISABLED"; break; } case 1: { _axisMode = "STANDARD"; break; } case 2: { _axisMode = "INHIBITED"; break; } case 3: { _axisMode = "RADIUS"; break; } case 4: { _axisMode = "SLAVE_X"; break; } case 5: { _axisMode = "SLAVE_Y"; break; } case 6: { _axisMode = "SLAVE_Z"; break; } case 7: { _axisMode = "SLAVE_XY"; break; } case 8: { _axisMode = "SLAVE_XZ"; break; } case 9: { _axisMode = "SLAVE_YZ"; break; } case 10: { _axisMode = "SLAVE_XYZ"; break; } default: { _axisMode = "DISABLED"; return; } } this.setAxis_mode(val); Main.print("\t[+]Set Axis: " + this.getAxis_name() + " Axis Mode to: " + _axisMode); return; } case "vm": { int val = (int) Double.parseDouble(value); this.setVelocityMaximum(val); Main.print("\t[+]Set Axis: " + this.getAxis_name() + " Velocity Max to: " + this.getVelocityMaximum()); return; } case "fr": { int val = (int) Double.parseDouble(value); this.setFeed_rate_maximum(val); Main.print("\t[+]Set Axis: " + this.getFeed_rate_maximum() + " Feed Rate Max to: " + this.getFeed_rate_maximum()); return; } case "tm": { int val = (int) Double.parseDouble(value); this.setTravel_maximum(val); Main.print("\t[+]Set Axis: " + this.getAxis_name() + " Travel Max to: " + this.getTravel_maximum()); return; } case "jm": { int val = (int) Double.parseDouble(value); this.setJerkMaximum(val); Main.print("\t[+]Set Axis: " + this.getJerkMaximum() + " Jerk Max to: " + this.getJerkMaximum()); return; } case "jd": { int val = (int) Double.parseDouble(value); this.setJunctionDevation(val); Main.print("\t[+]Set Axis: " + this.getJunction_devation() + " Junction Deviation Max to: " + this.getJunction_devation()); return; } case "sx": { int val = Double.valueOf(value.substring(0)).intValue(); String _switchMode = "UNKNOWN"; switch (val) { case 0: { _switchMode = "DISABLED"; break; } case 1: { _switchMode = "HOMING ONLY"; break; } case 2: { _switchMode = "HOMING AND LIMIT"; break; } } this.setMaxSwitchMode(val); Main.print("\t[+]Set Axis: " + this.getAxis_name() + " Axis Mode to: " + _switchMode); return; } case "sn": { int val = Double.valueOf(value.substring(0)).intValue(); String _switchMode = "UNKNOWN"; switch (val) { case 0: { _switchMode = "DISABLED"; break; } case 1: { _switchMode = "HOMING ONLY"; break; } case 2: { _switchMode = "HOMING AND LIMIT"; break; } } this.setMaxSwitchMode(val); Main.print("\t[+]Set Axis: " + this.getAxis_name() + " Axis Mode to: " + _switchMode); return; } case "sv": { int val = (int) Double.parseDouble(value); this.setSearch_velocity(val); Main.print("\t[+]Set Axis: " + this.getAxis_name() + " Search Velocity to: " + this.getSearch_velocity()); return; } case "lv": { int val = (int) Double.parseDouble(value); this.setLatch_velocity(val); Main.print("\t[+]Set Axis: " + this.getAxis_name() + " Latch Velocity to: " + this.getLatch_velocity()); return; } case "lb": { int val = (int) Double.parseDouble(value); this.setLatch_backoff(val); Main.print("\t[+]Set Axis: " + this.getAxis_name() + " Latch Back Off to: " + this.getLatch_backoff()); return; } case "zb": { int val = (int) Double.parseDouble(value); this.setZero_backoff(val); Main.print("\t[+]Set Axis: " + this.getAxis_name() + " Zero Back Off to: " + this.getZero_backoff()); return; } case "ra": { int val = (int) Double.parseDouble(value); this.setRadius(val); Main.print("\t[+]Set Axis: " + this.getAxis_name() + " Radius to: " + this.getRadius()); return; } default: { Main.print("[!]Error... No such setting: " + value + " in Axis Settings..."); } } } public double getLatch_backoff() { return formatDoubleValue(latch_backoff); } public double getRadius() { return formatDoubleValue(radius); } // public void setRadius(int radius) { // this.radius = radius; // } public boolean setLatch_backoff(float latch_backoff) { this.latch_backoff = latch_backoff; return true; } public float getLatch_velocity() { return formatFloatValue(latch_velocity); } // public float getSeek_rate_maximum() { // return seek_rate_maximum; // } // // public void setSeek_rate_maximum(float seek_rate_maximum) { // this.seek_rate_maximum = seek_rate_maximum; // } public double getSearch_velocity() { return formatDoubleValue(searchVelocity); } public boolean setSearch_velocity(double search_velocity) { this.searchVelocity = search_velocity; return true; } public boolean setLatch_velocity(float latch_velocity) { this.latch_velocity = latch_velocity; return true; } public double getZero_backoff() { return formatDoubleValue(zero_backoff); } public boolean setZero_backoff(float zero_backoff) { this.zero_backoff = zero_backoff; return true; } public void setRadius(double r) { this.radius = r; } public void setAxisType(AXIS_TYPE at) { this.axis_type = at; } public AXIS_TYPE getAxisType() { return (this.axis_type); } public Axis(AXIS ax, AXIS_TYPE at, AXIS_MODES am) { this.axis_mode = am; if (ax == AXIS.X) { this.setAxis_name("X"); this.setAxisType(at); } else if (ax == AXIS.Y) { this.setAxis_name("Y"); this.setAxisType(at); } else if (ax == AXIS.Z) { this.setAxis_name("Z"); this.setAxisType(at); } else if (ax == AXIS.A) { this.setAxis_name("A"); this.setAxisType(at); } else if (ax == AXIS.B) { this.setAxis_name("B"); this.setAxisType(at); } else if (ax == AXIS.C) { this.setAxis_name("C"); this.setAxisType(at); } else { Main.print("[!]Invalide Axis Name Specified.\n"); } } public AXIS_MODES getAxis_mode() { return axis_mode; } // public boolean setMotorCommand(String cmd, String value) { // //Generic command parser when a single axis command has been given. // //IE: $xsr=1200 // //cmd would be sr and value would be 1200 // switch (cmd) { // case MnemonicManager.MNEMONIC_AXIS_AXIS_MODE: { // int val = (int) Double.parseDouble(value); // return (this.setAxis_mode(val)); // } // case MnemonicManager.MNEMONIC_AXIS_VELOCITY_MAXIMUM: // return (this.setVelocityMaximum(Float.valueOf(value))); // case MnemonicManager.MNEMONIC_AXIS_FEEDRATE_MAXIMUM: // return (this.setFeed_rate_maximum(Float.valueOf(value))); // case MnemonicManager.MNEMONIC_AXIS_TRAVEL_MAXIMUM: // return (this.setTravel_maximum(Float.valueOf(value))); // case MnemonicManager.MNEMONIC_AXIS_JERK_MAXIMUM: // return (this.setJerkMaximum(Double.valueOf(value))); // case MnemonicManager.MNEMONIC_AXIS_JUNCTION_DEVIATION: // return (this.setJunctionDevation(Float.valueOf(value))); // case "sn": { // int val = (int) Double.parseDouble(value); // return (this.setMaxSwitchMode(val)); // } // case MnemonicManager.MNEMONIC_AXIS_SEARCH_VELOCITY: // return (this.setSearch_velocity(Double.parseDouble(value))); // case MnemonicManager.MNEMONIC_AXIS_LATCH_VELOCITY: // return (this.setLatch_velocity(Float.parseFloat(value))); // case MnemonicManager.MNEMONIC_AXIS_LATCH_BACKOFF: // return (this.setLatch_backoff(Float.parseFloat(value))); // case MnemonicManager.MNEMONIC_AXIS_ZERO_BACKOFF: // return (this.setZero_backoff(Float.parseFloat(value))); // default: // return false; // } // } public boolean setAxis_mode(int axMode) { switch (axMode) { case 0: this.axis_mode = AXIS_MODES.DISABLE; return true; case 1: this.axis_mode = AXIS_MODES.STANDARD; return true; case 2: this.axis_mode = AXIS_MODES.INHIBITED; return true; case 3: this.axis_mode = AXIS_MODES.RADIUS; return true; case 4: this.axis_mode = AXIS_MODES.SLAVE_X; return true; case 5: this.axis_mode = AXIS_MODES.SLAVE_Y; return true; case 6: this.axis_mode = AXIS_MODES.SLAVE_Z; return true; case 7: this.axis_mode = AXIS_MODES.SLAVE_XY; return true; case 8: this.axis_mode = AXIS_MODES.SLAVE_XZ; return true; case 9: this.axis_mode = AXIS_MODES.SLAVE_YZ; return true; case 10: this.axis_mode = AXIS_MODES.SLAVE_XYZ; return true; default: return false; } // if (axMode == 0) { // this.axis_mode =AXIS_MODES.DISABLE; // }else if( axMode == 1){ // this.axis_mode = AXIS_MODES. // } } public String getAxis_name() { return axis_name; } public void setAxis_name(String axis_name) { this.axis_name = axis_name; } public double getFeed_rate_maximum() { return formatDoubleValue(feedRateMaximum); } public boolean setFeed_rate_maximum(float feed_rate_maximum) { this.feedRateMaximum = feed_rate_maximum; return true; } public double getJerkHomingMaximum() { return jerkHomingMaximum; } public void setJerkHomingMaximum(double jerkHomingMaximum) { this.jerkHomingMaximum = jerkHomingMaximum; } public double getJerkMaximum() { return (jerkMaximum); } public boolean setJerkMaximum(double jerk_maximum) { this.jerkMaximum = jerk_maximum; return true; } public double getJunction_devation() { return formatJuctionDeviation(junction_devation); } public boolean setJunctionDevation(float junction_devation) { this.junction_devation = junction_devation; return true; } public double getMachinePosition() { return machine_position; } public boolean setMachinePosition(float machine_position) { this.machine_position = machine_position; return true; } public SimpleDoubleProperty getOffset() { return offset; } public void setOffset(double offset) { this.offset.set(offset); } public List<Motor> getMotors() { return motors; } public boolean addMotor(Motor motor) { if (!motors.contains(motor)) { motors.add(motor); return true; } return false; } public void setMotors(List<Motor> motors) { this.motors = motors; } public SWITCH_MODES getMaxSwitchMode() { return max_switch_mode; } public SWITCH_MODES getMinSwitchMode() { return min_switch_mode; } public Boolean setMaxSwitchMode(int _sw_mode) { switch (_sw_mode) { case 0: max_switch_mode = SWITCH_MODES.DISABLED; return true; case 1: max_switch_mode = SWITCH_MODES.HOMING_ONLY; return true; case 2: max_switch_mode = SWITCH_MODES.LIMIT_ONLY; return true; case 3: max_switch_mode = SWITCH_MODES.HOMING_AND_LIMIT; return true; } return false; } public Boolean setMinSwitch_mode(int _sw_mode) { switch (_sw_mode) { case 0: min_switch_mode = SWITCH_MODES.DISABLED; return true; case 1: min_switch_mode = SWITCH_MODES.HOMING_ONLY; return true; case 2: min_switch_mode = SWITCH_MODES.LIMIT_ONLY; return true; case 3: min_switch_mode = SWITCH_MODES.HOMING_AND_LIMIT; return true; } return false; } public SimpleDoubleProperty getTravelMaxSimple() { return (travel_maximum); } private double formatDoubleValue(double val) { //Utility Method to cleanly trim doubles for display in the UI return (Double.parseDouble(decimalFormat.format(val))); } private double formatJuctionDeviation(double val) { //Utility Method to cleanly trim doubles for display in the UI return (Double.parseDouble(decimalFormatjunctionDeviation.format(val))); } private double formatJerkMaximum(double val) { //Utility Method to cleanly trim doubles for display in the UI return (Double.parseDouble(decimalFormat.format(val))); } private float formatFloatValue(float val) { //Utility Method to cleanly trim doubles for display in the UI return (Float.parseFloat(decimalFormat.format(val))); } public double getTravel_maximum() { return formatDoubleValue(travel_maximum.getValue()); } public boolean setTravel_maximum(float travel_maximum) { try { //Stub to always track the largest travel axis allAxis = TinygDriver.getInstance().machine.getAllLinearAxis(); Iterator<Axis> iterator = allAxis.iterator(); double _maxTravel = 0; Axis _ax; while (iterator.hasNext()) { _ax = (Axis) iterator.next(); if (_ax.getTravel_maximum() > _maxTravel) { //This is the largest travel max so far.. lets set it. _maxTravel = _ax.getTravel_maximum(); } TinygDriver.getInstance().machine.longestTravelAxisValue.set(_maxTravel); //We set this binding now to the largest value } this.travel_maximum.set(travel_maximum); return true; } catch (Exception ex) { //supress this error return false; } } public double getVelocityMaximum() { return formatDoubleValue(velocityMaximum); } public boolean setVelocityMaximum(double velocity_maximum) { this.velocityMaximum = velocity_maximum; return true; } public SimpleDoubleProperty getWorkPosition() { return workPosition; } public void setWorkPosition(double workpos) { this.workPosition.set(workpos); } public void setMachinePosition(double workpos) { this.machinePosition.set(workpos); } public SimpleDoubleProperty getMachinePositionSimple() { return machinePosition; } public void applyJsonSystemSetting(responseCommand rc) { _applyJsonSystemSetting(rc); } //This is the main method to parser a JSON Axis object public void applyJsonSystemSetting(JSONObject js, String parent) { logger.info("Applying JSON Object to " + parent + " Group"); Iterator ii = js.keySet().iterator(); try { while (ii.hasNext()) { String _key = ii.next().toString(); String _val = js.get(_key).toString(); responseCommand rc = new responseCommand(parent, _key, _val); _applyJsonSystemSetting(rc); } } catch (JSONException | NumberFormatException ex) { logger.error("Error in applyJsonSystemSetting in Axis"); } } private void _applyJsonSystemSetting(responseCommand rc) { switch (rc.getSettingKey()) { case (MnemonicManager.MNEMONIC_AXIS_AXIS_MODE): TinygDriver.getInstance().machine.getAxisByName(rc.getSettingParent()).setAxis_mode(Double.valueOf(rc.getSettingValue()).intValue()); logger.info("[APPLIED:" + rc.getSettingParent() + " " + rc.getSettingKey() + ":" + rc.getSettingValue()); break; case (MnemonicManager.MNEMONIC_AXIS_FEEDRATE_MAXIMUM): TinygDriver.getInstance().machine.getAxisByName(rc.getSettingParent()).setFeed_rate_maximum(Float.valueOf(rc.getSettingValue())); logger.info("[APPLIED:" + rc.getSettingParent() + " " + rc.getSettingKey() + ":" + rc.getSettingValue()); break; case (MnemonicManager.MNEMONIC_AXIS_JERK_MAXIMUM): TinygDriver.getInstance().machine.getAxisByName(rc.getSettingParent()).setJerkMaximum(Float.valueOf(rc.getSettingValue())); logger.info("[APPLIED:" + rc.getSettingParent() + " " + rc.getSettingKey() + ":" + rc.getSettingValue()); break; case (MnemonicManager.MNEMONIC_AXIS_JUNCTION_DEVIATION): TinygDriver.getInstance().machine.getAxisByName(rc.getSettingParent()).setJunctionDevation(Float.valueOf(rc.getSettingValue())); logger.info("[APPLIED:" + rc.getSettingParent() + " " + rc.getSettingKey() + ":" + rc.getSettingValue()); break; case (MnemonicManager.MNEMONIC_AXIS_LATCH_BACKOFF): TinygDriver.getInstance().machine.getAxisByName(rc.getSettingParent()).setLatch_backoff(Float.valueOf(rc.getSettingValue())); logger.info("[APPLIED:" + rc.getSettingParent() + " " + rc.getSettingKey() + ":" + rc.getSettingValue()); break; case (MnemonicManager.MNEMONIC_AXIS_LATCH_VELOCITY): TinygDriver.getInstance().machine.getAxisByName(rc.getSettingParent()).setLatch_velocity(Float.valueOf(rc.getSettingValue())); logger.info("[APPLIED:" + rc.getSettingParent() + " " + rc.getSettingKey() + ":" + rc.getSettingValue()); break; case (MnemonicManager.MNEMONIC_AXIS_MAX_SWITCH_MODE): TinygDriver.getInstance().machine.getAxisByName(rc.getSettingParent()).setMaxSwitchMode(Integer.valueOf(rc.getSettingValue())); logger.info("[APPLIED:" + rc.getSettingParent() + " " + rc.getSettingKey() + ":" + rc.getSettingValue()); break; case (MnemonicManager.MNEMONIC_AXIS_MIN_SWITCH_MODE): TinygDriver.getInstance().machine.getAxisByName(rc.getSettingParent()).setMinSwitch_mode(Integer.valueOf(rc.getSettingValue())); logger.info("[APPLIED:" + rc.getSettingParent() + " " + rc.getSettingKey() + ":" + rc.getSettingValue()); break; case (MnemonicManager.MNEMONIC_AXIS_RADIUS): TinygDriver.getInstance().machine.getAxisByName(rc.getSettingParent()).setRadius(Float.valueOf(rc.getSettingValue())); logger.info("[APPLIED:" + rc.getSettingParent() + " " + rc.getSettingKey() + ":" + rc.getSettingValue()); break; case (MnemonicManager.MNEMONIC_AXIS_SEARCH_VELOCITY): TinygDriver.getInstance().machine.getAxisByName(rc.getSettingParent()).setSearch_velocity(Float.valueOf(rc.getSettingValue())); logger.info("[APPLIED:" + rc.getSettingParent() + " " + rc.getSettingKey() + ":" + rc.getSettingValue()); break; case (MnemonicManager.MNEMONIC_AXIS_TRAVEL_MAXIMUM): TinygDriver.getInstance().machine.getAxisByName(rc.getSettingParent()).setTravel_maximum(Float.valueOf(rc.getSettingValue())); logger.info("[APPLIED:" + rc.getSettingParent() + " " + rc.getSettingKey() + ":" + rc.getSettingValue()); break; case (MnemonicManager.MNEMONIC_AXIS_VELOCITY_MAXIMUM): TinygDriver.getInstance().machine.getAxisByName(rc.getSettingParent()).setVelocityMaximum(Float.valueOf(rc.getSettingValue())); logger.info("[APPLIED:" + rc.getSettingParent() + " " + rc.getSettingKey() + ":" + rc.getSettingValue()); break; case (MnemonicManager.MNEMONIC_AXIS_ZERO_BACKOFF): TinygDriver.getInstance().machine.getAxisByName(rc.getSettingParent()).setZero_backoff(Float.valueOf(rc.getSettingValue())); logger.info("[APPLIED:" + rc.getSettingParent() + " " + rc.getSettingKey() + ":" + rc.getSettingValue()); break; default: logger.info("Default Switch"); } } }