package org.goko.core.gcode.rs274ngcv3.instruction.builder; import java.util.List; 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.quantity.Angle; import org.goko.core.common.measure.quantity.AngleUnit; import org.goko.core.common.measure.quantity.Length; import org.goko.core.gcode.element.GCodeWord; 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.gcode.rs274ngcv3.element.InstructionType; import org.goko.core.gcode.rs274ngcv3.instruction.ArcFeedInstruction; import org.goko.core.gcode.rs274ngcv3.utils.GCodeWordUtils; public class ArcFeedBuilder extends AbstractInstructionBuilder<ArcFeedInstruction> { public ArcFeedBuilder() { super(InstructionType.ARC_FEED); } /** (inheritDoc) * @see org.goko.core.gcode.rs274ngcv3.instruction.IInstructionBuilder#match(org.goko.core.gcode.rs274ngcv3.context.GCodeContext, java.util.List) */ @Override public boolean match(GCodeContext context, List<GCodeWord> words) throws GkException { if(GCodeWordUtils.containsWordByLetter("X", words) || GCodeWordUtils.containsWordByLetter("Y", words) || GCodeWordUtils.containsWordByLetter("Z", words) || GCodeWordUtils.containsWordByLetter("A", words) || GCodeWordUtils.containsWordByLetter("B", words) || GCodeWordUtils.containsWordByLetter("C", words)){ if(context.getMotionMode() == EnumMotionMode.ARC_CLOCKWISE || context.getMotionMode() == EnumMotionMode.ARC_COUNTERCLOCKWISE ){ // Make sure there is no other motion mode word if(!GCodeWordUtils.containsWordRegex("G(0?)0", words) && !GCodeWordUtils.containsWordRegex("G(0?)1", words) && !GCodeWordUtils.containsWord("G38.2", words)){ return true; } }else{ //Context motion mode is not ARC, we need an explicit G2 or G3 return GCodeWordUtils.containsWordRegex("G(0?)2", words) || GCodeWordUtils.containsWordRegex("G(0?)3", words); } } return false; } /** (inheritDoc) * @see org.goko.core.gcode.rs274ngcv3.instruction.IInstructionBuilder#toInstruction(org.goko.core.gcode.rs274ngcv3.context.GCodeContext, java.util.List) */ @Override protected ArcFeedInstruction getInstruction(GCodeContext context, List<GCodeWord> words) throws GkException { EnumPlane plane = context.getPlane(); Length x = findWordLength("X", words, null, context.getUnit().getUnit()); Length y = findWordLength("Y", words, null, context.getUnit().getUnit()); Length z = findWordLength("Z", words, null, context.getUnit().getUnit()); Angle a = findWordAngle("A", words, null, AngleUnit.DEGREE_ANGLE); Angle b = findWordAngle("B", words, null, AngleUnit.DEGREE_ANGLE); Angle c = findWordAngle("C", words, null, AngleUnit.DEGREE_ANGLE); Length i = findWordLength("I", words, null, context.getUnit().getUnit()); Length j = findWordLength("J", words, null, context.getUnit().getUnit()); Length k = findWordLength("K", words, null, context.getUnit().getUnit()); Integer r = 1; Boolean clockwise = null; if(context.getMotionMode() == EnumMotionMode.ARC_CLOCKWISE){ clockwise = true; }else if(context.getMotionMode() == EnumMotionMode.ARC_COUNTERCLOCKWISE){ clockwise = false; } GCodeWord gWord = GCodeWordUtils.findAndRemoveWordRegex("G(0?)2", words); if(gWord == null){ gWord = GCodeWordUtils.findAndRemoveWordRegex("G(0?)3", words); if(gWord != null){ clockwise = false; } }else{ clockwise = true; } GCodeWord rWord = GCodeWordUtils.findAndRemoveWordByLetter("R", words); if( rWord != null ){ r = Integer.valueOf(rWord.getValue()); } ArcFeedInstruction instruction = null; if(plane == null){ throw new GkTechnicalException("No plane in GCodeContext ["+plane+"]"); } // Words verification switch (plane) { case XY_PLANE: if(x == null && y == null){ throw new GkFunctionalException("GCO-130", "X", "Y"); } if(i == null && j == null){ throw new GkFunctionalException("GCO-130", "I", "J"); } break; case YZ_PLANE: if(y == null && z == null){ throw new GkFunctionalException("GCO-130", "Y", "Z"); } if(j == null && k == null){ throw new GkFunctionalException("GCO-130", "J", "K"); } break; case XZ_PLANE: if(z == null && x == null){ throw new GkFunctionalException("GCO-130", "X", "Z"); } if(k == null && i == null){ throw new GkFunctionalException("GCO-130", "I", "K"); } break; default: throw new GkTechnicalException("Not a valid plane in GCodeContext ["+plane+"]"); } if(context.getDistanceMode() == EnumDistanceMode.RELATIVE){ // x = NumberQuantity.add(x, context.getX()); // y = NumberQuantity.add(y, context.getY()); // z = NumberQuantity.add(z, context.getZ()); // a = NumberQuantity.add(a, context.getA()); // b = NumberQuantity.add(b, context.getB()); // c = NumberQuantity.add(c, context.getC()); } // else{ // if(x == null) x = context.getX(); // if(y == null) y = context.getY(); // if(z == null) z = context.getZ(); // if(a == null) a = context.getA(); // if(b == null) b = context.getB(); // if(c == null) c = context.getC(); // } // Compute the center of the arc // i = NumberQuantity.add(i, context.getX()); // j = NumberQuantity.add(j, context.getY()); // k = NumberQuantity.add(k, context.getZ()); instruction = new ArcFeedInstruction(x, y, z, i, j, k, a, b, c, r, clockwise); // switch (plane) { // // public ArcFeedInstruction(Length firstEnd, Length secondEnd, Length firstAxis, Length secondAxis, Length axisEndPoint, Integer rotation, Angle a, Angle b, Angle c, boolean clockwise) { // case XY_PLANE: instruction = new ArcFeedInstruction(x, y, i, j, z, r, a, b, c, clockwise); // break; // case XZ_PLANE: instruction = new ArcFeedInstruction(z, x, k, i, y, r, a, b, c, clockwise); // break; // case YZ_PLANE: instruction = new ArcFeedInstruction(y, z, j, k, x, r, a, b, c, clockwise); // break; // default: throw new GkTechnicalException("Not a valid plane in GCodeContext ["+plane+"]"); // } return instruction; } }