using Aurora.Api; using Hermes; using System; using System.Runtime.InteropServices; namespace AuroraLaserScanner { class ScannerRTC6 : ScannerObj { static new readonly Logger Log = new Logger("Scanner"); // For storage of each queried data set, the user program must provide (at an address specified by Ptr) an area of PC main memory equal to 528520 bytes. [MarshalAs(UnmanagedType.LPArray, SizeConst = 528520)] uint[] m_coordinationTransformPtr = new uint[528520]; //set_trigger 관련 추가, get_waveform 에서 얻어올 포인터 추가, 최대 크기로 설정 (2^20 = 1,048,576) [MarshalAs(UnmanagedType.LPArray, SizeConst = 1048576)] int[] m_getWaveformPtr = new int[1048576]; private bool _ModulationMode = false; public override uint Open() { uint errorCode = NO_ERROR; try { errorCode = RTC6Wrap.init_rtc6_dll(); if (!IsOpenUnit && errorCode != 0U && errorCode != 2U) { RTC6Wrap.free_rtc6_dll(); throw new Exception(string.Format("ERR_SCANNER_FAIL_TO_OPEN_DLL_FILE;ERROR CODE:{0}", errorCode)); } RTC6Wrap.select_rtc(m_deviceNo); IsOpenUnit = true; } catch (Exception ex) { throw ex; } return errorCode; } public override void Close() { if (IsOpenUnit == true) { RTC6Wrap.release_rtc(m_deviceNo); RTC6Wrap.free_rtc6_dll(); IsOpenUnit = false; } } public override int Initialize(ScannerConfig config) { //작성 필요 uint errorCode = NO_ERROR; var res = base.Initialize(config); if (res != E1.OK) { return res; } _ModulationMode = config.Modulation; RTC6Wrap.n_stop_execution(m_deviceNo); Log.D(string.Format("[RTC6ScannerUnit] 스캐너 실행 강제 정지")); errorCode = LoadProgramFile(config.ProgramFile); if (errorCode != NO_ERROR) { Log.E(string.Format($"ERR_SCANNER_FAIL_TO_LOAD_PROGRAM_FILE;ERROR CODE:{errorCode},FILE:{config.ProgramFile}")); return E1.ARGUMENT; } Log.D(string.Format($"[RTC6ScannerUnit] Program 파일({config.ProgramFile}) 로딩")); // Acquire board for further access errorCode = RTC6Wrap.acquire_rtc(m_deviceNo); if (errorCode != m_deviceNo) { throw new Exception(string.Format("ERR_SCANNER_FAIL_TO_ACQUIRE_RTC;ERROR CODE:{0},DEVICE_NO:{1}", errorCode, m_deviceNo)); } errorCode = LoadCorrectionFile(config.CorrectionFile, 1, config.Use3DMode); if (errorCode != NO_ERROR) { Log.E(string.Format($"ERR_SCANNER_FAIL_TO_LOAD_CORRECTION_FILE;ERROR CODE:{errorCode},FILE:{config.CorrectionFile}")); return E1.ARGUMENT; } Log.D(string.Format($"[RTC6ScannerUnit] Correction 파일({config.CorrectionFile}) 로딩")); errorCode = LoadCorrectionFile(config.LaserCorrectionFile, 2, config.Use3DMode); if (errorCode != NO_ERROR) { Log.E(string.Format($"ERR_SCANNER_FAIL_TO_LOAD_CORRECTION_FILE;ERROR CODE:{errorCode},FILE:{config.LaserCorrectionFile}")); return E1.ARGUMENT; } Log.D(string.Format($"[RTC6ScannerUnit] Correction 파일({config.LaserCorrectionFile}) 로딩")); //수정 SelectCorrectionTable(1); Log.D(string.Format("[RTC6ScannerUnit] Correction Table 설정")); SetControlMode(config.ControlMode); Log.D(string.Format($"[RTC6ScannerUnit] Control 모드 설정(Value:{config.ControlMode})")); SetLaserMode(config.LaserMode); Log.D(string.Format($"[RTC6ScannerUnit] Laser 모드 설정(Value:{config.LaserMode})")); SetLaserControl(config.LaserControl); Log.D(string.Format($"[RTC6ScannerUnit] Laser 컨트롤값 설정(Value:{config.LaserControl})")); SetFirstPulseKiller(config.FirstPulseKiller); Log.D(string.Format($"[RTC6ScannerUnit] Firse Killer값 설정(Value:{config.FirstPulseKiller})")); ConfigLaserSignal(config.LaserSiganlPin2, config.LaserSiganlPin1, config.LaserSiganlPin9); Log.D(string.Format($"[RTC6ScannerUnit] Laser Signal Pin (Value:{config.LaserSiganlPin2},{config.LaserSiganlPin1},{config.LaserSiganlPin9})")); SetEthernetConfigLinkLoss(config.EthernetConfigLinkLoss); Log.D(string.Format($"[RTC6ScannerUnit] Ehternet 연결 끊김 설정(Value:{config.EthernetConfigLinkLoss})")); for (uint i = 0; i < PORT_COUNT; i++) { RTC6Wrap.n_set_port_default(m_deviceNo, i, 0); Log.D(string.Format($"[RTC6ScannerUnit] {i + 1}번 Port 값 초기화")); } #region ExecuteUpdateParameterList(); SetStartList(eListNo.LIST1); SetScannerDelay(config.JumpDelay, config.MarkDelay, config.PolygonDelay); Log.D(string.Format($"[RTC6ScannerUnit] 스캐너 Delay값 설정(Jump:{config.JumpDelay},Mark:{config.MarkDelay},Polygon:{config.PolygonDelay})")); SetLaesrDelay(config.LaserOnDelay, config.LaserOffDelay); Log.D(string.Format($"[RTC6ScannerUnit] 레이저 Delay값 설정(On:{config.LaserOnDelay},Off:{config.LaserOffDelay})")); SetLaserTiming(config.LaserPeriod, config.Laser1PulseWidth, config.Laser1PulseWidth); Log.D(string.Format($"[RTC6ScannerUnit] 레이저 Timing값 설정(Period:{config.LaserPeriod},Laser1PulseWidth:{config.Laser1PulseWidth})")); SetJumpSpeed(config.JumpSpeed); SetMarkSpeed(config.MarkSpeed); Log.D(string.Format($"[RTC6ScannerUnit] 스캐너 속도값 설정(Jump:{config.JumpSpeed},Mark:{config.MarkSpeed})")); SetEndList(); ExecuteList(eListNo.LIST1); while (GetBusyStatus() == true) ; #endregion #region 2.스캐너모터 원점 복귀 CommandPosX = 0; CommandPosY = 0; CommandPosZ = 0; if (config.Use3DMode) { RTC6Wrap.n_home_position_xyz(m_deviceNo, (int)CommandPosX, (int)CommandPosY, (int)CommandPosZ); Log.D(string.Format($"[RTC6ScannerUnit] 스캐너 X,Y,Z축 위치값 원점복귀")); } else { RTC6Wrap.n_home_position(m_deviceNo, (int)CommandPosX, (int)CommandPosY); Log.D(string.Format($"[RTC6ScannerUnit] 스캐너 X,Y,Z축 위치값 원점복귀")); } #endregion // Rotary On The Fly 임시 if (config.UseMarkingOnTheFly && config.OnTheFlyCoordinate == eOntheFlyCoordinate.Rotate) { SetRotateCenter(config.MarkingOnTheFlyRotateCenterX, config.MarkingOnTheFlyRotateCenterY); } #region 좌표 변환 작업 수행 SetOffset(config.TranslationXOffset, config.TranslationYOffset, 1); SetAngle(config.TranslationAngle, 1); Log.D(string.Format($"[RTC6ScannerUnit] 스캐너 좌표 변화값 설정(X,Y,Θ:{config.TranslationXOffset},{config.TranslationYOffset},{config.TranslationAngle})")); #endregion #region 3.RTC보드의 transform data를 PC로 옮기는 기능 수행 while (GetBusyStatus() == true) ; errorCode = RTC6Wrap.n_upload_transform(m_deviceNo, config.PrimaryHeadNo, m_coordinationTransformPtr); if (errorCode != NO_ERROR) { throw new Exception(string.Format("ERR_SCANNER_FAIL_TO_UPLOAD_TRANSFORM;ERROR CODE:{0}", errorCode)); } Log.D(string.Format($"[RTC6ScannerUnit] Upload Transformation 작업 완료")); #endregion return E1.OK; } public override bool GetModulationMode() { return _ModulationMode; } public override void JumpAbs(double x, double y, eFunctionType type = eFunctionType.COMMAND) { CommandPosX = x; CommandPosY = y; int nX = Convert.ToInt32(CommandPosX * m_ScaleXYFactor); int nY = Convert.ToInt32(CommandPosY * m_ScaleXYFactor); if (type == eFunctionType.COMMAND) { RTC6Wrap.n_goto_xy(m_deviceNo, nX, nY); } else { RTC6Wrap.n_jump_abs(m_deviceNo, nX, nY); } } public override void JumpAbs3D(double x, double y, double z, eFunctionType type = eFunctionType.COMMAND) { CommandPosX = x; CommandPosY = y; CommandPosZ = z; int nX = Convert.ToInt32(CommandPosX * m_ScaleXYFactor); int nY = Convert.ToInt32(CommandPosY * m_ScaleXYFactor); int nZ = Convert.ToInt32(CommandPosZ * m_ScaleZFactor); if (type == eFunctionType.COMMAND) { RTC6Wrap.n_goto_xyz(m_deviceNo, nX, nY, nZ); } else { RTC6Wrap.n_jump_abs_3d(m_deviceNo, nX, nY, nZ); } } public override void JumpRel(double x, double y, eFunctionType type = eFunctionType.COMMAND) { CommandPosX += x; CommandPosY += y; int nX, nY; if (type == eFunctionType.COMMAND) { nX = Convert.ToInt32(CommandPosX * m_ScaleXYFactor); nY = Convert.ToInt32(CommandPosY * m_ScaleXYFactor); RTC6Wrap.n_goto_xy(m_deviceNo, nX, nY); } else { nX = Convert.ToInt32(x * m_ScaleXYFactor); nY = Convert.ToInt32(y * m_ScaleXYFactor); RTC6Wrap.n_jump_rel(m_deviceNo, nX, nY); } } public override void JumpRel3D(double x, double y, double z, eFunctionType type = eFunctionType.COMMAND) { CommandPosX += x; CommandPosY += y; CommandPosZ += z; int nX, nY, nZ; if (type == eFunctionType.COMMAND) { nX = Convert.ToInt32(CommandPosX * m_ScaleXYFactor); nY = Convert.ToInt32(CommandPosY * m_ScaleXYFactor); nZ = Convert.ToInt32(CommandPosZ * m_ScaleZFactor); RTC6Wrap.n_goto_xyz(m_deviceNo, nX, nY, nY); } else { nX = Convert.ToInt32(x * m_ScaleXYFactor); nY = Convert.ToInt32(y * m_ScaleXYFactor); nZ = Convert.ToInt32(z * m_ScaleZFactor); RTC6Wrap.n_jump_rel_3d(m_deviceNo, nX, nY, nZ); } } public override void MarkAbs(double x, double y) { CommandPosX = x; CommandPosY = y; int nX = Convert.ToInt32(CommandPosX * m_ScaleXYFactor); int nY = Convert.ToInt32(CommandPosY * m_ScaleXYFactor); RTC6Wrap.n_mark_abs(m_deviceNo, nX, nY); } public override void MarkRel(double x, double y) { CommandPosX += x; CommandPosY += y; int nX = Convert.ToInt32(x * m_ScaleXYFactor); int nY = Convert.ToInt32(y * m_ScaleXYFactor); RTC6Wrap.n_mark_rel(m_deviceNo, nX, nY); } public override void ArcAbs(double x, double y, double angle) { CommandPosX = x; CommandPosY = y; int nX = Convert.ToInt32(CommandPosX * m_ScaleXYFactor); int nY = Convert.ToInt32(CommandPosY * m_ScaleXYFactor); //각도는 시계방향이 플러스 RTC6Wrap.n_arc_abs(m_deviceNo, nX, nY, angle * (-1)); } public override void ArcRel(double x, double y, double angle) { CommandPosX += x; CommandPosY += y; int nX = Convert.ToInt32(x * m_ScaleXYFactor); int nY = Convert.ToInt32(y * m_ScaleXYFactor); //각도는 시계방향이 플러스 RTC6Wrap.n_arc_abs(m_deviceNo, nX, nY, angle * (-1)); } public override void JumpAbsZ(double z, eFunctionType type = eFunctionType.COMMAND) { CommandPosZ = z; int nZ = Convert.ToInt32(CommandPosZ * m_ScaleZFactor); if (type == eFunctionType.COMMAND) { RTC6Wrap.n_set_defocus(m_deviceNo, nZ); } else { RTC6Wrap.n_set_defocus_list(m_deviceNo, nZ); } } public override void JumpRelZ(double z, eFunctionType type = eFunctionType.COMMAND) { CommandPosZ += z; int nZ = Convert.ToInt32(CommandPosZ * m_ScaleZFactor); if (type == eFunctionType.COMMAND) { RTC6Wrap.n_set_defocus(m_deviceNo, nZ); } else { RTC6Wrap.n_set_defocus_list(m_deviceNo, nZ); } } public override void GetXYPos(out double x, out double y) { if (m_UseEncoderFeedbackMode == true) { RTC6Wrap.n_control_command(m_deviceNo, m_PrimaryHeadNo, 1, 0x501); int currXPos = RTC6Wrap.n_get_value(m_deviceNo, 1); //int currXPos = RTC6Wrap.n_get_value(m_deviceNo, 7); RTC6Wrap.n_control_command(m_deviceNo, m_PrimaryHeadNo, 2, 0x501); int currYPos = RTC6Wrap.n_get_value(m_deviceNo, 2); //int currYPos = RTC6Wrap.n_get_value(m_deviceNo, 8); // RTC보드의 각종 correction파일의 정보를 PC 메모리로 옮겨놓은 데이터로 변경함 uint error = RTC6Wrap.transform(out currXPos, out currYPos, m_coordinationTransformPtr, 0); x = currXPos / m_ScaleXYFactor; y = currYPos / m_ScaleXYFactor; } else { x = CommandPosX; y = CommandPosY; } } public override void GetZPos(out double z) { if (m_UseEncoderFeedbackMode == true) { RTC6Wrap.n_control_command(m_deviceNo, 2, 1, 0x501); int[] currZPos = new int[2]; currZPos[0] = RTC6Wrap.n_get_value(m_deviceNo, 4); currZPos[1] = 0;//Unuse Axis RTC6Wrap.transform(out currZPos[0], out currZPos[1], m_coordinationTransformPtr, 1); z = (currZPos[0] / 16) / m_ScaleZFactor;//get_value로 얻은 bit 값([–524288 … 524287]) 을 z축 bit 값([-32768...32767])로 변환하기 위해 16으로 나누어 줌 } else { z = CommandPosZ; } } public override void WriteDA(uint portNo, float value/*0~100%*/, eFunctionType type = eFunctionType.COMMAND) { uint targetValue = (uint)(value * 40.95); // 인수 범위는 0 ~ 4095 if (type == eFunctionType.COMMAND) { RTC6Wrap.n_write_da_x(m_deviceNo, portNo, targetValue); } else { RTC6Wrap.n_write_da_x_list(m_deviceNo, portNo, targetValue); } } public override void GetEncoder(out double encoderX, out double encoderY, bool rotateMode = false) { int valueX, valueY; RTC6Wrap.n_get_encoder(m_deviceNo, out valueX, out valueY); if (m_MarkingOnTheFlyEncoderResolutionX != 0) encoderX = (valueX / 1000f) * m_MarkingOnTheFlyEncoderResolutionX; // 단위는 count else encoderX = 0; if (m_MarkingOnTheFlyEncoderResolutionY != 0) encoderY = (valueY / 1000f) * m_MarkingOnTheFlyEncoderResolutionY; // 단위는 count else encoderY = 0; if (rotateMode) { if (m_MarkingOnTheFlyEncoderResolutionRotate != 0) { encoderX = (valueX * 360f) / m_MarkingOnTheFlyEncoderResolutionRotate; // 단위는 count encoderY = (valueY * 360f) / m_MarkingOnTheFlyEncoderResolutionRotate; } else { encoderX = 0; encoderY = 0; } } } public override uint GetMarkingInfo() { return RTC6Wrap.n_get_marking_info(m_deviceNo); } public override uint GetStartStopInfo() { return RTC6Wrap.n_get_startstop_info(m_deviceNo); } public override void StoreEncoder(uint pos) { RTC6Wrap.n_store_encoder(m_deviceNo, pos); } public override void ReadEncoder(out double encoder0_0, out double encoder1_0, out double encoder0_1, out double encoder1_1, bool rotateMode = false) { int buffEncoder0_0, buffEncoder1_0, buffEncoder0_1, buffEncoder1_1; RTC6Wrap.n_read_encoder(m_deviceNo, out buffEncoder0_0, out buffEncoder1_0, out buffEncoder0_1, out buffEncoder1_1); if (m_MarkingOnTheFlyEncoderResolutionX != 0) { encoder0_0 = (buffEncoder0_0 / 1000f) * m_MarkingOnTheFlyEncoderResolutionX; // 단위는 count encoder0_1 = (buffEncoder0_1 / 1000f) * m_MarkingOnTheFlyEncoderResolutionX; // 단위는 count } else { encoder0_0 = 0; encoder0_1 = 0; } if (m_MarkingOnTheFlyEncoderResolutionY != 0) { encoder1_0 = (buffEncoder1_0 / 1000f) * m_MarkingOnTheFlyEncoderResolutionX; // 단위는 count encoder1_1 = (buffEncoder1_1 / 1000f) * m_MarkingOnTheFlyEncoderResolutionX; // 단위는 count } else { encoder1_0 = 0; encoder1_1 = 0; } if (rotateMode) { encoder0_0 = (buffEncoder0_0 * 360f) / m_MarkingOnTheFlyEncoderResolutionRotate; encoder1_0 = (buffEncoder1_0 * 360f) / m_MarkingOnTheFlyEncoderResolutionRotate; encoder0_1 = (buffEncoder0_1 * 360f) / m_MarkingOnTheFlyEncoderResolutionRotate; encoder1_1 = (buffEncoder1_1 * 360f) / m_MarkingOnTheFlyEncoderResolutionRotate; } } public override void WaitForEncoderX(double position) { if (m_MarkingOnTheFlyEncoderResolutionX == 0) { throw new DivideByZeroException("Encoder resolution value is 0"); } int value = Convert.ToInt32((position * 1000) / m_MarkingOnTheFlyEncoderResolutionX); // 단위는 count RTC6Wrap.n_wait_for_encoder(m_deviceNo, value, 0); } public override void WaitForEncoderY(double position) { if (m_MarkingOnTheFlyEncoderResolutionY == 0) { throw new DivideByZeroException("Encoder resolution value is 0"); } int value = Convert.ToInt32((position * 1000) / m_MarkingOnTheFlyEncoderResolutionY); // 단위는 count RTC6Wrap.n_wait_for_encoder(m_deviceNo, value, 1); } public override void WaitForEncoderRotateX(double angle) { if (m_MarkingOnTheFlyEncoderResolutionRotate == 0) { throw new DivideByZeroException("Encoder resolution value is 0"); } int value = Convert.ToInt32((angle) / 360 * m_MarkingOnTheFlyEncoderResolutionRotate); // 단위는 count RTC6Wrap.n_wait_for_encoder(m_deviceNo, value, 0); } public override void WaitForEncoderRotateY(double angle) { if (m_MarkingOnTheFlyEncoderResolutionRotate == 0) { throw new DivideByZeroException("Encoder resolution value is 0"); } int value = Convert.ToInt32((angle) / 360 * m_MarkingOnTheFlyEncoderResolutionRotate); // 단위는 count RTC6Wrap.n_wait_for_encoder(m_deviceNo, value, 1); } public override void WaitForEncoderRotateXMode(double angle, eEncoderWaitThroughMode mode) { if (m_MarkingOnTheFlyEncoderResolutionRotate == 0) { throw new DivideByZeroException("Encoder resolution value is 0"); } int value = Convert.ToInt32((angle) / 360 * m_MarkingOnTheFlyEncoderResolutionRotate); // 단위는 count RTC6Wrap.n_wait_for_encoder_mode(m_deviceNo, value, 0, (int)mode); } public override void WaitForEncoderRotateYMode(double angle, eEncoderWaitThroughMode mode) { if (m_MarkingOnTheFlyEncoderResolutionRotate == 0) { throw new DivideByZeroException("Encoder resolution value is 0"); } int value = Convert.ToInt32((angle) / 360 * m_MarkingOnTheFlyEncoderResolutionRotate); // 단위는 count RTC6Wrap.n_wait_for_encoder_mode(m_deviceNo, value, 1, (int)mode); } public override void WaitForEncoderXMode(double position, eEncoderWaitThroughMode mode) { double resolution = 0; resolution = m_MarkingOnTheFlyEncoderResolutionX; if (resolution == 0) { throw new DivideByZeroException("Encoder resolution value is 0"); } int value = Convert.ToInt32((position * 1000) / resolution); // 단위는 count RTC6Wrap.n_wait_for_encoder_mode(m_deviceNo, value, 0, (int)mode); } public override void WaitForEncoderYMode(double position, eEncoderWaitThroughMode mode) { double resolution = 0; resolution = m_MarkingOnTheFlyEncoderResolutionY; if (resolution == 0) { throw new DivideByZeroException("Encoder resolution value is 0"); } int value = Convert.ToInt32((position * 1000) / resolution); // 단위는 count RTC6Wrap.n_wait_for_encoder_mode(m_deviceNo, value, 1, (int)mode); } public override void WaitForEncoderMode(double position, uint encoderNo, eEncoderWaitThroughMode mode) { double resolution = 0; if (encoderNo == 0) { resolution = m_MarkingOnTheFlyEncoderResolutionX; } else if (encoderNo == 1) { resolution = m_MarkingOnTheFlyEncoderResolutionY; } else { throw new Exception("Encoder Number is incorrect"); } if (resolution == 0) { throw new DivideByZeroException("Encoder resolution value is 0"); } int value = Convert.ToInt32((position * 1000) / resolution); // 단위는 count RTC6Wrap.n_wait_for_encoder_mode(m_deviceNo, value, encoderNo, (int)mode); } public override void WaitForEncoderRange(double minX, double maxX, double minY, double maxY) { int valueMinX = Convert.ToInt32((minX * 1000) / m_MarkingOnTheFlyEncoderResolutionX); // 단위는 count int valueMaxX = Convert.ToInt32((maxX * 1000) / m_MarkingOnTheFlyEncoderResolutionX); // 단위는 count int valueMinY = Convert.ToInt32((minY * 1000) / m_MarkingOnTheFlyEncoderResolutionY); // 단위는 count int valueMaxY = Convert.ToInt32((maxY * 1000) / m_MarkingOnTheFlyEncoderResolutionY); // 단위는 count valueMinX = CutValue(valueMinX, (-1) * (int)Math.Pow(2, 31), (int)Math.Pow(2, 31) - 1); valueMaxX = CutValue(valueMaxX, (-1) * (int)Math.Pow(2, 31), (int)Math.Pow(2, 31) - 1); valueMinY = CutValue(valueMinY, (-1) * (int)Math.Pow(2, 31), (int)Math.Pow(2, 31) - 1); valueMaxY = CutValue(valueMaxY, (-1) * (int)Math.Pow(2, 31), (int)Math.Pow(2, 31) - 1); RTC6Wrap.n_wait_for_encoder_in_range(m_deviceNo, valueMinX, valueMaxX, valueMinY, valueMaxY); } public override void WaitForEncoderRotateRange(double minX, double maxX, double minY, double maxY) { int valueMinX = Convert.ToInt32((minX) / 360 * m_MarkingOnTheFlyEncoderResolutionRotate); // 단위는 count int valueMaxX = Convert.ToInt32((maxX) / 360 * m_MarkingOnTheFlyEncoderResolutionRotate); // 단위는 count int valueMinY = Convert.ToInt32((minY) / 360 * m_MarkingOnTheFlyEncoderResolutionRotate); // 단위는 count int valueMaxY = Convert.ToInt32((maxY) / 360 * m_MarkingOnTheFlyEncoderResolutionRotate); // 단위는 count valueMinX = CutValue(valueMinX, (-1) * (int)Math.Pow(2, 31), (int)Math.Pow(2, 31) - 1); valueMaxX = CutValue(valueMaxX, (-1) * (int)Math.Pow(2, 31), (int)Math.Pow(2, 31) - 1); valueMinY = CutValue(valueMinY, (-1) * (int)Math.Pow(2, 31), (int)Math.Pow(2, 31) - 1); valueMaxY = CutValue(valueMaxY, (-1) * (int)Math.Pow(2, 31), (int)Math.Pow(2, 31) - 1); RTC6Wrap.n_wait_for_encoder_in_range(m_deviceNo, valueMinX, valueMaxX, valueMinY, valueMaxY);// valueMin, valueMax); } public override void SetFlyX(double encoderResolution) { double scale = encoderResolution * m_ScaleXYFactor / 1000; // 단위는 bits/count if (scale != 0) { if (Math.Abs(scale) < 1.0 / 256.0 || 16000 < Math.Abs(scale)) { throw new ArgumentOutOfRangeException("encoderResolution"); } } RTC6Wrap.n_set_fly_x(m_deviceNo, scale); } public override void SetFlyX(double encoderResolution, double diameter) { double diskmotorlength = 3.14159265358979 * diameter; double scale = (diskmotorlength / encoderResolution) * m_ScaleXYFactor; // ≈ 3.24705 bits/count if (scale != 0) { if (Math.Abs(scale) < 1.0 / 256.0 || 16000 < Math.Abs(scale)) { throw new ArgumentOutOfRangeException("encoderResolution"); } } RTC5Wrap.n_set_fly_x(m_deviceNo, scale); } public override void SetFlyY(double encoderResolution) { double scale = encoderResolution * m_ScaleXYFactor / 1000; // 단위는 bits/count if (scale != 0) { if (Math.Abs(scale) < 1.0 / 256.0 || 16000 < Math.Abs(scale)) { throw new ArgumentOutOfRangeException("encoderResolution"); } } RTC6Wrap.n_set_fly_y(m_deviceNo, scale); } public override void SetRotateCenter(double posX, double posY, eFunctionType type = eFunctionType.COMMAND) { int bitX = Convert.ToInt32(posX * m_ScaleXYFactor); // 단위는 count int bitY = Convert.ToInt32(posY * m_ScaleXYFactor); // 단위는 count if (type == eFunctionType.COMMAND) { RTC6Wrap.n_set_rot_center(m_deviceNo, bitX, bitY); } else { RTC6Wrap.n_set_rot_center_list(m_deviceNo, bitX, bitY); } } public override void SetFlyRotate(double encoderResolution) { double scale = encoderResolution; // 단위는 count RTC6Wrap.n_set_fly_rot(m_deviceNo, scale); } public override void SetFlyRotatePos(double encoderResolution) { double scale = encoderResolution; // 단위는 bits/count RTC6Wrap.n_set_fly_rot_pos(m_deviceNo, scale); } public override void ActivateFlyXY(double encoderResolutionX, double encoderResolutionY) { double scaleX = encoderResolutionX * m_ScaleXYFactor / 1000; // 단위는 bits/count double scaleY = encoderResolutionY * m_ScaleXYFactor / 1000; // 단위는 bits/count if (scaleX != 0) { if (Math.Abs(scaleX) < 1.0 / 256.0 || 16000 < Math.Abs(scaleX)) { throw new ArgumentOutOfRangeException("encoderResolution"); } } if (scaleY != 0) { if (Math.Abs(scaleY) < 1.0 / 256.0 || 16000 < Math.Abs(scaleY)) { throw new ArgumentOutOfRangeException("encoderResolution"); } } RTC6Wrap.n_activate_fly_xy(m_deviceNo, scaleX, scaleY); } public override void ActivateFly1Axis(int axis, int mode, double scale, int offset) { } public override void Fly_Return(double x, double y) { CommandPosX = x; CommandPosY = y; int nX = Convert.ToInt32(CommandPosX * m_ScaleXYFactor); int nY = Convert.ToInt32(CommandPosY * m_ScaleXYFactor); RTC6Wrap.n_fly_return(m_deviceNo, nX, nY); } public override void ParkPosition(double posX, double posY, eParkType type = eParkType.VirtualImage) { int nX = Convert.ToInt32(posX * m_ScaleXYFactor); int nY = Convert.ToInt32(posY * m_ScaleXYFactor); RTC6Wrap.n_park_position(m_deviceNo, (uint)type, nX, nY); } public override void ParkReturn(double posX, double posY, eParkType type = eParkType.VirtualImage) { int nX = Convert.ToInt32(posX * m_ScaleXYFactor); int nY = Convert.ToInt32(posY * m_ScaleXYFactor); RTC6Wrap.n_park_return(m_deviceNo, (uint)type, nX, nY); } public override void InitFly2D(int offsetX = 0, int offsetY = 0) { //임시 선언 uint no = 0; RTC6Wrap.n_init_fly_2d(m_deviceNo, offsetX, offsetY, no); } public override void SimulateEncoder(uint EncoderNo) { RTC6Wrap.n_simulate_encoder(m_deviceNo, EncoderNo); } public override void SetControlMode(uint mode) { RTC6Wrap.n_set_control_mode(m_deviceNo, mode); } public override void SetLaesrDelay(int laserOnDelay, uint laserOffDelay) { const double delayScale = 64; //1bit당 1/64us RTC6Wrap.n_set_laser_delays(m_deviceNo, Convert.ToInt32(laserOnDelay * delayScale), Convert.ToUInt32(laserOffDelay * delayScale)); } public override void SetScannerDelay(uint jumpDelay, uint markDelay, uint arcDelay) { const double delayScale = 10;//1bit당 10us RTC6Wrap.n_set_scanner_delays(m_deviceNo, Convert.ToUInt32(jumpDelay / delayScale), Convert.ToUInt32(markDelay / delayScale), Convert.ToUInt32(arcDelay / delayScale)); } public override void SetJumpSpeedCtrl(double speed) { double targetSpeed = (speed * m_ScaleXYFactor) / 1000; RTC6Wrap.n_set_jump_speed_ctrl(m_deviceNo, targetSpeed); } public override void SetJumpSpeed(double speed) { double targetSpeed = (speed * m_ScaleXYFactor) / 1000; RTC6Wrap.n_set_jump_speed(m_deviceNo, targetSpeed); } public override void SetMarkSpeed(double speed) { double targetSpeed = (speed * m_ScaleXYFactor) / 1000; RTC6Wrap.n_set_mark_speed(m_deviceNo, targetSpeed); } public override void SetStartList(eListNo no) { RTC6Wrap.n_set_start_list(m_deviceNo, Convert.ToUInt32(no)); } public override uint LoadList(eListNo no) { return RTC6Wrap.n_load_list(m_deviceNo, Convert.ToUInt32(no), 0); } public override void SetEndList() { RTC6Wrap.n_set_end_of_list(m_deviceNo); } public override void ExecuteList(eListNo no) { RTC6Wrap.n_execute_list(m_deviceNo, Convert.ToUInt32(no)); } public override void StartLoop() { RTC6Wrap.n_start_loop(m_deviceNo); } public override void QuitLoop() { RTC6Wrap.n_quit_loop(m_deviceNo); } public override void AutoChange() { RTC6Wrap.n_auto_change(m_deviceNo); } public override bool GetBusyStatus() { uint status; uint position; RTC6Wrap.n_get_status(m_deviceNo, out status, out position); //return (status != 0); if (status != 0) { return true; } else { return false; } } public override void StopExecution() { RTC6Wrap.n_stop_execution(m_deviceNo); } public override uint GetRTCVersion() { return RTC6Wrap.n_get_rtc_version(m_deviceNo); } public override uint GetDLLVersion() { return RTC6Wrap.get_dll_version(); } public override void SetLaserTiming(uint periodHz, uint laser1PulseWidthUs, uint laser2PulseWidthUs) //단위는 Khz, us임 { //uint halfPeriodBit = (32 / periodkHz) * 1000; //KHz를 halfPeriod bit로 변경함 uint halfPeriodBit = (uint)((32.0 / (double)periodHz) * 1000000.0); //KHz를 halfPeriod bit로 변경함 uint laser1PulseWidthBit = laser1PulseWidthUs * 64; uint laser2PulseWidthBit = laser2PulseWidthUs * 64; RTC6Wrap.n_set_laser_timing(m_deviceNo , halfPeriodBit , laser1PulseWidthBit , laser2PulseWidthBit , 1); } public override void SetStandby(uint periodHz, uint laserPulseWidthUs) //단위는 Khz, us임 { //uint halfPeriodBit = (32 / periodkHz) * 1000; //KHz를 halfPeriod bit로 변경함 uint halfPeriodBit = (uint)((32.0 / (double)periodHz) * 1000000.0); //KHz를 halfPeriod bit로 변경함 uint laserPulseWidthBit = laserPulseWidthUs * 64; RTC6Wrap.n_set_standby(m_deviceNo, halfPeriodBit, laserPulseWidthBit); } public override void SetLaserMode(eLaserMode mode) { RTC6Wrap.n_set_laser_mode(m_deviceNo, (uint)mode); } public override void SetLaserControl(uint ctrl) { RTC6Wrap.n_set_laser_control(m_deviceNo, ctrl); } public override void SetFirstPulseKiller(uint width) //단위는 us->bit 로 변경해야 함 { uint FirstPulseKillerBit = width * 64; RTC6Wrap.n_set_firstpulse_killer(m_deviceNo, FirstPulseKillerBit); } public override void LaserSignalOn() { RTC6Wrap.n_laser_signal_on(m_deviceNo); } public override void LaserSignalOff() { RTC6Wrap.n_laser_signal_off(m_deviceNo); } /// /// 지정한 시간 시간만큼 Laser Active 신호를 켜주는 리스트 함수 /// /// 시간[ms] public override void LaserOnList(double interval) { uint intervalInBits = (uint)(interval * 100); // 1[bit] = 10[us] RTC6Wrap.n_laser_on_list(m_deviceNo, intervalInBits); } /// /// Laser Active가 Off된 상태에서 지정한 시간 시간만큼 delay를 추가하는 함수 /// /// 시간[ms] public override void LongDelay(uint delay) { uint delayInBits = delay * 100; // 1[bit] = 10[us] RTC6Wrap.n_long_delay(m_deviceNo, delayInBits); } public override void SetAngle(double angle/*degree*/, uint atOnce, eFunctionType type = eFunctionType.COMMAND) { if (type == eFunctionType.COMMAND) { RTC6Wrap.n_set_angle(m_deviceNo, m_PrimaryHeadNo, angle, atOnce); } else { RTC6Wrap.n_set_angle_list(m_deviceNo, m_PrimaryHeadNo, angle, atOnce); } } public override void SetOffset(double offsetX, double offsetY, uint atOnce, eFunctionType type = eFunctionType.COMMAND) { int nX = Convert.ToInt32(offsetX * m_ScaleXYFactor); int nY = Convert.ToInt32(offsetY * m_ScaleXYFactor); if (type == eFunctionType.COMMAND) { RTC6Wrap.n_set_offset(m_deviceNo, m_PrimaryHeadNo, nX, nY, atOnce); } else { RTC6Wrap.n_set_offset_list(m_deviceNo, m_PrimaryHeadNo, nX, nY, atOnce); } } public override void DisableLaser() { RTC6Wrap.n_disable_laser(m_deviceNo); } public override void EnableLaser() { RTC6Wrap.n_enable_laser(m_deviceNo); } public override void ParaLaserOnPulsesList(double period, uint pulses, float powerValue) { uint periodbit = 0; if (period >= 0) { periodbit = (uint)(period * 100); } uint pulsesbit = (uint)pulses; uint targetValue = (uint)(powerValue * 40.95); // 인수 범위는 0 ~ 4095 RTC6Wrap.n_para_laser_on_pulses_list(m_deviceNo, periodbit, pulsesbit, targetValue); } //Ramping 기능 public override void ParaMarkAbs(double x, double y, float power) { CommandPosX = x; CommandPosY = y; int nX = Convert.ToInt32(CommandPosX * m_ScaleXYFactor); int nY = Convert.ToInt32(CommandPosY * m_ScaleXYFactor); uint targetValue = (uint)(power * 40.95); // 인수 범위는 0 ~ 4095 RTC6Wrap.n_para_mark_abs(m_deviceNo, nX, nY, targetValue); } public override void ParaMarkRel(double x, double y, float power) { CommandPosX += x; CommandPosY += y; int nX = Convert.ToInt32(x * m_ScaleXYFactor); int nY = Convert.ToInt32(y * m_ScaleXYFactor); uint targetValue = (uint)(power * 40.95); // 인수 범위는 0 ~ 4095 RTC6Wrap.n_para_mark_rel(m_deviceNo, nX, nY, targetValue); } public override void ParaJumpAbs(double x, double y, float power) { CommandPosX = x; CommandPosY = y; int nX = Convert.ToInt32(CommandPosX * m_ScaleXYFactor); int nY = Convert.ToInt32(CommandPosY * m_ScaleXYFactor); uint targetValue = (uint)(power * 40.95); // 인수 범위는 0 ~ 4095 RTC6Wrap.n_para_jump_abs(m_deviceNo, nX, nY, targetValue); } public override void ParaJumpRel(double x, double y, float power) { CommandPosX += x; CommandPosY += y; int nX = Convert.ToInt32(x * m_ScaleXYFactor); int nY = Convert.ToInt32(y * m_ScaleXYFactor); uint targetValue = (uint)(power * 40.95); // 인수 범위는 0 ~ 4095 RTC6Wrap.n_para_jump_rel(m_deviceNo, nX, nY, targetValue); } public override void SetVectorControl(uint portNo, uint value) { RTC6Wrap.n_set_vector_control(m_deviceNo, portNo, value); } //측정 기능 public override void StopTrigger() { RTC6Wrap.n_stop_trigger(m_deviceNo); } public override void SetTrigger(uint period/*㎲*/, eRecordSignal signal1, eRecordSignal signal2, eRecordSignal signal3, eRecordSignal signal4) { uint targetPeriod = period / 10;//1bit = 10㎲ RTC6Wrap.n_set_trigger4(m_deviceNo, targetPeriod, (uint)signal1, (uint)signal2, (uint)signal3, (uint)signal4); } public override void SetTrigger(uint period/*㎲*/, eRecordSignal signal1, eRecordSignal signal2) { uint targetPeriod = period / 10;//1bit = 10㎲ RTC6Wrap.n_set_trigger(m_deviceNo, targetPeriod, (uint)signal1, (uint)signal2); } public override void Measurement_status(out uint busy, out uint pos) { RTC6Wrap.n_measurement_status(m_deviceNo, out busy, out pos); } public override uint ReadStatus() { return RTC6Wrap.n_read_status(m_deviceNo); } public override void GetWaveForm(uint channel, uint number, out int[] data) { data = new int[number]; for (int i = 0; i < m_getWaveformPtr.Length; i++) { m_getWaveformPtr[i] = 0; } RTC6Wrap.n_get_waveform(m_deviceNo, channel, number, m_getWaveformPtr); for (int i = 0; i < data.Length; i++) { data[i] = m_getWaveformPtr[i]; } } //안오산-170224-Wobbel모드 추가(V1.7.0) //set_wobbel_mode public override void SetWobbelMode(bool wobbelEnable, double transversal, double longitudinal, double frequency, int shape) { //wobbel 모드 사용 안할 경우 Frequency 0 if (!wobbelEnable) { frequency = 0; } //Amplitude 설정(Transversal, Longitudinal uint nTrans = Convert.ToUInt32(transversal * m_ScaleXYFactor); uint nLong = Convert.ToUInt32(longitudinal * m_ScaleXYFactor); int mode = (int)shape; RTC6Wrap.n_set_wobbel_mode(m_deviceNo, nTrans, nLong, frequency, mode); } public override void SetWobbelDirection(int dX, int dY) { RTC6Wrap.n_set_wobbel_direction(m_deviceNo, dX, dY); } public override void SetWobbelVector(double tansversal, double longitudinal, uint period, float power) { RTC6Wrap.n_set_wobbel_vector(m_deviceNo, tansversal, longitudinal, period, power); } public override void ConfigLaserSignal(eLaserSignal pin2, eLaserSignal pin1, eLaserSignal pin9) { uint iPin2 = (uint)pin2; uint iPin1 = (uint)pin1; uint iPin9 = (uint)pin9; uint config = iPin9 << 4 | iPin1 << 2 | iPin2; RTC6Wrap.n_config_laser_signals(m_deviceNo, config); } public override void SelectCorrectionTable(int no) { RTC6Wrap.n_select_cor_table(m_deviceNo, (uint)no, 0); } public override void SetEthernetConfigLinkLoss(eEthConfigLinkLossMode mode) { } public override int CheckEthernetConnection(out uint errorCode) { errorCode = 0; return 0; } #region 리스트 실행 시간 측정 /// /// Delayed Short List Command /// Stores the current value of the RTC6 timer and resets it to zero. /// public override void SaveAndRestartTimer() { RTC6Wrap.save_and_restart_timer(); } /// /// Ctrl Command /// Returns the RTC5 timer value (without resetting it to zero). It has been stored during the most recent call of save_and_restart_timer. /// /// RTC5 timer value in seconds. As a 64-bit IEEE floating point value. public override double GetTime() { return RTC6Wrap.get_time(); } #endregion // 기존 추상함수 아닌 3개 항목 추상함수로 추가 //ExecuteUpdateParameterList는 Initialize에 직접구현할수밖에.. config의 항목 쓰려면.. public override uint LoadProgramFile(string fileName) { return RTC6Wrap.n_load_program_file(m_deviceNo, fileName); } public override uint LoadCorrectionFile(string fileName, uint correctionNo, bool use3DMode) { uint dimm = (use3DMode) ? 3U : 2U; return RTC6Wrap.n_load_correction_file(m_deviceNo, fileName, correctionNo, dimm); } public static int CutValue(int value, int min, int max) { if (value > max) { return max; } else if (value < min) { return min; } else { return value; } } public override void SetLaserPinOutList(uint pins) { RTC6Wrap.set_laser_pin_out_list(pins); } public override void SetPortDefault(uint port, uint value) { RTC5Wrap.set_port_default(port, value); } public override void SetLaserPinOut(uint pins) { RTC6Wrap.set_laser_pin_out(pins); } public override uint GetLastError() { return RTC6Wrap.get_last_error(); } public override uint GetListSpace() { return RTC6Wrap.get_list_space(); } public override void SetConfigList(uint mem1, uint mem2) { RTC6Wrap.config_list(mem1, mem2); } public override void GetListPointer(out eListNo list_no, out uint list_pos) { list_no = eListNo.NONE; uint listNo = 0, listPos = 0; RTC6Wrap.get_list_pointer(out listNo, out listPos); list_no = (eListNo)listNo; list_pos = listPos; } } }