package org.goko.controller.tinyg.controller;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletionService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.goko.controller.tinyg.commons.AbstractTinyGControllerService;
import org.goko.controller.tinyg.commons.ITinyGStatus;
import org.goko.controller.tinyg.commons.TinyGJsonUtils;
import org.goko.controller.tinyg.commons.bean.EnumTinyGAxis;
import org.goko.controller.tinyg.commons.bean.TinyGExecutionError;
import org.goko.controller.tinyg.commons.probe.ProbeUtility;
import org.goko.controller.tinyg.controller.configuration.TinyGAxisSettings;
import org.goko.controller.tinyg.controller.configuration.TinyGConfiguration;
import org.goko.controller.tinyg.controller.configuration.TinyGConfigurationValue;
import org.goko.controller.tinyg.controller.prefs.TinyGPreferences;
import org.goko.controller.tinyg.controller.topic.TinyGExecutionErrorTopic;
import org.goko.core.common.GkUtils;
import org.goko.core.common.applicative.logging.ApplicativeLogEvent;
import org.goko.core.common.applicative.logging.IApplicativeLogService;
import org.goko.core.common.event.EventBrokerUtils;
import org.goko.core.common.exception.GkException;
import org.goko.core.common.exception.GkFunctionalException;
import org.goko.core.common.exception.GkTechnicalException;
import org.goko.core.common.measure.Units;
import org.goko.core.common.measure.quantity.AngleUnit;
import org.goko.core.common.measure.quantity.Length;
import org.goko.core.common.measure.quantity.TimeUnit;
import org.goko.core.config.GokoPreference;
import org.goko.core.controller.action.ControllerActionFactory;
import org.goko.core.controller.bean.MachineState;
import org.goko.core.controller.bean.ProbeRequest;
import org.goko.core.controller.bean.ProbeResult;
import org.goko.core.gcode.element.ICoordinateSystem;
import org.goko.core.gcode.element.IGCodeProvider;
import org.goko.core.gcode.execution.ExecutionQueueType;
import org.goko.core.gcode.execution.ExecutionState;
import org.goko.core.gcode.execution.ExecutionTokenState;
import org.goko.core.gcode.execution.IExecutionToken;
import org.goko.core.gcode.rs274ngcv3.context.CoordinateSystemFactory;
import org.goko.core.log.GkLog;
import org.goko.core.math.Tuple6b;
import org.osgi.service.event.EventAdmin;
import com.eclipsesource.json.JsonObject;
/**
* Implementation of the TinyG controller
*
* @author PsyKo
*
*/
// public class G2CoreControllerService extends AbstractTinyGControllerService<G2CoreControllerService, G2CoreState, G2CoreConfiguration, G2CoreCommunicator, G2CoreJogger, G2CoreExecutor> implements IG2CoreControllerService{
public class TinyGControllerService extends AbstractTinyGControllerService<TinyGControllerService, TinyGState, TinyGConfiguration, TinyGCommunicator, TinyGJogging, TinyGExecutor> implements ITinygControllerService{
static final GkLog LOG = GkLog.getLogger(TinyGControllerService.class);
/** Service ID */
public static final String SERVICE_ID = "Controller for TinyG v0.97";
/** Applicative log service */
private IApplicativeLogService applicativeLogService;
/** Event admin service */
private EventAdmin eventAdmin;
/** The probe utility */
private ProbeUtility probeUtility;
/**
* Constructor
* @throws GkException GkException
*/
public TinyGControllerService(TinyGCommunicator communicator) throws GkException {
super(new TinyGState(), new TinyGConfiguration(), communicator);
getCommunicator().setControllerService(this);
}
/** (inheritDoc)
* @see org.goko.core.common.service.IGokoService#getServiceId()
*/
@Override
public String getServiceId() throws GkException {
return SERVICE_ID;
}
/** (inheritDoc)
* @see org.goko.controller.tinyg.commons.AbstractTinyGControllerService#createActionFactory()
*/
@Override
protected ControllerActionFactory createActionFactory() throws GkException {
return new TinyGActionFactory(this);
}
/** (inheritDoc)
* @see org.goko.controller.tinyg.commons.AbstractTinyGControllerService#createJogger()
*/
@Override
protected TinyGJogging createJogger() {
return new TinyGJogging(this, getCommunicator());
}
/** (inheritDoc)
* @see org.goko.controller.tinyg.commons.AbstractTinyGControllerService#createExecutor()
*/
@Override
protected TinyGExecutor createExecutor() {
return new TinyGExecutor(this);
}
/** (inheritDoc)
* @see org.goko.core.controller.IControllerService#verifyReadyForExecution()
*/
@Override
public void verifyReadyForExecution() throws GkException{
if(!isReadyForFileStreaming()){
throw new GkFunctionalException("TNG-003");
}
getCommunicator().requestQueueReport();
getCommunicator().checkExecutionControl();
checkVerbosity();
}
private void checkVerbosity() throws GkException{
BigDecimal jsonVerbosity = getConfiguration().getSetting(TinyGConfiguration.SYSTEM_SETTINGS, TinyGConfiguration.JSON_VERBOSITY, BigDecimal.class);
if(!ObjectUtils.equals(jsonVerbosity, TinyGConfigurationValue.JSON_VERBOSITY_VERBOSE)){
throw new GkFunctionalException("TNG-007");
}
BigDecimal qrVerbosity = getConfiguration().getSetting(TinyGConfiguration.SYSTEM_SETTINGS, TinyGConfiguration.QUEUE_REPORT_VERBOSITY, BigDecimal.class);
if(isPlannerBufferCheck()){
if(ObjectUtils.equals(qrVerbosity, TinyGConfigurationValue.QUEUE_REPORT_SILENT)){
throw new GkFunctionalException("TNG-002");
}
}
}
/** (inheritDoc)
* @see org.goko.core.controller.IControllerService#isReadyForFileStreaming()
*/
@Override
public boolean isReadyForFileStreaming() throws GkException {
return MachineState.READY.equals(getState())
|| MachineState.PROGRAM_END.equals(getState())
|| MachineState.PROGRAM_STOP.equals(getState());
}
/** (inheritDoc)
* @see org.goko.core.controller.IProbingService#checkReadyToProbe()
*/
@Override
public void checkReadyToProbe() throws GkException {
if(!getCommunicator().isConnected()){
throw new GkFunctionalException("TNG-008");
}
if(!isReadyForFileStreaming()){
throw new GkFunctionalException("TNG-003");
}
}
/** (inheritDoc)
* @see org.goko.core.controller.IProbingService#isReadyToProbe()
*/
@Override
public boolean isReadyToProbe() {
try {
return getCommunicator().isConnected() && isReadyForFileStreaming();
} catch (GkException e) {
LOG.error(e);
return false;
}
}
/**
* Handling GCode response from TinyG
* @param jsonValue
* @throws GkTechnicalException
*/
protected void handleGCodeResponse(String receivedCommand, ITinyGStatus status) throws GkException {
if(getExecutionService().getExecutionState() == ExecutionState.RUNNING ||
getExecutionService().getExecutionState() == ExecutionState.PAUSED ||
getExecutionService().getExecutionState() == ExecutionState.ERROR ){
if(status == TinyGStatusCode.TG_OK){
getExecutor().confirmNextLineExecution();
}else{
notifyNonOkStatus(status, receivedCommand);
getExecutor().handleNonOkStatus(status);
}
}else{
if(status != TinyGStatusCode.TG_OK){
notifyNonOkStatus(status, receivedCommand);
}
}
}
/**
* Handles any TinyG Status that is not TG_OK
* @param status the received status or <code>null</code> if unknown
* @param receivedCommand the received command
* @throws GkException GkException
*/
protected void notifyNonOkStatus(ITinyGStatus status, String receivedCommand) throws GkException {
String message = StringUtils.EMPTY;
if(status == null){
message = " Unknown error status";
}else{
if(status.isError()){
// Error report
message = "Error status returned : "+status.getValue() +" - "+status.getLabel();
LOG.error(message);
applicativeLogService.log(ApplicativeLogEvent.LOG_ERROR, message, "TinyG");
EventBrokerUtils.send(eventAdmin, new TinyGExecutionErrorTopic(), new TinyGExecutionError("Error reported durring execution", "Execution was paused after TinyG reported an error. You can resume, or stop the execution at your own risk.", message));
}else if(status.isWarning()){
// Warning report
message = "Warning status returned : "+status.getValue() +" - "+status.getLabel();
LOG.warn(message);
applicativeLogService.log(ApplicativeLogEvent.LOG_WARNING, message, "TinyG");
}
}
}
/** (inheritDoc)
* @see org.goko.controller.tinyg.controller.ITinygControllerService#applyConfiguration(org.goko.controller.tinyg.controller.configuration.TinyGConfiguration)
*/
@Override
public void applyConfiguration(TinyGConfiguration cfg) throws GkException {
checkVerbosity();
getCommunicator().sendConfigurationUpdate(cfg);
}
/**
* Initiate TinyG homing sequence
* @throws GkException GkException
*/
public void startHomingSequence() throws GkException{
LOG.info("Homing...");
String homingCommand = "G28.2";
if(TinyGPreferences.getInstance().isHomingEnabledAxisX()){
homingCommand += " X0";
}
if(TinyGPreferences.getInstance().isHomingEnabledAxisY()){
homingCommand += " Y0";
}
if(TinyGPreferences.getInstance().isHomingEnabledAxisZ()){
homingCommand += " Z0";
}
if(TinyGPreferences.getInstance().isHomingEnabledAxisA()){
homingCommand += " A0";
}
getCommunicator().send(GkUtils.toBytesList(homingCommand), true);
}
/* ************************************************
* CONTROLLER ACTIONS
* ************************************************/
/** (inheritDoc)
* @see org.goko.controller.tinyg.controller.ITinygControllerService#pauseMotion()
*/
@Override
public void pauseMotion() throws GkException{
getCommunicator().pauseMotion();
getExecutionService().pauseQueueExecution();
}
/** (inheritDoc)
* @see org.goko.controller.tinyg.controller.ITinygControllerService#resumeMotion()
*/
@Override
public void resumeMotion() throws GkException{
getCommunicator().resumeMotion();
getExecutionService().resumeQueueExecution();
}
/** (inheritDoc)
* @see org.goko.controller.tinyg.controller.ITinygControllerService#startMotion()
*/
@Override
public void startMotion() throws GkException {
getCommunicator().startMotion();
getExecutionService().beginQueueExecution(ExecutionQueueType.DEFAULT);
}
/** (inheritDoc)
* @see org.goko.controller.tinyg.controller.ITinygControllerService#stopMotion()
*/
@Override
public void stopMotion() throws GkException{
getCommunicator().getConnectionService().clearOutputBuffer();
if(probeUtility != null && probeUtility.isProbingInProgress()){
probeUtility.cancelActiveProbing();
// Probe active, let's hack over a TinyG bug
getCommunicator().sendImmediately(GkUtils.toBytesList(TinyGv097.FEED_HOLD), true);
schedule().send(TinyGv097.QUEUE_FLUSH).whenState(MachineState.MOTION_HOLDING).timeout(10, TimeUnit.SECOND).begin();
}else{
getCommunicator().stopMotion();
}
getExecutionService().stopQueueExecution();
//communicator.send(GkUtils.toBytesList(TinyG.QUEUE_FLUSH));
// Force a queue report update
// updateQueueReport();
// this.resetAvailableBuffer();
}
public void resetZero(List<String> axes) throws GkException{
List<Byte> lstBytes = GkUtils.toBytesList("G28.3");
if(CollectionUtils.isNotEmpty(axes)){
for (String axe : axes) {
lstBytes.addAll(GkUtils.toBytesList(axe+"0"));
}
}else{
lstBytes.addAll( GkUtils.toBytesList("X0Y0Z0"));
}
getCommunicator().send(lstBytes, true);
}
public void turnSpindleOn() throws GkException{
getCommunicator().turnSpindleOn();
}
public void turnSpindleOff() throws GkException{
getCommunicator().turnSpindleOff();
}
/**
* @return the availableBuffer
* @throws GkException
*/
@Override
public int getAvailablePlannerBuffer() {
try {
return getInternalState().getAvailableBuffer();
} catch (GkException e) {
LOG.error(e);
return 0;
}
}
/**
* @param availableBuffer the availableBuffer to set
* @throws GkException exception
*/
@Override
public void setAvailablePlannerBuffer(int availableBuffer) {
try {
getInternalState().setAvailableBuffer(availableBuffer);
// TODO : find a better way to deal with this
getExecutor().onBufferSpaceAvailableChange(availableBuffer);
} catch (GkException e) {
LOG.error(e);
}
}
/**
* Set the last received message
* @param message the message
* @throws GkException GkException
*/
public void setMessage(String message) throws GkException{
getInternalState().setMessage(message);
}
public void resetAvailableBuffer() {
setAvailablePlannerBuffer(28);
}
/** (inheritDoc)
* @see org.goko.core.controller.IProbingService#probe(java.util.List)
*/
@Override
public CompletionService<ProbeResult> probe(List<ProbeRequest> lstProbeRequest) throws GkException {
probeUtility = new ProbeUtility(this);
probeUtility.prepare(lstProbeRequest);
IGCodeProvider probeGCodeProvider = probeUtility.getProbeGCodeProvider();
getExecutionService().clearExecutionQueue(ExecutionQueueType.SYSTEM);
getExecutionService().addToExecutionQueue(ExecutionQueueType.SYSTEM, probeGCodeProvider);
getExecutionService().beginQueueExecution(ExecutionQueueType.SYSTEM);
return probeUtility.getExecutorCompletionService();
}
protected double getPositionAsDouble(Length q) throws GkException{
return Double.valueOf(GokoPreference.getInstance().format(q.to(getCurrentUnit()), true, false));
}
/**
* @param applicativeLogService the IApplicativeLogService to set
*/
public void setApplicativeLogService(IApplicativeLogService applicativeLogService) {
this.applicativeLogService = applicativeLogService;
getCommunicator().setApplicativeLogService(applicativeLogService);
}
/** (inheritDoc)
* @see org.goko.core.controller.ICoordinateSystemAdapter#setCurrentCoordinateSystem(org.goko.core.gcode.bean.commands.EnumCoordinateSystem)
*/
@Override
public void setCurrentCoordinateSystem(ICoordinateSystem cs) throws GkException {
getCommunicator().send( cs.getCode(), true );
}
/** (inheritDoc)
* @see org.goko.core.controller.ICoordinateSystemAdapter#getCoordinateSystem()
*/
@Override
public List<ICoordinateSystem> getCoordinateSystem() throws GkException {
List<ICoordinateSystem> lstCoordinateSystem = new ArrayList<>();
lstCoordinateSystem.addAll(new CoordinateSystemFactory().get());
return lstCoordinateSystem;
}
/** (inheritDoc)
* @see org.goko.core.controller.ICoordinateSystemAdapter#resetCurrentCoordinateSystem()
*/
@Override
public void resetCurrentCoordinateSystem() throws GkException {
ICoordinateSystem current = getCurrentCoordinateSystem();
Tuple6b offsets = getCoordinateSystemOffset(current);
Tuple6b mPos = new Tuple6b(getInternalState().getWorkPosition());
mPos = mPos.add(offsets);
JsonObject xyzPosition = new JsonObject();
xyzPosition.add(EnumTinyGAxis.X_POSITIVE.getAxisCode(), getPositionAsDouble(mPos.getX()));
xyzPosition.add(EnumTinyGAxis.Y_POSITIVE.getAxisCode(), getPositionAsDouble(mPos.getY()));
xyzPosition.add(EnumTinyGAxis.Z_POSITIVE.getAxisCode(), getPositionAsDouble(mPos.getZ()));
JsonObject csObject = new JsonObject();
csObject.add(current.getCode(), xyzPosition);
getCommunicator().send( csObject , true );
getCommunicator().requestCoordinateSystemUpdate(current);
}
/** (inheritDoc)
* @see org.goko.controller.tinyg.commons.AbstractTinyGControllerService#isPlannerBufferCheck()
*/
@Override
public boolean isPlannerBufferCheck() {
return TinyGPreferences.getInstance().isPlannerBufferSpaceCheck();
}
/** (inheritDoc)
* @see org.goko.controller.tinyg.commons.AbstractTinyGControllerService#setPlannerBufferCheck(boolean)
*/
@Override
public void setPlannerBufferCheck(boolean value) {
TinyGPreferences.getInstance().setPlannerBufferSpaceCheck(value);
}
/** (inheritDoc)
* @see org.goko.core.controller.IWorkVolumeProvider#getWorkVolumeMaximalPosition()
*/
@Override
public Tuple6b getWorkVolumeMaximalPosition() throws GkException {
Tuple6b max = findWorkVolumeMaximalPosition();
if(max == null){
throw new GkTechnicalException("No maximal position currently defined for the travel max position");
}
return max;
}
/** (inheritDoc)
* @see org.goko.core.controller.IWorkVolumeProvider#getWorkVolumeMinimalPosition()
*/
@Override
public Tuple6b getWorkVolumeMinimalPosition() throws GkException {
Tuple6b min = findWorkVolumeMinimalPosition();
if(min == null){
throw new GkTechnicalException("No minimal position currently defined for the travel max position");
}
return min;
}
/** (inheritDoc)
* @see org.goko.core.controller.IWorkVolumeProvider#getWorkVolumeProviderName()
*/
@Override
public String getWorkVolumeProviderName() {
return "TinyG 0.97";
}
/** (inheritDoc)
* @see org.goko.core.controller.IWorkVolumeProvider#findWorkVolumeMaximalPosition()
*/
@Override
public Tuple6b findWorkVolumeMaximalPosition() throws GkException {
TinyGConfiguration cfg = getConfiguration();
Tuple6b max = null;
if(cfg != null){
max = new Tuple6b(Units.MILLIMETRE, AngleUnit.DEGREE_ANGLE);
max.setX( Length.valueOf( cfg.getSetting(TinyGConfiguration.X_AXIS_SETTINGS, TinyGAxisSettings.TRAVEL_MAXIMUM, BigDecimal.class), Units.MILLIMETRE));
max.setY( Length.valueOf( cfg.getSetting(TinyGConfiguration.Y_AXIS_SETTINGS, TinyGAxisSettings.TRAVEL_MAXIMUM, BigDecimal.class), Units.MILLIMETRE));
max.setZ( Length.valueOf( cfg.getSetting(TinyGConfiguration.Z_AXIS_SETTINGS, TinyGAxisSettings.TRAVEL_MAXIMUM, BigDecimal.class), Units.MILLIMETRE));
}
return max;
}
/** (inheritDoc)
* @see org.goko.core.controller.IWorkVolumeProvider#findWorkVolumeMinimalPosition()
*/
@Override
public Tuple6b findWorkVolumeMinimalPosition() throws GkException {
TinyGConfiguration cfg = getConfiguration();
Tuple6b min = null;
if(cfg != null){
min = new Tuple6b(Units.MILLIMETRE, AngleUnit.DEGREE_ANGLE);
min.setX( Length.valueOf( cfg.getSetting(TinyGConfiguration.X_AXIS_SETTINGS, TinyGAxisSettings.TRAVEL_MINIMUM, BigDecimal.class), Units.MILLIMETRE));
min.setY( Length.valueOf( cfg.getSetting(TinyGConfiguration.Y_AXIS_SETTINGS, TinyGAxisSettings.TRAVEL_MINIMUM, BigDecimal.class), Units.MILLIMETRE));
min.setZ( Length.valueOf( cfg.getSetting(TinyGConfiguration.Z_AXIS_SETTINGS, TinyGAxisSettings.TRAVEL_MINIMUM, BigDecimal.class), Units.MILLIMETRE));
}
return min;
}
/** (inheritDoc)
* @see org.goko.controller.tinyg.commons.AbstractTinyGControllerService#detectWorkVolumeUpdate(org.goko.controller.tinyg.commons.configuration.AbstractTinyGConfiguration, org.goko.controller.tinyg.commons.configuration.AbstractTinyGConfiguration)
*/
@Override
protected boolean detectWorkVolumeUpdate(TinyGConfiguration currentConfiguration, TinyGConfiguration newConfiguration) {
return newConfiguration.isCompletelyLoaded() &&
( detectWorkVolumeUpdateOnAxis(TinyGConfiguration.X_AXIS_SETTINGS, currentConfiguration, newConfiguration)
|| detectWorkVolumeUpdateOnAxis(TinyGConfiguration.Y_AXIS_SETTINGS, currentConfiguration, newConfiguration)
|| detectWorkVolumeUpdateOnAxis(TinyGConfiguration.Z_AXIS_SETTINGS, currentConfiguration, newConfiguration)
|| detectWorkVolumeUpdateOnAxis(TinyGConfiguration.A_AXIS_SETTINGS, currentConfiguration, newConfiguration)
|| detectWorkVolumeUpdateOnAxis(TinyGConfiguration.B_AXIS_SETTINGS, currentConfiguration, newConfiguration)
|| detectWorkVolumeUpdateOnAxis(TinyGConfiguration.C_AXIS_SETTINGS, currentConfiguration, newConfiguration));
}
/**
* Detect any work volume update on the given axis
* @param axis the axis
* @param currentConfiguration the current configuration
* @param newConfiguration the new configuration
* @return <code>true</code> if an update was detected, <code>false</code> otherwise
*/
protected boolean detectWorkVolumeUpdateOnAxis(String axis, TinyGConfiguration currentConfiguration, TinyGConfiguration newConfiguration){
try {
BigDecimal oldMinValue = currentConfiguration.getSetting(axis, TinyGAxisSettings.TRAVEL_MINIMUM, BigDecimal.class);
BigDecimal newMinValue = newConfiguration.getSetting(axis, TinyGAxisSettings.TRAVEL_MINIMUM, BigDecimal.class);
if(oldMinValue != null && newMinValue != null && oldMinValue.compareTo(newMinValue) != 0){
return true;
}
BigDecimal oldMaxValue = currentConfiguration.getSetting(axis, TinyGAxisSettings.TRAVEL_MAXIMUM, BigDecimal.class);
BigDecimal newMaxValue = newConfiguration.getSetting(axis, TinyGAxisSettings.TRAVEL_MAXIMUM, BigDecimal.class);
if(oldMaxValue != null && newMaxValue != null && oldMaxValue.compareTo(newMaxValue) != 0){
return true;
}
} catch (GkException e) {
LOG.error(e);
}
return false;
}
/** (inheritDoc)
* @see org.goko.core.controller.IControllerConfigurationFileExporter#getFileExtension()
*/
@Override
public String getFileExtension() {
return "tinyg.cfg";
}
/** (inheritDoc)
* @see org.goko.core.controller.IControllerConfigurationFileExporter#canExport()
*/
@Override
public boolean canExport() throws GkException {
return MachineState.READY.equals(getState())
|| MachineState.PROGRAM_STOP.equals(getState())
|| MachineState.PROGRAM_END.equals(getState());
}
/** (inheritDoc)
* @see org.goko.core.controller.IControllerConfigurationFileExporter#exportTo(java.io.OutputStream)
*/
@Override
public void exportTo(OutputStream stream) throws GkException {
JsonObject json = TinyGJsonUtils.toJson(getConfiguration());
try {
stream.write(json.toString().getBytes());
} catch (IOException e) {
throw new GkTechnicalException(e);
}
}
/** (inheritDoc)
* @see org.goko.core.controller.IControllerConfigurationFileImporter#canImport()
*/
@Override
public boolean canImport() throws GkException {
return canExport();
}
/** (inheritDoc)
* @see org.goko.core.controller.IControllerConfigurationFileImporter#importFrom(java.io.InputStream)
*/
@Override
public void importFrom(InputStream inputStream) throws GkException {
TinyGConfiguration currentConfiguration = getConfiguration();
try {
JsonObject jsonCfg = JsonObject.readFrom(new InputStreamReader(inputStream));
currentConfiguration.setFromJson(jsonCfg);
applyConfiguration(currentConfiguration);
} catch (IOException e) {
throw new GkTechnicalException(e);
}
}
/**
* @return the eventAdmin
*/
public EventAdmin getEventAdmin() {
return eventAdmin;
}
/**
* @param eventAdmin the eventAdmin to set
*/
public void setEventAdmin(EventAdmin eventAdmin) {
this.eventAdmin = eventAdmin;
}
/** (inheritDoc)
* @see org.goko.controller.tinyg.controller.ITinygControllerService#killAlarm()
*/
@Override
public void killAlarm() throws GkException {
getCommunicator().send(GkUtils.toBytesList("{\"clear\":\"\"}"), true);
}
/** (inheritDoc)
* @see org.goko.core.gcode.service.IGCodeTokenExecutionListener#onQueueExecutionComplete()
*/
@Override
public void onQueueExecutionComplete() throws GkException {
if(probeUtility != null){
probeUtility.clearProbingGCode();
}
}
/** (inheritDoc)
* @see org.goko.core.gcode.service.IGCodeTokenExecutionListener#onQueueExecutionCanceled()
*/
@Override
public void onQueueExecutionCanceled() throws GkException {
if(probeUtility != null){
probeUtility.clearProbingGCode();
}
}
/** (inheritDoc)
* @see org.goko.core.gcode.service.IGCodeLineExecutionListener#onLineStateChanged(org.goko.core.gcode.execution.IExecutionToken, java.lang.Integer)
*/
@Override
public void onLineStateChanged(IExecutionToken<ExecutionTokenState> token, Integer idLine) throws GkException {}
/** (inheritDoc)
* @see org.goko.controller.tinyg.controller.ITinygControllerService#resetTinyG()
*/
@Override
public void resetTinyG() throws GkException {
getCommunicator().resetTinyG();
}
/** (inheritDoc)
* @see org.goko.controller.tinyg.commons.AbstractTinyGControllerService#handleProbeResult(boolean, org.goko.core.math.Tuple6b)
*/
@Override
public void handleProbeResult(boolean probeSuccess, Tuple6b probePosition) throws GkException {
probeUtility.handleProbeResult(probeSuccess, probePosition);
}
/** (inheritDoc)
* @see org.goko.controller.tinyg.commons.AbstractTinyGControllerService#resetConfiguration()
*/
@Override
public void resetConfiguration() {
setConfiguration( new TinyGConfiguration() );
}
}