857 lines
30 KiB
C#
857 lines
30 KiB
C#
using Aurora.Api;
|
|
using Hermes;
|
|
using System;
|
|
using System.Diagnostics;
|
|
using System.Runtime.InteropServices;
|
|
using System.Threading;
|
|
using static AuroraPLC.PLCBase;
|
|
|
|
namespace AuroraLaserScanner
|
|
{
|
|
public class ScannerSimul : 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;
|
|
private ScannerConfig _config;
|
|
|
|
// -----------------------------
|
|
// MOTF Simulation state
|
|
// -----------------------------
|
|
public Func<int, ePLCDevice, bool, (int err, bool data)> PLCReadBit;
|
|
public Func<int, ePLCDevice, bool, (int err, short data)> PLCReadWord;
|
|
public Func<int, ePLCDevice, bool, (int err, int data)> PLCReadDWord;
|
|
public Func<double> PLCGetAbsDeg;
|
|
|
|
private const int PLC_CURRENT_POS_1_ADDR = 4;
|
|
|
|
public Stopwatch sw = Stopwatch.StartNew();
|
|
|
|
// encoder가 반환할 값
|
|
public volatile int _simEncXCount = 0; //랩핑 각도(0~360
|
|
public volatile int _simEncYCount = 0; //누적 각도
|
|
|
|
public volatile bool LastWaitMissedRange = false;
|
|
|
|
private const int RotaryJigCount = 16;
|
|
private const double JigPerMsec = 300;
|
|
private const double DegreePerRev = 360.0;
|
|
private const double OneCycleMsec = JigPerMsec * RotaryJigCount;
|
|
|
|
// 누적각을 scanner 내부에서 유지
|
|
public double _angleAbsDeg = 0.0;
|
|
private bool _listClosed = false;
|
|
private bool _list1Busy = false;
|
|
private bool _list2Busy = false;
|
|
private eListNo _currentExecutingList = eListNo.NONE;
|
|
private bool _autoChangeRequested = false;
|
|
|
|
private long _listStartMs = 0; // ← 이게 executionStartTime 역할
|
|
|
|
// 리스트 기록 대상 추적 (LoadList 성공 시 설정, SetEndList 시 초기화)
|
|
private eListNo _recordingList = eListNo.NONE;
|
|
|
|
// 리스트별 WaitForEncoderRotateRange 조건 저장 (실제 RTC 펌웨어 리스트 명령 역할)
|
|
private bool _list1HasEncoderWait;
|
|
private double _list1EncoderMinY, _list1EncoderMaxY;
|
|
private bool _list2HasEncoderWait;
|
|
private double _list2EncoderMinY, _list2EncoderMaxY;
|
|
|
|
// 현재 실행 중인 리스트의 엔코더 조건 충족 여부
|
|
private bool _encoderConditionMet;
|
|
|
|
// InitFly2D() 호출 시점의 PLC 누적각 (실제 RTC 엔코더 리셋과 동일한 역할)
|
|
// _angleAbsDeg = PLCGetAbsDeg() - _flyResetAbsDeg 로 항상 InitFly2D 이후 상대각을 유지
|
|
private double _flyResetAbsDeg = 0.0;
|
|
|
|
private const int MinListTimeMs = 30; // 너무 빠른 완료 방지
|
|
private const int MaxListTimeMs = 800; // 너무 느린 완료 방지
|
|
private int SimulatedListTimeMs = 250; // 리스트 실행 시간
|
|
|
|
private const double RecommendWindowDeg = 45.0;
|
|
private const double RecommendUseRatio = 0.35; // 45도 중 실제 마킹이 차지하는 비율(가볍게)
|
|
|
|
public void EquipmentSimulator()
|
|
{
|
|
PullEncoderFromPlcOnce();
|
|
UpdateListExecution();
|
|
}
|
|
|
|
private int DegToCount(double deg)
|
|
{
|
|
double c = deg * _config.MarkingOnTheFlyEncoderResolutionRotate / DegreePerRev;
|
|
return (int)System.Math.Round(c);
|
|
}
|
|
|
|
private int DegToCountAbs(double absDeg)
|
|
{
|
|
double c = absDeg * _config.MarkingOnTheFlyEncoderResolutionRotate / DegreePerRev;
|
|
long lc = (long)System.Math.Round(c);
|
|
return unchecked((int)lc);
|
|
}
|
|
|
|
private void UpdateListExecution()
|
|
{
|
|
if (_currentExecutingList == eListNo.NONE)
|
|
return;
|
|
|
|
long now = sw.ElapsedMilliseconds;
|
|
|
|
// ── Phase 1: 엔코더 조건 대기 ───────────────────────────────────────
|
|
// 실제 RTC 펌웨어에서 WaitForEncoderRotateRange 명령이 리스트 실행 중
|
|
// 엔코더가 구간에 진입할 때까지 대기하는 동작을 모사.
|
|
bool hasWait = (_currentExecutingList == eListNo.LIST1) ? _list1HasEncoderWait : _list2HasEncoderWait;
|
|
if (hasWait && !_encoderConditionMet) {
|
|
double minY = (_currentExecutingList == eListNo.LIST1) ? _list1EncoderMinY : _list2EncoderMinY;
|
|
double maxY = (_currentExecutingList == eListNo.LIST1) ? _list1EncoderMaxY : _list2EncoderMaxY;
|
|
// _angleAbsDeg는 PullEncoderFromPlcOnce에서 InitFly2D 기준 상대각으로 갱신됨
|
|
double absDeg = _angleAbsDeg;
|
|
if (absDeg >= minY && absDeg <= maxY) {
|
|
_encoderConditionMet = true;
|
|
_listStartMs = now; // 조건 충족 시점부터 마킹 타이머 시작
|
|
}
|
|
return; // 조건 미충족이면 busy 유지, 충족 직후도 이번 주기는 return
|
|
}
|
|
|
|
// ── Phase 2: 마킹 시간 경과 후 리스트 완료 ─────────────────────────
|
|
long elapsed = now - _listStartMs;
|
|
int doneTime = GetEffectiveListTimeMs();
|
|
|
|
// 최소 현실 가드: elapsed가 음수인 경우 방지
|
|
if (elapsed < 0) {
|
|
_listStartMs = now;
|
|
return;
|
|
}
|
|
|
|
if (elapsed >= doneTime) {
|
|
// 현재 리스트 실행 완료
|
|
if (_currentExecutingList == eListNo.LIST1)
|
|
_list1Busy = false;
|
|
else
|
|
_list2Busy = false;
|
|
|
|
if (_autoChangeRequested) {
|
|
// 반대 리스트 자동 실행
|
|
_currentExecutingList =
|
|
(_currentExecutingList == eListNo.LIST1) ? eListNo.LIST2 : eListNo.LIST1;
|
|
|
|
if (_currentExecutingList == eListNo.LIST1) {
|
|
_list1Busy = true;
|
|
_list2Busy = false;
|
|
} else {
|
|
_list2Busy = true;
|
|
_list1Busy = false;
|
|
}
|
|
|
|
_autoChangeRequested = false;
|
|
_encoderConditionMet = false; // 새 리스트의 엔코더 조건 초기화
|
|
|
|
bool newHasWait = (_currentExecutingList == eListNo.LIST1) ? _list1HasEncoderWait : _list2HasEncoderWait;
|
|
if (!newHasWait)
|
|
_listStartMs = now; // 엔코더 대기 없으면 마킹 타이머 즉시 시작
|
|
} else {
|
|
_currentExecutingList = eListNo.NONE;
|
|
}
|
|
}
|
|
}
|
|
private int GetEffectiveListTimeMs()
|
|
{
|
|
int t = SimulatedListTimeMs;
|
|
|
|
// 4800msec / 360 * 45 * ratio
|
|
int recommendedListRunTime = (int)Math.Round((OneCycleMsec / DegreePerRev) * RecommendWindowDeg * RecommendUseRatio);
|
|
|
|
// recommended가 너무 작거나 0이 되는 경우 방지
|
|
if (recommendedListRunTime < MinListTimeMs)
|
|
recommendedListRunTime = MinListTimeMs;
|
|
|
|
if (t < MinListTimeMs)
|
|
t = MinListTimeMs;
|
|
|
|
if (t > MaxListTimeMs)
|
|
t = MaxListTimeMs;
|
|
|
|
if (recommendedListRunTime > MaxListTimeMs)
|
|
recommendedListRunTime = MaxListTimeMs;
|
|
|
|
return t;
|
|
}
|
|
public void TrySyncAbsAngleToPlcNow()
|
|
{
|
|
_angleAbsDeg = PLCGetAbsDeg();
|
|
|
|
// mod 동기화도 같이
|
|
int modRaw = PLCReadDWord(PLC_CURRENT_POS_1_ADDR, ePLCDevice.W, false).data;
|
|
double modDeg = (modRaw / 100_000.0) % DegreePerRev;
|
|
if (modDeg < 0)
|
|
modDeg += DegreePerRev;
|
|
|
|
LastWaitMissedRange = false;
|
|
}
|
|
public void ResetSim()
|
|
{
|
|
_angleAbsDeg = 0.0;
|
|
|
|
_simEncXCount = 0;
|
|
_simEncYCount = 0;
|
|
|
|
StopExecution(); // 리스트 상태 리셋
|
|
LastWaitMissedRange = false;
|
|
}
|
|
public override uint Open()
|
|
{
|
|
IsOpenUnit = true;
|
|
return NO_ERROR;
|
|
}
|
|
public override void Close()
|
|
{
|
|
if (IsOpenUnit == true) {
|
|
IsOpenUnit = false;
|
|
}
|
|
}
|
|
public override int Initialize(ScannerConfig config)
|
|
{
|
|
CommandPosX = 0;
|
|
CommandPosY = 0;
|
|
CommandPosZ = 0;
|
|
|
|
_ModulationMode = config.Modulation;
|
|
_config = config;
|
|
|
|
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;
|
|
}
|
|
public override void JumpAbs3D(double x, double y, double z, eFunctionType type = eFunctionType.COMMAND)
|
|
{
|
|
CommandPosX = x;
|
|
CommandPosY = y;
|
|
CommandPosZ = z;
|
|
}
|
|
public override void JumpRel(double x, double y, eFunctionType type = eFunctionType.COMMAND)
|
|
{
|
|
CommandPosX += x;
|
|
CommandPosY += y;
|
|
}
|
|
public override void JumpRel3D(double x, double y, double z, eFunctionType type = eFunctionType.COMMAND)
|
|
{
|
|
CommandPosX += x;
|
|
CommandPosY += y;
|
|
CommandPosZ += z;
|
|
}
|
|
public override void MarkAbs(double x, double y)
|
|
{
|
|
CommandPosX = x;
|
|
CommandPosY = y;
|
|
}
|
|
public override void MarkRel(double x, double y)
|
|
{
|
|
CommandPosX += x;
|
|
CommandPosY += y;
|
|
}
|
|
public override void ArcAbs(double x, double y, double angle)
|
|
{
|
|
CommandPosX = x;
|
|
CommandPosY = y;
|
|
}
|
|
|
|
public override void ArcRel(double x, double y, double angle)
|
|
{
|
|
CommandPosX += x;
|
|
CommandPosY += y;
|
|
}
|
|
|
|
public override void JumpAbsZ(double z, eFunctionType type = eFunctionType.COMMAND)
|
|
{
|
|
CommandPosZ = z;
|
|
}
|
|
public override void JumpRelZ(double z, eFunctionType type = eFunctionType.COMMAND)
|
|
{
|
|
CommandPosZ += z;
|
|
}
|
|
public override void GetXYPos(out double x, out double y)
|
|
{
|
|
x = CommandPosX;
|
|
y = CommandPosY;
|
|
}
|
|
public override void GetZPos(out double z)
|
|
{
|
|
z = CommandPosZ;
|
|
}
|
|
|
|
public override void WriteDA(uint portNo, float value/*0~100%*/, eFunctionType type = eFunctionType.COMMAND)
|
|
{
|
|
|
|
}
|
|
|
|
public override void GetEncoder(out double encoderX, out double encoderY, bool rotateMode = false)
|
|
{
|
|
int valueX = _simEncXCount;
|
|
int valueY = _simEncYCount;
|
|
|
|
// 너가 쓰는 변환식 그대로
|
|
encoderX = (valueX * DegreePerRev) / _config.MarkingOnTheFlyEncoderResolutionRotate;
|
|
encoderY = _angleAbsDeg;
|
|
if (encoderY > -0.5 && encoderY < 0)
|
|
encoderY = 0; // 시뮬 안정화
|
|
return;
|
|
}
|
|
|
|
public override uint GetMarkingInfo()
|
|
{
|
|
//return RTC5Wrap.n_get_marking_info(m_deviceNo);
|
|
return 0;
|
|
}
|
|
public override uint GetStartStopInfo()
|
|
{
|
|
//return RTC5Wrap.n_get_startstop_info(m_deviceNo);
|
|
return 0;
|
|
}
|
|
public override void StoreEncoder(uint pos)
|
|
{
|
|
//RTC5Wrap.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)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
encoder0_0 = 0;
|
|
encoder1_0 = 0;
|
|
encoder0_1 = 0;
|
|
encoder1_1 = 0;
|
|
}
|
|
|
|
public override void WaitForEncoderX(double position)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
|
|
public override void WaitForEncoderY(double position)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
|
|
public override void WaitForEncoderRotateX(double angle)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
|
|
public override void WaitForEncoderRotateY(double angle)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
|
|
public override void WaitForEncoderRotateXMode(double angle, eEncoderWaitThroughMode mode)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
|
|
public override void WaitForEncoderRotateYMode(double angle, eEncoderWaitThroughMode mode)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void WaitForEncoderXMode(double position, eEncoderWaitThroughMode mode)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void WaitForEncoderYMode(double position, eEncoderWaitThroughMode mode)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void WaitForEncoderMode(double position, uint encoderNo, eEncoderWaitThroughMode mode)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void WaitForEncoderRange(double minX, double maxX, double minY, double maxY)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
|
|
public override void WaitForEncoderRotateRange(double minX, double maxX, double minY, double maxY)
|
|
{
|
|
// 실제 RTC 펌웨어와 동일하게: PC 스레드를 블로킹하지 않고 리스트 명령으로 조건 저장.
|
|
// EquipmentSimulator → UpdateListExecution 에서 PLCGetAbsDeg()가 [minY, maxY] 구간
|
|
// 진입을 확인한 후 마킹 타이머를 시작하므로, 그 전까지 리스트는 busy 상태를 유지.
|
|
// LoadList 폴링(CheckLoadComplete)이 busy 해소를 기다리는 방식으로 타이밍 동기화.
|
|
if (_recordingList == eListNo.LIST1) {
|
|
_list1HasEncoderWait = true;
|
|
_list1EncoderMinY = minY;
|
|
_list1EncoderMaxY = maxY;
|
|
} else if (_recordingList == eListNo.LIST2) {
|
|
_list2HasEncoderWait = true;
|
|
_list2EncoderMinY = minY;
|
|
_list2EncoderMaxY = maxY;
|
|
}
|
|
}
|
|
private void PullEncoderFromPlcOnce()
|
|
{
|
|
// 방어: delegate 미설정이면 아무 것도 못함
|
|
if (PLCReadDWord == null || _config == null || _config.MarkingOnTheFlyEncoderResolutionRotate == 0)
|
|
return;
|
|
|
|
// 1) 랩핑각 (0~360)
|
|
int modRaw = PLCReadDWord(PLC_CURRENT_POS_1_ADDR, ePLCDevice.W, true).data;
|
|
double angleModDeg = (modRaw / 100_000.0) % 360.0;
|
|
if (angleModDeg < 0)
|
|
angleModDeg += 360.0;
|
|
|
|
// 2) 누적각 (계속 증가)
|
|
//int absRaw = PLCReadDWord(PLC_CURRENT_POS_ABS_ADDR, ePLCDevice.W, true).data;
|
|
//double angleAbsDeg = absRaw / 100_000.0;
|
|
if (PLCGetAbsDeg != null) {
|
|
// InitFly2D 시점 기준 상대각 유지 (실제 RTC 엔코더 리셋 동작과 동일)
|
|
_angleAbsDeg = PLCGetAbsDeg() - _flyResetAbsDeg;
|
|
}
|
|
|
|
// 3) count로 변환 (n_get_encoder가 반환한다고 가정하는 값)
|
|
_simEncXCount = DegToCount(angleModDeg);
|
|
_simEncYCount = DegToCountAbs(_angleAbsDeg);
|
|
}
|
|
public override void SetFlyX(double encoderResolution)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
|
|
public override void SetFlyX(double encoderResolution, double diameter)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void SetFlyY(double encoderResolution)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void SetRotateCenter(double posX, double posY, eFunctionType type = eFunctionType.COMMAND)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
|
|
}
|
|
public override void SetFlyRotate(double encoderResolution)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
|
|
public override void SetFlyRotatePos(double encoderResolution)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
|
|
|
|
public override void ActivateFlyXY(double encoderResolutionX, double encoderResolutionY)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
|
|
public override void ActivateFly1Axis(int axis, int mode, double scale, int offset)
|
|
{
|
|
|
|
}
|
|
|
|
public override void Fly_Return(double x, double y)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
|
|
}
|
|
public override void ParkPosition(double posX, double posY, eParkType type = eParkType.VirtualImage)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void ParkReturn(double posX, double posY, eParkType type = eParkType.VirtualImage)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
|
|
public override void InitFly2D(int offsetX = 0, int offsetY = 0)
|
|
{
|
|
// 실제 RTC InitFly2D는 펌웨어 MOTF 엔코더 카운터를 0으로 리셋.
|
|
// 시뮬에서는 현재 PLC 누적각을 기준점으로 저장하여 이후 _angleAbsDeg가
|
|
// 0부터 시작하는 상대각이 되도록 함 → sectionStartAngle 계산과 좌표계 일치.
|
|
_flyResetAbsDeg = (PLCGetAbsDeg != null) ? PLCGetAbsDeg() : 0.0;
|
|
_angleAbsDeg = 0.0;
|
|
}
|
|
public override void SimulateEncoder(uint EncoderNo)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void SetControlMode(uint mode)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void SetLaesrDelay(int laserOnDelay, uint laserOffDelay)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void SetScannerDelay(uint jumpDelay, uint markDelay, uint arcDelay)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
|
|
public override void SetJumpSpeedCtrl(double speed)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
|
|
public override void SetJumpSpeed(double speed)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void SetMarkSpeed(double speed)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void SetStartList(eListNo no)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override uint LoadList(eListNo no)
|
|
{
|
|
bool busy = (no == eListNo.LIST1) ? _list1Busy : _list2Busy;
|
|
|
|
if (busy)
|
|
return 0; // 실행 중 → Load 불가
|
|
|
|
// 기록 대상 리스트 확정 및 엔코더 대기 조건 초기화
|
|
// (WaitForEncoderRotateRange가 이번 사이클에서 호출될 때 여기 저장된다)
|
|
if (_recordingList != no) {
|
|
_recordingList = no;
|
|
if (no == eListNo.LIST1) _list1HasEncoderWait = false;
|
|
else _list2HasEncoderWait = false;
|
|
}
|
|
|
|
return (uint)no; // Load 가능
|
|
}
|
|
public override void SetEndList()
|
|
{
|
|
_listClosed = true;
|
|
_recordingList = eListNo.NONE; // 기록 완료
|
|
}
|
|
public override void ExecuteList(eListNo no)
|
|
{
|
|
if (!_listClosed)
|
|
Log.W("ExecuteList called without SetEndList");
|
|
_listClosed = false; // 실행 시작하면서 다시 열림 상태로
|
|
|
|
_currentExecutingList = no;
|
|
_encoderConditionMet = false; // 엔코더 조건부터 평가
|
|
|
|
if (no == eListNo.LIST1) {
|
|
_list1Busy = true;
|
|
_list2Busy = false;
|
|
} else {
|
|
_list2Busy = true;
|
|
_list1Busy = false;
|
|
}
|
|
|
|
bool hasWait = (no == eListNo.LIST1) ? _list1HasEncoderWait : _list2HasEncoderWait;
|
|
if (!hasWait)
|
|
_listStartMs = sw.ElapsedMilliseconds; // 엔코더 대기 없으면 마킹 타이머 즉시 시작
|
|
}
|
|
public override void StartLoop()
|
|
{
|
|
RTC5Wrap.n_start_loop(m_deviceNo);
|
|
}
|
|
public override void QuitLoop()
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void AutoChange()
|
|
{
|
|
if (_currentExecutingList == eListNo.NONE)
|
|
return;
|
|
|
|
_autoChangeRequested = true;
|
|
}
|
|
public override bool GetBusyStatus()
|
|
{
|
|
return _list1Busy || _list2Busy || _currentExecutingList != eListNo.NONE;
|
|
}
|
|
public override void StopExecution()
|
|
{
|
|
_list1Busy = false;
|
|
_list2Busy = false;
|
|
_currentExecutingList = eListNo.NONE;
|
|
_autoChangeRequested = false;
|
|
_listStartMs = 0;
|
|
_listClosed = false;
|
|
|
|
_recordingList = eListNo.NONE;
|
|
_list1HasEncoderWait = false;
|
|
_list2HasEncoderWait = false;
|
|
_encoderConditionMet = false;
|
|
|
|
_flyResetAbsDeg = 0.0;
|
|
_angleAbsDeg = 0.0;
|
|
|
|
_simEncXCount = 0;
|
|
_simEncYCount = 0;
|
|
}
|
|
public override uint GetRTCVersion()
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
return 0;
|
|
}
|
|
public override uint GetDLLVersion()
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
return 0;
|
|
}
|
|
public override void SetLaserTiming(uint periodHz, uint laser1PulseWidthUs, uint laser2PulseWidthUs) //단위는 Khz, us임
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
|
|
public override void SetStandby(uint periodHz, uint laserPulseWidthUs) //단위는 Khz, us임
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
|
|
public override void SetLaserMode(eLaserMode mode)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void SetLaserControl(uint ctrl)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void SetFirstPulseKiller(uint width) //단위는 us->bit 로 변경해야 함
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void LaserSignalOn()
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void LaserSignalOff()
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
|
|
/// <summary>
|
|
/// 지정한 시간 시간만큼 Laser Active 신호를 켜주는 리스트 함수
|
|
/// </summary>
|
|
/// <param name="interval">시간[ms]</param>
|
|
public override void LaserOnList(double interval)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
|
|
/// <summary>
|
|
/// Laser Active가 Off된 상태에서 지정한 시간 시간만큼 delay를 추가하는 함수
|
|
/// </summary>
|
|
/// <param name="delay">시간[ms]</param>
|
|
public override void LongDelay(uint delay)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
|
|
public override void SetAngle(double angle/*degree*/, uint atOnce, eFunctionType type = eFunctionType.COMMAND)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void SetOffset(double offsetX, double offsetY, uint atOnce, eFunctionType type = eFunctionType.COMMAND)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void DisableLaser()
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void EnableLaser()
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void ParaLaserOnPulsesList(double period, uint pulses, float powerValue)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
|
|
|
|
|
|
//Ramping 기능
|
|
public override void ParaMarkAbs(double x, double y, float power)
|
|
{
|
|
CommandPosX = x;
|
|
CommandPosY = y;
|
|
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void ParaMarkRel(double x, double y, float power)
|
|
{
|
|
CommandPosX += x;
|
|
CommandPosY += y;
|
|
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void ParaJumpAbs(double x, double y, float power)
|
|
{
|
|
CommandPosX = x;
|
|
CommandPosY = y;
|
|
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void ParaJumpRel(double x, double y, float power)
|
|
{
|
|
CommandPosX += x;
|
|
CommandPosY += y;
|
|
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void SetVectorControl(uint portNo, uint value)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
|
|
//측정 기능
|
|
public override void StopTrigger()
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void SetTrigger(uint period/*㎲*/, eRecordSignal signal1, eRecordSignal signal2, eRecordSignal signal3, eRecordSignal signal4)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void SetTrigger(uint period/*㎲*/, eRecordSignal signal1, eRecordSignal signal2)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void Measurement_status(out uint busy, out uint pos)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
busy = 0; pos = 0;
|
|
}
|
|
public override uint ReadStatus()
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
return 0;
|
|
}
|
|
public override void GetWaveForm(uint channel, uint number, out int[] data)
|
|
{
|
|
data = new int[number];
|
|
// simulation 할때 값 반영 검토 필요
|
|
|
|
}
|
|
|
|
//안오산-170224-Wobbel모드 추가(V1.7.0)
|
|
//set_wobbel_mode
|
|
public override void SetWobbelMode(bool wobbelEnable, double transversal, double longitudinal, double frequency, int shape)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
|
|
public override void SetWobbelDirection(int dX, int dY)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void SetWobbelVector(double tansversal, double longitudinal, uint period, float power)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
public override void ConfigLaserSignal(eLaserSignal pin2, eLaserSignal pin1, eLaserSignal pin9)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
|
|
public override void SelectCorrectionTable(int no)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
|
|
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()
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
}
|
|
|
|
/// <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()
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
return 0;
|
|
}
|
|
#endregion
|
|
|
|
|
|
|
|
// 기존 추상함수 아닌 3개 항목 추상함수로 추가
|
|
//ExecuteUpdateParameterList는 Initialize에 직접구현할수밖에.. config의 항목 쓰려면..
|
|
public override uint LoadProgramFile(string fileName)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
return 0;
|
|
}
|
|
|
|
public override uint LoadCorrectionFile(string fileName, uint correctionNo, bool use3DMode)
|
|
{
|
|
// simulation 할때 값 반영 검토 필요
|
|
return 0;
|
|
}
|
|
|
|
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)
|
|
{
|
|
|
|
}
|
|
public override void SetPortDefault(uint port, uint value)
|
|
{
|
|
|
|
}
|
|
public override void SetLaserPinOut(uint pins)
|
|
{
|
|
|
|
}
|
|
public override uint GetLastError()
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
public override uint GetListSpace()
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
public override void SetConfigList(uint mem1, uint mem2)
|
|
{
|
|
|
|
}
|
|
}
|
|
}
|