Compare commits

..

2 Commits

Author SHA1 Message Date
e941e64918 21번 레시피라면 기존처럼 동작하도록 수정 2026-07-21 21:16:47 +09:00
d770494ff0 1.0.0.3 프로그램 업데이트
- RCC NG 프로세스 추가
- 현장 코드에 있는 프로젝트 속성 수정
- RCC 장비 옵션 선택 기능 Disable
2026-07-21 16:29:31 +09:00
31 changed files with 118 additions and 962 deletions

View File

@ -1,9 +1,9 @@
using Aurora.Api; using Aurora.Api;
using Aurora.Api.DataType; using Aurora.Api.DataType;
using Aurora.Api.Devices; using Aurora.Api.Devices;
using PropertyTools.DataAnnotations;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.IO.Ports; using System.IO.Ports;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@ -14,50 +14,6 @@ namespace AuroraLight
public class LightConfig : IDeviceConfig public class LightConfig : IDeviceConfig
{ {
public IConnConfig ConnConfig { get; set; } public IConnConfig ConnConfig { get; set; }
[Category("Light Level")]
[DisplayName("Channel 1 Level (0~255)")]
[Description("Channel 1 Brightness")]
public int Ch1Level { get; set; } = 200;
[Category("Light Level")]
[DisplayName("Channel 2 Level (0~255)")]
[Description("Channel 2 Brightness")]
public int Ch2Level { get; set; } = 200;
[Category("Light Level")]
[DisplayName("Channel 3 Level (0~255)")]
[Description("Channel 3 Brightness")]
public int Ch3Level { get; set; } = 200;
[Category("Light Level")]
[DisplayName("Channel 4 Level (0~255)")]
[Description("Channel 4 Brightness")]
public int Ch4Level { get; set; } = 200;
public int GetChannelLevel(int channel)
{
switch (channel)
{
case 0: return Ch1Level;
case 1: return Ch2Level;
case 2: return Ch3Level;
case 3: return Ch4Level;
default: return Ch1Level;
}
}
public void SetChannelLevel(int channel, int value)
{
switch (channel)
{
case 0: Ch1Level = value; break;
case 1: Ch2Level = value; break;
case 2: Ch3Level = value; break;
case 3: Ch4Level = value; break;
}
}
public LightConfig() public LightConfig()
{ {
ConnConfig = new SerialConnConfig() { ConnConfig = new SerialConnConfig() {
@ -68,10 +24,6 @@ namespace AuroraLight
DataBits = 8, DataBits = 8,
ReadTimeout = 500 ReadTimeout = 500
}; };
Ch1Level = 200;
Ch2Level = 200;
Ch3Level = 200;
Ch4Level = 200;
} }
public static LightConfig GetDefaultConfig() public static LightConfig GetDefaultConfig()
@ -85,10 +37,6 @@ namespace AuroraLight
DataBits = 8, DataBits = 8,
ReadTimeout = 500 ReadTimeout = 500
}; };
config.Ch1Level = 200;
config.Ch2Level = 200;
config.Ch3Level = 200;
config.Ch4Level = 200;
return config; return config;
} }

View File

@ -1,4 +1,4 @@
using Aurora.Api; using Aurora.Api;
using Aurora.Api.DataType; using Aurora.Api.DataType;
using Aurora.Api.Devices; using Aurora.Api.Devices;
using AuroraLight.ALT; using AuroraLight.ALT;
@ -25,7 +25,6 @@ namespace AuroraLight
Logger Log; Logger Log;
internal eLight _lightType; internal eLight _lightType;
internal ILight _light; internal ILight _light;
public LightConfig Config { get; private set; }
public LightDevice(string deviceId, eLight light) public LightDevice(string deviceId, eLight light)
{ {
@ -39,7 +38,6 @@ namespace AuroraLight
protected override int DoActivate(IDeviceConfig config) protected override int DoActivate(IDeviceConfig config)
{ {
var l_config = config as LightConfig; var l_config = config as LightConfig;
Config = l_config;
if (IsSimul) { if (IsSimul) {
return E1.OK; return E1.OK;
@ -59,15 +57,7 @@ namespace AuroraLight
break; break;
} }
bool connected = _light.InitInternal(config.ConnConfig as SerialConnConfig); return _light.InitInternal(config.ConnConfig as SerialConnConfig) ? E1.OK : E2.NOT_CONNECTED;
if (connected && l_config != null) {
int chCount = _lightType == eLight.ALT_8CH ? 8 : 4;
for (int i = 0; i < chCount; i++) {
_light.SetLightValueInternal(i, l_config.GetChannelLevel(i));
}
}
return connected ? E1.OK : E2.NOT_CONNECTED;
} }
} }

View File

@ -1,4 +1,4 @@
<UserControl x:Class="AuroraLight.View.KsLight" <UserControl x:Class="AuroraLight.View.KsLight"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@ -19,9 +19,8 @@
<StackPanel Orientation="Vertical" Margin="0,20,0,20" HorizontalAlignment="Center" VerticalAlignment="Center"> <StackPanel Orientation="Vertical" Margin="0,20,0,20" HorizontalAlignment="Center" VerticalAlignment="Center">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> <StackPanel>
<Button Margin="10,20,10,20" Width="100" Height="40" Command="{Binding CMD_Reload}" Content="ReLoad"/> <Button Margin="0,20,0,20" Width="100" Height="40" Command="{Binding CMD_Reload}" Content="ReLoad"/>
<Button Margin="10,20,10,20" Width="100" Height="40" Command="{Binding CMD_Save}" Content="Save"/>
<!-- <Button Width="100" Height="40" Margin="10" Command="{Binding CMD_GetStat}" Content="GetStat"/> --> <!-- <Button Width="100" Height="40" Margin="10" Command="{Binding CMD_GetStat}" Content="GetStat"/> -->
</StackPanel> </StackPanel>

View File

@ -1,4 +1,4 @@
using Aurora; using Aurora;
using Aurora.Api; using Aurora.Api;
using Aurora.View; using Aurora.View;
using Hermes; using Hermes;
@ -140,12 +140,6 @@ namespace AuroraLight.View
{ {
if (_LightDevice1 != null && _LightDevice1._light != null) if (_LightDevice1 != null && _LightDevice1._light != null)
_LightDevice1._light.SetLightValueInternal(cbChannel1, value); _LightDevice1._light.SetLightValueInternal(cbChannel1, value);
var config = _aurora?.DeviceManager?.GetDeviceConfig(_deviceId1) as LightConfig;
if (config != null)
{
config.SetChannelLevel(cbChannel1, value);
}
} }
} }
catch (Exception ex) catch (Exception ex)
@ -167,12 +161,6 @@ namespace AuroraLight.View
{ {
if (_LightDevice2 != null && _LightDevice2._light != null) if (_LightDevice2 != null && _LightDevice2._light != null)
_LightDevice2._light.SetLightValueInternal(cbChannel2, value); _LightDevice2._light.SetLightValueInternal(cbChannel2, value);
var config = _aurora?.DeviceManager?.GetDeviceConfig(_deviceId2) as LightConfig;
if (config != null)
{
config.SetChannelLevel(cbChannel2, value);
}
} }
} }
catch (Exception ex) catch (Exception ex)
@ -203,48 +191,10 @@ namespace AuroraLight.View
public List<int> lsChannel2 { get => _lsChannel2; set => SetProperty(ref _lsChannel2, value); } public List<int> lsChannel2 { get => _lsChannel2; set => SetProperty(ref _lsChannel2, value); }
private int _cbChannel1; private int _cbChannel1;
public int cbChannel1 public int cbChannel1 { get => _cbChannel1; set => SetProperty(ref _cbChannel1, value); }
{
get => _cbChannel1;
set
{
if (SetProperty(ref _cbChannel1, value))
{
var config = _aurora?.DeviceManager?.GetDeviceConfig(_deviceId1) as LightConfig;
if (config != null)
{
int chLevel = config.GetChannelLevel(value);
if (_nSliderValue1 != chLevel)
{
_nSliderValue1 = chLevel;
NotifyPropertyChanged(nameof(nSliderValue1));
}
}
}
}
}
private int _cbChannel2; private int _cbChannel2;
public int cbChannel2 public int cbChannel2 { get => _cbChannel2; set => SetProperty(ref _cbChannel2, value); }
{
get => _cbChannel2;
set
{
if (SetProperty(ref _cbChannel2, value))
{
var config = _aurora?.DeviceManager?.GetDeviceConfig(_deviceId2) as LightConfig;
if (config != null)
{
int chLevel = config.GetChannelLevel(value);
if (_nSliderValue2 != chLevel)
{
_nSliderValue2 = chLevel;
NotifyPropertyChanged(nameof(nSliderValue2));
}
}
}
}
}
@ -271,17 +221,6 @@ namespace AuroraLight.View
_LightDevice2._light.SetLightValueInternal(cbChannelALL, value); _LightDevice2._light.SetLightValueInternal(cbChannelALL, value);
} }
var config1 = _aurora?.DeviceManager?.GetDeviceConfig(_deviceId1) as LightConfig;
if (config1 != null)
{
config1.SetChannelLevel(cbChannelALL, value);
}
var config2 = _aurora?.DeviceManager?.GetDeviceConfig(_deviceId2) as LightConfig;
if (config2 != null)
{
config2.SetChannelLevel(cbChannelALL, value);
}
nSliderValue1 = value; nSliderValue1 = value;
nSliderValue2 = value; nSliderValue2 = value;
} }
@ -323,13 +262,9 @@ namespace AuroraLight.View
public ICommand CMD_LightOnOffALL { get; } public ICommand CMD_LightOnOffALL { get; }
public ICommand CMD_Reload { get; } public ICommand CMD_Reload { get; }
public ICommand CMD_Save { get; }
public ICommand CMD_GetStat { get; } public ICommand CMD_GetStat { get; }
#endregion #endregion
private IAuroraEnvironment _aurora;
private string _deviceId1;
private string _deviceId2;
private LightDevice _LightDevice1; private LightDevice _LightDevice1;
private LightDevice _LightDevice2; private LightDevice _LightDevice2;
@ -340,30 +275,35 @@ namespace AuroraLight.View
public KsLightModel(IAuroraEnvironment aurora, string deviceId1, string deviceId2) public KsLightModel(IAuroraEnvironment aurora, string deviceId1, string deviceId2)
{ {
_aurora = aurora;
_deviceId1 = deviceId1;
_deviceId2 = deviceId2;
_LightDevice1 = aurora.DeviceManager[deviceId1] as LightDevice; _LightDevice1 = aurora.DeviceManager[deviceId1] as LightDevice;
_LightDevice2 = aurora.DeviceManager[deviceId2] as LightDevice; _LightDevice2 = aurora.DeviceManager[deviceId2] as LightDevice;
IsActive1 = true; IsActive1 = true;
IsActive2 = true; IsActive2 = true;
IsActiveALL = true; IsActiveALL = true;
SliderName1 = _LightDevice1 != null ? _LightDevice1.DeviceId : deviceId1; SliderName1 = _LightDevice1.DeviceId;
SliderName2 = _LightDevice2 != null ? _LightDevice2.DeviceId : deviceId2; SliderName2 = _LightDevice2.DeviceId;
#region Initialize Binding Properties #region Initialize Binding Properties
// config 에서 읽어와서 update 해야한다. device 등록할 때 config 만든 config 를 받아올 것. 임시로 고정값 입력
nSliderMax = 100; nSliderMax = 100;
_nSliderValue1 = 0; nSliderValue1 = 0;
_nSliderValue2 = 0; nSliderValue2 = 0;
_nSliderValueALL = 0; nSliderValueALL = 0;
if ((_LightDevice1 != null && _LightDevice1._lightType == eLight.ERI) && (_LightDevice2 != null && _LightDevice2._lightType == eLight.ERI)) if ((_LightDevice1 != null && _LightDevice1._lightType == eLight.ERI) && (_LightDevice2 != null && _LightDevice2._lightType == eLight.ERI))
{ {
// 안타깝게도 채널수나 config 는 추상화항목에 없다. 추후에 업데이트하겠음. 일단은 type convert 해서 가져옴
// activate 된 후에나 class 생성이 된다. 클래스에서 property 를 가져올수없음
//var lightdevice = _LightDevice as ERILight;
//nChannel = lightdevice.GetChannelCount();
nChannel = 4; nChannel = 4;
nSliderMax = 255; nSliderMax = 255;
nSliderValue1 = 200;
nSliderValue2 = 200;
nSliderValueALL = 200;
} }
else nChannel = 8; else nChannel = 8;
@ -379,39 +319,16 @@ namespace AuroraLight.View
int nChannelMax2 = nChannel; // default setting int nChannelMax2 = nChannel; // default setting
for (int i = 0; i < nChannelMax2; i++) lsChannel2.Add(i); for (int i = 0; i < nChannelMax2; i++) lsChannel2.Add(i);
buttonOnOffToggle1 = true;
strButtonOnOff1 = "ON";
buttonOnOffToggle2 = true;
strButtonOnOff2 = "ON";
lsChannelALL = new List<int>(); lsChannelALL = new List<int>();
int nChannelMaxALL = nChannel; // default setting int nChannelMaxALL = nChannel; // default setting
for (int i = 0; i < nChannelMaxALL; i++) lsChannelALL.Add(i); for (int i = 0; i < nChannelMaxALL; i++) lsChannelALL.Add(i);
strButtonOnOffALL = "ON";
// Read saved values from LightConfig
var config1 = _aurora?.DeviceManager?.GetDeviceConfig(_deviceId1) as LightConfig;
var config2 = _aurora?.DeviceManager?.GetDeviceConfig(_deviceId2) as LightConfig;
_nSliderValue1 = config1 != null ? config1.GetChannelLevel(cbChannel1) : 200;
_nSliderValue2 = config2 != null ? config2.GetChannelLevel(cbChannel2) : 200;
_nSliderValueALL = _nSliderValue1;
NotifyPropertyChanged(nameof(nSliderValue1));
NotifyPropertyChanged(nameof(nSliderValue2));
NotifyPropertyChanged(nameof(nSliderValueALL));
// Turn on lights with configured brightness values
if (_LightDevice1 != null && _LightDevice1._light != null)
{
_LightDevice1._light.SetLightValueInternal(cbChannel1, _nSliderValue1);
}
if (_LightDevice2 != null && _LightDevice2._light != null)
{
_LightDevice2._light.SetLightValueInternal(cbChannel2, _nSliderValue2);
}
buttonOnOffToggle1 = false;
strButtonOnOff1 = "OFF";
buttonOnOffToggle2 = false;
strButtonOnOff2 = "OFF";
buttonOnOffToggleALL = false;
strButtonOnOffALL = "OFF";
#endregion #endregion
@ -421,7 +338,6 @@ namespace AuroraLight.View
CMD_LightOnOffALL = new DelegateCommand(LightOnOffALL); CMD_LightOnOffALL = new DelegateCommand(LightOnOffALL);
CMD_Reload = new DelegateCommand(ReLoad); CMD_Reload = new DelegateCommand(ReLoad);
CMD_Save = new DelegateCommand(Save);
CMD_GetStat = new DelegateCommand(GetStat); CMD_GetStat = new DelegateCommand(GetStat);
#endregion #endregion
} }
@ -435,7 +351,7 @@ namespace AuroraLight.View
private void ReLoad(object obj) private void ReLoad(object obj)
{ {
if (_LightDevice1 != null && _LightDevice1.IsActivated) if (_LightDevice1.IsActivated)
{ {
IsActive1 = true; IsActive1 = true;
} }
@ -444,7 +360,7 @@ namespace AuroraLight.View
IsActive1 = false; IsActive1 = false;
} }
if (_LightDevice2 != null && _LightDevice2.IsActivated) if (_LightDevice2.IsActivated)
{ {
IsActive2 = true; IsActive2 = true;
} }
@ -461,51 +377,6 @@ namespace AuroraLight.View
{ {
IsActiveALL = false; IsActiveALL = false;
} }
if (_aurora != null && _aurora.DeviceManager != null)
{
var config1 = _aurora.DeviceManager.GetDeviceConfig(_deviceId1) as LightConfig;
if (config1 != null)
{
_nSliderValue1 = config1.GetChannelLevel(cbChannel1);
NotifyPropertyChanged(nameof(nSliderValue1));
}
var config2 = _aurora.DeviceManager.GetDeviceConfig(_deviceId2) as LightConfig;
if (config2 != null)
{
_nSliderValue2 = config2.GetChannelLevel(cbChannel2);
NotifyPropertyChanged(nameof(nSliderValue2));
}
}
}
private void Save(object obj)
{
try
{
if (_aurora != null && _aurora.DeviceManager != null)
{
var config1 = _aurora.DeviceManager.GetDeviceConfig(_deviceId1) as LightConfig;
if (config1 != null)
{
config1.SetChannelLevel(cbChannel1, nSliderValue1);
_aurora.DeviceManager.SaveDeviceConfig(_deviceId1);
}
var config2 = _aurora.DeviceManager.GetDeviceConfig(_deviceId2) as LightConfig;
if (config2 != null)
{
config2.SetChannelLevel(cbChannel2, nSliderValue2);
_aurora.DeviceManager.SaveDeviceConfig(_deviceId2);
}
MessageUtil.ShowSuccessToast("Light configuration saved.");
}
}
catch (Exception ex)
{
MessageUtil.ShowErrorToast($"Failed to save light config: {ex.Message}");
}
} }
private void LightOnOff1(object obj) private void LightOnOff1(object obj)

