OnMonitoring의 IsLaserReady 판정을 DI(9)(CoreLaser_Laser_Ready 단독)에서 DI(12) && DI(24) (CoreLaser_Control_Status AND RingLaser_Control_Status)로 변경. 버튼이 켜는 Control(DO9/13)의 피드백을 Core·Ring 둘 다 확인. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
490 lines
19 KiB
C#
490 lines
19 KiB
C#
using Aurora;
|
|
using Aurora.Api;
|
|
using Aurora.View;
|
|
using AuroraIO;
|
|
using AuroraLaser;
|
|
using AuroraLaserScanner;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Linq;
|
|
using System.Reactive.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using System.Windows.Input;
|
|
using System.Windows.Threading;
|
|
using VisionCommon;
|
|
using WeldingCommon;
|
|
using WeldingCommon.Devices.Laser;
|
|
using WeldingCommon.Models;
|
|
using WeldingCommon.Sequences;
|
|
using WeldingCommon.Settings;
|
|
using WeldingCommon.Utils;
|
|
using static AuroraLaser.Ekspla.NL202;
|
|
using static WeldingCommon.Devices.Laser.PAIX_PrismaticScanner;
|
|
|
|
namespace WeldingCommon.Views
|
|
{
|
|
public class UCScannerObjectTeachingControlBoxViewModel : NotifyPropertyChangedBase
|
|
{
|
|
private readonly Logger Log = new Logger("UCScannerObjectTeachingControlBoxViewModel");
|
|
|
|
public ICommand CMD_VisibleChanged { get; }
|
|
|
|
public ICommand CMD_RunScoutNormal { get; }
|
|
public ICommand CMD_StopScoutNormal { get; }
|
|
|
|
public ICommand CMD_RunScoutFlyingVision { get; }
|
|
public ICommand CMD_StopScoutFlyingVision { get; }
|
|
|
|
public ICommand CMD_RunTeachingRun { get; }
|
|
public ICommand CMD_StopTeachingRun { get; }
|
|
|
|
public ICommand CMD_LaserGuideBeam { get; }
|
|
public ICommand CMD_LaserReadyCheck { get; }
|
|
public ICommand CMD_ImportObjectFromDXF { get; }
|
|
|
|
private readonly IAuroraEnvironment _Aurora;
|
|
private SystemParameter _SystemParameter;
|
|
//private readonly EquipmentInfo _EquipmentInfo;
|
|
|
|
private readonly Scanner _Scanner;
|
|
private readonly Laser _Laser;
|
|
private readonly LaserConfig _LaserConfig;
|
|
private IODevice _IODevice;
|
|
|
|
|
|
private ISequence _SeqScoutNormal;
|
|
private bool _IsSequenceRunning_ScoutNormal;
|
|
public bool IsSequenceRunning_ScoutNormal { get => _IsSequenceRunning_ScoutNormal; set => SetProperty(ref _IsSequenceRunning_ScoutNormal, value); }
|
|
|
|
private ISequence _SeqScoutFlyingVision;
|
|
private bool _IsSequenceRunning_ScoutFlyingVision;
|
|
public bool IsSequenceRunning_ScoutFlyingVision { get => _IsSequenceRunning_ScoutFlyingVision; set => SetProperty(ref _IsSequenceRunning_ScoutFlyingVision, value); }
|
|
|
|
private ISequence _SeqTeachingRun;
|
|
|
|
private bool _IsSequenceRunning_TeachingRun;
|
|
public bool IsSequenceRunning_TeachingRun { get => _IsSequenceRunning_TeachingRun; set => SetProperty(ref _IsSequenceRunning_TeachingRun, value); }
|
|
|
|
private bool _IsSelectedScoutNormal;
|
|
public bool IsSelectedScoutNormal { get => _IsSelectedScoutNormal; set => SetProperty(ref _IsSelectedScoutNormal, value); }
|
|
|
|
private bool _IsGuidBeam;
|
|
public bool IsGuidBeam { get => _IsGuidBeam; set => SetProperty(ref _IsGuidBeam, value); }
|
|
private bool _IsLaserReady;
|
|
public bool IsLaserReady { get => _IsLaserReady; set => SetProperty(ref _IsLaserReady, value); }
|
|
|
|
// Object Select Type
|
|
private bool _IsObjectSelectAll;
|
|
public bool IsObjectSelectAll { get => _IsObjectSelectAll; set => SetProperty(ref _IsObjectSelectAll, value); }
|
|
|
|
private readonly DispatcherTimer _MonitorTimer;
|
|
|
|
private SequenceDialog _SequenceDialog;
|
|
|
|
private WinSequenceDiagram _WinSequenceDiagramScoutNormal;
|
|
private WinSequenceDiagram _WinSequenceDiagramScoutFlyingVision;
|
|
private WinSequenceDiagram _WinSequenceDiagramTeachingRun;
|
|
private WinSequenceDiagram _WinSequenceDiagramComponentTeachingRun;
|
|
public bool toggleIO = true;
|
|
public UCScannerObjectTeachingControlBoxViewModel(IAuroraEnvironment aurora)
|
|
{
|
|
_Aurora = aurora;
|
|
|
|
_SystemParameter = aurora.SettingEntry[CommonSettingIds.SystemParameter] as SystemParameter;
|
|
|
|
_SeqScoutNormal = _Aurora.SequenceEntry[CommonSequenceIds.SeqScoutNormal];
|
|
_SeqScoutFlyingVision = _Aurora.SequenceEntry[CommonSequenceIds.SeqScoutFlyingVision];
|
|
|
|
_Scanner = _Aurora.DeviceManager[CommonDeviceIds.Scanner] as Scanner;
|
|
_Laser = _Aurora.DeviceManager[CommonDeviceIds.Laser] as Laser;
|
|
_IODevice = _Aurora.DeviceManager[CommonDeviceIds.IODevice] as IODevice;
|
|
// Trumpf 레이저인 경우에는 ComponentTeachingRun 실행
|
|
_LaserConfig = _Aurora.DeviceManager.GetDeviceConfig(CommonDeviceIds.Laser) as LaserConfig;
|
|
_SeqTeachingRun = _Aurora.SequenceEntry[CommonSequenceIds.SeqComponentTeachingRun];
|
|
|
|
InitVariable();
|
|
|
|
CMD_VisibleChanged = new DelegateCommand(VisibleChanged);
|
|
|
|
CMD_RunScoutNormal = new DelegateCommand(PerformCmdRunScoutNormal);
|
|
CMD_StopScoutNormal = new DelegateCommand(PerformCmdStopScoutNormal);
|
|
CMD_RunScoutFlyingVision = new DelegateCommand(PerformCmdRunScoutFlyingVision);
|
|
CMD_StopScoutFlyingVision = new DelegateCommand(PerformCmdStopScoutFlyingVision);
|
|
CMD_RunTeachingRun = new DelegateCommand(PerformCmdRunTeachingRun);
|
|
CMD_StopTeachingRun = new DelegateCommand(PerformCmdStopTeachingRun);
|
|
|
|
CMD_LaserGuideBeam = new DelegateCommand(PerformCmdLaserGuideBeam);
|
|
CMD_LaserReadyCheck = new DelegateCommand(PerformCmdLaserReadyCheck);
|
|
CMD_ImportObjectFromDXF = new DelegateCommand(PerformCmdImportObjectFromDXF);
|
|
|
|
_Aurora.EventObservable.AsObservable(AuroraSysEvent.SYS_SETTING_CHANGED)
|
|
.ObserveOnDispatcher()
|
|
.Subscribe(OnSettingReloaded);
|
|
|
|
_MonitorTimer = new DispatcherTimer();
|
|
_MonitorTimer.Tick += OnMonitoring;
|
|
_MonitorTimer.Interval = TimeSpan.FromMilliseconds(100);
|
|
|
|
}
|
|
|
|
private void InitVariable()
|
|
{
|
|
if (_SystemParameter.ScoutType == eScoutType.Normal) {
|
|
IsSelectedScoutNormal = true;
|
|
} else {
|
|
IsSelectedScoutNormal = false;
|
|
}
|
|
|
|
IsSequenceRunning_ScoutNormal = false;
|
|
IsSequenceRunning_ScoutFlyingVision = false;
|
|
IsSequenceRunning_TeachingRun = false;
|
|
|
|
IsGuidBeam = false;
|
|
IsLaserReady = false;
|
|
|
|
IsObjectSelectAll = true;
|
|
}
|
|
|
|
private void VisibleChanged(object obj)
|
|
{
|
|
bool visible = (bool)obj;
|
|
if (visible) {
|
|
_MonitorTimer.Start();
|
|
} else {
|
|
_MonitorTimer.Stop();
|
|
}
|
|
}
|
|
|
|
private void OnSettingReloaded(object obj)
|
|
{
|
|
_SystemParameter = _Aurora.SettingEntry[CommonSettingIds.SystemParameter] as SystemParameter;
|
|
if (_SystemParameter.ScoutType == eScoutType.Normal) {
|
|
IsSelectedScoutNormal = true;
|
|
} else {
|
|
IsSelectedScoutNormal = false;
|
|
}
|
|
}
|
|
|
|
private void OnMonitoring(object sender, EventArgs e)
|
|
{
|
|
|
|
// TODO: Laser Device 에 구현된 내용에 따르면, 일부 Laser Device 는 구현이 되어 있지 않은 상태. 항상 false
|
|
if (_Laser.GetPilotLaserStatus()) {
|
|
IsGuidBeam = true;
|
|
} else {
|
|
IsGuidBeam = false;
|
|
}
|
|
try
|
|
{
|
|
// 변경 후
|
|
if (_IODevice.ReadDI(12) && _IODevice.ReadDI(24))
|
|
{
|
|
IsLaserReady = true;
|
|
}
|
|
else
|
|
{
|
|
IsLaserReady = false;
|
|
}
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.E($"[OnMonitoring] DI 읽기 실패: {ex.Message}");
|
|
IsLaserReady = false;
|
|
}
|
|
|
|
// TODO: PRIBAT_L1, PRIBAT_L2 는 Blow 의 상태 check 가 들어 있음. 장비 한정이므로 이를 check 하는 것을 modelItem 이나 setting 으로 빼서 진행되도록 함.
|
|
}
|
|
|
|
private void PerformCmdRunScoutNormal(object obj)
|
|
{
|
|
var result = MessageUtil.ShowYesNoMessageDialog("Scanner Scout", "Start Scanner Scout Normal Sequence?");
|
|
if (result == false) {
|
|
return;
|
|
}
|
|
|
|
if (VisionRecipeManager.GetFovInfos().Count == 0) {
|
|
MessageUtil.ShowWarningToast(string.Format("Please check the Vision Recipe of the currently active Recipe."));
|
|
return;
|
|
}
|
|
|
|
if (_SeqScoutNormal.RunState == SequenceRunState.Running) {
|
|
MessageUtil.ShowWarningToast(string.Format("이미 시퀀스가 Start 상태입니다.", "SeqScoutNormal"), Log);
|
|
return;
|
|
}
|
|
|
|
var scoutSeqParams = new ScoutSeqParams(VisionRecipeManager.GetFovInfos()[0], eDisplayType.Machine_B);
|
|
var param = new SeqScoutNormal_InitParam() {
|
|
IsRealTimeScout = false,
|
|
ScoutSeqParams = scoutSeqParams,
|
|
};
|
|
|
|
PopupSequenceDiagram(ref _WinSequenceDiagramScoutNormal, CommonSequenceIds.SeqScoutNormal, param);
|
|
|
|
IsSequenceRunning_ScoutNormal = true;
|
|
_SeqScoutNormal.Start(param, OnCompleteScoutNormal);
|
|
|
|
}
|
|
|
|
private void OnCompleteScoutNormal(SequenceActionResult res)
|
|
{
|
|
if (res != null) {
|
|
if (res.Param is SeqScoutNormal_OutParam result && result.Success == true) {
|
|
IsSequenceRunning_ScoutNormal = false;
|
|
MessageUtil.ShowSuccessToast(string.Format("Success SeqScoutNormal"));
|
|
|
|
CloseSequenceDiagram(_WinSequenceDiagramScoutNormal);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (_Laser.GetLaserReady()) {
|
|
_Laser.LaserOff();
|
|
}
|
|
|
|
IsSequenceRunning_ScoutNormal = false;
|
|
MessageUtil.ShowWarningToast(string.Format("Fail SeqScoutNormal"));
|
|
}
|
|
|
|
private void PerformCmdStopScoutNormal(object obj)
|
|
{
|
|
if (_SeqScoutNormal.RunState == SequenceRunState.Idle) {
|
|
return;
|
|
}
|
|
|
|
IsSequenceRunning_ScoutNormal = false;
|
|
_SeqScoutNormal.Stop();
|
|
}
|
|
|
|
private void PerformCmdRunScoutFlyingVision(object obj)
|
|
{
|
|
var result = MessageUtil.ShowYesNoMessageDialog("Flying Vision", "Start Scanner Scout Flying Vision Sequence?");
|
|
if (result == false) {
|
|
return;
|
|
}
|
|
|
|
if (VisionRecipeManager.GetFovInfos().Count == 0) {
|
|
MessageUtil.ShowWarningToast(string.Format("Please check the Vision Recipe of the currently active Recipe."));
|
|
return;
|
|
}
|
|
|
|
if (_SeqScoutFlyingVision.RunState == SequenceRunState.Running) {
|
|
MessageUtil.ShowWarningToast(string.Format("이미 시퀀스가 Start 상태입니다.", "SeqScoutFlyingVision"), Log);
|
|
return;
|
|
}
|
|
|
|
var scoutSeqParams = new ScoutSeqParams(VisionRecipeManager.GetFovInfos()[0], eDisplayType.Machine_B);
|
|
var param = new SeqScoutFlyingVision_InitParam() {
|
|
IsRealTimeScout = false,
|
|
ScoutSeqParams = scoutSeqParams,
|
|
SequenceAutoRunCount = 0,
|
|
WeldingScannerListNo = eListNo.LIST2,
|
|
};
|
|
|
|
PopupSequenceDiagram(ref _WinSequenceDiagramScoutFlyingVision, CommonSequenceIds.SeqScoutFlyingVision, param);
|
|
|
|
IsSequenceRunning_ScoutFlyingVision = true;
|
|
_SeqScoutFlyingVision.Start(param, OnCompleteScoutFlyingVision);
|
|
|
|
}
|
|
|
|
private void OnCompleteScoutFlyingVision(SequenceActionResult res)
|
|
{
|
|
if (res != null) {
|
|
if (res.Param is SeqScoutFlyingVision_OutParam result && result.Success == true) {
|
|
IsSequenceRunning_ScoutFlyingVision = false;
|
|
MessageUtil.ShowSuccessToast(string.Format("Success SeqScoutFlyingVision"));
|
|
|
|
CloseSequenceDiagram(_WinSequenceDiagramScoutFlyingVision);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (_Laser.GetLaserReady()) {
|
|
_Laser.LaserOff();
|
|
}
|
|
|
|
IsSequenceRunning_ScoutFlyingVision = false;
|
|
MessageUtil.ShowWarningToast(string.Format("Fail SeqScoutFlyingVision"));
|
|
}
|
|
|
|
private void PerformCmdStopScoutFlyingVision(object obj)
|
|
{
|
|
if (_SeqScoutFlyingVision.RunState == SequenceRunState.Idle) {
|
|
return;
|
|
}
|
|
|
|
IsSequenceRunning_ScoutFlyingVision = false;
|
|
_SeqScoutFlyingVision.Stop();
|
|
}
|
|
|
|
private void PerformCmdRunTeachingRun(object obj)
|
|
{
|
|
var result = MessageUtil.ShowYesNoMessageDialog("Teaching Run", "Start TeachingRun Sequence?");
|
|
if (result == false) {
|
|
return;
|
|
}
|
|
|
|
if (IsLaserReady == false) {
|
|
MessageUtil.ShowWarningToast(string.Format("Please check Laser Ready."));
|
|
return;
|
|
}
|
|
|
|
// TODO: PRIBAT_L1, PRIBAT_L2 에서 Suction 과 CLAMP 상태 등에 따라 Laser 가 나가지 않도록 해야 함.
|
|
// TODO: 이 부분은, Delegate 를 사용해서, Interlock 을 각 장비별로 설정할 수 있도록 해주는게 좋겠음.
|
|
|
|
if (_SeqTeachingRun.RunState == SequenceRunState.Running) {
|
|
MessageUtil.ShowWarningToast(string.Format("이미 시퀀스가 Start 상태입니다.", "SeqTeachingRun"), Log);
|
|
return;
|
|
}
|
|
|
|
// TODO: NeedSetLaserTiming 는 트럼프 레이저 를 사용할 때, UploadWeldingList Sequence 에서 LaserTiming Set 을 해야 할때 사용함.
|
|
// TODO: SMW 와 LHS 는 트럼프 레이저를 사용하지 않으므로 false, PRIBAT_L1 과 PRIBAT_L2 할때 LaserType 을 읽어서 설정하는 것으로 추가하자
|
|
|
|
var currentModelInfo = EquipmentSpecificModelUtil.GetCurrentRecipeEquipmentSpecificModel();
|
|
if (currentModelInfo.equipmentSpecificModel == null) {
|
|
MessageUtil.ShowWarningToast(string.Format("선택된 model 이 없습니다.", "SeqTeachingRun"));
|
|
return;
|
|
}
|
|
|
|
var intervalTimeBlowOn = 0;
|
|
var intervalTimeBlowOff = 0;
|
|
|
|
if (currentModelInfo.equipmentSpecificModel.UseBlow) {
|
|
intervalTimeBlowOn = currentModelInfo.equipmentSpecificModel.IntervalTimeBlowOn;
|
|
intervalTimeBlowOff = currentModelInfo.equipmentSpecificModel.IntervalTimeBlowOff;
|
|
}
|
|
|
|
var param = new SeqTeachingRun_InitParam() {
|
|
IsObjectSelectAll = IsObjectSelectAll,
|
|
|
|
//UseStream = _EquipmentInfo.UseStream,
|
|
UseStream = currentModelInfo.equipmentSpecificModel.UseStream,
|
|
|
|
UseBlow = currentModelInfo.equipmentSpecificModel.UseBlow,
|
|
IntervalTimeBlowOn = intervalTimeBlowOn,
|
|
IntervalTimeBlowOff = intervalTimeBlowOff,
|
|
|
|
NeedSetLaserTiming = false,
|
|
};
|
|
|
|
//PopupSequenceDiagram(ref _WinSequenceDiagramTeachingRun, CommonSequenceIds.SeqComponentTeachingRun, param);
|
|
|
|
IsSequenceRunning_TeachingRun = true;
|
|
_SeqTeachingRun.Start(param, OnCompleteTeachingRun);
|
|
|
|
}
|
|
|
|
private void OnCompleteTeachingRun(SequenceActionResult res)
|
|
{
|
|
|
|
//if (res != null) {
|
|
// if (res.Param is SeqTeachingRun_OutParam result && result.Success == true) {
|
|
// IsSequenceRunning_TeachingRun = false;
|
|
// MessageUtil.ShowSuccessToast(string.Format("Success SeqTeachingRun"));
|
|
|
|
// CloseSequenceDiagram(_WinSequenceDiagramTeachingRun);
|
|
// return;
|
|
// }
|
|
//}
|
|
|
|
if (_Laser.GetLaserReady()) {
|
|
_Laser.LaserOff();
|
|
}
|
|
|
|
IsSequenceRunning_TeachingRun = false;
|
|
//MessageUtil.ShowWarningToast(string.Format("Fail SeqTeachingRun"));
|
|
}
|
|
|
|
private void PerformCmdStopTeachingRun(object obj)
|
|
{
|
|
IsSequenceRunning_TeachingRun = false;
|
|
if (_SeqTeachingRun.RunState == SequenceRunState.Idle) {
|
|
return;
|
|
}
|
|
|
|
_SeqTeachingRun.Stop();
|
|
}
|
|
|
|
|
|
private void PopupSequenceDiagram(ref WinSequenceDiagram winSequenceDiagram, string seqId, object param)
|
|
{
|
|
if (winSequenceDiagram == null) {
|
|
winSequenceDiagram = new WinSequenceDiagram(seqId);
|
|
winSequenceDiagram.Closing += ClosingEvent;
|
|
winSequenceDiagram.SetParam(new SeqDrawerParam() {
|
|
SequenceId = seqId,
|
|
DiagramType = eDiagramType.Tree,
|
|
LineType = eLineType.Straight,
|
|
IsShowSubSequence = false,
|
|
VisibleKeys = new List<string>()
|
|
});
|
|
|
|
winSequenceDiagram.Owner = Application.Current.MainWindow;
|
|
winSequenceDiagram.Width = 600;
|
|
winSequenceDiagram.SequenceParam = param;
|
|
winSequenceDiagram.Show();
|
|
} else {
|
|
winSequenceDiagram.SequenceParam = param;
|
|
winSequenceDiagram.WindowState = WindowState.Normal;
|
|
winSequenceDiagram.Show();
|
|
}
|
|
}
|
|
private void CloseSequenceDiagram(WinSequenceDiagram winSequenceDiagram)
|
|
{
|
|
Application.Current.Dispatcher.Invoke(() => {
|
|
if (winSequenceDiagram != null) {
|
|
winSequenceDiagram.Close();
|
|
}
|
|
});
|
|
}
|
|
private void ClosingEvent(object sender, CancelEventArgs e)
|
|
{
|
|
e.Cancel = true;
|
|
(sender as Window).Hide();
|
|
}
|
|
|
|
private void PerformCmdLaserGuideBeam(object obj)
|
|
{
|
|
if (!_Laser.GetPilotLaserSetBitStatus()) {
|
|
_Laser.PilotLaserOn();
|
|
} else {
|
|
_Laser.PilotLaserOff();
|
|
}
|
|
}
|
|
|
|
private void PerformCmdLaserReadyCheck(object obj)
|
|
{
|
|
// 추후 Write bit 파라미터화 해야함
|
|
if(toggleIO)
|
|
{
|
|
_IODevice._iOUnit.WriteDoBit(9, true);
|
|
_IODevice._iOUnit.WriteDoBit(13, true);
|
|
toggleIO = false;
|
|
}
|
|
else
|
|
{
|
|
_IODevice._iOUnit.WriteDoBit(9, false);
|
|
_IODevice._iOUnit.WriteDoBit(13, false);
|
|
toggleIO = true;
|
|
}
|
|
}
|
|
|
|
private void PerformCmdImportObjectFromDXF(object obj)
|
|
{
|
|
System.Windows.Forms.FileDialog dlg = new System.Windows.Forms.OpenFileDialog();
|
|
dlg.InitialDirectory = @"D:\share\jungwoo.jin\모바일글라스도면 외 (3) 파일_20241028";
|
|
dlg.DefaultExt = "dxf";
|
|
dlg.Filter = "DXF 도면 파일 (*.dxf)|*.dxf";
|
|
dlg.Title = "DXF 도면 열기";
|
|
|
|
if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
|
|
CommonHelper.GetMainPage().DxfParser(dlg.FileName);
|
|
}
|
|
}
|
|
}
|
|
}
|