/// <summary> /// Копирование почти всех параметров из указанного источника /// </summary> /// <param name="_sourceRow"></param> public void duplicate(DataRow tmp) { POS = new Position(tmp.POS.X, tmp.POS.Y, tmp.POS.Z, tmp.POS.A); Machine = new PropMaсhine(tmp.Machine.NumGkode, tmp.Machine.SpeedMaсhine,tmp.Machine.SpindelON,tmp.Machine.SpeedSpindel,tmp.Machine.Chanel2ON,tmp.Machine.Chanel3ON,tmp.Machine.WithoutPause); Tools = new ToolOptions(tmp.Tools.NeedChange, tmp.Tools.NumberTools, tmp.Tools.DiametrTools); Extra = new ExtraOtions(false, 0, tmp.Extra.useThisCommand); //не нужно копировать паузу.... }
public static void FillStructure(DataRow lastDataRow, ref DataRow nextDataRow) { // Установим большинство параметров, из предыдущей строки, // и при дальнейшем парсинге, изменим только те поля которые встретятся в анализируемой строке nextDataRow.duplicate(lastDataRow); //получим символ разделения дробной и целой части. string symbSeparatorDec = CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalSeparator; char csourse = '.'; char cdestination = ','; if (symbSeparatorDec == ".") { csourse = ','; cdestination = '.'; } nextDataRow.DataString = nextDataRow.DataString.ToUpper(); // 1) распарсим строку на отдельные строки с параметрами List<string> lcmd = ParseStringToSubString(nextDataRow.DataString); if (lcmd.Count == 0) return; //необходимо для получения следующей команды, т.к. команда G04 P500 будет раздельно int index = 0; foreach (string code in lcmd) { if (code == "M3") { nextDataRow.Machine.SpindelON = true; } if (code == "M5") { nextDataRow.Machine.SpindelON = false; } if (code == "M7") { nextDataRow.Machine.Chanel2ON = true; } if (code == "M8") { nextDataRow.Machine.Chanel3ON = true; } if (code == "M9") { nextDataRow.Machine.Chanel2ON = false; nextDataRow.Machine.Chanel3ON = false; } if (code == "G0") //холостое движение { nextDataRow.Machine.NumGkode = 0; } if (code == "G1") //рабочее движение { nextDataRow.Machine.NumGkode = 1; nextDataRow.Machine.WithoutPause = false; } // TODO: добавить условие при котором данная команда доступна только с контроллером MK2, или вместо неё просто срабатывает команда g1 if (code == "G1.1") //рабочее движение без дальнейшей остановки в конце отрезка { nextDataRow.Machine.NumGkode = 1; nextDataRow.Machine.WithoutPause = true; } if (code == "G2") //TODO: не реализовано { nextDataRow.Machine.NumGkode = 2; } if (code == "G3") //TODO: не реализовано { nextDataRow.Machine.NumGkode = 3; } if (code == "G4") //пауза { try { //следующий параметр должен быть длительностью типа P500 string strNext = lcmd[index + 1].ToUpper(); if (strNext.Substring(0,1) == "P") { int times; int.TryParse(strNext.Substring(1), out times); nextDataRow.Extra.NeedPause = true; nextDataRow.Extra.timeoutMsec = times; } } catch (Exception) { nextDataRow.Extra.NeedPause = false; } } #region G92 - несколько кодов отвечающие за смещение координат if (code == "G92") { //TODO: пока применим простое смещение с переносом в точку ноль Controller.CorrectionPos.useCorrection = true; Controller.CorrectionPos.deltaX = Controller.INFO.AxesX_PositionMM; Controller.CorrectionPos.deltaY = Controller.INFO.AxesY_PositionMM; Controller.CorrectionPos.deltaZ = Controller.INFO.AxesZ_PositionMM; Controller.CorrectionPos.deltaA = Controller.INFO.AxesA_PositionMM; } if (code == "G92.1") { Controller.CorrectionPos.useCorrection = false; Controller.CorrectionPos.deltaX = 0; Controller.CorrectionPos.deltaY = 0; Controller.CorrectionPos.deltaZ = 0; Controller.CorrectionPos.deltaA = 0; } if (code == "G92.2") { Controller.CorrectionPos.useCorrection = false; } if (code == "G92.3") { Controller.CorrectionPos.useCorrection = true; } #endregion if (code.Substring(0, 1) == "F") //скорость движения, извлечем { string svalue = code.Substring(1).Replace(csourse, cdestination); int spd; int.TryParse(svalue, out spd); nextDataRow.Machine.SpeedMaсhine = spd; } if (code.Substring(0, 1) == "N") //номер кадра { string svalue = code.Substring(1).Replace(csourse, cdestination); ; int numKadr = 0; int.TryParse(svalue, out numKadr); nextDataRow.numberKadr = numKadr; } if (code.Substring(0, 1) == "S") //скорость движения, извлечем { string svalue = code.Substring(1).Replace(csourse, cdestination); ; int spd = 0; int.TryParse(svalue, out spd); nextDataRow.Machine.SpeedSpindel = spd; } if (code.Substring(0, 1) == "X") //координата { string svalue = code.Substring(1).Replace(csourse, cdestination); ; decimal pos = 0; decimal.TryParse(svalue, out pos); if (AbsolutlePosParsing) nextDataRow.POS.X = pos; else nextDataRow.POS.X += pos; } if (code.Substring(0, 1) == "Y") //координата { string svalue = code.Substring(1).Replace(csourse, cdestination); ; decimal pos = 0; decimal.TryParse(svalue, out pos); if (AbsolutlePosParsing) nextDataRow.POS.Y = pos; else nextDataRow.POS.Y += pos; } if (code.Substring(0, 1) == "Z") //координата { string svalue = code.Substring(1).Replace(csourse, cdestination); ; decimal pos = 0; decimal.TryParse(svalue, out pos); if (AbsolutlePosParsing) nextDataRow.POS.Z = pos; else nextDataRow.POS.Z += pos; } if (code.Substring(0, 1) == "A") //координата { string svalue = code.Substring(1); decimal pos = 0; decimal.TryParse(svalue, out pos); if (AbsolutlePosParsing) nextDataRow.POS.A = pos; else nextDataRow.POS.A += pos; } if (code == "G90") { AbsolutlePosParsing = true; //применяем абсолютные координаты } if (code == "G91") { AbsolutlePosParsing = false;//применяем относительные координаты } index++; }//foreach (string CODE in lcmd) }
/// <summary> /// поток загрузки данных из буффера /// </summary> private static void DoWork1(object data) { status = eDataSetStatus.loadingFromFile; descryption = @"Загрузка данных из файла"; percentCompleated = 0; int countLines = 0; int currentLine = 0; string tmp = (string) data; tmp = tmp.Replace('\r', ' '); string[] Gkode = tmp.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries); //"\r\n" countLines = Gkode.Length; foreach (string line in Gkode) { DataRows.Add(new DataRow(currentLine, line)); percentCompleated = (int)(((decimal)100 / countLines) * currentLine); currentLine++; } status = eDataSetStatus.parsingData; descryption = @"Парсинг данных"; percentCompleated = 0; currentLine = 0; DataRow tmpDataRowRecord = new DataRow(0, ""); while ((currentLine < countLines) && !_shouldStop) { percentCompleated = (int)(((decimal)100 / countLines) * currentLine); DataRow curDataRow = DataRows[currentLine]; FillStructure(tmpDataRowRecord, ref curDataRow); //скопируем, ля возможности дальше знать предыдущие параметры tmpDataRowRecord = curDataRow; currentLine++; } status = eDataSetStatus.none; dateGetNewDataCode = DateTime.Now; }
/// <summary> /// поток загрузки данных из файла /// </summary> private static void DoWork(object data) { status = eDataSetStatus.loadingFromFile; descryption = @"Загрузка данных из файла"; percentCompleated = 0; int countLines = 0; int currentLine = 0; // в начале узнаем сколько строк using (StreamReader r = new StreamReader((string)data)) { while ((r.ReadLine()) != null) { countLines++; } } // а теперь из файла прочитаем using (StreamReader srReader = File.OpenText((string)data)) { string line; while ((line = srReader.ReadLine()) != null && !_shouldStop) { // в переменной line имеем строку которую парсим DataRows.Add(new DataRow(currentLine, line)); //Data_string.Add(new stringData(indx++,line)); percentCompleated = (int)(((decimal)100 / countLines) * currentLine); currentLine++; } } status = eDataSetStatus.parsingData; descryption = @"Парсинг данных"; percentCompleated = 0; currentLine = 0; DataRow tmpDataRowRecord = new DataRow(0, ""); while ((currentLine < countLines) && !_shouldStop) { percentCompleated = (int)(((decimal)100 / countLines) * currentLine); DataRow curDataRow = DataRows[currentLine]; FillStructure(tmpDataRowRecord, ref curDataRow); //скопируем, ля возможности дальше знать предыдущие параметры tmpDataRowRecord = curDataRow; currentLine++; } status = eDataSetStatus.none; dateGetNewDataCode = DateTime.Now; }
/// <summary> /// Выполнение G-кода /// </summary> /// <param name="command">строка с G-кодом</param> public static void ExecuteCommand(string command) { DataRow dataRowNow = new DataRow(0, command); DataLoader.FillStructure(PlanetCNC_Controller.LastStatus, ref dataRowNow); if (dataRowNow.Machine.SpindelON != PlanetCNC_Controller.LastStatus.Machine.SpindelON || dataRowNow.Machine.SpeedSpindel != PlanetCNC_Controller.LastStatus.Machine.SpeedSpindel) { Controller.SendBinaryData(BinaryData.pack_B5(dataRowNow.Machine.SpindelON, 2, BinaryData.TypeSignal.Hz, dataRowNow.Machine.SpeedSpindel)); //зафиксируем PlanetCNC_Controller.LastStatus = dataRowNow; } if (dataRowNow.POS.X != PlanetCNC_Controller.LastStatus.POS.X || dataRowNow.POS.Y != PlanetCNC_Controller.LastStatus.POS.Y || dataRowNow.POS.Z != PlanetCNC_Controller.LastStatus.POS.Z || dataRowNow.POS.Z != PlanetCNC_Controller.LastStatus.POS.Z) { // int xtmp = Controller.INFO.NuberCompleatedInstruction + 10; // не будем давать возможность слать более чем данное количество комманд //if (dataRowNow.numberRow>xtmp) return; Controller.SendBinaryData(BinaryData.pack_CA(Controller.INFO.CalcPosPulse("X", dataRowNow.POS.X), Controller.INFO.CalcPosPulse("Y", dataRowNow.POS.Y), Controller.INFO.CalcPosPulse("Z", dataRowNow.POS.Z), Controller.INFO.CalcPosPulse("A", dataRowNow.POS.A), dataRowNow.Machine.SpeedMaсhine, dataRowNow.numberRow)); //зафиксируем PlanetCNC_Controller.LastStatus = dataRowNow; } }
/// <summary> /// Предыдущее значение /// </summary> private void timer1_Tick(object sender, EventArgs e) { if (_statusTask == ETaskStatus.Start) { Controller.SendBinaryData(BinaryData.pack_9E(0x05)); Controller.SendBinaryData(BinaryData.pack_BF(GlobalSetting.ControllerSetting.AxleX.MaxSpeed, GlobalSetting.ControllerSetting.AxleY.MaxSpeed, GlobalSetting.ControllerSetting.AxleZ.MaxSpeed, GlobalSetting.ControllerSetting.AxleA.MaxSpeed)); Controller.SendBinaryData(BinaryData.pack_C0()); _statusTask = ETaskStatus.Work; } if (_statusTask == ETaskStatus.Stop) { Controller.SendBinaryData(BinaryData.pack_FF()); Controller.SendBinaryData(BinaryData.pack_9D()); Controller.SendBinaryData(BinaryData.pack_9E(0x02)); Controller.SendBinaryData(BinaryData.pack_FF()); Controller.SendBinaryData(BinaryData.pack_FF()); Controller.SendBinaryData(BinaryData.pack_FF()); Controller.SendBinaryData(BinaryData.pack_FF()); Controller.SendBinaryData(BinaryData.pack_FF()); _statusTask = ETaskStatus.Off; Controller.Locked = false; //разблокируем } if (_statusTask == ETaskStatus.Work) { if (_nowPos >= _endPos) { _statusTask = ETaskStatus.Stop; return; } // сравним наличие изменений в данных, и проанализируем какие команды послать в контроллер DataRow dataRowNow = DataLoader.DataRows[_nowPos]; DataRow dataRowOld = new DataRow(0,""); if (_nowPos != 0) dataRowOld = DataLoader.DataRows[_nowPos-1]; //TODO: пока не работает if (dataRowNow.Extra.NeedPause) { //MessageBox.Show(@"Выполняется пауза длительностью " + dataRowNow.Extra.timeoutMsec + @" мс.", "", // MessageBoxButtons.OK); //System.Threading.Thread.Sleep(dataRowNow.Extra.timeoutMsec); } //Сравнить, и установить в случае необходимости //1) Шпиндель и скорость работы //2) Выполнить движение с необходимой скоростью //if (dataRowNow.Machine != dataRowOld.Machine) if (dataRowNow.Machine.SpindelON != dataRowOld.Machine.SpindelON || dataRowNow.Machine.SpeedSpindel != dataRowOld.Machine.SpeedSpindel) { Controller.SendBinaryData(BinaryData.pack_B5(dataRowNow.Machine.SpindelON, 2, BinaryData.TypeSignal.Hz, dataRowNow.Machine.SpeedSpindel)); //зафиксируем PlanetCNC_Controller.LastStatus = dataRowNow; } if (dataRowNow.POS.X != dataRowOld.POS.X || dataRowNow.POS.Y != dataRowOld.POS.Y || dataRowNow.POS.Z != dataRowOld.POS.Z || dataRowNow.POS.Z != dataRowOld.POS.Z) { if (Controller.INFO.NuberCompleatedInstruction == 0) { //если нет номера инструкции, то отправляем пока буфер не сильно занят if (GlobalSetting.AppSetting.Controller == ControllerModel.PlanetCNC_MK1 && Controller.INFO.FreebuffSize < 4) return; if (GlobalSetting.AppSetting.Controller == ControllerModel.PlanetCNC_MK2 && Controller.INFO.FreebuffSize < 230) return; } else { //знаем номер инструкции, и будем отправлять пока не более 10 инструкций if (_nowPos > (Controller.INFO.NuberCompleatedInstruction + GlobalSetting.ControllerSetting.MinBuffSize)) return; } int speedToSend = dataRowNow.Machine.SpeedMaсhine; if (checkBoxManualSpeed.Checked) { if (dataRowNow.Machine.NumGkode == 0) speedToSend = (int)numericUpDown1.Value; if (dataRowNow.Machine.NumGkode == 1) speedToSend = (int)numericUpDown2.Value; } //координаты следующей точки float pointX = (float)dataRowNow.POS.X; float pointY = (float)dataRowNow.POS.Y; float pointZ = (float)dataRowNow.POS.Z; //добавление смещения G-кода if (Controller.CorrectionPos.useCorrection) { //// применение пропорций //pointX *= Setting.koeffSizeX; //pointY *= Setting.koeffSizeY; //применение смещения pointX += (float)Controller.CorrectionPos.deltaX; pointY += (float)Controller.CorrectionPos.deltaY; //применение матрицы поверхности детали if (Controller.CorrectionPos.UseMatrix) { pointZ += ScanSurface.GetPosZ(pointX, pointY); } pointZ += (float)Controller.CorrectionPos.deltaZ; } Controller.SendBinaryData(BinaryData.pack_CA(Controller.INFO.CalcPosPulse("X", (decimal)pointX), Controller.INFO.CalcPosPulse("Y", (decimal)pointY), Controller.INFO.CalcPosPulse("Z", (decimal)pointZ), Controller.INFO.CalcPosPulse("A", dataRowNow.POS.A), speedToSend, dataRowNow.numberRow)); //зафиксируем PlanetCNC_Controller.LastStatus = dataRowNow; } if (_nowPos < _endPos) _nowPos++; } }