View File

@ -1,4 +1,4 @@
using Aurora; using Aurora;
using Aurora.View; using Aurora.View;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -17,12 +17,6 @@ namespace AuroraLight.View
if (SetProperty(ref _nSliderValue, value)) { if (SetProperty(ref _nSliderValue, value)) {
if (_LightDevice != null && _LightDevice._light != null) if (_LightDevice != null && _LightDevice._light != null)
_LightDevice._light.SetLightValueInternal(cbChannel, value); _LightDevice._light.SetLightValueInternal(cbChannel, value);
var config = _aurora?.DeviceManager?.GetDeviceConfig(_deviceId) as LightConfig;
if (config != null)
{
config.SetChannelLevel(cbChannel, value);
}
} }
} catch (Exception ex) { } catch (Exception ex) {
} }
@ -40,45 +34,32 @@ namespace AuroraLight.View
private List<int> _lsChannel; private List<int> _lsChannel;
public List<int> lsChannel { get => _lsChannel; set => SetProperty(ref _lsChannel, value); } public List<int> lsChannel { get => _lsChannel; set => SetProperty(ref _lsChannel, value); }
private int _cbChannel; private int _cbChannel;
public int cbChannel { public int cbChannel { get => _cbChannel; set => SetProperty(ref _cbChannel, value); }
get => _cbChannel;
set {
if (SetProperty(ref _cbChannel, value)) {
var config = _aurora?.DeviceManager?.GetDeviceConfig(_deviceId) as LightConfig;
if (config != null) {
int chLevel = config.GetChannelLevel(value);
if (_nSliderValue != chLevel) {
_nSliderValue = chLevel;
NotifyPropertyChanged(nameof(nSliderValue));
}
}
}
}
}
#endregion #endregion
#region EventCommands #region EventCommands
public ICommand CMD_LightOnOff { get; } public ICommand CMD_LightOnOff { get; }
public ICommand CMD_Save { get; }
#endregion #endregion
private IAuroraEnvironment _aurora;
private string _deviceId;
private LightDevice _LightDevice; private LightDevice _LightDevice;
public UCLightViewModel(IAuroraEnvironment aurora, string deviceId) public UCLightViewModel(IAuroraEnvironment aurora, string deviceId)
{ {
_aurora = aurora;
_deviceId = deviceId;
_LightDevice = aurora.DeviceManager[deviceId] as LightDevice; _LightDevice = aurora.DeviceManager[deviceId] as LightDevice;
#region Initialize Binding Properties #region Initialize Binding Properties
// config 에서 읽어와서 update 해야한다. device 등록할 때 config 만든 config 를 받아올 것. 임시로 고정값 입력
nSliderMax = 100; nSliderMax = 100;
_nSliderValue = 0; nSliderValue = 0;
if (_LightDevice != null && _LightDevice._lightType == eLight.ERI) { if (_LightDevice != null && _LightDevice._lightType == eLight.ERI) {
// 안타깝게도 채널수나 config 는 추상화항목에 없다. 추후에 업데이트하겠음. 일단은 type convert 해서 가져옴
// activate 된 후에나 class 생성이 된다. 클래스에서 property 를 가져올수없음
//var lightdevice = _LightDevice as ERILight;
//nChannel = lightdevice.GetChannelCount();
nChannel = 4; nChannel = 4;
nSliderMax = 255; nSliderMax = 255;
nSliderValue = 180;
} else nChannel = 8; } else nChannel = 8;
if (lsChannel != null) if (lsChannel != null)
@ -88,42 +69,17 @@ namespace AuroraLight.View
for (int i = 0; i < nChannelMax; i++) for (int i = 0; i < nChannelMax; i++)
lsChannel.Add(i); lsChannel.Add(i);
var config = _aurora?.DeviceManager?.GetDeviceConfig(_deviceId) as LightConfig; buttonOnOffToggle = true;
_nSliderValue = config != null ? config.GetChannelLevel(cbChannel) : 200; strButtonOnOff = "ON";
NotifyPropertyChanged(nameof(nSliderValue));
if (_LightDevice != null && _LightDevice._light != null) {
_LightDevice._light.SetLightValueInternal(cbChannel, _nSliderValue);
}
buttonOnOffToggle = false;
strButtonOnOff = "OFF";
#endregion #endregion
#region DelegateCommands #region DelegateCommands
CMD_LightOnOff = new DelegateCommand(LightOnOff); CMD_LightOnOff = new DelegateCommand(LightOnOff);
CMD_Save = new DelegateCommand(Save);
#endregion #endregion
} }
private void Save(object obj)
{
try {
if (_aurora != null && _aurora.DeviceManager != null) {
var config = _aurora.DeviceManager.GetDeviceConfig(_deviceId) as LightConfig;
if (config != null) {
config.SetChannelLevel(cbChannel, nSliderValue);
_aurora.DeviceManager.SaveDeviceConfig(_deviceId);
}
MessageUtil.ShowSuccessToast("Light configuration saved.");
}
} catch (Exception ex) {
MessageUtil.ShowErrorToast($"Failed to save light config: {ex.Message}");
}
}
private void LightOnOff(object obj) private void LightOnOff(object obj)
{ {
if (_LightDevice != null && _LightDevice._light != null) { if (_LightDevice != null && _LightDevice._light != null) {

View File

@ -431,9 +431,6 @@ namespace CogUI {
return DisplayDrawer.ExistsGetInteractiveGraphic(cogDisplay, CogConstants.KEY_TRAIN_ORIGIN); return DisplayDrawer.ExistsGetInteractiveGraphic(cogDisplay, CogConstants.KEY_TRAIN_ORIGIN);
} }
public void UpdateRadiusOfTrainOrigin(double radius) {
}
public void AddRoi(ROI roi, eColor color, bool isRotatable = false) { public void AddRoi(ROI roi, eColor color, bool isRotatable = false) {
if (ROI.IsNullOrEmpty(roi)) { if (ROI.IsNullOrEmpty(roi)) {
DisplayDrawer.AddRoi(cogDisplay, ColorConverter.ConvertColor(color), roi, CogConstants.KEY_ROI); DisplayDrawer.AddRoi(cogDisplay, ColorConverter.ConvertColor(color), roi, CogConstants.KEY_ROI);

View File

@ -219,8 +219,5 @@ namespace CogUI {
NotifyPropertyChanged(nameof(RunParam)); NotifyPropertyChanged(nameof(RunParam));
} }
} }
public void UpdateRadiusOfRoi(eGraRoiType graRoiType, double radius) {
}
} }
} }

