From 32b246d14d0737676c17e2e5e721c0783ec4d64f Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Thu, 8 Mar 2012 18:28:33 -0800 Subject: [PATCH 01/35] Added a (failing) test to demonstrate dithering. The Makerbot-derived printer drivers contain a math error that manifests several different ways: Z-hold unexpectedly engaged during a print; wobbles on otherwise straight edges; increased loss of steps (including Z steps) during rapid motion, as in fills. This test case demonstrates the bug. The next commit fixes it. --- test/lib/cglib-nodep-2.2.2.jar | Bin 0 -> 326917 bytes test/lib/easymock-3.1.jar | Bin 0 -> 111958 bytes test/lib/objenesis-1.2.jar | Bin 0 -> 36034 bytes .../gen3/Makerbot4GAlternateDriverTest.java | 271 ++++++++++++++++++ 4 files changed, 271 insertions(+) create mode 100644 test/lib/cglib-nodep-2.2.2.jar create mode 100644 test/lib/easymock-3.1.jar create mode 100644 test/lib/objenesis-1.2.jar create mode 100644 unittest/replicatorg/drivers/gen3/Makerbot4GAlternateDriverTest.java diff --git a/test/lib/cglib-nodep-2.2.2.jar b/test/lib/cglib-nodep-2.2.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..02d81e8804001956c22b05c8e18cec1e596efc76 GIT binary patch literal 326917 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%0Am)P;1#U_2WR^RdD-yG0h2E+#Ed4S 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ð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 Q@Q?llG_=?(kQ&hbA8zkSqyPW_ literal 0 HcmV?d00001 diff --git a/test/lib/easymock-3.1.jar b/test/lib/easymock-3.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..f56f07aceaa79963eee1981efaa02aefdcbccebf GIT binary patch literal 111958 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 P)9_DON*Ys%-oMX(QbM;I literal 0 HcmV?d00001 diff --git a/test/lib/objenesis-1.2.jar b/test/lib/objenesis-1.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..45cb6416838ba263335373cd93d507cccfcdefe6 GIT binary patch literal 36034 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�vbna5Pgjz%Sr1t^Y@@PI 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 Sp`aKc|G;RFs3XtY-~JyEs + * The driver wasn't designed with testing in mind, so I had to + * pound it pretty hard to fit it into this jig. If you're not + * fluent in EasyMock this test may be somewhat confusing, and + * for that I apologize. These are the compromises we must make + * to test legacy code. + * + * @author cbiffle + */ +public class Makerbot4GAlternateDriverTest { + /* + * Yeah, I copied and pasted the machine def out of Rob Giseburt's XML file. + * This avoids a filesystem dependency in the unit test. + */ + private static final String CANNED_MACHINE_DEF = + "" + + "3G 5D (RPM) Cupcake (Gen3 XYZ, Mk5/6+Gen4 Extruder)" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "38400" + + "8" + + "" + + "" + + "" + + "" + + "(Turn off steppers after a build.)" + + "M18" + + "" + + ""; + + Serial serial; + MachineCallbackHandler machineCallbackHandler; + Makerbot4GAlternateDriver driver; + + @Before public void setUp() throws Exception { + MachineModel mm = new MachineModel(); + mm.loadXML( + DocumentBuilderFactory.newInstance() + .newDocumentBuilder() + .parse(new InputSource(new StringReader(CANNED_MACHINE_DEF))) + .getDocumentElement()); + + System.out.println("steps per mm: " + mm.getStepsPerMM()); + + /* + * There are two facilities we need to mock to evaluate the + * driver: the serial port, and the MachineCallbackHandler, + * which is used to inform the program of machine status + * changes. We only care about the former. + */ + serial = createMock(Serial.class); + machineCallbackHandler = createMock(MachineCallbackHandler.class); + prepareMachineCallbackHandler(); + replayAll(); + + driver = new Makerbot4GAlternateDriver(); + driver.setMachine(mm); + + // Class design gives us no choice but to break out the chainsaw: + Field serialField = SerialDriver.class.getDeclaredField("serial"); + serialField.setAccessible(true); + serialField.set(driver, serial); + + // Check that the driver hasn't done anything silly during init. + verifyAll(); + resetAll(); + + prepareMachineCallbackHandler(); + } + + /* + * Stubs out the relevant methods in MCH. We don't care about the + * interaction with this object. + */ + private void prepareMachineCallbackHandler() { + machineCallbackHandler.schedule(anyObject(MachineProgressEvent.class)); + expectLastCall().asStub(); + + machineCallbackHandler.schedule(anyObject(MachineStateChangeEvent.class)); + expectLastCall().asStub(); + + machineCallbackHandler.schedule(anyObject(MachineToolStatusEvent.class)); + expectLastCall().asStub(); + } + + @Test public void testZeroLengthMove() throws RetryException { + serial.write(aryEq(makeQueuePointExt(0, 0, 0, 0, 0, 1250))); + prepareOkResponse(); + replayAll(); + + driver.queuePoint(new Point5d(0, 0, 0, 0, 0)); + verifyAll(); + } + + @Test public void testFractionalStepPattern() throws RetryException { + /* + * This test alternates back and forth between the origin and a + * position on positive X. When the excess-tracking code is + * enabled, it demonstrates how dithering hampers repeatability. + */ + final double X = 1.57; // Where we're headed + final int S = 18; // Equivalent in steps + final int US = 18840; // Duration of move at default feedrate + final int A_AXIS = (1 << 3); // Relative-motion flag for A + + /* + * The machine we've selected has 11.767463 steps/mm on X. + * 1.57 * 11.767463 = 18.4749169. + * The excess tracking code rounds this to 18 and accumulates + * the 0.4746169 difference. It takes only three moves for + * this to surface as an unintended step; ITERATIONS records + * the second two (the ones that generate QUEUE_POINT_NEW). + */ + final int ITERATIONS = 2; + + /* + * Here's what we'll see at the serial port: + */ + + // First, the positionLost() logic generates QUEUE_POINT_EXT. + serial.write(aryEq(makeQueuePointExt(0, 0, 0, 0, 0, 1250))); + prepareOkResponse(); // "Machine" acknowledges + + // Next, the driver emits a sequence of QUEUE_POINT_NEW. + for (int i = 0; i < ITERATIONS; ++i) { + serial.write(aryEq(makeQueuePointNew(S, 0, 0, 0, 0, US, A_AXIS))); + prepareOkResponse(); + serial.write(aryEq(makeQueuePointNew(0, 0, 0, 0, 0, US, A_AXIS))); + prepareOkResponse(); + } + replayAll(); + + driver.setFeedrate(5000); + driver.queuePoint(new Point5d(0, 0, 0, 0, 0)); + + for (int i = 0; i < ITERATIONS; ++i) { + driver.queuePoint(new Point5d(X, 0, 0, 0, 0)); + driver.queuePoint(new Point5d(0, 0, 0, 0, 0)); + } + verifyAll(); + } + + @Test public void testSideToSideMoves() throws RetryException { + /* + * This tests the supposition that moves along an axis should + * *never* induce moves on another axis. + * + * When the excess-tracking code is enabled, it demonstrates + * the appearance of "phantom" Z moves during horizontal + * motion along X. + * + * The machine we've selected has 320.0 steps/mm on Z. We + * choose a Z height of 1.57 mm, or in steps, 1.57 * 320 = 502.4. + * The excess-tracking code rounds this to 502 and accumulates + * the 0.4 difference. By the second motion, this passes 0.5 + * and causes the Z position to get rounded up one step, + * inducing a vertical move. From then on each motion along + * X produces opposing vertical motions of one step. + */ + final double X = 1.57; // Where we're headed on X in mm + final int SX = 18; // ...and in steps. + final double Z = X; // Constant Z position in mm + final int SZ = 502; // ...and in steps. + final int US = 37680; // Duration of moves in microseconds + final int A_AXIS = (1 << 3); // Relative motion flag on A + + /* + * Here's what we expect on the serial port: + */ + + // Initial point emitted as QUEUE_POINT_EXT. + serial.write(aryEq(makeQueuePointExt(SX, 0, SZ, 0, 0, 1250))); + prepareOkResponse(); + + // Subsequent two points are QUEUE_POINT_NEW. Z is constant. + serial.write(aryEq(makeQueuePointNew(-SX, 0, SZ, 0, 0, US, A_AXIS))); + prepareOkResponse(); + serial.write(aryEq(makeQueuePointNew(SX, 0, SZ, 0, 0, US, A_AXIS))); + prepareOkResponse(); + replayAll(); + + driver.setFeedrate(5000); + driver.queuePoint(new Point5d(X, 0, Z, 0, 0)); + driver.queuePoint(new Point5d(-X, 0, Z, 0, 0)); + driver.queuePoint(new Point5d(X, 0, Z, 0, 0)); + verifyAll(); + } + + private byte[] makeQueuePointExt(int x, int y, int z, int a, int b, int micros) { + PacketBuilder pb = new PacketBuilder(MotherboardCommandCode.QUEUE_POINT_EXT.getCode()); + pb.add32(x); + pb.add32(y); + pb.add32(z); + pb.add32(a); + pb.add32(b); + pb.add32(micros); + + return pb.getPacket(); + } + + private byte[] makeQueuePointNew(int x, int y, int z, int a, int b, int micros, int relative) { + PacketBuilder pb = new PacketBuilder(MotherboardCommandCode.QUEUE_POINT_NEW.getCode()); + + // just add them in now. + pb.add32(x); + pb.add32(y); + pb.add32(z); + pb.add32(a); + pb.add32(b); + pb.add32(micros); + pb.add8(relative); + + return pb.getPacket(); + } + + private void prepareOkResponse() { + for (byte b : new PacketBuilder(0x01).getPacket()) { + expect(serial.read()).andReturn((int) b); + } + } + + private void replayAll() { + replay(machineCallbackHandler, serial); + } + + private void verifyAll() { + verify(machineCallbackHandler, serial); + } + + private void resetAll() { + reset(machineCallbackHandler, serial); + } +} From cab13a4a2182f1c338c6210ef2e1ea39d1c728a7 Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Thu, 8 Mar 2012 18:34:03 -0800 Subject: [PATCH 02/35] Removed the excess-tracking code from the drivers. This fixes the dithering problem; the Makerbot4GAlternateDriverTest now passes. --- .../drivers/gen3/Makerbot4GAlternateDriver.java | 14 ++------------ src/replicatorg/drivers/gen3/MightyBoard.java | 6 +----- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/src/replicatorg/drivers/gen3/Makerbot4GAlternateDriver.java b/src/replicatorg/drivers/gen3/Makerbot4GAlternateDriver.java index 3e60a13b6..fa23cb906 100644 --- a/src/replicatorg/drivers/gen3/Makerbot4GAlternateDriver.java +++ b/src/replicatorg/drivers/gen3/Makerbot4GAlternateDriver.java @@ -32,9 +32,6 @@ public void reset() { super.reset(); } - /** The excess, in steps, from previous operations. */ - protected Point5d stepExcess = new Point5d(); - /** * Overloaded to manage a hijacked axis and run this axis in relative mode instead of the extruder DC motor */ @@ -69,10 +66,7 @@ public void queuePoint(Point5d p) throws RetryException { // okay, send it off! // TODO: bug: We move all axes (even ones that shouldn't be moved) How to avoid? - Point5d excess = new Point5d(stepExcess); - queueAbsolutePoint(machine.mmToSteps(filteredPoint, excess), longestDDA); - // Only update excess if no retry was thrown. - stepExcess = excess; + queueAbsolutePoint(machine.mmToSteps(filteredPoint), longestDDA); // Finally, recored the position, and mark it as valid. setInternalPosition(filteredPoint); } else { @@ -100,9 +94,8 @@ public void queuePoint(Point5d p) throws RetryException { delta.add(axesmovement); filteredpoint.add(axesmovement); - Point5d excess = new Point5d(stepExcess); // Calculate time for move in usec - Point5d steps = machine.mmToSteps(filteredpoint,excess); + Point5d steps = machine.mmToSteps(filteredpoint); // okay, send it off! // The 4. and 5. dimensions doesn't have a spatial interpretation. Calculate time in 3D space @@ -110,9 +103,6 @@ public void queuePoint(Point5d p) throws RetryException { queueNewPoint(steps, (long) (60 * 1000 * 1000 * minutes), relative); - // Only update excess if no retry was thrown. - stepExcess = excess; - setInternalPosition(filteredpoint); } } diff --git a/src/replicatorg/drivers/gen3/MightyBoard.java b/src/replicatorg/drivers/gen3/MightyBoard.java index 4bbfeba7d..5ef0136a8 100644 --- a/src/replicatorg/drivers/gen3/MightyBoard.java +++ b/src/replicatorg/drivers/gen3/MightyBoard.java @@ -475,8 +475,7 @@ public void queuePoint(final Point5d p) throws RetryException { } // calculate absolute position of target in steps - Point5d excess = new Point5d(stepExcess); - Point5d steps = machine.mmToSteps(target,excess); + Point5d steps = machine.mmToSteps(target); double usec = (60 * 1000 * 1000 * minutes); @@ -486,9 +485,6 @@ public void queuePoint(final Point5d p) throws RetryException { int relativeAxes = (1 << AxisId.A.getIndex()) | (1 << AxisId.B.getIndex()); queueNewPoint(steps, (long) usec, relativeAxes); - // Only update excess if no retry was thrown. - stepExcess = excess; - // because of the hinky stuff we've been doing with A & B axes, just pretend we've // moved where we thought we were moving Point5d fakeOut = new Point5d(target); From 3cfb577c93bf401020805e14b6317dce20340988 Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Thu, 8 Mar 2012 19:30:07 -0800 Subject: [PATCH 03/35] Fixed compilation errors in MachineLoaderTest. Which, incidentally, doesn't pass. --- unittest/machineTests/MachineLoaderTest.java | 21 +++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/unittest/machineTests/MachineLoaderTest.java b/unittest/machineTests/MachineLoaderTest.java index f7ca170e1..c01863f62 100644 --- a/unittest/machineTests/MachineLoaderTest.java +++ b/unittest/machineTests/MachineLoaderTest.java @@ -17,6 +17,9 @@ import replicatorg.machine.MachineStateChangeEvent; import replicatorg.machine.MachineToolStatusEvent; +/* + * NOTE: as of 2012-03-08 this test is known to fail! + */ public class MachineLoaderTest { // Simple class to collect Machine events so they can be read back later. public class TestMachineListener implements MachineListener { @@ -103,25 +106,25 @@ public void testGetDriver() { @Test public void testLoad() { // Try loading a garbage machine - assertFalse(loader.getMachineInterface("fake machine")); + assertNull(loader.getMachineInterface("fake machine")); // Now try loading a known good machine - assertTrue(loader.getMachineInterface("Cupcake Basic")); + assertNotNull(loader.getMachineInterface("Cupcake Basic")); // Test that the isLoaded() function actually works assertTrue(loader.isLoaded()); // Now, try loading another garbage machine on top of the known good one. - assertFalse(loader.getMachineInterface("fake machine")); + assertNull(loader.getMachineInterface("fake machine")); // Finally, load the good one again to make sure it can recover. - assertTrue(loader.getMachineInterface("Cupcake Basic")); + assertNotNull(loader.getMachineInterface("Cupcake Basic")); } @Test public void testUnload() { // See if we can bring up and then dispose of a machine - assertTrue(loader.getMachineInterface("Cupcake Basic")); + assertNotNull(loader.getMachineInterface("Cupcake Basic")); loader.unload(); @@ -136,7 +139,7 @@ public void testConnectionInvalidPort() { // This should give us a couple of messages: CONNECTING ERROR // Make sure that we get them both back in order, within a reasonable time. // Finally, unload the machine to receive NOT_ATTACHED. - assertTrue(loader.getMachineInterface("Cupcake Basic")); + assertNotNull(loader.getMachineInterface("Cupcake Basic")); loader.connect(""); event = listener.getMachineStateChangedEvent(commTimeout); @@ -174,7 +177,7 @@ public void testConnectionKnownGoodPort() { // Finally, unload the machine to receive NOT_ATTACHED. for(int i = 0; i < 1; i++) { Base.logger.info("i = " + i ); - assertTrue(loader.getMachineInterface("Thingomatic w/ HBP and Stepstruder MK6")); + assertNotNull(loader.getMachineInterface("Thingomatic w/ HBP and Stepstruder MK6")); loader.connect("/dev/ttyUSB0"); event = listener.getMachineStateChangedEvent(commTimeout); @@ -204,7 +207,7 @@ public void testConnectionKnownGoodPort() { public void testDisconnect() { MachineStateChangeEvent event; - assertTrue(loader.getMachineInterface("Thingomatic w/ HBP and Stepstruder MK6")); + assertNotNull(loader.getMachineInterface("Thingomatic w/ HBP and Stepstruder MK6")); loader.connect("/dev/ttyUSB0"); event = listener.getMachineStateChangedEvent(commTimeout); @@ -241,7 +244,7 @@ public void testDisconnect() { public void testUserDisconnect() { MachineStateChangeEvent event; - assertTrue(loader.getMachineInterface("Thingomatic w/ HBP and Stepstruder MK6")); + assertNotNull(loader.getMachineInterface("Thingomatic w/ HBP and Stepstruder MK6")); loader.connect("/dev/ttyUSB0"); event = listener.getMachineStateChangedEvent(commTimeout); From c01bd8d23ef1e3f397c8f40959738964fa3f1e2a Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Thu, 8 Mar 2012 23:42:13 -0800 Subject: [PATCH 04/35] Removed unused deprecated code in Sanguino3GDriver. --- .../drivers/gen3/Sanguino3GDriver.java | 126 +----------------- 1 file changed, 1 insertion(+), 125 deletions(-) diff --git a/src/replicatorg/drivers/gen3/Sanguino3GDriver.java b/src/replicatorg/drivers/gen3/Sanguino3GDriver.java index c488d255f..b0bc4e90b 100644 --- a/src/replicatorg/drivers/gen3/Sanguino3GDriver.java +++ b/src/replicatorg/drivers/gen3/Sanguino3GDriver.java @@ -1003,12 +1003,6 @@ public void setMotorSpeedPWM(int pwm, int toolhead) throws RetryException { super.setMotorSpeedPWM(pwm, toolhead); } - @Deprecated - public void enableMotor() throws RetryException { - /// toolhead -1 indicate auto-detect - this.enableMotor(-1); - } - public void enableMotor(int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. @@ -1060,10 +1054,6 @@ public void disableMotor(int toolhead) throws RetryException { super.disableMotor(toolhead); } - @Deprecated - public int getMotorSpeedPWM() { - return this.getMotorSpeedPWM(machine.currentTool().getIndex()); - } public int getMotorSpeedPWM(int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. @@ -1118,11 +1108,6 @@ public double getMotorRPM(int toolhead) { } - @Deprecated - public void readToolStatus() { - this.readToolStatus(machine.currentTool().getIndex()); - } - public void readToolStatus(int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. @@ -1151,7 +1136,7 @@ public void readToolStatus(int toolhead) { + (((status & 0x01) != 0) ? "READY" : "NOT READY") + " "); } - readToolPIDState(); + readToolPIDState(toolhead); } // TODO: This doesn't belong here @@ -1163,10 +1148,6 @@ private int fixSigned(int value) { return value; } - @Deprecated - public void readToolPIDState() { - this.readToolPIDState(machine.currentTool().getIndex()); - } // TODO: Implement a way for this to reach the outside public void readToolPIDState(int toolhead) { @@ -1266,10 +1247,6 @@ public void setServoPos(int index, double degree, int toolhead) throws RetryExce /*************************************************************************** * Spindle interface functions **************************************************************************/ - @Deprecated - public void setSpindleRPM(double rpm) throws RetryException { - this.setSpindleRPM(rpm, machine.currentTool().getIndex() ); - } public void setSpindleRPM(double rpm, int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. @@ -1296,11 +1273,6 @@ public void setSpindleRPM(double rpm, int toolhead) throws RetryException { super.setSpindleRPM(rpm, toolhead); } - @Deprecated - public void setSpindleSpeedPWM(int pwm) throws RetryException { - this.setSpindleSpeedPWM(pwm, machine.currentTool().getIndex()); - } - public void setSpindleSpeedPWM(int pwm, int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. @@ -1320,11 +1292,6 @@ public void setSpindleSpeedPWM(int pwm, int toolhead) throws RetryException { super.setSpindleSpeedPWM(pwm, toolhead); } - @Deprecated - public void enableSpindle() throws RetryException { - this.enableSpindle(machine.currentTool().getIndex()); - } - public void enableSpindle(int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. @@ -1352,11 +1319,6 @@ public void enableSpindle(int toolhead) throws RetryException { super.enableSpindle(toolhead); } - @Deprecated - public void disableSpindle() throws RetryException { - disableSpindle(machine.currentTool().getIndex()); - } - public void disableSpindle(int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. @@ -1380,11 +1342,6 @@ public void disableSpindle(int toolhead) throws RetryException { super.disableSpindle(toolhead); } - @Deprecated - public double getSpindleSpeedRPM() throws RetryException { - return this.getSpindleSpeedRPM(machine.currentTool().getIndex()); - } - public double getSpindleSpeedRPM(int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. @@ -1408,11 +1365,6 @@ public double getSpindleSpeedRPM(int toolhead) throws RetryException { return rpm; } - @Deprecated - public int getSpindleSpeedPWM() { - return this.getSpindleSpeedPWM(machine.currentTool().getIndex()); - } - public int getSpindleSpeedPWM(int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. @@ -1440,11 +1392,6 @@ public int getSpindleSpeedPWM(int toolhead) { * Temperature interface functions * @throws RetryException **************************************************************************/ - @Deprecated - public void setTemperature(double temperature) throws RetryException { - this.setTemperature(temperature, machine.currentTool().getIndex()); - } - public void setTemperature(double temperature, int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. @@ -1467,12 +1414,6 @@ public void setTemperature(double temperature, int toolhead) throws RetryExcepti super.setTemperature(temperature, toolhead); } - @Deprecated - public void readTemperature() { - readAllTemperatures(); /// for safety, read all the temps we can - //readTemperature(machine.currentTool().getIndex()); - } - @Override public void readAllTemperatures() { Vector tools = machine.getTools(); @@ -1519,11 +1460,6 @@ else if (pr.isEmpty()) * @throws RetryException **************************************************************************/ - @Deprecated - public void setPlatformTemperature(double temperature) throws RetryException { - setAllPlatformTemperatures(temperature); - } - public void setPlatformTemperature(double temperature, int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. @@ -1553,11 +1489,6 @@ public void setAllPlatformTemperatures(double temperature) throws RetryException } } - @Deprecated - public void readPlatformTemperature() { - this.readAllPlatformTemperatures(); - } - public void readPlatformTemperature(int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -1622,11 +1553,6 @@ public void disableMistCoolant() { * * @throws RetryException **************************************************************************/ - @Deprecated - public void enableFan() throws RetryException { - this.enableFan(machine.currentTool().getIndex() ); - } - public void enableFan(int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. @@ -1645,10 +1571,6 @@ public void enableFan(int toolhead) throws RetryException { super.enableFan(toolhead); } - @Deprecated - public void disableFan() throws RetryException { - this.disableFan(machine.currentTool().getIndex()); - } public void disableFan(int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. @@ -1667,12 +1589,6 @@ public void disableFan(int toolhead) throws RetryException { super.disableFan(toolhead); } - @Deprecated - public void setAutomatedBuildPlatformRunning(boolean state) - throws RetryException { - this.setAutomatedBuildPlatformRunning(state, machine.currentTool().getIndex()); - } - public void setAutomatedBuildPlatformRunning(boolean state, int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. @@ -1698,11 +1614,6 @@ public void setAutomatedBuildPlatformRunning(boolean state, int toolhead) * * @throws RetryException **************************************************************************/ - @Deprecated - public void openValve() throws RetryException { - openValve(machine.currentTool().getIndex()); - } - public void openValve(int toolhead) throws RetryException { Base.logger.fine("Opening valve"); @@ -1722,11 +1633,6 @@ public void openValve(int toolhead) throws RetryException { } - @Deprecated - public void closeValve() throws RetryException { - closeValve(machine.currentTool().getIndex()); - } - public void closeValve(int toolhead) throws RetryException { Base.logger.fine("Closing valve"); @@ -1939,11 +1845,6 @@ protected void writeToEEPROM(int offset, byte[] data) { assert pr.get8() == data.length; } - @Deprecated - protected byte[] readFromToolEEPROM(int offset, int len) - { - return readFromToolEEPROM(offset, len, machine.currentTool().getIndex()); - } protected byte[] readFromToolEEPROM(int offset, int len, int toolhead) { @@ -1972,16 +1873,6 @@ protected byte[] readFromToolEEPROM(int offset, int len, int toolhead) { return null; } - /** - * - * @param offset - * @param data - */ - @Deprecated - protected void writeToToolEEPROM(int offset, byte[] data) { - writeToToolEEPROM(offset, data, machine.currentTool().getIndex()); - } - /** * * @param offset @@ -2556,11 +2447,6 @@ final private static class CoolingFanOffsets { }; - @Deprecated - protected int read16FromToolEEPROM(int offset, int defaultValue) { - return read16FromToolEEPROM(offset, defaultValue, machine.currentTool().getIndex()); - } - protected int read16FromToolEEPROM(int offset, int defaultValue, int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -2729,11 +2615,6 @@ public void setEstopConfig(EstopType estop) { writeToEEPROM(Sanguino3GEEPRPOM.EEPROM_ESTOP_CONFIGURATION_OFFSET, b); } - @Deprecated - public double getPlatformTemperatureSetting() { - return this.getPlatformTemperatureSetting(machine.currentTool().getIndex()); - } - public double getPlatformTemperatureSetting(int toolhead) { /// toolhead -1 indicates auto-detect. Fast hack to get software out... if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -2753,11 +2634,6 @@ public double getPlatformTemperatureSetting(int toolhead) { return machine.getTool(toolhead).getPlatformTargetTemperature(); } - @Deprecated - public double getTemperatureSetting() { - return this.getTemperatureSetting(machine.currentTool().getIndex()); - } - public double getTemperatureSetting(int toolhead) { /// toolhead -1 indicates auto-detect. Fast hack to get software out... if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); From 45dc178f28157611b5da6ee990007522d913413d Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Thu, 8 Mar 2012 23:44:15 -0800 Subject: [PATCH 05/35] Fixed incorrect override that disabled stepper fan. I've added @Override annotations to all overrides. This revealed a bug: the enableMotor/disableMotor, despite being documented as overrides, weren't. As a result, the Sanguino3GDriver behavior was being invoked, generating DC motor control messages even when the axis has been hijacked for a stepper extruder. Because this driver reuses the same motor control channel for the stepper fan, this meant the fan turned on...until the first motion. Then it started toggling on and off with the stepper motor. That's kind of silly, so with this change it obeys the flag passed to enableStepperExtruderFan(boolean). --- .../gen3/Makerbot4GAlternateDriver.java | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/replicatorg/drivers/gen3/Makerbot4GAlternateDriver.java b/src/replicatorg/drivers/gen3/Makerbot4GAlternateDriver.java index fa23cb906..d1a5c4846 100644 --- a/src/replicatorg/drivers/gen3/Makerbot4GAlternateDriver.java +++ b/src/replicatorg/drivers/gen3/Makerbot4GAlternateDriver.java @@ -20,11 +20,11 @@ public class Makerbot4GAlternateDriver extends Makerbot4GDriver { private boolean stepperExtruderFanEnabled = false; - public String getDriverName() { + @Override public String getDriverName() { return "Makerbot4GAlternate"; } - public void reset() { + @Override public void reset() { // We should poll the machine for it's state here, but it is more important to have the // fan on than off. stepperExtruderFanEnabled = false; @@ -35,7 +35,7 @@ public void reset() { /** * Overloaded to manage a hijacked axis and run this axis in relative mode instead of the extruder DC motor */ - public void queuePoint(Point5d p) throws RetryException { + @Override public void queuePoint(Point5d p) throws RetryException { // If we don't know our current position, make this move an old-style move, ignoring any hijacked axes. if (positionLost()) { Base.logger.fine("Position invalid, reverting to default speed for next motion"); @@ -112,7 +112,7 @@ public void queuePoint(Point5d p) throws RetryException { * In legacy use, delayed while a DC motor ran. For compatiblity, this function * creates a Point5D to do 'extrude while sitting still'. */ - public void delay(long millis) throws RetryException { + @Override public void delay(long millis) throws RetryException { Base.logger.finer("Delaying " + millis + " millis."); Point5d steps = pointsFromHijackedAxes( machine.currentTool(), millis / 60000d); @@ -223,7 +223,7 @@ private Point5d pointsFromHijackedAxes(ToolModel curTool, double minutes) { return steps; } - public void stop(boolean abort) { + @Override public void stop(boolean abort) { // Record the toolstate as off, so we don't excite the extruder motor in future moves. machine.currentTool().disableMotor(); @@ -264,38 +264,41 @@ protected void queueNewPoint(Point5d steps, long us, int relative) throws RetryE /** * Overridden to not talk to the DC motor driver. This driver is reused for the stepper motor fan */ - public void enableMotor() throws RetryException { - machine.currentTool().enableMotor(); + @Override public void enableMotor(int toolhead) throws RetryException { + if (toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + machine.getTool(toolhead).enableMotor(); } /** * Overridden to not talk to the DC motor driver. This driver is reused for the stepper motor fan */ - public void disableMotor() throws RetryException { - machine.currentTool().disableMotor(); + @Override public void disableMotor(int toolhead) throws RetryException { + if (toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + + machine.getTool(toolhead).disableMotor(); } /** * Overridden to not talk to the DC motor driver. This driver is reused for the stepper motor fan */ - public void setMotorSpeedPWM(int pwm) throws RetryException { + @Override public void setMotorSpeedPWM(int pwm) throws RetryException { machine.currentTool().setMotorSpeedPWM(pwm); } /** * Overridden to not talk to the DC motor driver. This driver is reused for the stepper motor fan */ - public void setMotorRPM(double rpm, int toolhead) throws RetryException { + @Override public void setMotorRPM(double rpm, int toolhead) throws RetryException { machine.currentTool().setMotorSpeedRPM(rpm); } - public void enableDrives() throws RetryException { + @Override public void enableDrives() throws RetryException { enableStepperExtruderFan(true); super.enableDrives(); } - public void disableDrives() throws RetryException { + @Override public void disableDrives() throws RetryException { enableStepperExtruderFan(false); super.disableDrives(); @@ -305,7 +308,7 @@ public void disableDrives() throws RetryException { * Will turn on/off the stepper extruder fan if it's not already in the correct state. * */ - public void enableStepperExtruderFan(boolean enabled) throws RetryException { + @Override public void enableStepperExtruderFan(boolean enabled) throws RetryException { // Always re-enable the fan when if (this.stepperExtruderFanEnabled == enabled) return; @@ -342,11 +345,10 @@ public void enableStepperExtruderFan(boolean enabled) throws RetryException { /// This is a list of which axis are hijacked for extruder use. EnumMap extruderHijackedMap = new EnumMap(AxisId.class); - @Override /** * When the machine is set for this driver, some toolheads may poach the an extrusion axis. */ - public void setMachine(MachineModel m) { + @Override public void setMachine(MachineModel m) { super.setMachine(m); for (ToolModel tm : m.getTools()) { Element e = (Element)tm.getXml(); @@ -370,12 +372,11 @@ public void setMachine(MachineModel m) { } } - @Override /** * Overridden to not ask the board for the RPM as it would report the RPM from the extruder * controller, which doesn't know about it in this case. */ - public double getMotorRPM() { + @Override public double getMotorRPM() { double rpm = machine.currentTool().getMotorSpeedRPM(); machine.currentTool().setMotorSpeedReadingRPM(rpm); return rpm; From f9db2bbd6685e19cc18c8d8b4e13ef90c32f4a8b Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Fri, 9 Mar 2012 08:55:26 -0800 Subject: [PATCH 06/35] Removed overrides of deprecated API in MightyBoard. --- src/replicatorg/drivers/gen3/MightyBoard.java | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/src/replicatorg/drivers/gen3/MightyBoard.java b/src/replicatorg/drivers/gen3/MightyBoard.java index 5ef0136a8..eb535544b 100644 --- a/src/replicatorg/drivers/gen3/MightyBoard.java +++ b/src/replicatorg/drivers/gen3/MightyBoard.java @@ -879,7 +879,7 @@ public double temp(double adc) { byte eepromIndicator[] = new byte[2]; eepromIndicator[0] = MightyBoardEEPROM.EEPROM_CHECK_LOW; eepromIndicator[1] = MightyBoardEEPROM.EEPROM_CHECK_HIGH; - writeToToolEEPROM(0,eepromIndicator); + writeToToolEEPROM(0, eepromIndicator, machine.currentTool().getIndex()); writeToEEPROM(MightyBoardEEPROM.ECThermistorOffsets.beta(which),intToLE((int)beta)); writeToEEPROM(MightyBoardEEPROM.ECThermistorOffsets.r0(which),intToLE((int)r0)); @@ -939,7 +939,7 @@ public void setExtraFeatures(ExtraFeatures features) { efdat |= features.hbpChannel << 4; efdat |= features.abpChannel << 6; //System.err.println("Writing to EF: "+Integer.toHexString(efdat)); - writeToToolEEPROM(ToolheadEEPROM.FEATURES, intToLE(efdat,2)); + writeToToolEEPROM(ToolheadEEPROM.FEATURES, intToLE(efdat,2), machine.currentTool().getIndex()); } @Override @@ -1019,13 +1019,6 @@ public boolean setConnectedToolIndex(int index) { } - @Override - @Deprecated - protected void writeToToolEEPROM(int offset, byte[] data) { - writeToToolEEPROM(offset, data, machine.currentTool().getIndex()); - } - - @Override protected void writeToToolEEPROM(int offset, byte[] data, int toolIndex) { final int MAX_PAYLOAD = 11; @@ -1182,12 +1175,6 @@ public int getT0(int which, int toolIndex) { return val; } - @Override - @Deprecated - protected int read16FromToolEEPROM(int offset, int defaultValue) { - return read16FromToolEEPROM(offset, defaultValue, machine.currentTool().getIndex()); - } - @Override protected int read16FromToolEEPROM(int offset, int defaultValue, int toolIndex) { byte r[] = readFromToolEEPROM(offset, 2, toolIndex); From 75c54f1a5e67c98c742be79e7139921eb6faa1c5 Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Fri, 9 Mar 2012 08:59:09 -0800 Subject: [PATCH 07/35] Improved code reuse in Makerbot4G*Driver. While Makerbot4GAlternateDriver was technically a subclass of Makerbot4GDriver, it was basically copied and pasted, duplicating most of the code. The duplicated code has diverged in some places; I've preserved those where they seem significant, even though I'm not sure they're correct. (In particular, setMachine behaves slightly differently in the two drivers.) This became pretty apparent under a debugger, where an instance of Makerbot4GAlternateDriver had *two* copies of all its fields... because they were defined as private in both classes. This helped to mask the bug (fixed in a previous commit) that disabled the extruder cooling fan. More subtly, the two drivers used to override slightly different subsets of Driver. This meant that my fix last night to stop toggling the DC motor controls didn't help the original Makerbot4G driver. Anyway, things are better now. --- .../gen3/Makerbot4GAlternateDriver.java | 154 +----------------- .../drivers/gen3/Makerbot4GDriver.java | 41 ++--- 2 files changed, 30 insertions(+), 165 deletions(-) diff --git a/src/replicatorg/drivers/gen3/Makerbot4GAlternateDriver.java b/src/replicatorg/drivers/gen3/Makerbot4GAlternateDriver.java index d1a5c4846..9d0cb2adc 100644 --- a/src/replicatorg/drivers/gen3/Makerbot4GAlternateDriver.java +++ b/src/replicatorg/drivers/gen3/Makerbot4GAlternateDriver.java @@ -1,14 +1,10 @@ package replicatorg.drivers.gen3; -import java.util.EnumMap; import java.util.Map; import java.util.Vector; -import java.util.logging.Level; import javax.vecmath.Point3d; -import org.w3c.dom.Element; - import replicatorg.app.Base; import replicatorg.drivers.RetryException; import replicatorg.machine.model.AxisId; @@ -17,21 +13,11 @@ import replicatorg.util.Point5d; public class Makerbot4GAlternateDriver extends Makerbot4GDriver { - - private boolean stepperExtruderFanEnabled = false; @Override public String getDriverName() { return "Makerbot4GAlternate"; } - @Override public void reset() { - // We should poll the machine for it's state here, but it is more important to have the - // fan on than off. - stepperExtruderFanEnabled = false; - - super.reset(); - } - /** * Overloaded to manage a hijacked axis and run this axis in relative mode instead of the extruder DC motor */ @@ -128,10 +114,10 @@ public class Makerbot4GAlternateDriver extends Makerbot4GDriver { } /** - * Each Axis can be overriden (hijacked) by XML settings. Return all overridden + * Each Axis can be overridden (hijacked) by XML settings. Return all overridden * axes associated with tool curTool. * @param curTool target tool to find overrides for - * @return a list of AxisId containing all overriden axis for tool curTool + * @return a list of AxisId containing all overridden axis for tool curTool */ protected Iterable getHijackedAxes(ToolModel curTool) { //NOTE: @@ -148,21 +134,6 @@ protected Iterable getHijackedAxes(ToolModel curTool) { } - /** - * Each Axis can be overriden (hijacked) by XML settings. Return all overridden - * axes for the currently loaded machine. - * @return a list of AxisId containing all overriden axis for the loaded machine profile - */ - protected Iterable getAllHijackedAxes() { - Vector axes = new Vector(); - - for ( Map.Entry entry : extruderHijackedMap.entrySet()) { - AxisId axis = entry.getKey(); - axes.add(axis); - } - return axes; - } - /** * Calculate and return the corresponding movement of any hijacked axes where the extruder is on. * The returned movement is in mm of incoming filament (corresponding to mm in machines.xml) @@ -223,24 +194,13 @@ private Point5d pointsFromHijackedAxes(ToolModel curTool, double minutes) { return steps; } - @Override public void stop(boolean abort) { - // Record the toolstate as off, so we don't excite the extruder motor in future moves. - machine.currentTool().disableMotor(); - - // We should stop the fan here, but it will be stopped for us by the super. - stepperExtruderFanEnabled = false; - - super.stop(abort); - } - protected void queueNewPoint(Point5d steps, long us, int relative) throws RetryException { - Base.logger.finer("Makerbot4GAlternateDriver queueNewPoint"); // Turn on fan if necessary for (AxisId axis : getHijackedAxes( machine.currentTool()) ) { if (steps.axis(axis) != 0) { - enableStepperExtruderFan(true); + enableStepperExtruderFan(true, machine.currentTool().getIndex()); } } PacketBuilder pb = new PacketBuilder(MotherboardCommandCode.QUEUE_POINT_NEW.getCode()); @@ -260,115 +220,17 @@ protected void queueNewPoint(Point5d steps, long us, int relative) throws RetryE runCommand(pb.getPacket()); } - - /** - * Overridden to not talk to the DC motor driver. This driver is reused for the stepper motor fan - */ - @Override public void enableMotor(int toolhead) throws RetryException { - if (toolhead == -1 ) toolhead = machine.currentTool().getIndex(); - machine.getTool(toolhead).enableMotor(); - } - - /** - * Overridden to not talk to the DC motor driver. This driver is reused for the stepper motor fan - */ - @Override public void disableMotor(int toolhead) throws RetryException { - if (toolhead == -1 ) toolhead = machine.currentTool().getIndex(); - - machine.getTool(toolhead).disableMotor(); - } - - /** - * Overridden to not talk to the DC motor driver. This driver is reused for the stepper motor fan - */ - @Override public void setMotorSpeedPWM(int pwm) throws RetryException { - machine.currentTool().setMotorSpeedPWM(pwm); - } - - /** - * Overridden to not talk to the DC motor driver. This driver is reused for the stepper motor fan - */ - @Override public void setMotorRPM(double rpm, int toolhead) throws RetryException { - machine.currentTool().setMotorSpeedRPM(rpm); - } - - @Override public void enableDrives() throws RetryException { - enableStepperExtruderFan(true); - - super.enableDrives(); - } - - @Override public void disableDrives() throws RetryException { - enableStepperExtruderFan(false); - - super.disableDrives(); - } - - /** - * Will turn on/off the stepper extruder fan if it's not already in the correct state. - * - */ - @Override public void enableStepperExtruderFan(boolean enabled) throws RetryException { - - // Always re-enable the fan when - if (this.stepperExtruderFanEnabled == enabled) return; - - // FIXME: Should be called per hijacked axis with the correct tool - // our flag variable starts with motors enabled. - byte flags = (byte) (enabled ? 1 : 0); - - // bit 1 determines direction... - flags |= 2; - - Base.logger.log(Level.FINE,"Stepper Extruder fan w/flags: " - + Integer.toBinaryString(flags)); - - // send it! - PacketBuilder pb = new PacketBuilder(MotherboardCommandCode.TOOL_COMMAND.getCode()); - pb.add8((byte) machine.currentTool().getIndex()); - pb.add8(ToolCommandCode.TOGGLE_MOTOR_1.getCode()); - pb.add8((byte) 1); // payload length - pb.add8(flags); - runCommand(pb.getPacket()); - - // Always use max PWM - pb = new PacketBuilder(MotherboardCommandCode.TOOL_COMMAND.getCode()); - pb.add8((byte) machine.currentTool().getIndex()); - pb.add8(ToolCommandCode.SET_MOTOR_1_PWM.getCode()); - pb.add8((byte) 1); // length of payload. - pb.add8((byte) 255); - runCommand(pb.getPacket()); - - this.stepperExtruderFanEnabled = enabled; - } - /// This is a list of which axis are hijacked for extruder use. - EnumMap extruderHijackedMap = new EnumMap(AxisId.class); - /** * When the machine is set for this driver, some toolheads may poach the an extrusion axis. */ @Override public void setMachine(MachineModel m) { super.setMachine(m); - for (ToolModel tm : m.getTools()) { - Element e = (Element)tm.getXml(); - if (e.hasAttribute("stepper_axis")) { - final String stepAxisStr = e.getAttribute("stepper_axis"); - try { - AxisId axis = AxisId.valueOf(stepAxisStr.toUpperCase()); - if (m.hasAxis(axis)) { - Base.logger.finer("seize the axis for extrusion! Hijacking axis "+axis.name()); - // If we're seizing an axis for an extruder, remove it from the available axes and get - // the data associated with that axis. - extruderHijackedMap.put(axis,tm); - m.getAvailableAxes().remove(axis); - } else { - Base.logger.severe("Tool claims unavailable axis "+axis.name()); - } - } catch (IllegalArgumentException iae) { - Base.logger.severe("Unintelligible axis designator "+stepAxisStr); - } - } + + // Curiously, this driver removes axes from the available list; + // the parent does not. + for (AxisId axis : extruderHijackedMap.keySet()) { + m.getAvailableAxes().remove(axis); } } diff --git a/src/replicatorg/drivers/gen3/Makerbot4GDriver.java b/src/replicatorg/drivers/gen3/Makerbot4GDriver.java index dc7eb06b6..707f1dce0 100644 --- a/src/replicatorg/drivers/gen3/Makerbot4GDriver.java +++ b/src/replicatorg/drivers/gen3/Makerbot4GDriver.java @@ -16,12 +16,14 @@ public class Makerbot4GDriver extends Sanguino3GDriver { - private boolean stepperExtruderFanEnabled = false; + protected boolean stepperExtruderFanEnabled = false; + @Override public String getDriverName() { return "Makerbot4G"; } + @Override public void reset() { // We should poll the machine for it's state here, but it is more important to have the // fan on than off. @@ -30,6 +32,7 @@ public void reset() { super.reset(); } + @Override public void stop(boolean abort) { // Record the toolstate as off, so we don't excite the extruder motor in future moves. machine.currentTool().disableMotor(); @@ -40,7 +43,7 @@ public void stop(boolean abort) { super.stop(abort); } - private Iterable getHijackedAxes(int toolhead){ + protected Iterable getHijackedAxes(int toolhead){ Vector axes = new Vector(); AxisId toolheadAxis = machine.getTool(toolhead).getMotorStepperAxis(); if( extruderHijackedMap.containsKey( toolheadAxis ) ) @@ -65,9 +68,11 @@ private Iterable getHijackedAxes(int toolhead){ // } /** - * Returns the hijacked axes for all tools. + * Each Axis can be overridden (hijacked) by XML settings. Return all overridden + * axes for the currently loaded machine. + * @return a list of AxisId containing all overridden axis for the loaded machine profile */ - private Iterable getAllHijackedAxes() { + protected Iterable getAllHijackedAxes() { Vector axes = new Vector(); for ( Map.Entry entry : extruderHijackedMap.entrySet()) { AxisId axis = entry.getKey(); @@ -77,6 +82,7 @@ private Iterable getAllHijackedAxes() { } /** relies on currentTool too much **/ + @Override @Deprecated protected void queueAbsolutePoint(Point5d steps, long micros) throws RetryException { // Turn on fan if necessary @@ -105,6 +111,7 @@ protected void queueAbsolutePoint(Point5d steps, long micros) throws RetryExcept runCommand(pb.getPacket()); } + @Override public void setCurrentPosition(Point5d p) throws RetryException { PacketBuilder pb = new PacketBuilder(MotherboardCommandCode.SET_POSITION_EXT.getCode()); @@ -125,6 +132,7 @@ public void setCurrentPosition(Point5d p) throws RetryException { // super.setCurrentPosition(p); } + @Override protected Point5d reconcilePosition() { // If we're writing to a file, we can't actually know what the current position is. if (fileCaptureOstream != null) { @@ -149,22 +157,23 @@ protected Point5d reconcilePosition() { /** * Overridden to not talk to the DC motor driver. This driver is reused for the stepper motor fan */ - public void enableMotor() throws RetryException { - Base.logger.fine("MakerBot4G.enableMotor()");//REMOVE + @Override public void enableMotor(int toolhead) throws RetryException { + if (toolhead == -1 ) toolhead = machine.currentTool().getIndex(); machine.currentTool().enableMotor(); } /** * Overridden to not talk to the DC motor driver. This driver is reused for the stepper motor fan */ - public void disableMotor() throws RetryException { - Base.logger.fine("MakerBot4G.enableMotor()"); //REMOVE + @Override public void disableMotor(int toolhead) throws RetryException { + if (toolhead == -1 ) toolhead = machine.currentTool().getIndex(); machine.currentTool().disableMotor(); } /** * Overridden to not talk to the DC motor driver. This driver is reused for the stepper motor fan */ + @Override public void setMotorSpeedPWM(int pwm) throws RetryException { machine.currentTool().setMotorSpeedPWM(pwm); } @@ -172,6 +181,7 @@ public void setMotorSpeedPWM(int pwm) throws RetryException { /** * Overridden to not talk to the DC motor driver. This driver is reused for the stepper motor fan */ + @Override public void setMotorRPM(double rpm, int toolhead) throws RetryException { if (toolhead == -1) { machine.currentTool().setMotorSpeedRPM(rpm); @@ -181,26 +191,20 @@ public void setMotorRPM(double rpm, int toolhead) throws RetryException { } + @Override public void enableDrives() throws RetryException { enableStepperExtruderFan(true,machine.currentTool().getIndex()); super.enableDrives(); } + @Override public void disableDrives() throws RetryException { enableStepperExtruderFan(false,machine.currentTool().getIndex()); super.disableDrives(); } - /** - * Due to async command dispatch, this version should not be called. - */ - @Deprecated - public void enableStepperExtruderFan(boolean enabled) throws RetryException { - enableStepperExtruderFan(enabled, machine.currentTool().getIndex()); - } - /** * Will turn on/off the stepper extruder fan if it's not already in the correct state. * @@ -239,14 +243,13 @@ public void enableStepperExtruderFan(boolean enabled, int toolIndex) throws Retr this.stepperExtruderFanEnabled = enabled; } - EnumMap extruderHijackedMap = new EnumMap(AxisId.class); + protected EnumMap extruderHijackedMap = new EnumMap(AxisId.class); - @Override /** * When the machine is set for this driver, some toolheads may poach the an extrusion axis. */ - public void setMachine(MachineModel m) { + @Override public void setMachine(MachineModel m) { super.setMachine(m); for (ToolModel tm : m.getTools()) { Element e = (Element)tm.getXml(); From 5ea1e1c804af7b8b14cbc2640d5decc98ca8a3ae Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Fri, 9 Mar 2012 10:30:48 -0800 Subject: [PATCH 08/35] @Deprecated/@Override cleanup in Driver classes. I've deprecated some new methods on Driver. These methods -- or, more specifically, the fact that two versions of each of these methods existed -- hid the stepper fan bug I fixed in a previous commit. Interestingly, many of the Driver implementations deprecated these methods, but the annotations never got propagated back to the interface, and so some were missed. At the same time, I added @Override where appropriate to a subset of the Driver classes (those I use). The interesting thing about that change is the methods that *didn't* get @Override. Driver defines no multiple-tool-aware version of e.g. getMotorRPM, but some of the drivers attempt to override it...resulting in dead code. To be fixed in a subsequent commit. --- src/replicatorg/drivers/Driver.java | 20 +- .../drivers/DriverBaseImplementation.java | 182 +++++++++--------- src/replicatorg/drivers/SerialDriver.java | 22 +-- .../drivers/gen3/Sanguino3GDriver.java | 180 ++++++++--------- 4 files changed, 202 insertions(+), 202 deletions(-) diff --git a/src/replicatorg/drivers/Driver.java b/src/replicatorg/drivers/Driver.java index 815fae3d9..59dfd7fc6 100644 --- a/src/replicatorg/drivers/Driver.java +++ b/src/replicatorg/drivers/Driver.java @@ -270,12 +270,12 @@ public interface Driver { /*************************************************************************** * Motor interface functions **************************************************************************/ - public void setMotorDirection(int dir); + @Deprecated public void setMotorDirection(int dir); public void setMotorDirection(int dir, int toolhead); public void setMotorRPM(double rpm, int toolhead) throws RetryException; - public void setMotorSpeedPWM(int pwm) throws RetryException; + @Deprecated public void setMotorSpeedPWM(int pwm) throws RetryException; public void setMotorSpeedPWM(int pwm, int toolhead) throws RetryException; public double getMotorRPM(); @@ -286,17 +286,17 @@ public interface Driver { * Enable motor until stopped by disableMotor * @throws RetryException */ - public void enableMotor() throws RetryException; + @Deprecated public void enableMotor() throws RetryException; public void enableMotor(int toolhead) throws RetryException; /** * Enable motor for a fixed duration, then disable * @throws RetryException */ - public void enableMotor(long millis) throws RetryException; + @Deprecated public void enableMotor(long millis) throws RetryException; public void enableMotor(long millis, int toolhead) throws RetryException; - public void disableMotor() throws RetryException; + @Deprecated public void disableMotor() throws RetryException; public void disableMotor(int toolhead) throws RetryException; /*************************************************************************** @@ -321,7 +321,7 @@ public interface Driver { * Temperature interface functions * @throws RetryException **************************************************************************/ - public void setTemperature(double temperature) throws RetryException; + @Deprecated public void setTemperature(double temperature) throws RetryException; public void setTemperature(double temperature, int toolIndex) throws RetryException; public void readTemperature(); @@ -333,7 +333,7 @@ public interface Driver { * Platform Temperature interface functions * @throws RetryException **************************************************************************/ - public void setPlatformTemperature(double temperature) throws RetryException; + @Deprecated public void setPlatformTemperature(double temperature) throws RetryException; public void setPlatformTemperature(double temperature, int toolIndex) throws RetryException; public void readPlatformTemperature(); @@ -369,10 +369,10 @@ public interface Driver { * Fan interface functions * @throws RetryException **************************************************************************/ - public void enableFan() throws RetryException; + @Deprecated public void enableFan() throws RetryException; public void enableFan(int toolhead) throws RetryException; - public void disableFan() throws RetryException; + @Deprecated public void disableFan() throws RetryException; public void disableFan(int toolhead) throws RetryException; @@ -380,7 +380,7 @@ public interface Driver { * abp interface functions * @throws RetryException **************************************************************************/ - public void setAutomatedBuildPlatformRunning(boolean state) throws RetryException; + @Deprecated public void setAutomatedBuildPlatformRunning(boolean state) throws RetryException; public void setAutomatedBuildPlatformRunning(boolean state, int toolhead) throws RetryException; /*************************************************************************** diff --git a/src/replicatorg/drivers/DriverBaseImplementation.java b/src/replicatorg/drivers/DriverBaseImplementation.java index 1828c9b7b..418465fdc 100644 --- a/src/replicatorg/drivers/DriverBaseImplementation.java +++ b/src/replicatorg/drivers/DriverBaseImplementation.java @@ -101,13 +101,13 @@ public DriverBaseImplementation() { machine = new MachineModel(); } - public void loadXML(Node xml) { + @Override public void loadXML(Node xml) { } - public void updateManualControl() { + @Override public void updateManualControl() { } - public boolean isPassthroughDriver() { + @Override public boolean isPassthroughDriver() { return false; } @@ -115,11 +115,11 @@ public boolean isPassthroughDriver() { * Execute a line of GCode directly (ie, don't use the parser) * @param code The line of GCode that we should execute */ - public void executeGCodeLine(String code) { + @Override public void executeGCodeLine(String code) { Base.logger.severe("Ignoring executeGCode command: " + code); } - public void dispose() { + @Override public void dispose() { if (Base.logger.isLoggable(Level.FINE)) { Base.logger.fine("Disposing of driver " + getDriverName()); } @@ -130,11 +130,11 @@ public void dispose() { * Initialization handling functions **************************************************************************/ - public void initialize() { + @Override public void initialize() { setInitialized(true); } - public void uninitialize() { + @Override public void uninitialize() { setInitialized(false); } @@ -146,7 +146,7 @@ public void setInitialized(boolean status) { } } - public boolean isInitialized() { + @Override public boolean isInitialized() { return isInitialized.get(); } @@ -154,7 +154,7 @@ public boolean isInitialized() { * Error handling functions **************************************************************************/ - public void assessState() { + @Override public void assessState() { } protected void setError(DriverError newError) { @@ -166,15 +166,15 @@ protected void setError(String e) { } - public boolean hasError() { + @Override public boolean hasError() { return (errorList.size() > 0); } - public DriverError getError() { + @Override public DriverError getError() { return errorList.remove(); } - @Deprecated + @Override @Deprecated public void checkErrors() throws BuildFailureException { if (errorList.size() > 0) { throw new BuildFailureException(getError().getMessage()); @@ -182,7 +182,7 @@ public void checkErrors() throws BuildFailureException { } - public boolean isFinished() { + @Override public boolean isFinished() { return true; } @@ -193,7 +193,7 @@ public boolean isFinished() { /** * Is our buffer empty? If don't have a buffer, its always true. */ - public boolean isBufferEmpty() { + @Override public boolean isBufferEmpty() { return true; } @@ -201,7 +201,7 @@ public boolean isBufferEmpty() { * Firmware information functions **************************************************************************/ - public String getFirmwareInfo() { + @Override public String getFirmwareInfo() { return firmwareName + " v" + getVersion(); } @@ -211,15 +211,15 @@ public String getBotName(){ return "Unnamed Bot (a Sad Bot)"; } - public Version getVersion() { + @Override public Version getVersion() { return version; } - public Version getMinimumVersion() { + @Override public Version getMinimumVersion() { return minimumVersion; } - public Version getPreferredVersion() { + @Override public Version getPreferredVersion() { return preferredVersion; } @@ -227,26 +227,26 @@ public Version getPreferredVersion() { * Machine positioning functions **************************************************************************/ - public Point3d getOffset(int i) { + @Override public Point3d getOffset(int i) { return offsets[i]; } - public void setOffsetX(int offsetSystemNum, double j) { + @Override public void setOffsetX(int offsetSystemNum, double j) { offsets[offsetSystemNum].x = j; } - public void setOffsetY(int offsetSystemNum, double j) { + @Override public void setOffsetY(int offsetSystemNum, double j) { offsets[offsetSystemNum].y = j; } - public void setOffsetZ(int offsetSystemNum, double j) { + @Override public void setOffsetZ(int offsetSystemNum, double j) { offsets[offsetSystemNum].z = j; } protected final AtomicReference currentPosition = new AtomicReference(null); - public void setCurrentPosition(Point5d p) throws RetryException { + @Override public void setCurrentPosition(Point5d p) throws RetryException { currentPosition.set(p); } @@ -254,7 +254,7 @@ public void setCurrentPosition(Point5d p) throws RetryException { * Indicate that the currently maintained position may no longer be the machine's position, * and that the machine should be queried for its actual location. */ - public void invalidatePosition() { + @Override public void invalidatePosition() { // System.err.println("invalidating position."); currentPosition.set(null); } @@ -270,7 +270,7 @@ protected Point5d reconcilePosition() throws RetryException { /** * @return true if the machine position is unknown */ - public boolean positionLost() { + @Override public boolean positionLost() { return (currentPosition.get() == null); } @@ -282,7 +282,7 @@ public boolean positionLost() { * * Side effects: currentPosition will be updated with the current position if the machine position is successfully polled. */ - public Point5d getCurrentPosition(boolean forceUpdate) { + @Override public Point5d getCurrentPosition(boolean forceUpdate) { synchronized(currentPosition) { // If we are lost, or an explicit update has been requested, poll the machine for it's state. @@ -306,7 +306,7 @@ public Point5d getCurrentPosition(boolean forceUpdate) { } } - public Point5d getPosition() { + @Override public Point5d getPosition() { return getCurrentPosition(false); } @@ -315,7 +315,7 @@ public Point5d getPosition() { * @param p The point, in mm. * @throws RetryException */ - public void queuePoint(Point5d p) throws RetryException { + @Override public void queuePoint(Point5d p) throws RetryException { setInternalPosition(p); } @@ -326,14 +326,14 @@ protected void setInternalPosition(Point5d position) { /** * sets the feedrate in mm/minute */ - public void setFeedrate(double feed) { + @Override public void setFeedrate(double feed) { currentFeedrate = feed; } /** * gets the feedrate in mm/minute */ - public double getCurrentFeedrate() { + @Override public double getCurrentFeedrate() { return currentFeedrate; } @@ -393,17 +393,17 @@ public Point5d getDelta(Point5d p) { * various homing functions * @throws RetryException **************************************************************************/ - public void homeAxes(EnumSet axes, boolean positive, double feedrate) throws RetryException { + @Override public void homeAxes(EnumSet axes, boolean positive, double feedrate) throws RetryException { } /*************************************************************************** * Machine interface functions **************************************************************************/ - public MachineModel getMachine() { + @Override public MachineModel getMachine() { return machine; } - public void setMachine(MachineModel m) { + @Override public void setMachine(MachineModel m) { machine = m; } @@ -411,11 +411,11 @@ public void setMachine(MachineModel m) { * Tool interface functions * @throws RetryException **************************************************************************/ - public void requestToolChange(int toolIndex, int timeout) throws RetryException { + @Override public void requestToolChange(int toolIndex, int timeout) throws RetryException { machine.selectTool(toolIndex); } - public void selectTool(int toolIndex) throws RetryException { + @Override public void selectTool(int toolIndex) throws RetryException { machine.selectTool(toolIndex); } @@ -423,7 +423,7 @@ public void selectTool(int toolIndex) throws RetryException { * pause function * @throws RetryException **************************************************************************/ - public void delay(long millis) throws RetryException { + @Override public void delay(long millis) throws RetryException { // System.out.println("Delay: " + millis); } @@ -431,11 +431,11 @@ public void delay(long millis) throws RetryException { /*************************************************************************** * functions for dealing with clamps **************************************************************************/ - public void openClamp(int index) { + @Override public void openClamp(int index) { machine.getClamp(index).open(); } - public void closeClamp(int index) { + @Override public void closeClamp(int index) { machine.getClamp(index).close(); } @@ -443,19 +443,19 @@ public void closeClamp(int index) { * enabling/disabling our drivers (steppers, servos, etc.) * @throws RetryException **************************************************************************/ - public void enableDrives() throws RetryException { + @Override public void enableDrives() throws RetryException { machine.enableDrives(); } - public void disableDrives() throws RetryException { + @Override public void disableDrives() throws RetryException { machine.disableDrives(); } - public void enableAxes(EnumSet axes) throws RetryException { + @Override public void enableAxes(EnumSet axes) throws RetryException { // Not all drivers support this method. } - public void disableAxes(EnumSet axes) throws RetryException { + @Override public void disableAxes(EnumSet axes) throws RetryException { // Not all drivers support this method. } @@ -463,7 +463,7 @@ public void disableAxes(EnumSet axes) throws RetryException { * Change our gear ratio. **************************************************************************/ - public void changeGearRatio(int ratioIndex) { + @Override public void changeGearRatio(int ratioIndex) { machine.changeGearRatio(ratioIndex); } @@ -474,7 +474,7 @@ public void changeGearRatio(int ratioIndex) { /*************************************************************************** * Motor interface functions **************************************************************************/ - public void setMotorDirection(int dir) { + @Override public void setMotorDirection(int dir) { this.setMotorDirection(machine.currentTool().getIndex()); } @@ -501,7 +501,7 @@ public void setMotorSpeedPWM(int pwm) throws RetryException { this.setMotorSpeedPWM(pwm, machine.currentTool().getIndex()); } - public void setMotorSpeedPWM(int pwm, int toolhead) throws RetryException { + @Override public void setMotorSpeedPWM(int pwm, int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -539,7 +539,7 @@ public void enableMotor(int toolhead) throws RetryException { - public void disableMotor(int toolhead) throws RetryException { + @Override public void disableMotor(int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -552,11 +552,11 @@ public void disableMotor() throws RetryException { } - public double getMotorRPM() { + @Override public double getMotorRPM() { return machine.currentTool().getMotorSpeedRPM(); } - public int getMotorSpeedPWM() { + @Override public int getMotorSpeedPWM() { return machine.currentTool().getMotorSpeedReadingPWM(); } @@ -565,10 +565,10 @@ public double getMotorSteps() { } // TODO: These are backwards? - public void readToolStatus() { + @Override public void readToolStatus() { } - public int getToolStatus() { + @Override public int getToolStatus() { readToolStatus(); return machine.currentTool().getToolStatus(); @@ -578,23 +578,23 @@ public int getToolStatus() { /*************************************************************************** * Spindle interface functions **************************************************************************/ - public void setSpindleDirection(int dir) { + @Override public void setSpindleDirection(int dir) { machine.currentTool().setSpindleDirection(dir); } - public void setSpindleRPM(double rpm) throws RetryException { + @Override public void setSpindleRPM(double rpm) throws RetryException { setSpindleRPM(rpm, -1); } - public void setSpindleSpeedPWM(int pwm) throws RetryException { + @Override public void setSpindleSpeedPWM(int pwm) throws RetryException { setSpindleSpeedPWM(pwm, -1); } - public void enableSpindle() throws RetryException { + @Override public void enableSpindle() throws RetryException { enableSpindle(-1); } - public void disableSpindle() throws RetryException { + @Override public void disableSpindle() throws RetryException { disableSpindle(-1); } public void setSpindleRPM(double rpm, int toolhead) throws RetryException { @@ -625,11 +625,11 @@ public void disableSpindle(int toolhead) throws RetryException { machine.getTool(toolhead).disableSpindle(); } - public double getSpindleRPM() { + @Override public double getSpindleRPM() { return machine.currentTool().getSpindleSpeedReadingRPM(); } - public int getSpindleSpeedPWM() { + @Override public int getSpindleSpeedPWM() { return machine.currentTool().getSpindleSpeedReadingPWM(); } @@ -650,7 +650,7 @@ public void setTemperature(double temperature, int toolhead) throws RetryExcepti machine.getTool(toolhead).setTargetTemperature(temperature); } - public void readTemperature() { + @Override public void readTemperature() { } public void readTemperature(int toolhead) { @@ -690,7 +690,7 @@ public void setPlatformTemperature(double temperature, int toolhead) throws Retr } /** relies on timing to have the 'right selected toolhead', deprecated */ - @Deprecated + @Override @Deprecated public void readPlatformTemperature() { this.readPlatformTemperature(-1); } @@ -708,7 +708,7 @@ public double getPlatformTemperature() { return this.getPlatformTemperature(-1); } - public double getPlatformTemperature(int toolhead) { + @Override public double getPlatformTemperature(int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -719,22 +719,22 @@ public double getPlatformTemperature(int toolhead) { /*************************************************************************** * Flood Coolant interface functions **************************************************************************/ - public void enableFloodCoolant() { + @Override public void enableFloodCoolant() { machine.currentTool().enableFloodCoolant(); } - public void disableFloodCoolant() { + @Override public void disableFloodCoolant() { machine.currentTool().disableFloodCoolant(); } /*************************************************************************** * Mist Coolant interface functions **************************************************************************/ - public void enableMistCoolant() { + @Override public void enableMistCoolant() { machine.currentTool().enableMistCoolant(); } - public void disableMistCoolant() { + @Override public void disableMistCoolant() { machine.currentTool().disableMistCoolant(); } @@ -742,7 +742,7 @@ public void disableMistCoolant() { * Fan interface functions * @throws RetryException **************************************************************************/ - public void enableFan() throws RetryException { + @Override public void enableFan() throws RetryException { this.enableFan(machine.currentTool().getIndex()); } @Override @@ -753,7 +753,7 @@ public void enableFan(int toolhead) throws RetryException { } - public void disableFan() throws RetryException { + @Override public void disableFan() throws RetryException { this.disableFan(machine.currentTool().getIndex()); } @@ -765,7 +765,7 @@ public void disableFan(int toolhead) throws RetryException { } - public void setAutomatedBuildPlatformRunning(boolean state) throws RetryException { + @Override public void setAutomatedBuildPlatformRunning(boolean state) throws RetryException { this.setAutomatedBuildPlatformRunning(state, machine.currentTool().getIndex()); } @Override @@ -777,7 +777,7 @@ public void setAutomatedBuildPlatformRunning(boolean state, int toolhead) } - public boolean hasAutomatedBuildPlatform() + @Override public boolean hasAutomatedBuildPlatform() { return hasAutomatedBuildPlatform(-1); } @@ -793,11 +793,11 @@ public boolean hasAutomatedBuildPlatform(int toolhead) * Valve interface functions * @throws RetryException **************************************************************************/ - public void openValve() throws RetryException { + @Override public void openValve() throws RetryException { openValve(-1); } - public void closeValve() throws RetryException { + @Override public void closeValve() throws RetryException { closeValve(-1); } public void openValve(int toolhead) throws RetryException { @@ -810,7 +810,7 @@ public void closeValve(int toolhead) throws RetryException { machine.getTool(toolhead).closeValve(); } - public void setStepperVoltage(int stepperId, int referenceValue) throws RetryException + @Override public void setStepperVoltage(int stepperId, int referenceValue) throws RetryException { Base.logger.fine("BaseImplementation setStepperVoltage called."); } @@ -820,20 +820,20 @@ public void setStepperVoltage(int stepperId, int referenceValue) throws RetryExc // Base.logger.fine("BaseImplementation setStepperVoltage called."); // } - public int getStepperVoltage(int stepperId) + @Override public int getStepperVoltage(int stepperId) { Base.logger.fine("BaseImplementation getStepperVoltage called."); return -1; } - public void setLedStrip(Color color, int effectId) throws RetryException + @Override public void setLedStrip(Color color, int effectId) throws RetryException { Base.logger.fine("BaseImplementation setLedStrip called."); } - public void sendBeep(int frequencyHz, int durationMs,int effect) throws RetryException + @Override public void sendBeep(int frequencyHz, int durationMs,int effect) throws RetryException { Base.logger.fine("BaseImplementation sendBeep called."); } @@ -841,76 +841,76 @@ public void sendBeep(int frequencyHz, int durationMs,int effect) throws RetryExc /*************************************************************************** * Collet interface functions **************************************************************************/ - public void openCollet() { + @Override public void openCollet() { machine.currentTool().openCollet(); } - public void closeCollet() { + @Override public void closeCollet() { machine.currentTool().closeCollet(); } /*************************************************************************** * Pause/unpause functionality for asynchronous devices **************************************************************************/ - public void pause() { + @Override public void pause() { // No implementation needed for synchronous machines. } - public void unpause() { + @Override public void unpause() { // No implementation needed for synchronous machines. } /*************************************************************************** * Stop and system state reset **************************************************************************/ - public void stop(boolean abort) { + @Override public void stop(boolean abort) { // No implementation needed for synchronous machines. Base.logger.info("Machine stop called."); } - public void reset() { + @Override public void reset() { // No implementation needed for synchronous machines. Base.logger.info("Machine reset called."); } - public String getDriverName() { + @Override public String getDriverName() { return null; } - public boolean heartbeat() { + @Override public boolean heartbeat() { return true; } - public double getChamberTemperature() { + @Override public double getChamberTemperature() { return 0; } - public void readChamberTemperature() { + @Override public void readChamberTemperature() { } - public void setChamberTemperature(double temperature) { + @Override public void setChamberTemperature(double temperature) { } - public double getPlatformTemperatureSetting() { + @Override public double getPlatformTemperatureSetting() { return machine.currentTool().getPlatformTargetTemperature(); } - public double getTemperatureSetting() { + @Override public double getTemperatureSetting() { return machine.currentTool().getTargetTemperature(); } - public void storeHomePositions(EnumSet axes) throws RetryException { + @Override public void storeHomePositions(EnumSet axes) throws RetryException { } - public void recallHomePositions(EnumSet axes) throws RetryException { + @Override public void recallHomePositions(EnumSet axes) throws RetryException { } - public boolean hasSoftStop() { + @Override public boolean hasSoftStop() { return hasSoftStop; } - public boolean hasEmergencyStop() { + @Override public boolean hasEmergencyStop() { return hasEmergencyStop; } diff --git a/src/replicatorg/drivers/SerialDriver.java b/src/replicatorg/drivers/SerialDriver.java index 562eb33b6..2bcd3a7a6 100644 --- a/src/replicatorg/drivers/SerialDriver.java +++ b/src/replicatorg/drivers/SerialDriver.java @@ -49,7 +49,7 @@ protected SerialDriver() { stopbits = Base.preferences.getInt("serial.stopbits",1); } - public void loadXML(Node xml) { + @Override public void loadXML(Node xml) { super.loadXML(xml); // load from our XML config, if we have it. if (XML.hasChildNode(xml, "portname")) { @@ -66,7 +66,7 @@ public void loadXML(Node xml) { stopbits = Integer.parseInt(XML.getChildNodeValue(xml, "stopbits")); } - public synchronized void openSerial(String portName) { + @Override public synchronized void openSerial(String portName) { // Grab a lock serialLock.writeLock().lock(); @@ -105,7 +105,7 @@ public synchronized void openSerial(String portName) { } // TODO: Move all of this to a new object that causes this when it is destroyed. - public void closeSerial() { + @Override public void closeSerial() { serialLock.writeLock().lock(); if (serial != null) serial.dispose(); @@ -113,35 +113,35 @@ public void closeSerial() { serialLock.writeLock().unlock(); } - public boolean isConnected() { + @Override public boolean isConnected() { return (this.serial != null && this.serial.isConnected()); } - public char getParity() { + @Override public char getParity() { return parity; } - public String getPortName() { + @Override public String getPortName() { return portName; } - public int getDataBits() { + @Override public int getDataBits() { return databits; } - public int getRate() { + @Override public int getRate() { return rate; } - public float getStopBits() { + @Override public float getStopBits() { return stopbits; } - public boolean isExplicit() { + @Override public boolean isExplicit() { return explicit; } - public void dispose() { + @Override public void dispose() { closeSerial(); super.dispose(); } diff --git a/src/replicatorg/drivers/gen3/Sanguino3GDriver.java b/src/replicatorg/drivers/gen3/Sanguino3GDriver.java index b0bc4e90b..f45f21c60 100644 --- a/src/replicatorg/drivers/gen3/Sanguino3GDriver.java +++ b/src/replicatorg/drivers/gen3/Sanguino3GDriver.java @@ -121,12 +121,12 @@ public Sanguino3GDriver() { setInitialized(false); } - public void loadXML(Node xml) { + @Override public void loadXML(Node xml) { super.loadXML(xml); } - public void initialize() { + @Override public void initialize() { Base.logger.fine("Attempting to initialize device"); // Assert: serial port present. @@ -204,7 +204,7 @@ private boolean attemptConnection() { return isInitialized(); } - public void assessState() { + @Override public void assessState() { // If we are supposed to have a serial connection, see if it is still // active if (isInitialized() && !serial.isConnected()) { @@ -287,7 +287,7 @@ protected PacketResponse runQuery(byte[] packet) { } //// Get a list of all toolheads we save onboard preferences for - public List toolheadsWithStoredData() + @Override public List toolheadsWithStoredData() { Vector tools = this.getMachine().getTools(); Vector toolsList = new Vector(); @@ -449,7 +449,7 @@ protected PacketResponse runCommand(byte[] packet, int retries) static boolean isNotifiedFinishedFeature = false; - public boolean isFinished() { + @Override public boolean isFinished() { if (fileCaptureOstream != null) { return true; } // always done instantly if writing to file @@ -475,7 +475,7 @@ public boolean isFinished() { - public boolean isBufferEmpty() { + @Override public boolean isBufferEmpty() { // TODO: Make sure this is right PacketBuilder pb = new PacketBuilder( MotherboardCommandCode.IS_FINISHED.getCode()); @@ -497,7 +497,7 @@ public boolean isBufferEmpty() { return finished; } - public void dispose() { + @Override public void dispose() { super.dispose(); } @@ -543,7 +543,7 @@ public Version getVersionInternal() { } - public CommunicationStatistics getCommunicationStatistics() { + @Override public CommunicationStatistics getCommunicationStatistics() { CommunicationStatistics stats = new CommunicationStatistics(); PacketBuilder pb = new PacketBuilder( @@ -657,7 +657,7 @@ public void sendInit() { * @throws RetryException **************************************************************************/ - public void queuePoint(Point5d p) throws RetryException { + @Override public void queuePoint(Point5d p) throws RetryException { // TODO: check if our current position is valid? Base.logger.finer("Queued point " + p); @@ -734,7 +734,7 @@ protected void queueAbsolutePoint(Point5d steps, long micros) runCommand(pb.getPacket()); } - public void setCurrentPosition(Point5d p) throws RetryException { + @Override public void setCurrentPosition(Point5d p) throws RetryException { // System.err.println(" SCP: "+p.toString()+ // " (current "+getCurrentPosition().toString()+")"); // if (super.getCurrentPosition().equals(p)) return; @@ -758,7 +758,7 @@ public void setCurrentPosition(Point5d p) throws RetryException { /// TODO: this says it homes the first three axes, but it actually homes /// whatever's passed /// Homes the three first axes - public void homeAxes(EnumSet axes, boolean positive, double feedrate) + @Override public void homeAxes(EnumSet axes, boolean positive, double feedrate) throws RetryException { Base.logger.fine("Homing axes " + axes.toString()); byte flags = 0x00; @@ -798,7 +798,7 @@ public void homeAxes(EnumSet axes, boolean positive, double feedrate) invalidatePosition(); } - public void delay(long millis) throws RetryException { + @Override public void delay(long millis) throws RetryException { Base.logger.finer("Delaying " + millis + " millis."); Base.logger.fine("Sanguino3GDriver.enableMotor()");//REMOVE: @@ -809,17 +809,17 @@ public void delay(long millis) throws RetryException { runCommand(pb.getPacket()); } - public void openClamp(int clampIndex) { + @Override public void openClamp(int clampIndex) { // TODO: throw some sort of unsupported exception. super.openClamp(clampIndex); } - public void closeClamp(int clampIndex) { + @Override public void closeClamp(int clampIndex) { // TODO: throw some sort of unsupported exception. super.closeClamp(clampIndex); } - public void enableDrives() throws RetryException { + @Override public void enableDrives() throws RetryException { // Command RMB to enable its steppers. Note that they are // already automagically enabled by most commands and need // not be explicitly enabled. @@ -830,7 +830,7 @@ public void enableDrives() throws RetryException { super.enableDrives(); } - public void disableDrives() throws RetryException { + @Override public void disableDrives() throws RetryException { // Command RMB to disable its steppers. PacketBuilder pb = new PacketBuilder( MotherboardCommandCode.ENABLE_AXES.getCode()); @@ -860,7 +860,7 @@ private int axesToBitfield(EnumSet axes) { * already automagically enabled by most commands and need * not be explicitly enabled. */ - public void enableAxes(EnumSet axes) throws RetryException { + @Override public void enableAxes(EnumSet axes) throws RetryException { PacketBuilder pb = new PacketBuilder( MotherboardCommandCode.ENABLE_AXES.getCode()); pb.add8(0x80 + (axesToBitfield(axes) & 0x1f)); // enable axes @@ -869,7 +869,7 @@ public void enableAxes(EnumSet axes) throws RetryException { } /// Command machine to disable some steppers. - public void disableAxes(EnumSet axes) throws RetryException { + @Override public void disableAxes(EnumSet axes) throws RetryException { PacketBuilder pb = new PacketBuilder( MotherboardCommandCode.ENABLE_AXES.getCode()); pb.add8(axesToBitfield(axes) & 0x1f); // disable axes @@ -877,7 +877,7 @@ public void disableAxes(EnumSet axes) throws RetryException { super.disableAxes(axes); } - public void changeGearRatio(int ratioIndex) { + @Override public void changeGearRatio(int ratioIndex) { // TODO: throw some sort of unsupported exception. super.changeGearRatio(ratioIndex); } @@ -890,7 +890,7 @@ public void changeGearRatio(int ratioIndex) { * timeout is given in seconds. If the tool isn't ready by then, the machine * will continue anyway. */ - public void requestToolChange(int toolhead, int timeout) + @Override public void requestToolChange(int toolhead, int timeout) throws RetryException { selectTool(toolhead); @@ -926,7 +926,7 @@ public void requestToolChange(int toolhead, int timeout) } - public void selectTool(int toolIndex) throws RetryException { + @Override public void selectTool(int toolIndex) throws RetryException { Base.logger.fine("Selecting tool #" + toolIndex); // send it! @@ -942,7 +942,7 @@ public void selectTool(int toolIndex) throws RetryException { /*************************************************************************** * Motor interface functions **************************************************************************/ - public void setMotorRPM(double rpm, int toolhead) throws RetryException { + @Override public void setMotorRPM(double rpm, int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -973,12 +973,12 @@ public void setMotorRPM(double rpm, int toolhead) throws RetryException { } - public void setMotorSpeedPWM(int pwm) throws RetryException { + @Override public void setMotorSpeedPWM(int pwm) throws RetryException { this.setMotorSpeedPWM(pwm, machine.currentTool().getIndex()); } - public void setMotorSpeedPWM(int pwm, int toolhead) throws RetryException { + @Override public void setMotorSpeedPWM(int pwm, int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -1003,7 +1003,7 @@ public void setMotorSpeedPWM(int pwm, int toolhead) throws RetryException { super.setMotorSpeedPWM(pwm, toolhead); } - public void enableMotor(int toolhead) throws RetryException { + @Override public void enableMotor(int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) @@ -1077,7 +1077,7 @@ public int getMotorSpeedPWM(int toolhead) { return pwm; } - public double getMotorRPM() + @Override public double getMotorRPM() { return getMotorRPM(machine.currentTool().getIndex()); } @@ -1194,7 +1194,7 @@ public void readToolPIDState(int toolhead) { // public void disableServo() {} - @Deprecated + @Override @Deprecated public void setServoPos(int index, double degree) throws RetryException { this.setServoPos(index, degree, machine.currentTool().getIndex()); } @@ -1247,7 +1247,7 @@ public void setServoPos(int index, double degree, int toolhead) throws RetryExce /*************************************************************************** * Spindle interface functions **************************************************************************/ - public void setSpindleRPM(double rpm, int toolhead) throws RetryException { + @Override public void setSpindleRPM(double rpm, int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -1273,7 +1273,7 @@ public void setSpindleRPM(double rpm, int toolhead) throws RetryException { super.setSpindleRPM(rpm, toolhead); } - public void setSpindleSpeedPWM(int pwm, int toolhead) throws RetryException { + @Override public void setSpindleSpeedPWM(int pwm, int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -1292,7 +1292,7 @@ public void setSpindleSpeedPWM(int pwm, int toolhead) throws RetryException { super.setSpindleSpeedPWM(pwm, toolhead); } - public void enableSpindle(int toolhead) throws RetryException { + @Override public void enableSpindle(int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -1319,7 +1319,7 @@ public void enableSpindle(int toolhead) throws RetryException { super.enableSpindle(toolhead); } - public void disableSpindle(int toolhead) throws RetryException { + @Override public void disableSpindle(int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -1392,7 +1392,7 @@ public int getSpindleSpeedPWM(int toolhead) { * Temperature interface functions * @throws RetryException **************************************************************************/ - public void setTemperature(double temperature, int toolhead) throws RetryException { + @Override public void setTemperature(double temperature, int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -1424,7 +1424,7 @@ public void readAllTemperatures() { } } - public void readTemperature(int toolhead) + @Override public void readTemperature(int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. @@ -1460,7 +1460,7 @@ else if (pr.isEmpty()) * @throws RetryException **************************************************************************/ - public void setPlatformTemperature(double temperature, int toolhead) throws RetryException { + @Override public void setPlatformTemperature(double temperature, int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -1489,7 +1489,7 @@ public void setAllPlatformTemperatures(double temperature) throws RetryException } } - public void readPlatformTemperature(int toolhead) { + @Override public void readPlatformTemperature(int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -1507,7 +1507,7 @@ public void readPlatformTemperature(int toolhead) { } - public void readAllPlatformTemperatures() + @Override public void readAllPlatformTemperatures() { for(ToolModel tool : machine.getTools() ) @@ -1521,13 +1521,13 @@ public void readAllPlatformTemperatures() /*************************************************************************** * Flood Coolant interface functions **************************************************************************/ - public void enableFloodCoolant() { + @Override public void enableFloodCoolant() { // TODO: throw unsupported exception super.enableFloodCoolant(); } - public void disableFloodCoolant() { + @Override public void disableFloodCoolant() { // TODO: throw unsupported exception super.disableFloodCoolant(); @@ -1536,13 +1536,13 @@ public void disableFloodCoolant() { /*************************************************************************** * Mist Coolant interface functions **************************************************************************/ - public void enableMistCoolant() { + @Override public void enableMistCoolant() { // TODO: throw unsupported exception super.enableMistCoolant(); } - public void disableMistCoolant() { + @Override public void disableMistCoolant() { // TODO: throw unsupported exception super.disableMistCoolant(); @@ -1553,7 +1553,7 @@ public void disableMistCoolant() { * * @throws RetryException **************************************************************************/ - public void enableFan(int toolhead) throws RetryException { + @Override public void enableFan(int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -1571,7 +1571,7 @@ public void enableFan(int toolhead) throws RetryException { super.enableFan(toolhead); } - public void disableFan(int toolhead) throws RetryException { + @Override public void disableFan(int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -1589,7 +1589,7 @@ public void disableFan(int toolhead) throws RetryException { super.disableFan(toolhead); } - public void setAutomatedBuildPlatformRunning(boolean state, int toolhead) + @Override public void setAutomatedBuildPlatformRunning(boolean state, int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -1614,7 +1614,7 @@ public void setAutomatedBuildPlatformRunning(boolean state, int toolhead) * * @throws RetryException **************************************************************************/ - public void openValve(int toolhead) throws RetryException { + @Override public void openValve(int toolhead) throws RetryException { Base.logger.fine("Opening valve"); /// toolhead -1 indicate auto-detect.Fast hack to get software out.. @@ -1634,7 +1634,7 @@ public void openValve(int toolhead) throws RetryException { - public void closeValve(int toolhead) throws RetryException { + @Override public void closeValve(int toolhead) throws RetryException { Base.logger.fine("Closing valve"); /// toolhead -1 indicate auto-detect.Fast hack to get software out.. @@ -1654,13 +1654,13 @@ public void closeValve(int toolhead) throws RetryException { /*************************************************************************** * Collet interface functions **************************************************************************/ - public void openCollet() { + @Override public void openCollet() { // TODO: throw unsupported exception. super.openCollet(); } - public void closeCollet() { + @Override public void closeCollet() { // TODO: throw unsupported exception. super.closeCollet(); @@ -1669,14 +1669,14 @@ public void closeCollet() { /*************************************************************************** * Pause/unpause functionality for asynchronous devices **************************************************************************/ - public void pause() { + @Override public void pause() { Base.logger.fine("Sending asynch pause command"); PacketBuilder pb = new PacketBuilder( MotherboardCommandCode.PAUSE.getCode()); runQuery(pb.getPacket()); } - public void unpause() { + @Override public void unpause() { Base.logger.fine("Sending asynch unpause command"); // There is no explicit unpause command on the Sanguino3G; instead we // use the pause command to toggle the pause state. @@ -1741,7 +1741,7 @@ protected double getLongestLength(Point5d p) { return longest; } - public String getDriverName() { + @Override public String getDriverName() { return "Sanguino3G"; } @@ -1751,7 +1751,7 @@ public String getDriverName() { final private Version extendedStopVersion = new Version(2, 7); /// resets the bot, doesn't stop threads - public void stop(boolean abort) { + @Override public void stop(boolean abort) { PacketBuilder pb; if (!abort && version.atLeast(extendedStopVersion)) { Base.logger.fine("Stop motion."); @@ -1770,7 +1770,7 @@ public void stop(boolean abort) { invalidatePosition(); } - protected Point5d reconcilePosition() throws RetryException { + @Override protected Point5d reconcilePosition() throws RetryException { // If we're writing to a file, we can't actually know what the current // position is. if (fileCaptureOstream != null) { @@ -1786,7 +1786,7 @@ protected Point5d reconcilePosition() throws RetryException { } - public void reset() { + @Override public void reset() { Base.logger.info("Reset Board"); if (isInitialized() && version.compareTo(new Version(1, 4)) >= 0) { // WDT reset introduced in version 1.4 firmware @@ -1945,7 +1945,7 @@ protected byte[] readFromEEPROM(int offset, int len) { return null; } - public EnumSet getInvertedAxes() { + @Override public EnumSet getInvertedAxes() { checkEEPROM(); byte[] b = readFromEEPROM( Sanguino3GEEPRPOM.EEPROM_AXIS_INVERSION_OFFSET, 1); @@ -1965,7 +1965,7 @@ public EnumSet getInvertedAxes() { return r; } - public void setInvertedAxes(EnumSet axes) { + @Override public void setInvertedAxes(EnumSet axes) { byte b[] = new byte[1]; if (axes.contains(AxisId.X)) b[0] = (byte) (b[0] | (0x01 << 0)); @@ -1982,7 +1982,7 @@ public void setInvertedAxes(EnumSet axes) { writeToEEPROM(Sanguino3GEEPRPOM.EEPROM_AXIS_INVERSION_OFFSET, b); } - public String getMachineName() { + @Override public String getMachineName() { checkEEPROM(); byte[] data = readFromEEPROM( Sanguino3GEEPRPOM.EEPROM_MACHINE_NAME_OFFSET, @@ -2002,7 +2002,7 @@ public String getMachineName() { } } - public void setMachineName(String machineName) { + @Override public void setMachineName(String machineName) { machineName = new String(machineName); if (machineName.length() > 16) { machineName = machineName.substring(0, 16); @@ -2023,7 +2023,7 @@ public void setMachineName(String machineName) { * Reads a 32 bit double from EEPROM on the MightyBoard to indicate the * number of steps of offset from end-stop to home on the specified axis */ - public double getAxisHomeOffset(int axis) { + @Override public double getAxisHomeOffset(int axis) { if ((axis < 0) || (axis > 4)) { // TODO: handle this return 0; @@ -2061,7 +2061,7 @@ public double getAxisHomeOffset(int axis) { } - public void setAxisHomeOffset(int axis, double offset) { + @Override public void setAxisHomeOffset(int axis, double offset) { if ((axis < 0) || (axis > 4)) { // TODO: handle this return; @@ -2107,7 +2107,7 @@ public void eepromStoreToolDelta(int axis, double offset){ return; } - public void storeHomePositions(EnumSet axes) throws RetryException { + @Override public void storeHomePositions(EnumSet axes) throws RetryException { byte b = 0; if (axes.contains(AxisId.X)) b = (byte) (b | (0x01 << 0)); @@ -2134,7 +2134,7 @@ public void storeHomePositions(EnumSet axes) throws RetryException { runCommand(pb.getPacket()); } - public void recallHomePositions(EnumSet axes) throws RetryException { + @Override public void recallHomePositions(EnumSet axes) throws RetryException { byte b = 0; if (axes.contains(AxisId.X)) b = (byte) (b | (0x01 << 0)); @@ -2163,13 +2163,13 @@ public void recallHomePositions(EnumSet axes) throws RetryException { invalidatePosition(); } - public boolean hasFeatureOnboardParameters() { + @Override public boolean hasFeatureOnboardParameters() { if (!isInitialized()) return false; return version.compareTo(new Version(1, 2)) >= 0; } - public void createThermistorTable(int which, double r0, double t0, double beta, int toolhead) { + @Override public void createThermistorTable(int which, double r0, double t0, double beta, int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -2228,7 +2228,7 @@ public double temp(double adc) { writeToToolEEPROM(Sanguino3GEEPRPOM.ECThermistorOffsets.data(which), table, toolhead); } - public boolean getCoolingFanEnabled(int toolhead) { + @Override public boolean getCoolingFanEnabled(int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -2237,13 +2237,13 @@ public boolean getCoolingFanEnabled(int toolhead) { return (a[0] == 1); } - public int getCoolingFanSetpoint(int toolhead) { + @Override public int getCoolingFanSetpoint(int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); return read16FromToolEEPROM(CoolingFanOffsets.COOLING_FAN_SETPOINT_C, 50, toolhead); } - public void setCoolingFanParameters(boolean enabled, int setpoint, int toolhead) { + @Override public void setCoolingFanParameters(boolean enabled, int setpoint, int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); if (enabled) { @@ -2303,16 +2303,16 @@ ResponseCode convertSDCode(int code) { FileOutputStream fileCaptureOstream = null; - public void beginFileCapture(String path) throws FileNotFoundException { + @Override public void beginFileCapture(String path) throws FileNotFoundException { fileCaptureOstream = new FileOutputStream(new File(path)); } - public void endFileCapture() throws IOException { + @Override public void endFileCapture() throws IOException { fileCaptureOstream.close(); fileCaptureOstream = null; } - public ResponseCode beginCapture(String filename) { + @Override public ResponseCode beginCapture(String filename) { PacketBuilder pb = new PacketBuilder( MotherboardCommandCode.CAPTURE_TO_FILE.getCode()); for (byte b : filename.getBytes()) { @@ -2323,14 +2323,14 @@ public ResponseCode beginCapture(String filename) { return convertSDCode(pr.get8()); } - public int endCapture() { + @Override public int endCapture() { PacketBuilder pb = new PacketBuilder( MotherboardCommandCode.END_CAPTURE.getCode()); PacketResponse pr = runQuery(pb.getPacket()); return pr.get32(); } - public ResponseCode playback(String filename) { + @Override public ResponseCode playback(String filename) { PacketBuilder pb = new PacketBuilder( MotherboardCommandCode.PLAYBACK_CAPTURE.getCode()); for (byte b : filename.getBytes()) { @@ -2341,13 +2341,13 @@ public ResponseCode playback(String filename) { return convertSDCode(pr.get8()); } - public boolean hasFeatureSDCardCapture() { + @Override public boolean hasFeatureSDCardCapture() { if (!isInitialized()) return false; return version.compareTo(new Version(1, 3)) >= 0; } - public List getFileList() { + @Override public List getFileList() { Vector fileList = new Vector(); boolean reset = true; while (true) { @@ -2374,7 +2374,7 @@ public List getFileList() { return fileList; } - public int getBeta(int which, int toolhead) { + @Override public int getBeta(int which, int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -2390,7 +2390,7 @@ public int getBeta(int which, int toolhead) { return val; } - public int getR0(int which, int toolhead) { + @Override public int getR0(int which, int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); byte r[] = readFromToolEEPROM(Sanguino3GEEPRPOM.ECThermistorOffsets.r0(which),4,toolhead); @@ -2405,7 +2405,7 @@ public int getR0(int which, int toolhead) { return val; } - public int getT0(int which, int toolhead) { + @Override public int getT0(int which, int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); byte r[] = readFromToolEEPROM(Sanguino3GEEPRPOM.ECThermistorOffsets.t0(which),4,toolhead); @@ -2475,7 +2475,7 @@ private float readFloat16FromToolEEPROM(int offset, float defaultValue, int tool return (float) byteToInt(r[0]) + ((float) byteToInt(r[1])) / 256.0f; } - public BackoffParameters getBackoffParameters(int toolhead) { + @Override public BackoffParameters getBackoffParameters(int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -2487,7 +2487,7 @@ public BackoffParameters getBackoffParameters(int toolhead) { return bp; } - public void setBackoffParameters(BackoffParameters bp, int toolhead) { + @Override public void setBackoffParameters(BackoffParameters bp, int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -2497,7 +2497,7 @@ public void setBackoffParameters(BackoffParameters bp, int toolhead) { writeToToolEEPROM(ECBackoffOffsets.TRIGGER_MS,intToLE(bp.triggerMs,2), toolhead); } - public PIDParameters getPIDParameters(int which, int toolhead) { + @Override public PIDParameters getPIDParameters(int which, int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); PIDParameters pp = new PIDParameters(); @@ -2508,7 +2508,7 @@ public PIDParameters getPIDParameters(int which, int toolhead) { return pp; } - public void setPIDParameters(int which, PIDParameters pp, int toolhead) { + @Override public void setPIDParameters(int which, PIDParameters pp, int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); int offset = (which == OnboardParameters.EXTRUDER)?PIDOffsets.PID_EXTRUDER:PIDOffsets.PID_HBP; @@ -2545,7 +2545,7 @@ public void resetToolToFactory(int toolhead) { resetToolToBlank(toolhead); /// for generic S3G, just wipe the EEPROM } - public void resetToolToBlank(int toolhead){ + @Override public void resetToolToBlank(int toolhead){ /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -2557,20 +2557,20 @@ public void resetToolToBlank(int toolhead){ } - public EndstopType getInvertedEndstops() { + @Override public EndstopType getInvertedEndstops() { checkEEPROM(); byte[] b = readFromEEPROM( Sanguino3GEEPRPOM.EEPROM_ENDSTOP_INVERSION_OFFSET, 1); return EndstopType.endstopTypeForValue(b[0]); } - public void setInvertedEndstops(EndstopType endstops) { + @Override public void setInvertedEndstops(EndstopType endstops) { byte b[] = new byte[1]; b[0] = endstops.getValue(); writeToEEPROM(Sanguino3GEEPRPOM.EEPROM_ENDSTOP_INVERSION_OFFSET, b); } - public ExtraFeatures getExtraFeatures(int toolhead) { + @Override public ExtraFeatures getExtraFeatures(int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); int efdat = read16FromToolEEPROM(Sanguino3GEEPRPOM.EC_EEPROM_EXTRA_FEATURES, 0x4084, toolhead); @@ -2586,7 +2586,7 @@ public ExtraFeatures getExtraFeatures(int toolhead) { return ef; } - public void setExtraFeatures(ExtraFeatures features, int toolhead) { + @Override public void setExtraFeatures(ExtraFeatures features, int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -2602,14 +2602,14 @@ public void setExtraFeatures(ExtraFeatures features, int toolhead) { writeToToolEEPROM(Sanguino3GEEPRPOM.EC_EEPROM_EXTRA_FEATURES,intToLE(efdat,2), toolhead); } - public EstopType getEstopConfig() { + @Override public EstopType getEstopConfig() { checkEEPROM(); byte[] b = readFromEEPROM( Sanguino3GEEPRPOM.EEPROM_ESTOP_CONFIGURATION_OFFSET, 1); return EstopType.estopTypeForValue(b[0]); } - public void setEstopConfig(EstopType estop) { + @Override public void setEstopConfig(EstopType estop) { byte b[] = new byte[1]; b[0] = estop.getValue(); writeToEEPROM(Sanguino3GEEPRPOM.EEPROM_ESTOP_CONFIGURATION_OFFSET, b); @@ -2658,7 +2658,7 @@ public Version getToolVersion() { return toolVersion; } - public boolean setConnectedToolIndex(int index) { + @Override public boolean setConnectedToolIndex(int index) { byte[] data = new byte[1]; data[0] = (byte) index; @@ -2671,11 +2671,11 @@ public boolean setConnectedToolIndex(int index) { return false; } - public boolean toolsCanBeReindexed() { + @Override public boolean toolsCanBeReindexed() { return true; } - public boolean supportsSimultaneousTools() { + @Override public boolean supportsSimultaneousTools() { return true; } From ecc5d15e16e951787f3dfe2a6a09e803f267c6da Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Fri, 9 Mar 2012 10:55:32 -0800 Subject: [PATCH 09/35] Cleaned up DriverBaseImplementation, mostly. Made it clear that DriverBaseImplementation is not to be used on its own by marking it abstract and making the constructor protected. Put big scary comments on methods that appear to have been attempts at overrides, but which actually overload methods in Driver. Because the rest of RepG manipulates Drivers through the Driver interface -- not as objects of type DriverBaseImplementation -- this means all these functions are dead! Which is too bad, because they're awesome. Marked them for eventual transfer to Driver. Removed all commented-out code and fields. Tightened access modifiers as far as possible (e.g. fields to private, methods to protected). This revealed that some code and fields were dead, but not being detected as such because they were declared as visible; removed all that. Routed all internal setting of currentPosition through the setInternalPosition method, which appears to have been provided for this purpose. Inlining it would also be a reasonable choice. Propagated @Deprecated annotations forward from Driver. There's still some stuff left to do here, but the change does too many things already. --- .../drivers/DriverBaseImplementation.java | 85 +++++++++---------- 1 file changed, 40 insertions(+), 45 deletions(-) diff --git a/src/replicatorg/drivers/DriverBaseImplementation.java b/src/replicatorg/drivers/DriverBaseImplementation.java index 418465fdc..c6b5a874c 100644 --- a/src/replicatorg/drivers/DriverBaseImplementation.java +++ b/src/replicatorg/drivers/DriverBaseImplementation.java @@ -40,10 +40,7 @@ import replicatorg.machine.model.MachineModel; import replicatorg.util.Point5d; -public class DriverBaseImplementation implements Driver, DriverQueryInterface{ -// // our gcode parser -// private GCodeParser parser; - +public abstract class DriverBaseImplementation implements Driver, DriverQueryInterface{ // models for our machine protected MachineModel machine; @@ -64,18 +61,11 @@ public class DriverBaseImplementation implements Driver, DriverQueryInterface{ private AtomicBoolean isInitialized = new AtomicBoolean(false); // our error variable. - ConcurrentLinkedQueue errorList; + private ConcurrentLinkedQueue errorList; // how fast are we moving in mm/minute private double currentFeedrate; - // what is our mode of positioning? - protected int positioningMode = 0; - - static public int ABSOLUTE = 0; - - static public int INCREMENTAL = 1; - /** * Support for emergency stop is not assumed until it is detected. Detection of this feature should be in initialization. */ @@ -89,7 +79,7 @@ public class DriverBaseImplementation implements Driver, DriverQueryInterface{ /** * Creates the driver object. */ - public DriverBaseImplementation() { + protected DriverBaseImplementation() { errorList = new ConcurrentLinkedQueue(); // initialize our offsets @@ -123,7 +113,6 @@ public DriverBaseImplementation() { if (Base.logger.isLoggable(Level.FINE)) { Base.logger.fine("Disposing of driver " + getDriverName()); } -// parser = null; } /*************************************************************************** @@ -138,7 +127,7 @@ public DriverBaseImplementation() { setInitialized(false); } - public void setInitialized(boolean status) { + protected void setInitialized(boolean status) { synchronized(isInitialized) { isInitialized.set(status); @@ -205,12 +194,6 @@ public void checkErrors() throws BuildFailureException { return firmwareName + " v" + getVersion(); } - public String getBotName(){ - if ( botName != null ) - return botName; - return "Unnamed Bot (a Sad Bot)"; - } - @Override public Version getVersion() { return version; } @@ -247,7 +230,7 @@ public String getBotName(){ new AtomicReference(null); @Override public void setCurrentPosition(Point5d p) throws RetryException { - currentPosition.set(p); + setInternalPosition(p); } /** @@ -255,8 +238,7 @@ public String getBotName(){ * and that the machine should be queried for its actual location. */ @Override public void invalidatePosition() { -// System.err.println("invalidating position."); - currentPosition.set(null); + setInternalPosition(null); } /** @@ -290,7 +272,7 @@ protected Point5d reconcilePosition() throws RetryException { try { // Try to reconcile our position. Point5d newPoint = reconcilePosition(); - currentPosition.set(newPoint); + setInternalPosition(newPoint); } catch (RetryException e) { Base.logger.severe("Attempt to reconcile machine position failed, due to Retry Exception"); @@ -342,13 +324,11 @@ protected void setInternalPosition(Point5d position) { * @param delta The delta in mm. * @return safe feedrate in mm/min */ - public double getSafeFeedrate(Point5d delta) { + protected double getSafeFeedrate(Point5d delta) { double feedrate = getCurrentFeedrate(); Point5d maxFeedrates = machine.getMaximumFeedrates(); - // System.out.println("max feedrates: " + maxFeedrates); - // If the current feedrate is 0, set it to the maximum feedrate of any // of the machine axis. If those are also all 0 (misconfiguration?), // set the feedrate to 1. @@ -379,7 +359,7 @@ public double getSafeFeedrate(Point5d delta) { return feedrate; } - public Point5d getDelta(Point5d p) { + protected Point5d getDelta(Point5d p) { Point5d delta = new Point5d(); Point5d current = getCurrentPosition(false); @@ -424,7 +404,6 @@ public Point5d getDelta(Point5d p) { * @throws RetryException **************************************************************************/ @Override public void delay(long millis) throws RetryException { - // System.out.println("Delay: " + millis); } @@ -473,8 +452,9 @@ public Point5d getDelta(Point5d p) { /*************************************************************************** * Motor interface functions + * @deprecated **************************************************************************/ - @Override public void setMotorDirection(int dir) { + @Deprecated @Override public void setMotorDirection(int dir) { this.setMotorDirection(machine.currentTool().getIndex()); } @@ -496,7 +476,7 @@ public void setMotorRPM(double rpm, int toolhead) throws RetryException { } - @Override + @Deprecated @Override public void setMotorSpeedPWM(int pwm) throws RetryException { this.setMotorSpeedPWM(pwm, machine.currentTool().getIndex()); } @@ -509,12 +489,12 @@ public void setMotorSpeedPWM(int pwm) throws RetryException { } - @Override + @Deprecated @Override public void enableMotor() throws RetryException { this.enableMotor(machine.currentTool().getIndex()); } - @Override + @Deprecated @Override public void enableMotor(long millis) throws RetryException { this.enableMotor(millis, machine.currentTool().getIndex()); } @@ -528,6 +508,7 @@ public void enableMotor(long millis, int toolhead) throws RetryException { delay( millis ); disableMotor(toolhead); } + @Override public void enableMotor(int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. @@ -546,7 +527,7 @@ public void enableMotor(int toolhead) throws RetryException { machine.getTool(toolhead).disableMotor(); } - @Override + @Deprecated @Override public void disableMotor() throws RetryException { this.disableMotor(-1); @@ -597,6 +578,12 @@ public double getMotorSteps() { @Override public void disableSpindle() throws RetryException { disableSpindle(-1); } + + /* + * N.B. the methods below are dead code! They should be added + * to the Driver interface. + */ + public void setSpindleRPM(double rpm, int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -624,6 +611,10 @@ public void disableSpindle(int toolhead) throws RetryException { machine.getTool(toolhead).disableSpindle(); } + + /* + * End of dead code. + */ @Override public double getSpindleRPM() { return machine.currentTool().getSpindleSpeedReadingRPM(); @@ -636,8 +627,9 @@ public void disableSpindle(int toolhead) throws RetryException { /*************************************************************************** * Temperature interface functions * @throws RetryException + * @deprecated **************************************************************************/ - @Override + @Deprecated @Override public void setTemperature(double temperature) throws RetryException { machine.currentTool().setTargetTemperature(temperature); } @@ -653,6 +645,8 @@ public void setTemperature(double temperature, int toolhead) throws RetryExcepti @Override public void readTemperature() { } + + // Dead code! public void readTemperature(int toolhead) { } @@ -675,8 +669,9 @@ public double getTemperature(int toolhead) { /*************************************************************************** * Platform Temperature interface functions * @throws RetryException + * @deprecated **************************************************************************/ - @Override + @Deprecated @Override public void setPlatformTemperature(double temperature) throws RetryException { this.setPlatformTemperature(temperature, -1); } @@ -741,8 +736,9 @@ public double getPlatformTemperature() { /*************************************************************************** * Fan interface functions * @throws RetryException + * @deprecated **************************************************************************/ - @Override public void enableFan() throws RetryException { + @Deprecated @Override public void enableFan() throws RetryException { this.enableFan(machine.currentTool().getIndex()); } @Override @@ -753,7 +749,7 @@ public void enableFan(int toolhead) throws RetryException { } - @Override public void disableFan() throws RetryException { + @Deprecated @Override public void disableFan() throws RetryException { this.disableFan(machine.currentTool().getIndex()); } @@ -765,7 +761,7 @@ public void disableFan(int toolhead) throws RetryException { } - @Override public void setAutomatedBuildPlatformRunning(boolean state) throws RetryException { + @Deprecated @Override public void setAutomatedBuildPlatformRunning(boolean state) throws RetryException { this.setAutomatedBuildPlatformRunning(state, machine.currentTool().getIndex()); } @Override @@ -782,6 +778,7 @@ public void setAutomatedBuildPlatformRunning(boolean state, int toolhead) return hasAutomatedBuildPlatform(-1); } + // Dead code! public boolean hasAutomatedBuildPlatform(int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. @@ -800,11 +797,14 @@ public boolean hasAutomatedBuildPlatform(int toolhead) @Override public void closeValve() throws RetryException { closeValve(-1); } + + // Dead code! public void openValve(int toolhead) throws RetryException { if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); machine.getTool(toolhead).openValve(); } + // Dead code! public void closeValve(int toolhead) throws RetryException { if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); machine.getTool(toolhead).closeValve(); @@ -815,11 +815,6 @@ public void closeValve(int toolhead) throws RetryException { Base.logger.fine("BaseImplementation setStepperVoltage called."); } -// public void storeStepperVoltage(int stepperId, int referenceValue) throws RetryException -// { -// Base.logger.fine("BaseImplementation setStepperVoltage called."); -// } - @Override public int getStepperVoltage(int stepperId) { Base.logger.fine("BaseImplementation getStepperVoltage called."); From 3b6b3f6429cd0fa55c169d34ab70557a95288302 Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Fri, 9 Mar 2012 10:56:55 -0800 Subject: [PATCH 10/35] Marked SerialDriver as abstract. --- src/replicatorg/drivers/SerialDriver.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/replicatorg/drivers/SerialDriver.java b/src/replicatorg/drivers/SerialDriver.java index 2bcd3a7a6..f8f584b32 100644 --- a/src/replicatorg/drivers/SerialDriver.java +++ b/src/replicatorg/drivers/SerialDriver.java @@ -18,7 +18,7 @@ * @author phooky * */ -public class SerialDriver extends DriverBaseImplementation implements UsesSerial { +public abstract class SerialDriver extends DriverBaseImplementation implements UsesSerial { protected Serial serial; From 17b477d63be4339fef54fa58c5a9d0e95523abab Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Fri, 9 Mar 2012 11:14:34 -0800 Subject: [PATCH 11/35] Cleaned up Sanguino3GDriver, mostly. Tightened access modifiers as much as possible. Removed do-nothing overrides that just call the super impl. Removed a dead null check (line 349). Removed commented-out code. Propagated @Deprecated forward from Driver. Did not remove all dead code. This driver contains the same attempted overrides as DriverBaseImplementation; I've left them private, so that they light up on a dead code analysis pass but aren't lost to the mists of time (or git log). I expect to expose these shortly. --- .../drivers/gen3/Sanguino3GDriver.java | 92 +++++-------------- 1 file changed, 23 insertions(+), 69 deletions(-) diff --git a/src/replicatorg/drivers/gen3/Sanguino3GDriver.java b/src/replicatorg/drivers/gen3/Sanguino3GDriver.java index f45f21c60..5debbfe04 100644 --- a/src/replicatorg/drivers/gen3/Sanguino3GDriver.java +++ b/src/replicatorg/drivers/gen3/Sanguino3GDriver.java @@ -35,8 +35,6 @@ import java.util.Vector; import java.util.logging.Level; -import org.w3c.dom.Node; - import replicatorg.app.Base; import replicatorg.drivers.DriverError; import replicatorg.drivers.MultiTool; @@ -52,8 +50,6 @@ import replicatorg.uploader.FirmwareUploader; import replicatorg.util.Point5d; -import replicatorg.drivers.gen3.EEPROMClass; - class Sanguino3GEEPRPOM implements EEPROMClass { public static final int EEPROM_CHECK_LOW = 0x5A; @@ -105,12 +101,11 @@ public class Sanguino3GDriver extends SerialDriver implements OnboardParameters, SDCardCapture, PenPlotter, MultiTool { protected final static int DEFAULT_RETRIES = 5; - Version toolVersion = new Version(0, 0); + private Version toolVersion = new Version(0, 0); private boolean eepromChecked = false; public Sanguino3GDriver() { - super(); hasEmergencyStop = true; hasSoftStop = true; @@ -121,11 +116,6 @@ public Sanguino3GDriver() { setInitialized(false); } - @Override public void loadXML(Node xml) { - super.loadXML(xml); - - } - @Override public void initialize() { Base.logger.fine("Attempting to initialize device"); @@ -159,8 +149,6 @@ public Sanguino3GDriver() { sendInit(); super.initialize(); invalidatePosition(); - - return; } else { Base.logger.info("Unable to connect to firmware."); // Dispose of driver to free up any resources @@ -168,7 +156,7 @@ public Sanguino3GDriver() { } } - public boolean initializeBot() + protected boolean initializeBot() { // Scan for each slave for (ToolModel t : getMachine().getTools()) { @@ -220,7 +208,7 @@ private boolean attemptConnection() { * handshake. * @return true if we received a handshake; false if we timed out. */ - protected void connectToDevice(int timeoutMillis) { + private void connectToDevice(int timeoutMillis) { assert (serial != null); synchronized (serial) { serial.clear(); @@ -299,7 +287,7 @@ protected PacketResponse runQuery(byte[] packet) { } - void printDebugData(String title, byte[] data) { + private void printDebugData(String title, byte[] data) { StringBuffer buf = new StringBuffer(title + ": "); for (int i = 0; i < data.length; i++) { buf.append(Integer.toHexString((int) data[i] & 0xff)); @@ -325,7 +313,7 @@ void printDebugData(String title, byte[] data) { * @return * @throws RetryException */ - protected PacketResponse runCommand(byte[] packet, int retries) + private PacketResponse runCommand(byte[] packet, int retries) throws RetryException { if (retries == 0) { @@ -383,11 +371,6 @@ protected PacketResponse runCommand(byte[] packet, int retries) pp = new PacketProcessor(); - if(packet == null) { - Base.logger.severe("null packet in runCommand"); - return PacketResponse.timeoutResponse(); - } - // This can actually happen during shutdown. if (serial == null){ Base.logger.severe("null serial in runCommand"); @@ -447,7 +430,7 @@ protected PacketResponse runCommand(byte[] packet, int retries) return pr; } - static boolean isNotifiedFinishedFeature = false; + private static boolean isNotifiedFinishedFeature = false; @Override public boolean isFinished() { if (fileCaptureOstream != null) { @@ -497,10 +480,6 @@ protected PacketResponse runCommand(byte[] packet, int retries) return finished; } - @Override public void dispose() { - super.dispose(); - } - /*************************************************************************** * commands used internally to driver **************************************************************************/ @@ -509,7 +488,7 @@ protected PacketResponse runCommand(byte[] packet, int retries) * Make an inital connection to read the version code. * @return */ - public Version getVersionInternal() { + private Version getVersionInternal() { PacketBuilder pb = new PacketBuilder(MotherboardCommandCode.VERSION.getCode()); pb.add16(Base.VERSION); @@ -639,13 +618,9 @@ private void initSlave(int toolhead) { } } } -// //TRICKY: this is just called to get the value cached into the ToolModel -// double ignore = getMotorRPM(toolIndex); - - } - public void sendInit() { + private void sendInit() { PacketBuilder pb = new PacketBuilder( MotherboardCommandCode.INIT.getCode()); runQuery(pb.getPacket()); @@ -686,10 +661,6 @@ public void sendInit() { } } - // public Point3d getPosition() { - // return new Point3d(); - // } - /* * //figure out the axis with the most steps. Point3d steps = * getAbsDeltaSteps(getCurrentPosition(), p); Point3d delta_steps = @@ -735,11 +706,6 @@ protected void queueAbsolutePoint(Point5d steps, long micros) } @Override public void setCurrentPosition(Point5d p) throws RetryException { - // System.err.println(" SCP: "+p.toString()+ - // " (current "+getCurrentPosition().toString()+")"); - // if (super.getCurrentPosition().equals(p)) return; - // System.err.println("COMMIT: "+p.toString()+ - // " (current "+getCurrentPosition().toString()+")"); PacketBuilder pb = new PacketBuilder( MotherboardCommandCode.SET_POSITION.getCode()); @@ -964,16 +930,11 @@ private int axesToBitfield(EnumSet axes) { pb.add32(microseconds); runCommand(pb.getPacket()); - //TRICKY: WAS 'super.setMotorRPM(rpm);', but this seems not to work right. - // Seems to set default motor value(motorSpeedRPM , not 'running' motor - // value. Caused gui to show bad values -// machine.getTool(toolhead).setMotorSpeedReadingRPM(rpm); -// Changed back - Ted super.setMotorRPM(rpm, toolhead); } - @Override public void setMotorSpeedPWM(int pwm) throws RetryException { + @Deprecated @Override public void setMotorSpeedPWM(int pwm) throws RetryException { this.setMotorSpeedPWM(pwm, machine.currentTool().getIndex()); } @@ -1054,7 +1015,7 @@ public void disableMotor(int toolhead) throws RetryException { super.disableMotor(toolhead); } - public int getMotorSpeedPWM(int toolhead) { + private int getMotorSpeedPWM(int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -1082,7 +1043,7 @@ public int getMotorSpeedPWM(int toolhead) { return getMotorRPM(machine.currentTool().getIndex()); } - public double getMotorRPM(int toolhead) { + private double getMotorRPM(int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -1107,8 +1068,7 @@ public double getMotorRPM(int toolhead) { return rpm; } - - public void readToolStatus(int toolhead) { + private void readToolStatus(int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -1149,7 +1109,7 @@ private int fixSigned(int value) { } // TODO: Implement a way for this to reach the outside - public void readToolPIDState(int toolhead) { + private void readToolPIDState(int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -1188,18 +1148,12 @@ public void readToolPIDState(int toolhead) { * * @throws RetryException **************************************************************************/ - // public void moveServo(int degree) {} - - // public void enableServo() {} - - // public void disableServo() {} - @Override @Deprecated public void setServoPos(int index, double degree) throws RetryException { this.setServoPos(index, degree, machine.currentTool().getIndex()); } - public void setServoPos(int index, double degree, int toolhead) throws RetryException { + private void setServoPos(int index, double degree, int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -1342,7 +1296,7 @@ public void setServoPos(int index, double degree, int toolhead) throws RetryExce super.disableSpindle(toolhead); } - public double getSpindleSpeedRPM(int toolhead) throws RetryException { + private double getSpindleSpeedRPM(int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -1365,7 +1319,7 @@ public double getSpindleSpeedRPM(int toolhead) throws RetryException { return rpm; } - public int getSpindleSpeedPWM(int toolhead) { + private int getSpindleSpeedPWM(int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -1480,7 +1434,7 @@ else if (pr.isEmpty()) } - public void setAllPlatformTemperatures(double temperature) throws RetryException { + private void setAllPlatformTemperatures(double temperature) throws RetryException { // constrain our temperature. //Set the platform temperature for any & every tool with an HBP for(ToolModel t : machine.getTools()) @@ -1710,7 +1664,7 @@ protected Point5d getAbsDeltaSteps(Point5d current, Point5d target) { * Feedrate in mm per minute * @return */ - protected long convertFeedrateToMicros(Point5d current, Point5d target, + private long convertFeedrateToMicros(Point5d current, Point5d target, double feedrate) { Point5d deltaDistance = getAbsDeltaDistance(current, target); Point5d deltaSteps = machine.mmToSteps(deltaDistance); @@ -1732,7 +1686,7 @@ protected long convertFeedrateToMicros(Point5d current, Point5d target, return (long) Math.round(step_delay); } - protected double getLongestLength(Point5d p) { + private double getLongestLength(Point5d p) { // find the dominant axis. double longest = 0d; for (int i = 0; i < 5; i++) { @@ -2278,7 +2232,7 @@ protected byte[] intToLE(int s) { return intToLE(s, 4); } - ResponseCode convertSDCode(int code) { + private ResponseCode convertSDCode(int code) { switch (code) { case 0: return ResponseCode.SUCCESS; @@ -2301,7 +2255,7 @@ ResponseCode convertSDCode(int code) { return ResponseCode.FAIL_GENERIC; } - FileOutputStream fileCaptureOstream = null; + protected FileOutputStream fileCaptureOstream = null; @Override public void beginFileCapture(String path) throws FileNotFoundException { fileCaptureOstream = new FileOutputStream(new File(path)); @@ -2615,7 +2569,7 @@ public void resetToolToFactory(int toolhead) { writeToEEPROM(Sanguino3GEEPRPOM.EEPROM_ESTOP_CONFIGURATION_OFFSET, b); } - public double getPlatformTemperatureSetting(int toolhead) { + protected double getPlatformTemperatureSetting(int toolhead) { /// toolhead -1 indicates auto-detect. Fast hack to get software out... if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -2634,7 +2588,7 @@ public double getPlatformTemperatureSetting(int toolhead) { return machine.getTool(toolhead).getPlatformTargetTemperature(); } - public double getTemperatureSetting(int toolhead) { + protected double getTemperatureSetting(int toolhead) { /// toolhead -1 indicates auto-detect. Fast hack to get software out... if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); From 1b37a7cbd7e19218c7d815026f77be7ca2d9b88b Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Fri, 9 Mar 2012 11:17:57 -0800 Subject: [PATCH 12/35] Cleaned up Makerbot4GDriver. Tightened access modifiers as much as possible. Removed commented-out code. Propagated @Deprecated forward from Driver. --- .../drivers/gen3/Makerbot4GDriver.java | 28 ++++--------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/src/replicatorg/drivers/gen3/Makerbot4GDriver.java b/src/replicatorg/drivers/gen3/Makerbot4GDriver.java index 707f1dce0..5208e8023 100644 --- a/src/replicatorg/drivers/gen3/Makerbot4GDriver.java +++ b/src/replicatorg/drivers/gen3/Makerbot4GDriver.java @@ -15,8 +15,7 @@ import replicatorg.util.Point5d; public class Makerbot4GDriver extends Sanguino3GDriver { - - protected boolean stepperExtruderFanEnabled = false; + private boolean stepperExtruderFanEnabled = false; @Override public String getDriverName() { @@ -43,7 +42,7 @@ public void stop(boolean abort) { super.stop(abort); } - protected Iterable getHijackedAxes(int toolhead){ + private Iterable getHijackedAxes(int toolhead){ Vector axes = new Vector(); AxisId toolheadAxis = machine.getTool(toolhead).getMotorStepperAxis(); if( extruderHijackedMap.containsKey( toolheadAxis ) ) @@ -51,22 +50,6 @@ protected Iterable getHijackedAxes(int toolhead){ return axes; } -// /** -// * Returns the hijacked axes for the current tool. -// */ -// @Deprecated -// private Iterable getHijackedAxes() { -// Vector axes = new Vector(); -// -// for ( Map.Entry entry : stepExtruderMap.entrySet()) { -// ToolModel curTool = machine.currentTool(); -// if (curTool.equals(entry.getValue())) { -// axes.add(curTool.getMotorStepperAxis()); -// } -// } -// return axes; -// } - /** * Each Axis can be overridden (hijacked) by XML settings. Return all overridden * axes for the currently loaded machine. @@ -129,7 +112,6 @@ public void setCurrentPosition(Point5d p) throws RetryException { // Set the current position explicitly instead of calling the super, to avoid sending the current position command twice. currentPosition.set(p); -// super.setCurrentPosition(p); } @Override @@ -149,7 +131,6 @@ protected Point5d reconcilePosition() { return null; } -// Base.logger.fine("Reconciling : "+machine.stepsToMM(steps).toString()); return machine.stepsToMM(steps); } @@ -172,8 +153,9 @@ protected Point5d reconcilePosition() { /** * Overridden to not talk to the DC motor driver. This driver is reused for the stepper motor fan + * @deprecated */ - @Override + @Deprecated @Override public void setMotorSpeedPWM(int pwm) throws RetryException { machine.currentTool().setMotorSpeedPWM(pwm); } @@ -209,7 +191,7 @@ public void disableDrives() throws RetryException { * Will turn on/off the stepper extruder fan if it's not already in the correct state. * */ - public void enableStepperExtruderFan(boolean enabled, int toolIndex) throws RetryException { + protected void enableStepperExtruderFan(boolean enabled, int toolIndex) throws RetryException { // Always re-enable the fan when if (this.stepperExtruderFanEnabled == enabled) return; From 817256068201550dda8c6e6bbad7a7731c906787 Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Fri, 9 Mar 2012 11:18:56 -0800 Subject: [PATCH 13/35] Removed an unused variable from MB4GAD. --- src/replicatorg/drivers/gen3/Makerbot4GAlternateDriver.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/replicatorg/drivers/gen3/Makerbot4GAlternateDriver.java b/src/replicatorg/drivers/gen3/Makerbot4GAlternateDriver.java index 9d0cb2adc..4703e966d 100644 --- a/src/replicatorg/drivers/gen3/Makerbot4GAlternateDriver.java +++ b/src/replicatorg/drivers/gen3/Makerbot4GAlternateDriver.java @@ -170,13 +170,11 @@ private Point5d calcHijackedAxesMovement(Point5d delta) { * by @minutes. If no axis is enabled and hijacked, returns an 'empty' Point5d with no motion. */ private Point5d pointsFromHijackedAxes(ToolModel curTool, double minutes) { - int relative = 0; Point5d steps = new Point5d(); Base.logger.finer("modify hijacked axes"); for (AxisId axis : getHijackedAxes(machine.currentTool())) { Base.logger.finer("modify hijacked axes doing " + axis.toString() ); - relative |= 1 << axis.getIndex(); double extruderSteps = 0; if (curTool.isMotorEnabled()) { From ff84f729b66354326cd4805cb8be45a8e7e3fe30 Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Fri, 9 Mar 2012 17:54:46 -0800 Subject: [PATCH 14/35] Miscellaneous cleanups in driver package: Added @Overrides. Removed unused classes (one of which appears to have a years-old comment asking why it existed). Fixed equals/hashCode contract violation in Version. --- .../drivers/BadFirmwareVersionException.java | 2 +- src/replicatorg/drivers/NullDriver.java | 41 - .../drivers/OnboardParameters.java | 1 - src/replicatorg/drivers/StopException.java | 2 +- src/replicatorg/drivers/Version.java | 10 +- src/replicatorg/drivers/VirtualPrinter.java | 714 ------------------ 6 files changed, 9 insertions(+), 761 deletions(-) delete mode 100644 src/replicatorg/drivers/NullDriver.java delete mode 100644 src/replicatorg/drivers/VirtualPrinter.java diff --git a/src/replicatorg/drivers/BadFirmwareVersionException.java b/src/replicatorg/drivers/BadFirmwareVersionException.java index 1a3c94d74..f6533ca81 100644 --- a/src/replicatorg/drivers/BadFirmwareVersionException.java +++ b/src/replicatorg/drivers/BadFirmwareVersionException.java @@ -22,7 +22,7 @@ public BadFirmwareVersionException(Version has, Version needs) { public Version getNeeds() { return needs; } - public String getMessage() { + @Override public String getMessage() { return "Firmware version "+getDetected()+" detected; firmware version "+needs+" required."; } diff --git a/src/replicatorg/drivers/NullDriver.java b/src/replicatorg/drivers/NullDriver.java deleted file mode 100644 index b29ad943f..000000000 --- a/src/replicatorg/drivers/NullDriver.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - NullDriver.java - - This driver does absolutely nothing. - - Part of the ReplicatorG project - http://www.replicat.org - Copyright (c) 2008 Zach Smith - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -package replicatorg.drivers; - -import org.w3c.dom.Node; - -import replicatorg.app.tools.XML; - - -//TODO: why do we have this? -public class NullDriver extends DriverBaseImplementation { - - public NullDriver() { - super(); - } - - public void loadXML(Node xml) { - super.loadXML(xml); - } -} diff --git a/src/replicatorg/drivers/OnboardParameters.java b/src/replicatorg/drivers/OnboardParameters.java index f3f0317e2..1aa7d3c08 100644 --- a/src/replicatorg/drivers/OnboardParameters.java +++ b/src/replicatorg/drivers/OnboardParameters.java @@ -5,7 +5,6 @@ import java.util.List; import replicatorg.machine.model.AxisId; -import replicatorg.machine.model.ToolModel; public interface OnboardParameters { diff --git a/src/replicatorg/drivers/StopException.java b/src/replicatorg/drivers/StopException.java index 35f22380c..2d61e046b 100644 --- a/src/replicatorg/drivers/StopException.java +++ b/src/replicatorg/drivers/StopException.java @@ -47,7 +47,7 @@ private String getFormattedMessage(String message) { return output.toString(); } - public String getMessage() { + @Override public String getMessage() { return getFormattedMessage(message); } } diff --git a/src/replicatorg/drivers/Version.java b/src/replicatorg/drivers/Version.java index 3ae56de0c..a48a5e73a 100644 --- a/src/replicatorg/drivers/Version.java +++ b/src/replicatorg/drivers/Version.java @@ -9,25 +9,29 @@ public Version( int major, int minor ) { this.minor = minor; } - public boolean equals(Object o) { + @Override public boolean equals(Object o) { if (o instanceof Version) { Version v = (Version)o; return major == v.major && minor == v.minor; } return false; } + + @Override public int hashCode() { + return (major * 31) + minor; + } public boolean atLeast(Version v) { return compareTo(v) >= 0; } - public int compareTo(Version v) { + @Override public int compareTo(Version v) { if (major > v.major || ((major == v.major) && (minor > v.minor))) return 1; if (equals(v)) return 0; return -1; } - public String toString() { + @Override public String toString() { return Integer.toString(major) + "." + Integer.toString(minor); } diff --git a/src/replicatorg/drivers/VirtualPrinter.java b/src/replicatorg/drivers/VirtualPrinter.java deleted file mode 100644 index 0e86b63be..000000000 --- a/src/replicatorg/drivers/VirtualPrinter.java +++ /dev/null @@ -1,714 +0,0 @@ -package replicatorg.drivers; - -/// A fake, but agreeable driver. - -import java.awt.Color; -import java.util.EnumSet; - -import javax.vecmath.Point3d; - -import org.w3c.dom.Node; - -import replicatorg.app.Base; -import replicatorg.app.exceptions.BuildFailureException; -import replicatorg.machine.model.AxisId; -import replicatorg.machine.model.MachineModel; -import replicatorg.util.Point5d; - -public class VirtualPrinter implements Driver, DriverQueryInterface { - - final String firmwareInfo = "No Firmware"; - final Version version = new Version(0,0); - final Version minimumVersion = new Version(0,0); - final Version preferredVersion = new Version(0,0); - final boolean hasSoftStop = true; - final boolean hasEStop = true; - - double toolTemperature = 0; - double toolTemperatureSetting = 0; - double platformTemperature = 0; - double platformTemperatureSetting = 0; - boolean isInitialized = false; - MachineModel machineModel = new MachineModel(); - Point5d currentPosition = new Point5d(); - Point5d maximumFeedrates = new Point5d(1,1,1,1,1); - Point3d[] currentOffset = new Point3d[]{ - new Point3d(), - new Point3d(), - new Point3d(), - new Point3d(), - new Point3d()}; - - @Override - public void loadXML(Node xml) { - // TODO Auto-generated method stub - machineModel.loadXML(xml); - } - - @Override - public boolean isPassthroughDriver() { - // TODO Auto-generated method stub - return false; - } - - @Override - public void executeGCodeLine(String code) { - // TODO Auto-generated method stub - - } - - @Override - public boolean isFinished() { - // TODO Auto-generated method stub - return true; - } - - @Override - public boolean isBufferEmpty() { - // TODO Auto-generated method stub - return true; - } - - @Override - public void assessState() { - // TODO Auto-generated method stub - - } - - @Override - public boolean hasError() { - // TODO Auto-generated method stub - return false; - } - - @Override - public DriverError getError() { - // TODO Auto-generated method stub - return null; - } - - @Override - public void checkErrors() throws BuildFailureException { - // TODO Auto-generated method stub - - } - - @Override - public void initialize() throws VersionException { - isInitialized = true; - } - - @Override - public void uninitialize() { - isInitialized = false; - } - - @Override - public boolean isInitialized() { - // TODO Auto-generated method stub - return isInitialized; - } - - @Override - public void dispose() { - // TODO Auto-generated method stub - - } - - @Override - public MachineModel getMachine() { - return machineModel; - } - - @Override - public void setMachine(MachineModel m) { - machineModel = m; - } - - @Override - public String getDriverName() { - // TODO Auto-generated method stub - return "VirtualPrinter"; - } - - @Override - public String getFirmwareInfo() { - // TODO Auto-generated method stub - return firmwareInfo; - } - - @Override - public Version getVersion() { - return version; - } - - @Override - public void updateManualControl() { - // TODO Auto-generated method stub - - } - - @Override - public Version getMinimumVersion() { - // TODO Auto-generated method stub - return minimumVersion; - } - - @Override - public Version getPreferredVersion() { - // TODO Auto-generated method stub - return preferredVersion; - } - - @Override - public void setCurrentPosition(Point5d p) throws RetryException { - currentPosition = p; - } - - @Override - public void storeHomePositions(EnumSet axes) throws RetryException { - // TODO Auto-generated method stub - - } - - @Override - public void recallHomePositions(EnumSet axes) throws RetryException { - // TODO Auto-generated method stub - - } - - @Override - public boolean positionLost() { - // TODO Auto-generated method stub - return false; - } - - @Override - public Point5d getCurrentPosition(boolean update) { - // Note that we don't have a - if (currentPosition == null) { - currentPosition = new Point5d(); - } - return currentPosition; - } - - @Override - public void invalidatePosition() { - currentPosition = null; - } - - @Override - public void queuePoint(Point5d p) throws RetryException { - currentPosition = p; - } - - @Override - public Point3d getOffset(int i) { - return currentOffset[i]; - } - - @Override - public void setOffsetX(int i, double j) { - currentOffset[i].x = j; - - } - - @Override - public void setOffsetY(int i, double j) { - currentOffset[i].y = j; - - } - - @Override - public void setOffsetZ(int i, double j) { - currentOffset[i].z = j; - - } - - @Override - public Point5d getPosition() { - // TODO Auto-generated method stub - return currentPosition; - } - - @Override - public void requestToolChange(int toolIndex, int timeout) - throws RetryException { - // TODO Auto-generated method stub - - } - - @Override - public void selectTool(int toolIndex) throws RetryException { - // TODO Auto-generated method stub - - } - - @Override - public void setFeedrate(double feed) { - // TODO Auto-generated method stub - - } - - @Override - public double getCurrentFeedrate() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public void homeAxes(EnumSet axes, boolean positive, double feedrate) - throws RetryException { - // TODO Auto-generated method stub - - } - - @Override - public void delay(long millis) throws RetryException { - // TODO Auto-generated method stub - - } - - @Override - public void openClamp(int clampIndex) { - // TODO Auto-generated method stub - - } - - @Override - public void closeClamp(int clampIndex) { - // TODO Auto-generated method stub - - } - - @Override - public void enableDrives() throws RetryException { - // TODO Auto-generated method stub - - } - - @Override - public void disableDrives() throws RetryException { - // TODO Auto-generated method stub - - } - - - public void enableAxes(EnumSet axes) throws RetryException { - // Not all drivers support this method. - } - - public void disableAxes(EnumSet axes) throws RetryException { - // Not all drivers support this method. - } - - @Override - public void changeGearRatio(int ratioIndex) { - // TODO Auto-generated method stub - - } - - @Override - public void readToolStatus() { - // TODO Auto-generated method stub - - } - - @Override - public int getToolStatus() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public void setMotorDirection(int dir) { - // TODO Auto-generated method stub - - } - - @Override - public void setMotorRPM(double rpm, int toolhead) throws RetryException { - // TODO Auto-generated method stub - - } - - @Override - public void setMotorSpeedPWM(int pwm) throws RetryException { - // TODO Auto-generated method stub - - } - - @Override - public double getMotorRPM() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public int getMotorSpeedPWM() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public void enableMotor() throws RetryException { - // TODO Auto-generated method stub - - } - - @Override - public void enableMotor(long millis) throws RetryException { - // TODO Auto-generated method stub - - } - - @Override - public void disableMotor() throws RetryException { - // TODO Auto-generated method stub - - } - - @Override - public void setSpindleRPM(double rpm) throws RetryException { - // TODO Auto-generated method stub - - } - - @Override - public void setSpindleSpeedPWM(int pwm) throws RetryException { - // TODO Auto-generated method stub - - } - - @Override - public void setSpindleDirection(int dir) { - // TODO Auto-generated method stub - - } - - @Override - public double getSpindleRPM() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public int getSpindleSpeedPWM() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public void enableSpindle() throws RetryException { - // TODO Auto-generated method stub - - } - - @Override - public void disableSpindle() throws RetryException { - // TODO Auto-generated method stub - - } - - @Override - public void setTemperature(double temperature) throws RetryException { - toolTemperature = temperature; - toolTemperatureSetting = temperature; - } - - @Override - public void setTemperature(double temperature, int toolhead) throws RetryException { - toolTemperature = temperature; - toolTemperatureSetting = temperature; - } - - @Override - public void readTemperature() { - } - - @Override - @Deprecated - public double getTemperature() { - return toolTemperature; - } - - @Override - public double getTemperature(int toolheadIndex) { - return toolTemperature; - } - - @Override - public double getTemperatureSetting() { - return toolTemperatureSetting; - } - - @Override - public void setPlatformTemperature(double temperature) - throws RetryException { - platformTemperature = temperature; - platformTemperatureSetting = temperature; - } - - @Override - public void setPlatformTemperature(double temperature, int toolhead) throws RetryException { - platformTemperature = temperature; - platformTemperatureSetting = temperature; - } - - - @Override - public void readPlatformTemperature() { - } - - @Override - public double getPlatformTemperature() { - return platformTemperature; - } - - /** relies on timing to have the 'right selected toolhead', deprecated */ - @Override - @Deprecated - public double getPlatformTemperature(int toolheadIndex) { - return platformTemperature; - } - - @Override - public double getPlatformTemperatureSetting() { - return platformTemperatureSetting; - } - - @Override - public void setChamberTemperature(double temperature) { - // TODO Auto-generated method stub - - } - - @Override - public void readChamberTemperature() { - // TODO Auto-generated method stub - - } - - @Override - public double getChamberTemperature() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public void enableFloodCoolant() { - // TODO Auto-generated method stub - - } - - @Override - public void disableFloodCoolant() { - // TODO Auto-generated method stub - - } - - @Override - public void enableMistCoolant() { - // TODO Auto-generated method stub - - } - - @Override - public void disableMistCoolant() { - // TODO Auto-generated method stub - - } - - @Override - public void enableFan() throws RetryException { - // TODO Auto-generated method stub - - } - - @Override - public void disableFan() throws RetryException { - // TODO Auto-generated method stub - - } - - @Override - public void setAutomatedBuildPlatformRunning(boolean state) throws RetryException { - //TODO: manually added - } - - @Override - public void openValve() throws RetryException { - // TODO Auto-generated method stub - - } - - @Override - public void closeValve() throws RetryException { - // TODO Auto-generated method stub - - } - - public void setStepperVoltage(int stepperId, int referenceValue) - { - Base.logger.finer("VirtualPrinter::setStepperVoltage"); - //generated method stub - } - - public int getStepperVoltage(int stepperId) - { - Base.logger.finer("VirtualPrinter::setStepperVoltage"); - return 0; - //generated method stub - } - - - public void storeStepperVoltage(int stepperId, int referenceValue) - { - Base.logger.finer("VirtualPrinter::storeStepperVoltage"); - //generated method stub - } - - - public void setLedStrip(Color color, int effectId) - { - Base.logger.finer("VirtualPrinter::setLedStrip"); - //generated method stub - } - - - public void sendBeep(int frequencyHz, int durationMs,int effect) throws RetryException - { - Base.logger.finer("VirtualPrinter::sendBeep"); - //generated method stub - } - - - @Override - public void openCollet() { - // TODO Auto-generated method stub - - } - - @Override - public void closeCollet() { - // TODO Auto-generated method stub - - } - - @Override - public void pause() { - // TODO Auto-generated method stub - - } - - @Override - public void unpause() { - // TODO Auto-generated method stub - - } - - @Override - public void stop(boolean abort) { - // TODO Auto-generated method stub - - } - - @Override - public boolean hasSoftStop() { - // TODO Auto-generated method stub - return hasSoftStop; - } - - @Override - public boolean hasEmergencyStop() { - // TODO Auto-generated method stub - return hasEStop; - } - - @Override - public void reset() { - // TODO Auto-generated method stub - - } - - @Override - public boolean heartbeat() { - // TODO Auto-generated method stub - return false; - } - - @Override - public Point5d getMaximumFeedrates() { - // TODO Auto-generated method stub - return maximumFeedrates; - } - - @Override - public boolean hasAutomatedBuildPlatform() { - // TODO Auto-generated method stub - return true; - } - - @Override - public void readAllTemperatures() { - // TODO Auto-generated method stub - - } - - @Override - public void readAllPlatformTemperatures() { - // TODO Auto-generated method stub - - } - - - @Override - public void setMotorDirection(int dir, int toolhead) { - // TODO Auto-generated method stub - - } - - @Override - public void setMotorSpeedPWM(int pwm, int toolhead) throws RetryException { - // TODO Auto-generated method stub - - } - - @Override - public void enableMotor(int toolhead) throws RetryException { - // TODO Auto-generated method stub - - } - - @Override - public void enableMotor(long millis, int toolhead) throws RetryException { - // TODO Auto-generated method stub - - } - - @Override - public void disableMotor(int toolhead) throws RetryException { - // TODO Auto-generated method stub - - } - - @Override - public void enableFan(int toolhead) throws RetryException { - // TODO Auto-generated method stub - - } - - @Override - public void disableFan(int toolhead) throws RetryException { - // TODO Auto-generated method stub - - } - - @Override - public void setAutomatedBuildPlatformRunning(boolean state, int toolhead) - throws RetryException { - // TODO Auto-generated method stub - - } - -} From 77bf80a2c280dabea12faf8394e526959bfc48fc Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Fri, 9 Mar 2012 18:10:29 -0800 Subject: [PATCH 15/35] Fixed infinite recursion in setMotorDirection. Clearly, this method is never called. --- src/replicatorg/drivers/DriverBaseImplementation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/replicatorg/drivers/DriverBaseImplementation.java b/src/replicatorg/drivers/DriverBaseImplementation.java index c6b5a874c..8a9272714 100644 --- a/src/replicatorg/drivers/DriverBaseImplementation.java +++ b/src/replicatorg/drivers/DriverBaseImplementation.java @@ -455,7 +455,7 @@ protected Point5d getDelta(Point5d p) { * @deprecated **************************************************************************/ @Deprecated @Override public void setMotorDirection(int dir) { - this.setMotorDirection(machine.currentTool().getIndex()); + this.setMotorDirection(dir, machine.currentTool().getIndex()); } @Override From 49bf43bfad4b5df94e20ae34b92dd0d9c400697c Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Fri, 9 Mar 2012 18:17:18 -0800 Subject: [PATCH 16/35] Added @Overrides in two virtual drivers. --- src/replicatorg/drivers/EstimationDriver.java | 6 +++--- src/replicatorg/drivers/SimulationDriver.java | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/replicatorg/drivers/EstimationDriver.java b/src/replicatorg/drivers/EstimationDriver.java index 914855a56..d55e18c0b 100644 --- a/src/replicatorg/drivers/EstimationDriver.java +++ b/src/replicatorg/drivers/EstimationDriver.java @@ -46,11 +46,11 @@ public EstimationDriver() { public Rectangle2D.Double getBounds() { return bounds; } - public void delay(long millis) { + @Override public void delay(long millis) { buildTime += (double) millis / 1000; } - protected Point5d reconcilePosition() { + @Override protected Point5d reconcilePosition() { // The estimation driver doesn't even care where it is. return new Point5d(); } @@ -60,7 +60,7 @@ protected Point5d reconcilePosition() { * @param p The point, in mm. * @throws RetryException */ - public void queuePoint(Point5d p) throws RetryException { + @Override public void queuePoint(Point5d p) throws RetryException { Point5d delta = getDelta(p); // add to the total length diff --git a/src/replicatorg/drivers/SimulationDriver.java b/src/replicatorg/drivers/SimulationDriver.java index d75111513..ead18a0c6 100644 --- a/src/replicatorg/drivers/SimulationDriver.java +++ b/src/replicatorg/drivers/SimulationDriver.java @@ -59,12 +59,12 @@ public void destroyWindow() { simulation = null; } - public void dispose() { + @Override public void dispose() { destroyWindow(); super.dispose(); } - public void queuePoint(Point5d p) throws RetryException { + @Override public void queuePoint(Point5d p) throws RetryException { simulation.queuePoint(p); super.queuePoint(p); @@ -103,7 +103,7 @@ public void homeZ() throws RetryException { queuePoint(pos); } - protected Point5d reconcilePosition() { + @Override protected Point5d reconcilePosition() { // Initial position irrelevant for this driver; it's all relative to the start pos return new Point5d(); } From 0b374df91b32911d17f47e60a79193b73d889435 Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Fri, 9 Mar 2012 19:01:22 -0800 Subject: [PATCH 17/35] Modernizing Driver's API. ReplicatorG is lurching toward supporting multiple toolheads. The Sanguino3G driver, in particular, has versions of methods like readToolStatus or getMotorSpeedPWM that take an explicit toolhead index. Unfortunately, as shown by my previous commit that moved those methods to private, nothing ever called them. This is because the rest of the code uses the Driver interface, which has only *some* of these methods. The migration was partial. This commit finishes it, with the exception of some little-used features that I don't understand well enough to test (collets, for one). All Driver methods that apply to toolheads now take an explicit index. The old versions are still here, but they're explicitly @Deprecated, so I can easily find all callers to modernize them, too. In a surprising bit of honesty, the code describes the practice of interpreting tool -1 to indicate "current tool" as a "fast hack to get software out." I am perpetuating the fast hack in this commit: all the deprecated methods forward to the modern ones, but with a tool index of -1. I will fix this in a subsequent change. Note that the RepRap drivers are not fully prepared to support multitool, and this commit does not change that. --- src/replicatorg/drivers/Driver.java | 59 +++-- .../drivers/DriverBaseImplementation.java | 130 +++++++---- .../drivers/SerialPassthroughDriver.java | 148 ++++++------ .../drivers/gen3/Makerbot4GDriver.java | 12 +- .../drivers/gen3/Sanguino3GDriver.java | 37 +-- .../drivers/reprap/ExtrusionUpdater.java | 4 +- .../drivers/reprap/RepRap5DDriver.java | 221 +++++++++--------- .../drivers/reprap/SimpleRepRap5DDriver.java | 165 +++++++------ 8 files changed, 401 insertions(+), 375 deletions(-) diff --git a/src/replicatorg/drivers/Driver.java b/src/replicatorg/drivers/Driver.java index 59dfd7fc6..c8bfc4123 100644 --- a/src/replicatorg/drivers/Driver.java +++ b/src/replicatorg/drivers/Driver.java @@ -263,9 +263,12 @@ public interface Driver { */ public void changeGearRatio(int ratioIndex); - public void readToolStatus(); + @Deprecated public void readToolStatus(); + public void readToolStatus(int toolhead); + + @Deprecated public int getToolStatus(); + public int getToolStatus(int toolhead); - public int getToolStatus(); /*************************************************************************** * Motor interface functions @@ -278,9 +281,11 @@ public interface Driver { @Deprecated public void setMotorSpeedPWM(int pwm) throws RetryException; public void setMotorSpeedPWM(int pwm, int toolhead) throws RetryException; - public double getMotorRPM(); + @Deprecated public double getMotorRPM(); + public double getMotorRPM(int toolhead); - public int getMotorSpeedPWM(); + @Deprecated public int getMotorSpeedPWM(); + public int getMotorSpeedPWM(int toolhead); /** * Enable motor until stopped by disableMotor @@ -303,19 +308,26 @@ public interface Driver { * Spindle interface functions * @throws RetryException **************************************************************************/ - public void setSpindleRPM(double rpm) throws RetryException; + @Deprecated public void setSpindleRPM(double rpm) throws RetryException; + public void setSpindleRPM(double rpm, int toolhead) throws RetryException; - public void setSpindleSpeedPWM(int pwm) throws RetryException; + @Deprecated public void setSpindleSpeedPWM(int pwm) throws RetryException; + public void setSpindleSpeedPWM(int pwm, int toolhead) throws RetryException; - public void setSpindleDirection(int dir); + @Deprecated public void setSpindleDirection(int dir); + public void setSpindleDirection(int dir, int toolhead); - public double getSpindleRPM(); + @Deprecated public double getSpindleRPM(); + public double getSpindleRPM(int toolhead); - public int getSpindleSpeedPWM(); + @Deprecated public int getSpindleSpeedPWM(); + public int getSpindleSpeedPWM(int toolhead); - public void enableSpindle() throws RetryException; + @Deprecated public void enableSpindle() throws RetryException; + public void enableSpindle(int toolhead) throws RetryException; - public void disableSpindle() throws RetryException; + @Deprecated public void disableSpindle() throws RetryException; + public void disableSpindle(int toolhead) throws RetryException; /*************************************************************************** * Temperature interface functions @@ -323,11 +335,15 @@ public interface Driver { **************************************************************************/ @Deprecated public void setTemperature(double temperature) throws RetryException; public void setTemperature(double temperature, int toolIndex) throws RetryException; - public void readTemperature(); - public double getTemperature(); + @Deprecated public void readTemperature(); + public void readTemperature(int toolhead); + + @Deprecated public double getTemperature(); + public double getTemperature(int toolhead); - public double getTemperatureSetting(); + @Deprecated public double getTemperatureSetting(); + public double getTemperatureSetting(int toolhead); /*************************************************************************** * Platform Temperature interface functions @@ -336,11 +352,14 @@ public interface Driver { @Deprecated public void setPlatformTemperature(double temperature) throws RetryException; public void setPlatformTemperature(double temperature, int toolIndex) throws RetryException; - public void readPlatformTemperature(); + @Deprecated public void readPlatformTemperature(); + public void readPlatformTemperature(int toolhead); - public double getPlatformTemperature(); + @Deprecated public double getPlatformTemperature(); + public double getPlatformTemperature(int toolhead); - public double getPlatformTemperatureSetting(); + @Deprecated public double getPlatformTemperatureSetting(); + public double getPlatformTemperatureSetting(int toolhead); /*************************************************************************** * Build chamber interface functions @@ -387,9 +406,11 @@ public interface Driver { * Valve interface functions * @throws RetryException **************************************************************************/ - public void openValve() throws RetryException; + @Deprecated public void openValve() throws RetryException; + public void openValve(int toolhead) throws RetryException; - public void closeValve() throws RetryException; + @Deprecated public void closeValve() throws RetryException; + public void closeValve(int toolhead) throws RetryException; /************************************************************************* * Potentiometer interface diff --git a/src/replicatorg/drivers/DriverBaseImplementation.java b/src/replicatorg/drivers/DriverBaseImplementation.java index 8a9272714..ac40fe0a8 100644 --- a/src/replicatorg/drivers/DriverBaseImplementation.java +++ b/src/replicatorg/drivers/DriverBaseImplementation.java @@ -452,7 +452,6 @@ protected Point5d getDelta(Point5d p) { /*************************************************************************** * Motor interface functions - * @deprecated **************************************************************************/ @Deprecated @Override public void setMotorDirection(int dir) { this.setMotorDirection(dir, machine.currentTool().getIndex()); @@ -533,12 +532,22 @@ public void disableMotor() throws RetryException { } - @Override public double getMotorRPM() { - return machine.currentTool().getMotorSpeedRPM(); + @Deprecated @Override public double getMotorRPM() { + return getMotorRPM(-1); + } + + @Override public double getMotorRPM(int toolhead) { + if (toolhead == -1) toolhead = machine.currentTool().getIndex(); + return machine.getTool(toolhead).getMotorSpeedRPM(); } - @Override public int getMotorSpeedPWM() { - return machine.currentTool().getMotorSpeedReadingPWM(); + @Deprecated @Override public int getMotorSpeedPWM() { + return getMotorSpeedPWM(-1); + } + + @Override public int getMotorSpeedPWM(int toolhead) { + if (toolhead == -1) toolhead = machine.currentTool().getIndex(); + return machine.getTool(toolhead).getMotorSpeedPWM(); } public double getMotorSteps() { @@ -546,81 +555,97 @@ public double getMotorSteps() { } // TODO: These are backwards? - @Override public void readToolStatus() { + @Deprecated @Override public void readToolStatus() { + readToolStatus(-1); + } + + @Override public void readToolStatus(int toolhead) { + + } + + @Deprecated @Override public int getToolStatus() { + return getToolStatus(-1); } - @Override public int getToolStatus() { - readToolStatus(); + @Override public int getToolStatus(int toolhead) { + if (toolhead == -1) toolhead = machine.currentTool().getIndex(); + readToolStatus(toolhead); - return machine.currentTool().getToolStatus(); + return machine.getTool(toolhead).getToolStatus(); } - /*************************************************************************** * Spindle interface functions + * @deprecated **************************************************************************/ - @Override public void setSpindleDirection(int dir) { - machine.currentTool().setSpindleDirection(dir); + @Deprecated @Override public void setSpindleDirection(int dir) { + setSpindleDirection(dir, -1); + } + + @Deprecated @Override public void setSpindleDirection(int dir, int toolhead) { + if (toolhead == -1) toolhead = machine.currentTool().getIndex(); + machine.getTool(toolhead).setSpindleDirection(dir); } - @Override public void setSpindleRPM(double rpm) throws RetryException { + @Deprecated @Override public void setSpindleRPM(double rpm) throws RetryException { setSpindleRPM(rpm, -1); } - @Override public void setSpindleSpeedPWM(int pwm) throws RetryException { + @Deprecated @Override public void setSpindleSpeedPWM(int pwm) throws RetryException { setSpindleSpeedPWM(pwm, -1); } - @Override public void enableSpindle() throws RetryException { + @Deprecated @Override public void enableSpindle() throws RetryException { enableSpindle(-1); } - @Override public void disableSpindle() throws RetryException { + @Deprecated @Override public void disableSpindle() throws RetryException { disableSpindle(-1); } - /* - * N.B. the methods below are dead code! They should be added - * to the Driver interface. - */ - - public void setSpindleRPM(double rpm, int toolhead) throws RetryException { + @Override public void setSpindleRPM(double rpm, int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); machine.getTool(toolhead).setSpindleSpeedRPM(rpm); } - public void setSpindleSpeedPWM(int pwm, int toolhead) throws RetryException { + @Override public void setSpindleSpeedPWM(int pwm, int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); machine.getTool(toolhead).setSpindleSpeedPWM(pwm); } - public void enableSpindle(int toolhead) throws RetryException { + @Override public void enableSpindle(int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); machine.getTool(toolhead).enableSpindle(); } - public void disableSpindle(int toolhead) throws RetryException { + @Override public void disableSpindle(int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); machine.getTool(toolhead).disableSpindle(); } - /* - * End of dead code. - */ - - @Override public double getSpindleRPM() { - return machine.currentTool().getSpindleSpeedReadingRPM(); + @Deprecated @Override public double getSpindleRPM() { + return getSpindleRPM(-1); + } + + @Override public double getSpindleRPM(int toolhead) { + if (toolhead == -1) toolhead = machine.currentTool().getIndex(); + return machine.getTool(toolhead).getSpindleSpeedReadingRPM(); } - @Override public int getSpindleSpeedPWM() { + @Deprecated @Override public int getSpindleSpeedPWM() { + return getSpindleSpeedPWM(-1); + } + + @Override public int getSpindleSpeedPWM(int toolhead) { + if (toolhead == -1) toolhead = machine.currentTool().getIndex(); return machine.currentTool().getSpindleSpeedReadingPWM(); } @@ -642,12 +667,11 @@ public void setTemperature(double temperature, int toolhead) throws RetryExcepti machine.getTool(toolhead).setTargetTemperature(temperature); } - @Override public void readTemperature() { - + @Deprecated @Override public void readTemperature() { + readTemperature(-1); } - // Dead code! - public void readTemperature(int toolhead) { + @Override public void readTemperature(int toolhead) { } @@ -690,7 +714,7 @@ public void readPlatformTemperature() { this.readPlatformTemperature(-1); } - public void readPlatformTemperature(int toolhead) { + @Override public void readPlatformTemperature(int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -778,8 +802,7 @@ public void setAutomatedBuildPlatformRunning(boolean state, int toolhead) return hasAutomatedBuildPlatform(-1); } - // Dead code! - public boolean hasAutomatedBuildPlatform(int toolhead) + private boolean hasAutomatedBuildPlatform(int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -789,23 +812,22 @@ public boolean hasAutomatedBuildPlatform(int toolhead) /*************************************************************************** * Valve interface functions * @throws RetryException + * @deprecated **************************************************************************/ - @Override public void openValve() throws RetryException { + @Deprecated @Override public void openValve() throws RetryException { openValve(-1); } - @Override public void closeValve() throws RetryException { + @Deprecated @Override public void closeValve() throws RetryException { closeValve(-1); } - // Dead code! - public void openValve(int toolhead) throws RetryException { + @Override public void openValve(int toolhead) throws RetryException { if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); machine.getTool(toolhead).openValve(); } - // Dead code! - public void closeValve(int toolhead) throws RetryException { + @Override public void closeValve(int toolhead) throws RetryException { if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); machine.getTool(toolhead).closeValve(); } @@ -886,12 +908,22 @@ public void closeValve(int toolhead) throws RetryException { @Override public void setChamberTemperature(double temperature) { } - @Override public double getPlatformTemperatureSetting() { - return machine.currentTool().getPlatformTargetTemperature(); + @Deprecated @Override public double getPlatformTemperatureSetting() { + return getPlatformTemperatureSetting(-1); + } + + @Override public double getPlatformTemperatureSetting(int toolhead) { + if (toolhead == -1) toolhead = machine.currentTool().getIndex(); + return machine.getTool(toolhead).getPlatformTargetTemperature(); } - @Override public double getTemperatureSetting() { - return machine.currentTool().getTargetTemperature(); + @Deprecated @Override public double getTemperatureSetting() { + return getTemperatureSetting(-1); + } + + @Override public double getTemperatureSetting(int toolhead) { + if (toolhead == -1) toolhead = machine.currentTool().getIndex(); + return machine.getTool(toolhead).getTargetTemperature(); } @Override public void storeHomePositions(EnumSet axes) throws RetryException { diff --git a/src/replicatorg/drivers/SerialPassthroughDriver.java b/src/replicatorg/drivers/SerialPassthroughDriver.java index a1b254bae..adb797849 100644 --- a/src/replicatorg/drivers/SerialPassthroughDriver.java +++ b/src/replicatorg/drivers/SerialPassthroughDriver.java @@ -24,16 +24,12 @@ package replicatorg.drivers; import java.io.IOException; -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; import java.text.NumberFormat; import java.util.Date; import java.util.EnumSet; import java.util.LinkedList; import java.util.Queue; -import org.w3c.dom.Node; - import replicatorg.app.Base; import replicatorg.machine.model.AxisId; import replicatorg.machine.model.ToolModel; @@ -76,11 +72,7 @@ public SerialPassthroughDriver() { setInitialized(false); } - public void loadXML(Node xml) { - super.loadXML(xml); - } - - public void initialize() { + @Override public void initialize() { // declare our serial guy. if (serial == null) { Base.logger.severe("No Serial Port found.\n"); @@ -117,14 +109,14 @@ public void initialize() { sendCommand("G90"); } - public boolean isPassthroughDriver() { + @Override public boolean isPassthroughDriver() { return true; } /** * Actually execute the GCode we just parsed. */ - public void executeGCodeLine(String code) { + @Override public void executeGCodeLine(String code) { // we *DONT* want to use the parents one, // as that will call all sorts of misc functions. // we'll simply pass it along. @@ -236,14 +228,14 @@ else if (line.startsWith("start")) { } } - public boolean isFinished() { + @Override public boolean isFinished() { return isBufferEmpty(); } /** * Is our buffer empty? If don't have a buffer, its always true. */ - public boolean isBufferEmpty() { + @Override public boolean isBufferEmpty() { try { readResponse(); } catch (Exception e) { @@ -251,7 +243,7 @@ public boolean isBufferEmpty() { return (bufferSize == 0); } - public void dispose() { + @Override public void dispose() { super.dispose(); commands = null; } @@ -262,7 +254,7 @@ public void dispose() { **************************************************************************/ // FIXME: 5D port - public void queuePoint(Point5d p) throws RetryException { + @Override public void queuePoint(Point5d p) throws RetryException { // Redundant feedrate send added in Ultimaker merge. TODO: ask Erik, D1plo1d about this. String cmd = "G1 F" + df.format(getCurrentFeedrate()); @@ -277,7 +269,7 @@ public void queuePoint(Point5d p) throws RetryException { } // FIXME: 5D port - public void setCurrentPosition(Point5d p) throws RetryException { + @Override public void setCurrentPosition(Point5d p) throws RetryException { sendCommand("G92 X" + df.format(p.x()) + " Y" + df.format(p.y()) + " Z" + df.format(p.z())); @@ -294,7 +286,7 @@ public void homeAxes(EnumSet axes) throws RetryException { super.homeAxes(axes,false,0); } - public void delay(long millis) { + @Override public void delay(long millis) { int seconds = Math.round(millis / 1000); sendCommand("G4 P" + seconds); @@ -302,31 +294,31 @@ public void delay(long millis) { // no super call requried. } - public void openClamp(int clampIndex) { + @Override public void openClamp(int clampIndex) { sendCommand("M11 Q" + clampIndex); super.openClamp(clampIndex); } - public void closeClamp(int clampIndex) { + @Override public void closeClamp(int clampIndex) { sendCommand("M10 Q" + clampIndex); super.closeClamp(clampIndex); } - public void enableDrives() throws RetryException { + @Override public void enableDrives() throws RetryException { sendCommand("M17"); super.enableDrives(); } - public void disableDrives() throws RetryException { + @Override public void disableDrives() throws RetryException { sendCommand("M18"); super.disableDrives(); } - public void changeGearRatio(int ratioIndex) { + @Override public void changeGearRatio(int ratioIndex) { // gear ratio codes are M40-M46 int code = 40 + ratioIndex; code = Math.max(40, code); @@ -337,28 +329,32 @@ public void changeGearRatio(int ratioIndex) { super.changeGearRatio(ratioIndex); } - private String _getToolCode() { - return "T" + machine.currentTool().getIndex() + " "; + private String _getCurrentToolCode() { + return _getToolCode(machine.currentTool().getIndex()); + } + + private String _getToolCode(int index) { + return "T" + (index == -1 ? machine.currentTool().getIndex() : index) + " "; } /*************************************************************************** * Motor interface functions * @throws RetryException **************************************************************************/ - public void setMotorRPM(double rpm, int toolhead) throws RetryException { - sendCommand(_getToolCode() + "M108 R" + df.format(rpm)); + @Override public void setMotorRPM(double rpm, int toolhead) throws RetryException { + sendCommand(_getToolCode(toolhead) + "M108 R" + df.format(rpm)); super.setMotorRPM(rpm, toolhead); } - public void setMotorSpeedPWM(int pwm) throws RetryException { - sendCommand(_getToolCode() + "M108 S" + df.format(pwm)); + @Override public void setMotorSpeedPWM(int pwm, int toolhead) throws RetryException { + sendCommand(_getToolCode(toolhead) + "M108 S" + df.format(pwm)); - super.setMotorSpeedPWM(pwm); + super.setMotorSpeedPWM(pwm, toolhead); } - public void enableMotor() throws RetryException { - String command = _getToolCode(); + @Override public void enableMotor(int toolhead) throws RetryException { + String command = _getToolCode(toolhead); if (machine.currentTool().getMotorDirection() == ToolModel.MOTOR_CLOCKWISE) command += "M101"; @@ -367,27 +363,27 @@ public void enableMotor() throws RetryException { sendCommand(command); - super.enableMotor(); + super.enableMotor(toolhead); } - public void disableMotor() throws RetryException { - sendCommand(_getToolCode() + "M103"); + @Override public void disableMotor(int toolhead) throws RetryException { + sendCommand(_getToolCode(toolhead) + "M103"); - super.disableMotor(); + super.disableMotor(toolhead); } /*************************************************************************** * Spindle interface functions * @throws RetryException **************************************************************************/ - public void setSpindleRPM(double rpm) throws RetryException { - sendCommand(_getToolCode() + "S" + df.format(rpm)); + @Override public void setSpindleRPM(double rpm, int toolhead) throws RetryException { + sendCommand(_getToolCode(toolhead) + "S" + df.format(rpm)); - super.setSpindleRPM(rpm); + super.setSpindleRPM(rpm, toolhead); } - public void enableSpindle() throws RetryException { - String command = _getToolCode(); + @Override public void enableSpindle(int toolhead) throws RetryException { + String command = _getToolCode(toolhead); if (machine.currentTool().getSpindleDirection() == ToolModel.MOTOR_CLOCKWISE) command += "M3"; @@ -396,42 +392,42 @@ public void enableSpindle() throws RetryException { sendCommand(command); - super.enableSpindle(); + super.enableSpindle(toolhead); } - public void disableSpindle() throws RetryException { - sendCommand(_getToolCode() + "M5"); + @Override public void disableSpindle(int toolhead) throws RetryException { + sendCommand(_getToolCode(toolhead) + "M5"); - super.disableSpindle(); + super.disableSpindle(toolhead); } /*************************************************************************** * Temperature interface functions * @throws RetryException **************************************************************************/ - public void setTemperature(double temperature) throws RetryException { - sendCommand(_getToolCode() + "M104 S" + df.format(temperature)); + @Override public void setTemperature(double temperature, int toolhead) throws RetryException { + sendCommand(_getToolCode(toolhead) + "M104 S" + df.format(temperature)); - super.setTemperature(temperature); + super.setTemperature(temperature, toolhead); } - public void readTemperature() { - sendCommand(_getToolCode() + "M105"); + @Override public void readTemperature(int toolhead) { + sendCommand(_getToolCode(toolhead) + "M105"); - super.readTemperature(); + super.readTemperature(toolhead); } /*************************************************************************** * Flood Coolant interface functions **************************************************************************/ - public void enableFloodCoolant() { - sendCommand(_getToolCode() + "M7"); + @Override public void enableFloodCoolant() { + sendCommand(_getCurrentToolCode() + "M7"); super.enableFloodCoolant(); } - public void disableFloodCoolant() { - sendCommand(_getToolCode() + "M9"); + @Override public void disableFloodCoolant() { + sendCommand(_getCurrentToolCode() + "M9"); super.disableFloodCoolant(); } @@ -439,14 +435,14 @@ public void disableFloodCoolant() { /*************************************************************************** * Mist Coolant interface functions **************************************************************************/ - public void enableMistCoolant() { - sendCommand(_getToolCode() + "M8"); + @Override public void enableMistCoolant() { + sendCommand(_getCurrentToolCode() + "M8"); super.enableMistCoolant(); } - public void disableMistCoolant() { - sendCommand(_getToolCode() + "M9"); + @Override public void disableMistCoolant() { + sendCommand(_getCurrentToolCode() + "M9"); super.disableMistCoolant(); } @@ -455,56 +451,56 @@ public void disableMistCoolant() { * Fan interface functions * @throws RetryException **************************************************************************/ - public void enableFan() throws RetryException { - sendCommand(_getToolCode() + "M106"); + @Override public void enableFan(int toolhead) throws RetryException { + sendCommand(_getToolCode(toolhead) + "M106"); - super.enableFan(); + super.enableFan(toolhead); } - public void disableFan() throws RetryException { - sendCommand(_getToolCode() + "M107"); + @Deprecated @Override public void disableFan(int toolhead) throws RetryException { + sendCommand(_getToolCode(toolhead) + "M107"); - super.disableFan(); + super.disableFan(toolhead); } /*************************************************************************** * Valve interface functions * @throws RetryException **************************************************************************/ - public void openValve() throws RetryException { - sendCommand(_getToolCode() + "M126"); + @Deprecated @Override public void openValve(int toolhead) throws RetryException { + sendCommand(_getToolCode(toolhead) + "M126"); - super.openValve(); + super.openValve(toolhead); } - public void closeValve() throws RetryException { - sendCommand(_getToolCode() + "M127"); + @Deprecated @Override public void closeValve(int toolhead) throws RetryException { + sendCommand(_getToolCode(toolhead) + "M127"); - super.closeValve(); + super.closeValve(toolhead); } /*************************************************************************** * Collet interface functions **************************************************************************/ - public void openCollet() { - sendCommand(_getToolCode() + "M21"); + @Override public void openCollet() { + sendCommand(_getCurrentToolCode() + "M21"); super.openCollet(); } - public void closeCollet() { - sendCommand(_getToolCode() + "M22"); + @Override public void closeCollet() { + sendCommand(_getCurrentToolCode() + "M22"); super.closeCollet(); } - public void reset() { + @Override public void reset() { Base.logger.info("Reset."); setInitialized(false); initialize(); } - protected Point5d reconcilePosition() { + @Override protected Point5d reconcilePosition() { return new Point5d(); } } diff --git a/src/replicatorg/drivers/gen3/Makerbot4GDriver.java b/src/replicatorg/drivers/gen3/Makerbot4GDriver.java index 5208e8023..f2a1e7c24 100644 --- a/src/replicatorg/drivers/gen3/Makerbot4GDriver.java +++ b/src/replicatorg/drivers/gen3/Makerbot4GDriver.java @@ -140,7 +140,7 @@ protected Point5d reconcilePosition() { */ @Override public void enableMotor(int toolhead) throws RetryException { if (toolhead == -1 ) toolhead = machine.currentTool().getIndex(); - machine.currentTool().enableMotor(); + machine.getTool(toolhead).enableMotor(); } /** @@ -148,16 +148,16 @@ protected Point5d reconcilePosition() { */ @Override public void disableMotor(int toolhead) throws RetryException { if (toolhead == -1 ) toolhead = machine.currentTool().getIndex(); - machine.currentTool().disableMotor(); + machine.getTool(toolhead).disableMotor(); } /** * Overridden to not talk to the DC motor driver. This driver is reused for the stepper motor fan - * @deprecated */ - @Deprecated @Override - public void setMotorSpeedPWM(int pwm) throws RetryException { - machine.currentTool().setMotorSpeedPWM(pwm); + @Override + public void setMotorSpeedPWM(int pwm, int toolhead) throws RetryException { + if (toolhead == -1) toolhead = machine.currentTool().getIndex(); + machine.getTool(toolhead).setMotorSpeedPWM(pwm); } /** diff --git a/src/replicatorg/drivers/gen3/Sanguino3GDriver.java b/src/replicatorg/drivers/gen3/Sanguino3GDriver.java index 5debbfe04..6d23e4371 100644 --- a/src/replicatorg/drivers/gen3/Sanguino3GDriver.java +++ b/src/replicatorg/drivers/gen3/Sanguino3GDriver.java @@ -933,12 +933,6 @@ private int axesToBitfield(EnumSet axes) { super.setMotorRPM(rpm, toolhead); } - - @Deprecated @Override public void setMotorSpeedPWM(int pwm) throws RetryException { - this.setMotorSpeedPWM(pwm, machine.currentTool().getIndex()); - } - - @Override public void setMotorSpeedPWM(int pwm, int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. @@ -1015,7 +1009,7 @@ public void disableMotor(int toolhead) throws RetryException { super.disableMotor(toolhead); } - private int getMotorSpeedPWM(int toolhead) { + @Override public int getMotorSpeedPWM(int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -1038,12 +1032,7 @@ private int getMotorSpeedPWM(int toolhead) { return pwm; } - @Override public double getMotorRPM() - { - return getMotorRPM(machine.currentTool().getIndex()); - } - - private double getMotorRPM(int toolhead) { + @Override public double getMotorRPM(int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -1068,8 +1057,7 @@ private double getMotorRPM(int toolhead) { return rpm; } - private void readToolStatus(int toolhead) { - + @Override public void readToolStatus(int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -1296,7 +1284,7 @@ private void setServoPos(int index, double degree, int toolhead) throws RetryExc super.disableSpindle(toolhead); } - private double getSpindleSpeedRPM(int toolhead) throws RetryException { + @Override public double getSpindleRPM(int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -1305,7 +1293,7 @@ private double getSpindleSpeedRPM(int toolhead) throws RetryException { MotherboardCommandCode.TOOL_QUERY.getCode()); pb.add8((byte) toolhead); pb.add8(ToolCommandCode.GET_MOTOR_2_RPM.getCode()); - PacketResponse pr = runCommand(pb.getPacket()); + PacketResponse pr = runQuery(pb.getPacket()); // convert back to RPM long micros = pr.get32(); @@ -1319,7 +1307,7 @@ private double getSpindleSpeedRPM(int toolhead) throws RetryException { return rpm; } - private int getSpindleSpeedPWM(int toolhead) { + @Override public int getSpindleSpeedPWM(int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -1434,15 +1422,6 @@ else if (pr.isEmpty()) } - private void setAllPlatformTemperatures(double temperature) throws RetryException { - // constrain our temperature. - //Set the platform temperature for any & every tool with an HBP - for(ToolModel t : machine.getTools()) - { - this.setPlatformTemperature(temperature, t.getIndex()); - } - } - @Override public void readPlatformTemperature(int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -2569,7 +2548,7 @@ public void resetToolToFactory(int toolhead) { writeToEEPROM(Sanguino3GEEPRPOM.EEPROM_ESTOP_CONFIGURATION_OFFSET, b); } - protected double getPlatformTemperatureSetting(int toolhead) { + @Override public double getPlatformTemperatureSetting(int toolhead) { /// toolhead -1 indicates auto-detect. Fast hack to get software out... if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -2588,7 +2567,7 @@ protected double getPlatformTemperatureSetting(int toolhead) { return machine.getTool(toolhead).getPlatformTargetTemperature(); } - protected double getTemperatureSetting(int toolhead) { + @Override public double getTemperatureSetting(int toolhead) { /// toolhead -1 indicates auto-detect. Fast hack to get software out... if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); diff --git a/src/replicatorg/drivers/reprap/ExtrusionUpdater.java b/src/replicatorg/drivers/reprap/ExtrusionUpdater.java index e72a11433..cdd8023ad 100644 --- a/src/replicatorg/drivers/reprap/ExtrusionUpdater.java +++ b/src/replicatorg/drivers/reprap/ExtrusionUpdater.java @@ -66,9 +66,9 @@ private void sendExtrudeCommand(double distance, double feedrate) { // Base.logger.info("commandPeriod="+this.commandPeriod); if (driver.feedrate.get() != feedrate) { - driver.sendCommand(driver._getToolCode() + "G1 F"+feedrateString); + driver.sendCommand(driver._getCurrentToolCode() + "G1 F"+feedrateString); } - driver.sendCommand(driver._getToolCode() + "G1 E"+ + driver.sendCommand(driver._getCurrentToolCode() + "G1 E"+ driver.df.format(distance+driver.ePosition.get())+" F"+feedrateString); } diff --git a/src/replicatorg/drivers/reprap/RepRap5DDriver.java b/src/replicatorg/drivers/reprap/RepRap5DDriver.java index bed30c410..4484eb671 100644 --- a/src/replicatorg/drivers/reprap/RepRap5DDriver.java +++ b/src/replicatorg/drivers/reprap/RepRap5DDriver.java @@ -145,11 +145,6 @@ public class RepRap5DDriver extends SerialDriver implements SerialFifoEventListe private final ExtrusionUpdater extrusionUpdater = new ExtrusionUpdater(this); - /** - * the size of the buffer on the GCode host - */ - private int maxBufferSize = 128; - /** * The commands sent but not yet acknowledged by the firmware. Stored so they can be resent * if there is a checksum problem. @@ -181,11 +176,11 @@ public RepRap5DDriver() { df = new DecimalFormat("#.######", dfs); } - public String getDriverName() { + @Override public String getDriverName() { return "RepRap5D"; } - public synchronized void loadXML(Node xml) { + @Override public synchronized void loadXML(Node xml) { super.loadXML(xml); // load from our XML config, if we have it. if (XML.hasChildNode(xml, "waitforstart")) { @@ -245,7 +240,7 @@ public synchronized void loadXML(Node xml) { } } - public void updateManualControl() + @Override public void updateManualControl() { try { extrusionUpdater.update(); @@ -260,14 +255,14 @@ public void updateManualControl() * the firmware state. Sent on startup and if we see "start" * indicating an uncommanded firmware reset. */ - public void sendInitializationGcode(boolean synchronous) { + private void sendInitializationGcode(boolean synchronous) { sendCommand("M110", synchronous); // may be duplicate, that's ok // default us to absolute positioning sendCommand("G90", synchronous); sendCommand("G92 X0 Y0 Z0 E0", synchronous); } - public synchronized void initialize() { + @Override public synchronized void initialize() { // declare our serial guy. if (serial == null) { Base.logger.severe("No Serial Port found.\n"); @@ -387,14 +382,14 @@ private void pulseRTS() throws TimeoutException } } - public boolean isPassthroughDriver() { + @Override public boolean isPassthroughDriver() { return true; } /** * Actually execute the GCode we just parsed. */ - public void executeGCodeLine(String code) { + @Override public void executeGCodeLine(String code) { //If we're not initialized (ie. disconnected) do not execute commands on the disconnected machine. if(!isInitialized()) return; @@ -439,7 +434,7 @@ protected void sendCommand(String next, boolean synchronous) { } - protected void resendCommand(String command) { + private void resendCommand(String command) { synchronized (sendCommandLock) { numResends++; @@ -452,7 +447,7 @@ protected void resendCommand(String command) { /** * inner method. not for use outside sendCommand and resendCommand */ - protected void _sendCommand(String next, boolean synchronous, boolean resending) { + private void _sendCommand(String next, boolean synchronous, boolean resending) { // If this line is uncommented, it simply sends the next line instead of doing a retransmit! if (!resending) @@ -559,7 +554,7 @@ protected void _sendCommand(String next, boolean synchronous, boolean resending) sendCommandLock.unlock(); } - public String clean(String str) { + private static String clean(String str) { String clean = str; // trim whitespace @@ -573,7 +568,7 @@ public String clean(String str) { return clean; } - public String fix(String str) { + private String fix(String str) { String fixed = str; // The 5D firmware expects E codes for extrusion control instead of M101, M102, M103 @@ -644,7 +639,7 @@ public String fix(String str) { /** * takes a line of gcode and returns that gcode with a line number and checksum */ - public String applyNandChecksum(String gcode) { + private String applyNandChecksum(String gcode) { // RepRap Syntax: N *\n if (gcode.contains("M110")) @@ -662,7 +657,7 @@ public String applyNandChecksum(String gcode) { return applyChecksum(gcode); } - public String applyChecksum(String gcode) { + private String applyChecksum(String gcode) { // chksum = 0 xor each byte of the gcode (including the line number and trailing space) byte checksum = 0; byte[] gcodeBytes = gcode.getBytes(); @@ -673,7 +668,7 @@ public String applyChecksum(String gcode) { return gcode+'*'+checksum; } - public void serialByteReceivedEvent(ByteFifo fifo) { + @Override public void serialByteReceivedEvent(ByteFifo fifo) { readResponseLock.lock(); serialInUse.lock(); @@ -890,7 +885,7 @@ else if (line.contains("start")) { readResponseLock.unlock(); } - public boolean isFinished() { + @Override public boolean isFinished() { return isBufferEmpty(); } @@ -913,7 +908,7 @@ private void flushBuffer() { /** * Is our buffer empty? If don't have a buffer, its always true. */ - public boolean isBufferEmpty() { + @Override public boolean isBufferEmpty() { bufferLock.lock(); boolean isEmpty = buffer.isEmpty(); bufferLock.unlock(); @@ -937,7 +932,7 @@ private synchronized void disconnect() { bufferLock.unlock(); } - public synchronized void dispose() { + @Override public synchronized void dispose() { bufferLock.lock(); flushBuffer(); super.dispose(); @@ -949,7 +944,7 @@ public synchronized void dispose() { * @throws RetryException **************************************************************************/ - public void queuePoint(Point5d p) throws RetryException { + @Override public void queuePoint(Point5d p) throws RetryException { String cmd = "G1 F" + df.format(getCurrentFeedrate()); sendCommand(cmd); @@ -962,7 +957,7 @@ public void queuePoint(Point5d p) throws RetryException { super.queuePoint(p); } - public void setCurrentPosition(Point5d p) throws RetryException { + @Override public void setCurrentPosition(Point5d p) throws RetryException { sendCommand("G92 X" + df.format(p.x()) + " Y" + df.format(p.y()) + " Z" + df.format(p.z())); @@ -983,7 +978,7 @@ public void homeAxes(EnumSet axes, boolean positive, double feedrate) th super.homeAxes(axes,false,0); } - public void delay(long millis) { + @Override public void delay(long millis) { int seconds = Math.round(millis / 1000); sendCommand("G4 P" + seconds); @@ -991,32 +986,32 @@ public void delay(long millis) { // no super call requried. } - public void openClamp(int clampIndex) { + @Override public void openClamp(int clampIndex) { sendCommand("M11 Q" + clampIndex); super.openClamp(clampIndex); } - public void closeClamp(int clampIndex) { + @Override public void closeClamp(int clampIndex) { sendCommand("M10 Q" + clampIndex); super.closeClamp(clampIndex); } - public void enableDrives() throws RetryException { + @Override public void enableDrives() throws RetryException { sendCommand("M17"); super.enableDrives(); } - public void disableDrives() throws RetryException { + @Override public void disableDrives() throws RetryException { sendCommand("M18"); sendCommand("M84"); // Klimentkip super.disableDrives(); } - public void changeGearRatio(int ratioIndex) { + @Override public void changeGearRatio(int ratioIndex) { // gear ratio codes are M40-M46 int code = 40 + ratioIndex; code = Math.max(40, code); @@ -1027,18 +1022,22 @@ public void changeGearRatio(int ratioIndex) { super.changeGearRatio(ratioIndex); } - protected String _getToolCode() { - return "T" + machine.currentTool().getIndex() + " "; + private String _getToolCode(int toolhead) { + return "T" + (toolhead == -1 ? machine.currentTool().getIndex() : toolhead) + " "; + } + + String _getCurrentToolCode() { + return _getToolCode(machine.currentTool().getIndex()); } /*************************************************************************** * Motor interface functions * @throws RetryException **************************************************************************/ - public void setMotorRPM(double rpm, int toolhead) throws RetryException { + @Override public void setMotorRPM(double rpm, int toolhead) throws RetryException { if (fiveD == false) { - sendCommand(_getToolCode() + "M108 R" + df.format(rpm)); + sendCommand(_getToolCode(toolhead) + "M108 R" + df.format(rpm)); } else { @@ -1048,21 +1047,21 @@ public void setMotorRPM(double rpm, int toolhead) throws RetryException { super.setMotorRPM(rpm, toolhead); } - public void setMotorSpeedPWM(int pwm) throws RetryException { + @Override public void setMotorSpeedPWM(int pwm, int toolhead) throws RetryException { if (fiveD == false) { - sendCommand(_getToolCode() + "M108 S" + df.format(pwm)); + sendCommand(_getToolCode(toolhead) + "M108 S" + df.format(pwm)); } - super.setMotorSpeedPWM(pwm); + super.setMotorSpeedPWM(pwm, toolhead); } - public synchronized void enableMotor() throws RetryException { - String command = _getToolCode(); + @Override public synchronized void enableMotor(int toolhead) throws RetryException { + String command = _getToolCode(toolhead); if (fiveD == false) { - if (machine.currentTool().getMotorDirection() == ToolModel.MOTOR_CLOCKWISE) + if (machine.getTool(toolhead).getMotorDirection() == ToolModel.MOTOR_CLOCKWISE) command += "M101"; else command += "M102"; @@ -1076,108 +1075,108 @@ public synchronized void enableMotor() throws RetryException { extrusionUpdater.startExtruding(); } - super.enableMotor(); + super.enableMotor(toolhead); } /** * Unified enable+delay+disable to allow us to use G1 E */ - public synchronized void enableMotor(long millis) throws RetryException { + @Override public synchronized void enableMotor(long millis, int toolhead) throws RetryException { if (fiveD == false) { - super.enableMotor(millis); + super.enableMotor(millis, toolhead); } else { - super.enableMotor(); - double feedrate = machine.currentTool().getMotorSpeedRPM(); + super.enableMotor(toolhead); + double feedrate = machine.getTool(toolhead).getMotorSpeedRPM(); double distance = millis * feedrate / 60 / 1000; - if (machine.currentTool().getMotorDirection() != 1) { + if (machine.getTool(toolhead).getMotorDirection() != 1) { distance *= -1; } - sendCommand(_getToolCode() + "G1 E" + (ePosition.get() + distance) + " F" + feedrate); - super.disableMotor(); + sendCommand(_getToolCode(toolhead) + "G1 E" + (ePosition.get() + distance) + " F" + feedrate); + super.disableMotor(toolhead); } } - public void disableMotor() throws RetryException { + @Override public void disableMotor(int toolhead) throws RetryException { if (fiveD == false) { - sendCommand(_getToolCode() + "M103"); + sendCommand(_getToolCode(toolhead) + "M103"); } else { extrusionUpdater.stopExtruding(); } - super.disableMotor(); + super.disableMotor(toolhead); } /*************************************************************************** * Spindle interface functions * @throws RetryException **************************************************************************/ - public void setSpindleRPM(double rpm) throws RetryException { - sendCommand(_getToolCode() + "S" + df.format(rpm)); + @Override public void setSpindleRPM(double rpm, int toolhead) throws RetryException { + sendCommand(_getToolCode(toolhead) + "S" + df.format(rpm)); - super.setSpindleRPM(rpm); + super.setSpindleRPM(rpm, toolhead); } - public void enableSpindle() throws RetryException { - String command = _getToolCode(); + @Override public void enableSpindle(int toolhead) throws RetryException { + String command = _getToolCode(toolhead); - if (machine.currentTool().getSpindleDirection() == ToolModel.MOTOR_CLOCKWISE) + if (machine.getTool(toolhead).getSpindleDirection() == ToolModel.MOTOR_CLOCKWISE) command += "M3"; else command += "M4"; sendCommand(command); - super.enableSpindle(); + super.enableSpindle(toolhead); } - public void disableSpindle() throws RetryException { - sendCommand(_getToolCode() + "M5"); + @Override public void disableSpindle(int toolhead) throws RetryException { + sendCommand(_getToolCode(toolhead) + "M5"); - super.disableSpindle(); + super.disableSpindle(toolhead); } /*************************************************************************** * Temperature interface functions * @throws RetryException **************************************************************************/ - public void setTemperature(double temperature) throws RetryException { - sendCommand(_getToolCode() + "M104 S" + df.format(temperature)); + @Override public void setTemperature(double temperature, int toolhead) throws RetryException { + sendCommand(_getToolCode(toolhead) + "M104 S" + df.format(temperature)); - super.setTemperature(temperature); + super.setTemperature(temperature, toolhead); } - public void readTemperature() { - sendCommand(_getToolCode() + "M105"); + @Override public void readTemperature(int toolhead) { + sendCommand(_getToolCode(toolhead) + "M105"); - super.readTemperature(); + super.readTemperature(toolhead); } - public double getPlatformTemperature(){ - return machine.currentTool().getPlatformCurrentTemperature(); + @Override public double getPlatformTemperature(int toolhead){ + return machine.getTool(toolhead).getPlatformCurrentTemperature(); } - public void setPlatformTemperature(double temperature) throws RetryException { - sendCommand(_getToolCode() + "M140 S" + df.format(temperature)); + @Override public void setPlatformTemperature(double temperature, int toolhead) throws RetryException { + sendCommand(_getToolCode(toolhead) + "M140 S" + df.format(temperature)); - super.setPlatformTemperature(temperature); + super.setPlatformTemperature(temperature, toolhead); } /*************************************************************************** * Flood Coolant interface functions **************************************************************************/ - public void enableFloodCoolant() { - sendCommand(_getToolCode() + "M7"); + @Override public void enableFloodCoolant() { + sendCommand(_getCurrentToolCode() + "M7"); super.enableFloodCoolant(); } - public void disableFloodCoolant() { - sendCommand(_getToolCode() + "M9"); + @Override public void disableFloodCoolant() { + sendCommand(_getCurrentToolCode() + "M9"); super.disableFloodCoolant(); } @@ -1185,14 +1184,14 @@ public void disableFloodCoolant() { /*************************************************************************** * Mist Coolant interface functions **************************************************************************/ - public void enableMistCoolant() { - sendCommand(_getToolCode() + "M8"); + @Override public void enableMistCoolant() { + sendCommand(_getCurrentToolCode() + "M8"); super.enableMistCoolant(); } - public void disableMistCoolant() { - sendCommand(_getToolCode() + "M9"); + @Override public void disableMistCoolant() { + sendCommand(_getCurrentToolCode() + "M9"); super.disableMistCoolant(); } @@ -1201,56 +1200,56 @@ public void disableMistCoolant() { * Fan interface functions * @throws RetryException **************************************************************************/ - public void enableFan() throws RetryException { - sendCommand(_getToolCode() + "M106"); + @Override public void enableFan(int toolhead) throws RetryException { + sendCommand(_getToolCode(toolhead) + "M106"); - super.enableFan(); + super.enableFan(toolhead); } - public void disableFan() throws RetryException { - sendCommand(_getToolCode() + "M107"); + @Override public void disableFan(int toolhead) throws RetryException { + sendCommand(_getToolCode(toolhead) + "M107"); - super.disableFan(); + super.disableFan(toolhead); } /*************************************************************************** * Valve interface functions * @throws RetryException **************************************************************************/ - public void openValve() throws RetryException { - sendCommand(_getToolCode() + "M126"); + @Override public void openValve(int toolhead) throws RetryException { + sendCommand(_getToolCode(toolhead) + "M126"); - super.openValve(); + super.openValve(toolhead); } - public void closeValve() throws RetryException { - sendCommand(_getToolCode() + "M127"); + @Override public void closeValve(int toolhead) throws RetryException { + sendCommand(_getToolCode(toolhead) + "M127"); - super.closeValve(); + super.closeValve(toolhead); } /*************************************************************************** * Collet interface functions **************************************************************************/ - public void openCollet() { - sendCommand(_getToolCode() + "M21"); + @Override public void openCollet() { + sendCommand(_getCurrentToolCode() + "M21"); super.openCollet(); } - public void closeCollet() { - sendCommand(_getToolCode() + "M22"); + @Override public void closeCollet() { + sendCommand(_getCurrentToolCode() + "M22"); super.closeCollet(); } - public void reset() { + @Override public void reset() { Base.logger.info("Reset."); setInitialized(false); initialize(); } - public void stop(boolean abort) { + @Override public void stop(boolean abort) { // No implementation needed for synchronous machines. //sendCommand("M0"); // M0 is the same as emergency stop: will hang all communications. You don't really want that... @@ -1258,7 +1257,7 @@ public void stop(boolean abort) { Base.logger.info("RepRap/Ultimaker Machine stop called."); } - protected Point5d reconcilePosition() { + @Override protected Point5d reconcilePosition() { sendCommand("M114"); // If the firmware returned a position then the reply parser // already set the current position. Return null to tell @@ -1271,60 +1270,60 @@ protected Point5d reconcilePosition() { /* =============== * This driver has real time control over feedrate and extrusion parameters, allowing real-time tuning! */ - public boolean hasFeatureRealtimeControl() { + @Override public boolean hasFeatureRealtimeControl() { Base.logger.info("Yes, I have a Realtime Control feature." ); return true; } - public void enableRealtimeControl(boolean enable) { + @Override public void enableRealtimeControl(boolean enable) { realtimeControl = enable; Base.logger.info("Realtime Control (RC) is: "+ realtimeControl ); } - public double getExtrusionMultiplier() { + @Override public double getExtrusionMultiplier() { return rcExtrusionMultiply; } - public double getFeedrateMultiplier() { + @Override public double getFeedrateMultiplier() { return rcFeedrateMultiply; } - public double getTravelFeedrateMultiplier() { + @Override public double getTravelFeedrateMultiplier() { return rcTravelFeedrateMultiply; } - public boolean setExtrusionMultiplier(double multiplier) { + @Override public boolean setExtrusionMultiplier(double multiplier) { rcExtrusionMultiply = multiplier; if(debugLevel == 2) Base.logger.info("RC muplipliers: extrusion="+rcExtrusionMultiply+"x, feedrate="+rcFeedrateMultiply+"x" ); return true; } - public boolean setFeedrateMultiplier(double multiplier) { + @Override public boolean setFeedrateMultiplier(double multiplier) { rcFeedrateMultiply = multiplier; if(debugLevel == 2) Base.logger.info("RC muplipliers: extrusion="+rcExtrusionMultiply+"x, feedrate="+rcFeedrateMultiply+"x" ); return true; } - public boolean setTravelFeedrateMultiplier(double multiplier) { + @Override public boolean setTravelFeedrateMultiplier(double multiplier) { rcTravelFeedrateMultiply = multiplier; if(debugLevel == 2) Base.logger.info("RC muplipliers: extrusion="+rcExtrusionMultiply+"x, feedrate="+rcFeedrateMultiply+"x, travel feedrate="+rcTravelFeedrateMultiply+"x" ); return true; } - public void setDebugLevel(int level) { + @Override public void setDebugLevel(int level) { debugLevel = level; } - public int getDebugLevel() { + @Override public int getDebugLevel() { return debugLevel; } - public double getFeedrateLimit() { + @Override public double getFeedrateLimit() { return rcFeedrateLimit; } - public boolean setFeedrateLimit(double limit) { + @Override public boolean setFeedrateLimit(double limit) { rcFeedrateLimit = limit; return true; } diff --git a/src/replicatorg/drivers/reprap/SimpleRepRap5DDriver.java b/src/replicatorg/drivers/reprap/SimpleRepRap5DDriver.java index 86d80b9e3..70263fb2a 100644 --- a/src/replicatorg/drivers/reprap/SimpleRepRap5DDriver.java +++ b/src/replicatorg/drivers/reprap/SimpleRepRap5DDriver.java @@ -37,8 +37,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.w3c.dom.Node; - import replicatorg.app.Base; import replicatorg.drivers.RetryException; import replicatorg.drivers.SerialDriver; @@ -85,15 +83,11 @@ public SimpleRepRap5DDriver() { df = new DecimalFormat("#.######", dfs); } - public String getDriverName() { + @Override public String getDriverName() { return "SimpleRepRap5D"; } - public void loadXML(Node xml) { - super.loadXML(xml); - } - - public void initialize() { + @Override public void initialize() { // declare our serial guy. if (serial == null) { Base.logger.severe("No Serial Port found.\n"); @@ -136,14 +130,14 @@ public void initialize() { sendCommand("G90"); } - public boolean isPassthroughDriver() { + @Override public boolean isPassthroughDriver() { return true; } /** * Actually execute the GCode we just parsed. */ - public void executeGCodeLine(String code) { + @Override public void executeGCodeLine(String code) { // we *DONT* want to use the parents one, // as that will call all sorts of misc functions. // we'll simply pass it along. @@ -155,7 +149,7 @@ public void executeGCodeLine(String code) { * Actually sends command over serial. If the Arduino buffer is full, this * method will block until the command has been sent. */ - protected void sendCommand(String next) { + private void sendCommand(String next) { assert (isInitialized()); assert (serial != null); // System.out.println("sending: " + next); @@ -188,7 +182,7 @@ protected void sendCommand(String next) { // commands)"); } - public String clean(String str) { + private static String clean(String str) { String clean = str; // trim whitespace @@ -199,7 +193,8 @@ public String clean(String str) { return clean; } - public String fix(String str) { + + private static String fix(String str) { String fixed = str; // The 5D firmware expects E codes for extrusion control instead of M101, M102, M103 @@ -235,7 +230,7 @@ public String fix(String str) { return fixed; // no change! } - public void readResponse() { + private void readResponse() { assert (serial != null); synchronized (serial) { try { @@ -305,14 +300,14 @@ else if (line.startsWith("start")) { } } - public boolean isFinished() { + @Override public boolean isFinished() { return isBufferEmpty(); } /** * Is our buffer empty? If don't have a buffer, its always true. */ - public boolean isBufferEmpty() { + @Override public boolean isBufferEmpty() { try { readResponse(); } catch (Exception e) { @@ -320,7 +315,7 @@ public boolean isBufferEmpty() { return (bufferSize == 0); } - public void dispose() { + @Override public void dispose() { super.dispose(); commands = null; } @@ -330,7 +325,7 @@ public void dispose() { * @throws RetryException **************************************************************************/ - public void queuePoint(Point5d p) throws RetryException { + @Override public void queuePoint(Point5d p) throws RetryException { String cmd = "G1 F" + df.format(getCurrentFeedrate()); sendCommand(cmd); @@ -343,7 +338,7 @@ public void queuePoint(Point5d p) throws RetryException { super.queuePoint(p); } - public void setCurrentPosition(Point5d p) throws RetryException { + @Override public void setCurrentPosition(Point5d p) throws RetryException { sendCommand("G92 X" + df.format(p.x()) + " Y" + df.format(p.y()) + " Z" + df.format(p.z())); @@ -363,7 +358,7 @@ public void homeAxes(EnumSet axes, boolean positive, double feedrate) th super.homeAxes(axes,false,0); } - public void delay(long millis) { + @Override public void delay(long millis) { int seconds = Math.round(millis / 1000); sendCommand("G4 P" + seconds); @@ -371,31 +366,31 @@ public void delay(long millis) { // no super call requried. } - public void openClamp(int clampIndex) { + @Override public void openClamp(int clampIndex) { sendCommand("M11 Q" + clampIndex); super.openClamp(clampIndex); } - public void closeClamp(int clampIndex) { + @Override public void closeClamp(int clampIndex) { sendCommand("M10 Q" + clampIndex); super.closeClamp(clampIndex); } - public void enableDrives() throws RetryException { + @Override public void enableDrives() throws RetryException { sendCommand("M17"); super.enableDrives(); } - public void disableDrives() throws RetryException { + @Override public void disableDrives() throws RetryException { sendCommand("M18"); super.disableDrives(); } - public void changeGearRatio(int ratioIndex) { + @Override public void changeGearRatio(int ratioIndex) { // gear ratio codes are M40-M46 int code = 40 + ratioIndex; code = Math.max(40, code); @@ -406,101 +401,105 @@ public void changeGearRatio(int ratioIndex) { super.changeGearRatio(ratioIndex); } - protected String _getToolCode() { - return "T" + machine.currentTool().getIndex() + " "; + private String _getToolCode(int toolhead) { + return "T" + (toolhead == -1 ? machine.currentTool().getIndex() : toolhead) + " "; + } + + private String _getCurrentToolCode() { + return _getToolCode(machine.currentTool().getIndex()); } /*************************************************************************** * Motor interface functions **************************************************************************/ - public void setMotorRPM(double rpm, int toolhead) throws RetryException { - sendCommand(_getToolCode() + "M108 R" + df.format(rpm)); + @Override public void setMotorRPM(double rpm, int toolhead) throws RetryException { + sendCommand(_getToolCode(toolhead) + "M108 R" + df.format(rpm)); super.setMotorRPM(rpm, toolhead); } - public void setMotorSpeedPWM(int pwm) throws RetryException { - sendCommand(_getToolCode() + "M108 S" + df.format(pwm)); + @Override public void setMotorSpeedPWM(int pwm, int toolhead) throws RetryException { + sendCommand(_getToolCode(toolhead) + "M108 S" + df.format(pwm)); - super.setMotorSpeedPWM(pwm); + super.setMotorSpeedPWM(pwm, toolhead); } - public void enableMotor() throws RetryException { - String command = _getToolCode(); + @Override public void enableMotor(int toolhead) throws RetryException { + String command = _getToolCode(toolhead); - if (machine.currentTool().getMotorDirection() == ToolModel.MOTOR_CLOCKWISE) + if (machine.getTool(toolhead).getMotorDirection() == ToolModel.MOTOR_CLOCKWISE) command += "M101"; else command += "M102"; sendCommand(command); - super.enableMotor(); + super.enableMotor(toolhead); } - public void disableMotor() throws RetryException { - sendCommand(_getToolCode() + "M103"); + @Override public void disableMotor(int toolhead) throws RetryException { + sendCommand(_getToolCode(toolhead) + "M103"); - super.disableMotor(); + super.disableMotor(toolhead); } /*************************************************************************** * Spindle interface functions **************************************************************************/ - public void setSpindleRPM(double rpm) throws RetryException { - sendCommand(_getToolCode() + "S" + df.format(rpm)); + @Override public void setSpindleRPM(double rpm, int toolhead) throws RetryException { + sendCommand(_getToolCode(toolhead) + "S" + df.format(rpm)); - super.setSpindleRPM(rpm); + super.setSpindleRPM(rpm, toolhead); } - public void enableSpindle() throws RetryException { - String command = _getToolCode(); + @Override public void enableSpindle(int toolhead) throws RetryException { + String command = _getToolCode(toolhead); - if (machine.currentTool().getSpindleDirection() == ToolModel.MOTOR_CLOCKWISE) + if (machine.getTool(toolhead).getSpindleDirection() == ToolModel.MOTOR_CLOCKWISE) command += "M3"; else command += "M4"; sendCommand(command); - super.enableSpindle(); + super.enableSpindle(toolhead); } - public void disableSpindle() throws RetryException { - sendCommand(_getToolCode() + "M5"); + @Override public void disableSpindle(int toolhead) throws RetryException { + sendCommand(_getToolCode(toolhead) + "M5"); - super.disableSpindle(); + super.disableSpindle(toolhead); } /*************************************************************************** * Temperature interface functions **************************************************************************/ - public void setTemperature(double temperature) throws RetryException { - sendCommand(_getToolCode() + "M104 S" + df.format(temperature)); + @Override public void setTemperature(double temperature, int toolhead) throws RetryException { + sendCommand(_getToolCode(toolhead) + "M104 S" + df.format(temperature)); - super.setTemperature(temperature); + super.setTemperature(temperature, toolhead); } - public void readTemperature() { - sendCommand(_getToolCode() + "M105"); + @Override public void readTemperature(int toolhead) { + sendCommand(_getToolCode(toolhead) + "M105"); - super.readTemperature(); + super.readTemperature(toolhead); } - public double getPlatformTemperature(){ - return machine.currentTool().getPlatformCurrentTemperature(); + @Override public double getPlatformTemperature(int toolhead){ + return machine.getTool(toolhead).getPlatformCurrentTemperature(); } /*************************************************************************** * Flood Coolant interface functions **************************************************************************/ - public void enableFloodCoolant() { - sendCommand(_getToolCode() + "M7"); + @Override public void enableFloodCoolant() { + sendCommand(_getCurrentToolCode() + "M7"); super.enableFloodCoolant(); } - public void disableFloodCoolant() { - sendCommand(_getToolCode() + "M9"); + @Override public void disableFloodCoolant() { + sendCommand(_getCurrentToolCode() + "M9"); super.disableFloodCoolant(); } @@ -508,14 +507,14 @@ public void disableFloodCoolant() { /*************************************************************************** * Mist Coolant interface functions **************************************************************************/ - public void enableMistCoolant() { - sendCommand(_getToolCode() + "M8"); + @Override public void enableMistCoolant() { + sendCommand(_getCurrentToolCode() + "M8"); super.enableMistCoolant(); } - public void disableMistCoolant() { - sendCommand(_getToolCode() + "M9"); + @Override public void disableMistCoolant() { + sendCommand(_getCurrentToolCode() + "M9"); super.disableMistCoolant(); } @@ -523,55 +522,55 @@ public void disableMistCoolant() { /*************************************************************************** * Fan interface functions **************************************************************************/ - public void enableFan() throws RetryException { - sendCommand(_getToolCode() + "M106"); + @Override public void enableFan(int toolhead) throws RetryException { + sendCommand(_getToolCode(toolhead) + "M106"); - super.enableFan(); + super.enableFan(toolhead); } - public void disableFan() throws RetryException { - sendCommand(_getToolCode() + "M107"); + @Override public void disableFan(int toolhead) throws RetryException { + sendCommand(_getToolCode(toolhead) + "M107"); - super.disableFan(); + super.disableFan(toolhead); } /*************************************************************************** * Valve interface functions **************************************************************************/ - public void openValve() throws RetryException { - sendCommand(_getToolCode() + "M126"); + @Override public void openValve(int toolhead) throws RetryException { + sendCommand(_getToolCode(toolhead) + "M126"); - super.openValve(); + super.openValve(toolhead); } - public void closeValve() throws RetryException { - sendCommand(_getToolCode() + "M127"); + @Override public void closeValve(int toolhead) throws RetryException { + sendCommand(_getToolCode(toolhead) + "M127"); - super.closeValve(); + super.closeValve(toolhead); } /*************************************************************************** * Collet interface functions **************************************************************************/ - public void openCollet() { - sendCommand(_getToolCode() + "M21"); + @Override public void openCollet() { + sendCommand(_getCurrentToolCode() + "M21"); super.openCollet(); } - public void closeCollet() { - sendCommand(_getToolCode() + "M22"); + @Override public void closeCollet() { + sendCommand(_getCurrentToolCode() + "M22"); super.closeCollet(); } - public void reset() { + @Override public void reset() { Base.logger.info("Reset."); setInitialized(false); initialize(); } - protected Point5d reconcilePosition() { + @Override protected Point5d reconcilePosition() { return new Point5d(); } } From 06a13f071209cd89b047319c6dbd10d673bce8ff Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Fri, 9 Mar 2012 21:28:36 -0800 Subject: [PATCH 18/35] Modernized DriverQueryInterface. While the Driver interface grew new methods to support multiple tools, DriverQueryInterface was left behind. Fortunately, it's a much less popular type, so fixing this is a relatively small change. Because classes tend to implement both Driver and DriverQueryInterface, and Driver already had the methods in question, I was able to simply remove the old-style methods from DriverQueryInterface. As a side effect, a few G-Code commands are now multi-tool aware -- specifically, the commands for setting spindle speed. --- src/replicatorg/app/gcode/GCodeParser.java | 18 +++++++++++----- .../app/ui/controlpanel/ExtruderPanel.java | 2 +- .../drivers/DriverBaseImplementation.java | 11 +++++----- .../drivers/DriverQueryInterface.java | 21 +++++++------------ 4 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/replicatorg/app/gcode/GCodeParser.java b/src/replicatorg/app/gcode/GCodeParser.java index 0697d2101..aa376e713 100644 --- a/src/replicatorg/app/gcode/GCodeParser.java +++ b/src/replicatorg/app/gcode/GCodeParser.java @@ -438,7 +438,11 @@ private void buildMCodes(GCodeCommand gcode, Queue< DriverCommand > commands) th break; // read spindle speed case M50: - driver.getSpindleRPM(); + if (gcode.hasCode('T')) { + driver.getSpindleRPM((int) gcode.getCodeValue('P')); + } else { + driver.getSpindleRPM(driver.getCurrentToolIndex()); + } break; // turn extruder on, forward case M70: @@ -493,19 +497,23 @@ private void buildMCodes(GCodeCommand gcode, Queue< DriverCommand > commands) th commands.add(new replicatorg.drivers.commands.ReadTemperature()); break; // turn AutomatedBuildPlatform on - case M106: - if(driver.hasAutomatedBuildPlatform()) + case M106: { + int toolIndex = gcode.hasCode('T') ? (int) gcode.getCodeValue('T') : driver.getCurrentToolIndex(); + if(driver.hasAutomatedBuildPlatform(toolIndex)) commands.add(new replicatorg.drivers.commands.ToggleAutomatedBuildPlatform(true)); else commands.add(new replicatorg.drivers.commands.EnableFan()); break; + } // turn AutomatedBuildPlatform off - case M107: - if(driver.hasAutomatedBuildPlatform()) + case M107: { + int toolIndex = gcode.hasCode('T') ? (int) gcode.getCodeValue('T') : driver.getCurrentToolIndex(); + if(driver.hasAutomatedBuildPlatform(toolIndex)) commands.add(new replicatorg.drivers.commands.ToggleAutomatedBuildPlatform(false)); else commands.add(new replicatorg.drivers.commands.DisableFan()); break; + } // set max extruder speed, RPM case M108: if (gcode.hasCode('S')) diff --git a/src/replicatorg/app/ui/controlpanel/ExtruderPanel.java b/src/replicatorg/app/ui/controlpanel/ExtruderPanel.java index cbfba69b3..7e3ecbf05 100644 --- a/src/replicatorg/app/ui/controlpanel/ExtruderPanel.java +++ b/src/replicatorg/app/ui/controlpanel/ExtruderPanel.java @@ -274,7 +274,7 @@ public void actionPerformed(ActionEvent e) { } } }, "handleTextField", "motor-speed-pwm", 5, Base.getLocalFormat()); - field.setValue(machine.getDriverQueryInterface().getMotorSpeedPWM()); + field.setValue(machine.getDriverQueryInterface().getMotorSpeedPWM(tool.getIndex())); panel.add(label); panel.add(field,"wrap"); } diff --git a/src/replicatorg/drivers/DriverBaseImplementation.java b/src/replicatorg/drivers/DriverBaseImplementation.java index ac40fe0a8..c6ece318e 100644 --- a/src/replicatorg/drivers/DriverBaseImplementation.java +++ b/src/replicatorg/drivers/DriverBaseImplementation.java @@ -398,6 +398,10 @@ protected Point5d getDelta(Point5d p) { @Override public void selectTool(int toolIndex) throws RetryException { machine.selectTool(toolIndex); } + + @Override public int getCurrentToolIndex() { + return machine.currentTool().getIndex(); + } /*************************************************************************** * pause function @@ -797,12 +801,7 @@ public void setAutomatedBuildPlatformRunning(boolean state, int toolhead) } - @Override public boolean hasAutomatedBuildPlatform() - { - return hasAutomatedBuildPlatform(-1); - } - - private boolean hasAutomatedBuildPlatform(int toolhead) + @Override public boolean hasAutomatedBuildPlatform(int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); diff --git a/src/replicatorg/drivers/DriverQueryInterface.java b/src/replicatorg/drivers/DriverQueryInterface.java index e970cd10d..eaf08fe75 100644 --- a/src/replicatorg/drivers/DriverQueryInterface.java +++ b/src/replicatorg/drivers/DriverQueryInterface.java @@ -11,31 +11,26 @@ * @author matt.mets */ public interface DriverQueryInterface { + public int getCurrentToolIndex(); + public Point3d getOffset(int i); public Point5d getMaximumFeedrates(); - public double getSpindleRPM(); + public double getSpindleRPM(int toolhead); - public double getMotorRPM(); + public double getMotorRPM(int toolhead); - public int getMotorSpeedPWM(); - - /** relies on timing to have the 'right selected toolhead', deprecated */ - @Deprecated - public double getTemperature(); + public int getMotorSpeedPWM(int toolhead); public double getTemperature(int toolhead); - public double getTemperatureSetting(); + public double getTemperatureSetting(int toolhead); - public boolean hasAutomatedBuildPlatform(); + public boolean hasAutomatedBuildPlatform(int toolhead); - /** relies on timing to have the 'right selected toolhead', deprecated */ - @Deprecated - public double getPlatformTemperature(); public double getPlatformTemperature(int toolhead); - public double getPlatformTemperatureSetting(); + public double getPlatformTemperatureSetting(int toolhead); public Point5d getCurrentPosition(boolean b); From 32022780b0b5cd47d8b37a40eaf5be2a0c3ce76a Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Fri, 9 Mar 2012 21:31:20 -0800 Subject: [PATCH 19/35] Removed old-style tool status methods from Driver. This was too easy: the methods appear to be completely unused. We may consider removing them down the road. --- src/replicatorg/drivers/Driver.java | 2 -- src/replicatorg/drivers/DriverBaseImplementation.java | 9 --------- 2 files changed, 11 deletions(-) diff --git a/src/replicatorg/drivers/Driver.java b/src/replicatorg/drivers/Driver.java index c8bfc4123..9ca9e7a83 100644 --- a/src/replicatorg/drivers/Driver.java +++ b/src/replicatorg/drivers/Driver.java @@ -263,10 +263,8 @@ public interface Driver { */ public void changeGearRatio(int ratioIndex); - @Deprecated public void readToolStatus(); public void readToolStatus(int toolhead); - @Deprecated public int getToolStatus(); public int getToolStatus(int toolhead); diff --git a/src/replicatorg/drivers/DriverBaseImplementation.java b/src/replicatorg/drivers/DriverBaseImplementation.java index c6ece318e..2cb4f0da4 100644 --- a/src/replicatorg/drivers/DriverBaseImplementation.java +++ b/src/replicatorg/drivers/DriverBaseImplementation.java @@ -558,19 +558,10 @@ public double getMotorSteps() { return machine.currentTool().getMotorSteps(); } - // TODO: These are backwards? - @Deprecated @Override public void readToolStatus() { - readToolStatus(-1); - } - @Override public void readToolStatus(int toolhead) { } - @Deprecated @Override public int getToolStatus() { - return getToolStatus(-1); - } - @Override public int getToolStatus(int toolhead) { if (toolhead == -1) toolhead = machine.currentTool().getIndex(); readToolStatus(toolhead); From 9901d17afb81143918eb20875cab297ccd78a0d0 Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Fri, 9 Mar 2012 21:34:20 -0800 Subject: [PATCH 20/35] Removed old-style methods for motor speed/dir from Driver. Fortunately, most code was already using the new-style methods. --- .../app/ui/controlpanel/ExtruderPanel.java | 4 ++-- src/replicatorg/drivers/Driver.java | 4 ---- .../drivers/DriverBaseImplementation.java | 17 ----------------- .../drivers/gen3/Makerbot4GAlternateDriver.java | 7 ++++--- src/replicatorg/drivers/gen3/MightyBoard.java | 2 +- 5 files changed, 7 insertions(+), 27 deletions(-) diff --git a/src/replicatorg/app/ui/controlpanel/ExtruderPanel.java b/src/replicatorg/app/ui/controlpanel/ExtruderPanel.java index 7e3ecbf05..a8e905483 100644 --- a/src/replicatorg/app/ui/controlpanel/ExtruderPanel.java +++ b/src/replicatorg/app/ui/controlpanel/ExtruderPanel.java @@ -801,14 +801,14 @@ private void handleChangedItem(ItemEvent e, ToolModel tool) { machine.runCommand(new replicatorg.drivers.commands.SetMotorDirection(AxialDirection.CLOCKWISE,toolhead)); // TODO: Hack to support RepRap/Ultimaker- always re-send RPM if (tool.motorHasEncoder() || tool.motorIsStepper()) { - machine.runCommand(new replicatorg.drivers.commands.SetMotorSpeedRPM(machine.getDriver().getMotorRPM(),toolhead)); + machine.runCommand(new replicatorg.drivers.commands.SetMotorSpeedRPM(machine.getDriverQueryInterface().getMotorRPM(toolhead), toolhead)); } machine.runCommand(new replicatorg.drivers.commands.EnableExtruderMotor(toolhead)); } else if (name.equals("motor-reverse")) { machine.runCommand(new replicatorg.drivers.commands.SetMotorDirection(AxialDirection.COUNTERCLOCKWISE,toolhead)); // TODO: Hack to support RepRap/Ultimaker- always re-send RPM if (tool.motorHasEncoder() || tool.motorIsStepper()) { - machine.runCommand(new replicatorg.drivers.commands.SetMotorSpeedRPM(machine.getDriver().getMotorRPM(),toolhead)); + machine.runCommand(new replicatorg.drivers.commands.SetMotorSpeedRPM(machine.getDriverQueryInterface().getMotorRPM(toolhead), toolhead)); } machine.runCommand(new replicatorg.drivers.commands.EnableExtruderMotor(toolhead)); } else if (name.equals("motor-stop")) { diff --git a/src/replicatorg/drivers/Driver.java b/src/replicatorg/drivers/Driver.java index 9ca9e7a83..00beb27ad 100644 --- a/src/replicatorg/drivers/Driver.java +++ b/src/replicatorg/drivers/Driver.java @@ -271,18 +271,14 @@ public interface Driver { /*************************************************************************** * Motor interface functions **************************************************************************/ - @Deprecated public void setMotorDirection(int dir); public void setMotorDirection(int dir, int toolhead); public void setMotorRPM(double rpm, int toolhead) throws RetryException; - @Deprecated public void setMotorSpeedPWM(int pwm) throws RetryException; public void setMotorSpeedPWM(int pwm, int toolhead) throws RetryException; - @Deprecated public double getMotorRPM(); public double getMotorRPM(int toolhead); - @Deprecated public int getMotorSpeedPWM(); public int getMotorSpeedPWM(int toolhead); /** diff --git a/src/replicatorg/drivers/DriverBaseImplementation.java b/src/replicatorg/drivers/DriverBaseImplementation.java index 2cb4f0da4..deaf46755 100644 --- a/src/replicatorg/drivers/DriverBaseImplementation.java +++ b/src/replicatorg/drivers/DriverBaseImplementation.java @@ -457,10 +457,6 @@ protected Point5d getDelta(Point5d p) { /*************************************************************************** * Motor interface functions **************************************************************************/ - @Deprecated @Override public void setMotorDirection(int dir) { - this.setMotorDirection(dir, machine.currentTool().getIndex()); - } - @Override public void setMotorDirection(int dir, int toolhead) { /// toolhead -1 indicate auto-detect. Fast hack to get software out.. @@ -479,11 +475,6 @@ public void setMotorRPM(double rpm, int toolhead) throws RetryException { } - @Deprecated @Override - public void setMotorSpeedPWM(int pwm) throws RetryException { - this.setMotorSpeedPWM(pwm, machine.currentTool().getIndex()); - } - @Override public void setMotorSpeedPWM(int pwm, int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -536,19 +527,11 @@ public void disableMotor() throws RetryException { } - @Deprecated @Override public double getMotorRPM() { - return getMotorRPM(-1); - } - @Override public double getMotorRPM(int toolhead) { if (toolhead == -1) toolhead = machine.currentTool().getIndex(); return machine.getTool(toolhead).getMotorSpeedRPM(); } - @Deprecated @Override public int getMotorSpeedPWM() { - return getMotorSpeedPWM(-1); - } - @Override public int getMotorSpeedPWM(int toolhead) { if (toolhead == -1) toolhead = machine.currentTool().getIndex(); return machine.getTool(toolhead).getMotorSpeedPWM(); diff --git a/src/replicatorg/drivers/gen3/Makerbot4GAlternateDriver.java b/src/replicatorg/drivers/gen3/Makerbot4GAlternateDriver.java index 4703e966d..17104f3a6 100644 --- a/src/replicatorg/drivers/gen3/Makerbot4GAlternateDriver.java +++ b/src/replicatorg/drivers/gen3/Makerbot4GAlternateDriver.java @@ -236,9 +236,10 @@ protected void queueNewPoint(Point5d steps, long us, int relative) throws RetryE * Overridden to not ask the board for the RPM as it would report the RPM from the extruder * controller, which doesn't know about it in this case. */ - @Override public double getMotorRPM() { - double rpm = machine.currentTool().getMotorSpeedRPM(); - machine.currentTool().setMotorSpeedReadingRPM(rpm); + @Override public double getMotorRPM(int toolhead) { + ToolModel tool = machine.getTool(toolhead); + double rpm = tool.getMotorSpeedRPM(); + tool.setMotorSpeedReadingRPM(rpm); return rpm; } diff --git a/src/replicatorg/drivers/gen3/MightyBoard.java b/src/replicatorg/drivers/gen3/MightyBoard.java index eb535544b..ba2b5aa65 100644 --- a/src/replicatorg/drivers/gen3/MightyBoard.java +++ b/src/replicatorg/drivers/gen3/MightyBoard.java @@ -297,11 +297,11 @@ public boolean initializeBot() for (ToolModel t : getMachine().getTools()) { if (t != null) { initSlave(t.getIndex()); + getMotorRPM(t.getIndex()); //load our motor RPM from firmware if we can. } } getStepperValues(); //read our current steppers into a local cache - getMotorRPM(); //load our motor RPM from firmware if we can. if (verifyMachineId() == false ) //read and verify our PID/VID if we can { Base.logger.severe("Machine ID Mismatch. Please re-select your machine."); From b1060b9b317ab79f4eb63414046e10b11631b372 Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Fri, 9 Mar 2012 21:35:32 -0800 Subject: [PATCH 21/35] Removed old-style motor enable/disable methods from Driver. All code was already using the new-style methods. --- src/replicatorg/drivers/Driver.java | 3 --- .../drivers/DriverBaseImplementation.java | 19 ------------------- 2 files changed, 22 deletions(-) diff --git a/src/replicatorg/drivers/Driver.java b/src/replicatorg/drivers/Driver.java index 00beb27ad..cd41b9ff7 100644 --- a/src/replicatorg/drivers/Driver.java +++ b/src/replicatorg/drivers/Driver.java @@ -285,17 +285,14 @@ public interface Driver { * Enable motor until stopped by disableMotor * @throws RetryException */ - @Deprecated public void enableMotor() throws RetryException; public void enableMotor(int toolhead) throws RetryException; /** * Enable motor for a fixed duration, then disable * @throws RetryException */ - @Deprecated public void enableMotor(long millis) throws RetryException; public void enableMotor(long millis, int toolhead) throws RetryException; - @Deprecated public void disableMotor() throws RetryException; public void disableMotor(int toolhead) throws RetryException; /*************************************************************************** diff --git a/src/replicatorg/drivers/DriverBaseImplementation.java b/src/replicatorg/drivers/DriverBaseImplementation.java index deaf46755..db05f2706 100644 --- a/src/replicatorg/drivers/DriverBaseImplementation.java +++ b/src/replicatorg/drivers/DriverBaseImplementation.java @@ -482,17 +482,6 @@ public void setMotorRPM(double rpm, int toolhead) throws RetryException { machine.getTool(toolhead).setMotorSpeedPWM(pwm); } - - @Deprecated @Override - public void enableMotor() throws RetryException { - this.enableMotor(machine.currentTool().getIndex()); - } - - @Deprecated @Override - public void enableMotor(long millis) throws RetryException { - this.enableMotor(millis, machine.currentTool().getIndex()); - } - @Override public void enableMotor(long millis, int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. @@ -511,8 +500,6 @@ public void enableMotor(int toolhead) throws RetryException { machine.getTool(toolhead).enableMotor(); } - - @Override public void disableMotor(int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. @@ -521,12 +508,6 @@ public void enableMotor(int toolhead) throws RetryException { machine.getTool(toolhead).disableMotor(); } - @Deprecated @Override - public void disableMotor() throws RetryException { - this.disableMotor(-1); - - } - @Override public double getMotorRPM(int toolhead) { if (toolhead == -1) toolhead = machine.currentTool().getIndex(); return machine.getTool(toolhead).getMotorSpeedRPM(); From 7d0291f79ec8d5134a69bda63f0cb1ab740083b3 Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Fri, 9 Mar 2012 21:38:35 -0800 Subject: [PATCH 22/35] Removed old-style temperature control methods from Driver. The commands support a deprecated form that infers the current tool selection. They're already equipped to pass -1 into the Driver, which is still supported by all drivers. --- src/replicatorg/drivers/Driver.java | 8 ---- .../drivers/DriverBaseImplementation.java | 43 ------------------- .../commands/SetPlatformTemperature.java | 5 +-- .../drivers/commands/SetTemperature.java | 5 +-- 4 files changed, 2 insertions(+), 59 deletions(-) diff --git a/src/replicatorg/drivers/Driver.java b/src/replicatorg/drivers/Driver.java index cd41b9ff7..9f7207c00 100644 --- a/src/replicatorg/drivers/Driver.java +++ b/src/replicatorg/drivers/Driver.java @@ -324,32 +324,24 @@ public interface Driver { * Temperature interface functions * @throws RetryException **************************************************************************/ - @Deprecated public void setTemperature(double temperature) throws RetryException; public void setTemperature(double temperature, int toolIndex) throws RetryException; - @Deprecated public void readTemperature(); public void readTemperature(int toolhead); - @Deprecated public double getTemperature(); public double getTemperature(int toolhead); - @Deprecated public double getTemperatureSetting(); public double getTemperatureSetting(int toolhead); /*************************************************************************** * Platform Temperature interface functions * @throws RetryException **************************************************************************/ - @Deprecated public void setPlatformTemperature(double temperature) throws RetryException; public void setPlatformTemperature(double temperature, int toolIndex) throws RetryException; - @Deprecated public void readPlatformTemperature(); public void readPlatformTemperature(int toolhead); - @Deprecated public double getPlatformTemperature(); public double getPlatformTemperature(int toolhead); - @Deprecated public double getPlatformTemperatureSetting(); public double getPlatformTemperatureSetting(int toolhead); /*************************************************************************** diff --git a/src/replicatorg/drivers/DriverBaseImplementation.java b/src/replicatorg/drivers/DriverBaseImplementation.java index db05f2706..6c4247a07 100644 --- a/src/replicatorg/drivers/DriverBaseImplementation.java +++ b/src/replicatorg/drivers/DriverBaseImplementation.java @@ -611,12 +611,7 @@ public double getMotorSteps() { /*************************************************************************** * Temperature interface functions * @throws RetryException - * @deprecated **************************************************************************/ - @Deprecated @Override - public void setTemperature(double temperature) throws RetryException { - machine.currentTool().setTargetTemperature(temperature); - } @Override public void setTemperature(double temperature, int toolhead) throws RetryException { @@ -626,21 +621,10 @@ public void setTemperature(double temperature, int toolhead) throws RetryExcepti machine.getTool(toolhead).setTargetTemperature(temperature); } - @Deprecated @Override public void readTemperature() { - readTemperature(-1); - } - @Override public void readTemperature(int toolhead) { } - /** relies on timing to have the 'correct selected toolhead', deprecated */ - @Override - @Deprecated - public double getTemperature() { - return getTemperature(-1); - } - @Override public double getTemperature(int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. @@ -652,13 +636,7 @@ public double getTemperature(int toolhead) { /*************************************************************************** * Platform Temperature interface functions * @throws RetryException - * @deprecated **************************************************************************/ - @Deprecated @Override - public void setPlatformTemperature(double temperature) throws RetryException { - this.setPlatformTemperature(temperature, -1); - } - @Override public void setPlatformTemperature(double temperature, int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. @@ -667,25 +645,12 @@ public void setPlatformTemperature(double temperature, int toolhead) throws Retr machine.getTool(toolhead).setPlatformTargetTemperature(temperature); } - /** relies on timing to have the 'right selected toolhead', deprecated */ - @Override @Deprecated - public void readPlatformTemperature() { - this.readPlatformTemperature(-1); - } - @Override public void readPlatformTemperature(int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); } - /** relies on timing to have the 'right selected toolhead', deprecated */ - @Override - @Deprecated - public double getPlatformTemperature() { - return this.getPlatformTemperature(-1); - } - @Override public double getPlatformTemperature(int toolhead) { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); @@ -862,19 +827,11 @@ public void setAutomatedBuildPlatformRunning(boolean state, int toolhead) @Override public void setChamberTemperature(double temperature) { } - @Deprecated @Override public double getPlatformTemperatureSetting() { - return getPlatformTemperatureSetting(-1); - } - @Override public double getPlatformTemperatureSetting(int toolhead) { if (toolhead == -1) toolhead = machine.currentTool().getIndex(); return machine.getTool(toolhead).getPlatformTargetTemperature(); } - @Deprecated @Override public double getTemperatureSetting() { - return getTemperatureSetting(-1); - } - @Override public double getTemperatureSetting(int toolhead) { if (toolhead == -1) toolhead = machine.currentTool().getIndex(); return machine.getTool(toolhead).getTargetTemperature(); diff --git a/src/replicatorg/drivers/commands/SetPlatformTemperature.java b/src/replicatorg/drivers/commands/SetPlatformTemperature.java index 900976297..41e733d36 100644 --- a/src/replicatorg/drivers/commands/SetPlatformTemperature.java +++ b/src/replicatorg/drivers/commands/SetPlatformTemperature.java @@ -31,9 +31,6 @@ public SetPlatformTemperature(double temperature, int toolIndex) { @Override public void run(Driver driver) throws RetryException { - if(this.toolIndex == -1) - driver.setPlatformTemperature(temperature); - else - driver.setPlatformTemperature(temperature, toolIndex); + driver.setPlatformTemperature(temperature, toolIndex); } } \ No newline at end of file diff --git a/src/replicatorg/drivers/commands/SetTemperature.java b/src/replicatorg/drivers/commands/SetTemperature.java index 2827f55b3..77c115bb0 100644 --- a/src/replicatorg/drivers/commands/SetTemperature.java +++ b/src/replicatorg/drivers/commands/SetTemperature.java @@ -32,9 +32,6 @@ public SetTemperature(double temperature, int toolIndex) { @Override public void run(Driver driver) throws RetryException { - if (this.toolhead == -1) - driver.setTemperature(temperature); /// do problematic 'get current toolhead - else - driver.setTemperature(temperature, toolhead); + driver.setTemperature(temperature, toolhead); } } From 102a0f7c3949a48061e65d66574d17f727764178 Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Fri, 9 Mar 2012 21:39:47 -0800 Subject: [PATCH 23/35] Removed old-style fan control methods from Driver. The methods were unused. --- src/replicatorg/drivers/Driver.java | 2 -- src/replicatorg/drivers/DriverBaseImplementation.java | 8 -------- 2 files changed, 10 deletions(-) diff --git a/src/replicatorg/drivers/Driver.java b/src/replicatorg/drivers/Driver.java index 9f7207c00..e5c88e5e9 100644 --- a/src/replicatorg/drivers/Driver.java +++ b/src/replicatorg/drivers/Driver.java @@ -371,10 +371,8 @@ public interface Driver { * Fan interface functions * @throws RetryException **************************************************************************/ - @Deprecated public void enableFan() throws RetryException; public void enableFan(int toolhead) throws RetryException; - @Deprecated public void disableFan() throws RetryException; public void disableFan(int toolhead) throws RetryException; diff --git a/src/replicatorg/drivers/DriverBaseImplementation.java b/src/replicatorg/drivers/DriverBaseImplementation.java index 6c4247a07..28317fd4f 100644 --- a/src/replicatorg/drivers/DriverBaseImplementation.java +++ b/src/replicatorg/drivers/DriverBaseImplementation.java @@ -684,11 +684,7 @@ public void setPlatformTemperature(double temperature, int toolhead) throws Retr /*************************************************************************** * Fan interface functions * @throws RetryException - * @deprecated **************************************************************************/ - @Deprecated @Override public void enableFan() throws RetryException { - this.enableFan(machine.currentTool().getIndex()); - } @Override public void enableFan(int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. @@ -697,10 +693,6 @@ public void enableFan(int toolhead) throws RetryException { } - @Deprecated @Override public void disableFan() throws RetryException { - this.disableFan(machine.currentTool().getIndex()); - } - @Override public void disableFan(int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. From 4ecb79c877da20a4b8c45cd2d679191e6c0c06b1 Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Fri, 9 Mar 2012 21:40:22 -0800 Subject: [PATCH 24/35] Removed old-style ABP method from Driver. The method was unused. --- src/replicatorg/drivers/Driver.java | 1 - src/replicatorg/drivers/DriverBaseImplementation.java | 4 ---- 2 files changed, 5 deletions(-) diff --git a/src/replicatorg/drivers/Driver.java b/src/replicatorg/drivers/Driver.java index e5c88e5e9..f85815247 100644 --- a/src/replicatorg/drivers/Driver.java +++ b/src/replicatorg/drivers/Driver.java @@ -380,7 +380,6 @@ public interface Driver { * abp interface functions * @throws RetryException **************************************************************************/ - @Deprecated public void setAutomatedBuildPlatformRunning(boolean state) throws RetryException; public void setAutomatedBuildPlatformRunning(boolean state, int toolhead) throws RetryException; /*************************************************************************** diff --git a/src/replicatorg/drivers/DriverBaseImplementation.java b/src/replicatorg/drivers/DriverBaseImplementation.java index 28317fd4f..cdd968167 100644 --- a/src/replicatorg/drivers/DriverBaseImplementation.java +++ b/src/replicatorg/drivers/DriverBaseImplementation.java @@ -700,10 +700,6 @@ public void disableFan(int toolhead) throws RetryException { machine.getTool(toolhead).disableFan(); } - - @Deprecated @Override public void setAutomatedBuildPlatformRunning(boolean state) throws RetryException { - this.setAutomatedBuildPlatformRunning(state, machine.currentTool().getIndex()); - } @Override public void setAutomatedBuildPlatformRunning(boolean state, int toolhead) throws RetryException { From 9af862482cf3fb7e5ad1c28ec2fe7ecad13239ff Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Fri, 9 Mar 2012 21:44:47 -0800 Subject: [PATCH 25/35] Removed old-style valve control methods from Driver. Deprecated the no-argument valve command constructors so I can track them down later. --- src/replicatorg/drivers/Driver.java | 2 -- .../drivers/DriverBaseImplementation.java | 9 --------- src/replicatorg/drivers/commands/CloseValve.java | 13 ++++++++++++- src/replicatorg/drivers/commands/OpenValve.java | 16 ++++++++++++++-- src/replicatorg/util/Preconditions.java | 15 +++++++++++++++ 5 files changed, 41 insertions(+), 14 deletions(-) create mode 100644 src/replicatorg/util/Preconditions.java diff --git a/src/replicatorg/drivers/Driver.java b/src/replicatorg/drivers/Driver.java index f85815247..42a9686f2 100644 --- a/src/replicatorg/drivers/Driver.java +++ b/src/replicatorg/drivers/Driver.java @@ -386,10 +386,8 @@ public interface Driver { * Valve interface functions * @throws RetryException **************************************************************************/ - @Deprecated public void openValve() throws RetryException; public void openValve(int toolhead) throws RetryException; - @Deprecated public void closeValve() throws RetryException; public void closeValve(int toolhead) throws RetryException; /************************************************************************* diff --git a/src/replicatorg/drivers/DriverBaseImplementation.java b/src/replicatorg/drivers/DriverBaseImplementation.java index cdd968167..944cd2f26 100644 --- a/src/replicatorg/drivers/DriverBaseImplementation.java +++ b/src/replicatorg/drivers/DriverBaseImplementation.java @@ -719,16 +719,7 @@ public void setAutomatedBuildPlatformRunning(boolean state, int toolhead) /*************************************************************************** * Valve interface functions * @throws RetryException - * @deprecated **************************************************************************/ - @Deprecated @Override public void openValve() throws RetryException { - openValve(-1); - } - - @Deprecated @Override public void closeValve() throws RetryException { - closeValve(-1); - } - @Override public void openValve(int toolhead) throws RetryException { if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); machine.getTool(toolhead).openValve(); diff --git a/src/replicatorg/drivers/commands/CloseValve.java b/src/replicatorg/drivers/commands/CloseValve.java index 39bc7babc..b52ca84f3 100644 --- a/src/replicatorg/drivers/commands/CloseValve.java +++ b/src/replicatorg/drivers/commands/CloseValve.java @@ -1,12 +1,23 @@ package replicatorg.drivers.commands; +import static replicatorg.util.Preconditions.checkNonNegative; import replicatorg.drivers.Driver; import replicatorg.drivers.RetryException; public class CloseValve implements DriverCommand { + private final int toolIndex; + + public CloseValve(int toolIndex) { + this.toolIndex = checkNonNegative(toolIndex, + "Tool indices should not be negative"); + } + + @Deprecated public CloseValve() { + this.toolIndex = -1; // Magic number to infer current tool + } @Override public void run(Driver driver) throws RetryException { - driver.closeValve(); + driver.closeValve(toolIndex); } } diff --git a/src/replicatorg/drivers/commands/OpenValve.java b/src/replicatorg/drivers/commands/OpenValve.java index e4d432f05..36b5b67f1 100644 --- a/src/replicatorg/drivers/commands/OpenValve.java +++ b/src/replicatorg/drivers/commands/OpenValve.java @@ -1,12 +1,24 @@ package replicatorg.drivers.commands; +import static replicatorg.util.Preconditions.*; + import replicatorg.drivers.Driver; import replicatorg.drivers.RetryException; public class OpenValve implements DriverCommand { - + private final int toolIndex; + + public OpenValve(int toolIndex) { + this.toolIndex = checkNonNegative(toolIndex, + "Tool indices should not be negative"); + } + + @Deprecated public OpenValve() { + this.toolIndex = -1; // Magic number to infer current tool + } + @Override public void run(Driver driver) throws RetryException { - driver.openValve(); + driver.openValve(toolIndex); } } diff --git a/src/replicatorg/util/Preconditions.java b/src/replicatorg/util/Preconditions.java new file mode 100644 index 000000000..8508a357c --- /dev/null +++ b/src/replicatorg/util/Preconditions.java @@ -0,0 +1,15 @@ +package replicatorg.util; + +/** + * This class provides static methods for concisely enforcing preconditions, + * e.g. on the arguments to a method or constructor. It's analogous to the + * class with the same name in the Guava library. + */ +public class Preconditions { + private Preconditions() {} // Disallow construction + + public static int checkNonNegative(int value, String message) { + if (value < 0) throw new IllegalArgumentException(message); + return value; + } +} From c54fd32168b3de5ff349e3e10d08abf37a4e8d96 Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Fri, 9 Mar 2012 21:51:13 -0800 Subject: [PATCH 26/35] Removed old-style spindle methods from Driver. This completes the removal of all deprecated methods. --- src/replicatorg/drivers/Driver.java | 9 ------ .../drivers/DriverBaseImplementation.java | 31 +------------------ .../drivers/commands/DisableSpindle.java | 14 +++++++-- .../drivers/commands/EnableSpindle.java | 14 +++++++-- .../drivers/commands/SetSpindleDirection.java | 20 ++++++++---- .../drivers/commands/SetSpindleRPM.java | 17 +++++++--- src/replicatorg/drivers/gen3/MightyBoard.java | 4 +-- 7 files changed, 54 insertions(+), 55 deletions(-) diff --git a/src/replicatorg/drivers/Driver.java b/src/replicatorg/drivers/Driver.java index 42a9686f2..9748fd429 100644 --- a/src/replicatorg/drivers/Driver.java +++ b/src/replicatorg/drivers/Driver.java @@ -299,25 +299,18 @@ public interface Driver { * Spindle interface functions * @throws RetryException **************************************************************************/ - @Deprecated public void setSpindleRPM(double rpm) throws RetryException; public void setSpindleRPM(double rpm, int toolhead) throws RetryException; - @Deprecated public void setSpindleSpeedPWM(int pwm) throws RetryException; public void setSpindleSpeedPWM(int pwm, int toolhead) throws RetryException; - @Deprecated public void setSpindleDirection(int dir); public void setSpindleDirection(int dir, int toolhead); - @Deprecated public double getSpindleRPM(); public double getSpindleRPM(int toolhead); - @Deprecated public int getSpindleSpeedPWM(); public int getSpindleSpeedPWM(int toolhead); - @Deprecated public void enableSpindle() throws RetryException; public void enableSpindle(int toolhead) throws RetryException; - @Deprecated public void disableSpindle() throws RetryException; public void disableSpindle(int toolhead) throws RetryException; /*************************************************************************** @@ -453,7 +446,5 @@ public interface Driver { * reads temperature from all heated build platforms */ public void readAllPlatformTemperatures(); - - } diff --git a/src/replicatorg/drivers/DriverBaseImplementation.java b/src/replicatorg/drivers/DriverBaseImplementation.java index 944cd2f26..6f906312c 100644 --- a/src/replicatorg/drivers/DriverBaseImplementation.java +++ b/src/replicatorg/drivers/DriverBaseImplementation.java @@ -535,32 +535,11 @@ public double getMotorSteps() { /*************************************************************************** * Spindle interface functions - * @deprecated **************************************************************************/ - @Deprecated @Override public void setSpindleDirection(int dir) { - setSpindleDirection(dir, -1); - } - - @Deprecated @Override public void setSpindleDirection(int dir, int toolhead) { + @Override public void setSpindleDirection(int dir, int toolhead) { if (toolhead == -1) toolhead = machine.currentTool().getIndex(); machine.getTool(toolhead).setSpindleDirection(dir); } - - @Deprecated @Override public void setSpindleRPM(double rpm) throws RetryException { - setSpindleRPM(rpm, -1); - } - - @Deprecated @Override public void setSpindleSpeedPWM(int pwm) throws RetryException { - setSpindleSpeedPWM(pwm, -1); - } - - @Deprecated @Override public void enableSpindle() throws RetryException { - enableSpindle(-1); - } - - @Deprecated @Override public void disableSpindle() throws RetryException { - disableSpindle(-1); - } @Override public void setSpindleRPM(double rpm, int toolhead) throws RetryException { /// toolhead -1 indicate auto-detect.Fast hack to get software out.. @@ -590,19 +569,11 @@ public double getMotorSteps() { machine.getTool(toolhead).disableSpindle(); } - @Deprecated @Override public double getSpindleRPM() { - return getSpindleRPM(-1); - } - @Override public double getSpindleRPM(int toolhead) { if (toolhead == -1) toolhead = machine.currentTool().getIndex(); return machine.getTool(toolhead).getSpindleSpeedReadingRPM(); } - @Deprecated @Override public int getSpindleSpeedPWM() { - return getSpindleSpeedPWM(-1); - } - @Override public int getSpindleSpeedPWM(int toolhead) { if (toolhead == -1) toolhead = machine.currentTool().getIndex(); return machine.currentTool().getSpindleSpeedReadingPWM(); diff --git a/src/replicatorg/drivers/commands/DisableSpindle.java b/src/replicatorg/drivers/commands/DisableSpindle.java index f87cb1d10..1efdf7590 100644 --- a/src/replicatorg/drivers/commands/DisableSpindle.java +++ b/src/replicatorg/drivers/commands/DisableSpindle.java @@ -1,14 +1,24 @@ package replicatorg.drivers.commands; +import static replicatorg.util.Preconditions.*; + import replicatorg.drivers.Driver; import replicatorg.drivers.RetryException; public class DisableSpindle implements DriverCommand { + private final int toolIndex; - public DisableSpindle() {}; + public DisableSpindle(int toolIndex) { + this.toolIndex = checkNonNegative(toolIndex, + "Tool indices should not be negative"); + } + + @Deprecated public DisableSpindle() { + this.toolIndex = -1; // Magic number to infer current tool index + } @Override public void run(Driver driver) throws RetryException { - driver.disableSpindle(); + driver.disableSpindle(toolIndex); } } diff --git a/src/replicatorg/drivers/commands/EnableSpindle.java b/src/replicatorg/drivers/commands/EnableSpindle.java index 5481a83d6..420092f4f 100644 --- a/src/replicatorg/drivers/commands/EnableSpindle.java +++ b/src/replicatorg/drivers/commands/EnableSpindle.java @@ -1,14 +1,24 @@ package replicatorg.drivers.commands; +import static replicatorg.util.Preconditions.*; + import replicatorg.drivers.Driver; import replicatorg.drivers.RetryException; public class EnableSpindle implements DriverCommand { + private final int toolIndex; - public EnableSpindle() {}; + public EnableSpindle(int toolIndex) { + this.toolIndex = checkNonNegative(toolIndex, + "Tool indices should not be negative"); + } + + @Deprecated public EnableSpindle() { + this.toolIndex = -1; // Magic number to infer current tool index + } @Override public void run(Driver driver) throws RetryException { - driver.enableSpindle(); + driver.enableSpindle(toolIndex); } } diff --git a/src/replicatorg/drivers/commands/SetSpindleDirection.java b/src/replicatorg/drivers/commands/SetSpindleDirection.java index 8ee69183c..04d16a80e 100644 --- a/src/replicatorg/drivers/commands/SetSpindleDirection.java +++ b/src/replicatorg/drivers/commands/SetSpindleDirection.java @@ -1,14 +1,22 @@ package replicatorg.drivers.commands; +import static replicatorg.util.Preconditions.*; + import replicatorg.drivers.Driver; import replicatorg.machine.model.ToolModel; public class SetSpindleDirection implements DriverCommand { - - - AxialDirection direction; + private final int toolIndex; + private final AxialDirection direction; + + public SetSpindleDirection(AxialDirection direction, int toolIndex) { + this.toolIndex = checkNonNegative(toolIndex, + "Tool indices should not be negative"); + this.direction = direction; + } - public SetSpindleDirection(AxialDirection direction) { + @Deprecated public SetSpindleDirection(AxialDirection direction) { + this.toolIndex = -1; // Magic number to infer current tool index this.direction = direction; } @@ -16,10 +24,10 @@ public SetSpindleDirection(AxialDirection direction) { public void run(Driver driver) { // TODO Auto-generated method stub if (direction == AxialDirection.CLOCKWISE) { - driver.setSpindleDirection(ToolModel.MOTOR_CLOCKWISE); + driver.setSpindleDirection(ToolModel.MOTOR_CLOCKWISE, toolIndex); } else { - driver.setSpindleDirection(ToolModel.MOTOR_COUNTER_CLOCKWISE); + driver.setSpindleDirection(ToolModel.MOTOR_COUNTER_CLOCKWISE, toolIndex); } } } diff --git a/src/replicatorg/drivers/commands/SetSpindleRPM.java b/src/replicatorg/drivers/commands/SetSpindleRPM.java index a30016525..5a335efc7 100644 --- a/src/replicatorg/drivers/commands/SetSpindleRPM.java +++ b/src/replicatorg/drivers/commands/SetSpindleRPM.java @@ -1,18 +1,27 @@ package replicatorg.drivers.commands; +import static replicatorg.util.Preconditions.*; + import replicatorg.drivers.Driver; import replicatorg.drivers.RetryException; public class SetSpindleRPM implements DriverCommand { - - double rpm; + private final int toolIndex; + private final double rpm; + + public SetSpindleRPM(double rpm, int toolIndex) { + this.toolIndex = checkNonNegative(toolIndex, + "Tool indices should not be negative"); + this.rpm = rpm; + } - public SetSpindleRPM(double rpm) { + @Deprecated public SetSpindleRPM(double rpm) { + this.toolIndex = -1; // Magic number to infer current tool index this.rpm = rpm; } @Override public void run(Driver driver) throws RetryException { - driver.setSpindleRPM(rpm); + driver.setSpindleRPM(rpm, toolIndex); } } \ No newline at end of file diff --git a/src/replicatorg/drivers/gen3/MightyBoard.java b/src/replicatorg/drivers/gen3/MightyBoard.java index ba2b5aa65..716b18ab8 100644 --- a/src/replicatorg/drivers/gen3/MightyBoard.java +++ b/src/replicatorg/drivers/gen3/MightyBoard.java @@ -298,6 +298,8 @@ public boolean initializeBot() if (t != null) { initSlave(t.getIndex()); getMotorRPM(t.getIndex()); //load our motor RPM from firmware if we can. + // I have no idea why we still do this, we may want to test and refactor away + getSpindleSpeedPWM(t.getIndex()); } } @@ -314,8 +316,6 @@ public boolean initializeBot() Base.logger.severe("Please double-check your selected machine."); } - // I have no idea why we still do this, we may want to test and refactor away - getSpindleSpeedPWM(); return true; } From 7af51aadc5e3b9e91ae5e7783b9ed4ce7034345e Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Fri, 9 Mar 2012 21:56:10 -0800 Subject: [PATCH 27/35] Valve G-Code commands are now multi-tool aware. --- src/replicatorg/app/gcode/GCodeCommand.java | 10 +++++++++- src/replicatorg/app/gcode/GCodeParser.java | 4 ++-- src/replicatorg/drivers/commands/CloseValve.java | 4 ---- src/replicatorg/drivers/commands/OpenValve.java | 4 ---- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/replicatorg/app/gcode/GCodeCommand.java b/src/replicatorg/app/gcode/GCodeCommand.java index 2444dbb8a..704e8f4dc 100644 --- a/src/replicatorg/app/gcode/GCodeCommand.java +++ b/src/replicatorg/app/gcode/GCodeCommand.java @@ -113,13 +113,21 @@ public boolean hasCode(char searchCode) { } public double getCodeValue(char searchCode) { + return getCodeValue(searchCode, -1); + } + + public double getCodeValue(char searchCode, double fallback) { for (gCodeParameter parameter : parameters) { if (parameter.code == searchCode) { return parameter.value; } } - return -1; // TODO: What do we return if there is no code? + return fallback; + } + + public int getCodeValueInt(char searchCode, int fallback) { + return (int) getCodeValue(searchCode, fallback); } // public Double removeCode(Character searchCode) { diff --git a/src/replicatorg/app/gcode/GCodeParser.java b/src/replicatorg/app/gcode/GCodeParser.java index aa376e713..45bc667f8 100644 --- a/src/replicatorg/app/gcode/GCodeParser.java +++ b/src/replicatorg/app/gcode/GCodeParser.java @@ -533,11 +533,11 @@ else if (gcode.hasCode('R')) break; // valve open case M126: - commands.add(new replicatorg.drivers.commands.OpenValve()); + commands.add(new replicatorg.drivers.commands.OpenValve(gcode.getCodeValueInt('T', driver.getCurrentToolIndex()))); break; // valve close case M127: - commands.add(new replicatorg.drivers.commands.CloseValve()); + commands.add(new replicatorg.drivers.commands.CloseValve(gcode.getCodeValueInt('T', driver.getCurrentToolIndex()))); break; // where are we? case M128: diff --git a/src/replicatorg/drivers/commands/CloseValve.java b/src/replicatorg/drivers/commands/CloseValve.java index b52ca84f3..2fd26a6c6 100644 --- a/src/replicatorg/drivers/commands/CloseValve.java +++ b/src/replicatorg/drivers/commands/CloseValve.java @@ -12,10 +12,6 @@ public CloseValve(int toolIndex) { "Tool indices should not be negative"); } - @Deprecated public CloseValve() { - this.toolIndex = -1; // Magic number to infer current tool - } - @Override public void run(Driver driver) throws RetryException { driver.closeValve(toolIndex); diff --git a/src/replicatorg/drivers/commands/OpenValve.java b/src/replicatorg/drivers/commands/OpenValve.java index 36b5b67f1..db2458a72 100644 --- a/src/replicatorg/drivers/commands/OpenValve.java +++ b/src/replicatorg/drivers/commands/OpenValve.java @@ -13,10 +13,6 @@ public OpenValve(int toolIndex) { "Tool indices should not be negative"); } - @Deprecated public OpenValve() { - this.toolIndex = -1; // Magic number to infer current tool - } - @Override public void run(Driver driver) throws RetryException { driver.openValve(toolIndex); From 5bd64acd2dc05dc85bebec2b7c7b96b86c6b8487 Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Fri, 9 Mar 2012 22:01:19 -0800 Subject: [PATCH 28/35] Spindle and temperature G-Codes are now multitool-aware. --- src/replicatorg/app/gcode/GCodeParser.java | 42 ++++++++++++------- .../drivers/commands/DisableSpindle.java | 4 -- .../drivers/commands/EnableSpindle.java | 4 -- .../commands/SetPlatformTemperature.java | 16 ++----- .../drivers/commands/SetSpindleDirection.java | 6 --- .../drivers/commands/SetSpindleRPM.java | 5 --- .../drivers/commands/SetTemperature.java | 16 ++----- 7 files changed, 36 insertions(+), 57 deletions(-) diff --git a/src/replicatorg/app/gcode/GCodeParser.java b/src/replicatorg/app/gcode/GCodeParser.java index 45bc667f8..0df69a555 100644 --- a/src/replicatorg/app/gcode/GCodeParser.java +++ b/src/replicatorg/app/gcode/GCodeParser.java @@ -317,17 +317,21 @@ private void buildMCodes(GCodeCommand gcode, Queue< DriverCommand > commands) th break; // spindle on, CW case M3: - commands.add(new replicatorg.drivers.commands.SetSpindleDirection(DriverCommand.AxialDirection.CLOCKWISE)); - commands.add(new replicatorg.drivers.commands.EnableSpindle()); + commands.add(new replicatorg.drivers.commands.SetSpindleDirection( + DriverCommand.AxialDirection.CLOCKWISE, + gcode.getCodeValueInt('T', driver.getCurrentToolIndex()))); + commands.add(new replicatorg.drivers.commands.EnableSpindle(gcode.getCodeValueInt('T', driver.getCurrentToolIndex()))); break; // spindle on, CCW case M4: - commands.add(new replicatorg.drivers.commands.SetSpindleDirection(DriverCommand.AxialDirection.COUNTERCLOCKWISE)); - commands.add(new replicatorg.drivers.commands.EnableSpindle()); + commands.add(new replicatorg.drivers.commands.SetSpindleDirection( + DriverCommand.AxialDirection.COUNTERCLOCKWISE, + gcode.getCodeValueInt('T', driver.getCurrentToolIndex()))); + commands.add(new replicatorg.drivers.commands.EnableSpindle(gcode.getCodeValueInt('T', driver.getCurrentToolIndex()))); break; // spindle off case M5: - commands.add(new replicatorg.drivers.commands.DisableSpindle()); + commands.add(new replicatorg.drivers.commands.DisableSpindle(gcode.getCodeValueInt('T', driver.getCurrentToolIndex()))); break; // tool change. case M6: @@ -373,14 +377,18 @@ private void buildMCodes(GCodeCommand gcode, Queue< DriverCommand > commands) th break; // spindle CW and coolant A on case M13: - commands.add(new replicatorg.drivers.commands.SetSpindleDirection(DriverCommand.AxialDirection.CLOCKWISE)); - commands.add(new replicatorg.drivers.commands.EnableSpindle()); + commands.add(new replicatorg.drivers.commands.SetSpindleDirection( + DriverCommand.AxialDirection.CLOCKWISE, + gcode.getCodeValueInt('T', driver.getCurrentToolIndex()))); + commands.add(new replicatorg.drivers.commands.EnableSpindle(gcode.getCodeValueInt('T', driver.getCurrentToolIndex()))); commands.add(new replicatorg.drivers.commands.EnableFloodCoolant()); break; // spindle CCW and coolant A on case M14: - commands.add(new replicatorg.drivers.commands.SetSpindleDirection(DriverCommand.AxialDirection.COUNTERCLOCKWISE)); - commands.add(new replicatorg.drivers.commands.EnableSpindle()); + commands.add(new replicatorg.drivers.commands.SetSpindleDirection( + DriverCommand.AxialDirection.COUNTERCLOCKWISE, + gcode.getCodeValueInt('T', driver.getCurrentToolIndex()))); + commands.add(new replicatorg.drivers.commands.EnableSpindle(gcode.getCodeValueInt('T', driver.getCurrentToolIndex()))); commands.add(new replicatorg.drivers.commands.EnableFloodCoolant()); break; // enable drives @@ -487,8 +495,11 @@ private void buildMCodes(GCodeCommand gcode, Queue< DriverCommand > commands) th break; // custom code for temperature control case M104: - if (gcode.hasCode('S')) - commands.add(new replicatorg.drivers.commands.SetTemperature(gcode.getCodeValue('S'))); + if (gcode.hasCode('S')) { + commands.add(new replicatorg.drivers.commands.SetTemperature( + gcode.getCodeValue('S'), + gcode.getCodeValueInt('T', driver.getCurrentToolIndex()))); + } break; // custom code for temperature reading // TODO: This command seems like a hack, it would be better for the driver to poll temperature rather than @@ -525,7 +536,9 @@ else if (gcode.hasCode('R')) case M109: case M140: // skeinforge chamber code for HBP if (gcode.hasCode('S')) - commands.add(new replicatorg.drivers.commands.SetPlatformTemperature(gcode.getCodeValue('S'))); + commands.add(new replicatorg.drivers.commands.SetPlatformTemperature( + gcode.getCodeValue('S'), + gcode.getCodeValueInt('T', driver.getCurrentToolIndex()))); break; // set build chamber temperature case M110: @@ -621,7 +634,6 @@ private void buildGCodes(GCodeCommand gcode, Queue< DriverCommand > commands) th double qVal = convertToMM(gcode.getCodeValue('Q'), units); // / feed // increment for // G83 - double rVal = convertToMM(gcode.getCodeValue('R'), units); // / arc radius double xVal = convertToMM(gcode.getCodeValue('X'), units); // / X units double yVal = convertToMM(gcode.getCodeValue('Y'), units); // / Y units double zVal = convertToMM(gcode.getCodeValue('Z'), units); // / Z units @@ -893,7 +905,9 @@ else if (gcode.hasCode('R')) { // break; // spindle speed rate case G97: - commands.add(new replicatorg.drivers.commands.SetSpindleRPM(gcode.getCodeValue('S'))); + commands.add(new replicatorg.drivers.commands.SetSpindleRPM( + gcode.getCodeValue('S'), + gcode.getCodeValueInt('T', driver.getCurrentToolIndex()))); break; case G130: /// TODO: axis ids should not be hard coded diff --git a/src/replicatorg/drivers/commands/DisableSpindle.java b/src/replicatorg/drivers/commands/DisableSpindle.java index 1efdf7590..3d7265e18 100644 --- a/src/replicatorg/drivers/commands/DisableSpindle.java +++ b/src/replicatorg/drivers/commands/DisableSpindle.java @@ -13,10 +13,6 @@ public DisableSpindle(int toolIndex) { "Tool indices should not be negative"); } - @Deprecated public DisableSpindle() { - this.toolIndex = -1; // Magic number to infer current tool index - } - @Override public void run(Driver driver) throws RetryException { driver.disableSpindle(toolIndex); diff --git a/src/replicatorg/drivers/commands/EnableSpindle.java b/src/replicatorg/drivers/commands/EnableSpindle.java index 420092f4f..786520c5f 100644 --- a/src/replicatorg/drivers/commands/EnableSpindle.java +++ b/src/replicatorg/drivers/commands/EnableSpindle.java @@ -13,10 +13,6 @@ public EnableSpindle(int toolIndex) { "Tool indices should not be negative"); } - @Deprecated public EnableSpindle() { - this.toolIndex = -1; // Magic number to infer current tool index - } - @Override public void run(Driver driver) throws RetryException { driver.enableSpindle(toolIndex); diff --git a/src/replicatorg/drivers/commands/SetPlatformTemperature.java b/src/replicatorg/drivers/commands/SetPlatformTemperature.java index 41e733d36..a4611b22b 100644 --- a/src/replicatorg/drivers/commands/SetPlatformTemperature.java +++ b/src/replicatorg/drivers/commands/SetPlatformTemperature.java @@ -1,5 +1,7 @@ package replicatorg.drivers.commands; +import static replicatorg.util.Preconditions.*; + import replicatorg.drivers.Driver; import replicatorg.drivers.RetryException; @@ -8,17 +10,6 @@ public class SetPlatformTemperature implements DriverCommand { double temperature; int toolIndex = -1; - /** - * Set temperature, trusting and hoping the right toolhead is active - * when we do. - * @param temperature - */ - @Deprecated - public SetPlatformTemperature(double temperature) { - this.temperature = temperature; - this.toolIndex = -1;// do problematic 'getcurrent tool' when comand runs - } - /** * Set temperature for a specified toolhead * @param temperature @@ -26,7 +17,8 @@ public SetPlatformTemperature(double temperature) { */ public SetPlatformTemperature(double temperature, int toolIndex) { this.temperature = temperature; - this.toolIndex = toolIndex; + this.toolIndex = checkNonNegative(toolIndex, + "Tool indices should not be negative"); } @Override diff --git a/src/replicatorg/drivers/commands/SetSpindleDirection.java b/src/replicatorg/drivers/commands/SetSpindleDirection.java index 04d16a80e..22aeaaafb 100644 --- a/src/replicatorg/drivers/commands/SetSpindleDirection.java +++ b/src/replicatorg/drivers/commands/SetSpindleDirection.java @@ -15,14 +15,8 @@ public SetSpindleDirection(AxialDirection direction, int toolIndex) { this.direction = direction; } - @Deprecated public SetSpindleDirection(AxialDirection direction) { - this.toolIndex = -1; // Magic number to infer current tool index - this.direction = direction; - } - @Override public void run(Driver driver) { - // TODO Auto-generated method stub if (direction == AxialDirection.CLOCKWISE) { driver.setSpindleDirection(ToolModel.MOTOR_CLOCKWISE, toolIndex); } diff --git a/src/replicatorg/drivers/commands/SetSpindleRPM.java b/src/replicatorg/drivers/commands/SetSpindleRPM.java index 5a335efc7..34f44de99 100644 --- a/src/replicatorg/drivers/commands/SetSpindleRPM.java +++ b/src/replicatorg/drivers/commands/SetSpindleRPM.java @@ -15,11 +15,6 @@ public SetSpindleRPM(double rpm, int toolIndex) { this.rpm = rpm; } - @Deprecated public SetSpindleRPM(double rpm) { - this.toolIndex = -1; // Magic number to infer current tool index - this.rpm = rpm; - } - @Override public void run(Driver driver) throws RetryException { driver.setSpindleRPM(rpm, toolIndex); diff --git a/src/replicatorg/drivers/commands/SetTemperature.java b/src/replicatorg/drivers/commands/SetTemperature.java index 77c115bb0..2ae2a4b10 100644 --- a/src/replicatorg/drivers/commands/SetTemperature.java +++ b/src/replicatorg/drivers/commands/SetTemperature.java @@ -1,5 +1,7 @@ package replicatorg.drivers.commands; +import static replicatorg.util.Preconditions.*; + import replicatorg.drivers.Driver; import replicatorg.drivers.RetryException; @@ -8,17 +10,6 @@ public class SetTemperature implements DriverCommand { double temperature; int toolhead = -1; - /** - * Set temperature, trusting and hoping the right toolhead is active - * when we do. - * @param temperature - */ - @Deprecated - public SetTemperature(double temperature) { - this.temperature = temperature; - this.toolhead = -1;/// do problematic 'get current toolhead - } - /** * Set temperature, specifying the toolhead index. * @param temperature @@ -26,7 +17,8 @@ public SetTemperature(double temperature) { */ public SetTemperature(double temperature, int toolIndex) { this.temperature = temperature; - this.toolhead = toolIndex; + this.toolhead = checkNonNegative(toolIndex, + "Tool indices should not be negative"); } From f3db5c8958afffa79e5827fadbfc7a2362bf2238 Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Fri, 9 Mar 2012 22:30:33 -0800 Subject: [PATCH 29/35] Most (all?) commands now take explicit tool indices. This is a step toward eliminating the tool=-1 hack. --- src/replicatorg/app/gcode/GCodeParser.java | 38 +++++++++++-------- .../app/ui/controlpanel/ExtruderPanel.java | 4 +- src/replicatorg/drivers/commands/Delay.java | 11 ++---- .../drivers/commands/DisableFan.java | 10 ++--- .../drivers/commands/DisableMotor.java | 10 ++--- .../drivers/commands/EnableExtruderMotor.java | 18 ++++----- .../drivers/commands/EnableFan.java | 11 +++--- .../drivers/commands/SetMotorDirection.java | 13 +++---- .../drivers/commands/SetMotorSpeedPWM.java | 13 +++---- .../drivers/commands/SetMotorSpeedRPM.java | 13 +++---- .../commands/SetPlatformTemperature.java | 4 +- .../drivers/commands/SetTemperature.java | 4 +- .../ToggleAutomatedBuildPlatform.java | 20 ++++------ 13 files changed, 79 insertions(+), 90 deletions(-) diff --git a/src/replicatorg/app/gcode/GCodeParser.java b/src/replicatorg/app/gcode/GCodeParser.java index 0df69a555..6786afb96 100644 --- a/src/replicatorg/app/gcode/GCodeParser.java +++ b/src/replicatorg/app/gcode/GCodeParser.java @@ -480,18 +480,22 @@ private void buildMCodes(GCodeCommand gcode, Queue< DriverCommand > commands) th // Manually sets the percent complete info on the bot. commands.add(new replicatorg.drivers.commands.SetBuildPercent(gcode.getCodeValue('P'), gcode.getComment() ) ); break; - case M101: - commands.add(new replicatorg.drivers.commands.SetMotorDirection(DriverCommand.AxialDirection.CLOCKWISE)); - commands.add(new replicatorg.drivers.commands.EnableExtruderMotor()); + case M101: { + int toolIndex = gcode.getCodeValueInt('T', driver.getCurrentToolIndex()); + commands.add(new replicatorg.drivers.commands.SetMotorDirection(DriverCommand.AxialDirection.CLOCKWISE, toolIndex)); + commands.add(new replicatorg.drivers.commands.EnableExtruderMotor(toolIndex)); break; + } // turn extruder on, reverse - case M102: - commands.add(new replicatorg.drivers.commands.SetMotorDirection(DriverCommand.AxialDirection.COUNTERCLOCKWISE)); - commands.add(new replicatorg.drivers.commands.EnableExtruderMotor()); + case M102: { + int toolIndex = gcode.getCodeValueInt('T', driver.getCurrentToolIndex()); + commands.add(new replicatorg.drivers.commands.SetMotorDirection(DriverCommand.AxialDirection.COUNTERCLOCKWISE, toolIndex)); + commands.add(new replicatorg.drivers.commands.EnableExtruderMotor(toolIndex)); break; + } // turn extruder off case M103: - commands.add(new replicatorg.drivers.commands.DisableMotor()); + commands.add(new replicatorg.drivers.commands.DisableMotor(gcode.getCodeValueInt('T', driver.getCurrentToolIndex()))); break; // custom code for temperature control case M104: @@ -509,29 +513,31 @@ private void buildMCodes(GCodeCommand gcode, Queue< DriverCommand > commands) th break; // turn AutomatedBuildPlatform on case M106: { - int toolIndex = gcode.hasCode('T') ? (int) gcode.getCodeValue('T') : driver.getCurrentToolIndex(); + int toolIndex = gcode.getCodeValueInt('T', driver.getCurrentToolIndex()); if(driver.hasAutomatedBuildPlatform(toolIndex)) - commands.add(new replicatorg.drivers.commands.ToggleAutomatedBuildPlatform(true)); + commands.add(new replicatorg.drivers.commands.ToggleAutomatedBuildPlatform(true, toolIndex)); else - commands.add(new replicatorg.drivers.commands.EnableFan()); + commands.add(new replicatorg.drivers.commands.EnableFan(toolIndex)); break; } // turn AutomatedBuildPlatform off case M107: { - int toolIndex = gcode.hasCode('T') ? (int) gcode.getCodeValue('T') : driver.getCurrentToolIndex(); + int toolIndex = gcode.getCodeValueInt('T', driver.getCurrentToolIndex()); if(driver.hasAutomatedBuildPlatform(toolIndex)) - commands.add(new replicatorg.drivers.commands.ToggleAutomatedBuildPlatform(false)); + commands.add(new replicatorg.drivers.commands.ToggleAutomatedBuildPlatform(false, toolIndex)); else - commands.add(new replicatorg.drivers.commands.DisableFan()); + commands.add(new replicatorg.drivers.commands.DisableFan(toolIndex)); break; } // set max extruder speed, RPM - case M108: + case M108: { + int toolIndex = gcode.getCodeValueInt('T', driver.getCurrentToolIndex()); if (gcode.hasCode('S')) - commands.add(new replicatorg.drivers.commands.SetMotorSpeedPWM((int)gcode.getCodeValue('S'))); + commands.add(new replicatorg.drivers.commands.SetMotorSpeedPWM((int)gcode.getCodeValue('S'), toolIndex)); else if (gcode.hasCode('R')) - commands.add(new replicatorg.drivers.commands.SetMotorSpeedRPM(gcode.getCodeValue('R'))); + commands.add(new replicatorg.drivers.commands.SetMotorSpeedRPM(gcode.getCodeValue('R'), toolIndex)); break; + } // set build platform temperature case M109: case M140: // skeinforge chamber code for HBP diff --git a/src/replicatorg/app/ui/controlpanel/ExtruderPanel.java b/src/replicatorg/app/ui/controlpanel/ExtruderPanel.java index a8e905483..952130081 100644 --- a/src/replicatorg/app/ui/controlpanel/ExtruderPanel.java +++ b/src/replicatorg/app/ui/controlpanel/ExtruderPanel.java @@ -852,7 +852,7 @@ private void handleMotorAction(ActionEvent e, ToolModel tool) { machine.runCommand(new replicatorg.drivers.commands.SelectTool(toolhead)); machine.runCommand(new replicatorg.drivers.commands.EnableExtruderMotor(toolhead)); - machine.runCommand(new replicatorg.drivers.commands.Delay(extrudeTime*1000,toolhead)); + machine.runCommand(new replicatorg.drivers.commands.Delay(extrudeTime*1000)); machine.runCommand(new replicatorg.drivers.commands.DisableMotor(toolhead)); } } @@ -867,7 +867,7 @@ private void handleMotorAction(ActionEvent e, ToolModel tool) { machine.runCommand(new replicatorg.drivers.commands.SelectTool(toolhead)); machine.runCommand(new replicatorg.drivers.commands.EnableExtruderMotor(toolhead)); - machine.runCommand(new replicatorg.drivers.commands.Delay(extrudeTime*1000,toolhead)); + machine.runCommand(new replicatorg.drivers.commands.Delay(extrudeTime*1000)); machine.runCommand(new replicatorg.drivers.commands.DisableMotor(toolhead)); } } diff --git a/src/replicatorg/drivers/commands/Delay.java b/src/replicatorg/drivers/commands/Delay.java index 79a4307a8..6c6921f46 100644 --- a/src/replicatorg/drivers/commands/Delay.java +++ b/src/replicatorg/drivers/commands/Delay.java @@ -5,19 +5,14 @@ public class Delay implements DriverCommand { - long delay; - int toolhead = -1; ///lazy lookup toolhead - public Delay(long delay) { - this.delay = delay; - } + private final long delay; - public Delay(long delay, int toolhead) { + public Delay(long delay) { this.delay = delay; - this.toolhead = toolhead; } @Override public void run(Driver driver) throws RetryException { - driver.delay(delay); ///toolhead is ignored for current gen machines + driver.delay(delay); } } \ No newline at end of file diff --git a/src/replicatorg/drivers/commands/DisableFan.java b/src/replicatorg/drivers/commands/DisableFan.java index bdd3d9fab..907b012ef 100644 --- a/src/replicatorg/drivers/commands/DisableFan.java +++ b/src/replicatorg/drivers/commands/DisableFan.java @@ -1,18 +1,18 @@ package replicatorg.drivers.commands; +import static replicatorg.util.Preconditions.*; + import replicatorg.drivers.Driver; import replicatorg.drivers.RetryException; public class DisableFan implements DriverCommand { - int toolhead = -1; ///lazy auto-detect tool - - public DisableFan() {} + private final int toolhead; - public DisableFan(int toolhead) { - this.toolhead = toolhead; + this.toolhead = checkNonNegative(toolhead, + "Tool indices should not be negative"); } @Override diff --git a/src/replicatorg/drivers/commands/DisableMotor.java b/src/replicatorg/drivers/commands/DisableMotor.java index e7f50ed54..edea6e590 100644 --- a/src/replicatorg/drivers/commands/DisableMotor.java +++ b/src/replicatorg/drivers/commands/DisableMotor.java @@ -1,16 +1,16 @@ package replicatorg.drivers.commands; +import static replicatorg.util.Preconditions.*; + import replicatorg.drivers.Driver; import replicatorg.drivers.RetryException; public class DisableMotor implements DriverCommand { - int toolhead = -1 ; /// + private final int toolhead; - - public DisableMotor() {} - public DisableMotor(int toolhead) { - this.toolhead = toolhead; + this.toolhead = checkNonNegative(toolhead, + "Tool indices should not be negative"); } @Override diff --git a/src/replicatorg/drivers/commands/EnableExtruderMotor.java b/src/replicatorg/drivers/commands/EnableExtruderMotor.java index 032efad96..e4cb92cb5 100644 --- a/src/replicatorg/drivers/commands/EnableExtruderMotor.java +++ b/src/replicatorg/drivers/commands/EnableExtruderMotor.java @@ -1,27 +1,23 @@ package replicatorg.drivers.commands; +import static replicatorg.util.Preconditions.*; + import replicatorg.drivers.Driver; import replicatorg.drivers.RetryException; public class EnableExtruderMotor implements DriverCommand { - long millis = 0; - int toolhead = -1; - - public EnableExtruderMotor() {} + private final long millis; + private final int toolhead; public EnableExtruderMotor(int toolhead) { - this.millis = 0; - this.toolhead = toolhead; - } - - public EnableExtruderMotor(long millis) { - this.millis = millis; + this(0, toolhead); } public EnableExtruderMotor(long millis, int toolhead) { this.millis = millis; - this.toolhead = toolhead; + this.toolhead = checkNonNegative(toolhead, + "Tool indices should not be negative"); } @Override diff --git a/src/replicatorg/drivers/commands/EnableFan.java b/src/replicatorg/drivers/commands/EnableFan.java index b61bb9e5c..b72622dc4 100644 --- a/src/replicatorg/drivers/commands/EnableFan.java +++ b/src/replicatorg/drivers/commands/EnableFan.java @@ -1,18 +1,17 @@ package replicatorg.drivers.commands; +import static replicatorg.util.Preconditions.*; + import replicatorg.drivers.Driver; import replicatorg.drivers.RetryException; public class EnableFan implements DriverCommand { + private final int toolhead; - int toolhead = -1; /// lazy lookup current tool - - public EnableFan() {} - - public EnableFan(int toolhead) { - this.toolhead = toolhead; + this.toolhead = checkNonNegative(toolhead, + "Tool indices should not be negative"); } @Override diff --git a/src/replicatorg/drivers/commands/SetMotorDirection.java b/src/replicatorg/drivers/commands/SetMotorDirection.java index b5e945633..93fad906a 100644 --- a/src/replicatorg/drivers/commands/SetMotorDirection.java +++ b/src/replicatorg/drivers/commands/SetMotorDirection.java @@ -1,20 +1,19 @@ package replicatorg.drivers.commands; +import static replicatorg.util.Preconditions.*; + import replicatorg.drivers.Driver; import replicatorg.machine.model.ToolModel; public class SetMotorDirection implements DriverCommand { - AxialDirection direction; - int toolhead = -1; /// lazy autodetect + private final AxialDirection direction; + private final int toolhead; - public SetMotorDirection(AxialDirection direction) { - this.direction = direction; - } - public SetMotorDirection(AxialDirection direction, int toolhead) { this.direction = direction; - this.toolhead = toolhead; + this.toolhead = checkNonNegative(toolhead, + "Tool indices should not be negative"); } @Override diff --git a/src/replicatorg/drivers/commands/SetMotorSpeedPWM.java b/src/replicatorg/drivers/commands/SetMotorSpeedPWM.java index 72f15dfe8..49387a338 100644 --- a/src/replicatorg/drivers/commands/SetMotorSpeedPWM.java +++ b/src/replicatorg/drivers/commands/SetMotorSpeedPWM.java @@ -1,20 +1,19 @@ package replicatorg.drivers.commands; +import static replicatorg.util.Preconditions.*; + import replicatorg.drivers.Driver; import replicatorg.drivers.RetryException; public class SetMotorSpeedPWM implements DriverCommand { - int pwm; - int toolhead = -1; /// by default, get current tool at dispatch time - - public SetMotorSpeedPWM(int pwm) { - this.pwm = pwm; - } + private final int pwm; + private final int toolhead; public SetMotorSpeedPWM(int pwm, int toolhead) { this.pwm = pwm; - this.toolhead = toolhead; + this.toolhead = checkNonNegative(toolhead, + "Tool indices should not be negative"); } @Override diff --git a/src/replicatorg/drivers/commands/SetMotorSpeedRPM.java b/src/replicatorg/drivers/commands/SetMotorSpeedRPM.java index e78174134..37c0ee7ea 100644 --- a/src/replicatorg/drivers/commands/SetMotorSpeedRPM.java +++ b/src/replicatorg/drivers/commands/SetMotorSpeedRPM.java @@ -1,20 +1,19 @@ package replicatorg.drivers.commands; +import static replicatorg.util.Preconditions.*; + import replicatorg.drivers.Driver; import replicatorg.drivers.RetryException; public class SetMotorSpeedRPM implements DriverCommand { - double rpm; - int toolhead = -1; /// by default, get current tool at dispatch time + private final double rpm; + private final int toolhead; - public SetMotorSpeedRPM(double rpm) { - this.rpm = rpm; - } - public SetMotorSpeedRPM(double rpm, int toolhead) { this.rpm = rpm; - this.toolhead = toolhead; + this.toolhead = checkNonNegative(toolhead, + "Tool indices should not be negative"); } @Override diff --git a/src/replicatorg/drivers/commands/SetPlatformTemperature.java b/src/replicatorg/drivers/commands/SetPlatformTemperature.java index a4611b22b..a613e5b91 100644 --- a/src/replicatorg/drivers/commands/SetPlatformTemperature.java +++ b/src/replicatorg/drivers/commands/SetPlatformTemperature.java @@ -7,8 +7,8 @@ public class SetPlatformTemperature implements DriverCommand { - double temperature; - int toolIndex = -1; + private final double temperature; + private final int toolIndex; /** * Set temperature for a specified toolhead diff --git a/src/replicatorg/drivers/commands/SetTemperature.java b/src/replicatorg/drivers/commands/SetTemperature.java index 2ae2a4b10..e376836de 100644 --- a/src/replicatorg/drivers/commands/SetTemperature.java +++ b/src/replicatorg/drivers/commands/SetTemperature.java @@ -7,8 +7,8 @@ public class SetTemperature implements DriverCommand { - double temperature; - int toolhead = -1; + private final double temperature; + private final int toolhead; /** * Set temperature, specifying the toolhead index. diff --git a/src/replicatorg/drivers/commands/ToggleAutomatedBuildPlatform.java b/src/replicatorg/drivers/commands/ToggleAutomatedBuildPlatform.java index f58ca4413..f943720f5 100644 --- a/src/replicatorg/drivers/commands/ToggleAutomatedBuildPlatform.java +++ b/src/replicatorg/drivers/commands/ToggleAutomatedBuildPlatform.java @@ -1,28 +1,24 @@ package replicatorg.drivers.commands; +import static replicatorg.util.Preconditions.*; + import replicatorg.drivers.Driver; import replicatorg.drivers.RetryException; public class ToggleAutomatedBuildPlatform implements DriverCommand { - - boolean state; - int toolhead = -1; - public ToggleAutomatedBuildPlatform(boolean state) - { - super(); - this.state = state; - } - + private final boolean state; + private final int toolhead; + public ToggleAutomatedBuildPlatform(boolean state, int toolhead) { - super(); this.state = state; - this.toolhead = toolhead; + this.toolhead = checkNonNegative(toolhead, + "Tool indices should not be negative"); } @Override public void run(Driver driver) throws RetryException { - driver.setAutomatedBuildPlatformRunning(state,toolhead ); + driver.setAutomatedBuildPlatformRunning(state, toolhead); } } From 0e207ef710b5e0cc69c66294bf0355d348bd1e0c Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Fri, 9 Mar 2012 22:34:23 -0800 Subject: [PATCH 30/35] Added driver name and stop info to DriverQueryInterface. This eliminates a few uses of the deprecated machine.getDriver() method, but not all. It seems to get pretty active use these days. --- .../app/ui/controlpanel/ExtruderPanel.java | 4 +-- .../app/ui/controlpanel/JogPanel.java | 26 +++++++++---------- .../drivers/DriverQueryInterface.java | 4 +++ 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/replicatorg/app/ui/controlpanel/ExtruderPanel.java b/src/replicatorg/app/ui/controlpanel/ExtruderPanel.java index 952130081..afdb59d42 100644 --- a/src/replicatorg/app/ui/controlpanel/ExtruderPanel.java +++ b/src/replicatorg/app/ui/controlpanel/ExtruderPanel.java @@ -845,7 +845,7 @@ private void handleMotorAction(ActionEvent e, ToolModel tool) { if (tool.getMotorStepperAxisName() != "") { machine.runCommand(new replicatorg.drivers.commands.SetMotorDirection(AxialDirection.CLOCKWISE,toolhead)); // Reverted to one single command for RepRap5D driver - if (machine.getDriver().getDriverName().equals("RepRap5D")) { + if (machine.getDriverQueryInterface().getDriverName().equals("RepRap5D")) { machine.runCommand(new replicatorg.drivers.commands.EnableExtruderMotor(extrudeTime*1000,toolhead)); } else { // See Note (***) Below: @@ -860,7 +860,7 @@ private void handleMotorAction(ActionEvent e, ToolModel tool) { if (tool.getMotorStepperAxisName() != "") { machine.runCommand(new replicatorg.drivers.commands.SetMotorDirection(AxialDirection.COUNTERCLOCKWISE,toolhead)); // Reverted to one single command for RepRap5D driver - if (machine.getDriver().getDriverName().equals("RepRap5D")) { + if (machine.getDriverQueryInterface().getDriverName().equals("RepRap5D")) { machine.runCommand(new replicatorg.drivers.commands.EnableExtruderMotor(extrudeTime*1000,toolhead)); } else { // See Note (***) Below: diff --git a/src/replicatorg/app/ui/controlpanel/JogPanel.java b/src/replicatorg/app/ui/controlpanel/JogPanel.java index 09c34197b..ad64a3f03 100644 --- a/src/replicatorg/app/ui/controlpanel/JogPanel.java +++ b/src/replicatorg/app/ui/controlpanel/JogPanel.java @@ -179,7 +179,7 @@ public JPanel getButtonPanel() { button = createJogButton(yPlusButtonString, yPlusTooltip, this, jogYPlusAction); panel.add(button, "pos "+yPlusButtonLocation.x+" "+yPlusButtonLocation.y); - if(machine.getDriver().hasEmergencyStop()) { + if(machine.getDriverQueryInterface().hasEmergencyStop()) { JButton panicButton = createJogButton(stopButtonString, stopTooltip, this, stopAction); panel.add(panicButton, "pos "+stopButtonLocation.x+" "+stopButtonLocation.y); } @@ -445,7 +445,7 @@ protected JTextField createDisplayField() { private void setJogMode(String mode) { if ("Continuous Jog".equals(mode)) { - if(this.machine.getDriver().hasSoftStop()) + if(this.machine.getDriverQueryInterface().hasSoftStop()) { continuousJogMode = true; jogRate = 0; @@ -537,18 +537,18 @@ void updateFromField() { slider.setValue(val); } - public void actionPerformed(ActionEvent e) { + @Override public void actionPerformed(ActionEvent e) { updateFromField(); } - public void focusGained(FocusEvent e) { + @Override public void focusGained(FocusEvent e) { } - public void focusLost(FocusEvent e) { + @Override public void focusLost(FocusEvent e) { updateFromField(); } - public void stateChanged(ChangeEvent e) { + @Override public void stateChanged(ChangeEvent e) { int val = slider.getValue(); feedrate.setAxis(axis, val); Base.preferences.putInt(getPrefName(), val); @@ -591,7 +591,7 @@ public JogPanel(MachineInterface machine) { jogPattern = Pattern.compile("([.0-9]+)"); // If it does have soft stops, happy continuous jogging!! - if(!this.machine.getDriver().hasSoftStop()) + if(!this.machine.getDriverQueryInterface().hasSoftStop()) { List list = new ArrayList(Arrays.asList(jogStrings)); list.removeAll(Arrays.asList("Continuous Jog")); @@ -649,7 +649,7 @@ synchronized public void updateStatus() { Pattern jogActionParser = Pattern.compile("([XYZAB])([\\+\\-])"); Pattern centerActionParser = Pattern.compile("Center ([XYZAB])"); - public void actionPerformed(ActionEvent e) { + @Override public void actionPerformed(ActionEvent e) { Point5d current = machine.getDriverQueryInterface().getCurrentPosition(false); String s = e.getActionCommand(); @@ -697,19 +697,19 @@ else if (s.equals("jog size")) { } } - public void mouseClicked(MouseEvent arg0) { + @Override public void mouseClicked(MouseEvent arg0) { // Ignore; let default handler take care of it } - public void mouseEntered(MouseEvent arg0) { + @Override public void mouseEntered(MouseEvent arg0) { // Ignore; let default handler take care of it } - public void mouseExited(MouseEvent arg0) { + @Override public void mouseExited(MouseEvent arg0) { // Ignore; let default handler take care of it } - public void mousePressed(MouseEvent e) { + @Override public void mousePressed(MouseEvent e) { if (continuousJogMode) { Point5d current = machine.getDriverQueryInterface().getCurrentPosition(false); @@ -729,7 +729,7 @@ public void mousePressed(MouseEvent e) { } } - public void mouseReleased(MouseEvent arg0) { + @Override public void mouseReleased(MouseEvent arg0) { if (continuousJogMode) { machine.stopMotion(); } diff --git a/src/replicatorg/drivers/DriverQueryInterface.java b/src/replicatorg/drivers/DriverQueryInterface.java index eaf08fe75..486a681b9 100644 --- a/src/replicatorg/drivers/DriverQueryInterface.java +++ b/src/replicatorg/drivers/DriverQueryInterface.java @@ -13,6 +13,10 @@ public interface DriverQueryInterface { public int getCurrentToolIndex(); + public String getDriverName(); + public boolean hasEmergencyStop(); + public boolean hasSoftStop(); + public Point3d getOffset(int i); public Point5d getMaximumFeedrates(); From 7b9c9cbc49045fd8ef5b68ffff2199ac5c99f983 Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Sat, 10 Mar 2012 00:21:32 -0800 Subject: [PATCH 31/35] Added code to defend against the negative tool hack. I'm pretty sure that all sources of negative tool indices have been stamped out at this point. This code will detect further uses and report them in the log. --- .../drivers/DriverBaseImplementation.java | 79 +++++----- .../drivers/SerialPassthroughDriver.java | 2 +- src/replicatorg/drivers/gen3/MightyBoard.java | 9 +- .../drivers/gen3/Sanguino3GDriver.java | 142 ++++++------------ .../drivers/reprap/RepRap5DDriver.java | 2 +- .../drivers/reprap/SimpleRepRap5DDriver.java | 2 +- 6 files changed, 88 insertions(+), 148 deletions(-) diff --git a/src/replicatorg/drivers/DriverBaseImplementation.java b/src/replicatorg/drivers/DriverBaseImplementation.java index 6f906312c..4457a9d89 100644 --- a/src/replicatorg/drivers/DriverBaseImplementation.java +++ b/src/replicatorg/drivers/DriverBaseImplementation.java @@ -91,6 +91,16 @@ protected DriverBaseImplementation() { machine = new MachineModel(); } + protected int fixToolIndex(int toolhead) { + if (toolhead < 0) { + new IllegalStateException("Negative toolhead index: " + toolhead) + .printStackTrace(); + return machine.currentTool().getIndex(); + } else { + return toolhead; + } + } + @Override public void loadXML(Node xml) { } @@ -459,8 +469,7 @@ protected Point5d getDelta(Point5d p) { **************************************************************************/ @Override public void setMotorDirection(int dir, int toolhead) { - /// toolhead -1 indicate auto-detect. Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); machine.getTool(toolhead).setMotorDirection(dir); } @@ -468,24 +477,21 @@ public void setMotorDirection(int dir, int toolhead) { @Override public void setMotorRPM(double rpm, int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect. Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); machine.getTool(toolhead).setMotorSpeedRPM(rpm); } @Override public void setMotorSpeedPWM(int pwm, int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); machine.getTool(toolhead).setMotorSpeedPWM(pwm); } @Override public void enableMotor(long millis, int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); enableMotor(toolhead); delay( millis ); @@ -494,27 +500,25 @@ public void enableMotor(long millis, int toolhead) throws RetryException { @Override public void enableMotor(int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); machine.getTool(toolhead).enableMotor(); } @Override public void disableMotor(int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); machine.getTool(toolhead).disableMotor(); } @Override public double getMotorRPM(int toolhead) { - if (toolhead == -1) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); return machine.getTool(toolhead).getMotorSpeedRPM(); } @Override public int getMotorSpeedPWM(int toolhead) { - if (toolhead == -1) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); return machine.getTool(toolhead).getMotorSpeedPWM(); } @@ -527,7 +531,7 @@ public double getMotorSteps() { } @Override public int getToolStatus(int toolhead) { - if (toolhead == -1) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); readToolStatus(toolhead); return machine.getTool(toolhead).getToolStatus(); @@ -537,34 +541,30 @@ public double getMotorSteps() { * Spindle interface functions **************************************************************************/ @Override public void setSpindleDirection(int dir, int toolhead) { - if (toolhead == -1) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); machine.getTool(toolhead).setSpindleDirection(dir); } @Override public void setSpindleRPM(double rpm, int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); machine.getTool(toolhead).setSpindleSpeedRPM(rpm); } @Override public void setSpindleSpeedPWM(int pwm, int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); machine.getTool(toolhead).setSpindleSpeedPWM(pwm); } @Override public void enableSpindle(int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); machine.getTool(toolhead).enableSpindle(); } @Override public void disableSpindle(int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); machine.getTool(toolhead).disableSpindle(); } @@ -586,8 +586,7 @@ public double getMotorSteps() { @Override public void setTemperature(double temperature, int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); machine.getTool(toolhead).setTargetTemperature(temperature); } @@ -598,8 +597,7 @@ public void setTemperature(double temperature, int toolhead) throws RetryExcepti @Override public double getTemperature(int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); return machine.getTool(toolhead).getCurrentTemperature(); } @@ -610,21 +608,18 @@ public double getTemperature(int toolhead) { **************************************************************************/ @Override public void setPlatformTemperature(double temperature, int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); machine.getTool(toolhead).setPlatformTargetTemperature(temperature); } @Override public void readPlatformTemperature(int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); } @Override public double getPlatformTemperature(int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); readPlatformTemperature(toolhead); return machine.getTool(toolhead).getPlatformCurrentTemperature(); @@ -658,32 +653,28 @@ public void setPlatformTemperature(double temperature, int toolhead) throws Retr **************************************************************************/ @Override public void enableFan(int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); machine.getTool(toolhead).enableFan(); } @Override public void disableFan(int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); machine.getTool(toolhead).disableFan(); } @Override public void setAutomatedBuildPlatformRunning(boolean state, int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); machine.getTool(toolhead).setAutomatedBuildPlatformRunning(state); } @Override public boolean hasAutomatedBuildPlatform(int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); return machine.getTool(toolhead).hasAutomatedPlatform(); } @@ -692,12 +683,12 @@ public void setAutomatedBuildPlatformRunning(boolean state, int toolhead) * @throws RetryException **************************************************************************/ @Override public void openValve(int toolhead) throws RetryException { - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); machine.getTool(toolhead).openValve(); } @Override public void closeValve(int toolhead) throws RetryException { - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); machine.getTool(toolhead).closeValve(); } diff --git a/src/replicatorg/drivers/SerialPassthroughDriver.java b/src/replicatorg/drivers/SerialPassthroughDriver.java index adb797849..3ea7f80a8 100644 --- a/src/replicatorg/drivers/SerialPassthroughDriver.java +++ b/src/replicatorg/drivers/SerialPassthroughDriver.java @@ -334,7 +334,7 @@ private String _getCurrentToolCode() { } private String _getToolCode(int index) { - return "T" + (index == -1 ? machine.currentTool().getIndex() : index) + " "; + return "T" + fixToolIndex(index) + " "; } /*************************************************************************** diff --git a/src/replicatorg/drivers/gen3/MightyBoard.java b/src/replicatorg/drivers/gen3/MightyBoard.java index 716b18ab8..f9cc2c948 100644 --- a/src/replicatorg/drivers/gen3/MightyBoard.java +++ b/src/replicatorg/drivers/gen3/MightyBoard.java @@ -1090,8 +1090,7 @@ protected byte[] readFromToolEEPROM(int offset, int len, int toolIndex) { @Override public void enableMotor(int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); //WARNING: this in unsafe, since tool is checked @@ -1115,8 +1114,7 @@ public void enableMotor(int toolhead) throws RetryException { @Override public void disableMotor(int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); ToolModel curTool = machine.getTool(toolhead);//WARNING: this in unsafe, since tool is checked @@ -1459,8 +1457,7 @@ public Version getToolVersion() { @Override public void setMotorRPM(double rpm, int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); ToolModel curTool = machine.getTool(toolhead);//WARNING: this in unsafe, since tool is checked diff --git a/src/replicatorg/drivers/gen3/Sanguino3GDriver.java b/src/replicatorg/drivers/gen3/Sanguino3GDriver.java index 6d23e4371..d0fb9e764 100644 --- a/src/replicatorg/drivers/gen3/Sanguino3GDriver.java +++ b/src/replicatorg/drivers/gen3/Sanguino3GDriver.java @@ -539,11 +539,9 @@ private Version getVersionInternal() { return stats; } - + private void initSlave(int toolhead) { - - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); PacketBuilder slavepb = new PacketBuilder( MotherboardCommandCode.TOOL_QUERY.getCode()); @@ -910,8 +908,7 @@ private int axesToBitfield(EnumSet axes) { **************************************************************************/ @Override public void setMotorRPM(double rpm, int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); // convert RPM into microseconds and then send. long microseconds = rpm == 0 ? 0 : Math.round(60.0 * 1000000.0 / rpm); // no // unsigned @@ -935,8 +932,7 @@ private int axesToBitfield(EnumSet axes) { @Override public void setMotorSpeedPWM(int pwm, int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); // If we are using a relay, make sure that we don't enable the PWM if (machine.getTool(toolhead).getMotorUsesRelay() && pwm > 0) { @@ -960,9 +956,7 @@ private int axesToBitfield(EnumSet axes) { @Override public void enableMotor(int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) - toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); // our flag variable starts with motors enabled. byte flags = 1; @@ -988,8 +982,7 @@ private int axesToBitfield(EnumSet axes) { @Override public void disableMotor(int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); // bit 1 determines direction... byte flags = 0; @@ -1011,8 +1004,7 @@ public void disableMotor(int toolhead) throws RetryException { @Override public int getMotorSpeedPWM(int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); PacketBuilder pb = new PacketBuilder( MotherboardCommandCode.TOOL_QUERY.getCode()); @@ -1034,8 +1026,7 @@ public void disableMotor(int toolhead) throws RetryException { @Override public double getMotorRPM(int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); PacketBuilder pb = new PacketBuilder( MotherboardCommandCode.TOOL_QUERY.getCode()); @@ -1058,8 +1049,7 @@ public void disableMotor(int toolhead) throws RetryException { } @Override public void readToolStatus(int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); PacketBuilder pb = new PacketBuilder( MotherboardCommandCode.TOOL_QUERY.getCode()); @@ -1099,8 +1089,7 @@ private int fixSigned(int value) { // TODO: Implement a way for this to reach the outside private void readToolPIDState(int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); if (Base.logger.isLoggable(Level.FINE)) { @@ -1143,8 +1132,7 @@ public void setServoPos(int index, double degree) throws RetryException { private void setServoPos(int index, double degree, int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); int command = 0; @@ -1191,8 +1179,7 @@ private void setServoPos(int index, double degree, int toolhead) throws RetryExc **************************************************************************/ @Override public void setSpindleRPM(double rpm, int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); // convert RPM into microseconds and then send. long microseconds = (int) Math.round(60 * 1000000 / rpm); // no @@ -1217,8 +1204,7 @@ private void setServoPos(int index, double degree, int toolhead) throws RetryExc @Override public void setSpindleSpeedPWM(int pwm, int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); Base.logger.fine("Setting motor 2 speed to " + pwm + " PWM"); @@ -1236,8 +1222,7 @@ private void setServoPos(int index, double degree, int toolhead) throws RetryExc @Override public void enableSpindle(int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); // our flag variable starts with spindles enabled. byte flags = 1; @@ -1263,8 +1248,7 @@ private void setServoPos(int index, double degree, int toolhead) throws RetryExc @Override public void disableSpindle(int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); // bit 1 determines direction... byte flags = 0; @@ -1286,8 +1270,7 @@ private void setServoPos(int index, double degree, int toolhead) throws RetryExc @Override public double getSpindleRPM(int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); PacketBuilder pb = new PacketBuilder( MotherboardCommandCode.TOOL_QUERY.getCode()); @@ -1309,8 +1292,7 @@ private void setServoPos(int index, double degree, int toolhead) throws RetryExc @Override public int getSpindleSpeedPWM(int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); PacketBuilder pb = new PacketBuilder( MotherboardCommandCode.TOOL_QUERY.getCode()); @@ -1336,8 +1318,7 @@ private void setServoPos(int index, double degree, int toolhead) throws RetryExc **************************************************************************/ @Override public void setTemperature(double temperature, int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); // constrain our temperature. int temp = (int) Math.round(temperature); @@ -1369,8 +1350,7 @@ public void readAllTemperatures() { @Override public void readTemperature(int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); PacketBuilder pb = new PacketBuilder( MotherboardCommandCode.TOOL_QUERY.getCode()); @@ -1404,8 +1384,7 @@ else if (pr.isEmpty()) @Override public void setPlatformTemperature(double temperature, int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); int temp = (int) Math.round(temperature); temp = Math.min(temp, 65535); @@ -1423,8 +1402,7 @@ else if (pr.isEmpty()) } @Override public void readPlatformTemperature(int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); PacketBuilder pb = new PacketBuilder(MotherboardCommandCode.TOOL_QUERY.getCode()); pb.add8((byte) toolhead); @@ -1488,8 +1466,7 @@ else if (pr.isEmpty()) **************************************************************************/ @Override public void enableFan(int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); Base.logger.fine("Enabling fan"); @@ -1506,8 +1483,7 @@ else if (pr.isEmpty()) @Override public void disableFan(int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); Base.logger.fine("Disabling fan"); @@ -1524,8 +1500,7 @@ else if (pr.isEmpty()) @Override public void setAutomatedBuildPlatformRunning(boolean state, int toolhead) throws RetryException { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); Base.logger.fine("Toggling ABP to " + state); byte newState = state ? (byte) 1 : (byte) 0; @@ -1550,8 +1525,7 @@ else if (pr.isEmpty()) @Override public void openValve(int toolhead) throws RetryException { Base.logger.fine("Opening valve"); - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); PacketBuilder pb = new PacketBuilder( @@ -1570,8 +1544,7 @@ else if (pr.isEmpty()) @Override public void closeValve(int toolhead) throws RetryException { Base.logger.fine("Closing valve"); - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); PacketBuilder pb = new PacketBuilder( MotherboardCommandCode.TOOL_COMMAND.getCode()); @@ -1781,8 +1754,7 @@ protected void writeToEEPROM(int offset, byte[] data) { protected byte[] readFromToolEEPROM(int offset, int len, int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); PacketBuilder pb = new PacketBuilder(MotherboardCommandCode.TOOL_QUERY.getCode()); @@ -1814,8 +1786,7 @@ protected byte[] readFromToolEEPROM(int offset, int len, int toolhead) { */ protected void writeToToolEEPROM(int offset, byte[] data, int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); final int MAX_PAYLOAD = 11; while (data.length > MAX_PAYLOAD) { @@ -2104,8 +2075,7 @@ public void eepromStoreToolDelta(int axis, double offset){ @Override public void createThermistorTable(int which, double r0, double t0, double beta, int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); // Generate a thermistor table for r0 = 100K. final int ADC_RANGE = 1024; @@ -2162,8 +2132,7 @@ public double temp(double adc) { } @Override public boolean getCoolingFanEnabled(int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); byte[] a = readFromToolEEPROM(CoolingFanOffsets.COOLING_FAN_ENABLE, 1, toolhead); @@ -2171,14 +2140,12 @@ public double temp(double adc) { } @Override public int getCoolingFanSetpoint(int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); return read16FromToolEEPROM(CoolingFanOffsets.COOLING_FAN_SETPOINT_C, 50, toolhead); } @Override public void setCoolingFanParameters(boolean enabled, int setpoint, int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); if (enabled) { writeToToolEEPROM(CoolingFanOffsets.COOLING_FAN_ENABLE, new byte[] { 0x1 }, toolhead); } else { @@ -2308,8 +2275,7 @@ private ResponseCode convertSDCode(int code) { } @Override public int getBeta(int which, int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); byte r[] = readFromToolEEPROM(Sanguino3GEEPRPOM.ECThermistorOffsets.beta(which),4,toolhead); int val = 0; @@ -2324,8 +2290,7 @@ private ResponseCode convertSDCode(int code) { } @Override public int getR0(int which, int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); byte r[] = readFromToolEEPROM(Sanguino3GEEPRPOM.ECThermistorOffsets.r0(which),4,toolhead); int val = 0; if( r == null || r.length < 4 ) { @@ -2339,8 +2304,7 @@ private ResponseCode convertSDCode(int code) { } @Override public int getT0(int which, int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); byte r[] = readFromToolEEPROM(Sanguino3GEEPRPOM.ECThermistorOffsets.t0(which),4,toolhead); int val = 0; if( r == null || r.length < 4 ) { @@ -2381,8 +2345,7 @@ final private static class CoolingFanOffsets { protected int read16FromToolEEPROM(int offset, int defaultValue, int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); byte r[] = readFromToolEEPROM(offset, 2, toolhead); int val = ((int) r[0]) & 0xff; val += (((int) r[1]) & 0xff) << 8; @@ -2396,8 +2359,7 @@ private int byteToInt(byte b) { } private float readFloat16FromToolEEPROM(int offset, float defaultValue, int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); byte r[] = readFromToolEEPROM(offset, 2, toolhead); if (r == null) { Base.logger.severe("null read from tool at " + offset + " for tool " + toolhead + " default " +defaultValue); @@ -2409,8 +2371,7 @@ private float readFloat16FromToolEEPROM(int offset, float defaultValue, int tool } @Override public BackoffParameters getBackoffParameters(int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); BackoffParameters bp = new BackoffParameters(); bp.forwardMs = read16FromToolEEPROM(ECBackoffOffsets.FORWARD_MS, 300, toolhead); @@ -2421,8 +2382,7 @@ private float readFloat16FromToolEEPROM(int offset, float defaultValue, int tool } @Override public void setBackoffParameters(BackoffParameters bp, int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); writeToToolEEPROM(ECBackoffOffsets.FORWARD_MS,intToLE(bp.forwardMs,2), toolhead); writeToToolEEPROM(ECBackoffOffsets.STOP_MS,intToLE(bp.stopMs,2), toolhead); @@ -2431,8 +2391,7 @@ private float readFloat16FromToolEEPROM(int offset, float defaultValue, int tool } @Override public PIDParameters getPIDParameters(int which, int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); PIDParameters pp = new PIDParameters(); int offset = (which == OnboardParameters.EXTRUDER)?PIDOffsets.PID_EXTRUDER:PIDOffsets.PID_HBP; pp.p = readFloat16FromToolEEPROM(offset+PIDOffsets.P_TERM_OFFSET, 7.0f, toolhead); @@ -2442,8 +2401,7 @@ private float readFloat16FromToolEEPROM(int offset, float defaultValue, int tool } @Override public void setPIDParameters(int which, PIDParameters pp, int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); int offset = (which == OnboardParameters.EXTRUDER)?PIDOffsets.PID_EXTRUDER:PIDOffsets.PID_HBP; writeToToolEEPROM(offset+PIDOffsets.P_TERM_OFFSET,floatToLE(pp.p),toolhead); writeToToolEEPROM(offset+PIDOffsets.I_TERM_OFFSET,floatToLE(pp.i),toolhead); @@ -2473,14 +2431,12 @@ public void resetSettingsToBlank() throws RetryException { @Override public void resetToolToFactory(int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); resetToolToBlank(toolhead); /// for generic S3G, just wipe the EEPROM } @Override public void resetToolToBlank(int toolhead){ - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); byte eepromWipe[] = new byte[16]; Arrays.fill(eepromWipe,(byte)0xff); @@ -2504,8 +2460,7 @@ public void resetToolToFactory(int toolhead) { } @Override public ExtraFeatures getExtraFeatures(int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); int efdat = read16FromToolEEPROM(Sanguino3GEEPRPOM.EC_EEPROM_EXTRA_FEATURES, 0x4084, toolhead); ExtraFeatures ef = new ExtraFeatures(); ef.swapMotorController = (efdat & 0x0001) != 0; @@ -2520,8 +2475,7 @@ public void resetToolToFactory(int toolhead) { } @Override public void setExtraFeatures(ExtraFeatures features, int toolhead) { - /// toolhead -1 indicate auto-detect.Fast hack to get software out.. - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); int efdat = 0x4000; if (features.swapMotorController) { @@ -2549,8 +2503,7 @@ public void resetToolToFactory(int toolhead) { } @Override public double getPlatformTemperatureSetting(int toolhead) { - /// toolhead -1 indicates auto-detect. Fast hack to get software out... - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); // This call was introduced in version 2.3 if (toolVersion.atLeast(new Version(2, 3))) { @@ -2568,8 +2521,7 @@ public void resetToolToFactory(int toolhead) { } @Override public double getTemperatureSetting(int toolhead) { - /// toolhead -1 indicates auto-detect. Fast hack to get software out... - if(toolhead == -1 ) toolhead = machine.currentTool().getIndex(); + toolhead = fixToolIndex(toolhead); // This call was introduced in version 2.3 if (toolVersion.atLeast(new Version(2, 3))) { diff --git a/src/replicatorg/drivers/reprap/RepRap5DDriver.java b/src/replicatorg/drivers/reprap/RepRap5DDriver.java index 4484eb671..1cb28b829 100644 --- a/src/replicatorg/drivers/reprap/RepRap5DDriver.java +++ b/src/replicatorg/drivers/reprap/RepRap5DDriver.java @@ -1023,7 +1023,7 @@ public void homeAxes(EnumSet axes, boolean positive, double feedrate) th } private String _getToolCode(int toolhead) { - return "T" + (toolhead == -1 ? machine.currentTool().getIndex() : toolhead) + " "; + return "T" + fixToolIndex(toolhead) + " "; } String _getCurrentToolCode() { diff --git a/src/replicatorg/drivers/reprap/SimpleRepRap5DDriver.java b/src/replicatorg/drivers/reprap/SimpleRepRap5DDriver.java index 70263fb2a..8e14e4605 100644 --- a/src/replicatorg/drivers/reprap/SimpleRepRap5DDriver.java +++ b/src/replicatorg/drivers/reprap/SimpleRepRap5DDriver.java @@ -402,7 +402,7 @@ public void homeAxes(EnumSet axes, boolean positive, double feedrate) th } private String _getToolCode(int toolhead) { - return "T" + (toolhead == -1 ? machine.currentTool().getIndex() : toolhead) + " "; + return "T" + fixToolIndex(toolhead) + " "; } private String _getCurrentToolCode() { From d6c714723bcfd8b559171e7c514a492e4a242101 Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Sat, 10 Mar 2012 10:25:14 -0800 Subject: [PATCH 32/35] Fixed a typo introduced in 06a13f07. P and T sure sound a lot alike. :-\ --- src/replicatorg/app/gcode/GCodeParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/replicatorg/app/gcode/GCodeParser.java b/src/replicatorg/app/gcode/GCodeParser.java index 6786afb96..d7a7e55bf 100644 --- a/src/replicatorg/app/gcode/GCodeParser.java +++ b/src/replicatorg/app/gcode/GCodeParser.java @@ -447,7 +447,7 @@ private void buildMCodes(GCodeCommand gcode, Queue< DriverCommand > commands) th // read spindle speed case M50: if (gcode.hasCode('T')) { - driver.getSpindleRPM((int) gcode.getCodeValue('P')); + driver.getSpindleRPM((int) gcode.getCodeValue('T')); } else { driver.getSpindleRPM(driver.getCurrentToolIndex()); } From f2343b08642adcc2ebdec6cf453121d1ecf3d653 Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Sat, 10 Mar 2012 10:28:43 -0800 Subject: [PATCH 33/35] Cleaned up MCode parser to use 'tool' field. My changes from the past few days were explicitly extracting the 'T' code from the command, when code at the top of the method had already done this. --- src/replicatorg/app/gcode/GCodeCommand.java | 18 ++++- src/replicatorg/app/gcode/GCodeParser.java | 90 ++++++++------------- 2 files changed, 52 insertions(+), 56 deletions(-) diff --git a/src/replicatorg/app/gcode/GCodeCommand.java b/src/replicatorg/app/gcode/GCodeCommand.java index 704e8f4dc..6829c650a 100644 --- a/src/replicatorg/app/gcode/GCodeCommand.java +++ b/src/replicatorg/app/gcode/GCodeCommand.java @@ -1,7 +1,6 @@ package replicatorg.app.gcode; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -130,6 +129,23 @@ public int getCodeValueInt(char searchCode, int fallback) { return (int) getCodeValue(searchCode, fallback); } + /* + * Note: unlike getCodeValue(char) above, this has no magic default + * return value. If used on a nonexistent code, it throws to indicate + * a programming error (in RepG, not the GCode). + */ + public int getCodeValueInt(char searchCode) { + for (gCodeParameter parameter : parameters) { + if (parameter.code == searchCode) { + return parameter.value.intValue(); + } + } + + throw new IllegalStateException( + "getCodeValueInt called for nonexistent code " + searchCode + + "; caller should have checked hasCode first!"); + } + // public Double removeCode(Character searchCode) { // for (Iterator i = parameters.iterator(); i.hasNext();) // { diff --git a/src/replicatorg/app/gcode/GCodeParser.java b/src/replicatorg/app/gcode/GCodeParser.java index d7a7e55bf..f74528c56 100644 --- a/src/replicatorg/app/gcode/GCodeParser.java +++ b/src/replicatorg/app/gcode/GCodeParser.java @@ -176,7 +176,7 @@ Queue< DriverCommand > drawArc(Point5d center, Point5d endpoint, boolean clockwi double feedrate = 0.0; // current selected tool - protected int tool = ToolheadAlias.SINGLE.number; + private int tool = ToolheadAlias.SINGLE.number; // unit variables. public static int UNITS_MM = 0; @@ -283,8 +283,8 @@ private void buildMCodes(GCodeCommand gcode, Queue< DriverCommand > commands) th // you may wish to avoid using M6. if (gcode.hasCode('T') && driver instanceof MultiTool && ((MultiTool)driver).supportsSimultaneousTools()) { - commands.add(new replicatorg.drivers.commands.SelectTool((int) gcode.getCodeValue('T'))); tool = (int) gcode.getCodeValue('T'); + commands.add(new replicatorg.drivers.commands.SelectTool(tool)); } // handle unrecognised GCode @@ -317,21 +317,17 @@ private void buildMCodes(GCodeCommand gcode, Queue< DriverCommand > commands) th break; // spindle on, CW case M3: - commands.add(new replicatorg.drivers.commands.SetSpindleDirection( - DriverCommand.AxialDirection.CLOCKWISE, - gcode.getCodeValueInt('T', driver.getCurrentToolIndex()))); - commands.add(new replicatorg.drivers.commands.EnableSpindle(gcode.getCodeValueInt('T', driver.getCurrentToolIndex()))); + commands.add(new replicatorg.drivers.commands.SetSpindleDirection(DriverCommand.AxialDirection.CLOCKWISE, tool)); + commands.add(new replicatorg.drivers.commands.EnableSpindle(tool)); break; // spindle on, CCW case M4: - commands.add(new replicatorg.drivers.commands.SetSpindleDirection( - DriverCommand.AxialDirection.COUNTERCLOCKWISE, - gcode.getCodeValueInt('T', driver.getCurrentToolIndex()))); - commands.add(new replicatorg.drivers.commands.EnableSpindle(gcode.getCodeValueInt('T', driver.getCurrentToolIndex()))); + commands.add(new replicatorg.drivers.commands.SetSpindleDirection(DriverCommand.AxialDirection.COUNTERCLOCKWISE, tool)); + commands.add(new replicatorg.drivers.commands.EnableSpindle(tool)); break; // spindle off case M5: - commands.add(new replicatorg.drivers.commands.DisableSpindle(gcode.getCodeValueInt('T', driver.getCurrentToolIndex()))); + commands.add(new replicatorg.drivers.commands.DisableSpindle(tool)); break; // tool change. case M6: @@ -340,7 +336,7 @@ private void buildMCodes(GCodeCommand gcode, Queue< DriverCommand > commands) th timeout = (int)gcode.getCodeValue('P'); } if (gcode.hasCode('T')) { - commands.add(new replicatorg.drivers.commands.RequestToolChange((int) gcode.getCodeValue('T'), timeout)); + commands.add(new replicatorg.drivers.commands.RequestToolChange(gcode.getCodeValueInt('T'), timeout)); } else { throw new GCodeException("The T parameter is required for tool changes. (M6)"); @@ -379,16 +375,16 @@ private void buildMCodes(GCodeCommand gcode, Queue< DriverCommand > commands) th case M13: commands.add(new replicatorg.drivers.commands.SetSpindleDirection( DriverCommand.AxialDirection.CLOCKWISE, - gcode.getCodeValueInt('T', driver.getCurrentToolIndex()))); - commands.add(new replicatorg.drivers.commands.EnableSpindle(gcode.getCodeValueInt('T', driver.getCurrentToolIndex()))); + tool)); + commands.add(new replicatorg.drivers.commands.EnableSpindle(tool)); commands.add(new replicatorg.drivers.commands.EnableFloodCoolant()); break; // spindle CCW and coolant A on case M14: commands.add(new replicatorg.drivers.commands.SetSpindleDirection( DriverCommand.AxialDirection.COUNTERCLOCKWISE, - gcode.getCodeValueInt('T', driver.getCurrentToolIndex()))); - commands.add(new replicatorg.drivers.commands.EnableSpindle(gcode.getCodeValueInt('T', driver.getCurrentToolIndex()))); + tool)); + commands.add(new replicatorg.drivers.commands.EnableSpindle(tool)); commands.add(new replicatorg.drivers.commands.EnableFloodCoolant()); break; // enable drives @@ -446,11 +442,7 @@ private void buildMCodes(GCodeCommand gcode, Queue< DriverCommand > commands) th break; // read spindle speed case M50: - if (gcode.hasCode('T')) { - driver.getSpindleRPM((int) gcode.getCodeValue('T')); - } else { - driver.getSpindleRPM(driver.getCurrentToolIndex()); - } + driver.getSpindleRPM(tool); break; // turn extruder on, forward case M70: @@ -480,29 +472,25 @@ private void buildMCodes(GCodeCommand gcode, Queue< DriverCommand > commands) th // Manually sets the percent complete info on the bot. commands.add(new replicatorg.drivers.commands.SetBuildPercent(gcode.getCodeValue('P'), gcode.getComment() ) ); break; - case M101: { - int toolIndex = gcode.getCodeValueInt('T', driver.getCurrentToolIndex()); - commands.add(new replicatorg.drivers.commands.SetMotorDirection(DriverCommand.AxialDirection.CLOCKWISE, toolIndex)); - commands.add(new replicatorg.drivers.commands.EnableExtruderMotor(toolIndex)); + case M101: + commands.add(new replicatorg.drivers.commands.SetMotorDirection(DriverCommand.AxialDirection.CLOCKWISE, tool)); + commands.add(new replicatorg.drivers.commands.EnableExtruderMotor(tool)); break; - } // turn extruder on, reverse - case M102: { - int toolIndex = gcode.getCodeValueInt('T', driver.getCurrentToolIndex()); - commands.add(new replicatorg.drivers.commands.SetMotorDirection(DriverCommand.AxialDirection.COUNTERCLOCKWISE, toolIndex)); - commands.add(new replicatorg.drivers.commands.EnableExtruderMotor(toolIndex)); + case M102: + commands.add(new replicatorg.drivers.commands.SetMotorDirection(DriverCommand.AxialDirection.COUNTERCLOCKWISE, tool)); + commands.add(new replicatorg.drivers.commands.EnableExtruderMotor(tool)); break; - } // turn extruder off case M103: - commands.add(new replicatorg.drivers.commands.DisableMotor(gcode.getCodeValueInt('T', driver.getCurrentToolIndex()))); + commands.add(new replicatorg.drivers.commands.DisableMotor(tool)); break; // custom code for temperature control case M104: if (gcode.hasCode('S')) { commands.add(new replicatorg.drivers.commands.SetTemperature( gcode.getCodeValue('S'), - gcode.getCodeValueInt('T', driver.getCurrentToolIndex()))); + tool)); } break; // custom code for temperature reading @@ -512,39 +500,31 @@ private void buildMCodes(GCodeCommand gcode, Queue< DriverCommand > commands) th commands.add(new replicatorg.drivers.commands.ReadTemperature()); break; // turn AutomatedBuildPlatform on - case M106: { - int toolIndex = gcode.getCodeValueInt('T', driver.getCurrentToolIndex()); - if(driver.hasAutomatedBuildPlatform(toolIndex)) - commands.add(new replicatorg.drivers.commands.ToggleAutomatedBuildPlatform(true, toolIndex)); + case M106: + if(driver.hasAutomatedBuildPlatform(tool)) + commands.add(new replicatorg.drivers.commands.ToggleAutomatedBuildPlatform(true, tool)); else - commands.add(new replicatorg.drivers.commands.EnableFan(toolIndex)); + commands.add(new replicatorg.drivers.commands.EnableFan(tool)); break; - } // turn AutomatedBuildPlatform off - case M107: { - int toolIndex = gcode.getCodeValueInt('T', driver.getCurrentToolIndex()); - if(driver.hasAutomatedBuildPlatform(toolIndex)) - commands.add(new replicatorg.drivers.commands.ToggleAutomatedBuildPlatform(false, toolIndex)); + case M107: + if(driver.hasAutomatedBuildPlatform(tool)) + commands.add(new replicatorg.drivers.commands.ToggleAutomatedBuildPlatform(false, tool)); else - commands.add(new replicatorg.drivers.commands.DisableFan(toolIndex)); + commands.add(new replicatorg.drivers.commands.DisableFan(tool)); break; - } // set max extruder speed, RPM - case M108: { - int toolIndex = gcode.getCodeValueInt('T', driver.getCurrentToolIndex()); + case M108: if (gcode.hasCode('S')) - commands.add(new replicatorg.drivers.commands.SetMotorSpeedPWM((int)gcode.getCodeValue('S'), toolIndex)); + commands.add(new replicatorg.drivers.commands.SetMotorSpeedPWM((int)gcode.getCodeValue('S'), tool)); else if (gcode.hasCode('R')) - commands.add(new replicatorg.drivers.commands.SetMotorSpeedRPM(gcode.getCodeValue('R'), toolIndex)); + commands.add(new replicatorg.drivers.commands.SetMotorSpeedRPM(gcode.getCodeValue('R'), tool)); break; - } // set build platform temperature case M109: case M140: // skeinforge chamber code for HBP if (gcode.hasCode('S')) - commands.add(new replicatorg.drivers.commands.SetPlatformTemperature( - gcode.getCodeValue('S'), - gcode.getCodeValueInt('T', driver.getCurrentToolIndex()))); + commands.add(new replicatorg.drivers.commands.SetPlatformTemperature(gcode.getCodeValue('S'), tool)); break; // set build chamber temperature case M110: @@ -552,11 +532,11 @@ else if (gcode.hasCode('R')) break; // valve open case M126: - commands.add(new replicatorg.drivers.commands.OpenValve(gcode.getCodeValueInt('T', driver.getCurrentToolIndex()))); + commands.add(new replicatorg.drivers.commands.OpenValve(tool)); break; // valve close case M127: - commands.add(new replicatorg.drivers.commands.CloseValve(gcode.getCodeValueInt('T', driver.getCurrentToolIndex()))); + commands.add(new replicatorg.drivers.commands.CloseValve(tool)); break; // where are we? case M128: From bf8c128958d2215180a75391b2a232a095e286fb Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Sat, 10 Mar 2012 12:49:06 -0800 Subject: [PATCH 34/35] Fixed HBP control hack in ExtruderPanel. Did you think a negative tool index means current tool? Not always! In this case it means "heated build platform." I love magic numbers. --- src/replicatorg/app/ui/controlpanel/ExtruderPanel.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/replicatorg/app/ui/controlpanel/ExtruderPanel.java b/src/replicatorg/app/ui/controlpanel/ExtruderPanel.java index afdb59d42..962d02fe9 100644 --- a/src/replicatorg/app/ui/controlpanel/ExtruderPanel.java +++ b/src/replicatorg/app/ui/controlpanel/ExtruderPanel.java @@ -748,6 +748,7 @@ private void handleChangedTextField(JFormattedTextField source) { String name = source.getName(); int toolhead; + boolean platform = false; double newValue = Double.NaN; // tools position may not match index @@ -755,9 +756,10 @@ private void handleChangedTextField(JFormattedTextField source) toolhead = tool0.getIndex(); else if(source == t1TargetTemperatureField) toolhead = tool1.getIndex(); - else if(source == pTargetTemperatureField) - toolhead = -1; // -1 means autodetect - else { + else if(source == pTargetTemperatureField) { + toolhead = tool0.getIndex(); + platform = true; + } else { Base.logger.warning("Unhandled text field: "+name); return; } @@ -767,7 +769,7 @@ else if(source == pTargetTemperatureField) newValue = ((Number)source.getValue()).doubleValue(); // if we have a toolhead temperature - if(toolhead != -1) { + if (!platform) { newValue = confirmTemperature(newValue,"temperature.acceptedLimit",260.0); if (newValue == Double.MIN_VALUE) { return; From 98c625eff564c1d3e980a3cfd8ee86b91d92461d Mon Sep 17 00:00:00 2001 From: "Cliff L. Biffle" Date: Sat, 10 Mar 2012 13:01:54 -0800 Subject: [PATCH 35/35] Removed bogus NaN check in ExtruderPanel. All comparisons with NaN return false. FindBugs will tell you this. Y'all should seriously consider running some analysis tools over this code. --- src/replicatorg/app/ui/controlpanel/ExtruderPanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/replicatorg/app/ui/controlpanel/ExtruderPanel.java b/src/replicatorg/app/ui/controlpanel/ExtruderPanel.java index 962d02fe9..b9973669f 100644 --- a/src/replicatorg/app/ui/controlpanel/ExtruderPanel.java +++ b/src/replicatorg/app/ui/controlpanel/ExtruderPanel.java @@ -783,7 +783,7 @@ else if(source == pTargetTemperatureField) { machine.runCommand(new replicatorg.drivers.commands.SetPlatformTemperature(newValue, toolhead)); } } - if(newValue != Double.NaN) { + if(!Double.isNaN(newValue)) { if(source == t0TargetTemperatureField) t0TargetTemperature = newValue; else if(source == t1TargetTemperatureField)