537 lines
20 KiB
C#
537 lines
20 KiB
C#
using MainShell.Common;
|
||
using MainShell.DeviceMaintance.Model;
|
||
using MainShell.Hardware;
|
||
using MainShell.Log;
|
||
using MainShell.Models;
|
||
using MainShell.Motion;
|
||
using MainShell.Parameter;
|
||
using MaxwellControl.Tools;
|
||
using MaxwellFramework.Core.Interfaces;
|
||
using MwFramework.ManagerService;
|
||
using Stylet;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
using System.Windows;
|
||
using System.Windows.Controls;
|
||
|
||
namespace MainShell.DeviceMaintance.ViewModel
|
||
{
|
||
public class NeedleCameraPrintViewModel : DeviceMaintanceBaseViewModel
|
||
{
|
||
private NeedlePrintCalibrateSetting _needlePrintCalibrateSetting;
|
||
private readonly IParamList _paramList;
|
||
private readonly HardwareManager _device;
|
||
private readonly SafeAxisMotion _safeMotion;
|
||
private readonly GlobalParameterContext _globalParam;
|
||
private CancellationTokenSource _cancellationTokenSource;
|
||
private List<Point> _workPos;
|
||
private readonly double _z1Speed = 70;
|
||
private MaintanceRecord maintanceRecord;
|
||
|
||
private ParameterHelper _parameterHelper = new ParameterHelper();
|
||
public ParameterHelper ParameterHelper
|
||
{
|
||
get
|
||
{
|
||
return _parameterHelper;
|
||
}
|
||
set
|
||
{
|
||
_parameterHelper = value;
|
||
OnPropertyChanged(nameof(ParameterHelper));
|
||
}
|
||
}
|
||
|
||
private MPoint _cameraPoint;
|
||
|
||
public MPoint CameraPoint
|
||
{
|
||
get { return _cameraPoint; }
|
||
set { SetAndNotify(ref _cameraPoint, value); }
|
||
}
|
||
|
||
private MPoint _currentNeedlePoint;
|
||
|
||
public MPoint CurrentNeedlePoint
|
||
{
|
||
get { return _currentNeedlePoint; }
|
||
set { SetAndNotify(ref _currentNeedlePoint, value); }
|
||
}
|
||
|
||
private MPoint _currentNeedleOffsetPoint;
|
||
|
||
public MPoint CurrentNeedleOffsetPoint
|
||
{
|
||
get { return _currentNeedleOffsetPoint; }
|
||
set { SetAndNotify(ref _currentNeedleOffsetPoint, value); }
|
||
}
|
||
|
||
|
||
private NeedlePrintCalibrateParameter _needlePrintCalibrateParameter;
|
||
|
||
public NeedlePrintCalibrateParameter NeedlePrintCalibrateParameter
|
||
{
|
||
get { return _needlePrintCalibrateParameter; }
|
||
set { SetAndNotify(ref _needlePrintCalibrateParameter, value); }
|
||
}
|
||
|
||
private bool _uiEnable = true;
|
||
|
||
public bool UiEnable
|
||
{
|
||
get { return _uiEnable; }
|
||
set
|
||
{
|
||
if (SetAndNotify(ref _uiEnable, value))
|
||
{
|
||
OnUiStateChanged(value);
|
||
}
|
||
}
|
||
}
|
||
|
||
/*
|
||
|
||
public NeedleCameraPrintViewModel(IParameterManager parameterManager, GlobalParam globalParam, HardwareManager hardwareManager, SafeAxisMotion safeAxisMotion)
|
||
{
|
||
_currentNeedleOffsetPoint = new MPoint();
|
||
CurrentNeedlePoint = new MPoint();
|
||
_cameraPoint = new MPoint();
|
||
_workPos = new List<Point>();
|
||
_device = hardwareManager;
|
||
_safeMotion = safeAxisMotion;
|
||
_globalParam = globalParam;
|
||
_paramList = parameterManager as IParamList;
|
||
_needlePrintCalibrateSetting = _globalParam.NeedlePrintCalibrateSetting;
|
||
_needlePrintCalibrateParameter = _needlePrintCalibrateSetting.NeedlePrintCalibrateParameter;
|
||
SetSpeed(50);
|
||
CalculteWorkPos();
|
||
maintanceRecord = new MaintanceRecord()
|
||
{
|
||
DeviceId = LogManager.MachineID,
|
||
MaintanceType = MaintanceType.针印验证,
|
||
};
|
||
}
|
||
protected override void OnViewLoaded()
|
||
{
|
||
base.OnViewLoaded();
|
||
NeedlePrintCalibrateParameter = _needlePrintCalibrateSetting.NeedlePrintCalibrateParameter;
|
||
var needleCalibrationSetting = _globalParam.NeedleCalibrationSetting;
|
||
CurrentNeedleOffsetPoint.X = needleCalibrationSetting.NeedleXYCalibrationItem.OffsetX;
|
||
CurrentNeedleOffsetPoint.Y = needleCalibrationSetting.NeedleXYCalibrationItem.OffsetY;
|
||
}
|
||
public void SpeedChanged(object sender, EventArgs eventArgs)
|
||
{
|
||
if (sender is RadioButton radioButton)
|
||
{
|
||
if (radioButton.Tag != null)
|
||
{
|
||
var speed = Convert.ToInt32(radioButton.Tag);
|
||
SetSpeed(speed);
|
||
}
|
||
|
||
}
|
||
}
|
||
private void SetSpeed(double speed)
|
||
{
|
||
_safeMotion.SetAxisSpeed(_device.Axis_X1, speed);
|
||
_safeMotion.SetAxisSpeed(_device.Axis_Y1, speed);
|
||
_safeMotion.SetAxisSpeed(_device.Axis_X2, speed);
|
||
_safeMotion.SetAxisSpeed(_device.Axis_Y2, speed);
|
||
_safeMotion.SetAxisSpeed(_device.Axis_Z1, _z1Speed);
|
||
}
|
||
public void MoveToOrginPos()
|
||
{
|
||
CommonUti.RunOnUi(() =>
|
||
{
|
||
MoveOrgin();
|
||
});
|
||
}
|
||
public void TeachWSPos()
|
||
{
|
||
CommonUti.RunOnUi(() =>
|
||
{
|
||
NeedlePrintCalibrateParameter.AvoidancePoint.X = _device.Axis_X2.GetPositionImmediate();
|
||
NeedlePrintCalibrateParameter.AvoidancePoint.Y = _device.Axis_Y2.GetPositionImmediate();
|
||
});
|
||
}
|
||
public void MoveToWsPos()
|
||
{
|
||
CommonUti.RunOnUi(() =>
|
||
{
|
||
MoveAvoidancePos();
|
||
});
|
||
}
|
||
public void TeachZ1Pos()
|
||
{
|
||
CommonUti.RunOnUi(() =>
|
||
{
|
||
NeedlePrintCalibrateParameter.Z1WorkHeight = _device.Axis_Z1.GetPositionImmediate();
|
||
});
|
||
}
|
||
public void MoveToZ1Pos()
|
||
{
|
||
CommonUti.RunOnUi(() =>
|
||
{
|
||
MoveZ1Pos();
|
||
});
|
||
}
|
||
public void TeachZ2Pos()
|
||
{
|
||
CommonUti.RunOnUi(() =>
|
||
{
|
||
NeedlePrintCalibrateParameter.Z2WorkHeight = _device.Axis_Z2.GetPositionImmediate();
|
||
});
|
||
}
|
||
public void MoveToZ2Pos()
|
||
{
|
||
CommonUti.RunOnUi(() =>
|
||
{
|
||
MoveZ2Pos();
|
||
});
|
||
}
|
||
public void TeachStartPos()
|
||
{
|
||
CommonUti.RunOnUi(() =>
|
||
{
|
||
NeedlePrintCalibrateParameter.StartPoint.X = _device.Axis_X1.GetPositionImmediate();
|
||
NeedlePrintCalibrateParameter.StartPoint.Y = _device.Axis_Y1.GetPositionImmediate();
|
||
});
|
||
}
|
||
|
||
public void MoveToStartPos()
|
||
{
|
||
CommonUti.RunOnUi(() =>
|
||
{
|
||
_safeMotion.MoveAxis(new AxisPos
|
||
{
|
||
Axis = _device.Axis_X11,
|
||
Pos = NeedlePrintCalibrateParameter.StartPoint.PointX
|
||
}, new AxisPos
|
||
{
|
||
Axis = _device.Axis_Y11,
|
||
Pos = NeedlePrintCalibrateParameter.StartPoint.PointY
|
||
});
|
||
});
|
||
}
|
||
public void TeachEndPos()
|
||
{
|
||
CommonUti.RunOnUi(() =>
|
||
{
|
||
NeedlePrintCalibrateParameter.EndPoint.X = _device.Axis_X1.GetPositionImmediate();
|
||
NeedlePrintCalibrateParameter.EndPoint.Y = _device.Axis_Y1.GetPositionImmediate();
|
||
});
|
||
}
|
||
public void MoveToEndPos()
|
||
{
|
||
CommonUti.RunOnUi(() =>
|
||
{
|
||
_safeMotion.SafeMove(new MotionData
|
||
{
|
||
Name = "X1",
|
||
TargetPosition = NeedlePrintCalibrateParameter.EndPoint.X
|
||
}, new MotionData
|
||
{
|
||
Name = "y1",
|
||
TargetPosition = NeedlePrintCalibrateParameter.EndPoint.Y
|
||
});
|
||
});
|
||
}
|
||
private void MoveOrgin()
|
||
{
|
||
_safeMotion.SafeMoveAxis(new AxisPos
|
||
{
|
||
Axis = _device.Axis_CY,
|
||
Pos = 0
|
||
}, new AxisPos
|
||
{
|
||
Axis = _device.Axis_CZ,
|
||
Pos = 0
|
||
});
|
||
}
|
||
private void MoveAvoidancePos()
|
||
{
|
||
_safeMotion.MoveAxis(new AxisPos
|
||
{
|
||
Axis = _device.Axis_X21,
|
||
Pos = NeedlePrintCalibrateParameter.AvoidancePoint.PointX
|
||
}, new AxisPos
|
||
{
|
||
Axis = _device.Axis_Y21,
|
||
Pos = NeedlePrintCalibrateParameter.AvoidancePoint.PointY
|
||
});
|
||
}
|
||
private void MoveZ1Pos()
|
||
{
|
||
_safeMotion.MoveAxis(new AxisPos
|
||
{
|
||
Axis = _device.Axis_Z1,
|
||
Pos = NeedlePrintCalibrateParameter.Z1WorkHeight
|
||
});
|
||
}
|
||
private void MoveZ2Pos()
|
||
{
|
||
_safeMotion.MoveAxis(new AxisPos
|
||
{
|
||
Axis = _device.Axis_Z2,
|
||
Pos = NeedlePrintCalibrateParameter.Z2WorkHeight
|
||
});
|
||
}
|
||
private void MoveAvoidanceAndWorkPos(Point workP)
|
||
{
|
||
_safeMotion.MoveAxis(new AxisPos
|
||
{
|
||
Axis = _device.Axis_X21,
|
||
Pos = NeedlePrintCalibrateParameter.AvoidancePoint.PointX
|
||
}, new AxisPos
|
||
{
|
||
Axis = _device.Axis_Y21,
|
||
Pos = NeedlePrintCalibrateParameter.AvoidancePoint.PointY
|
||
}, new AxisPos
|
||
{
|
||
Axis = _device.Axis_X11,
|
||
Pos = workP.X
|
||
}, new AxisPos
|
||
{
|
||
Axis = _device.Axis_Y11,
|
||
Pos = workP.Y
|
||
});
|
||
}
|
||
public void StartVerify()
|
||
{
|
||
CommonUti.RunOnUi(() =>
|
||
{
|
||
InitCancelToken();
|
||
if (_workPos.Count == 0)
|
||
{
|
||
MaxwellControl.Controls.MessageBox.Show("无法计算有效的下扎点,请检查铜箔示教的起始点坐标");
|
||
return;
|
||
}
|
||
if (_workPos.Count <= NeedlePrintCalibrateParameter.UsedNum)
|
||
{
|
||
MaxwellControl.Controls.MessageBox.Show("当前铜箔已用完,请确认是否需要更换");
|
||
}
|
||
IoC.Get<IProjectManager>().EnablePageAndDisableOther("刺晶头校正");
|
||
VisionParData visionParData = new VisionParData
|
||
{
|
||
LightSourceBack = 0,
|
||
LightSourceRingBlue = 255,
|
||
LightSourcePointBlue = 255,
|
||
LightSourcePointRed = 255,
|
||
LightSourceRingRed = 255,
|
||
};
|
||
_safeMotion.MoveZToEscape();
|
||
visionParData.SetLightData();
|
||
CheckCancel();
|
||
var workPoint = _workPos[NeedlePrintCalibrateParameter.UsedNum];
|
||
CurrentNeedlePoint.PointX = workPoint.X;
|
||
CurrentNeedlePoint.PointY = workPoint.Y;
|
||
MoveOrgin();
|
||
MoveAvoidanceAndWorkPos(workPoint);
|
||
MoveZ1Pos();
|
||
CheckCancel();
|
||
Thread.Sleep(NeedlePrintCalibrateParameter.SleepTime);
|
||
_safeMotion.Z1MoveToEscape();
|
||
CheckCancel();
|
||
var cameraPoint = IoC.Get<VisionOperation>().GetCameraRulerPointByRulerNeedle(new Point(_device.Axis_X11.GetPositionImmediate(), _device.Axis_Y11.GetPositionImmediate()));
|
||
_safeMotion.SafeMoveAxis(new AxisPos
|
||
{
|
||
Axis = _device.Axis_X11,
|
||
Pos = cameraPoint.X
|
||
}, new AxisPos
|
||
{
|
||
Axis = _device.Axis_Y11,
|
||
Pos = cameraPoint.Y
|
||
});
|
||
MoveZ2Pos();
|
||
NeedlePrintCalibrateParameter.UsedNum++;
|
||
_needlePrintCalibrateSetting.Write();
|
||
}, exceptionHandler: ex =>
|
||
{
|
||
_safeMotion.MoveZToEscape();
|
||
CommonUti.ShowMessageBox(ex);
|
||
}, begainAction: () =>
|
||
{
|
||
UiEnable = false;
|
||
}, afterAction: () =>
|
||
{
|
||
UiEnable = true;
|
||
IoC.Get<IProjectManager>().SwitchState();
|
||
});
|
||
}
|
||
|
||
private void InitCancelToken()
|
||
{
|
||
if (_cancellationTokenSource != null)
|
||
{
|
||
_cancellationTokenSource.Cancel();
|
||
_cancellationTokenSource.Dispose();
|
||
}
|
||
_cancellationTokenSource = new CancellationTokenSource();
|
||
}
|
||
|
||
private void CheckCancel()
|
||
{
|
||
_cancellationTokenSource.Token.ThrowIfCancellationRequested();
|
||
}
|
||
public void StopVerify()
|
||
{
|
||
_cancellationTokenSource?.Cancel();
|
||
IoC.Get<CancelSourceManager>().CancelMotionAndCheck();
|
||
IoC.Get<GlobalDeviceService>().StopMainAxis();
|
||
}
|
||
|
||
public void void NeedleAlignment()
|
||
{
|
||
CommonUti.RunOnUi(() =>
|
||
{
|
||
var needlePoint = IoC.Get<VisionOperation>().GetNeedleRulerPointByRulerCamera(new Point(_device.Axis_X11.GetPositionImmediate(), _device.Axis_Y11.GetPositionImmediate()));
|
||
_safeMotion.SafeMoveAxis(new AxisPos
|
||
{
|
||
Axis = _device.Axis_X11,
|
||
Pos = needlePoint.X
|
||
}, new AxisPos
|
||
{
|
||
Axis = _device.Axis_Y11,
|
||
Pos = needlePoint.Y
|
||
});
|
||
});
|
||
}
|
||
public void void CameraAlignment()
|
||
{
|
||
CommonUti.RunOnUi(() =>
|
||
{
|
||
var cameraPoint = IoC.Get<VisionOperation>().GetCameraRulerPointByRulerNeedle(new Point(_device.Axis_X11.GetPositionImmediate(), _device.Axis_Y11.GetPositionImmediate()));
|
||
_safeMotion.SafeMoveAxis(new AxisPos
|
||
{
|
||
Axis = _device.Axis_X11,
|
||
Pos = cameraPoint.X
|
||
}, new AxisPos
|
||
{
|
||
Axis = _device.Axis_Y11,
|
||
Pos = cameraPoint.Y
|
||
});
|
||
});
|
||
}
|
||
public void SaveParam()
|
||
{
|
||
CommonUti.RunOnUi(() =>
|
||
{
|
||
CalculteWorkPos();
|
||
if (_workPos.Count == 0)
|
||
{
|
||
MaxwellControl.Controls.MessageBox.Show("无法计算有效的下扎点,请检查铜箔示教的起始点坐标");
|
||
return;
|
||
}
|
||
_needlePrintCalibrateSetting.Write();
|
||
Application.Current.Dispatcher.Invoke(() =>
|
||
{
|
||
ParameterHelper.RaiseValueAccept();
|
||
});
|
||
MaxwellControl.Controls.MessageBox.Show("操作成功");
|
||
});
|
||
|
||
}
|
||
|
||
public void ResetRecord()
|
||
{
|
||
NeedlePrintCalibrateParameter.UsedNum = 0;
|
||
SaveParam();
|
||
}
|
||
|
||
public void TeachCameraPos()
|
||
{
|
||
CameraPoint.PointX = _device.Axis_X11.GetPositionImmediate();
|
||
CameraPoint.PointY = _device.Axis_Y11.GetPositionImmediate();
|
||
}
|
||
public void CalculateOffset()
|
||
{
|
||
CommonUti.RunOnUi(() =>
|
||
{
|
||
if (CameraPoint.PointX == 0 || CameraPoint.PointY == 0 || CurrentNeedlePoint.PointX == 0 || CurrentNeedlePoint.PointY == 0)
|
||
{
|
||
MaxwellControl.Controls.MessageBox.Show("请先示教相机位置和针尖位置");
|
||
return;
|
||
}
|
||
List<Point> cameraRealPointList = new List<Point>();
|
||
List<Point> needleRealPointList = new List<Point>();
|
||
VisionOperation visionOperation = IoC.Get<VisionOperation>();
|
||
|
||
Point cameraPointReal = visionOperation.GetRealByRuler(_device.Camera_Extend.Id, new Point(CameraPoint.PointX, CameraPoint.PointY));
|
||
Point needlePointReal = visionOperation.GetRealByRuler(_device.Camera_Extend.Id, new Point(CurrentNeedlePoint.PointX, CurrentNeedlePoint.PointY));
|
||
var needleCalibrationSetting = _paramList.GetParameter<NeedleCalibrationSetting>();
|
||
needleCalibrationSetting.NeedleXYCalibrationItem.InitialOffsetX = needlePointReal.X - cameraPointReal.X;
|
||
needleCalibrationSetting.NeedleXYCalibrationItem.InitialOffsetY = needlePointReal.Y - cameraPointReal.Y;
|
||
var offsetX = needleCalibrationSetting.NeedleXYCalibrationItem.OffsetX - needleCalibrationSetting.NeedleXYCalibrationItem.InitialOffsetX;
|
||
var offsetY = needleCalibrationSetting.NeedleXYCalibrationItem.OffsetY - needleCalibrationSetting.NeedleXYCalibrationItem.InitialOffsetY;
|
||
if (Math.Abs(offsetY) >= 2 || Math.Abs(offsetX) > 2.5)
|
||
{
|
||
MaxwellControl.Controls.MessageBox.Show("当前相机与针尖偏差过大,请重新校准!");
|
||
return;
|
||
}
|
||
needleCalibrationSetting.NeedleXYCalibrationItem.OffsetX = needleCalibrationSetting.NeedleXYCalibrationItem.CompensateX + needleCalibrationSetting.NeedleXYCalibrationItem.InitialOffsetX;
|
||
needleCalibrationSetting.NeedleXYCalibrationItem.OffsetY = needleCalibrationSetting.NeedleXYCalibrationItem.CompensateY + needleCalibrationSetting.NeedleXYCalibrationItem.InitialOffsetY;
|
||
|
||
CurrentNeedleOffsetPoint.PointX = needleCalibrationSetting.NeedleXYCalibrationItem.OffsetX;
|
||
CurrentNeedleOffsetPoint.PointY = needleCalibrationSetting.NeedleXYCalibrationItem.OffsetY;
|
||
|
||
EquipmentParaSysSetting equipmentParaSysSetting = _paramList.GetParameter<EquipmentParaSysSetting>();
|
||
equipmentParaSysSetting.SafeParaSysItem.NeedleCameraOffsetX = needleCalibrationSetting.NeedleXYCalibrationItem.OffsetX;
|
||
equipmentParaSysSetting.SafeParaSysItem.NeedleCameraOffsetY = needleCalibrationSetting.NeedleXYCalibrationItem.OffsetY;
|
||
equipmentParaSysSetting.Write();
|
||
needleCalibrationSetting.Write();
|
||
maintanceRecord.WriteToFile($"当前相机与针尖与上次偏差 X:{offsetX} Y:{offsetY}");
|
||
MaxwellControl.Controls.MessageBox.Show("操作成功");
|
||
|
||
});
|
||
}
|
||
private void CalculteWorkPos()
|
||
{
|
||
_workPos.Clear();
|
||
var startPoint = new Point(NeedlePrintCalibrateParameter.StartPoint.X, NeedlePrintCalibrateParameter.StartPoint.PointY);
|
||
var width = NeedlePrintCalibrateParameter.EndPoint.X - NeedlePrintCalibrateParameter.StartPoint.X;
|
||
var height = NeedlePrintCalibrateParameter.EndPoint.Y - NeedlePrintCalibrateParameter.StartPoint.Y;
|
||
var xscale = width > 0 ? 1 : -1;
|
||
var yscale = height > 0 ? 1 : -1;
|
||
var xcount = Math.Floor(Math.Abs(width) / NeedlePrintCalibrateParameter.Xpitch);
|
||
var ycount = Math.Floor(Math.Abs(height) / NeedlePrintCalibrateParameter.Ypitch);
|
||
for (int i = 0; i < ycount; i++)
|
||
{
|
||
for (int j = 0; j < xcount; j++)
|
||
{
|
||
var cameraPoint = new Point
|
||
{
|
||
X = startPoint.X + xscale * i * NeedlePrintCalibrateParameter.Xpitch,
|
||
Y = startPoint.Y + yscale * j * NeedlePrintCalibrateParameter.Ypitch,
|
||
};
|
||
|
||
var needlePoint = IoC.Get<VisionOperation>().GetNeedleRulerPointByRulerCamera(cameraPoint);
|
||
_workPos.Add(needlePoint);
|
||
}
|
||
}
|
||
}
|
||
|
||
*/
|
||
|
||
private bool CheckPointInRange(Point point)
|
||
{
|
||
return IsPointInRange(NeedlePrintCalibrateParameter.StartPoint, NeedlePrintCalibrateParameter.EndPoint, point);
|
||
}
|
||
|
||
bool IsPointInRange(MPoint p1, MPoint p2, Point current)
|
||
{
|
||
// 计算最小和最大 X 和 Y 值
|
||
double minX = Math.Min(p1.X, p2.X);
|
||
double maxX = Math.Max(p1.X, p2.X);
|
||
double minY = Math.Min(p1.Y, p2.Y);
|
||
double maxY = Math.Max(p1.Y, p2.Y);
|
||
|
||
// 检查待判断的点是否在范围内
|
||
return (current.X >= minX && current.X <= maxX) && (current.Y >= minY && current.Y <= maxY);
|
||
}
|
||
}
|
||
}
|