View File

@ -409,8 +409,5 @@ namespace CogUI {
NotifyPropertyChanged(nameof(TrainParam)); NotifyPropertyChanged(nameof(TrainParam));
} }
} }
public void UpdateRadiusOfRoi(eGraRoiType graRoiType, double radius) {
}
} }
} }

View File

@ -290,8 +290,5 @@ namespace CogUI {
NotifyPropertyChanged(nameof(RunParam)); NotifyPropertyChanged(nameof(RunParam));
} }
} }
public void UpdateRadiusOfRoi(eGraRoiType graRoiType, double radius) {
}
} }
} }

View File

@ -12,7 +12,6 @@ namespace MilPattern {
public class PmParamExt : ICloneable { public class PmParamExt : ICloneable {
private const string FILE_NAME = "PmParamExt.json"; private const string FILE_NAME = "PmParamExt.json";
public ROI FindROI { get; set; } = new ROI(); public ROI FindROI { get; set; } = new ROI();
public double TrainRoiSize { get; set; } = 25.0;
public PmParamExt() { public PmParamExt() {
} }
@ -23,8 +22,7 @@ namespace MilPattern {
public object Clone() { public object Clone() {
return new PmParamExt() { return new PmParamExt() {
FindROI = FindROI.Clone() as ROI, FindROI = FindROI.Clone() as ROI
TrainRoiSize = TrainRoiSize
}; };
} }

View File

@ -1,4 +1,4 @@
using Aurora.Api; using Aurora.Api;
using Aurora.Api.DataType; using Aurora.Api.DataType;
using Hermes; using Hermes;
using Hermes.Functional; using Hermes.Functional;
@ -61,10 +61,8 @@ namespace MilUI {
#region TrainRoi & FindRoi Changed Event #region TrainRoi & FindRoi Changed Event
private GCHandle _TrainRoiChangedDataHandle; private GCHandle _TrainRoiChangedDataHandle;
private GCHandle _TrainOriginChangedDataHandle;
private Dictionary<eRoiIdx, GCHandle> _FindRoiChangedDataHandles = new Dictionary<eRoiIdx, GCHandle>(); private Dictionary<eRoiIdx, GCHandle> _FindRoiChangedDataHandles = new Dictionary<eRoiIdx, GCHandle>();
private MIL_GRA_HOOK_FUNCTION_PTR _OnTrainRoiChangedFuncPtr; private MIL_GRA_HOOK_FUNCTION_PTR _OnTrainRoiChangedFuncPtr;
private MIL_GRA_HOOK_FUNCTION_PTR _OnTrainOriginChangedFuncPtr;
private Dictionary<eRoiIdx, MIL_GRA_HOOK_FUNCTION_PTR> _OnFindRoiChangedFuncPtrs = new Dictionary<eRoiIdx, MIL_GRA_HOOK_FUNCTION_PTR>(); private Dictionary<eRoiIdx, MIL_GRA_HOOK_FUNCTION_PTR> _OnFindRoiChangedFuncPtrs = new Dictionary<eRoiIdx, MIL_GRA_HOOK_FUNCTION_PTR>();
#endregion #endregion
@ -646,15 +644,11 @@ namespace MilUI {
return E1.GENERIC; return E1.GENERIC;
} }
double radius = imageCenter.Length > 0 ? imageCenter.Length : 25; MIL.MgraArc(GraphicContext, StaticGraphicList, imageCenter.Origin.X, imageCenter.Origin.Y, 25, 25, 0, 360);
MIL.MgraArc(GraphicContext, StaticGraphicList, imageCenter.Origin.X, imageCenter.Origin.Y, radius, radius, 0, 360);
MIL.MgraInquireList(StaticGraphicList, MIL.M_LIST, MIL.M_DEFAULT, MIL.M_LAST_LABEL, ref _trainOriginLabel); MIL.MgraInquireList(StaticGraphicList, MIL.M_LIST, MIL.M_DEFAULT, MIL.M_LAST_LABEL, ref _trainOriginLabel);
MIL.MgraControlList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_trainOriginLabel), MIL.M_DEFAULT, MIL.M_RESIZABLE, MIL.M_ENABLE); MIL.MgraControlList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_trainOriginLabel), MIL.M_DEFAULT, MIL.M_RESIZABLE, MIL.M_DISABLE);
MIL.MgraControlList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_trainOriginLabel), MIL.M_DEFAULT, MIL.M_CONSTRAIN_ASPECT_RATIO, 1.0);
MIL.MgraControlList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_trainOriginLabel), MIL.M_DEFAULT, MIL.M_SPECIFIC_FEATURES_EDITABLE, MIL.M_DISABLE); MIL.MgraControlList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_trainOriginLabel), MIL.M_DEFAULT, MIL.M_SPECIFIC_FEATURES_EDITABLE, MIL.M_DISABLE);
SetTrainOriginChangedEvent();
_trainGraphics.Add(); _trainGraphics.Add();
return E1.OK; return E1.OK;
@ -667,23 +661,10 @@ namespace MilUI {
double x = 0; double x = 0;
double y = 0; double y = 0;
double radius = 0;
MIL.MgraInquireList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_trainOriginLabel), MIL.M_DEFAULT, MIL.M_POSITION_X, ref x); MIL.MgraInquireList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_trainOriginLabel), MIL.M_DEFAULT, MIL.M_POSITION_X, ref x);
MIL.MgraInquireList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_trainOriginLabel), MIL.M_DEFAULT, MIL.M_POSITION_Y, ref y); MIL.MgraInquireList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_trainOriginLabel), MIL.M_DEFAULT, MIL.M_POSITION_Y, ref y);
MIL.MgraInquireList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_trainOriginLabel), MIL.M_DEFAULT, MIL.M_RADIUS_X, ref radius);
return new Cross(new ImagePoint(x, y), radius); return new Cross(new ImagePoint(x, y));
}
public void UpdateRadiusOfTrainOrigin(double radius) {
if (HasTrainOrigin()) {
MIL.MgraControlList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_trainOriginLabel), MIL.M_DEFAULT, MIL.M_RADIUS_X, radius);
MIL.MgraControlList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_trainOriginLabel), MIL.M_DEFAULT, MIL.M_RADIUS_Y, radius);
}
}
public bool HasTrainOrigin() {
return _trainGraphics != null && _trainGraphics.HasGraphicLabel(_trainOriginLabel);
} }
public int AddDefaultFindRoi(ImageSize imageSize, bool isRotatable = false) { public int AddDefaultFindRoi(ImageSize imageSize, bool isRotatable = false) {
@ -879,8 +860,6 @@ namespace MilUI {
} }
public int ClearTrainGraphics(eGraphicToClear graphicToClear = eGraphicToClear.ALL) { public int ClearTrainGraphics(eGraphicToClear graphicToClear = eGraphicToClear.ALL) {
RemoveTrainRoiChangedEvent();
RemoveTrainOriginChangedEvent();
_trainGraphics?.Clear(); _trainGraphics?.Clear();
_trainRoiLabel = MIL.M_NULL; _trainRoiLabel = MIL.M_NULL;
_trainOriginLabel = MIL.M_NULL; _trainOriginLabel = MIL.M_NULL;
@ -1072,68 +1051,6 @@ namespace MilUI {
} }
} }
private void SetTrainOriginChangedEvent() {
RemoveTrainOriginChangedEvent();
if (!_TrainOriginChangedDataHandle.IsAllocated) {
if (_trainOriginLabel != MIL.M_NULL) {
_TrainOriginChangedDataHandle = GCHandle.Alloc(_trainOriginLabel);
_OnTrainOriginChangedFuncPtr = new MIL_GRA_HOOK_FUNCTION_PTR(OnTrainOriginChanged);
MIL.MgraHookFunction(StaticGraphicList, MIL.M_INTERACTIVE_GRAPHIC_STATE_MODIFIED, _OnTrainOriginChangedFuncPtr, GCHandle.ToIntPtr(_TrainOriginChangedDataHandle));
}
}
}
private void RemoveTrainOriginChangedEvent() {
if (_TrainOriginChangedDataHandle.IsAllocated) {
MIL.MgraHookFunction(StaticGraphicList, MIL.M_INTERACTIVE_GRAPHIC_STATE_MODIFIED + MIL.M_UNHOOK, _OnTrainOriginChangedFuncPtr, GCHandle.ToIntPtr(_TrainOriginChangedDataHandle));
_OnTrainOriginChangedFuncPtr = null;
_TrainOriginChangedDataHandle.Free();
}
}
private MIL_INT OnTrainOriginChanged(MIL_INT HookType, MIL_ID EventId, IntPtr UserDataPtr) {
try {
if (_trainOriginLabel == MIL.M_NULL) {
return MIL.M_NULL;
}
if (!IntPtr.Zero.Equals(UserDataPtr)) {
MIL_INT curState = 0;
MIL.MgraGetHookInfo(EventId, MIL.M_INTERACTIVE_GRAPHIC_STATE, ref curState);
if (curState == MIL.M_STATE_GRAPHIC_HOVERED || curState == MIL.M_STATE_HANDLE_HOVERED) {
return MIL.M_NULL;
}
MIL_INT modifiedGraphicLabel = 0;
MIL.MgraGetHookInfo(EventId, MIL.M_GRAPHIC_LABEL_VALUE, ref modifiedGraphicLabel);
if (modifiedGraphicLabel == _trainOriginLabel) {
double radiusX = 0;
MIL.MgraInquireList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_trainOriginLabel), MIL.M_DEFAULT, MIL.M_RADIUS_X, ref radiusX);
if (radiusX > 500.0) {
radiusX = 500.0;
MIL.MgraControlList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_trainOriginLabel), MIL.M_DEFAULT, MIL.M_RADIUS_X, 500.0);
MIL.MgraControlList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_trainOriginLabel), MIL.M_DEFAULT, MIL.M_RADIUS_Y, 500.0);
}
if (_PatternInfos.ContainsKey(eRoiIdx.Roi0) && _GraEventSubscribers?.Count > 0) {
var patternInfo = _PatternInfos[eRoiIdx.Roi0];
if (_GraEventSubscribers.ContainsKey(patternInfo)) {
_GraEventSubscribers[patternInfo]?.UpdateRadiusOfRoi(eGraRoiType.TrainOrigin, radiusX);
}
}
}
}
}
catch (Exception e) {
_Logger?.FuncE(e.Message);
}
return MIL.M_NULL;
}
private void RemoveFindRoiChangedEvent(eRoiIdx roiIdx) { private void RemoveFindRoiChangedEvent(eRoiIdx roiIdx) {
if (_FindRoiChangedDataHandles.ContainsKey(roiIdx) && _FindRoiChangedDataHandles[roiIdx].IsAllocated) { if (_FindRoiChangedDataHandles.ContainsKey(roiIdx) && _FindRoiChangedDataHandles[roiIdx].IsAllocated) {
MIL.MgraHookFunction(StaticGraphicList, MIL.M_INTERACTIVE_GRAPHIC_STATE_MODIFIED + MIL.M_UNHOOK, _OnFindRoiChangedFuncPtrs[roiIdx], GCHandle.ToIntPtr(_FindRoiChangedDataHandles[roiIdx])); MIL.MgraHookFunction(StaticGraphicList, MIL.M_INTERACTIVE_GRAPHIC_STATE_MODIFIED + MIL.M_UNHOOK, _OnFindRoiChangedFuncPtrs[roiIdx], GCHandle.ToIntPtr(_FindRoiChangedDataHandles[roiIdx]));
@ -1210,7 +1127,6 @@ namespace MilUI {
private void RemoveHookFunc() { private void RemoveHookFunc() {
RemoveTrainRoiChangedEvent(); RemoveTrainRoiChangedEvent();
RemoveTrainOriginChangedEvent();
for (int i = 0; i < _FindRoiChangedDataHandles.Count; i++) { for (int i = 0; i < _FindRoiChangedDataHandles.Count; i++) {
RemoveFindRoiChangedEvent((eRoiIdx)i); RemoveFindRoiChangedEvent((eRoiIdx)i);
} }

View File

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Windows; using System.Windows;
@ -220,8 +220,5 @@ namespace MilUI {
NotifyPropertyChanged(nameof(RunParam)); NotifyPropertyChanged(nameof(RunParam));
} }
} }
public void UpdateRadiusOfRoi(eGraRoiType graRoiType, double radius) {
}
} }
} }

