2026-06-05 13:44:39 +09:00

844 lines
45 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Aurora.Api.Devices;
using Hermes;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
namespace AuroraLaser
{
class LaserIPG_YLS : SocketConn, ILaser
{
public bool IsEmissionReady { get; set; }
public bool HasAlarm { get; set; }
private bool _IsSimul;
private int _Status;
private double _OperatingPower;
private double _RepetitionRate = 0.0;
internal bool IsCommError => IsConnected();
#region IPG YLS Enumerator Definitions
public enum eFunctionCommand
{
GetLaserID = 1, // The command requests laser identification data
GetNetworkSettings = 2, // Command requests laser network settings
SetIpSettings = 3, // Command defines laser network address.
SetCommandTimeout = 4, // Set communication timeout. If there is no command during that time, the current connection will be closed. Default value – 5000 ms
GetCriticalErrorCounter = 5, // The command returns the counter of Critical Errors.
GetLongRunningOperationsState = 6, // The command returns the status off all long-running operations in the laser.
LockControl = 10, // The command locks controls on the Control page in LaserNet and for this protocol on other sockets (connections)
UnlockControl = 11, // The command unlocks controls on the Control page in LaserNet and for this protocol on other sockets (connections)
GetLaserStaticParameters = 2000, // Request static parameters structure from the laser
GetLaserData = 2001, // Request dynamic (current) parameters structure from the laser , 매우 중요.
GetTimeData = 2002, // Request time from the laser
SetCurrentTime = 2003, // Set time in the laser
SetAutoSwitchOff = 2004, // Set time for auto switch off the laser
GetPowerSuppliesStaticParameters = 2010, // Request static parameters structure of laser power supplies
GetPowerSupplyData = 2011, // Request dynamic (current) parameters structure of the power supply
GetPowerSupplyParameters = 2012, // Request static parameters structure of the power supply
GetExtOpticsStaticParameters = 2020, // Request static parameters structure of Beamswitch or Beamcoupler
GetBeamSwitchData = 2021, // Request dynamical (current) parameters structure of Beamswitch
GetFFCouplerData = 2022, // Request dynamical (current) parameters structure of Fiber-Fiber Coupler
GetChillerStaticParameters = 2030, // Request static parameters structure of the chiller
GetChillerData = 2031, // Request dynamic (current) parameters structure of the chiller
GetDewPointData = 2032, // Request dynamical (cuurent) parameters structure of dew point sensor
GetFieldbusStaticParameters = 2040, // Request static parameters structure of Fieldbus controller
GetFieldbusControllerParameters = 2041, // Request parameters structure of the given Fieldbus controller
GetFieldbusData = 2042, // Request dynamical (current) parameters structure of Fieldbus controller
SetFieldbusParameters = 2043, // Set common parameters structure for Fieldbus
SetFieldbusSlotParameters = 2044, // Set common parameters structure for Fieldbus
SetFieldbusSlotSpecificParameters = 2045, // Set specific parameters for Fieldbus
GetPulsedStaticParameters = 2050, // Request static parameters structure of pulsed operational modes (lasers of type QCW, QCW+, Pulsed)
GetPulsedData = 2051, // Request dynamical (current) parameters structure of pulsed operational modes (lasers of type QCW, QCW+, Pulsed, HPP, AMB-QCW)
GetAuxUserInterfaceStaticParameters = 2060, // Request static parameters structure of User Interface
GetAuxUserInterfaceData = 2061, // Request dynamic (current) parameters structure of User Interface
GetLaserProgram = 2070, // Request the laser program
SetLaserProgram = 2071, // Set to the laser program
GetQcwLaserProgram = 2052, // Request the Qcw laser program
SetQcwLaserProgram = 2053, // Set to the Qcw laser program
DownloadQcwPulsedLibrary = 2054, // Set to the laser Qcw Pulsed Library
SetAccessLevel = 2080, // The command set access level
GetEventsFromFile = 2090, // The request of stored events from internal file for the synchronization at start of connection session. This command can be sent one time per session only. After this command all new events should be read by command GetNewEvents
GetNewEvents = 2091, // The request of new events list from the last call of this command
GetPulseGeneratorParameters = 2092, // Request static parameters structure of pulse generator
GetPulseGeneratorData = 2093, // Request dynamical (current) parameters structure of pulse generator
SetPulseGeneratorParameter = 2520, // The command set pulse generator parameter
GetLaserModuleData = 2300, // Request dynamic (current) parameters structure of the laser module
GetXY2Data = 2400, // Request parameters structure of XY2-100 Interface
DownloadNewConfiguration = 2600, // The command download HPLP file with new configuration and/or new firmware into the laser
// Control Commands , See the manual : Access Permission
PowerSupply = 2500, // The command is switching on/off the main power supply of the laser: (= 0 – switching off) (= 1 – switching on)
SetCurrent = 2501, // The command set pump current
SetPower = 2502, // The command set output power
Emission = 2503, // The command is switching on/off the emission: (= 0 – switching off) (= 0x155 – switching on)
GuideLaser = 2504, // The command is switching on/off guide lasers:
// Parameter1: the optical channel number or 0 – the mian guide laser
// Parameter2: (= 0 – switching off) (= 1 – switching on)
SetOpticalChannel = 2505, // The command set optical channel (0 – home-position)
Reset = 2506, // The command reset non-critical errors
ResetCriticalError = 2507, // The command reset critical errors. Parameter is the string got from IPG Service.
AnalogCtrl = 2508, // The command is switching on/off the analogue control: (= 0 – switching off) (= 1 – switching on)
ModulationCtrl = 2509, // The command is switching on/off the external control (modulation input): (= 0 – switching off) (= 1 – switching on)
SetRiseTime = 2510, // The command set rise time for the program 0
SetFallTime = 2511, // The command set fall time for the program 0
StartProgram = 2512, // The command start of the laser program
StopProgram = 2513, // The command interrupt the running laser program
SetPulsedMode = 2514, // The command is switching on/off the pulsed (QCW) mode of the laser:
// bit 0 – switching on/off – the pulsed mode; For HPP lasers switch on/off HPP mode;
// bit 1 – switching on/off – the single short submode for the pulsed mode;
// bit 2 – switching on/off – the gate submode for the pulsed mode
SetFrequency = 2515, // The command set frequency for the pulsed mode
SetPulsedWidth = 2516, // The command set pulse width for the pulsed mode
DisableModules = 2517, // The command disables selected modules for working in “single module mode”. 0 – enable all working modules.
SetSideSpotPower = 2521, // The command set output power for the side spots of the Brazing lasers. For AMB lasers the command set output power for the central and ring cores. Parameter1: Power1 (W) , Parameter2: Power2 (W)
EnablePowerSensorAdjustment = 2522, // The command enabled/disabled adjustment of power sensor option: 1 – enable , 0 – disable
AdjustPowerSensor = 2523, // The command adjust power sensor if power sensor adjustment option is activated
EnableOutputPowerTune = 2524, // The command enabled/disabled output power tune option: 1 – enable, 0 – disable
TuneOutputPower = 2525, // The command tune output power if output power tune option is activated.
SetAMBCurrents = 2526, // The command set pump currents for the central and ring cores in AMB2 lasers. Parameter1: Central Current , Parameter2: Ring Current
SetPulsedModeCh2 = 2527, // Similar to SetPulsedMode (2514) command for the second channel.
SetFrequencyCh2 = 2528, // Similar to SetFrequency (2515) command for the second channel.
SetPulsedWidthCh2 = 2529, // Similar to SetPulsedWidth (2516) command for the second channel.
SetXY2Control = 2530 // The command set control word on XY2-100 Interface
}
// Table 5.1: Laser Types, GetLaserData → LaserType
enum eLaserType
{
MultiMode = 0,
SingleMode,
Reserved,
SingleModeHPLaser,
HighBrightnessMultiMode
}
//private static class MaskingData
//{
// // enum 으로 선언하면 맨마지막 항목인 FirmwareIsUpdatding 이 signed 로 처리되어서 overflow 가능성있음
// public const UInt32 LaserEmissionSlowSignal = 0x00000001; // Emission of the laser is on (slow signal from laser modules)
// public const UInt32 LaserModulationMode = 0x00000002;
// public const UInt32 MainGuideLaser = 0x00000004;
// public const UInt32 LaserReady = 0x00000008;
// public const UInt32 RearDoorOpen = 0x00000010;
// public const UInt32 FrontDoorOpen = 0x00000020;
// public const UInt32 LaserAnalogControl = 0x00000040;
// public const UInt32 LaserEmissionEnable = 0x00000080;
// public const UInt32 LaserHardwiringActive = 0x00000100;
// public const UInt32 Reserved1 = 0x00000200;
// public const UInt32 ChillerReady = 0x00000400;
// public const UInt32 SWControlDisabledRequired = 0x00000800;
// public const UInt32 MainPowerSupplyOn = 0x00001000;
// public const UInt32 ErrorOccurred = 0x00002000;
// public const UInt32 BeamSwitchReady = 0x00004000;
// public const UInt32 IPGServiceMode = 0x00008000;
// public const UInt32 LaserProgramActived = 0x00010000;
// public const UInt32 LaserProgramInterrupted = 0x00020000;
// public const UInt32 LaserProgramEnded = 0x00040000;
// public const UInt32 LaserPermission_BeamSwitchHighLevel = 0x00080000;
// public const UInt32 LaserEnable_BeamSwitchHighLevel = 0x00100000;
// public const UInt32 TestKeyInRobotPosition = 0x00200000;
// public const UInt32 LaserAssignedbyRobot = 0x00400000; // The laser is assigned by robot via hardwiring or fieldbus interface
// public const UInt32 LaserEmissionFastSignal = 0x00800000; // Emission of the laser is on (fast signal from detector in the combiner unit)
// public const UInt32 SignalRestoreDefaultSetting = 0x01000000; // The signal from hardware button for restore default settings (now it used only for restoration of IP settings in the laser)
// public const UInt32 SignalInitialization = 0x02000000; // The signal about initialization (restart) of main microcontroller in the laser
// public const UInt32 CanResetCriticalError = 0x04000000; // The laser can "reset critical errors" in the laser by command "reset"
// public const UInt32 QCWMode = 0x08000000;
// public const UInt32 ShutdownState = 0x10000000;
// public const UInt32 InverseShutdownState = 0x20000000; // 중요!. Inversion of bit 28. If this bit same as bit 28 – all information from the laser is inadequate
// public const UInt32 StandbyState = 0x40000000;
// public const UInt32 FirmwareIsUpdatding = 0x80000000;
//}
#region GetLaserData = 2001, Structure Info
// State1
const string LaserEmissionSlowSignal = "LaserEmissionSlowSignal";
const string LaserModulationMode = "LaserModulationMode";
const string MainGuideLaser = "MainGuideLaser";
const string LaserReady = "LaserReady";
const string RearDoorOpen = "RearDoorOpen";
const string FrontDoorOpen = "FrontDoorOpen";
const string LaserAnalogControll = "LaserAnalogControll";
const string LaserEmissionEnable = "LaserEmissionEnable";
const string LaserHardwiringActive = "LaserHardwiringActive";
const string Reserved1 = "Reserved1";
const string ChillerReady = "ChillerReady";
const string SWControlDisabledRequired = "SWControlDisabledRequired";
const string MainPowerSupplyOn = "MainPowerSupplyOn";
const string ErrorOccurred = "ErrorOccurred";
const string BeamSwitchReady = "BeamSwitchReady";
const string IPGServiceMode = "IPGServiceMode";
const string LaserProgramActived = "LaserProgramActived";
const string LaserProgramInterrupted = "LaserProgramInterrupted";
const string LaserProgramEnded = "LaserProgramEnded";
const string LaserPermission_BeamSwitchHighLevel = "LaserPermission_BeamSwitchHighLevel";
const string LaserEnable_BeamSwitchHighLevel = "LaserEnable_BeamSwitchHighLevel";
const string TestKeyInRobotPosition = "TestKeyInRobotPosition";
const string LaserAssignedbyRobot = "LaserAssignedbyRobot";
const string LaserEmissionFastSignal = "LaserEmissionFastSignal";
const string SignalRestoreDefaultSetting = "SignalRestoreDefaultSetting";
const string SignalInitialization = "SignalInitialization";
const string CanResetCriticalError = "CanResetCriticalError";
const string QCWMode = "QCWMode";
const string ShutdownState = "ShutdownState";
const string InverseShutdownState = "InverseShutdownState";
const string StandbyState = "StandbyState";
const string FirmwareIsUpdatding = "FirmwareIsUpdatding";
private Dictionary<string, UInt32> LaserStatusMaskMap = new Dictionary<string, UInt32>
{
{ LaserEmissionSlowSignal, 0x00000001},
{ LaserModulationMode, 0x00000002},
{ MainGuideLaser, 0x00000004},
{ LaserReady, 0x00000008},
{ RearDoorOpen, 0x00000010},
{ FrontDoorOpen, 0x00000020},
{ LaserAnalogControll, 0x00000040},
{ LaserEmissionEnable, 0x00000080},
{ LaserHardwiringActive, 0x00000100},
{ Reserved1, 0x00000200},
{ ChillerReady, 0x00000400},
{ SWControlDisabledRequired, 0x00000800},
{ MainPowerSupplyOn, 0x00001000},
{ ErrorOccurred, 0x00002000},
{ BeamSwitchReady, 0x00004000},
{ IPGServiceMode, 0x00008000},
{ LaserProgramActived, 0x00010000},
{ LaserProgramInterrupted, 0x00020000},
{ LaserProgramEnded, 0x00040000},
{ LaserPermission_BeamSwitchHighLevel, 0x00080000},
{ LaserEnable_BeamSwitchHighLevel, 0x00100000},
{ TestKeyInRobotPosition, 0x00200000},
{ LaserAssignedbyRobot, 0x00400000},
{ LaserEmissionFastSignal, 0x00800000},
{ SignalRestoreDefaultSetting, 0x01000000},
{ SignalInitialization, 0x02000000},
{ CanResetCriticalError, 0x04000000},
{ QCWMode, 0x08000000},
{ ShutdownState, 0x10000000},
{ InverseShutdownState, 0x20000000},
{ StandbyState, 0x40000000},
{ FirmwareIsUpdatding, 0x80000000},
};
// State2 는 생략
// Alarm1 Code
const string Alarm1_laserFiberInterlock = "laserFiberInterlock";
const string Alarm1_laserOverheating = "laserOverheating";
const string Alarm1_HighBackReflection = "HighBackReflection";
const string Alarm1_HighLevelSignalPhotoDiode1 = "HighLevelSignalPhotoDiode1";
const string Alarm1_HighLevelSignalPhotoDiode2 = "HighLevelSignalPhotoDiode2";
const string Alarm1_LaserModuleFailed = "LaserModuleFailed";
const string Alarm1_EStop = "EStop";
const string Alarm1_ElectronicOverheating = "ElectronicOverheating";
const string Alarm1_LowWaterFlowFeedingFiber = "LowWaterFlowFeedingFiber";
const string Alarm1_LowWaterFlowProcessFiberIn = "LowWaterFlowProcessFiberIn";
const string Alarm1_LowWaterFlowProcessFiberOut = "LowWaterFlowProcessFiberOut";
const string Alarm1_LowWaterFlowLaser = "LowWaterFlowLaser";
const string Alarm1_SignalLampErrorOnLaser = "SignalLampErrorOnLaser";
const string Alarm1_CombinerFailed = "CombinerFailed";
const string Alarm1_UnExpectedPumpCurrent = "UnExpectedPumpCurrent";
const string Alarm1_InitializationError = "InitializationError";
const string Alarm1_UnExpectedGroundLeakage = "UnExpectedGroundLeakage";
const string Alarm1_UnConnectedLaserModuleExist = "UnConnectedLaserModuleExist";
const string Alarm1_PowerSupplyErrorOfLaserModuleExist = "PowerSupplyErrorOfLaserModuleExist";
const string Alarm1_ChillerError = "ChillerError";
const string Alarm1_WaterInLaser = "WaterInLaser";
const string Alarm1_CriticalErrorLaser = "CriticalErrorLaser"; // Critical error in the laser (Call for service)
const string Alarm1_FeedingFiberInitialError = "FeedingFiberInitialError"; // Feeding Fiber initial diagnostic procedure finished unsuccessfully
const string Alarm1_ChillerParameterOutofRange = "ChillerParameterOutofRange";
const string Alarm1_PowerSupplyAlarmExist = "PowerSupplyAlarmExist";
const string Alarm1_EStopButtonPressed = "EStopButtonPressed";
const string Alarm1_ACPowerProblem = "ACPowerProblem";
const string Alarm1_ExternalSafetyLoopOpen = "ExternalSafetyLoopOpen";
private Dictionary<string, UInt32> LaserAlarmMaskMap1 = new Dictionary<string, UInt32>
{
{ Alarm1_laserFiberInterlock, 0x00000001},
{ Alarm1_laserOverheating, 0x00000002},
{ Alarm1_HighBackReflection, 0x00000004},
{ Alarm1_HighLevelSignalPhotoDiode1, 0x00000008},
{ Alarm1_HighLevelSignalPhotoDiode2, 0x00000010},
{ Alarm1_LaserModuleFailed, 0x00000020},
{ Alarm1_EStop, 0x00000040},
{ Alarm1_ElectronicOverheating, 0x00000080},
{ Alarm1_LowWaterFlowFeedingFiber, 0x00000100},
{ Alarm1_LowWaterFlowProcessFiberIn, 0x00000200},
{ Alarm1_LowWaterFlowProcessFiberOut, 0x00000400},
//{ Reserved, 0x00000800},
//{ Reserved, 0x00001000},
//{ Reserved, 0x00002000},
//{ Reserved, 0x00004000},
{ Alarm1_LowWaterFlowLaser, 0x00008000},
{ Alarm1_SignalLampErrorOnLaser, 0x00010000},
{ Alarm1_CombinerFailed, 0x00020000},
{ Alarm1_UnExpectedPumpCurrent, 0x00040000},
{ Alarm1_InitializationError, 0x00080000},
{ Alarm1_UnExpectedGroundLeakage, 0x00100000},
{ Alarm1_UnConnectedLaserModuleExist, 0x00200000},
{ Alarm1_PowerSupplyErrorOfLaserModuleExist, 0x00400000},
{ Alarm1_ChillerError, 0x00800000},
{ Alarm1_WaterInLaser, 0x01000000},
{ Alarm1_CriticalErrorLaser, 0x02000000},
{ Alarm1_FeedingFiberInitialError, 0x04000000},
{ Alarm1_ChillerParameterOutofRange, 0x08000000},
{ Alarm1_PowerSupplyAlarmExist, 0x10000000},
{ Alarm1_EStopButtonPressed, 0x20000000},
{ Alarm1_ACPowerProblem, 0x40000000},
{ Alarm1_ExternalSafetyLoopOpen, 0x80000000},
};
// Alarm2 Code
// Warning Code
#endregion
#endregion
STRUCT_LASER_DATA stLaserData;
Dictionary<string, bool> LaserDataMap { get; set; }
Dictionary<string, bool> LaserAlarmMap1 { get; set; }
Dictionary<string, bool> LaserAlarmMap2 { get; set; }
Dictionary<string, bool> LaserWarningMap { get; set; }
Thread m_threadUpdateLaserStatus = null;
private bool bPilotLaserOnCmd;
private bool bLaserEmissionReadyOnCmd;
public LaserIPG_YLS(string deviceid, bool isSimul) : base(deviceid, isSimul)
{
_IsSimul = isSimul;
bPilotLaserOnCmd = false;
if (LaserDataMap == null || LaserDataMap.Count < 1)
InitLaserDataMapInfo();
}
public int Open(LaserConfig Config)
{
if (_IsSimul) {
return E1.OK;
}
int nRet = Connect(Config.SocketConfig);
if (nRet == E1.OK) {
Thread.Sleep(100);
m_threadUpdateLaserStatus = new Thread(new ThreadStart(UpdateLaserStatus));
m_threadUpdateLaserStatus.Start();
}
return E1.OK;
}
public void DisConnect()
{
if (_IsSimul) {
return;
}
if (IsConnected()) {
// 동작중인것을 정지시키는 코드는 여기에
// update 하는 thread 정지
if (m_threadUpdateLaserStatus != null) {
m_threadUpdateLaserStatus.Join(500);
m_threadUpdateLaserStatus.Abort();
}
Close();
}
}
public int LaserOn()
{
STRUCTUREA stA = new STRUCTUREA() {
Parameter1 = (UInt16)0, // channel. main guide laser == 0
Parameter2 = (UInt16)1, // switch on == 1
};
STRUCT_COMMAND_RESPONSE stResponse = new STRUCT_COMMAND_RESPONSE();
// power supply on 이 맞는지 아닌지... Control Command 에 Laser On 명령이 따로 없는데, IPG Laser SW 에는 버튼이 있다.
// 장비에서 돌려보면서 명령을 찾아야할 수 있음
int nRet = SendNReceive(eFunctionCommand.PowerSupply, StructureAToByte(stA), out stResponse);
bLaserEmissionReadyOnCmd = true;
return nRet;
}
public int LaserOff()
{
STRUCTUREA stA = new STRUCTUREA() {
Parameter1 = (UInt16)0, // channel. main guide laser == 0
Parameter2 = (UInt16)0, // switch off == 0
};
STRUCT_COMMAND_RESPONSE stResponse = new STRUCT_COMMAND_RESPONSE();
// power supply on 이 맞는지 아닌지... Control Command 에 Laser On 명령이 따로 없는데, IPG Laser SW 에는 버튼이 있다.
// 장비에서 돌려보면서 명령을 찾아야할 수 있음
int nRet = SendNReceive(eFunctionCommand.PowerSupply, StructureAToByte(stA), out stResponse);
bLaserEmissionReadyOnCmd = false;
return nRet;
}
public int PilotLaserOn()
{
STRUCTUREA stA = new STRUCTUREA() {
Parameter1 = (UInt16)0, // channel. main guide laser == 0
Parameter2 = (UInt16)1, // switch on == 1
};
STRUCT_COMMAND_RESPONSE stResponse = new STRUCT_COMMAND_RESPONSE();
int nRet = SendNReceive(eFunctionCommand.GuideLaser, StructureAToByte(stA), out stResponse);
bPilotLaserOnCmd = true;
return nRet;
}
public int PilotLaserOff()
{
STRUCTUREA stA = new STRUCTUREA() {
Parameter1 = (UInt16)0, // channel. main guide laser == 0
Parameter2 = (UInt16)0, // switch off == 0
};
STRUCT_COMMAND_RESPONSE stResponse = new STRUCT_COMMAND_RESPONSE();
int nRet = SendNReceive(eFunctionCommand.GuideLaser, StructureAToByte(stA), out stResponse);
bPilotLaserOnCmd = false;
return nRet;
}
public bool GetConnected()
{
return IsConnected();
}
public int SetData(int nTarget, int value)
{
// nTarget 이 eSetCommand 로 들어와야지 쓸수있다.
// interlock 을 어떻게 할것인지는 고민이 필요하다.
if (nTarget < 0 || nTarget > 65)
return E2.INTERNAL_ERROR;
return E1.OK;
//return SendCommand((eSetCommand)nTarget, value) ? E1.OK : E2.ABORTED;
}
public string GetData(int nTarget)
{
// nTarget 이 eReadCommand 로 들어와야지 쓸수있다.
// interlock 을 어떻게 할것인지는 고민이 필요하다.
if (nTarget < 0 || nTarget > 96)
return E2.INTERNAL_ERROR.ToString();
return "";
//return bret ? outvalue.ToString() : E2.INTERNAL_ERROR.ToString();
}
private void InitLaserDataMapInfo()
{
if (LaserDataMap == null)
LaserDataMap = new Dictionary<string, bool>();
else
LaserDataMap.Clear();
foreach (var item in LaserStatusMaskMap) {
LaserDataMap.Add(item.Key, false);
}
}
private bool CalLaserStateData(UInt32 nData, UInt32 nMask)
{
// nMask 가 OR 연산해서 들어왔을때는?
return ((nData & nMask) == 0) ? false : true;
}
private bool CheckValidationLaserData(UInt32 nData)
{
bool bShutdown = ((nData & LaserStatusMaskMap[ShutdownState]) == 0) ? false : true;
bool bInvShutdown = ((nData & LaserStatusMaskMap[InverseShutdownState]) == 0) ? false : true;
return bShutdown == !bInvShutdown;
}
private bool GetLaserData(out STRUCT_LASER_DATA LaserData)
{
// sturcture 를 새로 만들어서 쓸때는 이거 호출
LaserData = new STRUCT_LASER_DATA();
if (_IsSimul) {
return true;
}
byte[] arrSend = null;
STRUCT_COMMAND_RESPONSE stReceive;
int nRet = SendNReceive(eFunctionCommand.GetLaserData, arrSend, out stReceive);
if (nRet == E1.OK) {
LaserData = BytesToObject<STRUCT_LASER_DATA>(stReceive.nData);
return true;
} else
return false;
}
private void GetLaserAllStatus()
{
// LaserDataMap 에 전부 넣어주는 함수
// 한번에 여러개 읽어올때 통신을 한번만 하는 용도로 사용
if (_IsSimul)
return;
if (LaserDataMap == null || LaserDataMap.Count < 1)
InitLaserDataMapInfo();
//GetLaserData(out stLaserData);
//foreach (var item in LaserDataMap)
//{
// LaserDataMap[item.Key] = CalLaserStateData(stLaserData.Status1, LaserStatusMaskMap[item.Key]);
//}
}
private void UpdateLaserStatus()
{
int UpdateTimeInterval = 300; // 300ms
Thread.Sleep(UpdateTimeInterval);
GetLaserAllStatus();
}
public bool GetInitCommunication()
{
// IPG 는 해당 함수 없음
return true;
}
public bool GetEmissionStatus()
{
if (_IsSimul)
return false;
if (LaserDataMap == null)
return false;
// 매번 불러오면 낭비니까 주기적으로 업데이트한 정보로 대체
//STRUCT_LASER_DATA stLaserData = new STRUCT_LASER_DATA();
//if (GetLaserData(out stLaserData))
//{
// bool bEmissionFastSignal = CalLaserStateData(stLaserData.Status1, MaskingData.LaserEmissionFastSignal);
// bool bEmissionSlowSignal = CalLaserStateData(stLaserData.Status1, MaskingData.LaserEmissionSlowSignal);
// return bEmissionFastSignal || bEmissionSlowSignal;
//}
return LaserDataMap[LaserEmissionFastSignal] || LaserDataMap[LaserEmissionSlowSignal];
}
public bool GetLaserReady()
{
if (LaserDataMap == null)
return false;
return LaserDataMap[LaserReady];
}
public bool GetLaserError()
{
// code 는 bit 연산해서 확인 가능함
bool AlarmOccured1 = stLaserData.Alarm1 == 0 ? false : true;
bool AlarmOccured2 = stLaserData.Alarm2 == 0 ? false : true;
return AlarmOccured1 || AlarmOccured2;
}
public bool GetWariningStatus()
{
// code 는 bit 연산해서 확인 가능함
bool WarningOccured1 = stLaserData.Warning1 == 0 ? false : true;
bool WarningOccured2 = stLaserData.Warning2 == 0 ? false : true;
return WarningOccured1 || WarningOccured2;
}
// MAINS_STATUS, ERROR_STATUS 는 위에 있음
public bool GetPilotLaserStatus()
{
if (LaserDataMap == null)
return false;
return LaserDataMap[MainGuideLaser];
}
public string GetControlMode()
{
// 업데이트 예정
return "";
}
public string GetPowerCenter()
{
// LaserData 에 power 는 1개만 있음. (SetPower 항목)
// Center 와 Ring 은 Current , Voltage 로 나뉘어져 있는데, 두개를 받아서 곱해야하는지 애매함.
double PowerCenter = stLaserData.SetPower;
return "";
}
public string GetPowerRing()
{
// 업데이트 예정
return "";
}
#region Set 명령 나간 bit 를 모니터링
public bool GetStartLaserSetBitStatus()
{
// Laser Start 명령. 비슷한 이름이 많은데 기능에 대한 설명이 없으니 유추가 어렵다.
return false;
}
public bool GetLaserStartSetBitStatus()
{
// Laser On 명령. Laser Emission Ready 를 위한 bit
return bLaserEmissionReadyOnCmd;
}
public bool GetPilotLaserSetBitStatus()
{
// Pilot Laser On 명령.
// IPG 는 명령이 나간것에 대한 정보는 없다. 내부적으로 처리
return bPilotLaserOnCmd;
}
public bool GetLaserResetSetBitStatus()
{
// Laser Reset 명령.
// 업데이트 예정
return false;
}
public bool GetControlModeSetStatus()
{
// Control mode Local(false) Remote(true)
// 업데이트 예정
return false;
}
#endregion
#region TCP/IP Functions
private int SendNReceive(eFunctionCommand eSetCommand, byte[] nData, out STRUCT_COMMAND_RESPONSE stReceive)
{
//if (nData == null)
// nData = new byte[2048];
STRUCT_COMMAND_REQUEST stCommand = new STRUCT_COMMAND_REQUEST(nData);
stCommand.nCommandCode = (UInt16)eSetCommand;
stCommand.nReserve = (UInt16)0;
if (nData == null)
stCommand.nDataSize = (UInt32)0;
else
stCommand.nDataSize = (UInt32)nData.Length;
byte[] btCommand = StructToBytes(stCommand);
stCommand.nCheckSum = GenerateCheckSum(btCommand, nData.Length + 7);
btCommand = StructToBytes(stCommand);
byte[] btReceive = new byte[2048];
SendAndRecieve(btCommand, out btReceive);
if (btReceive == null) {
stReceive = new STRUCT_COMMAND_RESPONSE();
return E1.ARGUMENT;
}
stReceive = BytesToStruct(btReceive);
return E1.OK;
}
private byte[] StructToBytes(STRUCT_COMMAND_REQUEST obj)
{
int datasize = Convert.ToInt32(obj.nDataSize + 10);
IntPtr buff = Marshal.AllocHGlobal(datasize);
Marshal.StructureToPtr(obj, buff, false);
byte[] data = new byte[datasize];
Marshal.Copy(buff, data, 0, datasize);
Marshal.FreeHGlobal(buff);
return data;
}
private STRUCT_COMMAND_RESPONSE BytesToStruct(byte[] data)
{
IntPtr ptr = Marshal.AllocHGlobal(data.Length);
if (data.Length < 10) return default(STRUCT_COMMAND_RESPONSE);
Marshal.Copy(data, 0, ptr, data.Length);
var obj = (STRUCT_COMMAND_RESPONSE_NODATA)Marshal.PtrToStructure(ptr, typeof(STRUCT_COMMAND_RESPONSE_NODATA));
Marshal.FreeHGlobal(ptr);
if (Marshal.SizeOf(obj) != data.Length) {
return default(STRUCT_COMMAND_RESPONSE);
}
return default(STRUCT_COMMAND_RESPONSE);
}
private UInt16 GenerateCheckSum(byte[] data, int nSize)
{
UInt16 sum = 0;
if (data.Length < nSize) return 0;
for (int i = 0; i < nSize; i++) {
sum += (UInt16)data[i];
}
return sum;
}
private byte[] StructureAToByte(STRUCTUREA stA)
{
byte[] bytes = new byte[4]; // StructureA 는 4Byte
IntPtr buff = Marshal.AllocHGlobal(4);
Marshal.StructureToPtr(stA, buff, true);
Marshal.Copy(buff, bytes, 0, 4);
Marshal.FreeHGlobal(buff);
return bytes;
}
private T BytesToObject<T>(byte[] data)
{
IntPtr ptr = Marshal.AllocHGlobal(data.Length);
Marshal.Copy(data, 0, ptr, data.Length);
var obj = (T)Marshal.PtrToStructure(ptr, typeof(T));
Marshal.FreeHGlobal(ptr);
if (Marshal.SizeOf(obj) != data.Length) {
return default(T);
}
return obj;
}
#endregion
public static object GetPropertyValue(object obj, string propertyName)
{
if (obj == null)
throw new ArgumentNullException(nameof(obj));
if (string.IsNullOrEmpty(propertyName))
throw new ArgumentNullException(nameof(propertyName));
Type type = obj.GetType();
PropertyInfo propertyInfo = type.GetProperty(propertyName);
if (propertyInfo == null)
throw new ArgumentException($"Property '{propertyName}' not found on type '{type.FullName}'");
return propertyInfo.GetValue(obj);
}
}
#region TCP/IP Communication Format
public struct STRUCT_COMMAND_REQUEST
{
public UInt16 nCommandCode; // Code of the command , 2byte
public UInt16 nReserve; // Should be 0 , 2byte
public UInt32 nDataSize; // Size of data for the command (N) , 4byte
public byte[] nData; // Data, Max size
public UInt16 nCheckSum; // Checksum CRC16 (bytes 0..N+8-1) , 2byte
public STRUCT_COMMAND_REQUEST(byte[] nData) : this()
{
this.nData = nData;
}
}
public struct STRUCT_COMMAND_RESPONSE
{
public UInt16 nAnswerCode; // Code of the answer (↔ command code) , 2byte
public UInt16 nExecutionCode; // Execution operation code , 2byte
public UInt32 nDataSize; // Size of data for the command (N) , 4byte
public byte[] nData; // Data, Max size
public UInt16 nCheckSum; // Checksum CRC16 (bytes 0..N+8-1) , 2byte
public STRUCT_COMMAND_RESPONSE(byte[] nData) : this()
{
this.nData = nData;
}
}
public struct STRUCT_COMMAND_RESPONSE_NODATA
{
public UInt16 nAnswerCode; // Code of the answer (↔ command code) , 2byte
public UInt16 nExecutionCode; // Execution operation code , 2byte
public UInt32 nDataSize; // Size of data for the command (N) , 4byte
public UInt16 nCheckSum; // Checksum CRC16 (bytes 0..N+8-1) , 2byte
}
public struct STRUCT_LASER_DATA
{
// 순서 및 data type 중요. data size 에 맞게 address offset 이 들어감. 임의 수정 금지.
public UInt16 Version; // Version of the structure
public UInt16 SetILD; // Set current , unit (0.01%)
public UInt32 SetPower; // Set power , unit (W)
public UInt32 OutputPower; // Current output power , unit (W)
public UInt16 TemperatureMean; // Modules average temperature , unit (0.1°C)
public UInt16 TemperatureMin; // Modules minimal temperature , unit (0.1°C)
public UInt16 TemperatureMax; // Modules maximal temperature , unit (0.1°C)
public byte nModuleMinTemp; // Number of module with minimal temperature
public byte nModuleMaxTemp; // Number of module with maximal temperature
public UInt16 WaterFlow; // Water flow through the laser, unit (0.1 l/min)
public UInt32 Status1; // Status 1. See Definition of Bit Mask
public UInt32 Status2; // Status 2. See Definition of Bit Mask
public UInt32 Alarm1; // Alarm 1. See Definition of Bit Mask
public UInt32 Alarm2; // Alarm 2. See Definition of Bit Mask
public UInt32 Warning1; // Warning 1. See Definition of Bit Mask
public UInt32 Warning2; // Warning 2. See Definition of Bit Mask
#region Module 16byte datas
// Module 정보. 16byte 씩 되어 있는데, 정의내용이 없다. 4byte 4개씩 정의해주고 안쓰는 방향으로 해야할듯
public UInt32 ModuleUnconnected1; // Modules with communication error
public UInt32 ModuleUnconnected2; //
public UInt32 ModuleUnconnected3; //
public UInt32 ModuleUnconnected4; //
public UInt32 ModuleDisabled1; // Disabled modules
public UInt32 ModuleDisabled2; //
public UInt32 ModuleDisabled3; //
public UInt32 ModuleDisabled4; //
public UInt32 ModuleReserved1; // Reserved modules
public UInt32 ModuleReserved2; //
public UInt32 ModuleReserved3; //
public UInt32 ModuleReserved4; //
public UInt32 ModuleFatalDisabled1; // Modules with critical failure
public UInt32 ModuleFatalDisabled2; //
public UInt32 ModuleFatalDisabled3; //
public UInt32 ModuleFatalDisabled4; //
public UInt32 ModuleErrors1; // Modules which have some error
public UInt32 ModuleErrors2; //
public UInt32 ModuleErrors3; //
public UInt32 ModuleErrors4; //
public UInt32 ModuleFibersInterlocks1; // Modules interlock state
public UInt32 ModuleFibersInterlocks2; //
public UInt32 ModuleFibersInterlocks3; //
public UInt32 ModuleFibersInterlocks4; //
#endregion
public UInt32 HardwiringInputs; // Hardwiring interface inputs states
public UInt32 HardwiringOutputs; // Hardwiring interface output states
public UInt16 RiseTime; // Emission on (rise) time , unit (0.1ms)
public UInt16 FallTime; // Emission off (fall) time , unit (0.1ms)
public UInt16 ProgramNumber; // Number of current laser program
public UInt16 ProgramEndCode; // Program exit code (Table 16.3)
public UInt16 ProgramErrorLine; // Number of line in laser program where the error has appeared
public UInt16 UControl; // Control voltage value , unit (1mV)
public UInt32 ePCStatus; // Table 5.12
public UInt16 FFWaterFlow; // Water flow through the Feeding Fiber , unit (0.1 l/min)
public UInt16 SideSpotLaserPower1; // Current output power for side spot 1 , unit (1W)
public UInt16 SideSpotLaserPower2; // Current output power for side spot 2 , unit (1W)
public UInt16 SetSideSpotLaserPower1; // Set output power for side spot 1. For AMB lasers is set output power of central core. , unit (1W)
public UInt16 SetSideSpotLaserPower2; // Set output power for side spot 2. For AMB lasers is set output power of ring core. , unit (1W)
public UInt32 OutputPeakPower; // Current output power (Peak) , unit (1W)
public UInt32 CustomerOutputPower; // Customer output power , unit (1W)
public UInt16 OutputPowerTune; // Output power tune value , unit (0.1%)
public UInt16 SetCentralCoreCurrent; // Set output pump current of central core. Valid only for AMB2 lasers , unit (0.1%)
public UInt16 SetRingCoreCurrent; // Set output pump current of ring core. Valid only for AMB2 lasers. , unit (0.1%)
public UInt16 ParamsChangedCounter; // Counter showing changes in laser parameters or configuration.
public UInt16 ExtAnalogControlVoltage1; // External analog control voltage 1 , unit (1mV)
public UInt16 ExtAnalogControlVoltage2; // External analog control voltage 2 , unit (1mV)
}
public struct STRUCTUREA
{
public UInt16 Parameter1;
public UInt16 Parameter2;
}
#endregion
}