using SA_LTT.Base;
|
using SA_LTT.Module.RTC5;
|
using System;
|
using System.Collections.Generic;
|
using System.IO;
|
|
namespace SA_LTT.Module
|
{
|
public enum ScanMode
|
{
|
JUMP,
|
MARK,
|
}
|
|
/// <summary>
|
/// Scanner 가공 좌표.
|
/// </summary>
|
public struct Coord
|
{
|
ScanMode _scanMode;
|
int _x;
|
int _y;
|
|
public ScanMode ScanMode
|
{
|
get
|
{
|
return _scanMode;
|
}
|
|
set
|
{
|
_scanMode = value;
|
}
|
}
|
|
/// <summary>
|
/// -8388608 ~ 8388607
|
/// </summary>
|
public int X
|
{
|
get
|
{
|
return _x;
|
}
|
|
set
|
{
|
if (value > 8388607)
|
{
|
_x = 8388607;
|
}
|
else if (value < -8388608)
|
{
|
_x = -8388608;
|
}
|
else
|
{
|
_x = value;
|
}
|
}
|
}
|
|
/// <summary>
|
/// -8388608 ~ 8388607
|
/// </summary>
|
public int Y
|
{
|
get
|
{
|
return _y;
|
}
|
|
set
|
{
|
if (value > 8388607)
|
{
|
_y = 8388607;
|
}
|
else if (value < -8388608)
|
{
|
_y = -8388608;
|
}
|
else
|
{
|
_y = value;
|
}
|
}
|
}
|
|
public Coord(ScanMode scanMode, int x, int y)
|
{
|
_scanMode = ScanMode.JUMP;
|
_x = 0;
|
_y = 0;
|
|
ScanMode = scanMode;
|
X = x;
|
Y = y;
|
}
|
}
|
|
public delegate void ScanListAdded(Coord coord);
|
public delegate void ScanListCleared();
|
|
public class Scanner : XmlManager<Scanner>
|
{
|
private Equipment _equipment;
|
|
private object _lock = new object();
|
|
public event ScanListAdded ScanListAdded;
|
public event ScanListCleared ScanListCleared;
|
|
readonly string _fileName = "Scanner.xml";
|
readonly string _filePath = @"Setting\";
|
|
#region Field
|
private string _correctionFilePath;
|
|
private bool _isInitialized;
|
private bool _isBusy;
|
private uint _isPosition;
|
|
private int _encoder0;
|
private int _encoder1;
|
|
private int _encoderCountPerMmX;
|
private int _encoderCountPerMmY;
|
|
private double _fieldOfView;
|
|
private uint _halfPeriod;
|
private uint _pulseLength1;
|
private uint _timeBase;
|
|
private uint _jumpDelay;
|
private uint _markDelay;
|
private uint _polygonDelay;
|
|
private int _laserOnDelay;
|
private uint _laserOffDelay;
|
|
private double _xGain;
|
private double _yGain;
|
|
private bool _isLaserOn;
|
private List<Coord> scanList = new List<Coord>();
|
#endregion
|
|
#region Property
|
//보정 파일 위치
|
public string CorrectionFilePath
|
{
|
get
|
{
|
return _correctionFilePath;
|
}
|
|
set
|
{
|
_correctionFilePath = value;
|
}
|
}
|
|
/// <summary>
|
/// RTC5 Board 마지막 초기화 결과
|
/// </summary>
|
public bool IsInitialized
|
{
|
get
|
{
|
return _isInitialized;
|
}
|
|
set
|
{
|
_isInitialized = value;
|
}
|
}
|
|
/// <summary>
|
/// RTC5 Board Status.
|
/// </summary>
|
public bool IsBusy
|
{
|
get
|
{
|
return _isBusy;
|
}
|
|
set
|
{
|
_isBusy = value;
|
}
|
}
|
|
/// <summary>
|
/// Scanner에 연결된 Encoder 0 값
|
/// </summary>
|
public int Encoder0
|
{
|
get
|
{
|
return _encoder0;
|
}
|
|
set
|
{
|
_encoder0 = value;
|
}
|
}
|
|
/// <summary>
|
/// Scanner에 연결된 Encoder 1 값
|
/// </summary>
|
public int Encoder1
|
{
|
get
|
{
|
return _encoder1;
|
}
|
|
set
|
{
|
_encoder1 = value;
|
}
|
}
|
|
/// <summary>
|
/// X축 mm당 Encoder Count
|
/// </summary>
|
public int EncoderCountPerMmX
|
{
|
get
|
{
|
return _encoderCountPerMmX;
|
}
|
|
set
|
{
|
_encoderCountPerMmX = value;
|
}
|
}
|
|
/// <summary>
|
/// Y축 mm당 Encoder Count
|
/// </summary>
|
public int EncoderCountPerMmY
|
{
|
get
|
{
|
return _encoderCountPerMmY;
|
}
|
|
set
|
{
|
_encoderCountPerMmY = value;
|
}
|
}
|
|
/// <summary>
|
/// 1mm당 bits 수.
|
/// </summary>
|
public double BitsPerMm
|
{
|
get
|
{
|
if (FOV == 0)
|
{
|
return 0;
|
}
|
else
|
{
|
return Math.Pow(2, 20 - 1) / (FOV / 2);
|
}
|
}
|
}
|
|
/// <summary>
|
/// Scanner의 field of view
|
/// </summary>
|
public double FOV
|
{
|
get
|
{
|
return _fieldOfView;
|
}
|
|
set
|
{
|
_fieldOfView = value;
|
}
|
}
|
|
/// <summary>
|
/// Scanner Kfactor : FOV에 따라 정해짐
|
/// </summary>
|
public double KFactor
|
{
|
get
|
{
|
if (FOV == 0)
|
{
|
return 1.0;
|
}
|
else
|
{
|
return Math.Pow(2, 20) / (FOV / 2);
|
}
|
}
|
}
|
|
/// <summary>
|
/// Half of the laser signal period
|
/// 1bit equals 1/64 us. Allowed range [0 ~ 2^(32 -1)]
|
/// </summary>
|
public uint HalfPeriod
|
{
|
get
|
{
|
return _halfPeriod;
|
}
|
|
set
|
{
|
if (value > 2147483648)
|
{
|
_halfPeriod = 2147483648;
|
}
|
else
|
{
|
_halfPeriod = value;
|
}
|
}
|
}
|
|
/// <summary>
|
/// Pulse widths of signals Laser1
|
/// 1bit equals 1/64 us. Allowed range [0 ~ 2^(32 -1)]
|
/// </summary>
|
public uint PulseLength1
|
{
|
get
|
{
|
return _pulseLength1;
|
}
|
|
set
|
{
|
if (value > 2147483648)
|
{
|
_pulseLength1 = 2147483648;
|
}
|
else
|
{
|
_pulseLength1 = value;
|
}
|
}
|
}
|
|
/// <summary>
|
/// Pulse widths of signals Laser2
|
/// The value of PulseLength2 is ignored and is no longer used
|
/// </summary>
|
public uint PulseLength2
|
{
|
get
|
{
|
return _pulseLength1;
|
}
|
}
|
|
/// <summary>
|
/// time base; 0 corresponds to 1 microsecond
|
/// In RTC5 mode, the value is ignored and the clock frequency is fixed
|
/// at 64 MHz. 1 bit equals 1/64 µs
|
/// </summary>
|
public uint TimeBase
|
{
|
get
|
{
|
return _timeBase;
|
}
|
|
set
|
{
|
_timeBase = value;
|
}
|
}
|
|
/// <summary>
|
/// Jump delay in 10 microseconds
|
/// </summary>
|
public uint JumpDelay
|
{
|
get
|
{
|
return _jumpDelay;
|
}
|
|
set
|
{
|
_jumpDelay = value;
|
}
|
}
|
|
/// <summary>
|
/// Mark delay in 10 microseconds
|
/// </summary>
|
public uint MarkDelay
|
{
|
get
|
{
|
return _markDelay;
|
}
|
|
set
|
{
|
_markDelay = value;
|
}
|
}
|
|
/// <summary>
|
/// Polygon delay in 10 microseconds
|
/// </summary>
|
public uint PolygonDelay
|
{
|
get
|
{
|
return _polygonDelay;
|
}
|
|
set
|
{
|
_polygonDelay = value;
|
}
|
}
|
|
/// <summary>
|
/// Laser on delay in microseconds
|
/// </summary>
|
public int LaserOnDelay
|
{
|
get
|
{
|
return _laserOnDelay;
|
}
|
|
set
|
{
|
_laserOnDelay = value;
|
}
|
}
|
|
/// <summary>
|
/// Laser off delay in microseconds
|
/// </summary>
|
public uint LaserOffDelay
|
{
|
get
|
{
|
return _laserOffDelay;
|
}
|
|
set
|
{
|
_laserOffDelay = value;
|
}
|
}
|
|
public uint IsPosition
|
{
|
get
|
{
|
return _isPosition;
|
}
|
|
set
|
{
|
_isPosition = value;
|
}
|
}
|
|
public double XGain
|
{
|
get
|
{
|
return _xGain;
|
}
|
|
set
|
{
|
if (value < 0)
|
_xGain = 1;
|
|
_xGain = value;
|
}
|
}
|
|
public double YGain
|
{
|
get
|
{
|
return _yGain;
|
}
|
|
set
|
{
|
if (value < 0)
|
_yGain = 1;
|
|
_yGain = value;
|
}
|
}
|
|
public bool IsLaserOn
|
{
|
get
|
{
|
return _isLaserOn;
|
}
|
|
set
|
{
|
_isLaserOn = value;
|
}
|
}
|
#endregion
|
|
public Scanner(Equipment equipment)
|
{
|
_equipment = equipment;
|
TimeBase = 0;
|
Refresh();
|
}
|
|
public Scanner()
|
{
|
|
}
|
|
public void Refresh()
|
{
|
DirectoryInfo directoryInfo = new DirectoryInfo(Equipment.settingFilePath + _filePath);
|
|
if (directoryInfo.Exists == false)
|
{
|
directoryInfo.Create();
|
}
|
|
FileInfo fileInfo = new FileInfo(directoryInfo.FullName + _fileName);
|
|
if (fileInfo.Exists == false)
|
{
|
fileInfo.Create().Close();
|
|
SaveFile(fileInfo.FullName, this);
|
}
|
else
|
{
|
Scanner scanner = new Scanner();
|
|
scanner = ReadFile(fileInfo.FullName);
|
|
Copy(scanner);
|
}
|
}
|
|
/// <summary>
|
/// Error 발생했는지 확인.
|
/// </summary>
|
/// <returns></returns>
|
private bool ErrorExist()
|
{
|
uint errorCode = RTC5Wrap.get_error();
|
|
if (errorCode == 0) return false;
|
|
byte[] errorBytes = BitConverter.GetBytes(errorCode);
|
System.Collections.BitArray errorBits = new System.Collections.BitArray(errorBytes);
|
|
string str = string.Empty;
|
|
if (errorBits[0] == true)
|
_equipment.alarmManager.Occur(AlarmCode.AL_0800_RTC5_NO_BOARD_FOUND);
|
|
if (errorBits[1] == true)
|
_equipment.alarmManager.Occur(AlarmCode.AL_0801_RTC5_ACCESS_DENIED);
|
|
if (errorBits[2] == true)
|
_equipment.alarmManager.Occur(AlarmCode.AL_0802_RTC5_COMMAND_NOT_FORWARDED);
|
|
if (errorBits[3] == true)
|
_equipment.alarmManager.Occur(AlarmCode.AL_0803_RTC5_NO_RESPONSE_FROM_BOARD);
|
|
if (errorBits[4] == true)
|
_equipment.alarmManager.Occur(AlarmCode.AL_0804_RTC5_INVALID_PARAMETER);
|
|
if (errorBits[5] == true)
|
_equipment.alarmManager.Occur(AlarmCode.AL_0805_RTC5_LIST_PROCESSING_IS_NOT_ACTIVE);
|
|
if (errorBits[6] == true)
|
_equipment.alarmManager.Occur(AlarmCode.AL_0806_RTC5_LIST_COMMAND_REJECTED);
|
|
if (errorBits[7] == true)
|
_equipment.alarmManager.Occur(AlarmCode.AL_0807_RTC5_LIST_COMMAND_HAS_BEEN_COVERTED);
|
|
if (errorBits[8] == true)
|
_equipment.alarmManager.Occur(AlarmCode.AL_0808_RTC5_VERSION_ERROR_RTC5_DLL_VERSION);
|
|
if (errorBits[9] == true)
|
_equipment.alarmManager.Occur(AlarmCode.AL_0809_RTC5_VERIFY_ERROR_RTC5_DLL_VERSION);
|
|
if (errorBits[10] == true)
|
_equipment.alarmManager.Occur(AlarmCode.AL_0810_RTC5_DSP_VERSION_ERROR);
|
|
if (errorBits[11] == true)
|
_equipment.alarmManager.Occur(AlarmCode.AL_0811_RTC5_DLL_INTERNAL_WINDOWS_MEMORY_REQUEST_FAIL);
|
|
if (errorBits[12] == true)
|
_equipment.alarmManager.Occur(AlarmCode.AL_0812_RTC5_EEPROM_READ_OR_WRITE_ERROR);
|
|
if (errorBits[16] == true)
|
_equipment.alarmManager.Occur(AlarmCode.AL_0813_RTC5_ERROR_READING_PCI_CONFIGURATION_REGISTER);
|
|
RTC5Wrap.reset_error(errorCode);
|
return true;
|
}
|
|
/// <summary>
|
/// Load Program 후 반환된 코드로 Error 발생 확인.
|
/// </summary>
|
/// <param name="errorCode"></param>
|
/// <returns></returns>
|
private bool LoadProgramFileErrorExist(uint errorCode)
|
{
|
switch (errorCode)
|
{
|
case 0:
|
return false;
|
case 1:
|
_equipment.alarmManager.Occur(AlarmCode.AL_0814_RTC5_RESET_ERROR);
|
return true;
|
case 2:
|
_equipment.alarmManager.Occur(AlarmCode.AL_0815_RTC5_UNRESET_ERROR);
|
return true;
|
case 3:
|
_equipment.alarmManager.Occur(AlarmCode.AL_0816_RTC5_FILE_ERROR);
|
return true;
|
case 4:
|
_equipment.alarmManager.Occur(AlarmCode.AL_0817_RTC5_FORMAT_ERROR);
|
return true;
|
case 5:
|
_equipment.alarmManager.Occur(AlarmCode.AL_0818_RTC5_SYSTEM_ERROR);
|
return true;
|
case 6:
|
_equipment.alarmManager.Occur(AlarmCode.AL_0819_RTC5_ACCESS_ERROR);
|
return true;
|
case 7:
|
_equipment.alarmManager.Occur(AlarmCode.AL_0820_RTC5_VERSION_ERROR);
|
return true;
|
case 8:
|
_equipment.alarmManager.Occur(AlarmCode.AL_0821_RTC5_SYSTEM_DRIVER_NOT_FOUND);
|
return true;
|
case 9:
|
_equipment.alarmManager.Occur(AlarmCode.AL_0822_RTC5_DRIVER_CALL_ERROR);
|
return true;
|
case 10:
|
_equipment.alarmManager.Occur(AlarmCode.AL_0823_RTC5_CONFIGURATION_ERROR);
|
return true;
|
case 11:
|
_equipment.alarmManager.Occur(AlarmCode.AL_0824_RTC5_FPGA_FIRMWARE_ERROR);
|
return true;
|
case 12:
|
_equipment.alarmManager.Occur(AlarmCode.AL_0825_RTC5_PCI_DOWNLOAD_ERROR);
|
return true;
|
case 13:
|
_equipment.alarmManager.Occur(AlarmCode.AL_0826_RTC5_BUSY_ERROR);
|
return true;
|
case 14:
|
_equipment.alarmManager.Occur(AlarmCode.AL_0827_RTC5_DSP_MEMORY_ERROR);
|
return true;
|
case 15:
|
_equipment.alarmManager.Occur(AlarmCode.AL_0828_RTC5_VERIFY_ERROR);
|
return true;
|
case 16:
|
_equipment.alarmManager.Occur(AlarmCode.AL_0829_RTC5_PCI_ERROR);
|
return true;
|
default:
|
return true;
|
}
|
}
|
|
/// <summary>
|
/// 보정파일 읽어올때 반환된 코드로 Error 발생 확인.
|
/// </summary>
|
/// <param name="errorCode"></param>
|
/// <returns></returns>
|
private bool LoadCorrectionFileErrorExist(uint errorCode)
|
{
|
switch (errorCode)
|
{
|
case 0:
|
return false;
|
case 1:
|
_equipment.alarmManager.Occur(AlarmCode.AL_0830_RTC5_FILE_ERROR);
|
return true;
|
case 2:
|
_equipment.alarmManager.Occur(AlarmCode.AL_0831_RTC5_MEMORY_ERROR);
|
return true;
|
case 3:
|
_equipment.alarmManager.Occur(AlarmCode.AL_0832_RTC5_FILE_OPEN_ERROR);
|
return true;
|
case 4:
|
_equipment.alarmManager.Occur(AlarmCode.AL_0833_RTC5_DSP_MEMORY_ERROR);
|
return true;
|
case 5:
|
_equipment.alarmManager.Occur(AlarmCode.AL_0834_RTC5_PCI_DOWNLOAD_ERROR);
|
return true;
|
case 8:
|
_equipment.alarmManager.Occur(AlarmCode.AL_0835_RTC5_SYSTEM_DRIVER_NOT_FOUND);
|
return true;
|
case 10:
|
_equipment.alarmManager.Occur(AlarmCode.AL_0836_RTC5_PARAMETER_ERROR);
|
return true;
|
case 11:
|
_equipment.alarmManager.Occur(AlarmCode.AL_0837_RTC5_ACCESS_ERROR);
|
return true;
|
case 12:
|
_equipment.alarmManager.Occur(AlarmCode.AL_0838_RTC5_WARNING_3D_CORRECTION_TABLE);
|
return true;
|
case 13:
|
_equipment.alarmManager.Occur(AlarmCode.AL_0839_RTC5_BUSY_ERROR);
|
return true;
|
case 14:
|
_equipment.alarmManager.Occur(AlarmCode.AL_0840_RTC5_PCI_UPLOAD_ERROR);
|
return true;
|
case 15:
|
_equipment.alarmManager.Occur(AlarmCode.AL_0841_RTC5_VERIFY_ERROR);
|
return true;
|
default:
|
return true;
|
}
|
}
|
|
/// <summary>
|
/// RTC 5 DLL 초기화.
|
/// </summary>
|
/// <returns></returns>
|
private bool InitializeRTC5Dll()
|
{
|
// ====== RTC 5 Dll 초기화 ======
|
RTC5Wrap.init_rtc5_dll();
|
|
if (ErrorExist())
|
{
|
return false;
|
}
|
else
|
{
|
return true;
|
}
|
}
|
|
/// <summary>
|
/// RTC5 RBF, OUT, DAT 파일 로드
|
/// </summary>
|
/// <returns></returns>
|
private bool LoadProgramFiles()
|
{
|
uint errorCode = RTC5Wrap.load_program_file(null);
|
|
if (LoadProgramFileErrorExist(errorCode))
|
{
|
return false;
|
}
|
else
|
{
|
return true;
|
}
|
}
|
|
/// <summary>
|
/// 보정파일 로드
|
/// </summary>
|
/// <param name="filePath">보정파일 위치</param>
|
/// <returns></returns>
|
private bool LoadCorrectionFiles(string filePath)
|
{
|
uint errorCode = RTC5Wrap.load_correction_file(CorrectionFilePath,
|
1, // table; #1 is used by default
|
2); // 2D correction files and 3D correction files are sotred as a 2D correction table.
|
|
if (LoadCorrectionFileErrorExist(errorCode))
|
{
|
return false;
|
}
|
else
|
{
|
return true;
|
}
|
}
|
|
/// <summary>
|
/// RTC5 보드 초기화. [기본 위치 : 실행파일 위치]
|
/// </summary>
|
/// <param name="correctionFilePath">보정 파일 위치</param>
|
/// <returns></returns>
|
public bool Initialize(string correctionFilePath = null)
|
{
|
lock (_lock)
|
{
|
if (InitializeRTC5Dll() == false)
|
{
|
IsInitialized = false;
|
return false;
|
}
|
|
if (LoadProgramFiles() == false)
|
{
|
IsInitialized = false;
|
return false;
|
}
|
|
if (LoadCorrectionFiles(correctionFilePath) == false)
|
{
|
IsInitialized = false;
|
return false;
|
}
|
}
|
|
RTC5Wrap.home_position(0, 0);
|
|
if(SetLaserDelays() && SetLaserTiming() && SetScannerDelay())
|
{
|
IsInitialized = true;
|
}
|
else
|
{
|
IsInitialized = false;
|
}
|
|
RTC5Wrap.set_laser_control(1);
|
|
return true;
|
}
|
|
/// <summary>
|
/// List 동작 중 확인.
|
/// </summary>
|
/// <returns></returns>
|
public bool GetBusy()
|
{
|
try
|
{
|
if (IsInitialized)
|
{
|
lock (_lock)
|
{
|
uint ubusy, position;
|
RTC5Wrap.get_status(out ubusy, out position);
|
IsBusy = ubusy != 0;
|
IsPosition = position;
|
}
|
}
|
else
|
{
|
IsBusy = false;
|
}
|
return IsBusy;
|
}
|
catch(Exception e)
|
{
|
EquipmentLogManager.Instance.WriteExceptionLog(e.StackTrace);
|
return false;
|
}
|
}
|
|
public bool GetLaserOn()
|
{
|
try
|
{
|
if (IsInitialized)
|
{
|
lock (_lock)
|
{
|
IsLaserOn = RTC5Wrap.get_value((ushort)0) == (short)1;
|
}
|
}
|
else
|
{
|
IsLaserOn = false;
|
}
|
|
return IsLaserOn;
|
}
|
catch(Exception e)
|
{
|
EquipmentLogManager.Instance.WriteExceptionLog(e.StackTrace);
|
return false;
|
}
|
}
|
|
/// <summary>
|
/// Laser timing 설정 [Laser Half of signal period, Laser Pulse widths, Time Base]
|
/// </summary>
|
/// <returns></returns>
|
public bool SetLaserTiming()
|
{
|
RTC5Wrap.set_start_list(1);
|
RTC5Wrap.set_laser_timing(HalfPeriod, PulseLength1, PulseLength2, TimeBase);
|
RTC5Wrap.set_end_of_list();
|
RTC5Wrap.execute_list(1);
|
|
//CtlFrequency(1000, 0.085f);
|
if (ErrorExist())
|
{
|
return false;
|
}
|
else
|
{
|
return true;
|
}
|
}
|
|
/// <summary>
|
/// Scanner delay 설정. [jump delay, mark delay, polygon delay]
|
/// </summary>
|
/// <returns></returns>
|
public bool SetScannerDelay()
|
{
|
RTC5Wrap.set_start_list(1);
|
RTC5Wrap.set_scanner_delays(JumpDelay, MarkDelay, PolygonDelay);
|
RTC5Wrap.set_end_of_list();
|
RTC5Wrap.execute_list(1);
|
|
if (ErrorExist())
|
{
|
return false;
|
}
|
else
|
{
|
return true;
|
}
|
}
|
|
/// <summary>주파수와 펄스폭 설정</summary>
|
/// <param name="frequency">주파수 (Hz)</param>
|
/// <param name="pulseWidth">펄스폭 (usec)</param>
|
/// <returns></returns>
|
public virtual bool CtlFrequency(float frequency, float pulseWidth)
|
{
|
if (IsBusy)
|
{
|
return false;
|
}
|
|
if ((double)frequency <= 0.0 || (double)pulseWidth <= 0.0)
|
{
|
return false;
|
}
|
|
double num1 = Math.Round(1.0 / (double)frequency * 1000000.0 / 2.0, 3);
|
double num2 = Math.Round((double)pulseWidth, 3);
|
RTC5Wrap.set_start_list(1);
|
RTC5Wrap.set_laser_timing((uint)Math.Floor(num1 * 64.0), (uint)Math.Floor(num2 * 64.0), (uint)Math.Floor(num2 * 64.0), 0U);
|
RTC5Wrap.set_end_of_list();
|
RTC5Wrap.execute_list(1);
|
|
return true;
|
}
|
|
/// <summary>
|
/// Laser delay 설정 [Laser on delay, Laser off delay]
|
/// </summary>
|
/// <returns></returns>
|
public bool SetLaserDelays()
|
{
|
RTC5Wrap.set_start_list(1);
|
RTC5Wrap.set_laser_delays(LaserOnDelay, LaserOffDelay);
|
RTC5Wrap.set_end_of_list();
|
RTC5Wrap.execute_list(1);
|
|
if (ErrorExist())
|
{
|
return false;
|
}
|
else
|
{
|
return true;
|
}
|
}
|
|
public void LaserOn()
|
{
|
RTC5Wrap.laser_signal_on();
|
}
|
|
public void LaserOff()
|
{
|
RTC5Wrap.laser_signal_off();
|
}
|
|
/// <summary>
|
/// Set jump speed, mark speed
|
/// </summary>
|
/// <param name="jumpSpeed"> mm/s </param>
|
/// <param name="markSpeed"> mm/s </param>
|
/// <returns></returns>
|
public bool SetJumpMarkSpeed(double jumpSpeed, double markSpeed)
|
{
|
if (jumpSpeed == 0)
|
jumpSpeed = 10;
|
|
if (markSpeed == 0)
|
markSpeed = 10;
|
|
double jump = (BitsPerMm / 1000) * jumpSpeed;
|
double mark = (BitsPerMm / 1000) * markSpeed;
|
|
RTC5Wrap.set_start_list(1);
|
RTC5Wrap.set_jump_speed(jump);
|
RTC5Wrap.set_mark_speed(mark);
|
RTC5Wrap.set_end_of_list();
|
RTC5Wrap.execute_list(1);
|
|
if (ErrorExist())
|
{
|
return false;
|
}
|
else
|
{
|
return true;
|
}
|
}
|
|
/// <summary>
|
/// RCT5 보드에 연결되어 있는 Encoder 값 읽기.
|
/// </summary>
|
/// <returns></returns>
|
public bool GetEncoder()
|
{
|
int encoder0, encoder1;
|
|
RTC5Wrap.get_encoder(out encoder0, out encoder1);
|
|
Encoder0 = encoder0;
|
Encoder1 = encoder1;
|
|
if (ErrorExist())
|
{
|
return false;
|
}
|
else
|
{
|
return true;
|
}
|
}
|
|
/// <summary>
|
/// Scan list Data 반환
|
/// </summary>
|
/// <returns></returns>
|
public Coord[] GetScanList()
|
{
|
return scanList.ToArray();
|
}
|
|
/// <summary>
|
/// Scan list 초기화
|
/// </summary>
|
/// <returns></returns>
|
public bool ClearScanList()
|
{
|
scanList.Clear();
|
|
ScanListCleared.Invoke();
|
return true;
|
}
|
|
/// <summary>
|
/// Scan list에 가공 정보 추가
|
/// </summary>
|
/// <param name="coord"></param>
|
/// <returns></returns>
|
public bool AddScanList(Coord coord)
|
{
|
scanList.Add(coord);
|
ScanListAdded?.Invoke(coord);
|
return true;
|
}
|
|
/// <summary>
|
///
|
/// </summary>
|
/// <param name="scanMode"></param>
|
/// <param name="x">mm</param>
|
/// <param name="y">mm</param>
|
/// <returns></returns>
|
public bool AddScanList(ScanMode scanMode, double x, double y)
|
{
|
Coord coord = new Coord();
|
coord.ScanMode = scanMode;
|
coord.X = (int)Math.Floor(x * BitsPerMm);
|
coord.Y = (int)Math.Floor(y * BitsPerMm);
|
|
scanList.Add(coord);
|
ScanListAdded?.Invoke(coord);
|
|
return true;
|
}
|
|
/// <summary>
|
/// 가공 시작
|
/// </summary>
|
/// <returns></returns>
|
public bool ExcuteScanList(bool onTheFly = false)
|
{
|
RTC5Wrap.set_start_list(1);
|
|
if (onTheFly)
|
{
|
double ScaleX;
|
double ScaleY;
|
|
if (EncoderCountPerMmX == 0)
|
{
|
ScaleX = 0;
|
}
|
else
|
{
|
ScaleX = BitsPerMm / EncoderCountPerMmX;
|
RTC5Wrap.set_fly_x(ScaleX);
|
}
|
|
if (EncoderCountPerMmY == 0)
|
{
|
ScaleY = 0;
|
}
|
else
|
{
|
ScaleY = BitsPerMm / EncoderCountPerMmY;
|
RTC5Wrap.set_fly_y(ScaleY);
|
}
|
|
RTC5Wrap.set_rot_center(0, 0);
|
}
|
|
foreach (Coord coord in scanList)
|
{
|
int x = (int)(coord.X * XGain);
|
int y = (int)(coord.Y * YGain);
|
|
if (coord.ScanMode == ScanMode.JUMP)
|
{
|
//RTC5Wrap.jump_abs(coord.X, coord.Y);
|
RTC5Wrap.jump_abs(x, y);
|
}
|
else
|
{
|
//RTC5Wrap.mark_abs(coord.X, coord.Y);
|
RTC5Wrap.mark_abs(x, y);
|
}
|
}
|
|
if (onTheFly)
|
{
|
RTC5Wrap.fly_return(0, 0);
|
}
|
else
|
{
|
RTC5Wrap.jump_abs(0, 0);
|
}
|
|
RTC5Wrap.set_end_of_list();
|
|
RTC5Wrap.execute_list(1);
|
|
if (ErrorExist())
|
{
|
return false;
|
}
|
else
|
{
|
return true;
|
}
|
}
|
|
public bool Stop()
|
{
|
RTC5Wrap.stop_execution();
|
|
if (ErrorExist())
|
{
|
return false;
|
}
|
else
|
{
|
return true;
|
}
|
}
|
|
public bool Save()
|
{
|
DirectoryInfo directoryInfo = new DirectoryInfo(Equipment.settingFilePath + _filePath);
|
|
if (directoryInfo.Exists == false)
|
{
|
directoryInfo.Create();
|
}
|
|
FileInfo fileInfo = new FileInfo(directoryInfo.FullName + _fileName);
|
|
if (fileInfo.Exists == false)
|
{
|
fileInfo.Create().Close();
|
}
|
|
SetScannerDelay();
|
SetLaserDelays();
|
SetLaserTiming();
|
|
return TrySaveFile(fileInfo.FullName, this);
|
}
|
|
public void AddScanField(int linecount = 5, double fieldSize = 15)
|
{
|
double intervalLength = 0;
|
|
if (linecount % 2 == 0) // Line count가 짝수 일 때
|
{
|
intervalLength = fieldSize / linecount;
|
|
//X축 그리기.
|
for (int i = linecount / 2; i > 0; i--)
|
{
|
AddScanList(ScanMode.JUMP, -(fieldSize / 2 + 1), intervalLength * i);
|
AddScanList(ScanMode.MARK, (fieldSize / 2 + 1), intervalLength * i);
|
}
|
|
for (int i = -(linecount / 2); i < 0; i++)
|
{
|
AddScanList(ScanMode.JUMP, -(fieldSize / 2 + 1), intervalLength * i);
|
AddScanList(ScanMode.MARK, (fieldSize / 2 + 1), intervalLength * i);
|
}
|
|
//Y축 그리기
|
for (int i = linecount / 2; i > 0; i--)
|
{
|
AddScanList(ScanMode.JUMP, intervalLength * i, -(fieldSize / 2 + 1));
|
AddScanList(ScanMode.MARK, intervalLength * i, (fieldSize / 2 + 1));
|
}
|
|
for (int i = -(linecount / 2); i < 0; i++)
|
{
|
AddScanList(ScanMode.JUMP, intervalLength * i, -(fieldSize / 2 + 1));
|
AddScanList(ScanMode.MARK, intervalLength * i, (fieldSize / 2 + 1));
|
}
|
}
|
else // Line count가 홀수 일 때
|
{
|
intervalLength = fieldSize / (linecount - 1);
|
|
//X축 그리기.
|
for (int i = -(linecount - 1) / 2; i <= (linecount - 1) / 2; i++)
|
{
|
AddScanList(ScanMode.JUMP, -(fieldSize / 2 + 1), intervalLength * i);
|
AddScanList(ScanMode.MARK, (fieldSize / 2 + 1), intervalLength * i);
|
}
|
|
//Y축 그리기
|
for (int i = -(linecount - 1) / 2; i <= (linecount - 1) / 2; i++)
|
{
|
AddScanList(ScanMode.JUMP, intervalLength * i, -(fieldSize / 2 + 1));
|
AddScanList(ScanMode.MARK, intervalLength * i, (fieldSize / 2 + 1));
|
}
|
}
|
}
|
}
|
}
|