View File

@ -174,7 +174,6 @@ namespace MilUI {
if (result == MessageBoxResult.Yes) { if (result == MessageBoxResult.Yes) {
var mainPatternInfo = _patternAgent.GetMainPatternInfo(_patternInfo.GetPatternIndex()); var mainPatternInfo = _patternAgent.GetMainPatternInfo(_patternInfo.GetPatternIndex());
if (E1.OK == _patternAgent.CopyPattern(mainPatternInfo.GetPatternIndex(), _patternInfo.GetPatternIndex())) { if (E1.OK == _patternAgent.CopyPattern(mainPatternInfo.GetPatternIndex(), _patternInfo.GetPatternIndex())) {
DeactivateRegisteredSubPattern();
InitRunParam(); InitRunParam();
InitFixturePatterns(); InitFixturePatterns();
UpdateControlButtons(true); UpdateControlButtons(true);
@ -187,7 +186,6 @@ namespace MilUI {
if (!_patternAgent.IsPatternExist(_patternInfo.GetPatternIndex())) { if (!_patternAgent.IsPatternExist(_patternInfo.GetPatternIndex())) {
if (E1.OK == _patternAgent.Create(_patternInfo) && if (E1.OK == _patternAgent.Create(_patternInfo) &&
E1.OK == _patternAgent.Save(_patternInfo)) { E1.OK == _patternAgent.Save(_patternInfo)) {
DeactivateRegisteredSubPattern();
InitRunParam(); InitRunParam();
InitFixturePatterns(); InitFixturePatterns();
UpdateControlButtons(true); UpdateControlButtons(true);
@ -216,34 +214,12 @@ namespace MilUI {
var result = MessageBoxUtil.ShowMessageBoxQuestion(StrTokens.MSG_Q_Delete); var result = MessageBoxUtil.ShowMessageBoxQuestion(StrTokens.MSG_Q_Delete);
if (result == MessageBoxResult.Yes) { if (result == MessageBoxResult.Yes) {
if (_patternAgent.IsPatternExist(_patternInfo.GetPatternIndex())) { if (_patternAgent.IsPatternExist(_patternInfo.GetPatternIndex())) {
if (_patternAgent.IsPatternFileLocked(_patternInfo, out string lockedFilePath)) {
MessageBoxUtil.ShowMessageBoxError(PatternAgentBase.GetPatternFileLockedMessage(lockedFilePath));
return;
}
if (E1.OK == _patternAgent.Remove(_patternInfo)) { if (E1.OK == _patternAgent.Remove(_patternInfo)) {
UpdateControlButtons(false); UpdateControlButtons(false);
} }
else {
MessageBoxUtil.ShowMessageBoxError(PatternAgentBase.GetPatternFileLockedMessage(string.Empty));
} }
} }
} }
}
// 서브 패턴은 OFF(IsActivated = false) 로 등록한다. 작업자가 확인한 뒤 ON 으로 바꾼다.
private void DeactivateRegisteredSubPattern() {
if (!IsSubPattern) {
return;
}
_patternInfo.IsActivated = false;
var registeredPatternInfo = _patternAgent.GetPatternInfo(_patternInfo.GetPatternIndex());
if (registeredPatternInfo != null) {
registeredPatternInfo.IsActivated = false;
_patternAgent.Save(registeredPatternInfo);
}
}
private void ClosingWindow() { private void ClosingWindow() {
_cameraDisplay.ClearTrainGraphics(); _cameraDisplay.ClearTrainGraphics();
@ -434,8 +410,5 @@ namespace MilUI {
NotifyPropertyChanged(nameof(TrainParam)); NotifyPropertyChanged(nameof(TrainParam));
} }
} }
public void UpdateRadiusOfRoi(eGraRoiType graRoiType, double radius) {
}
} }
} }

View File

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Windows; using System.Windows;
@ -290,8 +290,5 @@ namespace MilUI {
NotifyPropertyChanged(nameof(RunParam)); NotifyPropertyChanged(nameof(RunParam));
} }
} }
public void UpdateRadiusOfRoi(eGraRoiType graRoiType, double radius) {
}
} }
} }

View File

@ -170,9 +170,6 @@ namespace MilUI {
} }
} }
public void UpdateRadiusOfRoi(eGraRoiType graRoiType, double radius) {
}
private double ConvertDegreeDecimalPlaces(double degree) { private double ConvertDegreeDecimalPlaces(double degree) {
return Math.Round(degree, 1); return Math.Round(degree, 1);
} }

View File

@ -1,4 +1,4 @@
<UserControl x:Class="MilUI.PatternMatchingSettingView" <UserControl x:Class="MilUI.PatternMatchingSettingView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@ -65,7 +65,6 @@
<RowDefinition/> <RowDefinition/>
<RowDefinition/> <RowDefinition/>
<RowDefinition/> <RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition/> <ColumnDefinition/>
@ -128,15 +127,6 @@
</TextBlock> </TextBlock>
</visionCommonUI:UCContentComboBox> </visionCommonUI:UCContentComboBox>
</Grid> </Grid>
<visionCommonUI:UCContentSlider Grid.Row="3" Grid.ColumnSpan="2" Margin="5"
MinValue="1" MaxValue="500" TickFrequency="10" Step="1"
KeyValue="{Binding ElementName=patternMatchingSettingView, Path=DataContext.TrainRoiSize}">
<TextBlock Style="{StaticResource stylePatternSliderTextBlock}">
<Run Text="{Binding [Train], Source={StaticResource langTokens}, Mode=OneWay}"/>
<Run Text="{Binding [ROI], Source={StaticResource langTokens}, Mode=OneWay}"/>
</TextBlock>
</visionCommonUI:UCContentSlider>
</Grid> </Grid>
</GroupBox> </GroupBox>

View File

