LGES-OC5-PtoP-Welder/WeldingComponents/WeldingCommon/Views/Recipes/UCScannerObjectTeachingControlBoxViewModel.cs
2026-06-05 13:44:39 +09:00

488 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;
}
// 추후 파라미터화 해12함
if (_IODevice.ReadDI(9) &&
_IODevice.ReadDI(24))
{
IsLaserReady = true;
// TODO: PRIBAT_L1, PRIBAT_L2 는 IO에 LaserOnLamp 를 켜고 끄는게 필요함.
// TODO: 우선 주석 처리 해 둠. 레이저 Type 별로 달라서 그런건지 확인하고, 어떻게 공통으로 구현할지를 생각해서 추가해 두자
//_iODevice._iOUnit.WriteDoBit(Convert.ToInt32(ePDOAddress.LaserOnLampOn), true);
} else {
IsLaserReady = false;
// TODO: PRIBAT_L1, PRIBAT_L2 는 IO에 LaserOnLamp 를 켜고 끄는게 필요함.
// TODO: 우선 주석 처리 해 둠. 레이저 Type 별로 달라서 그런건지 확인하고, 어떻게 공통으로 구현할지를 생각해서 추가해 두자
//_iODevice._iOUnit.WriteDoBit(Convert.ToInt32(ePDOAddress.LaserOnLampOn), true);
}
// 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);
}
}
}
}