Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
package com.marginallyclever.makelangelo.plotter.plottersettings;
import com.marginallyclever.makelangelo.apps.previewpanel.plotterrenderer.PlotterRendererFactory;
import com.marginallyclever.util.PreferencesHelper;
import org.json.JSONObject;
import javax.vecmath.Point2d;
import java.awt.*;
import java.util.Arrays;
import java.util.prefs.Preferences;
/**
* {@link PlotterSettings} stores the physical settings for a single {@link com.marginallyclever.makelangelo.plotter.Plotter}.
* Not to be confused with the dynamic state of a {@link com.marginallyclever.makelangelo.plotter.Plotter}.
* @author Dan Royer
*/
public class PlotterSettings {
public static final String ANCESTOR = "ancestor";
/**
* mm/s/s
*/
public static final String MAX_ACCELERATION = "acceleration";
/**
* int
*/
public static final String BLOCK_BUFFER_SIZE = "blockBufferSize";
/**
* double
*/
public static final String DIAMETER = "diameter";
/**
* double
*/
public static final String FEED_RATE_TRAVEL = "feed_rate";
/**
* double
*/
public static final String FEED_RATE_DRAW = "feed_rate_current";
/**
* boolean
*/
public static final String HANDLE_SMALL_SEGMENTS = "handleSmallSegments";
/**
* boolean. if we wanted to test for Marginally Clever brand Makelangelo robots
*/
public static final String IS_REGISTERED = "isRegistered";
/**
* double
*/
public static final String LIMIT_BOTTOM = "limit_bottom";
/**
* double
*/
public static final String LIMIT_LEFT = "limit_left";
/**
* double
*/
public static final String LIMIT_RIGHT = "limit_right";
/**
* double
*/
public static final String LIMIT_TOP = "limit_top";
/**
* array of doubles
*/
public static final String MAX_JERK = "maxJerk";
/**
* double
*/
public static final String MINIMUM_PLANNER_SPEED = "minimumPlannerSpeed";
/**
* double
*/
public static final String MIN_ACCELERATION = "minAcceleration";
/**
* double
*/
public static final String MIN_SEGMENT_LENGTH = "minSegmentLength";
public static final String MIN_SEG_TIME = "minSegTime";
/**
* color
*/
public static final String PAPER_COLOR = "paperColor";
/**
* color
*/
public static final String PEN_DOWN_COLOR = "penDownColor";
/**
* color
*/
public static final String PEN_DOWN_COLOR_DEFAULT = "penDownColorDefault";
/**
* color
*/
public static final String PEN_UP_COLOR = "penUpColor";
/**
* integer
*/
public static final String SEGMENTS_PER_SECOND = "segmentsPerSecond";
/**
* integer.
* <pre>
* {
* @code
* private String[] startingStrings = { "Top Left", "Top Center", "Top Right", "Left", "Center", "Right",
* "Bottom Left", "Bottom Center", "Bottom Right" };
* }
* </pre>
*/
public static final String STARTING_POS_INDEX = "startingPosIndex";
/**
* double
*/
public static final String PEN_ANGLE_UP = "z_off";
/**
* double
*/
public static final String PEN_ANGLE_DOWN = "z_on";
/**
* double.
* The milliseconds delay to raise the pen. Marlin firmware will send intermediate values to the servo
* to approximate the slow movement, but it may cause the servo to jitter. Use with care.
*/
public static final String PEN_ANGLE_UP_TIME = "z_rate_up";
/**
* double.
* The milliseconds delay to lower the pen. Marlin firmware will send intermediate values to the servo
* to approximate the slow movement, but it may cause the servo to jitter. Use with care.
*/
public static final String PEN_ANGLE_DOWN_TIME = "z_rate";
/**
* String
*/
public static final String USER_GENERAL_END_GCODE = "userGeneralEndGcode";
/**
* String
*/
public static final String USER_GENERAL_START_GCODE = "userGeneralStartGcode";
/**
* integer
*/
public static final String Z_MOTOR_TYPE = "zMotorType";
/**
* String
*/
public static final String STYLE = "style";
public static final int Z_MOTOR_TYPE_SERVO = 1;
public static final int Z_MOTOR_TYPE_STEPPER = 2;
private final JSONObject json = new JSONObject();
private String robotUID = "0";
public PlotterSettings() {
super();
setDefaults();
}
private void setDefaults() {
json.put(IS_REGISTERED, false);
json.put(HANDLE_SMALL_SEGMENTS, false);
json.put(MIN_SEGMENT_LENGTH, 0.5); // mm
json.put(MAX_ACCELERATION, 100); // mm/s/s
json.put(MIN_ACCELERATION, 0.0); // mm/s/s
json.put(MINIMUM_PLANNER_SPEED, 0.05); // mm/s
json.put(LIMIT_LEFT, -325); // mm
json.put(LIMIT_RIGHT, 325); // mm
json.put(LIMIT_BOTTOM, -500); // mm
json.put(LIMIT_TOP, 500); // mm
json.put(DIAMETER, 0.8); // mm, >0
json.put(PEN_ANGLE_UP, 90); // servo angle (degrees,0...180)
json.put(PEN_ANGLE_DOWN, 25); // servo angle (degrees,0...180)
json.put(PEN_ANGLE_UP_TIME, 250);
json.put(PEN_ANGLE_DOWN_TIME, 150);
json.put(FEED_RATE_TRAVEL, 3000); // mm/min. 3000 = 50 mm/s
json.put(FEED_RATE_DRAW, 3000); // mm/min. 3000 = 50 mm/s
json.put(BLOCK_BUFFER_SIZE, 16);
json.put(SEGMENTS_PER_SECOND, 5);
json.put(MIN_SEG_TIME, 20000); // us
json.put(STARTING_POS_INDEX, 4);
json.put(Z_MOTOR_TYPE, PlotterSettings.Z_MOTOR_TYPE_SERVO);
json.put(ANCESTOR, "");
json.put(USER_GENERAL_START_GCODE, "");
json.put(USER_GENERAL_END_GCODE, "");
json.put(STYLE, PlotterRendererFactory.MAKELANGELO_5.getName());
json.put(PAPER_COLOR, (Color.WHITE.hashCode()));
json.put(PEN_DOWN_COLOR_DEFAULT, (Color.BLACK.hashCode()));
json.put(PEN_DOWN_COLOR, (Color.BLACK.hashCode()));
json.put(PEN_UP_COLOR, (Color.GREEN.hashCode()));
json.put(MAX_JERK, "[10,10,3]");
}
public PlotterSettings(String UID) {
super();
load(UID);
}
public String getUID() {
return robotUID;
}
protected void setRobotUID(String robotUID) {
this.robotUID = robotUID;
json.put("robotUID", robotUID);
}
/**
* @param key the key to look up
* @return the value of the key
* @throws NullPointerException key does not exist
* @throws IllegalStateException profile does not exist.
*/
public double getDouble(String key) throws NullPointerException, IllegalStateException {
return json.getDouble(key);
}
/**
* @param key the key to look up
* @return the value of the key
* @throws NullPointerException key does not exist
* @throws IllegalStateException profile does not exist.
*/
public int getInteger(String key) throws NullPointerException, IllegalStateException {
return json.getInt(key);
}
/**
* @param key the key to look up
* @return the value of the key
* @throws NullPointerException key does not exist
* @throws IllegalStateException profile does not exist.
*/
public String getString(String key) throws NullPointerException, IllegalStateException {
return json.getString(key);
}
/**
* @param key the key to look up
* @return the value of the key
* @throws NullPointerException key does not exist
* @throws IllegalStateException profile does not exist.
*/
public boolean getBoolean(String key) throws NullPointerException, IllegalStateException {
return json.getBoolean(key);
}
/**
* @param key the key to look up
* @return the value of the key
* @throws NullPointerException key does not exist
* @throws IllegalStateException profile does not exist.
*/
public Color getColor(String key) throws NullPointerException, IllegalStateException {
int v = getInteger(key);
return new Color(v);
}
/**
* @param key the key to look up
* @return the value of the key
* @throws NullPointerException key does not exist
* @throws IllegalStateException profile does not exist.
*/
public double [] getDoubleArray(String key) throws NullPointerException, IllegalStateException {
String s = getString(key);
String [] parts = s.substring(1,s.length()-1).split(",");
if(parts.length==0) return new double[0];
try {
double[] result = new double[parts.length];
for (int i = 0; i < parts.length; ++i) {
result[i] = Double.parseDouble(parts[i].trim());
}
return result;
} catch(Exception e) {
return new double[0];
}
}
/**
* @param key the key to look up
* @param value the value to set
* @throws NullPointerException key does not exist
* @throws IllegalStateException profile does not exist.
*/
public void setDouble(String key,double value) throws NullPointerException, IllegalStateException {
json.put(key, value);
}
/**
* @param key the key to look up
* @param value the value to set
* @throws NullPointerException key does not exist
* @throws IllegalStateException profile does not exist.
*/
public void setInteger(String key,int value) throws NullPointerException, IllegalStateException {
json.put(key,value);
}
/**
* @param key the key to look up
* @param value the value to set
* @throws NullPointerException key does not exist
* @throws IllegalStateException profile does not exist.
*/
public void setString(String key,String value) throws NullPointerException, IllegalStateException {
json.put(key, value);
}
/**
* @param key the key to look up
* @param value the value to set
* @throws NullPointerException key does not exist
* @throws IllegalStateException profile does not exist.
*/
public void setBoolean(String key,boolean value) throws NullPointerException, IllegalStateException {
json.put(key, value);
}
/**
* @param key the key to look up
* @param value the value to set
* @throws NullPointerException key does not exist
* @throws IllegalStateException profile does not exist.
*/
public void setColor(String key,Color value) throws NullPointerException, IllegalStateException {
setInteger(key,value.hashCode());
}
public void setDoubleArray(String key,double [] values) throws NullPointerException, IllegalStateException {
setString(key,Arrays.toString(values));
}
public Point2d getHome() {
return new Point2d(0,0);
}
/**
* Load the machine configuration from {@link Preferences}.
* @param uid the unique id of the robot to be loaded
*/
public void load(String uid) {
robotUID = uid;
Preferences allMachinesNode = PreferencesHelper.getPreferenceNode(PreferencesHelper.MakelangeloPreferenceKey.MACHINES);
Preferences thisMachineNode = allMachinesNode.node(robotUID);
json.put("robotUID", robotUID);
json.put(IS_REGISTERED, thisMachineNode.getBoolean(IS_REGISTERED,false));
json.put(HANDLE_SMALL_SEGMENTS, thisMachineNode.getBoolean(HANDLE_SMALL_SEGMENTS,false));
json.put(MIN_SEGMENT_LENGTH, thisMachineNode.getDouble(MIN_SEGMENT_LENGTH,0.5)); // mm
json.put(MAX_ACCELERATION, thisMachineNode.getDouble(MAX_ACCELERATION,100)); // mm/s/s
json.put(MIN_ACCELERATION, thisMachineNode.getDouble(MIN_ACCELERATION,0.0)); // mm/s/s
json.put(MINIMUM_PLANNER_SPEED, thisMachineNode.getDouble(MINIMUM_PLANNER_SPEED,0.05)); // mm/s
json.put(LIMIT_LEFT, thisMachineNode.getDouble(LIMIT_LEFT,-325)); // mm
json.put(LIMIT_RIGHT, thisMachineNode.getDouble(LIMIT_RIGHT,325)); // mm
json.put(LIMIT_BOTTOM, thisMachineNode.getDouble(LIMIT_BOTTOM,-500)); // mm
json.put(LIMIT_TOP, thisMachineNode.getDouble(LIMIT_TOP,500)); // mm
json.put(DIAMETER, thisMachineNode.getDouble(DIAMETER,0.8)); // mm, >0
json.put(PEN_ANGLE_UP, thisMachineNode.getDouble(PEN_ANGLE_UP,90)); // servo angle (degrees,0...180)
json.put(PEN_ANGLE_DOWN, thisMachineNode.getDouble(PEN_ANGLE_DOWN,25)); // servo angle (degrees,0...180)
json.put(PEN_ANGLE_UP_TIME, thisMachineNode.getDouble(PEN_ANGLE_UP_TIME,250));
json.put(PEN_ANGLE_DOWN_TIME, thisMachineNode.getDouble(PEN_ANGLE_DOWN_TIME,150));
json.put(FEED_RATE_TRAVEL, thisMachineNode.getDouble(FEED_RATE_TRAVEL,3000)); // mm/min. 3000 = 50 mm/s
json.put(FEED_RATE_DRAW, thisMachineNode.getDouble(FEED_RATE_DRAW,3000)); // mm/min. 3000 = 50 mm/s
json.put(BLOCK_BUFFER_SIZE, thisMachineNode.getInt(BLOCK_BUFFER_SIZE,16));
json.put(SEGMENTS_PER_SECOND, thisMachineNode.getInt(SEGMENTS_PER_SECOND,5));
json.put(MIN_SEG_TIME, thisMachineNode.getInt(MIN_SEG_TIME,20000)); // us
json.put(STARTING_POS_INDEX, thisMachineNode.getInt(STARTING_POS_INDEX,4));
json.put(Z_MOTOR_TYPE, thisMachineNode.getInt(Z_MOTOR_TYPE,PlotterSettings.Z_MOTOR_TYPE_SERVO));
json.put(ANCESTOR, thisMachineNode.get(ANCESTOR,""));
json.put(USER_GENERAL_START_GCODE, thisMachineNode.get(USER_GENERAL_START_GCODE,""));
json.put(USER_GENERAL_END_GCODE, thisMachineNode.get(USER_GENERAL_END_GCODE,""));
json.put(STYLE, thisMachineNode.get(STYLE, PlotterRendererFactory.MAKELANGELO_5.getName()));
json.put(PAPER_COLOR, thisMachineNode.getInt(PAPER_COLOR,(Color.WHITE.hashCode())));
json.put(PEN_DOWN_COLOR_DEFAULT, thisMachineNode.getInt(PEN_DOWN_COLOR_DEFAULT,(Color.BLACK.hashCode())));
json.put(PEN_DOWN_COLOR, thisMachineNode.getInt(PEN_DOWN_COLOR,(Color.BLACK.hashCode())));
json.put(PEN_UP_COLOR, thisMachineNode.getInt(PEN_UP_COLOR,(Color.GREEN.hashCode())));
json.put(MAX_JERK, thisMachineNode.get(MAX_JERK,"[10,10,3]"));
}
/**
* Save the machine configuration to {@link Preferences}. The preference node will be the unique id of the robot.
* Preferences save every time a value is changed, so save() does nothing.
*/
public void save() {
Preferences allMachinesNode = PreferencesHelper.getPreferenceNode(PreferencesHelper.MakelangeloPreferenceKey.MACHINES);
Preferences thisMachineNode = allMachinesNode.node(robotUID);
thisMachineNode.put("robotUID", robotUID);
thisMachineNode.put(STYLE, json.getString(STYLE));
thisMachineNode.putBoolean(IS_REGISTERED, json.getBoolean(IS_REGISTERED));
thisMachineNode.putBoolean(HANDLE_SMALL_SEGMENTS, json.getBoolean(HANDLE_SMALL_SEGMENTS));
thisMachineNode.putDouble(MIN_SEGMENT_LENGTH, json.getDouble(MIN_SEGMENT_LENGTH));
thisMachineNode.putDouble(MAX_ACCELERATION, json.getDouble(MAX_ACCELERATION));
thisMachineNode.putDouble(MIN_ACCELERATION, json.getDouble(MIN_ACCELERATION));
thisMachineNode.putDouble(MINIMUM_PLANNER_SPEED, json.getDouble(MINIMUM_PLANNER_SPEED));
thisMachineNode.putDouble(LIMIT_LEFT, json.getDouble(LIMIT_LEFT));
thisMachineNode.putDouble(LIMIT_RIGHT, json.getDouble(LIMIT_RIGHT));
thisMachineNode.putDouble(LIMIT_BOTTOM, json.getDouble(LIMIT_BOTTOM));
thisMachineNode.putDouble(LIMIT_TOP, json.getDouble(LIMIT_TOP));
thisMachineNode.putDouble(DIAMETER, json.getDouble(DIAMETER));
thisMachineNode.putDouble(PEN_ANGLE_UP, json.getDouble(PEN_ANGLE_UP));
thisMachineNode.putDouble(PEN_ANGLE_DOWN, json.getDouble(PEN_ANGLE_DOWN));
thisMachineNode.putDouble(PEN_ANGLE_UP_TIME, json.getDouble(PEN_ANGLE_UP_TIME));
thisMachineNode.putDouble(PEN_ANGLE_DOWN_TIME, json.getDouble(PEN_ANGLE_DOWN_TIME));
thisMachineNode.putDouble(FEED_RATE_TRAVEL, json.getDouble(FEED_RATE_TRAVEL));
thisMachineNode.putDouble(FEED_RATE_DRAW, json.getDouble(FEED_RATE_DRAW));
thisMachineNode.putInt(BLOCK_BUFFER_SIZE, json.getInt(BLOCK_BUFFER_SIZE));
thisMachineNode.putInt(SEGMENTS_PER_SECOND, json.getInt(SEGMENTS_PER_SECOND));
thisMachineNode.putInt(MIN_SEG_TIME, json.getInt(MIN_SEG_TIME));
thisMachineNode.putInt(STARTING_POS_INDEX, json.getInt(STARTING_POS_INDEX));
thisMachineNode.putInt(Z_MOTOR_TYPE, json.getInt(Z_MOTOR_TYPE));
thisMachineNode.put(ANCESTOR, json.getString(ANCESTOR));
thisMachineNode.put(USER_GENERAL_START_GCODE, json.getString(USER_GENERAL_START_GCODE));
thisMachineNode.put(USER_GENERAL_END_GCODE, json.getString(USER_GENERAL_END_GCODE));
thisMachineNode.putInt(PAPER_COLOR, json.getInt(PAPER_COLOR));
thisMachineNode.putInt(PEN_DOWN_COLOR_DEFAULT, json.getInt(PEN_DOWN_COLOR_DEFAULT));
thisMachineNode.putInt(PEN_DOWN_COLOR, json.getInt(PEN_DOWN_COLOR));
thisMachineNode.putInt(PEN_UP_COLOR, json.getInt(PEN_UP_COLOR));
thisMachineNode.put(MAX_JERK, json.getString(MAX_JERK));
}
/**
* Reset the machine configuration to the value of the progenitor (original ancestor).
*/
public void reset() {
// TODO finish me?
}
/**
* Sets the machine limits.
* @param width mm
* @param height mm
*/
public void setMachineSize(double width, double height) {
setDouble(PlotterSettings.LIMIT_LEFT,-width / 2.0);
setDouble(PlotterSettings.LIMIT_RIGHT,width / 2.0);
setDouble(PlotterSettings.LIMIT_BOTTOM,-height / 2.0);
setDouble(PlotterSettings.LIMIT_TOP,height / 2.0);
}
@Override
public String toString() {
return json.toString();
}
/**
* @param key the key to look up
* @return true if the value of this key is the same as the value of the previous ancestor.
*/
public boolean isDefaultValue(String key) {
String progenitor = getProgenitor();
if(progenitor.equals(getUID())) return true;
PlotterSettings ancestor = new PlotterSettings(progenitor);
return ancestor.getString(key).equals(getString(key));
}
/**
* Walk up the chain of ancestors to find the progenitor, the original.
* @return the name of the progenitor.
*/
public String getProgenitor() {
PlotterSettings trace = this;
while(!trace.isMostAncestral()) {
trace = new PlotterSettings(trace.getString(ANCESTOR));
}
return trace.getUID();
}
/**
* @return true if this profile has no ancestors.
*/
public boolean isMostAncestral() {
String ancestorName = getString(ANCESTOR);
return ancestorName==null || ancestorName.isEmpty();
}
}a199cc528This file is pinned to the selected release. Download the original to open it in your design tool.