/// <summary> /// Add the deceleration steps parameter to all G commands. /// Deceleration steps are calculated such that steppers move as quickly as possible without violating max speeds and junction speeds. /// </summary> /// <param name="convertedGCodeLinesList"></param> public void AddDecelerationStepsParameter(ref List <ConvertedGCodeLine> convertedGCodeLinesList) { //Reset the progress bar. _progressBarTick = 0; //A list of all the indeces where a new Material is set. List <int> materialIndecesList = new List <int>(); //The reference of the corresponding Material of the same index in the MaterialIndecesList. List <MaterialModel> materialModelsList = new List <MaterialModel>(); //Starting from the beginning of the list... //Search for the settings of a new Material. for (int i = 0; i < convertedGCodeLinesList.Count; i++) { //Found a new Material. if ((convertedGCodeLinesList[i].GCode.Length >= 15) && (convertedGCodeLinesList[i].GCode.Substring(1, 14) == "SwitchMaterial")) { materialIndecesList.Add(i); int materialNameStartIndex = convertedGCodeLinesList[i].GCode.IndexOf('"') + 1; string materialName = convertedGCodeLinesList[i].GCode.Substring(materialNameStartIndex, convertedGCodeLinesList[i].GCode.Length - (materialNameStartIndex + 1)); materialModelsList.Add(_printModel.FindMaterialByName(materialName)); } } //For each Material... //Calculate the number of steps of each movement until deceleration such that smooth cornerning is possible. for (int m = 0; m < materialIndecesList.Count; m++) { int materialStartIndex = materialIndecesList[m]; int materialEndIndex = ((m + 1) >= materialIndecesList.Count) ? (convertedGCodeLinesList.Count - 1) : materialIndecesList[m + 1]; List <List <MovementModel> > continuousMovementsList = FindContinuousMovements(convertedGCodeLinesList, materialModelsList[m], materialStartIndex, materialEndIndex); CalculateJunctionSpeeds(continuousMovementsList, materialModelsList[m]); CalculateVelocityProfile(continuousMovementsList, materialModelsList[m]); WriteExitSpeed(continuousMovementsList, ref convertedGCodeLinesList, materialModelsList[m]); } }
/// <summary> /// Interpret a switch material command set and return an array of commands. /// </summary> /// <param name="commandSet"></param> /// <returns></returns> private List <string> InterpretSwitchMaterial(string commandSet) { //Remove "*SwitchMaterial" from the beginning of the command set. commandSet = commandSet.Substring(14); //Potentially pause before deactivating the current printhead. bool pauseBeforeDeactivating = false; if (commandSet.Contains('D')) { pauseBeforeDeactivating = true; } //Potentially pause after activating the next printhead. bool pauseBeforeActivating = false; if (commandSet.Contains('A')) { pauseBeforeActivating = true; } //Set of commands to be returned at the end of this method. List <string> returnCommands = new List <string>(); //The name of the Material which will be switched to will be between quote characters. int firstNameIndex = commandSet.IndexOf('"'); int nameLength = commandSet.Substring(firstNameIndex + 1).IndexOf('"'); string materialName = commandSet.Substring(firstNameIndex + 1, nameLength); MaterialModel materialModel = _printModel.FindMaterialByName(materialName); if (materialModel == null) { _errorListViewModel.AddError("Command Set Invalid", materialName + " Not Set"); return(null); } //References to the current and new Printheads. PrintheadModel currentPrintheadModel = _printerModel.FindPrinthead(_realTimeStatusDataModel.ActivePrintheadModel.Name); PrintheadModel newPrintheadModel = materialModel.PrintheadModel; //References to the Z Axis on the current Printhead. AxisModel currentZAxisModel = _printerModel.FindAxis(currentPrintheadModel.AttachedZAxisModel.Name); int currentZLimitPinID = (currentZAxisModel.AttachedLimitSwitchGPIOPinModel != null) ? currentZAxisModel.AttachedLimitSwitchGPIOPinModel.PinID : GlobalValues.PinIDNull; //References to the XY Axes and new Z Axis. AxisModel xAxisModel = _printerModel.AxisModelList[0]; int xLimitPinID = (xAxisModel.AttachedLimitSwitchGPIOPinModel != null) ? xAxisModel.AttachedLimitSwitchGPIOPinModel.PinID : GlobalValues.PinIDNull; AxisModel yAxisModel = _printerModel.AxisModelList[1]; int yLimitPinID = (yAxisModel.AttachedLimitSwitchGPIOPinModel != null) ? yAxisModel.AttachedLimitSwitchGPIOPinModel.PinID : GlobalValues.PinIDNull; AxisModel zAxisModel = _printerModel.FindAxis(newPrintheadModel.AttachedZAxisModel.Name); int zLimitPinID = (zAxisModel.AttachedLimitSwitchGPIOPinModel != null) ? zAxisModel.AttachedLimitSwitchGPIOPinModel.PinID : GlobalValues.PinIDNull; //If a new Printhead is required... if (newPrintheadModel.Name != currentPrintheadModel.Name) { //1. Set previous Z Axis at max speeds. //2. Retract the previous Printhead / Z Axis. returnCommands.Add(_writeSetAxisModel.WriteSetAxis('Z', currentZAxisModel.AttachedMotorStepGPIOPinModel.PinID, currentZAxisModel.AttachedMotorDirectionGPIOPinModel.PinID, currentZAxisModel.StepPulseTime, currentZLimitPinID, currentZAxisModel.MaxSpeed, currentZAxisModel.MaxAcceleration, currentZAxisModel.MmPerStep)); List <string> retractZ = RetractZ("", currentPrintheadModel.AttachedZAxisModel); foreach (string command in retractZ) { if (!String.IsNullOrWhiteSpace(command)) { returnCommands.Add(command); } } //Pause before deactivating. if (pauseBeforeDeactivating == true) { returnCommands.Add(SerialMessageCharacters.SerialPrintPauseCharacter.ToString()); } //3. Set new XYZ to max speeds and move to the new Offset. //Set associated X Axis at max speeds. returnCommands.Add(_writeSetAxisModel.WriteSetAxis('X', xAxisModel.AttachedMotorStepGPIOPinModel.PinID, xAxisModel.AttachedMotorDirectionGPIOPinModel.PinID, xAxisModel.StepPulseTime, xLimitPinID, xAxisModel.MaxSpeed, xAxisModel.MaxAcceleration, xAxisModel.MmPerStep)); //Set associated Y Axis at max speeds. returnCommands.Add(_writeSetAxisModel.WriteSetAxis('Y', yAxisModel.AttachedMotorStepGPIOPinModel.PinID, yAxisModel.AttachedMotorDirectionGPIOPinModel.PinID, yAxisModel.StepPulseTime, yLimitPinID, yAxisModel.MaxSpeed, yAxisModel.MaxAcceleration, yAxisModel.MmPerStep)); //Set associated Z Axis at max speeds. returnCommands.Add(_writeSetAxisModel.WriteSetAxis('Z', zAxisModel.AttachedMotorStepGPIOPinModel.PinID, zAxisModel.AttachedMotorDirectionGPIOPinModel.PinID, zAxisModel.StepPulseTime, zLimitPinID, zAxisModel.MaxSpeed, zAxisModel.MaxAcceleration, zAxisModel.MmPerStep)); //4.Move to the new Offset at max speeds. double zPosition = _realTimeStatusDataModel.ZRealTimeStatusAxisModel.Position; List <string> moveToOffset = WriteMoveToOffset(newPrintheadModel, currentPrintheadModel, zPosition, pauseBeforeActivating); foreach (string command in moveToOffset) { if (!String.IsNullOrWhiteSpace(command)) { returnCommands.Add(command); } } } //5.Set the print speed parameters for the new Material. //Set associated X Axis at print speeds. returnCommands.Add(_writeSetAxisModel.WriteSetAxis('X', xAxisModel.AttachedMotorStepGPIOPinModel.PinID, xAxisModel.AttachedMotorDirectionGPIOPinModel.PinID, xAxisModel.StepPulseTime, xLimitPinID, materialModel.XYPrintSpeed, materialModel.XYPrintAcceleration, xAxisModel.MmPerStep)); //Set associated Y Axis at print speeds. returnCommands.Add(_writeSetAxisModel.WriteSetAxis('Y', yAxisModel.AttachedMotorStepGPIOPinModel.PinID, yAxisModel.AttachedMotorDirectionGPIOPinModel.PinID, yAxisModel.StepPulseTime, yLimitPinID, materialModel.XYPrintSpeed, materialModel.XYPrintAcceleration, yAxisModel.MmPerStep)); //Set associated Z Axis at print speeds. returnCommands.Add(_writeSetAxisModel.WriteSetAxis('Z', zAxisModel.AttachedMotorStepGPIOPinModel.PinID, zAxisModel.AttachedMotorDirectionGPIOPinModel.PinID, zAxisModel.StepPulseTime, zLimitPinID, materialModel.ZPrintSpeed, materialModel.ZPrintAcceleration, zAxisModel.MmPerStep)); //6. Set the new Printhead at print speeds. string setNewPrinthead = _setWritePrintheadModel.SetWritePrinthead(newPrintheadModel); returnCommands.Add(setNewPrinthead); return(returnCommands); }