219 lines
8.8 KiB
C#
219 lines
8.8 KiB
C#
using Aurora;
|
|
using Aurora.Api.Devices;
|
|
using Aurora.Api.Manager;
|
|
using Aurora.View;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Windows;
|
|
using System.Windows.Input;
|
|
using System.Windows.Threading;
|
|
|
|
namespace WeldingCommon.Views
|
|
{
|
|
internal class UCSingleAxisStatusViewModel : NotifyPropertyChangedBase
|
|
{
|
|
private readonly IDeviceManager DeviceManager;
|
|
private readonly DispatcherTimer MonitorTimer;
|
|
|
|
#region Binding Properties
|
|
private List<string> _MotorIDList;
|
|
public List<string> MotorIDList { get => _MotorIDList; set => SetProperty(ref _MotorIDList, value); }
|
|
|
|
private string _SelectedMotorID;
|
|
public string SelectedMotorID { get => _SelectedMotorID; set => SetProperty(ref _SelectedMotorID, value); }
|
|
|
|
// TODO: 아래 strMotorServoOnOffStatus 와 하나로 합치자. 이 부분은 background 색상 변경에 사용됨
|
|
private bool _bMotorServoOnOffStatus;
|
|
public bool bMotorServoOnOffStatus { get => _bMotorServoOnOffStatus; set => SetProperty(ref _bMotorServoOnOffStatus, value); }
|
|
private string _strMotorServoOnOffStatus;
|
|
public string strMotorServoOnOffStatus { get => _strMotorServoOnOffStatus; set => SetProperty(ref _strMotorServoOnOffStatus, value); }
|
|
|
|
private bool _MotorAlarmStatus;
|
|
public bool MotorAlarmStatus { get => _MotorAlarmStatus; set => SetProperty(ref _MotorAlarmStatus, value); }
|
|
|
|
private bool _MotorInMotion;
|
|
public bool MotorInMotion { get => _MotorInMotion; set => SetProperty(ref _MotorInMotion, value); }
|
|
|
|
private bool _MotorInPosition;
|
|
public bool MotorInPosition { get => _MotorInPosition; set => SetProperty(ref _MotorInPosition, value); }
|
|
|
|
private bool _MotorHomeStatus;
|
|
public bool MotorHomeStatus { get => _MotorHomeStatus; set => SetProperty(ref _MotorHomeStatus, value); }
|
|
|
|
private bool _MotorPlusLimitStatus;
|
|
public bool MotorPlusLimitStatus { get => _MotorPlusLimitStatus; set => SetProperty(ref _MotorPlusLimitStatus, value); }
|
|
|
|
private bool _MotorMinusLimitStatus;
|
|
public bool MotorMinusLimitStatus { get => _MotorMinusLimitStatus; set => SetProperty(ref _MotorMinusLimitStatus, value); }
|
|
|
|
private bool _MotorEmergencyStop;
|
|
public bool MotorEmergencyStop { get => _MotorEmergencyStop; set => SetProperty(ref _MotorEmergencyStop, value); }
|
|
|
|
private string _AlarmCode;
|
|
public string AlarmCode { get => _AlarmCode; set => SetProperty(ref _AlarmCode, value); }
|
|
|
|
private double _TargetPos;
|
|
public double TargetPos { get => _TargetPos; set => SetProperty(ref _TargetPos, value); }
|
|
|
|
private double _ActualPos;
|
|
public double ActualPos { get => _ActualPos; set => SetProperty(ref _ActualPos, value); }
|
|
|
|
private double _PosError;
|
|
public double PosError { get => _PosError; set => SetProperty(ref _PosError, value); }
|
|
|
|
private double _Velocity;
|
|
public double Velocity { get => _Velocity; set => SetProperty(ref _Velocity, value); }
|
|
|
|
#endregion
|
|
|
|
#region EventCommands
|
|
public ICommand CMD_VisibleChanged { get; }
|
|
public ICommand CMD_INCCOMBOMOTORID { get; }
|
|
public ICommand CMD_DECCOMBOMOTORID { get; }
|
|
public ICommand CMD_ServoOnOff { get; }
|
|
public ICommand CMD_ResetAlarm { get; }
|
|
#endregion
|
|
|
|
public UCSingleAxisStatusViewModel(IAuroraEnvironment aurora)
|
|
{
|
|
DeviceManager = aurora.DeviceManager;
|
|
|
|
#region Initialize Binding Properties
|
|
// Motor ID 를 List 에 넣기. devicemanager 에서 motor ID 를 받아오자.
|
|
// motor 가 define 되지 않았으니 테스트를 위해 임시로 몇개 넣어둔다.
|
|
MotorIDList = new List<string> { "Welding Y1", "Welding Z" };
|
|
SelectedMotorID = MotorIDList[0];
|
|
strMotorServoOnOffStatus = "Servo Off";
|
|
#endregion
|
|
|
|
#region DelegateCommands
|
|
CMD_VisibleChanged = new DelegateCommand(VisibleChanged);
|
|
CMD_INCCOMBOMOTORID = new DelegateCommand(IncreaseComboMotorID);
|
|
CMD_DECCOMBOMOTORID = new DelegateCommand(DecreaseComboMotorID);
|
|
CMD_ServoOnOff = new DelegateCommand(MotorServoOnOff);
|
|
CMD_ResetAlarm = new DelegateCommand(MotorResetAlarm);
|
|
#endregion
|
|
|
|
MonitorTimer = new DispatcherTimer();
|
|
MonitorTimer.Tick += OnMonitoring;
|
|
MonitorTimer.Interval = TimeSpan.FromMilliseconds(100);
|
|
}
|
|
|
|
private void OnMonitoring(object sender, EventArgs e)
|
|
{
|
|
try {
|
|
var motor = GetComboSelectedBaseMotor();
|
|
if (motor != null) {
|
|
if (motor.IsServoOn()) {
|
|
bMotorServoOnOffStatus = true;
|
|
strMotorServoOnOffStatus = "Servo Off";
|
|
} else {
|
|
bMotorServoOnOffStatus = false;
|
|
strMotorServoOnOffStatus = "Servo On";
|
|
}
|
|
if (motor.IsAlarm()) {
|
|
MotorAlarmStatus = true;
|
|
AlarmCode = motor.GetLastAlarm().ToString();
|
|
} else {
|
|
MotorAlarmStatus = false;
|
|
AlarmCode = "No Alarm";
|
|
}
|
|
if (motor.IsMoving()) MotorInMotion = true;
|
|
else MotorInMotion = false;
|
|
// inposition bit 를 받아오는 함수가 없다. current 와 target 을 비교하는 것으로 하기에는 위험성이 있다. 일단 만들어는 두자.
|
|
// motor position 정보를 받아오는 함수를 따로 만드는게 맞지만, 이 view 에서 쓰는 코드를 재활용할일이 없으므로 IsMotorInPositiong 함수안에서 다한다.
|
|
if (IsMotorInPosition(motor)) MotorInPosition = true;
|
|
else MotorInPosition = false;
|
|
if (motor.IsHomeCompleted()) MotorHomeStatus = true;
|
|
else MotorHomeStatus = false;
|
|
|
|
// plus limit 함수없음. ACS 모터는 IsHPLimit() 함수가 있음.
|
|
// minus limit 함수없음. ACS 모터는 IsHNLimit() 함수가 있음.
|
|
// EMG 함수 없음
|
|
MotorPlusLimitStatus = false;
|
|
MotorMinusLimitStatus = false;
|
|
MotorEmergencyStop = false;
|
|
|
|
Velocity = motor.GetVelocity();
|
|
}
|
|
AlarmCode = "No Alarm";
|
|
} catch (Exception ex) {
|
|
MessageBox.Show(ex.Message);
|
|
}
|
|
}
|
|
private void IncreaseComboMotorID(object obj)
|
|
{
|
|
try {
|
|
int nIndex = MotorIDList.IndexOf(SelectedMotorID);
|
|
if (nIndex >= MotorIDList.Count - 1) nIndex = MotorIDList.Count;
|
|
else nIndex++;
|
|
SelectedMotorID = MotorIDList[nIndex];
|
|
} catch { }
|
|
|
|
|
|
}
|
|
private void DecreaseComboMotorID(object obj)
|
|
{
|
|
try {
|
|
int nIndex = MotorIDList.IndexOf(SelectedMotorID);
|
|
|
|
if (nIndex < 1) nIndex = 0;
|
|
else nIndex--;
|
|
SelectedMotorID = MotorIDList[nIndex];
|
|
} catch { }
|
|
}
|
|
|
|
private void MotorServoOnOff(object obj)
|
|
{
|
|
try {
|
|
var motor = GetComboSelectedBaseMotor();
|
|
if (motor != null) {
|
|
if (motor.IsServoOn()) motor.ServoOn(false);
|
|
else motor.ServoOn(true);
|
|
}
|
|
} catch { }
|
|
}
|
|
private void MotorResetAlarm(object obj)
|
|
{
|
|
try {
|
|
var motor = GetComboSelectedBaseMotor();
|
|
if (motor != null) {
|
|
if (motor.IsAlarm()) motor.ClearAlarm();
|
|
}
|
|
} catch { }
|
|
}
|
|
|
|
private void VisibleChanged(object obj)
|
|
{
|
|
bool visible = (bool)obj;
|
|
if (visible) {
|
|
MonitorTimer.Start();
|
|
} else {
|
|
MonitorTimer.Stop();
|
|
}
|
|
}
|
|
private BaseMotor GetComboSelectedBaseMotor()
|
|
{
|
|
return DeviceManager[SelectedMotorID] as BaseMotor;
|
|
}
|
|
private bool IsMotorInPosition(string MotorID)
|
|
{
|
|
var motor = DeviceManager[MotorID] as BaseMotor;
|
|
return IsMotorInPosition(motor);
|
|
}
|
|
private bool IsMotorInPosition(BaseMotor motor)
|
|
{
|
|
if (motor == null) return false;
|
|
|
|
double dbInPositionRange = 0.001;
|
|
ActualPos = motor.GetCurrentPosition();
|
|
TargetPos = motor.GetTargetPosition();
|
|
PosError = TargetPos - ActualPos;
|
|
if (!motor.IsMoving() && (Math.Abs(PosError) < dbInPositionRange))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
}
|
|
}
|