package org.goko.tinyg.controller;
import java.math.BigDecimal;
import org.goko.controller.tinyg.controller.TinyGCommunicator;
import org.goko.controller.tinyg.controller.TinyGControllerService;
import org.goko.controller.tinyg.controller.configuration.TinyGConfiguration;
import org.goko.controller.tinyg.controller.configuration.TinyGConfigurationValue;
import org.goko.core.common.exception.GkFunctionalException;
import org.goko.core.common.measure.quantity.Length;
import org.goko.core.common.measure.quantity.LengthUnit;
import org.goko.core.common.measure.quantity.Speed;
import org.goko.core.common.measure.quantity.SpeedUnit;
import org.goko.core.connection.serial.SerialParameter;
import org.goko.core.controller.bean.EnumControllerAxis;
import org.goko.core.controller.bean.MachineState;
import org.goko.core.gcode.rs274ngcv3.IRS274NGCService;
import org.goko.core.gcode.rs274ngcv3.RS274NGCServiceImpl;
import org.goko.core.gcode.rs274ngcv3.context.CoordinateSystem;
import org.goko.core.gcode.rs274ngcv3.context.EnumDistanceMode;
import org.goko.core.gcode.rs274ngcv3.context.EnumMotionMode;
import org.goko.core.gcode.rs274ngcv3.context.EnumPlane;
import org.goko.core.gcode.rs274ngcv3.context.GCodeContext;
import org.goko.core.math.Tuple6b;
import org.goko.junit.tools.assertion.AssertGkFunctionalException;
import org.goko.junit.tools.connection.AssertSerialEmulator;
import org.goko.junit.tools.connection.SerialConnectionEmulator;
import junit.framework.TestCase;
/*
{"r":{"fv":0.970,"fb":435.10,"hp":1,"hv":8,"id":"9H3583-PXN","msg":"SYSTEM READY"},"f":[1,0,0,3412]}
{"qr":28,"qi":1,"qo":1}
{"r":{"sr":{"line":0,"posx":0.000,"posy":0.000,"posz":0.000,"posa":0.000,"feed":0.00,"vel":0.00,"unit":1,"coor":1,"dist":0,"frmo":1,"momo":4,"stat":1}},"f":[1,0,10,8936]}
{"sr":{"line":0,"posx":0.000,"posy":0.000,"posz":0.000,"posa":0.000,"feed":0.00,"vel":0.00,"unit":1,"coor":1,"dist":0,"frmo":1,"momo":4,"stat":1}}
{"r":{"qr":28},"f":[1,0,10,8758]}
{"r":{"1":{"ma":0,"sa":0.900,"tr":32.0000,"mi":8,"po":1,"pm":1}},"f":[1,0,9,8694]}
{"r":{"2":{"ma":1,"sa":0.900,"tr":32.0000,"mi":8,"po":1,"pm":1}},"f":[1,0,9,5984]}
{"r":{"3":{"ma":2,"sa":1.800,"tr":2.1170,"mi":8,"po":0,"pm":1}},"f":[1,0,9,3553]}
{"r":{"4":{"ma":3,"sa":1.800,"tr":75.0000,"mi":8,"po":1,"pm":1}},"f":[1,0,9,8385]}
{"r":{"x":{"am":1,"vm":1500,"fr":1500,"tn":0.000,"tm":300.000,"jm":5000,"jh":30000,"jd":0.0100,"sn":0,"sx":1,"sv":1000,"lv":100,"lb":20.000,"zb":3.000}},"f":[1,0,9,1167]}
{"r":{"y":{"am":1,"vm":1500,"fr":1500,"tn":0.000,"tm":220.000,"jm":5000,"jh":30000,"jd":0.0100,"sn":0,"sx":1,"sv":1000,"lv":100,"lb":20.000,"zb":3.000}},"f":[1,0,9,716]}
{"r":{"z":{"am":1,"vm":1000,"fr":1000,"tn":0.000,"tm":100.000,"jm":50,"jh":1000,"jd":0.0100,"sn":1,"sx":0,"sv":800,"lv":100,"lb":20.000,"zb":10.000}},"f":[1,0,9,6257]}
{"r":{"a":{"am":1,"vm":48000,"fr":48000,"tn":-1.000,"tm":-1.000,"jm":24000,"jh":24000,"jd":0.1000,"ra":0.000,"sn":0,"sx":0,"sv":6000,"lv":1000,"lb":5.000,"zb":2.000}},"f":[1,0,9,7419]}
{"r":{"sys":{"fb":435.10,"fv":0.970,"hp":1,"hv":8,"id":"9H3583-PXN","ja":2000000,"ct":0.0100,"sl":0,"st":1,"mt":180.00,"ej":1,"jv":5,"js":1,"tv":1,"qv":2,"sv":1,"si":100,"ec":0,"ee":0,"ex":2,"baud":5,"net":0,"gpl":0,"gun":1,"gco":1,"gpa":0,"gdi":0}},"f":[1,0,11,346]}
{"r":{"g55":{"x":-164.127,"y":-208.999,"z":53.778,"a":0.000,"b":0.000,"c":0.000}},"f":[1,0,11,1231]}
{"r":{"g56":{"x":-84.739,"y":-103.984,"z":-10.000,"a":0.000,"b":0.000,"c":0.000}},"f":[1,0,11,3338]}
{"r":{"g57":{"x":0.000,"y":0.000,"z":0.000,"a":0.000,"b":0.000,"c":0.000}},"f":[1,0,11,8386]}
{"r":{"g58":{"x":-8.931,"y":9.450,"z":0.000,"a":0.000,"b":0.000,"c":0.000}},"f":[1,0,11,2282]}
{"r":{"g59":{"x":0.434,"y":17.316,"z":0.000,"a":0.000,"b":0.000,"c":0.000}},"f":[1,0,11,4046]}
*/
public class TinyGControllerServiceTestCase extends TestCase {
private TinyGControllerService tinyg;
private SerialConnectionEmulator serialEmulator;
private IRS274NGCService gcodeService;
/** {@inheritDoc}
* @see junit.framework.TestCase#setUp()
*/
@Override
protected void setUp() throws Exception {
super.setUp();
serialEmulator = new SerialConnectionEmulator();
serialEmulator.setDebugOutputConsole(true);
TinyGCommunicator communicator = new TinyGCommunicator();
communicator.setConnectionService(serialEmulator);
tinyg = new TinyGControllerService(communicator);
gcodeService = new RS274NGCServiceImpl();
tinyg.setGCodeService(gcodeService);
tinyg.start(); // Start the TinyG service
serialEmulator.connect(null, null, null, null, null, null); // Make sure the service is connected
tinyg.setPlannerBufferCheck(false);
}
/**
* Simple test for configuration update
* @throws Exception Exception
*/
public void testConfigurationUpdate() throws Exception{
BigDecimal queueReportVerbosity = tinyg.getConfiguration().getSetting(TinyGConfiguration.QUEUE_REPORT_VERBOSITY, BigDecimal.class);
assertEquals(BigDecimal.ZERO, queueReportVerbosity);
serialEmulator.receiveData("{\"r\":{\"qv\":2},\"f\":[1,0,10,4252]}"+'\n');
BigDecimal queueReportVerbosityUpdated = tinyg.getConfiguration().getSetting(TinyGConfiguration.QUEUE_REPORT_VERBOSITY, BigDecimal.class);
assertEquals(new BigDecimal("2"), queueReportVerbosityUpdated);
}
/**
* Context : TinyG has no motion control enabled and we try to run a motion
* Result : TinyG throws an exception. Motion control is required
* @throws Exception
*/
public void testNoMotionControlEnabled() throws Exception{
// Emulate the reception of the GCode context
serialEmulator.receiveDataWithEndChar("{\"r\":{\"sr\":{\"line\":0,\"posx\":0.000,\"posy\":0.000,\"posz\":0.000,\"posa\":0.000,\"feed\":0.00,\"vel\":0.00,\"unit\":1,\"coor\":1,\"dist\":0,\"frmo\":1,\"momo\":4,\"stat\":1}},\"f\":[1,0,0,0]}");
serialEmulator.receiveDataWithEndChar("{\"r\":{\"ex\":2, \"jv\":5},\"f\":[1,0,0,0]}");
serialEmulator.getCurrentConnection().setFlowControl(SerialParameter.FLOWCONTROL_RTSCTS);
tinyg.setPlannerBufferCheck(true);
// Let's check that flow control is enabled
assertEquals(new BigDecimal("2"), tinyg.getConfiguration().getSetting(TinyGConfiguration.ENABLE_FLOW_CONTROL, BigDecimal.class));
try{
tinyg.verifyReadyForExecution();
fail();
}catch(GkFunctionalException e){
AssertGkFunctionalException.assertException(e, "TNG-002");
}
}
/**
* Context : TinyG has no flow control enabled and we try to run a motion
* Result : TinyG throws an exception. Flow control is required
* @throws Exception
*/
public void testNoFlowControlEnabled() throws Exception{
// Emulate the reception of the GCode context
serialEmulator.receiveDataWithEndChar("{\"r\":{\"sr\":{\"line\":0,\"posx\":0.000,\"posy\":0.000,\"posz\":0.000,\"posa\":0.000,\"feed\":0.00,\"vel\":0.00,\"unit\":1,\"coor\":1,\"dist\":0,\"frmo\":1,\"momo\":4,\"stat\":1}},\"f\":[1,0,0,0]}");
serialEmulator.receiveDataWithEndChar("{\"r\":{\"ex\":0},\"f\":[1,0,0,0]}");
tinyg.setPlannerBufferCheck(true);
// Let's check that flow control is enabled
assertEquals(new BigDecimal("0"), tinyg.getConfiguration().getSetting(TinyGConfiguration.ENABLE_FLOW_CONTROL, BigDecimal.class));
try{
tinyg.verifyReadyForExecution();
fail();
}catch(GkFunctionalException e){
AssertGkFunctionalException.assertException(e, "TNG-001");
}
}
/**
* Context : TinyG has a flow control enabled but it's not the same as the currently active serial connection
* Result : TinyG throws an exception. Flow control on TinyG and Serial connection have to match
* @throws Exception
*/
public void testNonMatchingFlowControlRtsCts() throws Exception{
// Emulate the reception of the GCode context
serialEmulator.receiveDataWithEndChar("{\"r\":{\"sr\":{\"line\":0,\"posx\":0.000,\"posy\":0.000,\"posz\":0.000,\"posa\":0.000,\"feed\":0.00,\"vel\":0.00,\"unit\":1,\"coor\":1,\"dist\":0,\"frmo\":1,\"momo\":4,\"stat\":1}},\"f\":[1,0,0,0]}");
serialEmulator.receiveDataWithEndChar("{\"r\":{\"ex\":2},\"f\":[1,0,0,0]}");
tinyg.setPlannerBufferCheck(true);
// Let's check that flow control is enabled
assertEquals(TinyGConfigurationValue.FLOW_CONTROL_RTS_CTS, tinyg.getConfiguration().getSetting(TinyGConfiguration.ENABLE_FLOW_CONTROL, BigDecimal.class));
try{
tinyg.verifyReadyForExecution();
fail();
}catch(GkFunctionalException e){
AssertGkFunctionalException.assertException(e, "TNG-005");
}
}
/**
* Context : TinyG has a flow control enabled but it's not the same as the currently active serial connection
* Result : TinyG throws an exception. Flow control on TinyG and Serial connection have to match
* @throws Exception
*/
public void testNonMatchingFlowControlXonXoff() throws Exception{
// Emulate the reception of the GCode context
serialEmulator.receiveDataWithEndChar("{\"r\":{\"sr\":{\"line\":0,\"posx\":0.000,\"posy\":0.000,\"posz\":0.000,\"posa\":0.000,\"feed\":0.00,\"vel\":0.00,\"unit\":1,\"coor\":1,\"dist\":0,\"frmo\":1,\"momo\":4,\"stat\":1}},\"f\":[1,0,0,0]}");
serialEmulator.receiveDataWithEndChar("{\"r\":{\"ex\":1},\"f\":[1,0,0,0]}");
tinyg.setPlannerBufferCheck(true);
// Let's check that flow control is enabled
assertEquals(TinyGConfigurationValue.FLOW_CONTROL_XON_XOFF, tinyg.getConfiguration().getSetting(TinyGConfiguration.ENABLE_FLOW_CONTROL, BigDecimal.class));
try{
tinyg.verifyReadyForExecution();
fail();
}catch(GkFunctionalException e){
AssertGkFunctionalException.assertException(e, "TNG-006");
}
}
/**
* Context : We receive notification about the modification of the units in the GCode context
* Result : TinyG controller updates it's internal units
* @throws Exception
*/
public void testGCodeContextUnitChange() throws Exception{
serialEmulator.clearOutputBuffer();
serialEmulator.clearSentBuffer();
serialEmulator.receiveDataWithEndChar("{\"r\":{\"sr\":{\"unit\":0}},\"f\":[1,0,0,0]}");
assertEquals(LengthUnit.INCH, tinyg.getCurrentUnit());
serialEmulator.receiveDataWithEndChar("{\"r\":{\"sr\":{\"unit\":1}},\"f\":[1,0,0,0]}");
assertEquals(LengthUnit.MILLIMETRE, tinyg.getCurrentUnit());
}
/**
*
* @throws Exception
*/
public void testResetCurrentCoordinateSystem() throws Exception{
serialEmulator.clearOutputBuffer();
serialEmulator.clearSentBuffer();
serialEmulator.receiveDataWithEndChar("{\"r\":{\"sr\":{\"posx\":15.031,\"posy\":35.000,\"posz\":-16.031}},\"f\":[1,0,0,0]}");
// Enable G55
serialEmulator.receiveDataWithEndChar("{\"r\":{\"sr\":{\"coor\":2}},\"f\":[1,0,0,0]}");
assertEquals(CoordinateSystem.G55, tinyg.getCurrentCoordinateSystem());
tinyg.resetCurrentCoordinateSystem();
AssertSerialEmulator.assertOutputMessagePresent(serialEmulator, "{\"G55\":{\"X\":15.031,\"Y\":35,\"Z\":-16.031}}"+'\n', 1000);
}
/**
* Context : We receive notification about the coordinate system update offset
* Result : TinyG controller updates it's internal units
* @throws Exception
*/
public void testGCodeContextCoordinateSystemOffsetChange() throws Exception{
serialEmulator.clearOutputBuffer();
serialEmulator.clearSentBuffer();
serialEmulator.receiveDataWithEndChar("{\"r\":{\"g55\":{\"x\":-10,\"y\":20,\"z\":35.53,\"a\":0,\"b\":0,\"c\":0}},\"f\":[1,0,12]}");
Tuple6b expectedG55 = new Tuple6b(Length.valueOf("-10", tinyg.getCurrentUnit()),
Length.valueOf("20", tinyg.getCurrentUnit()),
Length.valueOf("35.53", tinyg.getCurrentUnit()));
Tuple6b actualG55 = tinyg.getGCodeContext().getCoordinateSystemData(CoordinateSystem.G55);
assertEquals(expectedG55, actualG55);
}
/**
* Tests the various stat values in status report
* @throws Exception Exception
*/
public void testStatusReportState() throws Exception{
serialEmulator.clearOutputBuffer();
serialEmulator.clearSentBuffer();
{ // Stat 0
serialEmulator.receiveDataWithEndChar("{\"sr\":{\"stat\":0}}");
assertEquals(tinyg.getState(), MachineState.INITIALIZING);
}
{ // Stat 1
serialEmulator.receiveDataWithEndChar("{\"sr\":{\"stat\":1}}");
assertEquals(tinyg.getState(), MachineState.READY);
}
{ // Stat 2
serialEmulator.receiveDataWithEndChar("{\"sr\":{\"stat\":2}}");
assertEquals(tinyg.getState(), MachineState.ALARM);
}
{ // Stat 3
serialEmulator.receiveDataWithEndChar("{\"sr\":{\"stat\":3}}");
assertEquals(tinyg.getState(), MachineState.PROGRAM_STOP);
}
{ // Stat 4
serialEmulator.receiveDataWithEndChar("{\"sr\":{\"stat\":4}}");
assertEquals(tinyg.getState(), MachineState.PROGRAM_END);
}
{ // Stat 5
serialEmulator.receiveDataWithEndChar("{\"sr\":{\"stat\":5}}");
assertEquals(tinyg.getState(), MachineState.MOTION_RUNNING);
}
{ // Stat 6
serialEmulator.receiveDataWithEndChar("{\"sr\":{\"stat\":6}}");
assertEquals(tinyg.getState(), MachineState.MOTION_HOLDING);
}
{ // Stat 7
serialEmulator.receiveDataWithEndChar("{\"sr\":{\"stat\":7}}");
assertEquals(tinyg.getState(), MachineState.PROBE_CYCLE);
}
{ // Stat 9
serialEmulator.receiveDataWithEndChar("{\"sr\":{\"stat\":9}}");
assertEquals(tinyg.getState(), MachineState.HOMING);
}
}
/**
* Tests the various stat values in status report
* @throws Exception Exception
*/
public void testStatusReportVelocity() throws Exception{
serialEmulator.clearOutputBuffer();
serialEmulator.clearSentBuffer();
serialEmulator.receiveDataWithEndChar("{\"sr\":{\"vel\":109.35}}");
assertEquals(tinyg.getVelocity(), Speed.valueOf("109.35", SpeedUnit.MILLIMETRE_PER_MINUTE));
}
/**
* Tests the various feed values in status report
* @throws Exception Exception
*/
public void testStatusReportDistanceMode() throws Exception{
serialEmulator.clearOutputBuffer();
serialEmulator.clearSentBuffer();
{
serialEmulator.receiveDataWithEndChar("{\"sr\":{\"dist\":0}}");
assertEquals(EnumDistanceMode.ABSOLUTE, tinyg.getGCodeContext().getDistanceMode());
}
{
serialEmulator.receiveDataWithEndChar("{\"sr\":{\"dist\":1}}");
assertEquals(EnumDistanceMode.RELATIVE, tinyg.getGCodeContext().getDistanceMode());
}
}
/**
* Tests the various feed values in status report
* @throws Exception Exception
*/
public void testStatusReportCoordinateSystem() throws Exception{
serialEmulator.clearOutputBuffer();
serialEmulator.clearSentBuffer();
{
serialEmulator.receiveDataWithEndChar("{\"sr\":{\"coor\":0}}");
assertEquals(CoordinateSystem.G53, tinyg.getCurrentCoordinateSystem());
}
{
serialEmulator.receiveDataWithEndChar("{\"sr\":{\"coor\":1}}");
assertEquals(CoordinateSystem.G54, tinyg.getCurrentCoordinateSystem());
}
{
serialEmulator.receiveDataWithEndChar("{\"sr\":{\"coor\":2}}");
assertEquals(CoordinateSystem.G55, tinyg.getCurrentCoordinateSystem());
}
{
serialEmulator.receiveDataWithEndChar("{\"sr\":{\"coor\":3}}");
assertEquals(CoordinateSystem.G56, tinyg.getCurrentCoordinateSystem());
}
{
serialEmulator.receiveDataWithEndChar("{\"sr\":{\"coor\":4}}");
assertEquals(CoordinateSystem.G57, tinyg.getCurrentCoordinateSystem());
}
{
serialEmulator.receiveDataWithEndChar("{\"sr\":{\"coor\":5}}");
assertEquals(CoordinateSystem.G58, tinyg.getCurrentCoordinateSystem());
}
{
serialEmulator.receiveDataWithEndChar("{\"sr\":{\"coor\":6}}");
assertEquals(CoordinateSystem.G59, tinyg.getCurrentCoordinateSystem());
}
}
/**
* Tests the various plane values in status report
* @throws Exception Exception
*/
public void testStatusReportPlane() throws Exception{
serialEmulator.clearOutputBuffer();
serialEmulator.clearSentBuffer();
{
serialEmulator.receiveDataWithEndChar("{\"sr\":{\"plan\":0}}");
assertEquals(EnumPlane.XY_PLANE, tinyg.getGCodeContext().getPlane());
}
{
serialEmulator.receiveDataWithEndChar("{\"sr\":{\"plan\":1}}");
assertEquals(EnumPlane.XZ_PLANE, tinyg.getGCodeContext().getPlane());
}
{
serialEmulator.receiveDataWithEndChar("{\"sr\":{\"plan\":2}}");
assertEquals(EnumPlane.YZ_PLANE, tinyg.getGCodeContext().getPlane());
}
}
/**
* Tests the various motion mode values in status report
* @throws Exception Exception
*/
public void testStatusReportMotionMode() throws Exception{
serialEmulator.clearOutputBuffer();
serialEmulator.clearSentBuffer();
{
serialEmulator.receiveDataWithEndChar("{\"sr\":{\"momo\":0}}");
assertEquals(EnumMotionMode.RAPID, tinyg.getGCodeContext().getMotionMode());
}
{
serialEmulator.receiveDataWithEndChar("{\"sr\":{\"momo\":1}}");
assertEquals(EnumMotionMode.FEEDRATE, tinyg.getGCodeContext().getMotionMode());
}
{
serialEmulator.receiveDataWithEndChar("{\"sr\":{\"momo\":2}}");
assertEquals(EnumMotionMode.ARC_CLOCKWISE, tinyg.getGCodeContext().getMotionMode());
}
{
serialEmulator.receiveDataWithEndChar("{\"sr\":{\"momo\":3}}");
assertEquals(EnumMotionMode.ARC_COUNTERCLOCKWISE, tinyg.getGCodeContext().getMotionMode());
}
}
/**
* Tests the machine position values in status report
* @throws Exception Exception
*/
public void testStatusReportMachinePosition() throws Exception{
serialEmulator.clearOutputBuffer();
serialEmulator.clearSentBuffer();
{
serialEmulator.receiveDataWithEndChar("{\"sr\":{\"mpox\":-10,\"mpoy\":20,\"mpoz\":35.53}}");
Tuple6b expectedPosition = new Tuple6b(Length.valueOf("-10", tinyg.getCurrentUnit()),
Length.valueOf("20", tinyg.getCurrentUnit()),
Length.valueOf("35.53", tinyg.getCurrentUnit()));
assertEquals(expectedPosition, tinyg.getGCodeContext().getMachinePosition());
}
}
/**
* Tests the work position values in status report
* @throws Exception Exception
*/
public void testStatusReportWorkPosition() throws Exception{
serialEmulator.clearOutputBuffer();
serialEmulator.clearSentBuffer();
{
serialEmulator.receiveDataWithEndChar("{\"sr\":{\"posx\":-10,\"posy\":20,\"posz\":35.53}}");
Tuple6b expectedPosition = new Tuple6b(Length.valueOf("-10", tinyg.getCurrentUnit()),
Length.valueOf("20", tinyg.getCurrentUnit()),
Length.valueOf("35.53", tinyg.getCurrentUnit()));
assertEquals(expectedPosition, tinyg.getGCodeContext().getPosition());
}
}
/* ************************************************
* Jogging tests
* ************************************************/
public void testJogStartRelative() throws Exception{
serialEmulator.clearOutputBuffer();
serialEmulator.clearSentBuffer();
serialEmulator.receiveDataWithEndChar("{\"r\":{\"sr\":{\"posx\":15.031,\"posy\":35.000,\"posz\":-16.031, \"dist\":1, \"stat\":1}},\"f\":[1,0,0,0]}");
serialEmulator.receiveDataWithEndChar("{\"qr\":32,\"qi\":1,\"qo\":1}");
GCodeContext context = tinyg.getGCodeContext();
assertEquals(EnumDistanceMode.RELATIVE, context.getDistanceMode());
tinyg.jog(EnumControllerAxis.X_POSITIVE, Length.valueOf(BigDecimal.ONE, LengthUnit.MILLIMETRE), Speed.valueOf("1000", SpeedUnit.MILLIMETRE_PER_MINUTE));
AssertSerialEmulator.assertOutputMessagePresent(serialEmulator, "G91G1F1000X1.000\n",1000);
tinyg.jog(EnumControllerAxis.X_NEGATIVE, Length.valueOf(BigDecimal.ONE, LengthUnit.MILLIMETRE), Speed.valueOf("1000", SpeedUnit.MILLIMETRE_PER_MINUTE));
AssertSerialEmulator.assertOutputMessagePresent(serialEmulator, "G91G1F1000X-1.000\n",1000);
tinyg.jog(EnumControllerAxis.Y_POSITIVE, Length.valueOf("0.01", LengthUnit.MILLIMETRE), Speed.valueOf("1000", SpeedUnit.MILLIMETRE_PER_MINUTE));
AssertSerialEmulator.assertOutputMessagePresent(serialEmulator, "G91G1F1000Y0.010\n",1000);
tinyg.jog(EnumControllerAxis.Y_NEGATIVE, Length.valueOf("0.01", LengthUnit.MILLIMETRE), Speed.valueOf("1000", SpeedUnit.MILLIMETRE_PER_MINUTE));
AssertSerialEmulator.assertOutputMessagePresent(serialEmulator, "G91G1F1000Y-0.010\n",1000);
tinyg.jog(EnumControllerAxis.Z_POSITIVE, Length.valueOf("2.035", LengthUnit.MILLIMETRE), Speed.valueOf("1000", SpeedUnit.MILLIMETRE_PER_MINUTE));
AssertSerialEmulator.assertOutputMessagePresent(serialEmulator, "G91G1F1000Z2.035\n",1000);
tinyg.jog(EnumControllerAxis.Z_NEGATIVE, Length.valueOf(BigDecimal.ONE, LengthUnit.MILLIMETRE), Speed.valueOf("1000", SpeedUnit.MILLIMETRE_PER_MINUTE));
AssertSerialEmulator.assertOutputMessagePresent(serialEmulator, "G91G1F1000Z-1.000\n",1000);
}
/** (inheritDoc)
* @see junit.framework.TestCase#tearDown()
*/
@Override
protected void tearDown() throws Exception {
tinyg.stop();
};
}