359 lines
12 KiB
C#
359 lines
12 KiB
C#
using Aurora;
|
|
using Aurora.Api;
|
|
using Aurora.Api.Manager;
|
|
using Aurora.View;
|
|
using AuroraLaser;
|
|
using AuroraLaserScanner;
|
|
using HarfBuzzSharp;
|
|
using Microsoft.Office.Interop.Excel;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Input;
|
|
using System.Windows.Threading;
|
|
|
|
namespace WeldingCommon.Views
|
|
{
|
|
public enum eAxisType
|
|
{
|
|
AXIS_X,
|
|
AXIS_Y
|
|
}
|
|
|
|
public enum eJogDirection
|
|
{
|
|
MINUS,
|
|
PLUS
|
|
}
|
|
|
|
public enum eMotionMode
|
|
{
|
|
ABS,
|
|
REL
|
|
};
|
|
|
|
public class UCScannerMotionViewModel : NotifyPropertyChangedBase
|
|
{
|
|
private readonly Logger Log = new Logger("UCScannerMotionViewModel");
|
|
|
|
public ICommand CMD_VisibleChanged { get; }
|
|
public ICommand CMD_SpeedChanged { get; }
|
|
public ICommand CMD_MotionModeChanged { get; }
|
|
|
|
public ICommand CMD_JogMove { get; }
|
|
public ICommand CMD_CommandPosMove { get; }
|
|
|
|
|
|
private readonly IAuroraEnvironment _Aurora;
|
|
|
|
private readonly Scanner _Scanner;
|
|
private readonly ILaserDevice _Laser;
|
|
private readonly ScannerConfig _ScannerConfig;
|
|
|
|
private double _ScannerXPos;
|
|
public double ScannerXPos { get => _ScannerXPos; set => SetProperty(ref _ScannerXPos, value); }
|
|
private double _ScannerYPos;
|
|
public double ScannerYPos { get => _ScannerYPos; set => SetProperty(ref _ScannerYPos, value); }
|
|
private bool _IsScannerBusy;
|
|
public bool IsScannerBusy { get => _IsScannerBusy; set => SetProperty(ref _IsScannerBusy, value); }
|
|
|
|
private double _StepValue;
|
|
public double StepValue { get => _StepValue; set => SetProperty(ref _StepValue, value); }
|
|
|
|
private double _CommandPosX;
|
|
public double CommandPosX { get => _CommandPosX; set => SetProperty(ref _CommandPosX, value); }
|
|
private double _CommandPosY;
|
|
public double CommandPosY { get => _CommandPosY; set => SetProperty(ref _CommandPosY, value); }
|
|
|
|
private double _CommandPosLimitMinX;
|
|
public double CommandPosLimitMinX { get => _CommandPosLimitMinX; set => SetProperty(ref _CommandPosLimitMinX, value); }
|
|
private double _CommandPosLimitMaxX;
|
|
public double CommandPosLimitMaxX { get => _CommandPosLimitMaxX; set => SetProperty(ref _CommandPosLimitMaxX, value); }
|
|
|
|
private double _CommandPosLimitMinY;
|
|
public double CommandPosLimitMinY { get => _CommandPosLimitMinY; set => SetProperty(ref _CommandPosLimitMinY, value); }
|
|
private double _CommandPosLimitMaxY;
|
|
public double CommandPosLimitMaxY { get => _CommandPosLimitMaxY; set => SetProperty(ref _CommandPosLimitMaxY, value); }
|
|
|
|
private double _VelocityRate;
|
|
private eMotionMode _MotionMode;
|
|
|
|
private readonly DispatcherTimer _MonitorTimer;
|
|
|
|
// PAM, RUW 처럼 2개 이상의 scanner 를 사용하는 경우가 있어, scannerId 를 받는 형태로 생성
|
|
public UCScannerMotionViewModel(IAuroraEnvironment aurora, string scannerId)
|
|
{
|
|
_Aurora = aurora;
|
|
|
|
_Scanner = _Aurora.DeviceManager[scannerId] as Scanner;
|
|
_Laser = _Aurora.DeviceManager[CommonDeviceIds.Laser] as ILaserDevice;
|
|
_ScannerConfig = _Aurora.DeviceManager.GetDeviceConfig(scannerId) as ScannerConfig;
|
|
|
|
InitVariable();
|
|
|
|
CMD_VisibleChanged = new DelegateCommand(VisibleChanged);
|
|
CMD_SpeedChanged = new DelegateCommand(PerformCmdSpeedChanged);
|
|
CMD_MotionModeChanged = new DelegateCommand(PerformCmdMotionModeChanged);
|
|
CMD_JogMove = new DelegateCommand(PerformCmdJogMove);
|
|
CMD_CommandPosMove = new DelegateCommand(PerformCmdCommandPosMove);
|
|
|
|
_MonitorTimer = new DispatcherTimer();
|
|
_MonitorTimer.Tick += OnMonitoring;
|
|
_MonitorTimer.Interval = TimeSpan.FromMilliseconds(100);
|
|
}
|
|
|
|
private void InitVariable()
|
|
{
|
|
_VelocityRate = 1;
|
|
_MotionMode = eMotionMode.ABS;
|
|
}
|
|
|
|
private void VisibleChanged(object obj)
|
|
{
|
|
bool visible = (bool)obj;
|
|
if (visible) {
|
|
Init_XYLimitPos();
|
|
_MonitorTimer.Start();
|
|
} else {
|
|
_MonitorTimer.Stop();
|
|
}
|
|
}
|
|
|
|
private void Init_XYLimitPos()
|
|
{
|
|
// TODO: Limit 값을 Min, Max 로 따로 Setting 입력값으로 가져와야 할 수도 있음. 우선 현상태 유지
|
|
CommandPosLimitMinX = -1 * _ScannerConfig.ScanXSize / 2;
|
|
CommandPosLimitMaxX = _ScannerConfig.ScanXSize / 2;
|
|
|
|
CommandPosLimitMinY = -1 * _ScannerConfig.ScanYSize / 2;
|
|
CommandPosLimitMaxY = _ScannerConfig.ScanYSize / 2;
|
|
|
|
//CommandPosXLimit = string.Format($"{-1 * _ScannerConfig.ScanXSize / 2} ~ {_ScannerConfig.ScanXSize / 2}");
|
|
//CommandPosYLimit = string.Format($"{-1 * _ScannerConfig.ScanYSize / 2} ~ {_ScannerConfig.ScanYSize / 2}");
|
|
}
|
|
|
|
private void OnMonitoring(object sender, EventArgs e)
|
|
{
|
|
double xPos, yPos;
|
|
if (_Scanner != null && _Scanner.IsActivated) {
|
|
_Scanner.GetXYPos(out xPos, out yPos);
|
|
ScannerXPos = xPos;
|
|
ScannerYPos = yPos;
|
|
|
|
IsScannerBusy = _Scanner.GetBusyStatus();
|
|
} else {
|
|
ScannerXPos = 0;
|
|
ScannerYPos = 0;
|
|
IsScannerBusy = false;
|
|
}
|
|
|
|
}
|
|
|
|
private void PerformCmdSpeedChanged(object commandParameter)
|
|
{
|
|
switch ((string)commandParameter) {
|
|
case "Low": {
|
|
_VelocityRate = 0.5;
|
|
}
|
|
break;
|
|
|
|
case "Mid": {
|
|
_VelocityRate = 1;
|
|
}
|
|
break;
|
|
|
|
case "High": {
|
|
_VelocityRate = 1.5;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void PerformCmdMotionModeChanged(object commandParameter)
|
|
{
|
|
switch ((string)commandParameter) {
|
|
case "ABS": {
|
|
_MotionMode = eMotionMode.ABS;
|
|
}
|
|
break;
|
|
|
|
case "REL": {
|
|
_MotionMode = eMotionMode.REL;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void PerformCmdJogMove(object commandParameter)
|
|
{
|
|
// TODO: Left, Right, Up, Down 은 장비 Scanner 의 방향에 따라 달라질 수 있다
|
|
switch ((string)commandParameter) {
|
|
case "Left": {
|
|
MoveJogXYPos(eAxisType.AXIS_X, eJogDirection.MINUS);
|
|
}
|
|
break;
|
|
|
|
case "Right": {
|
|
MoveJogXYPos(eAxisType.AXIS_X, eJogDirection.PLUS);
|
|
}
|
|
break;
|
|
|
|
case "Up": {
|
|
MoveJogXYPos(eAxisType.AXIS_Y, eJogDirection.PLUS);
|
|
}
|
|
break;
|
|
|
|
case "Down": {
|
|
MoveJogXYPos(eAxisType.AXIS_Y, eJogDirection.MINUS);
|
|
}
|
|
break;
|
|
|
|
case "Home": {
|
|
MoveJogHome();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void MoveJogXYPos(eAxisType axisType, eJogDirection direction)
|
|
{
|
|
double xPos = 0.0;
|
|
double yPos = 0.0;
|
|
switch (axisType) {
|
|
case eAxisType.AXIS_X: {
|
|
if (direction == eJogDirection.MINUS) {
|
|
xPos = StepValue * -1;
|
|
yPos = 0;
|
|
} else if (direction == eJogDirection.PLUS) {
|
|
xPos = StepValue;
|
|
yPos = 0;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case eAxisType.AXIS_Y: {
|
|
if (direction == eJogDirection.MINUS) {
|
|
xPos = 0;
|
|
yPos = StepValue * -1;
|
|
} else if (direction == eJogDirection.PLUS) {
|
|
xPos = 0;
|
|
yPos = StepValue;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// 현재 Curruent Pos 기준으로, 입력방향으로 입력값이 Limit 를 넘어 서는지 확인 (Rel 임)
|
|
if (CheckOverLimitPos(ScannerXPos + xPos, ScannerYPos + yPos)) {
|
|
Log.E(string.Format("움직이려는 범위가 스캐너 범위를 초과하였습니다."));
|
|
return;
|
|
}
|
|
|
|
double finalVelocity = _ScannerConfig.JumpSpeed * _VelocityRate;
|
|
_Scanner.SetJumpSpeedCtrl(finalVelocity);
|
|
_Scanner.JumpRel(xPos, yPos);
|
|
|
|
//Jump 후 Speed 원복
|
|
_Scanner.SetJumpSpeedCtrl(_ScannerConfig.JumpSpeed);
|
|
}
|
|
|
|
private void MoveJogHome()
|
|
{
|
|
double finalVelocity = _ScannerConfig.JumpSpeed * _VelocityRate;
|
|
_Scanner.SetJumpSpeedCtrl(finalVelocity);
|
|
_Scanner.JumpAbs(0, 0);
|
|
|
|
//Jump 후 Speed 원복
|
|
_Scanner.SetJumpSpeedCtrl(_ScannerConfig.JumpSpeed);
|
|
}
|
|
|
|
private void PerformCmdCommandPosMove(object commandParameter)
|
|
{
|
|
switch ((string)commandParameter) {
|
|
case "X": {
|
|
MoveCommandXYPos(eAxisType.AXIS_X);
|
|
}
|
|
break;
|
|
|
|
case "Y": {
|
|
MoveCommandXYPos(eAxisType.AXIS_Y);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void MoveCommandXYPos(eAxisType axisType)
|
|
{
|
|
double xPos = 0.0;
|
|
double yPos = 0.0;
|
|
switch (axisType) {
|
|
case eAxisType.AXIS_X: {
|
|
xPos = CommandPosX;
|
|
|
|
if (_MotionMode == eMotionMode.ABS) {
|
|
yPos = _Scanner.GetCommandPosY();
|
|
} else {
|
|
yPos = 0.0;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case eAxisType.AXIS_Y: {
|
|
if (_MotionMode == eMotionMode.ABS) {
|
|
xPos = _Scanner.GetCommandPosX();
|
|
} else {
|
|
xPos = 0.0;
|
|
}
|
|
|
|
yPos = CommandPosY;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// 현재 Curruent Pos 기준으로, 입력방향으로 입력값이 Limit 를 넘어 서는지 확인
|
|
if (_MotionMode == eMotionMode.ABS) {
|
|
if (CheckOverLimitPos(xPos, yPos)) {
|
|
Log.E(string.Format("움직이려는 범위가 스캐너 범위를 초과하였습니다."));
|
|
return;
|
|
}
|
|
} else {
|
|
if (CheckOverLimitPos(ScannerXPos + xPos, ScannerYPos + yPos)) {
|
|
Log.E(string.Format("움직이려는 범위가 스캐너 범위를 초과하였습니다."));
|
|
return;
|
|
}
|
|
}
|
|
|
|
double finalVelocity = _ScannerConfig.JumpSpeed * _VelocityRate;
|
|
_Scanner.SetJumpSpeedCtrl(finalVelocity);
|
|
|
|
if (_MotionMode == eMotionMode.ABS) {
|
|
_Scanner.JumpAbs(xPos, yPos);
|
|
} else {
|
|
_Scanner.JumpRel(xPos, yPos);
|
|
}
|
|
|
|
//Jump 후 Speed 원복
|
|
_Scanner.SetJumpSpeedCtrl(_ScannerConfig.JumpSpeed);
|
|
}
|
|
|
|
private bool CheckOverLimitPos(double calcPosX, double calcPosY)
|
|
{
|
|
if (calcPosX < CommandPosLimitMinX || calcPosX > CommandPosLimitMaxX) {
|
|
return true;
|
|
} else if (calcPosY < CommandPosLimitMinY || calcPosY > CommandPosLimitMaxY) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
}
|