using Aurora; using Aurora.Api; using Aurora.Api.Devices; using AuroraDeviceCommon.Utils; using AuroraIO; using AuroraLaser.Trumpf; using Hermes; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.IO; using System.Windows; //using PropertyTools.DataAnnotations; namespace AuroraLaser { public class Laser : Device { protected Logger Log = new Logger("Laser"); public event EventHandler updateCore; // IOBoard 제어로 Laser On / Off 케이스... public Func ExtLaserEnable { get; set; } public Func ExtLaserDisable { get; set; } public Func ExtPilotOnOff { get; set; } #region Constructor public Laser(string deviceId, bool isSimul) { CommType = CommunicationType.Etc; _IsSimulBySetting = isSimul; DeviceId = deviceId; } #endregion #region Properties public bool IsLaser { get; set; } public LaserConfig Config { get; set; } //public LaserObj _laserObj { get; set; } private LaserObj _laserObj { get; set; } //public ILaser _Laser; private ILaser _Laser; #endregion #region Override method protected override int DoActivate(IDeviceConfig config) { Config = config as LaserConfig; IsSimul = Config.IsSimul || _IsSimulBySetting; if (IsActivated) { return E1.OK; } switch (Config.Type) { case eLaserType.ArmLaser: _Laser = new LaserArm(DeviceId, IsSimul, SocketProtocol.UDP); break; case eLaserType.TrueDiskLaser: _Laser = new LaserTrueDisk(DeviceId, IsSimul, SocketProtocol.TCP); break; case eLaserType.TruFiber: _Laser = new LaserTruFiber(DeviceId, IsSimul, Config.Opcua_Slot_No, SocketProtocol.TCP); break; case eLaserType.TruPulse: IExternalController core = new TruPulse(DeviceId, IsSimul); core.LaserEnableFunc = (on) => ExtLaserEnable(on); core.LaserDisableFunc = (on) => ExtLaserDisable(on); core.PilotOnOffFunc = (on) => ExtPilotOnOff(on); _Laser = core as ILaser; updateCore?.Invoke(this, null); break; case eLaserType.CoherentHyperRapidLaser: _laserObj = new LaserCoherent(); break; case eLaserType.LaserRapidLX: _Laser = new LaserRapid(DeviceId, IsSimul, SocketProtocol.TCP); break; case eLaserType.NL202: _Laser = new LaserNL202(DeviceId, IsSimul); break; case eLaserType.IPG_YLPN: _Laser = new LaserIPG_YLPN(DeviceId, IsSimul); break; case eLaserType.IPG_YLS: //_Laser = new LaserIPG_YLS(DeviceId, IsSimul); //EquipDef 를 가져올 방법이 없다. string 그대로 넣고 해봄 var obj = Application.Current.AuroraEnv().DeviceManager["IO_Board"] as IODevice; _Laser = new LaserIPG_IO(DeviceId, IsSimul, obj); break; case eLaserType.Coherent_Arm_IO: obj = Application.Current.AuroraEnv().DeviceManager["IO_Board"] as IODevice; _Laser = new LaserArm_IO(DeviceId, IsSimul, obj); break; case eLaserType.Trumpf_IO: obj = Application.Current.AuroraEnv().DeviceManager["IO_Board"] as IODevice; _Laser = new LaserTrumpf_IO(DeviceId, IsSimul, obj); break; default: _laserObj = null; Log.E(string.Format("Check Laser Type Setting")); break; } if (_Laser == null) { Log.E(string.Format("LaserObj is Null")); return E1.ARGUMENT; } if (Config.IsSimul) { return E1.OK; } return _Laser.Open(Config); ; } protected override int DoDeactivate() { if (IsSimul) { return E1.OK; } if (_Laser != null) { _Laser.DisConnect(); } return E1.OK; } #endregion public int Open(LaserConfig Config) { if (IsSimul) { return E1.OK; } if (_Laser == null) { return E1.GENERIC; } return _Laser.Open(Config); } public void DisConnect() { if (IsSimul) { return; } if (_Laser == null) { return; } _Laser.DisConnect(); } public int LaserOn() { if (IsSimul) { return E1.OK; } if (IsActivated == false || _Laser == null) { return E1.GENERIC; } return _Laser.LaserOn(); } public int LaserOff() { if (IsSimul) { return E1.OK; } if (IsActivated == false || _Laser == null) { return E1.GENERIC; } return _Laser.LaserOff(); } public int PilotLaserOn() { if (IsSimul) { return E1.OK; } if (IsActivated == false || _Laser == null) { return E1.GENERIC; } return _Laser.PilotLaserOn(); } public int PilotLaserOff() { if (IsSimul) { return E1.OK; } if (IsActivated == false || _Laser == null) { return E1.GENERIC; } return _Laser.PilotLaserOff(); } public bool GetInitCommunication() { if (IsSimul) { return true; } if (IsActivated == false || _Laser == null) { return false; } return _Laser.GetInitCommunication(); } public bool GetEmissionStatus() { if (IsSimul) { return true; } if (IsActivated == false || _Laser == null) { return false; } return _Laser.GetEmissionStatus(); } public bool GetPilotLaserStatus() { if (IsSimul) { return true; } if (IsActivated == false || _Laser == null) { return false; } return _Laser.GetPilotLaserStatus(); } public bool GetLaserReady() { if (IsSimul) { return true; } if (IsActivated == false || _Laser == null) { return false; } return _Laser.GetLaserReady(); } public bool GetWariningStatus() { if (IsSimul) { return true; } if (IsActivated == false || _Laser == null) { return false; } return _Laser.GetWariningStatus(); } public bool GetLaserError() { if (IsSimul) { return true; } if (IsActivated == false || _Laser == null) { return false; } return _Laser.GetLaserError(); } public bool GetStartLaserSetBitStatus() { if (IsSimul) { return true; } if (IsActivated == false || _Laser == null) { return false; } return _Laser.GetStartLaserSetBitStatus(); } public bool GetLaserStartSetBitStatus() { if (IsSimul) { return true; } if (IsActivated == false || _Laser == null) { return false; } return _Laser.GetLaserStartSetBitStatus(); } public bool GetPilotLaserSetBitStatus() { if (IsSimul) { return true; } if (IsActivated == false || _Laser == null) { return false; } return _Laser.GetPilotLaserSetBitStatus(); } public bool GetLaserResetSetBitStatus() { if (IsSimul) { return true; } if (IsActivated == false || _Laser == null) { return false; } return _Laser.GetLaserResetSetBitStatus(); } public string GetControlMode() { if (IsSimul) { return "LOCAL"; // Simul 이면 default "LOCAL" 로 return 해 주자. } if (IsActivated == false || _Laser == null) { return ""; } return _Laser.GetControlMode(); } public bool GetControlModeSetStatus() { if (IsSimul) { return true; } if (IsActivated == false || _Laser == null) { return false; } return _Laser.GetControlModeSetStatus(); } public string GetPowerCenter() { if (IsSimul) { return "1"; } if (IsActivated == false || _Laser == null) { return "0"; } return _Laser.GetPowerCenter(); } public string GetPowerRing() { if (IsSimul) { return ""; } if (IsActivated == false || _Laser == null) { return ""; } return _Laser.GetPowerRing(); } public bool GetConnected() { if (IsSimul) { return true; } if (IsActivated == false || _Laser == null) { return false; } return _Laser.GetConnected(); } public int SetData(int nTarget, int value) { if (IsSimul) { return E1.OK; } if (IsActivated == false || _Laser == null) { return E1.GENERIC; } return _Laser.SetData(nTarget, value); } public int GetLaserDevice(ref ILaser _laser) { if (IsActivated == false || _Laser == null) { return E1.GENERIC; } _laser = _Laser; return E1.OK; } public ILaser getCore() => _Laser; #region PowerProfile // PowerMeter 로 측정된 Calibration data 는 Laser 에 Dependent 하므로 Laser Class 에서 관리한다. private string pathPowerProfile = "PowerProfileTest.json"; private bool _IsSimulBySetting; public TopRootObject LoadPowerProfile() { //TopRootObject toproot; var json = File.ReadAllText(pathPowerProfile); var root = JsonConvert.DeserializeObject(json); return root; } public void AddPowerProfile() { TopRootObject root; if (File.Exists(pathPowerProfile)) { var json = File.ReadAllText(pathPowerProfile); root = JsonConvert.DeserializeObject(json); } else { root = new TopRootObject { PowerProfilesLists = new List() }; } PowerProfilesList profilelist = new PowerProfilesList(); PowerProfile profile = new PowerProfile(); PowerProfileParam param = new PowerProfileParam(); profile.PowerProfileParams.Add(param); profilelist.PowerProfiles.Add(profile); root.PowerProfilesLists.Add(profilelist); var outputjson = JsonConvert.SerializeObject(root, Formatting.Indented); File.WriteAllText(pathPowerProfile, outputjson); } public void CopyPowerProfile(int profileListSelectedIndex) { var json = File.ReadAllText(pathPowerProfile); var root = JsonConvert.DeserializeObject(json); PowerProfilesList profilelist = new PowerProfilesList(); for (int i = 0; i < root.PowerProfilesLists[profileListSelectedIndex].PowerProfiles.Count; i++) { PowerProfile profile = new PowerProfile(); profile.PowerProfileParams.Add(new PowerProfileParam()); profile.PowerProfileParams[0].Copy(root.PowerProfilesLists[profileListSelectedIndex].PowerProfiles[i].PowerProfileParams[0]); profilelist.PowerProfiles.Add(profile); } root.PowerProfilesLists.Add(profilelist); var outputjson = JsonConvert.SerializeObject(root, Formatting.Indented); File.WriteAllText(pathPowerProfile, outputjson); } public void SavePowerProfile(int profileListSelectedIndex) { var json = File.ReadAllText(pathPowerProfile); var root = JsonConvert.DeserializeObject(json); } public void DeleteProfiles(int profileListSelectedIndex) { try { var json = File.ReadAllText(pathPowerProfile); var root = JsonConvert.DeserializeObject(json); root.PowerProfilesLists.RemoveAt(profileListSelectedIndex); var outputjson = JsonConvert.SerializeObject(root, Formatting.Indented); File.WriteAllText(pathPowerProfile, outputjson); } catch (Exception ex) { Log.E($"{ex.Message}"); } } public void AddPowerProfileParam(int profileListSelectedIndex) { TopRootObject root = new TopRootObject(); if (File.Exists(pathPowerProfile)) { var json = File.ReadAllText(pathPowerProfile); root = JsonConvert.DeserializeObject(json); } else { Log.E(string.Format($"PowerPorfile Jason file이 존재하지 않습니다.")); } PowerProfile profile = new PowerProfile(); PowerProfileParam param = new PowerProfileParam(); profile.PowerProfileParams.Add(param); root.PowerProfilesLists[profileListSelectedIndex].PowerProfiles.Add(profile); var JASON = JsonConvert.SerializeObject(root, Formatting.Indented); File.WriteAllText(pathPowerProfile, JASON); } public void CopyProfileParam(int profileListSelectedIndex, int listboxProfileListSelectedIndex) { var json = File.ReadAllText(pathPowerProfile); var root = JsonConvert.DeserializeObject(json); PowerProfilesList profilelist = new PowerProfilesList(); PowerProfile profile = new PowerProfile(); profile.PowerProfileParams.Add(new PowerProfileParam()); profile.PowerProfileParams[0].Copy(root.PowerProfilesLists[profileListSelectedIndex].PowerProfiles[listboxProfileListSelectedIndex].PowerProfileParams[0]); root.PowerProfilesLists[profileListSelectedIndex].PowerProfiles.Add(profile); var outputjson = JsonConvert.SerializeObject(root, Formatting.Indented); File.WriteAllText(pathPowerProfile, outputjson); } public void DeleteProfileParam(int profileListSelectedIndex, int listboxProfileListSelectedIndex) { try { var json = File.ReadAllText(pathPowerProfile); var root = JsonConvert.DeserializeObject(json); root.PowerProfilesLists[profileListSelectedIndex].PowerProfiles.RemoveAt(listboxProfileListSelectedIndex); var outputjson = JsonConvert.SerializeObject(root, Formatting.Indented); File.WriteAllText(pathPowerProfile, outputjson); } catch (Exception ex) { Log.E($"{ex.Message}"); } } #endregion } public interface ILaser { int Open(LaserConfig Config); void DisConnect(); bool GetConnected(); int SetData(int nTarget, int value); string GetData(int nTarget); int LaserOn(); // Laser Ready On , 실제 Laser 를 쏘는 명령은 아님. int LaserOff(); // Laser Ready Off , 실제 쏘고 있는 Laser 를 끄는 명령은 아님. int PilotLaserOn(); int PilotLaserOff(); //int SetProgBit(string PROG_No); bool GetInitCommunication(); bool GetEmissionStatus(); bool GetLaserReady(); bool GetLaserError(); bool GetWariningStatus(); bool GetPilotLaserStatus(); string GetControlMode(); string GetPowerCenter(); string GetPowerRing(); #region Set 명령 나간 bit 를 모니터링 bool GetStartLaserSetBitStatus(); bool GetLaserStartSetBitStatus(); bool GetPilotLaserSetBitStatus(); bool GetLaserResetSetBitStatus(); bool GetControlModeSetStatus(); #endregion } public class LaserPowerCalibrationParam { DataTable m_centerCalibrationTable; DataTable m_ringCalibrationTable; string m_centerBeamPath, m_ringBeamPath; public enum beamMode { Center = 1, Ring = 2, Error = 3 } public DataTable CenterCalibrationTable { get { return m_centerCalibrationTable; } set { m_centerCalibrationTable = value; } } public DataTable RingCalibrationTable { get { return m_ringCalibrationTable; } set { m_ringCalibrationTable = value; } } public string CenterBeamPath { get { return m_centerBeamPath; } set { m_centerBeamPath = value; } } public string RingBeamPath { get { return m_ringBeamPath; } set { m_ringBeamPath = value; } } public LaserPowerCalibrationParam() { // 초기 설정할 때, CSV 파일을 토대로 Center, Ring Beam을 // 확인하는 부분이 필수적인 듯. } public void Initialize(string centerBeamPath, string ringBeamPath) { LoadTable(centerBeamPath, ringBeamPath); } public void InitializeTable(double maxPower, double interval, out DataTable dataTable, uint beam = 0) { DataTable m_calibrationTable = new DataTable(); if (beam == (int)beamMode.Error) { dataTable = m_calibrationTable; // MessageBox return; } m_calibrationTable.Columns.Add(new DataColumn("Index", typeof(double))); //m_calibrationTable.Columns.Add(new DataColumn("Voltage", typeof(double))); m_calibrationTable.Columns.Add(new DataColumn("DesiredPower", typeof(double))); m_calibrationTable.Columns.Add(new DataColumn("CalibratedPower", typeof(double))); double index = 0; DataRow row; int iRowCount; object[] rowArray; while (index < 100) { row = m_calibrationTable.NewRow(); iRowCount = m_calibrationTable.Rows.Count; rowArray = new object[3]; //Index Percentage(0 ~ 100 %) rowArray[0] = index; //Voltage(0 ~ 10 V) //rowArray[1] = index / 10; //Desired Power(0 ~ Max Watt) rowArray[1] = maxPower * index / 100; //초기에는 Calibrated Power = Desired Power rowArray[2] = rowArray[1]; row.ItemArray = rowArray; m_calibrationTable.Rows.Add(row); index = index + interval; } //마지막 100% 인 경우를 추가 row = m_calibrationTable.NewRow(); iRowCount = m_calibrationTable.Rows.Count; rowArray = new object[3]; //Index Percentage(0 ~ 100 %) rowArray[0] = 100; //Voltage(0 ~ 10 V) //rowArray[1] = 10; //Desired Power(0 ~ Max Watt) rowArray[1] = maxPower; //Calibrated Power(0 ~ Max Watt) rowArray[2] = maxPower; row.ItemArray = rowArray; m_calibrationTable.Rows.Add(row); index = index + interval; dataTable = m_calibrationTable; } public void LoadTable(string centerBeamPath, string ringBeamPath) { if (true == System.IO.Path.GetExtension(centerBeamPath).ToUpper().Contains("CSV") && true == System.IO.Path.GetExtension(ringBeamPath).ToUpper().Contains("CSV")) { CenterCalibrationTable = ExcelManagementUnit.ImportDataFromCsv(centerBeamPath); RingCalibrationTable = ExcelManagementUnit.ImportDataFromCsv(ringBeamPath); m_centerBeamPath = centerBeamPath; m_ringBeamPath = ringBeamPath; } else { // Message 박스 열기. } } public void SaveTable(DataTable dataTable, uint beam = (uint)beamMode.Center) { string fileName; if (beam == (int)beamMode.Center) { fileName = CenterBeamPath; CenterCalibrationTable = dataTable; ExcelManagementUnit.ExportToCSV(fileName, CenterCalibrationTable); } if (beam == (int)beamMode.Ring) { fileName = RingBeamPath; RingCalibrationTable = dataTable; ExcelManagementUnit.ExportToCSV(fileName, RingCalibrationTable); } // if (beam == (int)beamMode.Error) MessageBox } public double LinearInterpolation(double x1, double x2, double y1, double y2, double volt) { // x : a < c < b, y: f(a) < f(c) < f(b) double incline = (y2 - y1) / (x2 - x1); double sol = (volt - y1 + incline * x1) / incline; return sol; } public double CalibrateVoltToVolt(double volt, uint beam = (uint)beamMode.Center) { DataTable m_dataTable; if (beam == (int)beamMode.Center) m_dataTable = CenterCalibrationTable; else if (beam == (int)beamMode.Ring) m_dataTable = RingCalibrationTable; else return 0; int percentIndex = 0, calibratedIndex = 2; double x1 = 0, x2 = 0, y1 = 0, y2 = 0; for (int i = 1; i < m_dataTable.Rows.Count; i++) { double.TryParse(Convert.ToString(m_dataTable.Rows[i][calibratedIndex]), out y2); if (y1 < volt && volt <= y2) { double.TryParse(Convert.ToString(m_dataTable.Rows[i - 1][percentIndex]), out x1); double.TryParse(Convert.ToString(m_dataTable.Rows[i][percentIndex]), out x2); return LinearInterpolation(x1, x2, y1, y2, volt); } else y1 = y2; } return 0; } public double CalibrateWattToPercent(double power, uint beam = (uint)beamMode.Center) { DataTable m_dataTable; if (beam == (int)beamMode.Center) m_dataTable = CenterCalibrationTable; else if (beam == (int)beamMode.Ring) m_dataTable = RingCalibrationTable; else return 0; int percentIndex = 0, calibratedIndex = 2; double x1 = 0, x2 = 0, y1 = 0, y2 = 0; for (int i = 1; i < m_dataTable.Rows.Count; i++) { double.TryParse(Convert.ToString(m_dataTable.Rows[i][calibratedIndex]), out y2); if (y1 < power && power <= y2) { double.TryParse(Convert.ToString(m_dataTable.Rows[i - 1][percentIndex]), out x1); double.TryParse(Convert.ToString(m_dataTable.Rows[i][percentIndex]), out x2); return LinearInterpolation(x1, x2, y1, y2, power); } else y1 = y2; } return 0; } public double CalibratePercentToWatt(double power, uint beam = (uint)beamMode.Center) { DataTable m_dataTable; if (beam == (int)beamMode.Center) m_dataTable = CenterCalibrationTable; else if (beam == (int)beamMode.Ring) m_dataTable = RingCalibrationTable; else return 0; int percentIndex = 0, calibratedIndex = 2; double x1 = 0, x2 = 0, y1 = 0, y2 = 0; for (int i = 1; i < m_dataTable.Rows.Count; i++) { double.TryParse(Convert.ToString(m_dataTable.Rows[i][percentIndex]), out y2); if (y1 < power && power <= y2) { double.TryParse(Convert.ToString(m_dataTable.Rows[i - 1][calibratedIndex]), out x1); double.TryParse(Convert.ToString(m_dataTable.Rows[i][calibratedIndex]), out x2); return LinearInterpolation(x1, x2, y1, y2, power); } else y1 = y2; } return 0; } } public class PowerProfileParam { double m_startPowerPercent = 100; [Browsable(true)] [ReadOnly(false)] [DisplayName("1. Start Power(%)")] [Description("Start Power(%)")] public double StartPowerPercent { get { lock (this) { return m_startPowerPercent; } } set { lock (this) { m_startPowerPercent = value; } } } double m_endPowerPercent = 100; [Browsable(true)] [ReadOnly(false)] [DisplayName("2. End Power(%)")] [Description("End Power(%)")] public double EndPowerPercent { get { lock (this) { return m_endPowerPercent; } } set { lock (this) { m_endPowerPercent = value; } } } double m_time = 1; [Browsable(true)] [ReadOnly(false)] [DisplayName("3. Time(msec)")] [Description("Time(msec)")] public double Time { get { lock (this) { return m_time; } } set { lock (this) { m_time = value; } } } public void Copy(PowerProfileParam acopy) { m_startPowerPercent = acopy.m_startPowerPercent; m_endPowerPercent = acopy.m_endPowerPercent; m_time = acopy.m_time; } } public class TopRootObject { public List PowerProfilesLists { get; set; } } public class PowerProfilesList { List m_powerProfiles = new List(); public List PowerProfiles { get { lock (this) { return m_powerProfiles; } } set { lock (this) { m_powerProfiles = value; } } } } public class PowerProfile { List m_powerProfileParams = new List(); public List PowerProfileParams { get { lock (this) { return m_powerProfileParams; } } set { lock (this) { m_powerProfileParams = value; } } } public void Copy(PowerProfile acopy) { for (int i = 0; i < acopy.m_powerProfileParams.Count; i++) { m_powerProfileParams.Add(new PowerProfileParam()); m_powerProfileParams[i].Copy(acopy.m_powerProfileParams[i]); } } } }