/// <summary> /// 改变定位信息 /// </summary> /// <param name="station">要改变定位信息的工序列表</param> /// <param name="noOfProcessing">正在信息工序的工序号</param> /// <param name="pointOld">改变前的定位信息</param> /// <param name="typeOfAction">执行的试教动作</param> private static void changePosition(Station station, int noOfProcessing, Point pointOld, DebugAction typeOfAction) { //取得当前点的脉冲 Point _pointNew = Servo.GetPosition(); //根据试教的运动类型选择处理的方式 switch (typeOfAction) { #region DrillIn case DebugAction.DrillIn: //如果是正面和背面,则改变除了Y轴以外的其余轴的绝对定位信息 if (station[noOfProcessing].SideType == SideType.Front || station[noOfProcessing].SideType == SideType.Back) { station[noOfProcessing].IntoPoint.XPulse = _pointNew.XPulse; station[noOfProcessing].StartPoint.XPulse = station[noOfProcessing].IntoPoint.XPulse; station[noOfProcessing].IntoPoint.YPulse = _pointNew.YPulse - pointOld.YPulse + station[noOfProcessing].IntoPoint.YPulse; } //否则改变X轴以外的其余轴的定位信息 else { station[noOfProcessing].IntoPoint.YPulse = _pointNew.YPulse; station[noOfProcessing].StartPoint.YPulse = station[noOfProcessing].IntoPoint.YPulse; station[noOfProcessing].IntoPoint.XPulse = _pointNew.XPulse - pointOld.XPulse + station[noOfProcessing].IntoPoint.XPulse; } station[noOfProcessing].IntoPoint.ZPulse = _pointNew.ZPulse; station[noOfProcessing].IntoPoint.WPulse = _pointNew.WPulse; station[noOfProcessing].StartPoint.ZPulse = station[noOfProcessing].IntoPoint.ZPulse; station[noOfProcessing].StartPoint.WPulse = station[noOfProcessing].IntoPoint.WPulse; break; #endregion #region DrillOut case DebugAction.DrillOut: //如果是正面和背面,则Y轴StartPoint的定位信息 if (station[noOfProcessing].SideType == SideType.Front || station[noOfProcessing].SideType == SideType.Back) { station[noOfProcessing].StartPoint.YPulse = _pointNew.YPulse - pointOld.YPulse + station[noOfProcessing].StartPoint.YPulse; } //否则改变X轴StartPoint的定位信息 else { station[noOfProcessing].StartPoint.XPulse = _pointNew.XPulse - pointOld.XPulse + station[noOfProcessing].StartPoint.XPulse; } break; #endregion #region Cut case DebugAction.Cut: //如果是正面和背面,则改变除了Y轴以外的其.余轴的绝对定位信息 //if (station[noOfProcessing].SideType == SideType.Front || station[noOfProcessing].SideType == SideType.Back) //{ station[noOfProcessing].IntoPoint.XPulse = _pointNew.XPulse; //} ////否则改变X轴以外的其余轴的定位信息 //else //{ station[noOfProcessing].IntoPoint.YPulse = _pointNew.YPulse; //} station[noOfProcessing].IntoPoint.ZPulse = _pointNew.ZPulse; if (noOfProcessing != station.MillNum) { station[noOfProcessing].IntoPoint.WPulse = _pointNew.WPulse; } else { //如果相差超过270度 if (Math.Abs(double.Parse(station[noOfProcessing].IntoPoint.WCodinate) - double.Parse(_pointNew.WCodinate)) > 270) { if (station[noOfProcessing].IntoPoint.WPulse > _pointNew.WPulse) station[noOfProcessing].IntoPoint.WPulse = _pointNew.WPulse + Tool.WPulsePerCircle; else station[noOfProcessing].IntoPoint.WPulse = _pointNew.WPulse - Tool.WPulsePerCircle; station[noOfProcessing].StartPoint.WPulse = station[noOfProcessing].IntoPoint.WPulse; } //如果是正面和背面,则改变除了Y轴以外的其余轴的绝对定位信息 if (station[noOfProcessing].SideType == SideType.Front || station[noOfProcessing].SideType == SideType.Back) { station[noOfProcessing].StartPoint.XPulse = _pointNew.XPulse; } //否则改变X轴以外的其余轴的定位信息 else { station[noOfProcessing].StartPoint.YPulse = _pointNew.YPulse; } //} station[noOfProcessing].StartPoint.ZPulse = _pointNew.ZPulse; } break; #endregion #region DrillCir & DrillRec case DebugAction.MillCir: case DebugAction.MillRec: if (station[noOfProcessing].SideType == SideType.Front || station[noOfProcessing].SideType == SideType.Back) { station[noOfProcessing].IntoPoint.YPulse = _pointNew.YPulse; } else { station[noOfProcessing].IntoPoint.XPulse = _pointNew.XPulse; } break; #endregion case DebugAction.InOutChange: station.InOutChangeHeight = _pointNew.ZPulse; break; case DebugAction.Move: break; } }
/// <summary> /// 开始加工 /// </summary> /// <param name="strVel">初始速度</param> /// <param name="maxVel">最大速度</param> /// <param name="tAcc">加速时间</param> /// <param name="tDec">减速时间</param> private static void Processing(int strVel, int maxVel, double tAcc, double tDec) { try { zSpeedLimit = 150000000; //设启动时间 startTime = DateTime.Now; //开始加工循环时间 DateTime strTime; //如果加工开始事件被订阅,则执行 if (ProcessingStarted != null) { ProcessingStarted(null, new ProcessingStartEventArgs(DateTime.Now)); } //启动加工时间间隔定时器 spanTimer.Start(); //如果正在回原点则等待回原点完成 if (Servo.IsHoming) { while (!Servo.IsHomed) { Thread.Sleep(5); } } int startNo = 0, endNo = CurrentModel.StationNum; //如果是试加工,总是需要回到原点 if (IsTrying) { Servo.HomeBack(new ServoHomeParam()); System.Windows.MessageBox.Show("试教开始"); switch (TryMode) { case TryProcessingMode.OnlyStationOne: MoveToStartPosition(CurrentModel.StationList[0], strVel, maxVel, tAcc, tDec); startNo = 0; endNo = 1; break; case TryProcessingMode.OnlyStationTwo: MoveToStartPosition(CurrentModel.StationList[1], strVel, maxVel, tAcc, tDec); startNo = CurrentModel.StationNum - 1; endNo = CurrentModel.StationNum; break; case TryProcessingMode.TwoStation: MoveToStartPosition(CurrentModel.StationList[0], strVel, maxVel, tAcc, tDec); startNo = 0; endNo = CurrentModel.StationNum; break; } } else { Servo.HomeBack(new ServoHomeParam(ServoHomeMode.ToPoint, CurrentModel.StationList[0][0].StartPoint)); mainWindow.Dispatcher.Invoke(new Action(() => { mainWindow.btnPause.IsEnabled = true; })); MoveToStartPosition(CurrentModel.StationList[0], strVel, maxVel, tAcc, tDec); } while (IsProcessing) { //如果不是试教加工则要根据选择的暂停模式进行暂停 if (!IsTrying) { switch (PauseMode) { case PauseType.No: break; case PauseType.Always: RunStatus = RunStatus.Pause; OneStationCompleted(null, null); waitPause(); break; case PauseType.ByChose: RunStatus = RunStatus.Pause; OneStationCompleted(null, null); waitPause(); if (CurrentModel.StationNum == 2) { if (ChosedStationNo == 0) { startNo = 0; endNo = 1; } else { startNo = 1; endNo = 2; } } break; } } //更新开始时间 strTime = DateTime.Now; for (int stationNo = startNo; stationNo < endNo; stationNo++) { currentStation = CurrentModel.StationList[stationNo]; //执行加工工序 for (int i = 0; i < CurrentModel.StationList[stationNo].MillNum; i++) { //设置正在加工的工序号 currentProcessNo = i; //执行工序 doProcess(CurrentModel.StationList[stationNo][i], strVel, Parameter.maxVel, tAcc, tDec); processChange(CurrentModel.StationList[stationNo], i, strVel, Parameter.maxVel, tAcc, tDec); } //进行切底边 cutBottom(CurrentModel.StationList[stationNo], strVel, Parameter.maxVel, tAcc, tDec); int _nextStationNo = stationNo + 1 == endNo ? startNo : stationNo + 1; //进行工位切换 stationChange(CurrentModel.StationList[stationNo], CurrentModel.StationList[_nextStationNo], strVel, Parameter.maxVel, tAcc, tDec); //已加工数量加1 NumOfProcessed++; mainWindow.Dispatcher.Invoke(new Action(() => { Registry.LocalMachine.CreateSubKey(@"SOFTWARE\CNCMill").SetValue("ProcessedNum", NumOfProcessed); mainWindow.lblProcessedCount.Content = NumOfProcessed; })); new Thread(() => { ushort no = (ushort)(stationNo + 14); RM32.SetPortIO(no, 1); Thread.Sleep(SignalTime * 1000); if (IsProcessing) { RM32.SetPortIO(no, 0); } }).Start(); //如果不是试加工且需要等待 if (OneStationCompleted != null && PauseMode != PauseType.No) { RunStatus = RunStatus.Pause; OneStationCompleted(null, null); } } //计算一个加工循环的耗时 mainWindow.Dispatcher.Invoke(new Action(() => mainWindow.lblLastTime.Content = string.Format("{0,2}:{1,2}", (DateTime.Now - strTime).Minutes, (DateTime.Now - strTime).Seconds))); } } catch (FormatException ex) { Servo.HomeBackEscape(); System.Windows.MessageBox.Show(ex.Message); } }
/// <summary> /// 启动试教监视器 /// </summary> /// <param name="debugMode">试教模式</param> /// <param name="masterNode">调速主轴</param> /// <param name="process">要改变定位信息的工序</param> public static Thread StartDebugMonitor(DebugMode debugMode, ushort masterNode, Station station, int processingNo, DebugAction debugAction) { lock (debugMonitorLock) { //获取用以调速的主轴站号 masterAxisNode = masterNode; //根据选定的模式进行试教 if (debugMode == DebugMode.ModeOne) { debugMonitor = new Thread(debugMonitorHandle); } else { debugMonitor = new Thread(debugMonitorHandle2); } //获取正在加工的工位 debugingStation = station; //获取正在执行的工序号 noOfProcessing = processingNo; //获取正在执行的试教动作 debugingAction = debugAction; //设为后台线程,以使关闭窗口后退出线程 debugMonitor.IsBackground = true; debugMonitor.Priority = ThreadPriority.Highest; debugMonitor.Start(); //指示试教监视器已经启动 IsDebugMonitorStarted = true; return debugMonitor; } }
/// <summary> /// 工序切换 /// </summary> /// <param name="station">当前工位的工序列表</param> /// <param name="n">工序号</param> /// <param name="strVel">初始速度</param> /// <param name="maxVel">最大速度</param> /// <param name="tAcc">加速时间</param> /// <param name="tDec">减速时间</param> private static void processChange(Station station, int n, int strVel, int maxVel, double tAcc, double tDec) { //起始序号 int _startNo = 0; //终止序号 int _stopNo = 0; //获取下一工序起始点坐标 int[] _posArray = station[n + 1].StartPoint.ToArray(); //如果当前工序的内外侧面类型与下一工序的不同,则需要进行内外侧面的切换 if (station[n].IsOutside != station[n + 1].IsOutside) { inOutChange(station, n + 1, strVel, maxVel, tAcc, tDec); } //如果内外侧面的类型相同 else if (station[n].IsOutside) { //如果当前的工序和下一工序的加工面相同,则直接切换,否则需要进行环形运动以切换加工面 if (station[n].SideType != station[n + 1].SideType) { //起始序号 switch (station.MillDirection) { //铣型工序的执行过程为顺时针 case Direction.ClockWise: _startNo = (int)station[n].SideType * 2; if (station[n + 1].SideType > station[n].SideType) //终止序号 _stopNo = (int)station[n + 1].SideType * 2; else _stopNo = _startNo + (4 + (int)station[n + 1].SideType - (int)station[n].SideType) * 2; break; case Direction.CounterClockWise: _startNo = 4 - (int)station[n].SideType == 4 ? 0 : (4 - (int)station[n].SideType) * 2; if (station[n + 1].SideType < station[n].SideType) _stopNo = (4 - (int)station[n + 1].SideType) * 2; else //终止序号 _stopNo = _startNo + (4 - ((int)station[n + 1].SideType - (int)station[n].SideType)) * 2; break; } sideChange(station.CutPointList, station[n], station.MillDirection, _startNo, _stopNo, strVel, maxVel, tAcc, tDec); } waitPause(); if (station[n].SideType == station[n + 1].SideType) { //Point _pointNow = Servo.GetPosition(); //Point _pointNext = station[n + 1].StartPoint.Clone(); //_pointNext.ZPulse = _pointNow.ZPulse; ////先移动xyw,再下降 //DMC.CS_DMC_01_start_ta_move_xyz(ControlCard.CardNo, ref Parameter.xywNodeGroup[0], ref Parameter.slotGroup[0], _posArray[0], _posArray[1], _posArray[3], strVel, // getMaxSpeed(_pointNow, _pointNext, maxVel, CoeTable.ProcessChanging), tAcc, tDec); //waitForDone(Parameter.xywNodeGroup, n + 1, WaitMode.Always, DebugAction.Move); DMC.CS_DMC_01_multi_axes_move(ControlCard.CardNo, (ushort)(Servo.NumOfServo - 1), ref Parameter.nodeGroup[0], ref Parameter.slotGroup[0], ref _posArray[0], strVel, getMaxSpeed(Servo.GetPosition(), station[n + 1].StartPoint, maxVel, CoeTable.ProcessChanging), tAcc, tDec, 1, 1); } else { //经过之前的加工面切换,当前所在加工面已经与下一加工面相同 DMC.CS_DMC_01_multi_axes_move(ControlCard.CardNo, (ushort)(Servo.NumOfServo - 1), ref Parameter.nodeGroup[0], ref Parameter.slotGroup[0], ref _posArray[0], strVel, getMaxSpeed(new Point(station.CutPointList[_stopNo >= 8 ? _stopNo - 8 : _stopNo].XPulse, station.CutPointList[_stopNo >= 8 ? _stopNo - 8 : _stopNo].YPulse, station[n].StartPoint.ZPulse, 0), station[n + 1].StartPoint, maxVel, CoeTable.ProcessChanging), tAcc, tDec, 1, 1); } waitForDone(Parameter.nodeGroup, n + 1, WaitMode.Always, DebugAction.Move); } else { waitPause(); int _speed = 0; if (Math.Abs(Servo.GetPosition().WPulse - station[n + 1].StartPoint.WPulse) > Tool.WPulsePerCircle / 2) { _speed = Math.Abs(Tool.WPulsePerCircle) + 50000000; currentSpeed = _speed; } else { _speed = getMaxSpeed(station[n].StartPoint, station[n + 1].StartPoint, maxVel, CoeTable.ProcessChanging); } //DMC.CS_DMC_01_multi_axes_move(ControlCard.CardNo, (ushort)(Servo.NumOfServo - 1), ref Parameter.nodeGroup[0], // ref Parameter.slotGroup[0], ref _posArray[0], strVel, getMaxSpeed(station[n].StartPoint, station[n + 1].StartPoint, maxVel, CoeTable.ProcessChanging), tAcc, tDec, 1, 1); DMC.CS_DMC_01_multi_axes_move(ControlCard.CardNo, (ushort)(Servo.NumOfServo - 1), ref Parameter.nodeGroup[0], ref Parameter.slotGroup[0], ref _posArray[0], strVel, _speed, tAcc, tDec, 1, 1); waitForDone(Parameter.nodeGroup, n + 1, WaitMode.Always, DebugAction.Move); } }
/// <summary> /// 移动到加工起始点 /// </summary> /// <param name="station">起始工位</param> /// <param name="strVel">初始速度</param> /// <param name="maxVel">最大速度</param> /// <param name="tAcc">加速时间</param> /// <param name="tDec">减速时间</param> private static void MoveToStartPosition(Station station, int strVel, int maxVel, double tAcc, double tDec) { currentStation = station; //如果第一个加工点在内部则需要移动到内部 if (!station[0].IsOutside) { inOutChange(station, 0, strVel, maxVel, tAcc, tDec); } //如果起始点Y方向的坐标小于原点或者起始点位于背面,则先要移动Y轴避免碰撞工件 else if (station[0].StartPoint.YPulse < 0 || station[0].SideType == SideType.Back) { int[] _posArray = station[0].StartPoint.ToArray(); waitPause(); ushort[] _ywNode = { 2, 4 }; ushort[] _ywSlot = { 0, 0 }; DMC.CS_DMC_01_start_ta_move_xy(0, ref _ywNode[0], ref _ywSlot[0], station[0].StartPoint.YPulse, station[0].StartPoint.WPulse, strVel, Parameter.maxVel, 0.1, tDec); currentSpeed = Parameter.maxVel; waitForDone(_ywNode, 0, WaitMode.Always, DebugAction.Move); waitPause(); //移动到第一个加工点的startPoint DMC.CS_DMC_01_multi_axes_move(ControlCard.CardNo, (ushort)(Servo.NumOfServo - 1), ref Parameter.nodeGroup[0], ref Parameter.slotGroup[0], ref _posArray[0], strVel, getMaxSpeed(Servo.GetPosition(), station[0].StartPoint, Parameter.maxVel, CoeTable.ProcessChanging), tAcc, tDec, 1, 1); //等待动作完成 } else { int[] _posArray = station[0].StartPoint.ToArray(); waitPause(); //移动到第一个加工点的startPoint DMC.CS_DMC_01_multi_axes_move(ControlCard.CardNo, (ushort)(Servo.NumOfServo - 1), ref Parameter.nodeGroup[0], ref Parameter.slotGroup[0], ref _posArray[0], strVel, getMaxSpeed(Servo.GetPosition(), station[0].StartPoint, Parameter.maxVel, CoeTable.ProcessChanging), tAcc, tDec, 1, 1); } waitForDone(Parameter.nodeGroup, 0, WaitMode.Always, DebugAction.Move); }
/// <summary> /// 内外侧面切换动作 /// </summary> /// <param name="station">移入或移出的工位</param> /// <param name="nextNo">下一工序的工序号</param> /// <param name="strVel">起始速度</param> /// <param name="maxVel">最大速度</param> /// <param name="tAcc">加速时间</param> /// <param name="tDec">减速时间</param> private static void inOutChange(Station station, int nextNo, int strVel, int maxVel, double tAcc, double tDec) { //先移动到内外侧面的切换高度 waitPause(); //获取合理的最大速度 int _speedTemp = getMaxSpeed(maxVel, CoeTable.ProcessChanging) > zSpeedLimit ? zSpeedLimit : getMaxSpeed(maxVel, CoeTable.ProcessChanging); currentSpeed = _speedTemp; //移动到一定高度 DMC.CS_DMC_01_start_ta_move(ControlCard.CardNo, 3, 0, station.InOutChangeHeight, strVel, currentSpeed, tAcc, tDec); waitForDone(new ushort[] { 3 }, nextNo, WaitMode.Always, DebugAction.Move); waitPause(); //内外侧加工面切换 DMC.CS_DMC_01_start_ta_move_xyz(ControlCard.CardNo, ref Parameter.xywNodeGroup[0], ref Parameter.slotGroup[0], station[nextNo].StartPoint.XPulse, station[nextNo].StartPoint.YPulse, station[nextNo].StartPoint.WPulse, strVel, getMaxSpeed(maxVel, CoeTable.ProcessChanging), tAcc, tDec); waitForDone(Parameter.xywNodeGroup, nextNo, WaitMode.Always, DebugAction.InOutChange); //移动到起始点 waitPause(); currentSpeed = _speedTemp; DMC.CS_DMC_01_start_ta_move(ControlCard.CardNo, 3, 0, station[nextNo].StartPoint.ZPulse, strVel, currentSpeed, tAcc, tDec); waitForDone(new ushort[] { 3 }, nextNo, WaitMode.Always, DebugAction.Move); }
/// <summary> /// 切除底边动作 /// </summary> /// <param name="station">工序列表</param> /// <param name="strVel">起始速度</param> /// <param name="maxVel">最大速度</param> /// <param name="tAcc">加速时间</param> /// <param name="tDec">减速时间</param> private static void cutBottom(Station station, int strVel, int maxVel, double tAcc, double tDec) { zSpeedLimit = 20000000; short rc = 0; //station.DrillNum就是第一个切边点的索引号 //当前工序号与下一工序号 int iNext, iNow; //铣入一定深度 waitPause(); rc = DMC.CS_DMC_01_start_ta_move_xy(ControlCard.CardNo, ref Parameter.xyNodeGroup[0], ref Parameter.slotGroup[0], station[station.MillNum].IntoPoint.XPulse, station[station.MillNum].IntoPoint.YPulse, strVel, getMaxSpeed(maxVel, CoeTable.DrillingIn), tAcc, tDec); waitForDone(Parameter.xyNodeGroup, station.MillNum, WaitMode.Always, DebugAction.DrillIn); //开始执行切边,由第一个切边点开始到最后一个切边点 for (iNow = station.MillNum; iNow < station.ProcessNum; iNow++) { //确保缓冲区内没有超过20个未执行命令 ushort length = 0; do { DMC.CS_DMC_01_get_buffer_length(ControlCard.CardNo, 1, 0, ref length); Thread.Sleep(50); } while (length > 15); //如果当前的工序号小于最后一个切边点的加工序号 if (iNow < station.ProcessNum - 1) iNext = iNow + 1; else iNext = station.MillNum; //如果当前的加工面与下一个加工面不同,则要切换加工面 if (station[iNow].SideType != station[iNext].SideType) { //转动的脉冲值 int anglePulse; //圆心坐标 int[] centerPulse = getCenterPulse(station[iNow].IntoPoint, station[iNext].IntoPoint, out anglePulse); //xy轴圆周运动,w轴做切线追随运动,到达下一点 waitPause(); do { rc = DMC.CS_DMC_01_start_tr_heli_xy(ControlCard.CardNo, ref Parameter.xywNodeGroup[0], ref Parameter.slotGroup[0], centerPulse[0] - station[iNow].IntoPoint.XPulse, centerPulse[1] - station[iNow].IntoPoint.YPulse, anglePulse, Tool.WPulsePerCircle, (short)station.CutDirection, strVel, getMaxSpeed(maxVel == 1 ? maxVel : maxVel, CoeTable.CuttingArc), tAcc, tDec); if (rc != 0) { Thread.Sleep(10); } } while (rc != 0); waitForDone(Parameter.xyNodeGroup, iNext, WaitMode.OnlyDebug, DebugAction.Cut); } else { //否则直接移动到下一点,注意这里W轴也随之运动 waitPause(); if (station.CutNum > 8) { int[] _posDisarr = station[iNext].IntoPoint.ToArray(); while (_posDisarr[3] - station[iNow].IntoPoint.WPulse > Tool.WPulsePerCircle / 2) { _posDisarr[3] -= Tool.WPulsePerCircle; } while (_posDisarr[3] - station[iNow].IntoPoint.WPulse < -Tool.WPulsePerCircle / 2) { _posDisarr[3] += Tool.WPulsePerCircle; } do { rc = DMC.CS_DMC_01_multi_axes_move(ControlCard.CardNo, (ushort)(Servo.NumOfServo - 1), ref Parameter.nodeGroup[0], ref Parameter.slotGroup[0], ref _posDisarr[0], strVel, getMaxSpeed(station[iNow].IntoPoint, station[iNext].IntoPoint, maxVel, CoeTable.CuttingLine), tAcc, tDec, 1, 1); if (rc != 0) { Thread.Sleep(10); } } while (rc != 0); } else { int posWint = station[iNext].IntoPoint.WPulse; while (posWint - station[iNow].IntoPoint.WPulse > Tool.WPulsePerCircle / 2) { posWint -= Tool.WPulsePerCircle; } while (posWint - station[iNow].IntoPoint.WPulse < -Tool.WPulsePerCircle / 2) { posWint += Tool.WPulsePerCircle; } rc = DMC.CS_DMC_01_start_ta_move_xyz(ControlCard.CardNo, ref Parameter.xywNodeGroup[0], ref Servo.SlotID[0], station[iNext].IntoPoint.XPulse, station[iNext].IntoPoint.YPulse, posWint, strVel, getMaxSpeed(maxVel, CoeTable.CuttingLine), tAcc, tDec); } waitForDone(Parameter.xyNodeGroup, iNext, WaitMode.OnlyDebug, DebugAction.Cut); } } waitForDone(Parameter.xyNodeGroup, station.MillNum, WaitMode.Always, DebugAction.Move); //退刀 waitPause(); rc = DMC.CS_DMC_01_start_ta_move_xy(ControlCard.CardNo, ref Parameter.xyNodeGroup[0], ref Parameter.slotGroup[0], station[station.MillNum].StartPoint.XPulse, station[station.MillNum].StartPoint.YPulse, strVel, getMaxSpeed(maxVel, CoeTable.DrillingOut), tAcc, tDec); waitForDone(Parameter.xyNodeGroup, station.MillNum, WaitMode.Always, DebugAction.DrillOut); zSpeedLimit = 150000000; }
/// <summary> /// 进行工位的切换 /// </summary> /// <param name="stationNow">当前工位</param> /// <param name="stationNext">下一个工位</param> /// <param name="sideOne"></param> /// <param name="sideTwo"></param> /// <param name="strVel">初始速度</param> /// <param name="maxVel">最大速度</param> /// <param name="tAcc">加速时间</param> /// <param name="tDec">减速时间</param> private static void stationChange(Station stationNow, Station stationNext, int strVel, int maxVel, double tAcc, double tDec) { if (CurrentModel.Name.Last().Equals('X')) { //先移动到内外侧面的切换高度 waitPause(); //获取合理的最大速度 int _speedTemp = getMaxSpeed(maxVel, CoeTable.ProcessChanging) > zSpeedLimit ? zSpeedLimit : getMaxSpeed(maxVel, CoeTable.ProcessChanging); currentSpeed = _speedTemp; //移动到一定高度 DMC.CS_DMC_01_start_ta_move(ControlCard.CardNo, 3, 0, (stationNext[0].StartPoint.ZPulse + Servo.GetPosition().ZPulse) / 2, strVel, currentSpeed, tAcc, tDec); waitForDone(new ushort[] { 3 }, 0, WaitMode.Always, DebugAction.Move); } //如果下一工位的第一道工序在工件内部,则进行内外侧面的切换 if (!stationNext[0].IsOutside) { inOutChange(stationNext, 0, strVel, maxVel, tAcc, tDec); } else { //如果存在两个工位,则两个工位的靠近面 SideType sideTwo = SideType.Front, sideOne = SideType.Front; if (stationNow.Number < stationNext.Number) { sideOne = SideType.Right; sideTwo = SideType.Left; } else if (stationNow.Number > stationNext.Number) { sideOne = SideType.Left; sideTwo = SideType.Right; } short rc = 0; int nNow = stationNow.MillNum; int[] _posArray = stationNext[0].StartPoint.ToArray(); waitPause(); //当前工位的首个切边点为正(背)面且下一个工位的第一道工序为正(背)面,或者为相邻的两个面 if ((stationNow[nNow].SideType == SideType.Front && stationNext[0].SideType == SideType.Front) || (stationNow[nNow].SideType == SideType.Back && stationNext[0].SideType == SideType.Back)) { //直接移动到第一个加工点的startPoint rc = DMC.CS_DMC_01_multi_axes_move(ControlCard.CardNo, (ushort)(Servo.NumOfServo - 1), ref Parameter.nodeGroup[0], ref Parameter.slotGroup[0], ref _posArray[0], strVel, getMaxSpeed(Servo.GetPosition(), stationNext[0].StartPoint, maxVel, CoeTable.StationChanging), tAcc, tDec, 1, 1); } else if (stationNow[nNow].SideType == sideOne && stationNext[0].SideType == sideTwo) { //移动到第一个加工点的startPoint rc = DMC.CS_DMC_01_multi_axes_move(ControlCard.CardNo, (ushort)(Servo.NumOfServo - 1), ref Parameter.nodeGroup[0], ref Parameter.slotGroup[0], ref _posArray[0], strVel, getMaxSpeed(Servo.GetPosition(), stationNext[0].StartPoint, maxVel, CoeTable.StationChanging), tAcc, tDec, 1, 1); } //如果当前工位的首个切边点为正面或者背面,且下一个工位的第一道工序为左侧面或者右侧面 else if ((stationNow[nNow].SideType == SideType.Front || stationNow[nNow].SideType == SideType.Back) && (stationNext[0].SideType == SideType.Left || stationNext[0].SideType == SideType.Right)) { //先移动x轴到下一工位第一道工序起始点的x轴位置 rc = DMC.CS_DMC_01_start_ta_move_xy(ControlCard.CardNo, ref Parameter.xyNodeGroup[0], ref Parameter.slotGroup[0], stationNext[0].StartPoint.XPulse, stationNow[nNow].StartPoint.YPulse, strVel, getMaxSpeed(maxVel, CoeTable.StationChanging), tAcc, tDec); waitForDone(Parameter.xyNodeGroup, currentProcessNo, WaitMode.Always, DebugAction.Move); //移动到第一个加工点的startPoint waitPause(); rc = DMC.CS_DMC_01_multi_axes_move(ControlCard.CardNo, (ushort)(Servo.NumOfServo - 1), ref Parameter.nodeGroup[0], ref Parameter.slotGroup[0], ref _posArray[0], strVel, getMaxSpeed(Servo.GetPosition(), stationNext[0].StartPoint, maxVel, CoeTable.StationChanging), tAcc, tDec, 1, 1); } //当前工位的首个切边点为左侧面或为右侧面 else if (stationNow[nNow].SideType == SideType.Left || stationNow[nNow].SideType == SideType.Right) { //下一工位的第一道工序为正面或者背面 if ((stationNext[0].SideType == SideType.Front || stationNext[0].SideType == SideType.Back)) { //先移动y轴到下一工位第一道工序起始点的y轴位置 rc = DMC.CS_DMC_01_start_ta_move_xy(ControlCard.CardNo, ref Parameter.xyNodeGroup[0], ref Parameter.slotGroup[0], stationNow[nNow].StartPoint.XPulse, stationNext[0].StartPoint.YPulse, strVel, getMaxSpeed(maxVel, CoeTable.StationChanging), tAcc, tDec); waitForDone(Parameter.xyNodeGroup, currentProcessNo, WaitMode.Always, DebugAction.Move); //移动到第一个加工点的startPoint waitPause(); rc = DMC.CS_DMC_01_multi_axes_move(ControlCard.CardNo, (ushort)(Servo.NumOfServo - 1), ref Parameter.nodeGroup[0], ref Parameter.slotGroup[0], ref _posArray[0], strVel, getMaxSpeed(Servo.GetPosition(), stationNext[0].StartPoint, maxVel, CoeTable.StationChanging), tAcc, tDec, 1, 1); } //下一工位的第一道工序为sideTwo else if (stationNext[0].SideType == sideOne) { //先移动到下一工位第一道工序的Y轴位置 rc = DMC.CS_DMC_01_start_ta_move_xy(ControlCard.CardNo, ref Parameter.xyNodeGroup[0], ref Parameter.slotGroup[0], stationNow[nNow].StartPoint.XPulse, stationNext[0].StartPoint.YPulse, strVel, getMaxSpeed(maxVel, CoeTable.StationChanging), tAcc, tDec); waitForDone(Parameter.xyNodeGroup, currentProcessNo, WaitMode.Always, DebugAction.Move); waitPause(); //再移动到下一工位第一道工序的X轴位置 rc = DMC.CS_DMC_01_start_ta_move_xy(ControlCard.CardNo, ref Parameter.xyNodeGroup[0], ref Parameter.slotGroup[0], stationNext[0].StartPoint.XPulse, stationNext[0].StartPoint.YPulse, strVel, getMaxSpeed(maxVel, CoeTable.StationChanging), tAcc, tDec); waitForDone(Parameter.xyNodeGroup, currentProcessNo, WaitMode.Always, DebugAction.Move); //移动到第一个加工点的startPoint waitPause(); rc = DMC.CS_DMC_01_multi_axes_move(ControlCard.CardNo, (ushort)(Servo.NumOfServo - 1), ref Parameter.nodeGroup[0], ref Parameter.slotGroup[0], ref _posArray[0], strVel, getMaxSpeed(Servo.GetPosition(), stationNext[0].StartPoint, maxVel, CoeTable.StationChanging), tAcc, tDec, 1, 1); } } else { System.Windows.MessageBox.Show("未能找到有效的工位切换路径,请暂停加工并重新定位"); } waitForDone(Parameter.nodeGroup, currentProcessNo, WaitMode.Always, DebugAction.Move); } }