@ -19,7 +19,7 @@ using VisionCommonUI;
using VisionCommonUI.Resources; using VisionCommonUI.Resources;
namespace MilUI { namespace MilUI {
public class PatternMatchingSettingViewModel : NotifyPropertyChangedBase, IGraEventSubscriber { public class PatternMatchingSettingViewModel : NotifyPropertyChangedBase {
private Logger _logger = new Logger("PatternMatchingSettingVM"); private Logger _logger = new Logger("PatternMatchingSettingVM");
public ICommand CMD_VisibleChanged { get; } public ICommand CMD_VisibleChanged { get; }
@ -57,25 +57,6 @@ namespace MilUI {
private PatternMatchingRunParam _runParam; private PatternMatchingRunParam _runParam;
public PatternMatchingRunParam RunParam { get => _runParam; set => SetProperty(ref _runParam, value); } public PatternMatchingRunParam RunParam { get => _runParam; set => SetProperty(ref _runParam, value); }
private double _trainRoiSize = 25;
public double TrainRoiSize {
get => _trainRoiSize;
set {
if (SetProperty(ref _trainRoiSize, value)) {
if (RunParam?.PmParamExt != null) {
RunParam.PmParamExt.TrainRoiSize = value;
}
if (!_isUpdatingFromDisplay) {
if (_cameraDisplay != null && _cameraDisplay.HasTrainOrigin()) {
_cameraDisplay.UpdateRadiusOfTrainOrigin(value);
}
}
}
}
}
private bool _isUpdatingFromDisplay = false;
private IEnumerable<int> _fixturePatterns; private IEnumerable<int> _fixturePatterns;
public IEnumerable<int> FixturePatterns { get => _fixturePatterns; set => SetProperty(ref _fixturePatterns, value); } public IEnumerable<int> FixturePatterns { get => _fixturePatterns; set => SetProperty(ref _fixturePatterns, value); }
@ -115,7 +96,6 @@ namespace MilUI {
InitRunParam(); InitRunParam();
InitFixturePatterns(); InitFixturePatterns();
UpdateControlButtons(IsPatternRegistered); UpdateControlButtons(IsPatternRegistered);
_cameraDisplay.SetGraEventSubscriber(_patternInfo, this);
} }
public void InitRegistered() { public void InitRegistered() {
@ -129,10 +109,6 @@ namespace MilUI {
else { else {
RunParam = new PatternMatchingRunParam(); RunParam = new PatternMatchingRunParam();
} }
if (RunParam?.PmParamExt != null && RunParam.PmParamExt.TrainRoiSize > 0) {
_trainRoiSize = RunParam.PmParamExt.TrainRoiSize;
NotifyPropertyChanged(nameof(TrainRoiSize));
}
} }
public void InitFixturePatterns() { public void InitFixturePatterns() {
@ -158,7 +134,6 @@ namespace MilUI {
if (result == MessageBoxResult.Yes) { if (result == MessageBoxResult.Yes) {
var mainPatternInfo = _patternAgent.GetMainPatternInfo(_patternInfo.GetPatternIndex()); var mainPatternInfo = _patternAgent.GetMainPatternInfo(_patternInfo.GetPatternIndex());
if (E1.OK == _patternAgent.CopyPattern(mainPatternInfo.GetPatternIndex(), _patternInfo.GetPatternIndex())) { if (E1.OK == _patternAgent.CopyPattern(mainPatternInfo.GetPatternIndex(), _patternInfo.GetPatternIndex())) {
DeactivateRegisteredSubPattern();
InitRunParam(); InitRunParam();
InitFixturePatterns(); InitFixturePatterns();
UpdateControlButtons(true); UpdateControlButtons(true);
@ -171,7 +146,6 @@ namespace MilUI {
if (!_patternAgent.IsPatternExist(_patternInfo.GetPatternIndex())) { if (!_patternAgent.IsPatternExist(_patternInfo.GetPatternIndex())) {
if (E1.OK == _patternAgent.Create(_patternInfo) && if (E1.OK == _patternAgent.Create(_patternInfo) &&
E1.OK == _patternAgent.Save(_patternInfo)) { E1.OK == _patternAgent.Save(_patternInfo)) {
DeactivateRegisteredSubPattern();
InitRunParam(); InitRunParam();
InitFixturePatterns(); InitFixturePatterns();
UpdateControlButtons(true); UpdateControlButtons(true);
@ -184,9 +158,6 @@ namespace MilUI {
if (_cameraDisplay.HasFindRoi()) { if (_cameraDisplay.HasFindRoi()) {
RunParam.SetFindROI(_cameraDisplay.GetFindRoi().Clone() as ROI); RunParam.SetFindROI(_cameraDisplay.GetFindRoi().Clone() as ROI);
} }
if (RunParam?.PmParamExt != null) {
RunParam.PmParamExt.TrainRoiSize = TrainRoiSize;
}
_patternAgent.SetRunParam(_patternInfo, RunParam); _patternAgent.SetRunParam(_patternInfo, RunParam);
_patternAgent.Save(_patternInfo); _patternAgent.Save(_patternInfo);
MessageBoxUtil.ShowMessageBoxOk(StrTokens.MSG_O_SaveCompleted); MessageBoxUtil.ShowMessageBoxOk(StrTokens.MSG_O_SaveCompleted);
@ -202,34 +173,12 @@ namespace MilUI {
var result = MessageBoxUtil.ShowMessageBoxQuestion(StrTokens.MSG_Q_Delete); var result = MessageBoxUtil.ShowMessageBoxQuestion(StrTokens.MSG_Q_Delete);
if (result == MessageBoxResult.Yes) { if (result == MessageBoxResult.Yes) {
if (_patternAgent.IsPatternExist(_patternInfo.GetPatternIndex())) { if (_patternAgent.IsPatternExist(_patternInfo.GetPatternIndex())) {
if (_patternAgent.IsPatternFileLocked(_patternInfo, out string lockedFilePath)) {
MessageBoxUtil.ShowMessageBoxError(PatternAgentBase.GetPatternFileLockedMessage(lockedFilePath));
return;
}
if (E1.OK == _patternAgent.Remove(_patternInfo)) { if (E1.OK == _patternAgent.Remove(_patternInfo)) {
UpdateControlButtons(false); UpdateControlButtons(false);
} }
else {
MessageBoxUtil.ShowMessageBoxError(PatternAgentBase.GetPatternFileLockedMessage(string.Empty));
} }
} }
} }
}
// Sub pattern is registered as OFF (IsActivated = false). The operator turns it ON after checking.
private void DeactivateRegisteredSubPattern() {
if (!IsSubPattern) {
return;
}
_patternInfo.IsActivated = false;
var registeredPatternInfo = _patternAgent.GetPatternInfo(_patternInfo.GetPatternIndex());
if (registeredPatternInfo != null) {
registeredPatternInfo.IsActivated = false;
_patternAgent.Save(registeredPatternInfo);
}
}
private void ClosingWindow() { private void ClosingWindow() {
_cameraDisplay.ClearTrainGraphics(); _cameraDisplay.ClearTrainGraphics();
@ -267,7 +216,6 @@ namespace MilUI {
} }
private void SetTrainROI(object obj) { private void SetTrainROI(object obj) {
_cameraDisplay.SetPatternInfo(_patternInfo);
var milImage = _cameraDisplay.GetImage(); var milImage = _cameraDisplay.GetImage();
if (milImage != 0) { if (milImage != 0) {
var curPattern = _patternAgent.GetPattern(_patternInfo) as IPatternTrain; var curPattern = _patternAgent.GetPattern(_patternInfo) as IPatternTrain;
@ -277,15 +225,9 @@ namespace MilUI {
var imageCenter = MilEnvironment.GetImageCenter(milImage); var imageCenter = MilEnvironment.GetImageCenter(milImage);
if (ROI.IsNullOrEmpty(TrainParam.TrainRoi) || TrainParam.TrainOrigin is null) { if (ROI.IsNullOrEmpty(TrainParam.TrainRoi) || TrainParam.TrainOrigin is null) {
_cameraDisplay.AddTrainRoi(imageCenter); _cameraDisplay.AddTrainRoi(imageCenter);
_cameraDisplay.AddTrainOrigin(new Cross(imageCenter, TrainRoiSize)); _cameraDisplay.AddTrainOrigin(new Cross(imageCenter));
} }
else { else {
if (TrainParam.TrainOrigin.Length <= 0) {
TrainParam.TrainOrigin.Length = TrainRoiSize;
}
else {
TrainRoiSize = TrainParam.TrainOrigin.Length;
}
_cameraDisplay.AddTrainRoi(TrainParam.TrainRoi); _cameraDisplay.AddTrainRoi(TrainParam.TrainRoi);
_cameraDisplay.AddTrainOrigin(TrainParam.TrainOrigin); _cameraDisplay.AddTrainOrigin(TrainParam.TrainOrigin);
} }
@ -435,20 +377,5 @@ namespace MilUI {
ResetWindow(); ResetWindow();
} }
} }
public void UpdateAngleOfRoi(eGraRoiType graRoiType, object param) {
}
public void UpdateRadiusOfRoi(eGraRoiType graRoiType, double radius) {
if (graRoiType == eGraRoiType.TrainOrigin) {
_isUpdatingFromDisplay = true;
try {
TrainRoiSize = Math.Min(500, Math.Max(1, Math.Round(radius, 1)));
}
finally {
_isUpdatingFromDisplay = false;
}
}
}
} }
} }

View File

@ -495,30 +495,9 @@ namespace VisionCommon {
public int Remove(PatternInfo patternInfo) { public int Remove(PatternInfo patternInfo) {
if (patternInfo != null) { if (patternInfo != null) {
if (GetPatterns().ContainsKey(patternInfo)) { if (GetPatterns().ContainsKey(patternInfo)) {
// MIL 프로그램 등에서 패턴 파일을 열어 두면 폴더 삭제 중 예외가 나므로, 먼저 확인하고 아무것도 지우지 않는다.
if (IsPatternFileLocked(patternInfo, out string lockedFilePath)) {
_logger.E($"Pattern file is locked : {lockedFilePath}");
return E1.GENERIC;
}
try {
GetPatterns()[patternInfo].Remove(); // Remove Sub Pattern Directory GetPatterns()[patternInfo].Remove(); // Remove Sub Pattern Directory
GetPatterns().Remove(patternInfo); GetPatterns().Remove(patternInfo);
DeletePatternDirectory(patternInfo); DeletePatternDirectory(patternInfo);
}
catch (Exception e) {
_logger.E($"Remove pattern error : {patternInfo}, {e.Message}");
// 삭제 도중 실패하면 남은 파일로 패턴을 다시 불러와 둔다.
try {
if (GetPatterns().ContainsKey(patternInfo)) {
ReloadPattern(patternInfo);
}
}
catch (Exception reloadException) {
_logger.E($"Reload pattern error : {patternInfo}, {reloadException.Message}");
}
return E1.GENERIC;
}
return E1.OK; return E1.OK;
} }
@ -526,48 +505,6 @@ namespace VisionCommon {
return E2.NOT_FOUND; return E2.NOT_FOUND;
} }
// 패턴(메인 또는 서브 하나) 폴더의 파일 중 다른 프로그램이 열고 있는 파일이 있는지 확인한다.
public bool IsPatternFileLocked(PatternInfo patternInfo, out string lockedFilePath) {
lockedFilePath = string.Empty;
var patternDirPath = Path.GetDirectoryName(PatternConstants.GetSubPatternInfoFilePath(patternInfo));
if (!Directory.Exists(patternDirPath)) {
return false;
}
foreach (var filePath in Directory.GetFiles(patternDirPath, "*", SearchOption.AllDirectories)) {
try {
using (File.Open(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) {
}
}
catch (IOException) {
lockedFilePath = filePath;
return true;
}
catch (UnauthorizedAccessException) {
lockedFilePath = filePath;
return true;
}
}
return false;
}
// 메인과 서브 패턴 전체 중 다른 프로그램이 열고 있는 파일이 있는지 확인한다.
public bool IsMainSubPatternFileLocked(PatternInfo patternInfo, out string lockedFilePath) {
lockedFilePath = string.Empty;
foreach (var curPatternInfo in GetMainSubPatterns(patternInfo)) {
if (IsPatternFileLocked(curPatternInfo, out lockedFilePath)) {
return true;
}
}
return false;
}
public static string GetPatternFileLockedMessage(string lockedFilePath) {
return "패턴 파일이 다른 프로그램에서 열려 있어 삭제할 수 없습니다.\n" +
"MIL 프로그램 등에서 파일을 닫은 뒤 다시 삭제하세요.\n\n" + lockedFilePath;
}
public abstract IPatternFinder CreatePattern(PatternInfo patternInfo); public abstract IPatternFinder CreatePattern(PatternInfo patternInfo);
public void DeletePatternDirectory(PatternInfo patternInfo) { public void DeletePatternDirectory(PatternInfo patternInfo) {

View File

@ -34,8 +34,6 @@ namespace VisionCommon {
ROI GetTrainRoi(); ROI GetTrainRoi();
int AddTrainOrigin(Cross imageCenter); int AddTrainOrigin(Cross imageCenter);
Cross GetTrainOrigin(); Cross GetTrainOrigin();
void UpdateRadiusOfTrainOrigin(double radius);
bool HasTrainOrigin();
int AddDefaultFindRoi(ImageSize imageSize, bool isRotatable = false); int AddDefaultFindRoi(ImageSize imageSize, bool isRotatable = false);
int AddFindRoi(ROI findRoi, bool isRotatable = false); int AddFindRoi(ROI findRoi, bool isRotatable = false);

View File

@ -5,12 +5,10 @@
namespace VisionCommon { namespace VisionCommon {
public enum eGraRoiType { public enum eGraRoiType {
TrainRoi, TrainRoi,
FindRoi, FindRoi
TrainOrigin
} }
public interface IGraEventSubscriber { public interface IGraEventSubscriber {
void UpdateAngleOfRoi(eGraRoiType graRoiType, object param); void UpdateAngleOfRoi(eGraRoiType graRoiType, object param);
void UpdateRadiusOfRoi(eGraRoiType graRoiType, double radius);
} }
} }

View File

@ -48,9 +48,6 @@ namespace VisionCommon {
public int MilSystemId { get; set; } public int MilSystemId { get; set; }
[JsonIgnore] [JsonIgnore]
public Bitmap Thumbnail { get; set; } = ThumbnailUtil.GetDefaultImage(); public Bitmap Thumbnail { get; set; } = ThumbnailUtil.GetDefaultImage();
// Sub pattern list for display (pattern list thumbnails)
[JsonIgnore]
public System.Collections.Generic.List<PatternInfo> SubPatternInfos { get; set; } = new System.Collections.Generic.List<PatternInfo>();
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName) protected void OnPropertyChanged(string propertyName)

View File

@ -17,7 +17,7 @@ namespace VisionCommon {
public const int MAIN_PATTERN_INDEX = 0; public const int MAIN_PATTERN_INDEX = 0;
public const int FOV_PATTERN_COUNT = 20; public const int FOV_PATTERN_COUNT = 20;
public const int CAM_PATTERN_COUNT = 20; public const int CAM_PATTERN_COUNT = 20;
public const int SUB_PATTERN_COUNT = 11; // 메인(0) 포함. 서브는 1 ~ 10 public const int SUB_PATTERN_COUNT = 5;
public static bool IsMainPattern(PatternIndex patternIndex) { public static bool IsMainPattern(PatternIndex patternIndex) {
return patternIndex.PatternSubId == MAIN_PATTERN_INDEX; return patternIndex.PatternSubId == MAIN_PATTERN_INDEX;

View File

@ -4,7 +4,6 @@ using VisionSequence.Pattern;
using VisionCommonUI; using VisionCommonUI;
using VisionCommonUI.Resources; using VisionCommonUI.Resources;
using Aurora.View; using Aurora.View;
using Hermes;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
@ -134,7 +133,6 @@ namespace VisionUI {
var curPatternInfo = Patterns[Patterns.Count - 1]; var curPatternInfo = Patterns[Patterns.Count - 1];
curPatternInfo.Thumbnail = _PatternAgent.GetThumbnail(curPatternInfo); curPatternInfo.Thumbnail = _PatternAgent.GetThumbnail(curPatternInfo);
curPatternInfo.SubPatternInfos = GetSubPatternsWithThumbnail(curPatternInfo);
} }
else { else {
Patterns.Add(CreateDefaultPatternInfo(i)); Patterns.Add(CreateDefaultPatternInfo(i));
@ -149,22 +147,6 @@ namespace VisionUI {
} }
} }
// 목록의 행마다 서브 패턴 썸네일을 함께 보여주기 위해, 서브 번호순으로 썸네일을 채운 서브 패턴 목록을 만든다.
private List<PatternInfo> GetSubPatternsWithThumbnail(PatternInfo mainPatternInfo) {
var subPatternInfos = new List<PatternInfo>();
try {
foreach (var subPatternInfo in _PatternAgent.GetSubPatterns(mainPatternInfo)
.OrderBy(pi => pi.GetPatternIndex().PatternSubId)) {
subPatternInfo.Thumbnail = _PatternAgent.GetThumbnail(subPatternInfo);
subPatternInfos.Add(subPatternInfo);
}
}
catch (Exception e) {
_logger.FuncE(e.Message);
}
return subPatternInfos;
}
public List<PatternInfo> GetExistingPatterns() { public List<PatternInfo> GetExistingPatterns() {
if (_PatternAgent == null) { if (_PatternAgent == null) {
ResetPatternAgent(); ResetPatternAgent();
@ -274,39 +256,23 @@ namespace VisionUI {
var result = MessageBoxUtil.ShowMessageBoxQuestion( var result = MessageBoxUtil.ShowMessageBoxQuestion(
string.Format(StrTokens.MSG_Q_DeletePatternFormat, SelectedPatternIndex)); string.Format(StrTokens.MSG_Q_DeletePatternFormat, SelectedPatternIndex));
if (result == MessageBoxResult.Yes) { if (result == MessageBoxResult.Yes) {
// 메인/서브 중 하나라도 다른 프로그램이 열고 있으면 아무것도 지우지 않는다.
if (_PatternAgent.IsMainSubPatternFileLocked(Patterns[SelectedPatternIndex], out string lockedFilePath)) {
_logger.FuncE($"Pattern file is locked : {lockedFilePath}");
MessageBoxUtil.ShowMessageBoxError(PatternAgentBase.GetPatternFileLockedMessage(lockedFilePath));
return;
}
Application.Current.Dispatcher.Invoke(() => { Application.Current.Dispatcher.Invoke(() => {
try { DeleteSubPatterns(Patterns[SelectedPatternIndex]);
bool isRemoved = DeleteSubPatterns(Patterns[SelectedPatternIndex]); DeleteMainPattern(Patterns[SelectedPatternIndex]);
isRemoved &= DeleteMainPattern(Patterns[SelectedPatternIndex]); Patterns[SelectedPatternIndex] = CreateDefaultPatternInfo(SelectedPatternIndex);
if (!isRemoved) {
MessageBoxUtil.ShowMessageBoxError(PatternAgentBase.GetPatternFileLockedMessage(string.Empty));
}
}
catch (Exception e) {
_logger.FuncE(e.Message);
}
InitPatternList(lastSelectedPatternIndex); InitPatternList(lastSelectedPatternIndex);
}); });
} }
} }
private bool DeleteSubPatterns(PatternInfo patternInfo) { private void DeleteSubPatterns(PatternInfo patternInfo) {
bool isRemoved = true;
var subPatternList = _PatternAgent.GetSubPatterns(patternInfo); var subPatternList = _PatternAgent.GetSubPatterns(patternInfo);
foreach (var subPatternInfo in subPatternList) { foreach (var subPatternInfo in subPatternList) {
isRemoved &= (E1.OK == _PatternAgent.Remove(subPatternInfo)); _PatternAgent.Remove(subPatternInfo);
} }
return isRemoved;
} }
private bool DeleteMainPattern(PatternInfo patternInfo) { private void DeleteMainPattern(PatternInfo patternInfo) {
return E1.OK == _PatternAgent.Remove(patternInfo); _PatternAgent.Remove(patternInfo);
} }
private void Apply(object obj) { private void Apply(object obj) {

View File

@ -50,9 +50,9 @@
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/> <ColumnDefinition Width="1*"/>
<ColumnDefinition Width="3*"/> <ColumnDefinition Width="3*"/>
<ColumnDefinition Width="6*"/> <ColumnDefinition Width="7*"/>
<ColumnDefinition Width="8*"/> <ColumnDefinition Width="5*"/>
<ColumnDefinition Width="16*"/> <ColumnDefinition Width="15*"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Style="{StaticResource styleGroupBoxHeaderTextBlock}" TextAlignment="Center" FontSize="15" Text="ID"/> <TextBlock Grid.Column="0" Style="{StaticResource styleGroupBoxHeaderTextBlock}" TextAlignment="Center" FontSize="15" Text="ID"/>
<TextBlock Grid.Column="1" Style="{StaticResource styleGroupBoxHeaderTextBlock}" TextAlignment="Center" FontSize="15" <TextBlock Grid.Column="1" Style="{StaticResource styleGroupBoxHeaderTextBlock}" TextAlignment="Center" FontSize="15"
@ -77,58 +77,16 @@
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/> <ColumnDefinition Width="1*"/>
<ColumnDefinition Width="3*"/> <ColumnDefinition Width="3*"/>
<ColumnDefinition Width="6*"/> <ColumnDefinition Width="7*"/>
<ColumnDefinition Width="8*"/> <ColumnDefinition Width="5*"/>
<ColumnDefinition Width="16*"/> <ColumnDefinition Width="15*"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Style="{StaticResource styleTextBlockDataGridItem}" FontSize="15" Text="{Binding PatternIndex.PatternId}"/> <TextBlock Grid.Column="0" Style="{StaticResource styleTextBlockDataGridItem}" FontSize="15" Text="{Binding PatternIndex.PatternId}"/>
<TextBlock Grid.Column="1" Style="{StaticResource styleTextBlockDataGridItem}" FontSize="15" Text="{Binding IsActivated}"/> <TextBlock Grid.Column="1" Style="{StaticResource styleTextBlockDataGridItem}" FontSize="15" Text="{Binding IsActivated}"/>
<TextBlock Grid.Column="2" Style="{StaticResource styleTextBlockDataGridItem}" FontSize="15" Text="{Binding PatternType}"/> <TextBlock Grid.Column="2" Style="{StaticResource styleTextBlockDataGridItem}" FontSize="15" Text="{Binding PatternType}"/>
<!-- 메인(M) 썸네일 뒤에 서브 패턴 썸네일을 서브 번호순으로 한 줄로 보여준다. 서브는 2개 폭만 보이고 나머지는 좌우 스크롤. OFF 인 서브는 흐리게 표시한다. --> <Image Grid.Column="3" Margin="0" Width="38" Height="38"
<DockPanel Grid.Column="3" VerticalAlignment="Center" LastChildFill="True">
<StackPanel DockPanel.Dock="Left" Margin="2, 0" ToolTip="Main">
<Image Margin="0" Width="38" Height="38"
RenderOptions.BitmapScalingMode="HighQuality" RenderOptions.BitmapScalingMode="HighQuality"
Source="{Binding Thumbnail, Converter={StaticResource bitmapConverter}}"/> Source="{Binding Thumbnail, Converter={StaticResource bitmapConverter}}"/>
<TextBlock Style="{StaticResource styleTextBlockDataGridItem}" FontSize="10" HorizontalAlignment="Center" Text="M"/>
</StackPanel>
<ScrollViewer MaxWidth="88" HorizontalAlignment="Left"
HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled"
PanningMode="HorizontalOnly"
PreviewMouseWheel="svSubThumbnails_PreviewMouseWheel">
<ItemsControl ItemsSource="{Binding SubPatternInfos}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="spSubThumbnail" Margin="2, 0">
<StackPanel.ToolTip>
<TextBlock>
<Run Text="Sub"/>
<Run Text="{Binding PatternIndex.PatternSubId, Mode=OneWay}"/>
<Run Text=" : "/>
<Run Text="{Binding IsActivated, Mode=OneWay}"/>
</TextBlock>
</StackPanel.ToolTip>
<Image Margin="0" Width="38" Height="38"
RenderOptions.BitmapScalingMode="HighQuality"
Source="{Binding Thumbnail, Converter={StaticResource bitmapConverter}}"/>
<TextBlock Style="{StaticResource styleTextBlockDataGridItem}" FontSize="10" HorizontalAlignment="Center"
Text="{Binding PatternIndex.PatternSubId}"/>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsActivated}" Value="False">
<Setter TargetName="spSubThumbnail" Property="Opacity" Value="0.35"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</DockPanel>
<TextBlock Grid.Column="4" Style="{StaticResource styleTextBlockDataGridItem}" FontSize="15" Text="{Binding Description}"/> <TextBlock Grid.Column="4" Style="{StaticResource styleTextBlockDataGridItem}" FontSize="15" Text="{Binding Description}"/>
</Grid> </Grid>
</StackPanel> </StackPanel>

View File

@ -161,25 +161,6 @@ namespace VisionUI.Pattern {
} }
} }
// 썸네일 행 안 : Shift + 휠은 좌우 스크롤, 그냥 휠은 목록 위아래 스크롤로 넘긴다.
private void svSubThumbnails_PreviewMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e) {
if (!(sender is ScrollViewer scrollViewer)) {
return;
}
e.Handled = true;
if (System.Windows.Input.Keyboard.Modifiers == System.Windows.Input.ModifierKeys.Shift) {
scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset - e.Delta);
return;
}
var parent = System.Windows.Media.VisualTreeHelper.GetParent(scrollViewer) as UIElement;
parent?.RaiseEvent(new System.Windows.Input.MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta) {
RoutedEvent = UIElement.MouseWheelEvent,
Source = scrollViewer
});
}
private void UpdateVisionRecipes() { private void UpdateVisionRecipes() {
_FovRecipe = VisionRecipeManager.GetFovRecipe(_FovInfo); _FovRecipe = VisionRecipeManager.GetFovRecipe(_FovInfo);
} }

View File

@ -123,7 +123,6 @@ namespace ILSOS_KS.Device
PLC_DOOR_INTERLOCK, PLC_DOOR_INTERLOCK,
PLC_EMO_STATUS, PLC_EMO_STATUS,
PLC_RECIPE_CHANGE_REQ, PLC_RECIPE_CHANGE_REQ,
PLC_RCC_PATTERN_CHANGED_ACK = 0X09, // B2409 : B2506(RCC 패턴 변경) 수신 ACK
PLC_JIG_LOAD_COMPLETE = 0X0C, PLC_JIG_LOAD_COMPLETE = 0X0C,
/// <summary> /// <summary>
@ -157,7 +156,6 @@ namespace ILSOS_KS.Device
PC_MANUAL_COMPLETE, PC_MANUAL_COMPLETE,
PC_LIGHT_ALARM_STATUS, PC_LIGHT_ALARM_STATUS,
PC_HEAVY_ALARM_STATUS, PC_HEAVY_ALARM_STATUS,
PC_RCC_PATTERN_CHANGED = 0X06, // B2506 : RCC 패턴 변경 알림 (B2409 ACK 를 받으면 끈다)
PC_RECIPE_CHANGE_COMPLETE = 0X08, PC_RECIPE_CHANGE_COMPLETE = 0X08,
PC_RECIPE_PARAM_UPLOAD_COMPLETE, PC_RECIPE_PARAM_UPLOAD_COMPLETE,
PC_WELD_MANUAL_TEST, PC_WELD_MANUAL_TEST,

View File

@ -1,4 +1,4 @@
using Aurora; using Aurora;
using Aurora.Api; using Aurora.Api;
using Aurora.Api.Devices; using Aurora.Api.Devices;
using Aurora.Api.Manager; using Aurora.Api.Manager;
@ -156,10 +156,10 @@ namespace ILSOS_KS
// () => _plc, PLCMelsecNetConfig.GetDefaultConfig(), // () => _plc, PLCMelsecNetConfig.GetDefaultConfig(),
// device => new UCPLCDevice() { DataContext = new UCPLCDeviceViewModel(AuroraEnv, _plc) }); // device => new UCPLCDevice() { DataContext = new UCPLCDeviceViewModel(AuroraEnv, _plc) });
registry.Register(DeviceIds.KSLight1, () => new LightDevice(DeviceIds.KSLight1, eLight.ERI), new LightConfig(), registry.Register(DeviceIds.KSLight1, () => new LightDevice(CommonDeviceIds.Light, eLight.ERI), new LightConfig(),
device => new UCLight() { DataContext = new UCLightViewModel(AuroraEnv, DeviceIds.KSLight1) }); device => new UCLight() { DataContext = new UCLightViewModel(AuroraEnv, DeviceIds.KSLight1) });
registry.Register(DeviceIds.KSLight2, () => new LightDevice(DeviceIds.KSLight2, eLight.ERI), new LightConfig(), registry.Register(DeviceIds.KSLight2, () => new LightDevice(CommonDeviceIds.Light, eLight.ERI), new LightConfig(),
device => new UCLight() { DataContext = new UCLightViewModel(AuroraEnv, DeviceIds.KSLight2) }); device => new UCLight() { DataContext = new UCLightViewModel(AuroraEnv, DeviceIds.KSLight2) });
RegisterStreamServices(registry); RegisterStreamServices(registry);

View File

@ -328,10 +328,6 @@
<Project>{3db398e6-80b7-4bb9-8be7-caf12979c269}</Project> <Project>{3db398e6-80b7-4bb9-8be7-caf12979c269}</Project>
<Name>VisionCommon</Name> <Name>VisionCommon</Name>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\..\AuroraVision\VisionUI\VisionUI.csproj">
<Project>{DE586F5E-5BC0-4CAC-9CCB-360473A411B4}</Project>
<Name>VisionUI</Name>
</ProjectReference>
<ProjectReference Include="..\..\WeldingComponents\LASA\GUI\LASAGUI.csproj"> <ProjectReference Include="..\..\WeldingComponents\LASA\GUI\LASAGUI.csproj">
<Project>{e4658ed8-bbb0-4aad-899a-0bad56f2732a}</Project> <Project>{e4658ed8-bbb0-4aad-899a-0bad56f2732a}</Project>
<Name>LASAGUI</Name> <Name>LASAGUI</Name>

View File

@ -49,5 +49,5 @@ using System.Windows;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.4")] [assembly: AssemblyVersion("1.0.0.3")]
[assembly: AssemblyFileVersion("1.0.0.4")] [assembly: AssemblyFileVersion("1.0.0.3")]

View File

@ -61,7 +61,6 @@ using System.Windows.Media.Imaging;
using System.Windows.Shapes; using System.Windows.Shapes;
using System.Xml.Linq; using System.Xml.Linq;
using VisionCommon; using VisionCommon;
using VisionUI.Camera;
using WeldingCommon; using WeldingCommon;
using WeldingCommon.Alarm; using WeldingCommon.Alarm;
using WeldingCommon.Data; using WeldingCommon.Data;
@ -264,9 +263,6 @@ namespace ILSOS_KS.Sequences
bool ksExit = false; bool ksExit = false;
// RCC 패턴 변경 알림 : 변경이 있으면 B2506 을 켜고, PLC ACK(B2409) 가 오면 끈다.
private CancellationTokenSource _RccChangeNoticeCts;
int[] ResultDataList = new int[4]; int[] ResultDataList = new int[4];
public SeqAutoRunKS() public SeqAutoRunKS()
@ -1333,111 +1329,6 @@ namespace ILSOS_KS.Sequences
return SequenceAction.Ok(); return SequenceAction.Ok();
} }
// RCC 패턴이 바뀌었으면 B2506 을 켜고, PLC ACK(B2409) 를 받았을 때만 알림 완료로 기록한다.
// ACK 없이 오토런이 끝나면 B2506 만 끄고 기록하지 않아서 다음 오토런에서 다시 알린다. 오토런은 막지 않는다.
private void StartRccPatternChangeNotice(SequenceContext context)
{
_RccChangeNoticeCts?.Cancel();
WriteRccPatternChangedBit(false, "AutoRun Start Reset");
if (_SystemParameter.SequenceType != eSequenceType.RCC)
{
return;
}
string recipeKey;
string hash;
try
{
recipeKey = RccPatternChangeRecord.GetCurrentRecipeKey();
hash = RccPatternChangeRecord.ComputePatternHash();
}
catch (Exception e)
{
Log.E($"[RccPatternChange] Pattern hash failed : {e.Message}");
return;
}
if (RccPatternChangeRecord.IsAcknowledged(recipeKey, hash))
{
Log.I($"[RccPatternChange] No change. {GetRccPatternBitState()}");
return;
}
WriteRccPatternChangedBit(true, "RCC pattern changed -> Wait PLC ACK");
var cts = new CancellationTokenSource();
_RccChangeNoticeCts = cts;
Task.Run(() =>
{
bool acked = false;
try
{
// 이전 ACK 가 켜진 채로 남아 있으면 꺼질 때까지 기다린 뒤, 새로 켜지는 순간(OFF -> ON)만 ACK 로 본다.
bool ackArmed = !_PLC.ReadBit((int)eBitInput.PLC_RCC_PATTERN_CHANGED_ACK).data;
if (!ackArmed)
{
Log.I($"[RccPatternChange] PLC ACK is already ON. Wait ACK OFF. {GetRccPatternBitState()}");
}
while (!cts.IsCancellationRequested && !context.Stopped)
{
bool ack = _PLC.ReadBit((int)eBitInput.PLC_RCC_PATTERN_CHANGED_ACK).data;
if (!ackArmed)
{
if (!ack)
{
ackArmed = true;
Log.I($"[RccPatternChange] PLC ACK OFF. Wait new ACK. {GetRccPatternBitState()}");
}
}
else if (ack)
{
acked = true;
break;
}
Thread.Sleep(100);
}
if (acked)
{
RccPatternChangeRecord.Acknowledge(recipeKey, hash);
Log.I($"[RccPatternChange] PLC ACK received -> Recorded. {GetRccPatternBitState()}");
}
}
catch (Exception e)
{
Log.E($"[RccPatternChange] {e.Message}");
}
finally
{
// 오토런을 다시 시작해 새 감시가 돌고 있으면, 새로 켠 비트를 건드리지 않는다.
if (ReferenceEquals(_RccChangeNoticeCts, cts))
{
WriteRccPatternChangedBit(false, acked
? "After PLC ACK"
: "AutoRun ended without ACK -> Not recorded, notify again next AutoRun");
}
}
});
}
// B2506 을 쓰고, 쓴 뒤의 B2506 / B2409 상태를 읽어서 로그로 남긴다.
private void WriteRccPatternChangedBit(bool value, string reason)
{
int ret = _PLC.WriteBit((int)eBitOutput.PC_RCC_PATTERN_CHANGED, value);
Log.I($"[RccPatternChange] {reason} : ret={ret}, {GetRccPatternBitState()}");
}
// PC_RCC_PATTERN_CHANGED(B2506, PC 출력 블록) 와 PLC_RCC_PATTERN_CHANGED_ACK(B2409, PLC 입력) 를 읽어서 상태 문자열로 만든다.
private string GetRccPatternBitState()
{
var pc = _PLC.ReadBit((int)eBitOutput.PC_RCC_PATTERN_CHANGED, isInput: false);
var ack = _PLC.ReadBit((int)eBitInput.PLC_RCC_PATTERN_CHANGED_ACK);
return $"PC_RCC_PATTERN_CHANGED(B2506)={(pc.err == 0 ? pc.data.ToString() : $"ReadErr{pc.err}")}, " +
$"PLC_RCC_PATTERN_CHANGED_ACK(B2409)={(ack.err == 0 ? ack.data.ToString() : $"ReadErr{ack.err}")}";
}
private bool InitSequenceVariable(SequenceContext context) private bool InitSequenceVariable(SequenceContext context)
{ {
_AutoRunStartTime = DateTime.Now; _AutoRunStartTime = DateTime.Now;
@ -1568,9 +1459,6 @@ namespace ILSOS_KS.Sequences
// PLC Interface AutoStatus Start // PLC Interface AutoStatus Start
InitAutoRunBit(); InitAutoRunBit();
// RCC 패턴 변경 알림 : 해시 계산에 시간이 걸리므로 PC_AUTO_STATUS 를 켠 뒤에 한다.
StartRccPatternChangeNotice(context);
// Laser Initialize // Laser Initialize
_Laser.PilotLaserOff(); _Laser.PilotLaserOff();
_Laser.LaserOn(); _Laser.LaserOn();
@ -1666,9 +1554,9 @@ namespace ILSOS_KS.Sequences
Log.I(string.Format($"[IOInterface] Start AutoRun IO Bit Initialize")); Log.I(string.Format($"[IOInterface] Start AutoRun IO Bit Initialize"));
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADReadyStatus), false); _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADReadyStatus), false);
Log.I(string.Format($"[IOInterface]SET PCLBADReadyStatus False")); Log.I(string.Format($"[IOInterface]SET PCLBADReadyStatus False"));
WriteLBADDo(eADOAddress.PCLBADWeldingTrigger, false); _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingTrigger), false);
Log.I(string.Format($"[IOInterface]SET PCLBADWeldingTrigger False")); Log.I(string.Format($"[IOInterface]SET PCLBADWeldingTrigger False"));
WriteLBADDo(eADOAddress.PCLBADWeldingStop, false); _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), false);
Log.I(string.Format($"[IOInterface]SET PCLBADWeldingStop False")); Log.I(string.Format($"[IOInterface]SET PCLBADWeldingStop False"));
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADJudgementCompleteAck), false); _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADJudgementCompleteAck), false);
Log.I(string.Format($"[IOInterface]SET PCLBADJudgementCompleteAck False")); Log.I(string.Format($"[IOInterface]SET PCLBADJudgementCompleteAck False"));
@ -1914,10 +1802,6 @@ namespace ILSOS_KS.Sequences
_PLC.WriteBit((int)eBitOutput.PC_LBAD_RESULT_NG, false); _PLC.WriteBit((int)eBitOutput.PC_LBAD_RESULT_NG, false);
Log.I(string.Format($"[PLCInterface]SET PC_LBAD_RESULT_NG False")); Log.I(string.Format($"[PLCInterface]SET PC_LBAD_RESULT_NG False"));
// 이전 셀의 LBAD 판정값이 남아있으면 이번 셀에서 판정을 못했을 때 그대로 재전송되므로 여기서 초기화한다.
Status.GetProcessingWeldingData().LBAD_Judge = string.Empty;
Log.I(string.Format($"[PLCInterface]CLEAR LBAD_Judge"));
_InterfaceStartTime = DateTime.Now; _InterfaceStartTime = DateTime.Now;
while (!context.Stopped) while (!context.Stopped)
@ -2102,9 +1986,6 @@ namespace ILSOS_KS.Sequences
{ {
var resultOutParam = param.Param as SeqScoutFlyingVision_OutParam; var resultOutParam = param.Param as SeqScoutFlyingVision_OutParam;
CameraUcManager.Instance.StartLiveAll(eDisplayType.Machine_A);
return SequenceAction.Ok(); return SequenceAction.Ok();
//if (pre_welding) //if (pre_welding)
@ -2387,18 +2268,6 @@ namespace ILSOS_KS.Sequences
return SequenceAction.Ok(); return SequenceAction.Ok();
} }
// LBAD IO 출력 : 쓰기 반환값(0 = 성공)을 로그로 남기고, 실패하면 에러 로그를 남긴다.
private int WriteLBADDo(eADOAddress address, bool value)
{
int ret = _IO._iOUnit.WriteDoBit(Convert.ToInt32(address), value);
Log.I(string.Format($"[IOInterface] WriteDoBit {address}({Convert.ToInt32(address)}) {value} ret={ret}"));
if (ret != 0)
{
Log.E(string.Format($"[IOInterface] WriteDoBit {address}({Convert.ToInt32(address)}) {value} FAIL ret={ret}"));
}
return ret;
}
private SequenceActionResult ExecuteWelding(SequenceContext context, string id, SequenceActionResult param) private SequenceActionResult ExecuteWelding(SequenceContext context, string id, SequenceActionResult param)
{ {
Status.SetWorkingPosition(eWorkingPosition.EXECUTING_WELD); Status.SetWorkingPosition(eWorkingPosition.EXECUTING_WELD);
@ -2410,7 +2279,7 @@ namespace ILSOS_KS.Sequences
int recipeNo = _RecipeManager.ActivatedRecipe().Id; int recipeNo = _RecipeManager.ActivatedRecipe().Id;
WriteLBADDo(eADOAddress.PCLBADWeldingTrigger, true); _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingTrigger), true);
//int sendresult = _LBAD.SendCellData(_LotId, _CellId, recipeNo, _ModelNo); //int sendresult = _LBAD.SendCellData(_LotId, _CellId, recipeNo, _ModelNo);
if (_BcrID.Contains("")) if (_BcrID.Contains(""))
@ -2476,11 +2345,11 @@ namespace ILSOS_KS.Sequences
_PLC.WriteBit((int)eBitOutput.PC_WELD_READY, false); _PLC.WriteBit((int)eBitOutput.PC_WELD_READY, false);
Log.I(string.Format($"[PLCInterface]SET PC_WELD_READY False")); Log.I(string.Format($"[PLCInterface]SET PC_WELD_READY False"));
WriteLBADDo(eADOAddress.PCLBADWeldingTrigger, false); _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingTrigger), false);
Log.I(string.Format($"[IOInterface]SET PCWeldingTrigger false")); Log.I(string.Format($"[IOInterface]SET PCWeldingTrigger false"));
WriteLBADDo(eADOAddress.PCLBADWeldingStop, true); _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), true);
Log.I(string.Format($"[IOInterface]{_PageNo} setp --> SET PCWeldingStop true")); Log.I(string.Format($"[IOInterface]{_PageNo} setp --> SET PCWeldingStop true"));
return SequenceAction.Ok(); return SequenceAction.Ok();
@ -2525,7 +2394,7 @@ namespace ILSOS_KS.Sequences
//LBAD 결과 받아오는 부분 우선 여기서 추가하여 테스트하고 Sub 시퀀스로 빼자 //LBAD 결과 받아오는 부분 우선 여기서 추가하여 테스트하고 Sub 시퀀스로 빼자
if (_LBAD.IsSimul) if (_LBAD.IsSimul)
{ {
WriteLBADDo(eADOAddress.PCLBADWeldingStop, false); _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), false);
Log.I(string.Format($"[IOInterface]SET PCLBADWeldingStop false, LBAD is Simul")); Log.I(string.Format($"[IOInterface]SET PCLBADWeldingStop false, LBAD is Simul"));
} }
else else
@ -3317,7 +3186,7 @@ namespace ILSOS_KS.Sequences
{ {
Log.I(string.Format($"[IOInterface]Get PLC_WELD_REQEUST True")); Log.I(string.Format($"[IOInterface]Get PLC_WELD_REQEUST True"));
WriteLBADDo(eADOAddress.PCLBADWeldingStop, false); _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), false);
Log.I(string.Format($"[IOInterface]LBAD {_PageNoRcc} setp --> SET PCWeldingStop false")); Log.I(string.Format($"[IOInterface]LBAD {_PageNoRcc} setp --> SET PCWeldingStop false"));
bool[] Page = new bool[4]; bool[] Page = new bool[4];
@ -3361,7 +3230,7 @@ namespace ILSOS_KS.Sequences
WeldingEnd = true; WeldingEnd = true;
WriteLBADDo(eADOAddress.PCLBADWeldingStop, false); _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), false);
Log.I(string.Format($"[IOInterface]LBAD {_PageNoRcc} setp --> SET PCWeldingStop false")); Log.I(string.Format($"[IOInterface]LBAD {_PageNoRcc} setp --> SET PCWeldingStop false"));
DateTime startTime = DateTime.Now; DateTime startTime = DateTime.Now;
@ -3708,7 +3577,6 @@ namespace ILSOS_KS.Sequences
private SequenceActionResult Complete(SequenceContext context, string id, SequenceActionResult param) private SequenceActionResult Complete(SequenceContext context, string id, SequenceActionResult param)
{ {
_RccChangeNoticeCts?.Cancel();
RestoreDeviceStatus(); RestoreDeviceStatus();
Log.I("AutoRun Complete"); Log.I("AutoRun Complete");
@ -3728,10 +3596,6 @@ namespace ILSOS_KS.Sequences
private bool RestoreDeviceStatus() private bool RestoreDeviceStatus()
{ {
// RCC 패턴 변경 알림 감시 종료 + B2506 OFF (ACK 전이면 기록하지 않았으므로 다음 오토런에서 다시 알린다)
_RccChangeNoticeCts?.Cancel();
WriteRccPatternChangedBit(false, "AutoRun Stop");
//PLC All BIT OFF //PLC All BIT OFF
_PLC.WriteBit((int)eBitOutput.PC_WELD_REQEUST_ACK, false); _PLC.WriteBit((int)eBitOutput.PC_WELD_REQEUST_ACK, false);
_PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE, false); _PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE, false);
@ -3748,9 +3612,9 @@ namespace ILSOS_KS.Sequences
UpdatePLCMemoryAreaCls((int)eWordOutput.STEP1_Arc1_LowerLimit, (int)eWordOutput.WeldingOK_NG); UpdatePLCMemoryAreaCls((int)eWordOutput.STEP1_Arc1_LowerLimit, (int)eWordOutput.WeldingOK_NG);
//LBAD IO All BIT OFF //LBAD IO All BIT OFF
WriteLBADDo(eADOAddress.PCLBADWeldingTrigger, false); _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingTrigger), false);
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADReadyStatus), false); _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADReadyStatus), false);
WriteLBADDo(eADOAddress.PCLBADWeldingStop, false); _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), false);
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADJudgementCompleteAck), false); _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADJudgementCompleteAck), false);
Log.I(string.Format("[IOInterface]PC All Bit Off")); Log.I(string.Format("[IOInterface]PC All Bit Off"));
@ -3807,10 +3671,6 @@ namespace ILSOS_KS.Sequences
private void OnSeqActionStop() private void OnSeqActionStop()
{ {
// RCC 패턴 변경 알림 감시 종료 + B2506 OFF (ACK 전이면 기록하지 않았으므로 다음 오토런에서 다시 알린다)
_RccChangeNoticeCts?.Cancel();
WriteRccPatternChangedBit(false, "AutoRun Stop");
//PLC All BIT OFF //PLC All BIT OFF
_PLC.WriteBit((int)eBitOutput.PC_WELD_REQEUST_ACK, false); _PLC.WriteBit((int)eBitOutput.PC_WELD_REQEUST_ACK, false);
_PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE, false); _PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE, false);
@ -3827,9 +3687,9 @@ namespace ILSOS_KS.Sequences
UpdatePLCMemoryAreaCls((int)eWordOutput.STEP1_Arc1_LowerLimit, (int)eWordOutput.WeldingOK_NG); UpdatePLCMemoryAreaCls((int)eWordOutput.STEP1_Arc1_LowerLimit, (int)eWordOutput.WeldingOK_NG);
//LBAD IO All BIT OFF //LBAD IO All BIT OFF
WriteLBADDo(eADOAddress.PCLBADWeldingTrigger, false); _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingTrigger), false);
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADReadyStatus), false); _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADReadyStatus), false);
WriteLBADDo(eADOAddress.PCLBADWeldingStop, false); _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), false);
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADJudgementCompleteAck), false); _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADJudgementCompleteAck), false);
Log.I(string.Format("[IOInterface]PC All Bit Off")); Log.I(string.Format("[IOInterface]PC All Bit Off"));
@ -3890,86 +3750,6 @@ namespace ILSOS_KS.Sequences
} }
// RCC 패턴 변경 기록 : 패턴 폴더 전체 내용 해시를 레시피별로 DATA_PATH\_config_setting\RccPatternChangeRecord.json 에 기록하고 비교한다.
public static class RccPatternChangeRecord
{
private const string FILE_NAME = "RccPatternChangeRecord.json";
private static readonly object _Lock = new object();
private static string RecordFilePath =>
Path.Combine(ApplicationExt.DataPath, "_config_setting", FILE_NAME);
// 기록 키 : 현재 레시피 폴더 경로
public static string GetCurrentRecipeKey()
{
return Path.GetFullPath(PatternConstants.GetCurrentRecipeFilePath()).TrimEnd('\\').ToLowerInvariant();
}
// 현재 레시피의 패턴 폴더 전체 내용 해시
public static string ComputePatternHash()
{
string patternDir = PatternConstants.GetCurrentRecipePatternRootPath();
var files = new List<string>();
if (Directory.Exists(patternDir))
{
files.AddRange(Directory.GetFiles(patternDir, "*", SearchOption.AllDirectories));
}
using (var sha = SHA256.Create())
{
foreach (var file in files.OrderBy(f => f, StringComparer.OrdinalIgnoreCase))
{
byte[] name = Encoding.UTF8.GetBytes(GetRelativePath(patternDir, file).ToLowerInvariant());
sha.TransformBlock(name, 0, name.Length, null, 0);
byte[] content = File.ReadAllBytes(file);
sha.TransformBlock(content, 0, content.Length, null, 0);
}
sha.TransformFinalBlock(new byte[0], 0, 0);
return BitConverter.ToString(sha.Hash).Replace("-", "");
}
}
// 레시피가 이 해시로 알림 완료됐는지
public static bool IsAcknowledged(string recipeKey, string hash)
{
lock (_Lock)
{
return Load().TryGetValue(recipeKey, out string recorded) && recorded == hash;
}
}
// 레시피의 이 해시를 알림 완료로 기록한다.
public static void Acknowledge(string recipeKey, string hash)
{
lock (_Lock)
{
var records = Load();
records[recipeKey] = hash;
Directory.CreateDirectory(Path.GetDirectoryName(RecordFilePath));
File.WriteAllText(RecordFilePath,
Newtonsoft.Json.JsonConvert.SerializeObject(records, Newtonsoft.Json.Formatting.Indented), Encoding.UTF8);
}
}
private static Dictionary<string, string> Load()
{
if (!File.Exists(RecordFilePath))
{
return new Dictionary<string, string>();
}
return Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, string>>(File.ReadAllText(RecordFilePath))
?? new Dictionary<string, string>();
}
private static string GetRelativePath(string baseDir, string fullPath)
{
string root = Path.GetFullPath(baseDir).TrimEnd('\\') + "\\";
string full = Path.GetFullPath(fullPath);
return full.StartsWith(root, StringComparison.OrdinalIgnoreCase) ? full.Substring(root.Length) : full;
}
}
public class ScannerObjectInfo public class ScannerObjectInfo
{ {
public object Object { get; set; } // Arc, Line, Spline, Dot public object Object { get; set; } // Arc, Line, Spline, Dot

View File

@ -219,13 +219,13 @@ namespace ILSOS_KS.Views
NowDateTime = DateTime.Now; NowDateTime = DateTime.Now;
// Sequence Status check // Sequence Status check
if (_SeqAutoRun.RunState == SequenceRunState.Idle || _SeqAutoRun.RunState == SequenceRunState.EmergencyStopHandling) if (_SeqAutoRun.RunState != SequenceRunState.Idle)
{ {
IsSequenceRunning_AutoRun = false; IsSequenceRunning_AutoRun = true;
} }
else else
{ {
IsSequenceRunning_AutoRun = true; IsSequenceRunning_AutoRun = false;
} }
// Alarm Status check // Alarm Status check