1127 lines
44 KiB
C#
Raw 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;
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);
}
/// <summary>
/// 지정한 시간 시간만큼 Laser Active 신호를 켜주는 리스트 함수
/// </summary>
/// <param name="interval">시간[ms]</param>
public override void LaserOnList(double interval)
{
uint intervalInBits = (uint)(interval * 100); // 1[bit] = 10[us]
RTC6Wrap.n_laser_on_list(m_deviceNo, intervalInBits);
}
/// <summary>
/// Laser Active가 Off된 상태에서 지정한 시간 시간만큼 delay를 추가하는 함수
/// </summary>
/// <param name="delay">시간[ms]</param>
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 리스트 실행 시간 측정
/// <summary>
/// Delayed Short List Command
/// Stores the current value of the RTC6 timer and resets it to zero.
/// </summary>
public override void SaveAndRestartTimer()
{
RTC6Wrap.save_and_restart_timer();
}
/// <summary>
/// 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.
/// </summary>
/// <returns>RTC5 timer value in seconds. As a 64-bit IEEE floating point value.</returns>
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;
}
}
}