/// <summary> /// Takes in distance values in units of mm. /// </summary> /// <param name="X"></param> /// <param name="Y"></param> /// <param name="Z"></param> /// <param name="E"></param> /// <param name="GCodeIndex"></param> /// <param name="MaterialModel"></param> public MovementModel(double X, double Y, double Z, double E, int GCodeIndex, MaterialModel MaterialModel, PrinterModel PrinterModel) { _materialModel = MaterialModel; _printerModel = PrinterModel; //Record movement distances in steps. _x = X / _printerModel.AxisModelList[0].MmPerStep; _y = Y / _printerModel.AxisModelList[1].MmPerStep; _z = Z / _materialModel.PrintheadModel.AttachedZAxisModel.MmPerStep; if (_materialModel.PrintheadModel.PrintheadType == PrintheadType.Motorized) { MotorizedPrintheadTypeModel motorizedPrintheadTypeModel = (MotorizedPrintheadTypeModel)MaterialModel.PrintheadModel.PrintheadTypeModel; _e = E / motorizedPrintheadTypeModel.MmPerStep; } else { _e = 0; } _gCodeIndex = GCodeIndex; //Calculate total distance and speeds for this movement in steps / s. _totalDistance = Math.Sqrt(Math.Pow(_x, 2) + Math.Pow(_y, 2) + Math.Pow(_z, 2) + Math.Pow(_e, 2)); CalculateSpeeds(MaterialModel); }
/// <summary> /// Takes manual input parameters for a set motorized printhead command and outputs the command to the serial port. /// </summary> /// <param name="printheadName"></param> /// <param name="maxSpeed"></param> /// <param name="acceleration"></param> public void ProcessManualSetMotorizedPrintheadCommand(string printheadName, double maxSpeed, double acceleration) { try { List <string> outgoingMessagesList = new List <string>(); PrintheadModel printheadModel = _printerModel.FindPrinthead(printheadName); MotorizedPrintheadTypeModel motorizedPrintheadTypeModel = (MotorizedPrintheadTypeModel)printheadModel.PrintheadTypeModel; int printheadLimitPinID = (motorizedPrintheadTypeModel.AttachedLimitSwitchGPIOPinModel == null) ? GlobalValues.PinIDNull : motorizedPrintheadTypeModel.AttachedLimitSwitchGPIOPinModel.PinID; string setPrintheadString = _writeSetPrintheadModel.WriteSetMotorDrivenPrinthead(motorizedPrintheadTypeModel.AttachedMotorStepGPIOPinModel.PinID, motorizedPrintheadTypeModel.AttachedMotorDirectionGPIOPinModel.PinID, motorizedPrintheadTypeModel.StepPulseTime, printheadLimitPinID, maxSpeed, acceleration, motorizedPrintheadTypeModel.MmPerStep); outgoingMessagesList.Add(setPrintheadString); //Send GCode for the Z Axis attached to the Printhead. AxisModel axisModel = printheadModel.AttachedZAxisModel; int zAxisLimitPinID = (axisModel.AttachedLimitSwitchGPIOPinModel == null) ? GlobalValues.PinIDNull : axisModel.AttachedLimitSwitchGPIOPinModel.PinID; string setAxisString = _writeSetAxisModel.WriteSetAxis(axisModel.AxisID, axisModel.AttachedMotorStepGPIOPinModel.PinID, axisModel.AttachedMotorDirectionGPIOPinModel.PinID, axisModel.StepPulseTime, zAxisLimitPinID, axisModel.MaxSpeed, axisModel.MaxAcceleration, axisModel.MmPerStep); //Retract Z Axis before changing Printheads. outgoingMessagesList.Add(SerialMessageCharacters.SerialCommandSetCharacter + "RetractZ"); outgoingMessagesList.Add(setAxisString); _serialCommunicationOutgoingMessagesModel.QueueNextProspectiveOutgoingMessage(outgoingMessagesList); } catch (NullReferenceException e) { _errorListViewModel.AddError("", "Printhead or z actuator needs to be set in Printer Settings before setting printhead in Control Menu."); } catch { _errorListViewModel.AddError("", "Unknown error while setting valve printhead."); } }
/// <summary> /// Processes the command for Axis movement and Printing. /// </summary> public List <ConvertedGCodeLine> ProcessG00Command(string[] repRapGCodeLine, MaterialModel currentMaterial) { //The return GCode. List <ConvertedGCodeLine> convertedGCodeLinesList = null; //Reads the GCode line and sets the fields in the coord classes. //If the printer is moving or printing, then proceed to convert the GCode line. if ((ReadCoord(repRapGCodeLine) == true) && ((_parametersModel.XCoord.Changed == true) || (_parametersModel.YCoord.Changed == true) || (_parametersModel.ZCoord.Changed == true))) { //Does this RepRap line indicate printing? _parametersModel.IsPrinting = ((repRapGCodeLine[0] == "GX") || (_parametersModel.ERepRapCoord.PositiveChanged == true)) ? true : false; //To Do: Test is E retraction causes IsPrinting to be false. try { int eModiPrintCoordIndex = _parametersModel.FindEModiPrintCoordIndex(currentMaterial.PrintheadModel); //Check if a Motorized Printhead needs to retract or unretract. if ((currentMaterial.PrintheadModel.PrintheadType == PrintheadType.Motorized) && (currentMaterial.PrintStyle == PrintStyle.Continuous)) { //If a Motorized Printhead is in use, then retraction potentially needs to occur before the execution of the next command. if ((_parametersModel.IsPrinting == false) & (_parametersModel.IsRetracted == false)) { MotorizedPrintheadTypeModel motorizedPrintheadTypeModel = (MotorizedPrintheadTypeModel)currentMaterial.PrintheadModel.PrintheadTypeModel; ContinuousPrintStyleModel continuousPrintheadStyleModel = (ContinuousPrintStyleModel)currentMaterial.PrintStyleModel; convertedGCodeLinesList = WriteG00.WriteMotorizedPrintWithoutMovement(-1 * continuousPrintheadStyleModel.MotorizedDispenseRetractionDistance, motorizedPrintheadTypeModel.MmPerStep, motorizedPrintheadTypeModel.IsDirectionInverted, ref _parametersModel.ERepRapCoord.DeltaCoordRemainder, _parametersModel.EModiPrintCoordList[eModiPrintCoordIndex]); _parametersModel.IsRetracted = true; } //If a Motorized Printhead needs to print, then reversing the retraction potentially needs to occur before the execution of the next print command. else if ((_parametersModel.IsPrinting == true) && (_parametersModel.IsRetracted)) { MotorizedPrintheadTypeModel motorizedPrintheadTypeModel = (MotorizedPrintheadTypeModel)currentMaterial.PrintheadModel.PrintheadTypeModel; ContinuousPrintStyleModel continuousPrintheadStyleModel = (ContinuousPrintStyleModel)currentMaterial.PrintStyleModel; convertedGCodeLinesList = WriteG00.WriteMotorizedPrintWithoutMovement(continuousPrintheadStyleModel.MotorizedDispenseRetractionDistance, motorizedPrintheadTypeModel.MmPerStep, motorizedPrintheadTypeModel.IsDirectionInverted, ref _parametersModel.ERepRapCoord.DeltaCoordRemainder, _parametersModel.EModiPrintCoordList[eModiPrintCoordIndex]); _parametersModel.IsRetracted = false; } } //Write the movement or print command. List <ConvertedGCodeLine> gCommand = SetWriteG00Command( currentMaterial, _printerModel, _parametersModel.ERepRapCoord, _parametersModel.XCoord, _parametersModel.YCoord, _parametersModel.ZCoord, _parametersModel.EModiPrintCoordList[eModiPrintCoordIndex]); if (convertedGCodeLinesList == null) { convertedGCodeLinesList = gCommand; } else { convertedGCodeLinesList.AddRange(gCommand); } } catch when(currentMaterial == null) //Material unset. { //Catching and error handling should have happened earlier. convertedGCodeLinesList = null; }
/// <summary> /// Takes manual input parameters for a set of commands for motorized printhead droplet printing and outputs the commands to the serial port. /// </summary> /// <param name="xDistance"></param> /// <param name="yDistance"></param> /// <param name="zDistance"></param> /// <param name="interpolateDistance"></param> /// <param name="eDispensePerDroplet"></param> public void ProcessManualMotorDropletPrintCommand(double xDistance, double yDistance, double zDistance, double interpolateDistance, double eDispensePerDroplet) { PrintheadModel printheadModel = _printerModel.FindPrinthead(_realTimeStatusDataModel.ActivePrintheadModel.Name); MotorizedPrintheadTypeModel motorizedPrintheadTypeModel = (MotorizedPrintheadTypeModel)printheadModel.PrintheadTypeModel; double emmPerStep = motorizedPrintheadTypeModel.MmPerStep; RealTimeStatusMotorizedPrintheadModel realTimeStatusMotorizedPrintheadModel = (RealTimeStatusMotorizedPrintheadModel)_realTimeStatusDataModel.ActivePrintheadModel; double eMaxSpeed = realTimeStatusMotorizedPrintheadModel.MaxSpeed; double eAcceleration = realTimeStatusMotorizedPrintheadModel.Acceleration; double xmmPerStep = (xDistance != 0) ? _printerModel.AxisModelList[0].MmPerStep : double.MaxValue; double ymmPerStep = (yDistance != 0) ? _printerModel.AxisModelList[1].MmPerStep : double.MaxValue; AxisModel zAxisModel = _printerModel.FindAxis(_realTimeStatusDataModel.ZRealTimeStatusAxisModel.Name); double zmmPerStep = (zDistance != 0) ? _printerModel.FindAxis(zAxisModel.Name).MmPerStep : double.MaxValue; bool zDirectionInverted = (zAxisModel != null) ? zAxisModel.IsDirectionInverted : false; double unused = 0; string printString = GCodeLinesConverter.GCodeLinesListToString( WriteG00.WriteMotorizedDropletPrint( emmPerStep, xmmPerStep, ymmPerStep, zmmPerStep, eDispensePerDroplet, 0, xDistance, 0, yDistance, 0, zDistance, _printerModel.AxisModelList[0].IsDirectionInverted, _printerModel.AxisModelList[1].IsDirectionInverted, zDirectionInverted, motorizedPrintheadTypeModel.IsDirectionInverted, ref unused, ref unused, ref unused, ref unused, null, new DropletModel(interpolateDistance))); _serialCommunicationOutgoingMessagesModel.QueueNextProspectiveOutgoingMessage(printString); }
/// <summary> /// Set the new center as the origin (position 0) and adjust the max and min range around such. /// </summary> /// <param name="commandSet"></param> /// <returns></returns> private List <string> InterpretSetOrigin(string commandSet) { //Remove "*Origin" from the beginning of the string. commandSet = commandSet.Substring(6); if (commandSet.Contains("E")) { if (_realTimeStatusDataModel.ActivePrintheadType == PrintheadType.Motorized) { RealTimeStatusMotorizedPrintheadModel realTimeStatusMotorizedPrintheadModel = (RealTimeStatusMotorizedPrintheadModel)_realTimeStatusDataModel.ActivePrintheadModel; MotorizedPrintheadTypeModel motorizedPrintheadTypeModel = (MotorizedPrintheadTypeModel)_printerModel.FindPrinthead(realTimeStatusMotorizedPrintheadModel.Name).PrintheadTypeModel; double previousEPosition = realTimeStatusMotorizedPrintheadModel.Position; motorizedPrintheadTypeModel.MaxPosition -= previousEPosition; motorizedPrintheadTypeModel.MinPosition -= previousEPosition; realTimeStatusMotorizedPrintheadModel.Position = 0; } } if (commandSet.Contains("X")) { AxisModel xAxisModel = _printerModel.AxisModelList[0]; double previousXPosition = _realTimeStatusDataModel.XRealTimeStatusAxisModel.Position; xAxisModel.MaxPosition -= previousXPosition; xAxisModel.MinPosition -= previousXPosition; _realTimeStatusDataModel.XRealTimeStatusAxisModel.Position = 0; } if (commandSet.Contains("Y")) { AxisModel yAxisModel = _printerModel.AxisModelList[1]; double previousYPosition = _realTimeStatusDataModel.YRealTimeStatusAxisModel.Position; yAxisModel.MaxPosition -= previousYPosition; yAxisModel.MinPosition -= previousYPosition; _realTimeStatusDataModel.YRealTimeStatusAxisModel.Position = 0; } if (commandSet.Contains("Z")) { AxisModel zAxisModel = _printerModel.FindAxis(_realTimeStatusDataModel.ZRealTimeStatusAxisModel.Name); double previousZPosition = _realTimeStatusDataModel.ZRealTimeStatusAxisModel.Position; zAxisModel.MaxPosition -= previousZPosition; zAxisModel.MinPosition -= previousZPosition; _realTimeStatusDataModel.ZRealTimeStatusAxisModel.Position = 0; } OnCommandSetMinMaxPositionChanged(); OnCommandSetMinMaxPositionChanged(); //No commands to return. return(null); }
/// <summary> /// Takes manual input parameters for a motor print without movement command and outputs the command to the serial port. /// </summary> /// <param name="eDistance"></param> public void ProcessManualMotorPrintWithoutMovementCommand(double eDistance) { MotorizedPrintheadTypeModel motorizedPrintheadTypeModel = (MotorizedPrintheadTypeModel)_printerModel.FindPrinthead(_realTimeStatusDataModel.ActivePrintheadModel.Name).PrintheadTypeModel; double emmPerStep = motorizedPrintheadTypeModel.MmPerStep; RealTimeStatusMotorizedPrintheadModel realTimeStatusMotorizedPrintheadModel = (RealTimeStatusMotorizedPrintheadModel)_realTimeStatusDataModel.ActivePrintheadModel; double unused = 0; string printString = GCodeLinesConverter.GCodeLinesListToString( WriteG00.WriteMotorizedPrintWithoutMovement(eDistance, emmPerStep, motorizedPrintheadTypeModel.IsDirectionInverted, ref unused, null)); _serialCommunicationOutgoingMessagesModel.QueueNextProspectiveOutgoingMessage(printString); }
/// <summary> /// Reads the coordinate values in a movement or print command. /// </summary> /// <param name="convertedGCodeLine"></param> /// <param name="gCodeIndex"></param> /// <param name="materialModel"></param> /// <returns></returns> private MovementModel ReadCoord(string convertedGCodeLine, int gCodeIndex, MaterialModel materialModel) { //G Commands from Converted GCode are in relative positions. string[] gCodePhrases = GCodeStringParsing.GCodeTo2DArr(convertedGCodeLine)[0]; double xDistance = 0; double yDistance = 0; double zDistance = 0; double eDistance = 0; //Read the coordinates from the GCode. for (int phrase = 1; phrase < gCodePhrases.Length; phrase++) { switch (gCodePhrases[phrase][0]) { case 'X': int xSteps = (int)GCodeStringParsing.ParseDouble(gCodePhrases[phrase]); AxisModel xAxisModel = _printerModel.AxisModelList[0]; xDistance = G00Calculator.StepsToDistance(xSteps, xAxisModel.MmPerStep, xAxisModel.IsDirectionInverted); break; case 'Y': int ySteps = (int)GCodeStringParsing.ParseDouble(gCodePhrases[phrase]); AxisModel yAxisModel = _printerModel.AxisModelList[1]; yDistance = G00Calculator.StepsToDistance(ySteps, yAxisModel.MmPerStep, yAxisModel.IsDirectionInverted); break; case 'Z': int zSteps = (int)GCodeStringParsing.ParseDouble(gCodePhrases[phrase]); AxisModel zAxisModel = _printerModel.FindAxis(materialModel.PrintheadModel.AttachedZAxisModel.Name); zDistance = G00Calculator.StepsToDistance(zSteps, zAxisModel.MmPerStep, zAxisModel.IsDirectionInverted); break; case 'E': int eSteps = (int)GCodeStringParsing.ParseDouble(gCodePhrases[phrase]); MotorizedPrintheadTypeModel motorizedPrintheadTypeModel = (MotorizedPrintheadTypeModel)materialModel.PrintheadModel.PrintheadTypeModel; eDistance = G00Calculator.StepsToDistance(eSteps, motorizedPrintheadTypeModel.MmPerStep, motorizedPrintheadTypeModel.IsDirectionInverted); break; default: //Do nothing. break; } } MovementModel movementModel = new MovementModel(xDistance, yDistance, zDistance, eDistance, gCodeIndex, materialModel, _printerModel); return(movementModel); }
/// <summary> /// Record the parameters from a Set Motorized Printhead command. /// </summary> /// <param name="printheadName"></param> /// <param name="maxSpeed"></param> /// <param name="acceleration"></param> public void RecordSetMotorizedPrinthead(string printheadName, double maxSpeed, double acceleration) { _activePrintheadType = PrintheadType.Motorized; MotorizedPrintheadTypeModel motorizedPrintheadTypeModel = (MotorizedPrintheadTypeModel)_printerModel.FindPrinthead(printheadName).PrintheadTypeModel; double mmPerStep = motorizedPrintheadTypeModel.MmPerStep; //Max speed is read as steps / s and acceleration is read as steps / s2. //These parameters are converted to this program's convention of mm / s and mm / s2. double convertedMaxSpeed = maxSpeed * mmPerStep; double convertedAcceleration = acceleration * mmPerStep; _activePrintheadModel = new RealTimeStatusMotorizedPrintheadModel(printheadName, convertedMaxSpeed, convertedAcceleration); //Notify other classes. OnRecordSetMotorizedPrintheadExecuted(printheadName); }
/// <summary> /// Calculate max speed and acceleration such that these values do not exceed the individual max speed and acceleration values of each Axis. /// </summary> /// <param name="materialModel"></param> private void CalculateSpeeds(MaterialModel materialModel) { //Store all distance and speed values in arrays for easy calculation later. double[] distanceArr = new double[4]; distanceArr[0] = Math.Abs(_x); distanceArr[1] = Math.Abs(_y); distanceArr[2] = Math.Abs(_z); distanceArr[3] = Math.Abs(_e); double[] maxSpeedArr = new double[4]; maxSpeedArr[0] = materialModel.XYPrintSpeed / _printerModel.AxisModelList[0].MmPerStep; maxSpeedArr[1] = materialModel.XYPrintSpeed / _printerModel.AxisModelList[1].MmPerStep; maxSpeedArr[2] = materialModel.ZPrintSpeed / _materialModel.PrintheadModel.AttachedZAxisModel.MmPerStep; double[] accelerationArr = new double[4]; accelerationArr[0] = materialModel.XYPrintAcceleration / _printerModel.AxisModelList[0].MmPerStep; accelerationArr[1] = materialModel.XYPrintAcceleration / _printerModel.AxisModelList[1].MmPerStep; accelerationArr[2] = materialModel.ZPrintAcceleration / _materialModel.PrintheadModel.AttachedZAxisModel.MmPerStep; if (materialModel.PrintheadModel.PrintheadType == PrintheadType.Motorized) { MotorizedPrintheadTypeModel motorizedPrintheadTypeModel = (MotorizedPrintheadTypeModel)materialModel.PrintheadModel.PrintheadTypeModel; maxSpeedArr[3] = motorizedPrintheadTypeModel.MaxSpeed / motorizedPrintheadTypeModel.MmPerStep; accelerationArr[3] = motorizedPrintheadTypeModel.MaxAcceleration / motorizedPrintheadTypeModel.MmPerStep; } else { maxSpeedArr[3] = 0; accelerationArr[3] = 0; } //Calculate the maximum speeds and accelerations such that these values do not exceed the individual speed values of each Axis. for (int k = 0; k < 4; k++) { if (maxSpeedArr[k] != 0) { double scaledMaxSpeed = maxSpeedArr[k] * _totalDistance / distanceArr[k]; _maxSpeed = (scaledMaxSpeed < _maxSpeed) ? scaledMaxSpeed : _maxSpeed; } if (accelerationArr[k] != 0) { double scaledAcceleration = accelerationArr[k] * _totalDistance / distanceArr[k]; _acceleration = (scaledAcceleration < _acceleration) ? scaledAcceleration : _acceleration; } } }
/// <summary> /// Record the parameters from a Motorized Printhead Print With Movement command. /// </summary> /// <param name="taskQueuedMessage"></param> /// <param name="eStepsTaken"></param> /// <param name="xStepsTaken"></param> /// <param name="yStepsTaken"></param> /// <param name="zStepsTaken"></param> public void RecordMotorizedPrintWithMovement(int eStepsTaken, int xStepsTaken, int yStepsTaken, int zStepsTaken) { if (_activePrintheadType == PrintheadType.Motorized) { MotorizedPrintheadTypeModel motorizedPrintheadTypeModel = (MotorizedPrintheadTypeModel)_printerModel.FindPrinthead(_activePrintheadModel.Name).PrintheadTypeModel; double emmPerStep = motorizedPrintheadTypeModel.MmPerStep; double xmmPerStep = _printerModel.AxisModelList[0].MmPerStep; double ymmPerStep = _printerModel.AxisModelList[1].MmPerStep; double zmmPerStep = _printerModel.FindAxis(_zRealTimeStatusAxisModel.Name).MmPerStep; //Record data. RealTimeStatusMotorizedPrintheadModel motorizedPrintheadModel = (RealTimeStatusMotorizedPrintheadModel)_activePrintheadModel; //Record positions. if (eStepsTaken != 0) { motorizedPrintheadModel.Position += (motorizedPrintheadTypeModel.IsDirectionInverted == false) ? (double)(eStepsTaken * emmPerStep) : (double)(eStepsTaken * -1 * emmPerStep); motorizedPrintheadModel.LimitSwitchStatus = LimitSwitchStatus.NoLimit; } if (xStepsTaken != 0) { _xRealTimeStatusAxisModel.Position += (_printerModel.AxisModelList[0].IsDirectionInverted == false) ? (double)(xStepsTaken * xmmPerStep) : (double)(xStepsTaken * -1 * xmmPerStep); _xRealTimeStatusAxisModel.LimitSwitchStatus = LimitSwitchStatus.NoLimit; } if (yStepsTaken != 0) { _yRealTimeStatusAxisModel.Position += (_printerModel.AxisModelList[1].IsDirectionInverted == false) ? (double)(yStepsTaken * ymmPerStep) : (double)(yStepsTaken * -1 * ymmPerStep); _yRealTimeStatusAxisModel.LimitSwitchStatus = LimitSwitchStatus.NoLimit; } if (zStepsTaken != 0) { _zRealTimeStatusAxisModel.Position += (_printerModel.FindAxis(_zRealTimeStatusAxisModel.Name).IsDirectionInverted == false) ? (double)(zStepsTaken * zmmPerStep) : (double)(zStepsTaken * -1 * zmmPerStep); _zRealTimeStatusAxisModel.LimitSwitchStatus = LimitSwitchStatus.NoLimit; } //Notify other classes. OnRecordMotorizedPrintWithMovementExecuted(); } }
/// <summary> /// Record the parameters from a Motorized Printhead Print without Movement command. /// </summary> /// <param name="ePosition"></param> public void RecordMotorizedPrintWithoutMovement(double eStepsTaken) { if (_activePrintheadType == PrintheadType.Motorized) { MotorizedPrintheadTypeModel motorizedPrintheadTypeModel = (MotorizedPrintheadTypeModel)_printerModel.FindPrinthead(_activePrintheadModel.Name).PrintheadTypeModel; double emmPerStep = motorizedPrintheadTypeModel.MmPerStep; //Record data. RealTimeStatusMotorizedPrintheadModel motorizedPrintheadModel = (RealTimeStatusMotorizedPrintheadModel)_activePrintheadModel; if (eStepsTaken != 0) { motorizedPrintheadModel.Position += (motorizedPrintheadTypeModel.IsDirectionInverted == false) ? (double)(eStepsTaken * emmPerStep) : (double)(eStepsTaken * -1 * emmPerStep); motorizedPrintheadModel.LimitSwitchStatus = LimitSwitchStatus.NoLimit; } //Notify other classes. OnRecordMotorizedPrintWithoutMovementExecuted(); } }
/// <summary> /// Takes manual input parameters for a motor print with movement command and outputs the command to the serial port. /// </summary> /// <param name="xDistance"></param> /// <param name="yDistance"></param> /// <param name="zDistance"></param> /// <param name="eDispensePerDistance"></param> public void ProcessManualMotorPrintWithMovementCommand(double xDistance, double yDistance, double zDistance, double eDispensePerDistance) { MotorizedPrintheadTypeModel motorizedPrintheadTypeModel = (MotorizedPrintheadTypeModel)_printerModel.FindPrinthead(_realTimeStatusDataModel.ActivePrintheadModel.Name).PrintheadTypeModel; double emmPerStep = motorizedPrintheadTypeModel.MmPerStep; double xmmPerStep = (xDistance != 0) ? _printerModel.AxisModelList[0].MmPerStep : double.MaxValue; double ymmPerStep = (yDistance != 0) ? _printerModel.AxisModelList[1].MmPerStep : double.MaxValue; AxisModel zAxisModel = _printerModel.FindAxis(_realTimeStatusDataModel.ZRealTimeStatusAxisModel.Name); double zmmPerStep = (zDistance != 0) ? _printerModel.FindAxis(zAxisModel.Name).MmPerStep : double.MaxValue; bool zDirectionInverted = (zAxisModel != null) ? zAxisModel.IsDirectionInverted : false; double unused = 0; string printString = GCodeLinesConverter.GCodeLinesListToString( WriteG00.WriteMotorizedContinuousPrint(emmPerStep, xmmPerStep, ymmPerStep, zmmPerStep, eDispensePerDistance, xDistance, yDistance, zDistance, _printerModel.AxisModelList[0].IsDirectionInverted, _printerModel.AxisModelList[1].IsDirectionInverted, zDirectionInverted, motorizedPrintheadTypeModel.IsDirectionInverted, ref unused, ref unused, ref unused, ref unused, null)); _serialCommunicationOutgoingMessagesModel.QueueNextProspectiveOutgoingMessage(printString); }
/// <summary> /// Returns converted GCode for the setting of Motor-Driven Printheads. /// </summary> /// <param name="printheadModel"></param> /// <returns></returns> public string WriteSetMotorDrivenPrinthead(PrintheadModel printheadModel) { string convertedGCode = ""; if (printheadModel.PrintheadType == PrintheadType.Motorized) { MotorizedPrintheadTypeModel motorizedPrinthead = (MotorizedPrintheadTypeModel)printheadModel.PrintheadTypeModel; try { int limitPin = GlobalValues.PinIDNull; if (motorizedPrinthead.AttachedLimitSwitchGPIOPinModel != null) { limitPin = motorizedPrinthead.AttachedLimitSwitchGPIOPinModel.PinID; } convertedGCode = WriteSetMotorDrivenPrinthead(motorizedPrinthead.AttachedMotorStepGPIOPinModel.PinID, motorizedPrinthead.AttachedMotorDirectionGPIOPinModel.PinID, motorizedPrinthead.StepPulseTime, limitPin, motorizedPrinthead.MaxSpeed, motorizedPrinthead.MaxAcceleration, motorizedPrinthead.MmPerStep); } catch when(printheadModel == null) { _parametersModel.ErrorReporterViewModel.ReportError("GCode Converter: Printer Unset", "Printhead Not Found"); convertedGCode = ""; }
/// <summary> /// Translates raw task queued message for a Set Motorized Printhead command into a readable phrase. /// Sets the Real Time Status based on the message. /// </summary> /// <param name="incomingMessage"></param> /// <returns></returns> public void InterpretSetMotorizedPrintheadQueued(string incomingMessage) { string taskQueuedMessage = "Set Motorized Printhead: "; //Return string. string printheadName = "Unknown Motorized Printhead"; //Name of the Printhead. Labelled as unknown if Axis cannot be found. double[] parameterValues = ParseDoubleArray(incomingMessage); //Array of numerical values in incomingMessage. int stepPin = (int)parameterValues[0]; int maxSpeed = (int)parameterValues[4]; int acceleration = (int)parameterValues[5]; //Search for the PrintheadModel with the matching Step Pin ID then return the Printhead Name. foreach (PrintheadModel printheadModel in _printerModel.PrintheadModelList) { if (printheadModel.PrintheadType == PrintheadType.Motorized) { MotorizedPrintheadTypeModel motorizedPrintheadTypeModel = (MotorizedPrintheadTypeModel)printheadModel.PrintheadTypeModel; if ((int)stepPin == motorizedPrintheadTypeModel.AttachedMotorStepGPIOPinModel.PinID) { printheadName = printheadModel.Name; break; } } } taskQueuedMessage += printheadName; taskQueuedMessage += " S" + maxSpeed; taskQueuedMessage += " A" + acceleration; //Set Real Time Status parameters based on this incomingMessage. if (printheadName != "Unknown Motorized Printhead") { _realTimeStatusDataModel.RecordTaskQueued(taskQueuedMessage); _printerViewModel.FindPrinthead(printheadName).PrintheadStatus = PrintheadStatus.BeingSet; } }
/// <summary> /// Record the parameters from a Limit Switch status message. /// </summary> /// <param name="xLimit"></param> /// <param name="yLimit"></param> /// <param name="zLimit"></param> /// <param name="eLimit"></param> /// <param name="xStepsTaken"></param> /// <param name="yStepsTaken"></param> /// <param name="zStepsTaken"></param> /// <param name="eStepsTaken"></param> public void RecordLimit(bool xLimit, bool yLimit, bool zLimit, bool eLimit, int xStepsTaken, int yStepsTaken, int zStepsTaken, int eStepsTaken) { //E if (_activePrintheadType == PrintheadType.Motorized) { //mm Per Step. MotorizedPrintheadTypeModel motorizedPrintheadTypeModel = (MotorizedPrintheadTypeModel)_printerModel.FindPrinthead(_activePrintheadModel.Name).PrintheadTypeModel; eStepsTaken = (motorizedPrintheadTypeModel.IsDirectionInverted == false) ? eStepsTaken : (-1 * eStepsTaken); double emmPerStep = motorizedPrintheadTypeModel.MmPerStep; //Update Position. RealTimeStatusMotorizedPrintheadModel realTimeStatusMotorizedPrintheadTypeModel = (RealTimeStatusMotorizedPrintheadModel)_activePrintheadModel; realTimeStatusMotorizedPrintheadTypeModel.Position += (double)(eStepsTaken * -1 * emmPerStep); //Update Max/Min Position and Limit. if (eLimit == true) { if (eStepsTaken > 0) { motorizedPrintheadTypeModel.MaxPosition = realTimeStatusMotorizedPrintheadTypeModel.Position; realTimeStatusMotorizedPrintheadTypeModel.LimitSwitchStatus = LimitSwitchStatus.UpperLimit; } else if (eStepsTaken < 0) { motorizedPrintheadTypeModel.MinPosition = realTimeStatusMotorizedPrintheadTypeModel.Position; realTimeStatusMotorizedPrintheadTypeModel.LimitSwitchStatus = LimitSwitchStatus.LowerLimit; } } } AxisModel xAxisModel = _printerModel.AxisModelList[0]; AxisModel yAxisModel = _printerModel.AxisModelList[1]; AxisModel zAxisModel = _printerModel.FindAxis(_zRealTimeStatusAxisModel.Name); //mm Per Step. double xmmPerStep = xAxisModel.MmPerStep; double ymmPerStep = yAxisModel.MmPerStep; double zmmPerStep = (zAxisModel != null) ? _printerModel.FindAxis(_zRealTimeStatusAxisModel.Name).MmPerStep : 0; //Record positions. if (xStepsTaken != 0) { xStepsTaken = (_printerModel.AxisModelList[0].IsDirectionInverted == false) ? xStepsTaken : (-1 * xStepsTaken); _xRealTimeStatusAxisModel.Position += (double)(xStepsTaken * xmmPerStep); } if (yStepsTaken != 0) { yStepsTaken = (_printerModel.AxisModelList[1].IsDirectionInverted == false) ? yStepsTaken : (-1 * yStepsTaken); _yRealTimeStatusAxisModel.Position += (double)(yStepsTaken * ymmPerStep); } if (zStepsTaken != 0) { zStepsTaken = (_printerModel.FindAxis(_zRealTimeStatusAxisModel.Name).IsDirectionInverted == false) ? zStepsTaken : (-1 * zStepsTaken); _zRealTimeStatusAxisModel.Position += (double)(zStepsTaken * zmmPerStep); } //Set Max Positions and Limits. if (xLimit == true) { if (xStepsTaken > 0) { xAxisModel.MaxPosition = _xRealTimeStatusAxisModel.Position; _xRealTimeStatusAxisModel.LimitSwitchStatus = LimitSwitchStatus.UpperLimit; } else if (xStepsTaken < 0) { xAxisModel.MinPosition = _xRealTimeStatusAxisModel.Position; _xRealTimeStatusAxisModel.LimitSwitchStatus = LimitSwitchStatus.LowerLimit; } } if (yLimit == true) { if (yStepsTaken > 0) { yAxisModel.MaxPosition = _yRealTimeStatusAxisModel.Position; _yRealTimeStatusAxisModel.LimitSwitchStatus = LimitSwitchStatus.UpperLimit; } else if (yStepsTaken < 0) { yAxisModel.MinPosition = _yRealTimeStatusAxisModel.Position; _yRealTimeStatusAxisModel.LimitSwitchStatus = LimitSwitchStatus.LowerLimit; } } if (zLimit == true) { if (zStepsTaken > 0) { if (_shouldZCalibrate == true) { zAxisModel.MaxPosition = _zRealTimeStatusAxisModel.Position; _shouldZCalibrate = false; } _zRealTimeStatusAxisModel.LimitSwitchStatus = LimitSwitchStatus.UpperLimit; } else if (zStepsTaken < 0) { //The minimum Position of Z Axes are always zero. //If the lower limit of a Z Axis is hit, then adjust the Max Position such that the range remains the same. if (_shouldZCalibrate == true) { zAxisModel.MaxPosition = zAxisModel.MaxPosition + _zRealTimeStatusAxisModel.Position; zAxisModel.MinPosition = 0; _shouldZCalibrate = false; } _zRealTimeStatusAxisModel.LimitSwitchStatus = LimitSwitchStatus.LowerLimit; } } //Notify other classes. OnRecordLimitExecuted(); }
public MotorizedPrintheadTypeViewModel(MotorizedPrintheadTypeModel MotorizedPrintheadTypeModel, GPIOPinListsViewModel GPIOPinListsViewModel) : base(MotorizedPrintheadTypeModel, GPIOPinListsViewModel) { _motorizedPrintheadTypeModel = MotorizedPrintheadTypeModel; }
/// <summary> /// Sets the minimum and/or maximum position of actuator-based equipment as its current position. /// </summary> /// <param name="commandSet"></param> /// <returns></returns> private List <string> InterpretSetMinMaxPosition(string commandSet) { //Remove "*SetMinMaxPos" from the beginning of the command set. commandSet = commandSet.Substring(12); for (int index = 0; index < commandSet.Length; index++) { switch (commandSet[index]) { case 'E': if (_realTimeStatusDataModel.ActivePrintheadType == PrintheadType.Motorized) { //Set the current position as the parameter value. RealTimeStatusMotorizedPrintheadModel realTimeStatusMotorizedPrintheadModel = (RealTimeStatusMotorizedPrintheadModel)_realTimeStatusDataModel.ActivePrintheadModel; MotorizedPrintheadTypeModel motorizedPrintheadTypeModel = (MotorizedPrintheadTypeModel)_printerModel.FindPrinthead(_realTimeStatusDataModel.ActivePrintheadModel.Name).PrintheadTypeModel; double ePreviousPosition = realTimeStatusMotorizedPrintheadModel.Position; realTimeStatusMotorizedPrintheadModel.Position = ParseDouble(commandSet.Substring(index)); double ePositionDifference = realTimeStatusMotorizedPrintheadModel.Position - ePreviousPosition; //Set the Min or Max Position property as the parameter value. //Adjust the Min and Max positions such that the distance between Max and Min Position remains the same. switch (commandSet[index + 1]) { case 'N': motorizedPrintheadTypeModel.MinPosition = realTimeStatusMotorizedPrintheadModel.Position; motorizedPrintheadTypeModel.MaxPosition += ePositionDifference; break; case 'M': motorizedPrintheadTypeModel.MaxPosition = realTimeStatusMotorizedPrintheadModel.Position; motorizedPrintheadTypeModel.MinPosition += ePositionDifference; break; default: //Set position value only. //Do nothing here. break; } } break; case 'X': //Set the current position as the parameter value. RealTimeStatusAxisModel xRealTimeStatusAxisModel = _realTimeStatusDataModel.XRealTimeStatusAxisModel; AxisModel xAxisModel = _printerModel.AxisModelList[0]; double xPreviousPosition = xRealTimeStatusAxisModel.Position; xRealTimeStatusAxisModel.Position = ParseDouble(commandSet.Substring(index)); double xPositionDifference = xRealTimeStatusAxisModel.Position - xPreviousPosition; //Set the Min or Max Position property as the parameter value. //Adjust the Min and Max positions such that the distance between Max and Min Position remains the same. switch (commandSet[index + 1]) { case 'N': xAxisModel.MinPosition = xRealTimeStatusAxisModel.Position; xAxisModel.MaxPosition += xPositionDifference; break; case 'M': xAxisModel.MaxPosition = xRealTimeStatusAxisModel.Position; xAxisModel.MinPosition += xPositionDifference; break; default: //Set position value only. //Do nothing here. break; } break; case 'Y': //Set the current position as the parameter value. RealTimeStatusAxisModel yRealTimeStatusAxisModel = _realTimeStatusDataModel.YRealTimeStatusAxisModel; AxisModel yAxisModel = _printerModel.AxisModelList[1]; double yPreviousPosition = yRealTimeStatusAxisModel.Position; yRealTimeStatusAxisModel.Position = ParseDouble(commandSet.Substring(index)); double yPositionDifference = yRealTimeStatusAxisModel.Position - yPreviousPosition; //Set the Min or Max Position property as the parameter value. //Adjust the Min and Max positions such that the distance between Max and Min Position remains the same. switch (commandSet[index + 1]) { case 'N': yAxisModel.MinPosition = yRealTimeStatusAxisModel.Position; yAxisModel.MaxPosition += yPositionDifference; break; case 'M': yAxisModel.MaxPosition = yRealTimeStatusAxisModel.Position; yAxisModel.MinPosition += yPositionDifference; break; default: //Set position value only. //Do nothing here. break; } break; case 'Z': //Set the current position as the parameter value. RealTimeStatusAxisModel zRealTimeStatusAxisModel = _realTimeStatusDataModel.ZRealTimeStatusAxisModel; AxisModel zAxisModel = _printerModel.FindAxis(zRealTimeStatusAxisModel.Name); double zPreviousPosition = zRealTimeStatusAxisModel.Position; zRealTimeStatusAxisModel.Position = ParseDouble(commandSet.Substring(index)); double zPositionDifference = zRealTimeStatusAxisModel.Position - zPreviousPosition; //Set the Min or Max Position property as the parameter value. //Adjust the Min and Max positions such that the distance between Max and Min Position remains the same. switch (commandSet[index + 1]) { case 'N': zAxisModel.MinPosition = zRealTimeStatusAxisModel.Position; zAxisModel.MaxPosition += zPositionDifference; break; case 'M': zAxisModel.MaxPosition = zRealTimeStatusAxisModel.Position; zAxisModel.MinPosition += zPositionDifference; break; default: //Set position value only. //Do nothing here. break; } break; } } OnCommandSetPositionChanged(); OnCommandSetMinMaxPositionChanged(); //No commands to return. return(null); }
/// <summary> /// Processes the command of setting a printhead. /// </summary> public List <ConvertedGCodeLine> ProcessTCommand(string[] repRapLine, ref MaterialModel currentMaterial) { AxisModel xAxis = _printerModel.AxisModelList[0]; AxisModel yAxis = _printerModel.AxisModelList[1]; AxisModel zAxisCurrent = _printerModel.FindAxis(currentMaterial.PrintheadModel.AttachedZAxisModel.Name); //The return GCode. List <ConvertedGCodeLine> convertedGCodeLinesList = new List <ConvertedGCodeLine>(); //Finds the material that matches the TCommand. string repRapTCommand = repRapLine[0]; MaterialModel matchingMaterial = _printModel.FindMaterial(repRapTCommand); //Appends the converted GCode line with a command that sets the Printhead. //Also appends the converted GCode line with a command that sets the new Z Axis associated with the new Printhead. //Also appends the converted GCode line with commands that compensate for the new Printhead's offsets. try { //If the current Material is using a Motorized Printhead, retract it before switching Printheads. if (((currentMaterial.Name != "Unset") && //If this is not the first Material (currentMaterial.PrintheadModel.PrintheadType == PrintheadType.Motorized) && (currentMaterial.PrintheadModel.Name != matchingMaterial.PrintheadModel.Name) && //Do not execute retraction-related actions if no Printhead change occurs (_parametersModel.IsRetracted == false))) { MotorizedPrintheadTypeModel motorizedPrintheadTypeModel = (MotorizedPrintheadTypeModel)currentMaterial.PrintheadModel.PrintheadTypeModel; ContinuousPrintStyleModel continuousPrintheadStyleModel = (ContinuousPrintStyleModel)currentMaterial.PrintStyleModel; int eModiPrintCoordIndex = _parametersModel.FindEModiPrintCoordIndex(currentMaterial.PrintheadModel); convertedGCodeLinesList = WriteG00.WriteMotorizedPrintWithoutMovement(-1 * continuousPrintheadStyleModel.MotorizedDispenseRetractionDistance, motorizedPrintheadTypeModel.MmPerStep, motorizedPrintheadTypeModel.IsDirectionInverted, ref _parametersModel.ERepRapCoord.DeltaCoordRemainder, _parametersModel.EModiPrintCoordList[eModiPrintCoordIndex]); _parametersModel.IsRetracted = true; } //If a new Motorized Printhead is being set... //Finds the EModiPrintCoord corresponding to the given Printhead and sets the Minimum and Maximum Position values of the EModiPrintCoord. if (matchingMaterial.PrintheadModel.PrintheadType == PrintheadType.Motorized) { int eModiPrintCoordIndex = _parametersModel.FindEModiPrintCoordIndex(matchingMaterial.PrintheadModel); MotorizedPrintheadTypeModel motorizedPrintheadTypeModel = (MotorizedPrintheadTypeModel)matchingMaterial.PrintheadModel.PrintheadTypeModel; ContinuousPrintStyleModel continuousPrintheadStyleModel = (ContinuousPrintStyleModel)matchingMaterial.PrintStyleModel; //Sets new Min and Max Positions. _parametersModel.EModiPrintCoordList[eModiPrintCoordIndex].MinPosition = motorizedPrintheadTypeModel.MinPosition; _parametersModel.EModiPrintCoordList[eModiPrintCoordIndex].MaxPosition = motorizedPrintheadTypeModel.MaxPosition; //Sets the starting position of the new Motorized Printhead. //The starting position is the retracted state. //If this is the first Material, then retraction needs to occur to reach the starting retracted state. if (currentMaterial.Name == "Unset") //If this is the first Material. { //Retraction needs to occur to reach the starting retracted state. List <ConvertedGCodeLine> retractE = WriteG00.WriteMotorizedPrintWithoutMovement(-1 * continuousPrintheadStyleModel.MotorizedDispenseRetractionDistance, motorizedPrintheadTypeModel.MmPerStep, motorizedPrintheadTypeModel.IsDirectionInverted, ref _parametersModel.ERepRapCoord.DeltaCoordRemainder, _parametersModel.EModiPrintCoordList[eModiPrintCoordIndex]); if (retractE != null) { convertedGCodeLinesList.AddRange(retractE); } _parametersModel.ERepRapCoord.SetInitialCoord(continuousPrintheadStyleModel.MotorizedDispenseRetractionDistance); _parametersModel.IsRetracted = true; } //If this is a new Motorized Printhead, then it is by default, retracted. if (currentMaterial.PrintheadModel.Name != matchingMaterial.PrintheadModel.Name) { _parametersModel.ERepRapCoord.SetInitialCoord(continuousPrintheadStyleModel.MotorizedDispenseRetractionDistance); _parametersModel.IsRetracted = true; } } else { _parametersModel.IsRetracted = false; } //Set new Min and Max Positions for the X and Y Axes. //This is only relevant when the first Material is set. _parametersModel.SetNewXYZCoord('X', _parametersModel.XCoord.CurrentCoord, _printerModel.AxisModelList[0].MinPosition, _printerModel.AxisModelList[0].MaxPosition); _parametersModel.SetNewXYZCoord('Y', _parametersModel.YCoord.CurrentCoord, _printerModel.AxisModelList[1].MinPosition, _printerModel.AxisModelList[1].MaxPosition); //If the Z Axis does not need to be changed, then keep the same Min and Max Positions in the ZCoord. //If the Z Axis was switched, then set a new ZCoord Position assuming the Z Axis started from a retracted position and traversed its Offset. if (matchingMaterial.PrintheadModel.AttachedZAxisModel.Name != matchingMaterial.PrintheadModel.AttachedZAxisModel.Name) { AxisModel zAxisModel = _printerModel.FindAxis(matchingMaterial.PrintheadModel.AttachedZAxisModel.Name); double newZPosition = zAxisModel.MaxPosition - GlobalValues.LimitBuffer; _parametersModel.SetNewXYZCoord('Z', newZPosition, zAxisModel.MinPosition, zAxisModel.MaxPosition); } //Set new Droplet parameters if applicable. if (!((currentMaterial.Name == "Unset") || (currentMaterial == null)) && //If the current Material is set to Droplet... (currentMaterial.PrintStyle == PrintStyle.Droplet)) { //Execute movement for the remaining movement left in droplet movements. MaterialModel newMaterialParameter = (matchingMaterial.PrintStyle == PrintStyle.Droplet) ? matchingMaterial : null; double[] remainingDropletMovementArr = _parametersModel.ResetDropletPrintParameters(currentMaterial, newMaterialParameter); double unused = 0; List <ConvertedGCodeLine> remainingDropletMovement = WriteG00.WriteAxesMovement( xAxis.MmPerStep, yAxis.MmPerStep, zAxisCurrent.MmPerStep, remainingDropletMovementArr[0], remainingDropletMovementArr[1], remainingDropletMovementArr[2], xAxis.IsDirectionInverted, yAxis.IsDirectionInverted, zAxisCurrent.IsDirectionInverted, ref unused, ref unused, ref unused); if (remainingDropletMovement != null) { convertedGCodeLinesList.AddRange(remainingDropletMovement); } } else if (matchingMaterial.PrintStyle == PrintStyle.Droplet) //If the current Material is irrelevant and the new Material is set to Droplet... { _parametersModel.ResetDropletPrintParameters(null, matchingMaterial); } //Set the new Material. currentMaterial = matchingMaterial; //Command Set for switching Materials. //This Command Set will convert to the commands for retracting the Z Axis, switching Printheads, moving Offsets, and setting new movement speeds. string convertedGCodeLine = SerialMessageCharacters.SerialCommandSetCharacter + "SwitchMaterial "; //If applicable, pause the print sequence before switching to the next Material. if ((currentMaterial.Name != "Unset") && (currentMaterial.PauseBeforeDeactivating == true)) { convertedGCodeLine += "D"; } //If applicable pause the print sequence after switching printheads. if (matchingMaterial.PauseAfterActivating == true) { convertedGCodeLine += "A"; } if (convertedGCodeLine[convertedGCodeLine.Length - 1] != ' ') { convertedGCodeLine += " "; } convertedGCodeLine += '"' + matchingMaterial.Name + '"'; convertedGCodeLinesList.Add(new ConvertedGCodeLine(convertedGCodeLine)); } catch when((matchingMaterial == null) || (currentMaterial == null)) //Catch unset Material. { //Catching and error reporting should have happened earlier. _parametersModel.ErrorReporterViewModel.ReportError("G-Code Conversion Failed: Print Settings Incorrectly Set, Should Not Happen", "Material Null"); return(null); }