AutoRun Simulation 추가
- AutoRun은 수정 안함(들여쓰기 변경) - Timer 기반 시뮬레이션
This commit is contained in:
parent
e946197f8b
commit
5b4a856a2e
@ -143,6 +143,10 @@
|
|||||||
<Project>{E7E68E54-43D2-4413-9510-43D25F13CD80}</Project>
|
<Project>{E7E68E54-43D2-4413-9510-43D25F13CD80}</Project>
|
||||||
<Name>AuroraLaser</Name>
|
<Name>AuroraLaser</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\AuroraPLC\AuroraPLC.csproj">
|
||||||
|
<Project>{1A47B1F3-5BDE-41DF-8F4D-25298AD4F6DE}</Project>
|
||||||
|
<Name>AuroraPLC</Name>
|
||||||
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
</Project>
|
</Project>
|
||||||
@ -22,7 +22,7 @@ namespace AuroraLaserScanner
|
|||||||
public ScannerConfig Config { get; set; }
|
public ScannerConfig Config { get; set; }
|
||||||
|
|
||||||
//public ScannerObj _scannerObj { get; set; }
|
//public ScannerObj _scannerObj { get; set; }
|
||||||
private ScannerObj _scannerObj { get; set; }
|
protected ScannerObj _scannerObj { get; set; }
|
||||||
|
|
||||||
public Scanner(string deviceId)
|
public Scanner(string deviceId)
|
||||||
{
|
{
|
||||||
@ -37,9 +37,9 @@ namespace AuroraLaserScanner
|
|||||||
Config = config as ScannerConfig;
|
Config = config as ScannerConfig;
|
||||||
if (IsSimul) {
|
if (IsSimul) {
|
||||||
_scannerObj = new ScannerSimul();
|
_scannerObj = new ScannerSimul();
|
||||||
return E1.OK;
|
//return E1.OK;
|
||||||
}
|
}
|
||||||
if (Config.Type == eRTCType.RTC5) {
|
else if (Config.Type == eRTCType.RTC5) {
|
||||||
_scannerObj = new ScannerRTC5();
|
_scannerObj = new ScannerRTC5();
|
||||||
} else if (Config.Type == eRTCType.RTC6) {
|
} else if (Config.Type == eRTCType.RTC6) {
|
||||||
_scannerObj = new ScannerRTC6();
|
_scannerObj = new ScannerRTC6();
|
||||||
|
|||||||
@ -91,7 +91,7 @@ namespace AuroraLaserScanner
|
|||||||
RealImage = 0,
|
RealImage = 0,
|
||||||
VirtualImage = 1
|
VirtualImage = 1
|
||||||
}
|
}
|
||||||
public enum eListNo { LIST1 = 1, LIST2 = 2 };
|
public enum eListNo { NONE = 0, LIST1 = 1, LIST2 = 2 };
|
||||||
|
|
||||||
public enum eAutoControlParameter
|
public enum eAutoControlParameter
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,10 +1,14 @@
|
|||||||
using Aurora.Api;
|
using Aurora.Api;
|
||||||
using Hermes;
|
using Hermes;
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Threading;
|
||||||
|
using static AuroraPLC.PLCBase;
|
||||||
|
|
||||||
namespace AuroraLaserScanner
|
namespace AuroraLaserScanner
|
||||||
{
|
{
|
||||||
internal class ScannerSimul : ScannerObj
|
public class ScannerSimul : ScannerObj
|
||||||
{
|
{
|
||||||
static new readonly Logger Log = new Logger("Scanner");
|
static new readonly Logger Log = new Logger("Scanner");
|
||||||
|
|
||||||
@ -14,7 +18,154 @@ namespace AuroraLaserScanner
|
|||||||
//set_trigger 관련 추가, get_waveform 에서 얻어올 포인터 추가, 최대 크기로 설정 (2^20 = 1,048,576)
|
//set_trigger 관련 추가, get_waveform 에서 얻어올 포인터 추가, 최대 크기로 설정 (2^20 = 1,048,576)
|
||||||
[MarshalAs(UnmanagedType.LPArray, SizeConst = 1048576)] int[] m_getWaveformPtr = new int[1048576];
|
[MarshalAs(UnmanagedType.LPArray, SizeConst = 1048576)] int[] m_getWaveformPtr = new int[1048576];
|
||||||
private bool _ModulationMode;
|
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 역할
|
||||||
|
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
_listStartMs = now;
|
||||||
|
_autoChangeRequested = false;
|
||||||
|
} 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()
|
public override uint Open()
|
||||||
{
|
{
|
||||||
IsOpenUnit = true;
|
IsOpenUnit = true;
|
||||||
@ -33,6 +184,7 @@ namespace AuroraLaserScanner
|
|||||||
CommandPosZ = 0;
|
CommandPosZ = 0;
|
||||||
|
|
||||||
_ModulationMode = config.Modulation;
|
_ModulationMode = config.Modulation;
|
||||||
|
_config = config;
|
||||||
|
|
||||||
return E1.OK;
|
return E1.OK;
|
||||||
}
|
}
|
||||||
@ -107,12 +259,17 @@ namespace AuroraLaserScanner
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void GetEncoder(out double encoderX, out double encoderY, bool rotateMode = false)
|
public override void GetEncoder(out double encoderX, out double encoderY, bool rotateMode = false)
|
||||||
{
|
{
|
||||||
// simulation 할때 값 반영 검토 필요
|
int valueX = _simEncXCount;
|
||||||
encoderX = 0;
|
int valueY = _simEncYCount;
|
||||||
encoderY = 0;
|
|
||||||
|
// 너가 쓰는 변환식 그대로
|
||||||
|
encoderX = (valueX * DegreePerRev) / _config.MarkingOnTheFlyEncoderResolutionRotate;
|
||||||
|
encoderY = _angleAbsDeg;
|
||||||
|
if (encoderY > -0.5 && encoderY < 0)
|
||||||
|
encoderY = 0; // 시뮬 안정화
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override uint GetMarkingInfo()
|
public override uint GetMarkingInfo()
|
||||||
@ -187,9 +344,62 @@ namespace AuroraLaserScanner
|
|||||||
|
|
||||||
public override void WaitForEncoderRotateRange(double minX, double maxX, double minY, double maxY)
|
public override void WaitForEncoderRotateRange(double minX, double maxX, double minY, double maxY)
|
||||||
{
|
{
|
||||||
// simulation 할때 값 반영 검토 필요
|
LastWaitMissedRange = false;
|
||||||
}
|
|
||||||
|
|
||||||
|
long t0 = sw.ElapsedMilliseconds;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
// 블로킹 대기 중에도 PLC에서 최신값을 직접 당겨온다
|
||||||
|
PullEncoderFromPlcOnce();
|
||||||
|
|
||||||
|
// GetEncoder는 _simEncYCount를 deg로 바꿔줄 것
|
||||||
|
GetEncoder(out _, out double curY, true);
|
||||||
|
|
||||||
|
// 정상 진입
|
||||||
|
if (curY >= minY && curY <= maxY)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 최소 현실 가드: 구간을 지나쳤으면 TIMEOUT까지 끌지 말고 즉시 종료
|
||||||
|
// (실장에서도 "놓치면" 의미 없고 다음 로직이 꼬임)
|
||||||
|
if (curY > maxY) {
|
||||||
|
LastWaitMissedRange = true;
|
||||||
|
Log.W($"[SIM] WaitForEncoderRotateRange MISSED. curY={curY:F3}, range=[{minY:F3}..{maxY:F3}]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 최후 안전장치
|
||||||
|
if (sw.ElapsedMilliseconds - t0 > 5000) {
|
||||||
|
LastWaitMissedRange = true;
|
||||||
|
Log.W($"[SIM] WaitForEncoderRotateRange TIMEOUT. curY={curY:F3}, range=[{minY:F3}..{maxY:F3}]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread.Sleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
_angleAbsDeg = PLCGetAbsDeg();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3) count로 변환 (n_get_encoder가 반환한다고 가정하는 값)
|
||||||
|
_simEncXCount = DegToCount(angleModDeg);
|
||||||
|
_simEncYCount = DegToCountAbs(_angleAbsDeg);
|
||||||
|
}
|
||||||
public override void SetFlyX(double encoderResolution)
|
public override void SetFlyX(double encoderResolution)
|
||||||
{
|
{
|
||||||
// simulation 할때 값 반영 검토 필요
|
// simulation 할때 값 반영 검토 필요
|
||||||
@ -283,16 +493,34 @@ namespace AuroraLaserScanner
|
|||||||
}
|
}
|
||||||
public override uint LoadList(eListNo no)
|
public override uint LoadList(eListNo no)
|
||||||
{
|
{
|
||||||
// simulation 할때 값 반영 검토 필요
|
bool busy = (no == eListNo.LIST1) ? _list1Busy : _list2Busy;
|
||||||
return 0;
|
|
||||||
|
if (busy)
|
||||||
|
return 0; // 실행 중 → Load 불가
|
||||||
|
|
||||||
|
return (uint)no; // Load 가능
|
||||||
}
|
}
|
||||||
public override void SetEndList()
|
public override void SetEndList()
|
||||||
{
|
{
|
||||||
// simulation 할때 값 반영 검토 필요
|
_listClosed = true;
|
||||||
}
|
}
|
||||||
public override void ExecuteList(eListNo no)
|
public override void ExecuteList(eListNo no)
|
||||||
{
|
{
|
||||||
// simulation 할때 값 반영 검토 필요
|
if (!_listClosed)
|
||||||
|
Log.W("ExecuteList called without SetEndList");
|
||||||
|
_listClosed = false; // 실행 시작하면서 다시 열림 상태로
|
||||||
|
|
||||||
|
_currentExecutingList = no;
|
||||||
|
|
||||||
|
if (no == eListNo.LIST1) {
|
||||||
|
_list1Busy = true;
|
||||||
|
_list2Busy = false;
|
||||||
|
} else {
|
||||||
|
_list2Busy = true;
|
||||||
|
_list1Busy = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_listStartMs = sw.ElapsedMilliseconds;
|
||||||
}
|
}
|
||||||
public override void StartLoop()
|
public override void StartLoop()
|
||||||
{
|
{
|
||||||
@ -304,16 +532,28 @@ namespace AuroraLaserScanner
|
|||||||
}
|
}
|
||||||
public override void AutoChange()
|
public override void AutoChange()
|
||||||
{
|
{
|
||||||
// simulation 할때 값 반영 검토 필요
|
if (_currentExecutingList == eListNo.NONE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_autoChangeRequested = true;
|
||||||
}
|
}
|
||||||
public override bool GetBusyStatus()
|
public override bool GetBusyStatus()
|
||||||
{
|
{
|
||||||
// simulation 할때 값 반영 검토 필요
|
return _list1Busy || _list2Busy || _currentExecutingList != eListNo.NONE;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
public override void StopExecution()
|
public override void StopExecution()
|
||||||
{
|
{
|
||||||
// simulation 할때 값 반영 검토 필요
|
_list1Busy = false;
|
||||||
|
_list2Busy = false;
|
||||||
|
_currentExecutingList = eListNo.NONE;
|
||||||
|
_autoChangeRequested = false;
|
||||||
|
_listStartMs = 0;
|
||||||
|
_listClosed = false;
|
||||||
|
|
||||||
|
_angleAbsDeg = 0.0;
|
||||||
|
|
||||||
|
_simEncXCount = 0;
|
||||||
|
_simEncYCount = 0;
|
||||||
}
|
}
|
||||||
public override uint GetRTCVersion()
|
public override uint GetRTCVersion()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,11 +1,15 @@
|
|||||||
using Aurora;
|
using Aurora;
|
||||||
|
using Aurora.Api;
|
||||||
using AuroraPLC;
|
using AuroraPLC;
|
||||||
|
using Hermes;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using WeldingCommon.Devices;
|
using WeldingCommon.Devices;
|
||||||
|
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Rebar;
|
||||||
|
|
||||||
namespace ILSOS_CCW_H52A.Device
|
namespace ILSOS_CCW_H52A.Device
|
||||||
{
|
{
|
||||||
@ -13,7 +17,183 @@ namespace ILSOS_CCW_H52A.Device
|
|||||||
{
|
{
|
||||||
public PLCControllerCCWH52A(string deviceId, ePLCNetType plcNetType, PLCMMapFileType fileType, IAuroraEnvironment aurora) : base(deviceId, plcNetType, fileType, aurora)
|
public PLCControllerCCWH52A(string deviceId, ePLCNetType plcNetType, PLCMMapFileType fileType, IAuroraEnvironment aurora) : base(deviceId, plcNetType, fileType, aurora)
|
||||||
{
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override int DoActivate(IDeviceConfig config)
|
||||||
|
{
|
||||||
|
var ret = base.DoActivate(config);
|
||||||
|
if (ret == E1.OK && IsSimul) {
|
||||||
|
//WriteBit((int)eBitInput.PLC_AUTO_STATUS, true, ePLCDevice.B, false);
|
||||||
|
//WriteBit((int)eBitInput.PLC_AUTO_REQ, true, ePLCDevice.B, false);
|
||||||
|
SetMonitoringService(EquipmentSimulator, 1);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override int DoDeactivate()
|
||||||
|
{
|
||||||
|
StopMonitoringService();
|
||||||
|
|
||||||
|
var res = base.DoDeactivate();
|
||||||
|
|
||||||
|
if (res != E1.OK) {
|
||||||
|
Log.E("Deactivate is failed");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------
|
||||||
|
// Simulation state
|
||||||
|
// -----------------------------
|
||||||
|
private const int PLC_CURRENT_POS_1_ADDR = 4; // 기존 (mod 0~360)
|
||||||
|
|
||||||
|
private readonly Random _rand = new Random();
|
||||||
|
|
||||||
|
private readonly Stopwatch _sw = Stopwatch.StartNew();
|
||||||
|
private long _lastMs = -1;
|
||||||
|
|
||||||
|
private const int RotaryJigCount = 16;
|
||||||
|
private const double JigPerMsec = 300;
|
||||||
|
private const double DegreePerRev = 360.0;
|
||||||
|
private const double OneCycleMsec = JigPerMsec * RotaryJigCount;
|
||||||
|
private const double DegreePerMsec = DegreePerRev / OneCycleMsec;
|
||||||
|
private const double DegreePerJig = DegreePerRev / RotaryJigCount; // 22.5
|
||||||
|
private const double HalfDegreePerJig = DegreePerJig / 2.0; // 11.25
|
||||||
|
|
||||||
|
// PLC_CURRENT_POS_1 = degree * 100000
|
||||||
|
private const double PlcAngleScale = 100_000.0;
|
||||||
|
|
||||||
|
// 시퀀스가 "다음 지그"를 미리 읽으므로 안전하게 2칸 선행(권장)
|
||||||
|
private const int LeadSectors = 2;
|
||||||
|
|
||||||
|
// Motor position
|
||||||
|
private readonly object _absLock = new object();
|
||||||
|
public double GetSimAbsDeg()
|
||||||
|
{
|
||||||
|
long value = System.Threading.Interlocked.Read(ref _angleAbsDeg);
|
||||||
|
return value / 100000.0;
|
||||||
|
}
|
||||||
|
private long _angleAbsDeg = 0; // 누적 각도(계속 증가)
|
||||||
|
|
||||||
|
private double _angleModDeg = 0.0; // 0~360 랩핑 각도
|
||||||
|
|
||||||
|
// PLC USE_WELD_JIG bits
|
||||||
|
private readonly bool[] _canExist = new bool[RotaryJigCount];
|
||||||
|
private readonly bool[] _decided = new bool[RotaryJigCount]; // 이번 회전에서 해당 섹터가 결정됐는지
|
||||||
|
private int _prevSector = -1;
|
||||||
|
|
||||||
|
private static void FillBool(bool[] arr, bool value)
|
||||||
|
{
|
||||||
|
if (arr == null)
|
||||||
|
return;
|
||||||
|
for (int i = 0; i < arr.Length; i++)
|
||||||
|
arr[i] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int Mod(int x, int m)
|
||||||
|
{
|
||||||
|
int r = x % m;
|
||||||
|
return (r < 0) ? (r + m) : r;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetSectorFromAngle(double angleDeg)
|
||||||
|
{
|
||||||
|
// 시퀀스의 (angle + half)/per와 동일한 기준으로 섹터 결정
|
||||||
|
return (int)((angleDeg + HalfDegreePerJig) / DegreePerJig) % RotaryJigCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnSectorChanged(int prev, int curr)
|
||||||
|
{
|
||||||
|
// 첫 진입
|
||||||
|
if (prev < 0) {
|
||||||
|
// 처음 시작 시에는 전부 OFF 상태에서 시작
|
||||||
|
FillBool(_canExist, false);
|
||||||
|
FillBool(_decided, false);
|
||||||
|
} else {
|
||||||
|
// 랩(15 -> 0) 감지: 새 바퀴 시작으로 보고 "지나간 영역 OFF"를 강하게 반영
|
||||||
|
if (prev == RotaryJigCount - 1 && curr == 0) {
|
||||||
|
FillBool(_canExist, false);
|
||||||
|
FillBool(_decided, false);
|
||||||
|
} else {
|
||||||
|
// 지나간 섹터(prev)는 OFF 처리
|
||||||
|
_canExist[prev] = false;
|
||||||
|
_decided[prev] = false; // 다음 회전에서 다시 결정되도록
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 시퀀스는 "다음 지그"를 읽으므로 curr+1부터 선행 결정
|
||||||
|
for (int k = 1; k <= LeadSectors; k++) {
|
||||||
|
int s = Mod(curr + k, RotaryJigCount);
|
||||||
|
|
||||||
|
if (!_decided[s]) {
|
||||||
|
// 7/8 확률 ON (0~7 중 0만 OFF로 만들려면 >0)
|
||||||
|
bool isCanExist = true;// (_rand.Next(0, 8) > 0);
|
||||||
|
_canExist[s] = isCanExist;
|
||||||
|
_decided[s] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 현재 섹터(curr)도 켜고 싶다면 여기서 결정 가능
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EquipmentSimulator()
|
||||||
|
{
|
||||||
|
if (!ReadBit((int)eBitOutput.PC_AUTO_STATUS, ePLCDevice.B, false).data)
|
||||||
|
return;
|
||||||
|
|
||||||
|
long now = _sw.ElapsedMilliseconds;
|
||||||
|
if (_lastMs < 0)
|
||||||
|
_lastMs = now;
|
||||||
|
|
||||||
|
long dtMs = now - _lastMs;
|
||||||
|
if (dtMs < 0)
|
||||||
|
dtMs = 0;
|
||||||
|
|
||||||
|
if (dtMs > 100)
|
||||||
|
dtMs = 100;
|
||||||
|
|
||||||
|
_lastMs = now;
|
||||||
|
|
||||||
|
// abs 누적각 (시뮬 전용)
|
||||||
|
long deltaScaled = (long)Math.Round(DegreePerMsec * dtMs * 100000.0);
|
||||||
|
System.Threading.Interlocked.Add(ref _angleAbsDeg, deltaScaled);
|
||||||
|
|
||||||
|
double absDeg = GetSimAbsDeg();
|
||||||
|
_angleModDeg = absDeg % DegreePerRev;
|
||||||
|
if (_angleModDeg < 0)
|
||||||
|
_angleModDeg += DegreePerRev;
|
||||||
|
|
||||||
|
// mod 각도
|
||||||
|
int plcAngleMod = (int)Math.Round(_angleModDeg * PlcAngleScale);
|
||||||
|
WriteDWord(PLC_CURRENT_POS_1_ADDR, plcAngleMod, ePLCDevice.W, false);
|
||||||
|
|
||||||
|
// 섹터 변경/비트 처리 로직은 기존 그대로
|
||||||
|
int sectorNow = GetSectorFromAngle(_angleModDeg);
|
||||||
|
if (sectorNow != _prevSector) {
|
||||||
|
OnSectorChanged(_prevSector, sectorNow);
|
||||||
|
_prevSector = sectorNow;
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteBitBlock((int)eBitInput.PLC_USE_WELD_JIG_1, RotaryJigCount, _canExist, ePLCDevice.B, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResetSimulator()
|
||||||
|
{
|
||||||
|
_lastMs = -1;
|
||||||
|
System.Threading.Interlocked.Exchange(ref _angleAbsDeg, 0);
|
||||||
|
_angleModDeg = 0.0;
|
||||||
|
|
||||||
|
FillBool(_canExist, false);
|
||||||
|
FillBool(_decided, false);
|
||||||
|
_prevSector = -1;
|
||||||
|
|
||||||
|
// 각도 초기화 반영
|
||||||
|
WriteDWord(PLC_CURRENT_POS_1_ADDR, 0, ePLCDevice.W, false);
|
||||||
|
|
||||||
|
// 지그 비트 초기화 반영
|
||||||
|
WriteBitBlock((int)eBitInput.PLC_USE_WELD_JIG_1, RotaryJigCount, _canExist, ePLCDevice.B, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
66
Machines/ILSOS_CCW_H52A/Device/Scanner/ScannerCCWH52A.cs
Normal file
66
Machines/ILSOS_CCW_H52A/Device/Scanner/ScannerCCWH52A.cs
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
using Aurora;
|
||||||
|
using Aurora.Api;
|
||||||
|
using AuroraLaserScanner;
|
||||||
|
using Hermes;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using WeldingCommon;
|
||||||
|
using static ILSOS_CCW_H52A.Device.PLCControllerCCWH52A;
|
||||||
|
|
||||||
|
namespace ILSOS_CCW_H52A.Device
|
||||||
|
{
|
||||||
|
public class ScannerCCWH52A : Scanner
|
||||||
|
{
|
||||||
|
// -----------------------------
|
||||||
|
// Simulation state
|
||||||
|
// -----------------------------
|
||||||
|
private PLCControllerCCWH52A _plc;
|
||||||
|
|
||||||
|
public ScannerCCWH52A(string deviceId) : base(deviceId)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override int DoActivate(IDeviceConfig config)
|
||||||
|
{
|
||||||
|
var ret = base.DoActivate(config);
|
||||||
|
if (ret == E1.OK && IsSimul) {
|
||||||
|
if (_plc == null) {
|
||||||
|
_plc = Application.Current.AuroraEnv().DeviceManager[CommonDeviceIds.PLCDevice] as PLCControllerCCWH52A;
|
||||||
|
return E2.ABORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 값의 동기화가 필요해서 추가 함
|
||||||
|
if (!_plc.IsConnected && !_plc.IsSimul)
|
||||||
|
return E2.ABORTED;
|
||||||
|
|
||||||
|
var core = _scannerObj as ScannerSimul;
|
||||||
|
core.PLCReadBit = _plc.ReadBit;
|
||||||
|
core.PLCReadWord = _plc.ReadWord;
|
||||||
|
core.PLCReadDWord = _plc.ReadDWord;
|
||||||
|
core.PLCGetAbsDeg = _plc.GetSimAbsDeg;
|
||||||
|
//_plc.ResetSimulator();
|
||||||
|
core.ResetSim();
|
||||||
|
core.TrySyncAbsAngleToPlcNow();
|
||||||
|
|
||||||
|
SetMonitoringService((_scannerObj as ScannerSimul).EquipmentSimulator, 1);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override int DoDeactivate()
|
||||||
|
{
|
||||||
|
var ret = base.DoDeactivate();
|
||||||
|
if (ret == E1.OK && IsSimul){
|
||||||
|
var core = _scannerObj as ScannerSimul;
|
||||||
|
StopMonitoringService();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -11,6 +11,7 @@ using AuroraCellTracker.Views;
|
|||||||
using AuroraIO;
|
using AuroraIO;
|
||||||
using AuroraIO.View;
|
using AuroraIO.View;
|
||||||
using AuroraLaser;
|
using AuroraLaser;
|
||||||
|
using AuroraLaserScanner;
|
||||||
using AuroraLBAD;
|
using AuroraLBAD;
|
||||||
using AuroraLBAD.Services;
|
using AuroraLBAD.Services;
|
||||||
using AuroraOCT;
|
using AuroraOCT;
|
||||||
@ -153,6 +154,8 @@ namespace ILSOS_CCW_H52A
|
|||||||
() => _plc, PLCMelsecNetConfig.GetDefaultConfig(),
|
() => _plc, PLCMelsecNetConfig.GetDefaultConfig(),
|
||||||
device => new UCPLCDevice() { DataContext = new UCPLCDeviceViewModel(AuroraEnv, _plc) });
|
device => new UCPLCDevice() { DataContext = new UCPLCDeviceViewModel(AuroraEnv, _plc) });
|
||||||
|
|
||||||
|
registry.Register(CommonDeviceIds.Scanner, () => new ScannerCCWH52A(CommonDeviceIds.Scanner), new ScannerConfig());
|
||||||
|
|
||||||
var ioController = new IOController_CCW_H52A(AuroraEnv, CommonDeviceIds.IODevice);
|
var ioController = new IOController_CCW_H52A(AuroraEnv, CommonDeviceIds.IODevice);
|
||||||
registry.Register(CommonDeviceIds.IODevice, () => ioController, new IOUnitConfig());
|
registry.Register(CommonDeviceIds.IODevice, () => ioController, new IOUnitConfig());
|
||||||
|
|
||||||
|
|||||||
@ -98,6 +98,7 @@
|
|||||||
<Compile Include="Device\PLC\PLCContoller.Config.cs" />
|
<Compile Include="Device\PLC\PLCContoller.Config.cs" />
|
||||||
<Compile Include="Device\PLC\PLCController.Address.cs" />
|
<Compile Include="Device\PLC\PLCController.Address.cs" />
|
||||||
<Compile Include="Device\PLC\PLCController.Logic.cs" />
|
<Compile Include="Device\PLC\PLCController.Logic.cs" />
|
||||||
|
<Compile Include="Device\Scanner\ScannerCCWH52A.cs" />
|
||||||
<Compile Include="Device\Scanner\ScannerList.cs" />
|
<Compile Include="Device\Scanner\ScannerList.cs" />
|
||||||
<Compile Include="EquipDef.cs" />
|
<Compile Include="EquipDef.cs" />
|
||||||
<Compile Include="EquipmentSetup.cs" />
|
<Compile Include="EquipmentSetup.cs" />
|
||||||
@ -105,6 +106,7 @@
|
|||||||
<Compile Include="Recipes\RecipeEventHelper.cs" />
|
<Compile Include="Recipes\RecipeEventHelper.cs" />
|
||||||
<Compile Include="RMS\EDC.cs" />
|
<Compile Include="RMS\EDC.cs" />
|
||||||
<Compile Include="Sequences\Monitoring\AlarmMonitoring.cs" />
|
<Compile Include="Sequences\Monitoring\AlarmMonitoring.cs" />
|
||||||
|
<Compile Include="Sequences\ProcessManager.cs" />
|
||||||
<Compile Include="Sequences\SeqAutoRunCCWH52A.cs" />
|
<Compile Include="Sequences\SeqAutoRunCCWH52A.cs" />
|
||||||
<Compile Include="Sequences\SequenceContextEx.cs" />
|
<Compile Include="Sequences\SequenceContextEx.cs" />
|
||||||
<Compile Include="Views\Main\UCMainAutoRun.xaml.cs">
|
<Compile Include="Views\Main\UCMainAutoRun.xaml.cs">
|
||||||
|
|||||||
115
Machines/ILSOS_CCW_H52A/Sequences/ProcessManager.cs
Normal file
115
Machines/ILSOS_CCW_H52A/Sequences/ProcessManager.cs
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
using Aurora;
|
||||||
|
using Aurora.Api;
|
||||||
|
using Aurora.Util.HislogPlus;
|
||||||
|
using AuroraLaserScanner;
|
||||||
|
using AuroraPLC;
|
||||||
|
using ILSOS_CCW_H52A.Device;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static ILSOS_CCW_H52A.Device.PLCControllerCCWH52A;
|
||||||
|
|
||||||
|
namespace ILSOS_CCW_H52A.Sequences
|
||||||
|
{
|
||||||
|
public class ProcessManager
|
||||||
|
{
|
||||||
|
private bool usedAnalyzerLog = false;
|
||||||
|
private readonly Logger _log = new Logger("ProcessManager");
|
||||||
|
|
||||||
|
public const double compensateEncoderReset = 0.015; // 엔코더 리셋 보상 각도 설정(70도/sec 기준 약 0.015도)
|
||||||
|
public const int RotaryJigCount = 16;
|
||||||
|
public const int RotaryMaxAngle = 360;
|
||||||
|
public double DegreePerJig { get => RotaryMaxAngle / RotaryJigCount; }
|
||||||
|
public double HalfDegreePerJig { get => DegreePerJig / 2; }
|
||||||
|
|
||||||
|
|
||||||
|
private readonly IAuroraEnvironment _env;
|
||||||
|
private readonly PLCControllerCCWH52A _plc;
|
||||||
|
private readonly Scanner _scanner;
|
||||||
|
|
||||||
|
public ProcessManager()
|
||||||
|
{
|
||||||
|
_plc = _env.DeviceManager[DeviceIds.PLCDevice] as PLCControllerCCWH52A;
|
||||||
|
_scanner = _env.DeviceManager[DeviceIds.Scanner] as Scanner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<bool> CheckRotaryState()
|
||||||
|
{
|
||||||
|
List<bool> rotaryStates = new List<bool>();
|
||||||
|
for (int i = 0; i < RotaryJigCount; i++) {
|
||||||
|
var rotaryProcessState = _plc.ReadBit(eBitInput.PLC_USE_WELD_JIG_1 + i).data;
|
||||||
|
rotaryStates.Add(rotaryProcessState);
|
||||||
|
|
||||||
|
if (rotaryProcessState == false)
|
||||||
|
_plc.ToggleBit(eBitInput.PLC_USE_WELD_JIG_1 + i, eBitOutput.PC_WELD_COMPLETE_1 + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usedAnalyzerLog) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
rotaryStates.ForEach(x => sb.Append($"{x} "));
|
||||||
|
_log.D($"Check Rotary State : {sb.ToString()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return rotaryStates;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GetRotaryCanExist(int jigNo)
|
||||||
|
{
|
||||||
|
//var RotaryStates = CheckRotaryState();
|
||||||
|
|
||||||
|
if (jigNo == 0)
|
||||||
|
jigNo = 1;
|
||||||
|
|
||||||
|
if (jigNo <= RotaryJigCount)
|
||||||
|
return _plc.ReadBit(eBitInput.PLC_USE_WELD_JIG_1 + (jigNo - 1)).data;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Rotary의 현재 위치정보를 0~360로 전달함
|
||||||
|
/// </summary>
|
||||||
|
public double GetRotaryCurrentPosition(bool isView360 = true)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
double finalValue = Convert.ToDouble(_plc.ReadDWord(eWordInput.PLC_CURRENT_POS_1).data / 100_000f);
|
||||||
|
finalValue += _scanner.Config.RotaryEncoderOffset;
|
||||||
|
|
||||||
|
if (isView360) {
|
||||||
|
if (RotaryMaxAngle <= finalValue) {
|
||||||
|
while (RotaryMaxAngle <= finalValue) {
|
||||||
|
finalValue -= RotaryMaxAngle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (finalValue < 0) {
|
||||||
|
while (finalValue < 0) {
|
||||||
|
finalValue += RotaryMaxAngle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return finalValue;
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
return -9999.9999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 중심 기준 가장 가까운 지그 번호(내림 연산)
|
||||||
|
/// <param name="HalfDegreePerJig">내림 카운팅을 중심 기준 값</param>
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int getCurrentJigNo() => (int)((GetRotaryCurrentPosition(isView360:true) + HalfDegreePerJig) / DegreePerJig) + 1;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 360도 이상으로 준다고하면 Welding Count를 가져올 수 있음 2word = 2147483.647 / 3600 = 596 >> 596*16 = 9_536까지 카운팅 가능함
|
||||||
|
/// <param name="HalfDegreePerJig">내림 카운팅을 중심 기준 값</param>
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int getWeldingCount() => (int)((GetRotaryCurrentPosition(isView360:false) + HalfDegreePerJig) / DegreePerJig);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -12,6 +12,7 @@ using CoreUnit.Control.UserControl.Canvas;
|
|||||||
using CoreUnit.Scanner.UserControl.ScannerCanvas;
|
using CoreUnit.Scanner.UserControl.ScannerCanvas;
|
||||||
using DB;
|
using DB;
|
||||||
using Hermes;
|
using Hermes;
|
||||||
|
using ILSOS_CCW_H52A.Device;
|
||||||
using ILSOS_CCW_H52A.Models;
|
using ILSOS_CCW_H52A.Models;
|
||||||
using ILSOS_CCW_H52A.RMS;
|
using ILSOS_CCW_H52A.RMS;
|
||||||
using System;
|
using System;
|
||||||
@ -49,14 +50,13 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
// TODO: [장비구현필요] 실제 공정 추가
|
// TODO: [장비구현필요] 실제 공정 추가
|
||||||
const string SEQ_CHECK_LOAD_COMPLETE = "[SeqAutoRunCCWH52A] Check Load Complete";
|
const string SEQ_CHECK_LOAD_COMPLETE = "[SeqAutoRunCCWH52A] Check Load Complete";
|
||||||
|
|
||||||
public const string SEQ_CHECK_SCANNER_LIST_COMPLETE = "[SeqAutoRunCCWH52A] Check Scanner List Complete";
|
|
||||||
|
|
||||||
const string SEQ_READY_SCANNER_LIST = "[SeqAutoRunCCWH52A] Ready ScannerList";
|
|
||||||
|
|
||||||
const string SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ = "[SeqAutoRunCCWH52A] Set Sequence Param (UploadWeldingList Seq)";
|
const string SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ = "[SeqAutoRunCCWH52A] Set Sequence Param (UploadWeldingList Seq)";
|
||||||
const string SEQ_DO_ID_UPLOAD_WELDING_LIST_SEQ = "[SeqAutoRunCCWH52A] Process (UploadWeldingList Seq)";
|
const string SEQ_DO_ID_UPLOAD_WELDING_LIST_SEQ = "[SeqAutoRunCCWH52A] Process (UploadWeldingList Seq)";
|
||||||
const string SEQ_GET_RESULT_UPLOAD_WELDING_LIST_SEQ = "[SeqAutoRunCCWH52A] Get Sequence Result (UploadWeldingList Seq)";
|
const string SEQ_GET_RESULT_UPLOAD_WELDING_LIST_SEQ = "[SeqAutoRunCCWH52A] Get Sequence Result (UploadWeldingList Seq)";
|
||||||
|
|
||||||
|
public const string SEQ_CHECK_SCANNER_LIST_COMPLETE = "[SeqAutoRunCCWH52A] Check Scanner List Complete";
|
||||||
|
const string SEQ_READY_SCANNER_LIST = "[SeqAutoRunCCWH52A] Ready ScannerList";
|
||||||
|
|
||||||
const string SEQ_SET_PARAMS_RECEIVE_CELL_INFO_SEQ = "[SeqAutoRunCCWH52A] Set Sequence Param (ReceiveCellInfo Seq)";
|
const string SEQ_SET_PARAMS_RECEIVE_CELL_INFO_SEQ = "[SeqAutoRunCCWH52A] Set Sequence Param (ReceiveCellInfo Seq)";
|
||||||
const string SEQ_DO_ID_RECEIVE_CELL_INFO_SEQ = "[SeqAutoRunCCWH52A] Process (ReceiveCellInfo Seq)";
|
const string SEQ_DO_ID_RECEIVE_CELL_INFO_SEQ = "[SeqAutoRunCCWH52A] Process (ReceiveCellInfo Seq)";
|
||||||
const string SEQ_GET_PARAMS_RECEIVE_CELL_INFO_SEQ = "[SeqAutoRunCCWH52A] Get Sequence Result (ReceiveCellInfo Seq)";
|
const string SEQ_GET_PARAMS_RECEIVE_CELL_INFO_SEQ = "[SeqAutoRunCCWH52A] Get Sequence Result (ReceiveCellInfo Seq)";
|
||||||
@ -91,7 +91,7 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
private Scanner _Scanner;
|
private Scanner _Scanner;
|
||||||
private LaserDevice _Laser;
|
private LaserDevice _Laser;
|
||||||
|
|
||||||
private PLCController _PLC;
|
private PLCControllerCCWH52A _PLC;
|
||||||
private IODevice _IO;
|
private IODevice _IO;
|
||||||
private StreamLightLBAD _StreamLightLBAD;
|
private StreamLightLBAD _StreamLightLBAD;
|
||||||
private static CellTracker _CellTracker;
|
private static CellTracker _CellTracker;
|
||||||
@ -173,6 +173,11 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
sb.AddJoin(SEQ_JOIN_ENCODER_MONITOR);
|
sb.AddJoin(SEQ_JOIN_ENCODER_MONITOR);
|
||||||
|
|
||||||
sb.AddAction(SEQ_CHECK_LOAD_COMPLETE, CheckLoadComplete);
|
sb.AddAction(SEQ_CHECK_LOAD_COMPLETE, CheckLoadComplete);
|
||||||
|
|
||||||
|
sb.AddAction(SEQ_SET_PARAMS_RECEIVE_CELL_INFO_SEQ, SetReceiveCellInfo_SeqParams); // Cell 정보를 받아와 입력한다.
|
||||||
|
sb.AddSubsequence(SEQ_DO_ID_RECEIVE_CELL_INFO_SEQ, SequenceManager.GetSeqBuilder_SeqReceiveCellInfo()); // cell 정보를 받아오는 Sub Seq 실행
|
||||||
|
sb.AddAction(SEQ_GET_PARAMS_RECEIVE_CELL_INFO_SEQ, GetReceiveCellInfo_SeqResult); // Cell 정보를 가져온다
|
||||||
|
|
||||||
sb.AddAction(SEQ_CHECK_SCANNER_LIST_COMPLETE, CheckScannerListComplete);
|
sb.AddAction(SEQ_CHECK_SCANNER_LIST_COMPLETE, CheckScannerListComplete);
|
||||||
sb.AddDecision(SEQ_READY_SCANNER_LIST, ReadyScannerList);
|
sb.AddDecision(SEQ_READY_SCANNER_LIST, ReadyScannerList);
|
||||||
|
|
||||||
@ -180,10 +185,6 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
sb.AddSubsequence(SEQ_DO_ID_UPLOAD_WELDING_LIST_SEQ, SequenceManager.GetSeqBuilder_SeqUploadWeldingList());
|
sb.AddSubsequence(SEQ_DO_ID_UPLOAD_WELDING_LIST_SEQ, SequenceManager.GetSeqBuilder_SeqUploadWeldingList());
|
||||||
sb.AddAction(SEQ_GET_RESULT_UPLOAD_WELDING_LIST_SEQ, GetUploadWeldingList_SeqResult);
|
sb.AddAction(SEQ_GET_RESULT_UPLOAD_WELDING_LIST_SEQ, GetUploadWeldingList_SeqResult);
|
||||||
|
|
||||||
sb.AddAction(SEQ_SET_PARAMS_RECEIVE_CELL_INFO_SEQ, SetReceiveCellInfo_SeqParams); // Cell 정보를 받아와 입력한다.
|
|
||||||
sb.AddSubsequence(SEQ_DO_ID_RECEIVE_CELL_INFO_SEQ, SequenceManager.GetSeqBuilder_SeqReceiveCellInfo()); // cell 정보를 받아오는 Sub Seq 실행
|
|
||||||
sb.AddAction(SEQ_GET_PARAMS_RECEIVE_CELL_INFO_SEQ, GetReceiveCellInfo_SeqResult); // Cell 정보를 가져온다
|
|
||||||
|
|
||||||
sb.AddAction(SEQ_EXECUTE_WELDING, ExecuteWelding);
|
sb.AddAction(SEQ_EXECUTE_WELDING, ExecuteWelding);
|
||||||
sb.AddAction(SEQ_REQUEST_UNLOAD_CELL, RequestUnloadCell);
|
sb.AddAction(SEQ_REQUEST_UNLOAD_CELL, RequestUnloadCell);
|
||||||
|
|
||||||
@ -270,19 +271,13 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
_SystemParameter = context.GetSetting<SystemParameter>(CommonSettingIds.SystemParameter);
|
_SystemParameter = context.GetSetting<SystemParameter>(CommonSettingIds.SystemParameter);
|
||||||
|
|
||||||
InitDev(context);
|
InitDev(context);
|
||||||
if (!CheckDeviceReady(context))
|
if (!CheckDeviceReady(context)) {
|
||||||
{ //Check Device
|
//Check Device
|
||||||
//AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_AutoRun_DeviceNotReady);
|
|
||||||
Log.E("The devices are not active.");
|
Log.E("The devices are not active.");
|
||||||
return SequenceAction.ForceStopByAlarm(AlarmCode.ALARM_SEQUENCE_AutoRun_DeviceNotReady);
|
return SequenceAction.ForceStopByAlarm(AlarmCode.ALARM_SEQUENCE_AutoRun_DeviceNotReady);
|
||||||
|
|
||||||
//return null;
|
|
||||||
}
|
}
|
||||||
if (InitSequenceVariable(context) == false)
|
if (InitSequenceVariable(context) == false) {
|
||||||
{
|
|
||||||
//AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_AutoRun_InitVariableError);
|
|
||||||
return SequenceAction.ForceStopByAlarm(AlarmCode.ALARM_SEQUENCE_AutoRun_InitVariableError);
|
return SequenceAction.ForceStopByAlarm(AlarmCode.ALARM_SEQUENCE_AutoRun_InitVariableError);
|
||||||
//return null;
|
|
||||||
}
|
}
|
||||||
Thread.Sleep(1); // 부하 방지
|
Thread.Sleep(1); // 부하 방지
|
||||||
return SequenceAction.Ok();
|
return SequenceAction.Ok();
|
||||||
@ -317,14 +312,13 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
//Device Init
|
//Device Init
|
||||||
_Scanner = context.GetLaserScanner();
|
_Scanner = context.GetLaserScanner();
|
||||||
_Laser = context.GetLaser();
|
_Laser = context.GetLaser();
|
||||||
if (_InitParam.UseStream)
|
if (_InitParam.UseStream) {
|
||||||
{
|
|
||||||
_StreamLightLBAD = new StreamLightLBAD();
|
_StreamLightLBAD = new StreamLightLBAD();
|
||||||
_StreamLightLBAD._Client = context.GetStreamLightClient();
|
_StreamLightLBAD._Client = context.GetStreamLightClient();
|
||||||
_StreamLightLBAD._Sub = context.GetStreamLightSub();
|
_StreamLightLBAD._Sub = context.GetStreamLightSub();
|
||||||
}
|
}
|
||||||
_CellTracker = context.GetCellTracker();
|
_CellTracker = context.GetCellTracker();
|
||||||
_PLC = context.GetPLC();
|
_PLC = context.Devices[DeviceIds.PLCDevice] as PLCControllerCCWH52A;
|
||||||
_IO = context.GetIOUnit();
|
_IO = context.GetIOUnit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,17 +326,14 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
{
|
{
|
||||||
List<string> deviceListToCheck = new List<string>() { CommonDeviceIds.Scanner, CommonDeviceIds.Laser, CommonDeviceIds.PLCDevice, CommonDeviceIds.IODevice };
|
List<string> deviceListToCheck = new List<string>() { CommonDeviceIds.Scanner, CommonDeviceIds.Laser, CommonDeviceIds.PLCDevice, CommonDeviceIds.IODevice };
|
||||||
|
|
||||||
if (_InitParam.UseStream)
|
if (_InitParam.UseStream) {
|
||||||
{
|
|
||||||
deviceListToCheck.Add(CommonServiceIds.StreamLightLBADClient);
|
deviceListToCheck.Add(CommonServiceIds.StreamLightLBADClient);
|
||||||
deviceListToCheck.Add(CommonServiceIds.StreamLightLBADSub);
|
deviceListToCheck.Add(CommonServiceIds.StreamLightLBADSub);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isAllDeviceActivated = true;
|
bool isAllDeviceActivated = true;
|
||||||
foreach (string item in deviceListToCheck)
|
foreach (string item in deviceListToCheck) {
|
||||||
{
|
if (!context.Devices[item].IsActivated) {
|
||||||
if (!context.Devices[item].IsActivated)
|
|
||||||
{
|
|
||||||
isAllDeviceActivated = isAllDeviceActivated && false;
|
isAllDeviceActivated = isAllDeviceActivated && false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -352,29 +343,14 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
|
|
||||||
private bool CheckCondition(SequenceContext context)
|
private bool CheckCondition(SequenceContext context)
|
||||||
{
|
{
|
||||||
if (CheckCondition_Interlock())
|
int InitializeCode = InitializeDeviceStatus(context);
|
||||||
{
|
if (InitializeCode == (int)InitErrorList.SUCCESS)
|
||||||
int InitializeCode = InitializeDeviceStatus(context);
|
return true;
|
||||||
if (InitializeCode == (int)InitErrorList.SUCCESS)
|
else
|
||||||
return true;
|
context.PutValue(ContextKey.KEY_SEQUENCE_ERROR_CODE, InitializeCode);
|
||||||
else
|
|
||||||
context.PutValue(ContextKey.KEY_SEQUENCE_ERROR_CODE, InitializeCode);
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CheckCondition_Interlock()
|
|
||||||
{
|
|
||||||
// PLC, Data, IO 등 Interlock checking
|
|
||||||
// Config checking
|
|
||||||
//if (_Scanner.Config.UseMarkingOnTheFly == false)
|
|
||||||
//{
|
|
||||||
// Log.E("ERROR Config Setting : Scanner Marking on the fly (OFF)");
|
|
||||||
// return false;
|
|
||||||
//}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int InitializeDeviceStatus(SequenceContext context)
|
private int InitializeDeviceStatus(SequenceContext context)
|
||||||
{
|
{
|
||||||
// PLC Interface AutoStatus Start
|
// PLC Interface AutoStatus Start
|
||||||
@ -384,32 +360,26 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
//InitAutoRunBit();
|
//InitAutoRunBit();
|
||||||
// LBAD Initialize
|
// LBAD Initialize
|
||||||
// LBAD 는 server 이기 때문에, 만약 끊어졌으면 다시 접속이 필요함
|
// LBAD 는 server 이기 때문에, 만약 끊어졌으면 다시 접속이 필요함
|
||||||
if (_SystemParameter.BypassModeLBAD == false)
|
if (_SystemParameter.BypassModeLBAD == false) {
|
||||||
{
|
if (!_StreamLightLBAD._Client.IsActivated) {
|
||||||
if (!_StreamLightLBAD._Client.IsActivated)
|
|
||||||
{
|
|
||||||
int ret = _StreamLightLBAD._Client.Activate();
|
int ret = _StreamLightLBAD._Client.Activate();
|
||||||
Thread.Sleep(500);
|
Thread.Sleep(500);
|
||||||
if (ret != E1.OK)
|
if (ret != E1.OK) {
|
||||||
{
|
|
||||||
Log.E($"StreamLightClient activate failed");
|
Log.E($"StreamLightClient activate failed");
|
||||||
return (int)InitErrorList.LBAD_CLIENT_ACTIVATE_FAILED;
|
return (int)InitErrorList.LBAD_CLIENT_ACTIVATE_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_StreamLightLBAD._Sub.IsActivated == false)
|
if (_StreamLightLBAD._Sub.IsActivated == false) {
|
||||||
{
|
|
||||||
int ret = _StreamLightLBAD._Sub.Activate();
|
int ret = _StreamLightLBAD._Sub.Activate();
|
||||||
Thread.Sleep(500);
|
Thread.Sleep(500);
|
||||||
if (ret != E1.OK)
|
if (ret != E1.OK) {
|
||||||
{
|
|
||||||
Log.E($"StreamLightSub activate failed");
|
Log.E($"StreamLightSub activate failed");
|
||||||
return (int)InitErrorList.LBAD_SUB_ACTIVATE_FAILED;
|
return (int)InitErrorList.LBAD_SUB_ACTIVATE_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_StreamLightLBAD.Initialize();
|
_StreamLightLBAD.Initialize();
|
||||||
if (_StreamLightLBAD.SendReadyStatus(eRequestData.Ready_On) == false)
|
if (_StreamLightLBAD.SendReadyStatus(eRequestData.Ready_On) == false) {
|
||||||
{
|
|
||||||
Log.I(string.Format($"[LBAD Interface]CheckReadyStatus null"));
|
Log.I(string.Format($"[LBAD Interface]CheckReadyStatus null"));
|
||||||
//return false;
|
//return false;
|
||||||
}
|
}
|
||||||
@ -419,18 +389,15 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
_Laser.PilotLaserOff();
|
_Laser.PilotLaserOff();
|
||||||
_Laser.LaserOn();
|
_Laser.LaserOn();
|
||||||
Thread.Sleep(500);
|
Thread.Sleep(500);
|
||||||
if (!_Laser.GetLaserReady())
|
if (!_Laser.GetLaserReady()) {
|
||||||
{
|
|
||||||
Log.E("ERROR Initialize Laser");
|
Log.E("ERROR Initialize Laser");
|
||||||
return (int)InitErrorList.LASER_INIT_ERROR;
|
return (int)InitErrorList.LASER_INIT_ERROR;
|
||||||
}
|
}
|
||||||
// Scanner Initialize
|
// Scanner Initialize
|
||||||
if (_Scanner.GetModulationMode())
|
if (_Scanner.GetModulationMode()) {
|
||||||
{
|
|
||||||
_ModulationMode = true;
|
_ModulationMode = true;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
_ModulationMode = false;
|
_ModulationMode = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -442,16 +409,14 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
Log.E(string.Format("ERROR Initialize PLC, PLC Alarm ON")); // AutoRun Request와 AutoRun Bit 모두 OFF인 경우, PLC 측에서 Alarm 발생함.
|
Log.E(string.Format("ERROR Initialize PLC, PLC Alarm ON")); // AutoRun Request와 AutoRun Bit 모두 OFF인 경우, PLC 측에서 Alarm 발생함.
|
||||||
return (int)InitErrorList.PLC_ALARM;
|
return (int)InitErrorList.PLC_ALARM;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
Log.E(string.Format("ERROR Initialize PLC, Bit Off PLC_AUTO_STATUS")); // AutoRun Request가 ON인데 AutoRun Bit 모두 OFF인 경우, PLC에서 AutoRun Bit를 켜지 않음.
|
Log.E(string.Format("ERROR Initialize PLC, Bit Off PLC_AUTO_STATUS")); // AutoRun Request가 ON인데 AutoRun Bit 모두 OFF인 경우, PLC에서 AutoRun Bit를 켜지 않음.
|
||||||
return (int)InitErrorList.PLC_AUTORUN_BIT_OFF;
|
return (int)InitErrorList.PLC_AUTORUN_BIT_OFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Marking On The Flying Off
|
// Marking On The Flying Off
|
||||||
if (_Scanner.Config.UseMarkingOnTheFly == false)
|
if (_Scanner.Config.UseMarkingOnTheFly == false) {
|
||||||
{
|
|
||||||
Log.E("ERROR Config Setting : Scanner Marking on the fly (OFF)");
|
Log.E("ERROR Config Setting : Scanner Marking on the fly (OFF)");
|
||||||
return (int)InitErrorList.MOTF_OFF;
|
return (int)InitErrorList.MOTF_OFF;
|
||||||
}
|
}
|
||||||
@ -497,46 +462,36 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
isTheSecondListWrite = false;
|
isTheSecondListWrite = false;
|
||||||
isTheFirstListExecute = true; // 제일 첫 List는 ExecuteList 필요. 이후는 AutoChange
|
isTheFirstListExecute = true; // 제일 첫 List는 ExecuteList 필요. 이후는 AutoChange
|
||||||
|
|
||||||
InitAutoRunBit(); // GetRotaryCurrentPosition() 호출 이후 AutoStatus True 변경
|
_PLC.WriteBit(eBitOutput.PC_AUTO_STATUS, true);
|
||||||
|
Log.I(string.Format($"[PLCInterface]SET PC_AUTO_STATUS True"));
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
return (int)InitErrorList.SUCCESS;
|
return (int)InitErrorList.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitAutoRunBit()
|
|
||||||
{
|
|
||||||
_PLC.WriteBit((int)eBitOutput.PC_AUTO_STATUS, true);
|
|
||||||
Log.I(string.Format($"[PLCInterface]SET PC_AUTO_STATUS True"));
|
|
||||||
}
|
|
||||||
|
|
||||||
private double GetRotaryCurrentPosition()
|
private double GetRotaryCurrentPosition()
|
||||||
{
|
{
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
//double finalValue = Convert.ToDouble(_plc.GetLongAIValue("PLC_CURRENT_POS_1") / 100000f);
|
//double finalValue = Convert.ToDouble(_plc.GetLongAIValue("PLC_CURRENT_POS_1") / 100000f);
|
||||||
double finalValue = Convert.ToDouble(_PLC.ReadDWord((int)eWordInput.PLC_CURRENT_POS_1).data / 100000f);
|
double finalValue = Convert.ToDouble(_PLC.ReadDWord((int)eWordInput.PLC_CURRENT_POS_1).data / 100000f);
|
||||||
|
|
||||||
finalValue += _Scanner.Config.RotaryEncoderOffset;
|
finalValue += _Scanner.Config.RotaryEncoderOffset;
|
||||||
|
|
||||||
if (360.0 <= finalValue)
|
if (360.0 <= finalValue) {
|
||||||
{
|
while (360.0 <= finalValue) {
|
||||||
while (360.0 <= finalValue)
|
|
||||||
{
|
|
||||||
finalValue -= 360.0;
|
finalValue -= 360.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (finalValue < 0)
|
else if (finalValue < 0) {
|
||||||
{
|
while (finalValue < 0) {
|
||||||
while (finalValue < 0)
|
|
||||||
{
|
|
||||||
finalValue += 360.0;
|
finalValue += 360.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return finalValue;
|
return finalValue;
|
||||||
}
|
}
|
||||||
catch
|
catch {
|
||||||
{
|
|
||||||
return -9999.9999;
|
return -9999.9999;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -560,8 +515,7 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
|
|
||||||
private string CheckInitCondition(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
|
private string CheckInitCondition(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
|
||||||
{
|
{
|
||||||
if (!CheckCondition(context))
|
if (!CheckCondition(context)) {
|
||||||
{
|
|
||||||
//AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_AutoRun_CheckInitCondition);
|
//AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_AutoRun_CheckInitCondition);
|
||||||
Log.E("Condition is not in state to start sequence.");
|
Log.E("Condition is not in state to start sequence.");
|
||||||
context.PutValue(ContextKey.KEY_SEQUENCE_RESULT, false);
|
context.PutValue(ContextKey.KEY_SEQUENCE_RESULT, false);
|
||||||
@ -586,29 +540,18 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
{
|
{
|
||||||
Status.SetWorkingPosition(eWorkingPosition.LOADING_CELL);
|
Status.SetWorkingPosition(eWorkingPosition.LOADING_CELL);
|
||||||
|
|
||||||
// MOTF WaitScannerLoadListEnable
|
// MOTF WaitScannerLoadListEnable
|
||||||
// List가 실행 중이라면(ex : 엔코더 대기 상태 등), 반환값은 0, LoadList 할 수 없는 상태(List 실행 중이거나, 엔코더 대기 상태)
|
// List가 실행 중이라면(ex : 엔코더 대기 상태 등), 반환값은 0, LoadList 할 수 없는 상태(List 실행 중이거나, 엔코더 대기 상태)
|
||||||
// LoadList가 0보다 크면 다음 시퀀스 진행해야 함
|
// LoadList가 0보다 크면 다음 시퀀스 진행해야 함
|
||||||
_InterfaceStartTime = DateTime.Now;
|
WaitContinue:
|
||||||
while (!context.Stopped)
|
var ret = context.RetryUntilSuccess(() => _Scanner.LoadList(_WeldingScannerListNo) > 0, int.MaxValue, 10, true);
|
||||||
{
|
if (ret == E2.TIMEOUT) {
|
||||||
if (_Scanner.LoadList(_WeldingScannerListNo) > 0)
|
Log.E("TIMEOUT_Scanner_LoadList : 600시간 Run");
|
||||||
{
|
goto WaitContinue;
|
||||||
// List가 실행 상태가 아니라면(ex : 시작을 안 했거나, 완료되었으면) 반환값은 1 또는 2(리스트 번호)
|
|
||||||
Log.I(string.Format($"LoadList function success : List {_WeldingScannerListNo}"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
_InterfaceSpanTime = DateTime.Now.Subtract(_InterfaceStartTime);
|
|
||||||
if (_InterfaceSpanTime.TotalMilliseconds > (PLC_TIMEOUT * 1000))
|
|
||||||
{
|
|
||||||
Log.E("TIMEOUT_Scanner_LoadList");
|
|
||||||
_InterfaceStartTime = DateTime.Now;
|
|
||||||
}
|
|
||||||
Thread.Sleep(10);
|
|
||||||
}
|
}
|
||||||
Thread.Sleep(1); // 부하 방지
|
|
||||||
|
|
||||||
|
Log.I($"LoadList function success : List {_WeldingScannerListNo}");
|
||||||
|
Thread.Sleep(1); // 부하 방지
|
||||||
return SequenceAction.Ok();
|
return SequenceAction.Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -620,22 +563,19 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
Log.I("Write the 1st scanner list");
|
Log.I("Write the 1st scanner list");
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
if (isTheSecondListWrite) // 두번째 리스트는 바로 쓰지만, 첫번째 리스트 실행이 완료되면 자동으로 이어서 실행된다(AutoChange)
|
if (isTheSecondListWrite) // 두번째 리스트는 바로 쓰지만, 첫번째 리스트 실행이 완료되면 자동으로 이어서 실행된다(AutoChange)
|
||||||
{
|
{
|
||||||
isTheSecondListWrite = false;
|
isTheSecondListWrite = false;
|
||||||
Log.I("Write the 2nd scanner list");
|
Log.I("Write the 2nd scanner list");
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
isWeled = false;
|
isWeled = false;
|
||||||
// 첫번째나 두번째가 아니라면, 실제 리스트 실행이 끝난 것이기 때문에 완료 처리가 필요
|
// 첫번째나 두번째가 아니라면, 실제 리스트 실행이 끝난 것이기 때문에 완료 처리가 필요
|
||||||
CompleteScannerList = InputScannerList[(int)_WeldingScannerListNo - 1];
|
CompleteScannerList = InputScannerList[(int)_WeldingScannerListNo - 1];
|
||||||
|
|
||||||
if (!CheckCurrentEncoderAngle(CompleteScannerList.StartAngle))
|
if (!CheckCurrentEncoderAngle(CompleteScannerList.StartAngle)) {
|
||||||
{
|
|
||||||
// 에러 상황(현재 Rotary Encoder 값이 정상적인 스캐너 리스트 각도 범위를 벗어남)
|
// 에러 상황(현재 Rotary Encoder 값이 정상적인 스캐너 리스트 각도 범위를 벗어남)
|
||||||
Log.I("ERR_SCANNER_LIST_PROCESSING_TIMEOVER");
|
Log.I("ERR_SCANNER_LIST_PROCESSING_TIMEOVER");
|
||||||
|
|
||||||
@ -651,10 +591,8 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
// }
|
// }
|
||||||
// return SequenceAction.Ok();
|
// return SequenceAction.Ok();
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
if (CompleteScannerList.CanExist) {
|
||||||
if (CompleteScannerList.CanExist)
|
|
||||||
{
|
|
||||||
isWeled = true;
|
isWeled = true;
|
||||||
#region 용접 시간, 엔코더 측정/기록
|
#region 용접 시간, 엔코더 측정/기록
|
||||||
//_WeldInterval = DateTime.Now - _WeldEndTime;
|
//_WeldInterval = DateTime.Now - _WeldEndTime;
|
||||||
@ -665,8 +603,7 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
|
|
||||||
double elaspedTime = _Scanner.GetTime();
|
double elaspedTime = _Scanner.GetTime();
|
||||||
|
|
||||||
if (CompleteScannerList.WeldComplete)
|
if (CompleteScannerList.WeldComplete) {
|
||||||
{
|
|
||||||
_WeldInterval = DateTime.Now - _WeldEndTime;
|
_WeldInterval = DateTime.Now - _WeldEndTime;
|
||||||
_WeldEndTime = DateTime.Now;
|
_WeldEndTime = DateTime.Now;
|
||||||
_WeldingStartTime = CompleteScannerList.WeldStartTime;
|
_WeldingStartTime = CompleteScannerList.WeldStartTime;
|
||||||
@ -677,8 +614,7 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
Log.I(string.Format("JigNo : {0}, Weld start : {1}, Weld End : {2}, WeldTime : {3}, interval : {4:F3}",
|
Log.I(string.Format("JigNo : {0}, Weld start : {1}, Weld End : {2}, WeldTime : {3}, interval : {4:F3}",
|
||||||
CompleteScannerList.JigNo, _WeldingStartTime.ToString("HH:mm:ss.fff"), _WeldEndTime.ToString("HH:mm:ss.fff"), _WeldingSpanTime.TotalMilliseconds, _WeldInterval.TotalSeconds));
|
CompleteScannerList.JigNo, _WeldingStartTime.ToString("HH:mm:ss.fff"), _WeldEndTime.ToString("HH:mm:ss.fff"), _WeldingSpanTime.TotalMilliseconds, _WeldInterval.TotalSeconds));
|
||||||
|
|
||||||
if (_PLC.ReadBit((int)eBitInput.PLC_USE_WELD_JIG_1 + CompleteScannerList.JigNo - 1).data)
|
if (_PLC.ReadBit((int)eBitInput.PLC_USE_WELD_JIG_1 + CompleteScannerList.JigNo - 1).data) {
|
||||||
{
|
|
||||||
_PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE_1 + CompleteScannerList.JigNo - 1, true);
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE_1 + CompleteScannerList.JigNo - 1, true);
|
||||||
Log.I(string.Format($"PC_WELD_COMPLETE_{CompleteScannerList.JigNo} -> true)"));
|
Log.I(string.Format($"PC_WELD_COMPLETE_{CompleteScannerList.JigNo} -> true)"));
|
||||||
}
|
}
|
||||||
@ -707,8 +643,7 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
Log.I(string.Format("Encoder start : {0:F4}, end : {1:F4}, vel : {2:F2}", startEncoderCount, endEncoderCount, angularVelocity));
|
Log.I(string.Format("Encoder start : {0:F4}, end : {1:F4}, vel : {2:F2}", startEncoderCount, endEncoderCount, angularVelocity));
|
||||||
#endregion
|
#endregion
|
||||||
#region 스캐너 리스트 Record 파일 기록
|
#region 스캐너 리스트 Record 파일 기록
|
||||||
if (_Scanner.Config.UseRecordSignal)
|
if (_Scanner.Config.UseRecordSignal) {
|
||||||
{
|
|
||||||
String RecordFileName = _RecipeManager.ActivatedRecipe().Name + "_Jig#" + CompleteScannerList.JigNo.ToString();
|
String RecordFileName = _RecipeManager.ActivatedRecipe().Name + "_Jig#" + CompleteScannerList.JigNo.ToString();
|
||||||
string DataFilePath = ProjectUtil.GetDataLogSetting().GetFilePath_ScannerRecordLog(RecordFileName, true);
|
string DataFilePath = ProjectUtil.GetDataLogSetting().GetFilePath_ScannerRecordLog(RecordFileName, true);
|
||||||
_Scanner.SaveRecord(DataFilePath);
|
_Scanner.SaveRecord(DataFilePath);
|
||||||
@ -727,20 +662,18 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
|
|
||||||
_Scanner.GetEncoder(out encoderX, out currentAngle, true);
|
_Scanner.GetEncoder(out encoderX, out currentAngle, true);
|
||||||
|
|
||||||
if (0 < startAngle && currentAngle < 0)
|
if (0 < startAngle && currentAngle < 0) {
|
||||||
{
|
|
||||||
// Encoder 반전되는 순간이며, 이 때만 인터락 무시
|
// Encoder 반전되는 순간이며, 이 때만 인터락 무시
|
||||||
}
|
}
|
||||||
else if (startAngle <= currentAngle)
|
else if (startAngle <= currentAngle) {
|
||||||
{
|
|
||||||
if (currentAngle < startAngle + 45)// 다음 리스트 구간이 끝나기 전까지는 완료가 되어야 한다
|
if (currentAngle < startAngle + 45)// 다음 리스트 구간이 끝나기 전까지는 완료가 되어야 한다
|
||||||
{
|
{
|
||||||
Log.I(string.Format("Current encoder check OK, startAngle : {0}, currentAngle : {1})", startAngle, currentAngle));
|
Log.I(string.Format("Current encoder check OK, startAngle : {0}, currentAngle : {1})", startAngle, currentAngle));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else Log.I(string.Format("Current encoder check NG(Too late), startAngle : {0}, currentAngle : {1})", startAngle, currentAngle));
|
else Log.W(string.Format("Current encoder check NG(Too late), startAngle : {0}, currentAngle : {1})", startAngle, currentAngle));
|
||||||
}
|
}
|
||||||
else Log.I(string.Format("Current encoder check NG(Too early), startAngle : {0}, currentAngle : {1})", startAngle, currentAngle));
|
else Log.W(string.Format("Current encoder check NG(Too early), startAngle : {0}, currentAngle : {1})", startAngle, currentAngle));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -783,8 +716,7 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
|
|
||||||
bool canExist; // 지그 용접 수행 여부 확인
|
bool canExist; // 지그 용접 수행 여부 확인
|
||||||
|
|
||||||
if (UsePlcShotThemAll)
|
if (UsePlcShotThemAll) {
|
||||||
{
|
|
||||||
canExist = true;
|
canExist = true;
|
||||||
Log.I("Settings - PLC : Shot Them All Mode");
|
Log.I("Settings - PLC : Shot Them All Mode");
|
||||||
}
|
}
|
||||||
@ -793,40 +725,13 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
|
|
||||||
Log.I("Can Exist : " + canExist.ToString() + ", JigNo " + _WeldingJigNo + " ,CountNo " + _WeldingCount + ", StartAngle(Y) : " + _WeldingStartAngle);
|
Log.I("Can Exist : " + canExist.ToString() + ", JigNo " + _WeldingJigNo + " ,CountNo " + _WeldingCount + ", StartAngle(Y) : " + _WeldingStartAngle);
|
||||||
|
|
||||||
// 입력한 Scanner List를 완료대기열에 추가
|
if (canExist) {
|
||||||
//SetInputScannerList(_WeldingScannerListNo, DateTime.Now, _WeldingCount, _WeldingStartAngle, _WeldingJigNo, _RotaryJigCount, canExist);
|
|
||||||
|
|
||||||
//if (canExist) // Can이 존재할 경우만 리스트 안에 내용이 들어가며, 그렇지 않은 경우는 빈 리스트가 된다
|
|
||||||
//{
|
|
||||||
// #region 용접할 Objects 선택
|
|
||||||
// if (UsePlcPositionCompensation && _WeldingJigNo - 1 < _ScannerCanvasUserCtrl.Model.Layers.Length) {
|
|
||||||
// _SelectedDrawObjectList = _ScannerCanvasUserCtrl.Model.Layers[_WeldingJigNo - 1].Objects;
|
|
||||||
// Log.I(string.Format("Page 불러오기 : [{0}])", _WeldingJigNo - 1));
|
|
||||||
// } else {
|
|
||||||
// _SelectedDrawObjectList = _ScannerCanvasUserCtrl.Model.Layers[0].Objects;
|
|
||||||
// Log.I(string.Format("Page 불러오기 : [0])"));
|
|
||||||
// }
|
|
||||||
// #endregion
|
|
||||||
|
|
||||||
// // 여기서 어디로 가는지 설정 필요함
|
|
||||||
// return SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//// 기존 소스는 UploadWeldingList 건너 뛰고 SEQ_EXECUTE_WELDING 으로 바로 감
|
|
||||||
//// SEQ_WAIT_WELDING_START 의 기능이 어떻게 되는 지 확인 후
|
|
||||||
//// 건너뛰어도 되면 SEQ_EXECUTE_WELDING 으로 변경 해도 됨
|
|
||||||
//return SEQ_WAIT_WELDING_START;
|
|
||||||
|
|
||||||
if (canExist)
|
|
||||||
{
|
|
||||||
#region 용접할 Objects 선택
|
#region 용접할 Objects 선택
|
||||||
if (_WeldingJigNo - 1 < _ScannerCanvasUserCtrl.Model.Layers.Length)
|
if (_WeldingJigNo - 1 < _ScannerCanvasUserCtrl.Model.Layers.Length) {
|
||||||
{
|
|
||||||
_SelectedDrawObjectList = _ScannerCanvasUserCtrl.Model.Layers[_WeldingJigNo - 1].Objects;
|
_SelectedDrawObjectList = _ScannerCanvasUserCtrl.Model.Layers[_WeldingJigNo - 1].Objects;
|
||||||
Log.I(string.Format("Page 불러오기 : [{0}])", _WeldingJigNo - 1));
|
Log.I(string.Format("Page 불러오기 : [{0}])", _WeldingJigNo - 1));
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
_SelectedDrawObjectList = _ScannerCanvasUserCtrl.Model.Layers[0].Objects;
|
_SelectedDrawObjectList = _ScannerCanvasUserCtrl.Model.Layers[0].Objects;
|
||||||
Log.I(string.Format("Page 불러오기 : [0])"));
|
Log.I(string.Format("Page 불러오기 : [0])"));
|
||||||
}
|
}
|
||||||
@ -840,12 +745,11 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
_RecipeNo = _RecipeManager.ActivatedRecipe().Id;
|
_RecipeNo = _RecipeManager.ActivatedRecipe().Id;
|
||||||
|
|
||||||
SetWeldingData();
|
SetWeldingData();
|
||||||
|
return SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
return SEQ_EXECUTE_WELDING;
|
return SEQ_EXECUTE_WELDING;
|
||||||
}
|
}
|
||||||
return SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ;
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -865,8 +769,7 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
ScannerParam laserParam = null;
|
ScannerParam laserParam = null;
|
||||||
laserParam = GetSelectedDrawObjectData(_SelectedDrawObjectList[0]);
|
laserParam = GetSelectedDrawObjectData(_SelectedDrawObjectList[0]);
|
||||||
|
|
||||||
if (laserParam != null)
|
if (laserParam != null) {
|
||||||
{
|
|
||||||
// EDC 보내는 용도
|
// EDC 보내는 용도
|
||||||
Status.GetProcessingWeldingData().LaserPowerCore = laserParam.LaserPower1.ToString();
|
Status.GetProcessingWeldingData().LaserPowerCore = laserParam.LaserPower1.ToString();
|
||||||
Status.GetProcessingWeldingData().MarkSpeed = laserParam.MarkSpeed.ToString();
|
Status.GetProcessingWeldingData().MarkSpeed = laserParam.MarkSpeed.ToString();
|
||||||
@ -895,8 +798,7 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
// 1.2. 계산된 시작각도가 이미 지나버렸으면 알람 발생 필요
|
// 1.2. 계산된 시작각도가 이미 지나버렸으면 알람 발생 필요
|
||||||
|
|
||||||
// 1.3. Overflow가 나는 숫자라면, 보상할 것.
|
// 1.3. Overflow가 나는 숫자라면, 보상할 것.
|
||||||
if (sectionStartAngle > encoderAllowedMaxDegree)
|
if (sectionStartAngle > encoderAllowedMaxDegree) {
|
||||||
{
|
|
||||||
sectionStartAngle -= encoderAllowedMaxDegree - encoderAllowedMinDegree;
|
sectionStartAngle -= encoderAllowedMaxDegree - encoderAllowedMinDegree;
|
||||||
_EncoderOverflowCount++;
|
_EncoderOverflowCount++;
|
||||||
}
|
}
|
||||||
@ -911,18 +813,15 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
#region 지그 16개 요청기록 로그 남기기, 빠져나간 캔에 대한 Complete Bit 초기화
|
#region 지그 16개 요청기록 로그 남기기, 빠져나간 캔에 대한 Complete Bit 초기화
|
||||||
string result = "";
|
string result = "";
|
||||||
|
|
||||||
for (int i = 1; i <= _RotaryJigCount; i++)
|
for (int i = 1; i <= _RotaryJigCount; i++) {
|
||||||
{
|
|
||||||
if (_PLC.ReadBit((int)eBitInput.PLC_USE_WELD_JIG_1 + i).data)
|
if (_PLC.ReadBit((int)eBitInput.PLC_USE_WELD_JIG_1 + i).data)
|
||||||
result += "1, ";
|
result += "1, ";
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
result += "0, ";
|
result += "0, ";
|
||||||
|
|
||||||
string outId = string.Format("PC_WELD_COMPLETE_{0}", i);
|
string outId = string.Format("PC_WELD_COMPLETE_{0}", i);
|
||||||
|
|
||||||
if (_PLC.ReadBit((int)eBitInput.PLC_USE_WELD_JIG_1 + i).data)
|
if (_PLC.ReadBit((int)eBitInput.PLC_USE_WELD_JIG_1 + i).data) {
|
||||||
{
|
|
||||||
_PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE_1 + i, false);
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE_1 + i, false);
|
||||||
Log.I(string.Format($"PC_WELD_COMPLETE_{1 + i} -> FALSE)"));
|
Log.I(string.Format($"PC_WELD_COMPLETE_{1 + i} -> FALSE)"));
|
||||||
}
|
}
|
||||||
@ -941,8 +840,7 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
private SequenceActionResult SetUploadWeldingList_SeqParams(SequenceContext context, string id, SequenceActionResult param)
|
private SequenceActionResult SetUploadWeldingList_SeqParams(SequenceContext context, string id, SequenceActionResult param)
|
||||||
{
|
{
|
||||||
//현재 시퀀스에서 LoadList를 해주기 때문에 Sub 시퀀스에 IncludeListStartEnd를 false로 넘겨줘야 함
|
//현재 시퀀스에서 LoadList를 해주기 때문에 Sub 시퀀스에 IncludeListStartEnd를 false로 넘겨줘야 함
|
||||||
SeqUploadWeldingList_InitParam seqParams = new SeqUploadWeldingList_InitParam()
|
SeqUploadWeldingList_InitParam seqParams = new SeqUploadWeldingList_InitParam() {
|
||||||
{
|
|
||||||
NeedSetLaserTiming = _ModulationMode,
|
NeedSetLaserTiming = _ModulationMode,
|
||||||
IncludeListStartEnd = false,
|
IncludeListStartEnd = false,
|
||||||
CellMeasureCenterOffsetX = _CellMeasureCenterOffsetX,
|
CellMeasureCenterOffsetX = _CellMeasureCenterOffsetX,
|
||||||
@ -958,8 +856,7 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
private SequenceActionResult GetUploadWeldingList_SeqResult(SequenceContext context, string id, SequenceActionResult param)
|
private SequenceActionResult GetUploadWeldingList_SeqResult(SequenceContext context, string id, SequenceActionResult param)
|
||||||
{
|
{
|
||||||
var resultOutParam = param.Param as SeqUploadWeldingList_OutParam;
|
var resultOutParam = param.Param as SeqUploadWeldingList_OutParam;
|
||||||
if (resultOutParam.Success == false)
|
if (resultOutParam.Success == false) {
|
||||||
{
|
|
||||||
//AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_UploadWeldingList_ResultFailed);
|
//AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_UploadWeldingList_ResultFailed);
|
||||||
return SequenceAction.ForceStopByAlarm(AlarmCode.ALARM_SEQUENCE_UploadWeldingList_ResultFailed);
|
return SequenceAction.ForceStopByAlarm(AlarmCode.ALARM_SEQUENCE_UploadWeldingList_ResultFailed);
|
||||||
//return null;
|
//return null;
|
||||||
@ -970,8 +867,7 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
|
|
||||||
private SequenceActionResult SetReceiveCellInfo_SeqParams(SequenceContext context, string id, SequenceActionResult param)
|
private SequenceActionResult SetReceiveCellInfo_SeqParams(SequenceContext context, string id, SequenceActionResult param)
|
||||||
{
|
{
|
||||||
SeqReceiveCellInfo_InitParam seqParams = new SeqReceiveCellInfo_InitParam()
|
SeqReceiveCellInfo_InitParam seqParams = new SeqReceiveCellInfo_InitParam() {
|
||||||
{
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return SequenceAction.Ok(seqParams);
|
return SequenceAction.Ok(seqParams);
|
||||||
@ -980,8 +876,7 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
private SequenceActionResult GetReceiveCellInfo_SeqResult(SequenceContext context, string id, SequenceActionResult param)
|
private SequenceActionResult GetReceiveCellInfo_SeqResult(SequenceContext context, string id, SequenceActionResult param)
|
||||||
{
|
{
|
||||||
var resultOutParam = param.Param as SeqReceiveCellInfo_OutParam;
|
var resultOutParam = param.Param as SeqReceiveCellInfo_OutParam;
|
||||||
if (resultOutParam.Success == false)
|
if (resultOutParam.Success == false) {
|
||||||
{
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return SequenceAction.Ok();
|
return SequenceAction.Ok();
|
||||||
@ -996,15 +891,13 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
_Scanner.SetEndList();
|
_Scanner.SetEndList();
|
||||||
|
|
||||||
#region List 실행(처음엔 ExecuteList, 다음부터 AutoChangeList, 이후 대상 리스트 교체 (1 <-> 2))
|
#region List 실행(처음엔 ExecuteList, 다음부터 AutoChangeList, 이후 대상 리스트 교체 (1 <-> 2))
|
||||||
if (isTheFirstListExecute)
|
if (isTheFirstListExecute) {
|
||||||
{
|
|
||||||
isTheFirstListExecute = false;
|
isTheFirstListExecute = false;
|
||||||
|
|
||||||
_Scanner.ExecuteList(_WeldingScannerListNo);
|
_Scanner.ExecuteList(_WeldingScannerListNo);
|
||||||
Log.I(string.Format($"START Welding : ExecuteList_{_WeldingScannerListNo}"));
|
Log.I(string.Format($"START Welding : ExecuteList_{_WeldingScannerListNo}"));
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
_Scanner.AutoChange();
|
_Scanner.AutoChange();
|
||||||
Log.I(string.Format($"Next upload list : uploadList_{_WeldingScannerListNo}"));
|
Log.I(string.Format($"Next upload list : uploadList_{_WeldingScannerListNo}"));
|
||||||
}
|
}
|
||||||
@ -1027,26 +920,20 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
double send_time_offset = 0.1;
|
double send_time_offset = 0.1;
|
||||||
string LotID = "", CellID = "";
|
string LotID = "", CellID = "";
|
||||||
|
|
||||||
while (!context.Stopped)
|
while (!context.Stopped) {
|
||||||
{
|
|
||||||
double encoderX, currentAngle;
|
double encoderX, currentAngle;
|
||||||
_Scanner.GetEncoder(out encoderX, out currentAngle, true);
|
_Scanner.GetEncoder(out encoderX, out currentAngle, true);
|
||||||
double CurrentPosPLC = GetRotaryCurrentPosition();
|
double CurrentPosPLC = GetRotaryCurrentPosition();
|
||||||
bool WeldingInPosition = encoderX > _Scanner.Config.MarkingRangeMinRotate + 11.25 - send_time_offset - 0.1 && encoderX < _Scanner.Config.MarkingRangeMinRotate + 11.25 - send_time_offset + 0.1;
|
bool WeldingInPosition = encoderX > _Scanner.Config.MarkingRangeMinRotate + 11.25 - send_time_offset - 0.1 && encoderX < _Scanner.Config.MarkingRangeMinRotate + 11.25 - send_time_offset + 0.1;
|
||||||
|
|
||||||
if (WeldingInPosition)
|
if (WeldingInPosition) {
|
||||||
{
|
if (InputScannerList[(int)_WeldingScannerListNo - 1].CanExist) {
|
||||||
if (InputScannerList[(int)_WeldingScannerListNo - 1].CanExist)
|
|
||||||
{
|
|
||||||
Log.I($"Fork Before Min Rotate Encoder X : ({encoderX}), Encoder Y : ({currentAngle}), PLC Rotary : ({CurrentPosPLC}), List {_WeldingScannerListNo}, JigNo : ({InputScannerList[(int)_WeldingScannerListNo - 1].JigNo})");
|
Log.I($"Fork Before Min Rotate Encoder X : ({encoderX}), Encoder Y : ({currentAngle}), PLC Rotary : ({CurrentPosPLC}), List {_WeldingScannerListNo}, JigNo : ({InputScannerList[(int)_WeldingScannerListNo - 1].JigNo})");
|
||||||
if (!_SystemParameter.BypassModeLBAD)
|
if (!_SystemParameter.BypassModeLBAD) {
|
||||||
{
|
if (InputScannerList[(int)_WeldingScannerListNo - 1].CheckSendCellinfo == false) {
|
||||||
if (InputScannerList[(int)_WeldingScannerListNo - 1].CheckSendCellinfo == false)
|
|
||||||
{
|
|
||||||
LotID = InputScannerList[(int)_WeldingScannerListNo - 1].LotId;
|
LotID = InputScannerList[(int)_WeldingScannerListNo - 1].LotId;
|
||||||
CellID = InputScannerList[(int)_WeldingScannerListNo - 1].CellId;
|
CellID = InputScannerList[(int)_WeldingScannerListNo - 1].CellId;
|
||||||
if (currentAngle > InputScannerList[(int)_WeldingScannerListNo - 1].StartAngle)
|
if (currentAngle > InputScannerList[(int)_WeldingScannerListNo - 1].StartAngle) {
|
||||||
{
|
|
||||||
InputScannerList[(int)_WeldingScannerListNo - 1].CheckSendCellinfo = _StreamLightLBAD.SendCellInfo(LotID, CellID, _RecipeNo, _ModelNo, InputScannerList[(int)_WeldingScannerListNo - 1].JigNo);
|
InputScannerList[(int)_WeldingScannerListNo - 1].CheckSendCellinfo = _StreamLightLBAD.SendCellInfo(LotID, CellID, _RecipeNo, _ModelNo, InputScannerList[(int)_WeldingScannerListNo - 1].JigNo);
|
||||||
|
|
||||||
if (InputScannerList[(int)_WeldingScannerListNo - 1].CheckSendCellinfo == false)
|
if (InputScannerList[(int)_WeldingScannerListNo - 1].CheckSendCellinfo == false)
|
||||||
@ -1059,32 +946,27 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_IO._iOUnit.ReadDiBit(Convert.ToInt32(eADIAddress.LaserOn)))
|
if (_IO._iOUnit.ReadDiBit(Convert.ToInt32(eADIAddress.LaserOn))) {
|
||||||
{
|
if (InputScannerList[(int)_WeldingScannerListNo - 1].WeldStartTime == DateTime.MinValue && InputScannerList[(int)_WeldingScannerListNo - 1].CanExist) {
|
||||||
if (InputScannerList[(int)_WeldingScannerListNo - 1].WeldStartTime == DateTime.MinValue && InputScannerList[(int)_WeldingScannerListNo - 1].CanExist)
|
|
||||||
{
|
|
||||||
InputScannerList[(int)_WeldingScannerListNo - 1].WeldStartTime = DateTime.Now;
|
InputScannerList[(int)_WeldingScannerListNo - 1].WeldStartTime = DateTime.Now;
|
||||||
InputScannerList[(int)_WeldingScannerListNo - 1].WeldComplete = true;
|
InputScannerList[(int)_WeldingScannerListNo - 1].WeldComplete = true;
|
||||||
EncoderLogCount = 0;
|
EncoderLogCount = 0;
|
||||||
Log.I($"Laser On, Welding Complete. JigNo : ({InputScannerList[(int)_WeldingScannerListNo - 1].JigNo})");
|
Log.I($"Laser On, Welding Complete. JigNo : ({InputScannerList[(int)_WeldingScannerListNo - 1].JigNo})");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EncoderLogCount == 0)
|
if (EncoderLogCount == 0) {
|
||||||
{
|
|
||||||
Log.I($"Fork Laser On Encoder X : ({encoderX}), Encoder Y : ({currentAngle}), PLC Rotary : ({CurrentPosPLC}), List {_WeldingScannerListNo}, JigNo : ({InputScannerList[(int)_WeldingScannerListNo - 1].JigNo})");
|
Log.I($"Fork Laser On Encoder X : ({encoderX}), Encoder Y : ({currentAngle}), PLC Rotary : ({CurrentPosPLC}), List {_WeldingScannerListNo}, JigNo : ({InputScannerList[(int)_WeldingScannerListNo - 1].JigNo})");
|
||||||
}
|
}
|
||||||
EncoderLogCount = (EncoderLogCount + 1) % 7;
|
EncoderLogCount = (EncoderLogCount + 1) % 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < _RotaryJigCount; i++)
|
for (int i = 0; i < _RotaryJigCount; i++) {
|
||||||
{
|
if (_PLC.ReadBit((int)eBitInput.PLC_USE_WELD_JIG_1 + i).data == false) {
|
||||||
if (_PLC.ReadBit((int)eBitInput.PLC_USE_WELD_JIG_1 + i).data == false)
|
|
||||||
{
|
|
||||||
_PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE_1 + i, false);
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE_1 + i, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_PLC.WriteDWord((int)eWordOutput.PC_CURRENT_POS, (int)((currentAngle + _RotaryEncoderOffset) % 360 * 100000f));
|
_PLC.WriteDWord((int)eWordOutput.PC_CURRENT_POS, (int)((currentAngle + _RotaryEncoderOffset) % 360 * 100_000f));
|
||||||
Thread.Sleep(1); // 부하 방지
|
Thread.Sleep(1); // 부하 방지
|
||||||
}
|
}
|
||||||
return SequenceAction.Ok();
|
return SequenceAction.Ok();
|
||||||
@ -1092,8 +974,7 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
|
|
||||||
private void UpdateProductCount(SequenceContext context)
|
private void UpdateProductCount(SequenceContext context)
|
||||||
{
|
{
|
||||||
if (_SystemParameter.LastResetTime < DateTime.Now.Date)
|
if (_SystemParameter.LastResetTime < DateTime.Now.Date) {
|
||||||
{
|
|
||||||
_SystemParameter.LastResetTime = DateTime.Now.Date;
|
_SystemParameter.LastResetTime = DateTime.Now.Date;
|
||||||
Log.I($"Today Count Reset. {_SystemParameter.TodayProductCount} -> 0");
|
Log.I($"Today Count Reset. {_SystemParameter.TodayProductCount} -> 0");
|
||||||
_SystemParameter.TodayProductCount = 0;
|
_SystemParameter.TodayProductCount = 0;
|
||||||
@ -1101,12 +982,10 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
|
|
||||||
_TodayProduct = _SystemParameter.TodayProductCount;
|
_TodayProduct = _SystemParameter.TodayProductCount;
|
||||||
_TotalProduct = _SystemParameter.TotalProductCount;
|
_TotalProduct = _SystemParameter.TotalProductCount;
|
||||||
if (_TodayProduct < uint.MaxValue)
|
if (_TodayProduct < uint.MaxValue) {
|
||||||
{
|
|
||||||
_TodayProduct++;
|
_TodayProduct++;
|
||||||
}
|
}
|
||||||
if (_TotalProduct < uint.MaxValue)
|
if (_TotalProduct < uint.MaxValue) {
|
||||||
{
|
|
||||||
_TotalProduct++;
|
_TotalProduct++;
|
||||||
}
|
}
|
||||||
_SystemParameter.TodayProductCount = _TodayProduct;
|
_SystemParameter.TodayProductCount = _TodayProduct;
|
||||||
@ -1138,8 +1017,7 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
{
|
{
|
||||||
Status.SetWorkingPosition(eWorkingPosition.REPORTING_RESULT);
|
Status.SetWorkingPosition(eWorkingPosition.REPORTING_RESULT);
|
||||||
|
|
||||||
SeqReportCellResult_InitParam seqParams = new SeqReportCellResult_InitParam()
|
SeqReportCellResult_InitParam seqParams = new SeqReportCellResult_InitParam() {
|
||||||
{
|
|
||||||
EDC_Interface = new EDC(),
|
EDC_Interface = new EDC(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1149,8 +1027,7 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
private SequenceActionResult GetReportCellResult_SeqResult(SequenceContext context, string id, SequenceActionResult param)
|
private SequenceActionResult GetReportCellResult_SeqResult(SequenceContext context, string id, SequenceActionResult param)
|
||||||
{
|
{
|
||||||
var resultOutParam = param.Param as SeqReportCellResult_OutParam;
|
var resultOutParam = param.Param as SeqReportCellResult_OutParam;
|
||||||
if (resultOutParam.Success == false)
|
if (resultOutParam.Success == false) {
|
||||||
{
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1168,12 +1045,10 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
//Jin : cycleStop 명령을 용접 프로그램에서 할 경우가 현재는 없음..
|
//Jin : cycleStop 명령을 용접 프로그램에서 할 경우가 현재는 없음..
|
||||||
// CheckCycleStop 노드와 Complete 노드 사이 다른 노드가 필요하다면 해당 노드를 CheckCycleStop 노드 위로 올리자
|
// CheckCycleStop 노드와 Complete 노드 사이 다른 노드가 필요하다면 해당 노드를 CheckCycleStop 노드 위로 올리자
|
||||||
bool cycleStop = false;
|
bool cycleStop = false;
|
||||||
if (cycleStop)
|
if (cycleStop) {
|
||||||
{
|
|
||||||
return SEQ_SAVE_RESULT_DATA;
|
return SEQ_SAVE_RESULT_DATA;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
return SEQ_CHECK_LOAD_COMPLETE;
|
return SEQ_CHECK_LOAD_COMPLETE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1189,8 +1064,7 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
|
|
||||||
private void SaveCellAPD()
|
private void SaveCellAPD()
|
||||||
{
|
{
|
||||||
if (Status.GetProcessingWeldingData().APD.Count > 0)
|
if (Status.GetProcessingWeldingData().APD.Count > 0) {
|
||||||
{
|
|
||||||
string directoryPath = "D:\\ILSOSConfig\\APD_History";
|
string directoryPath = "D:\\ILSOSConfig\\APD_History";
|
||||||
string fileName = DateTime.Now.ToString("HH") + "_CellAPD";
|
string fileName = DateTime.Now.ToString("HH") + "_CellAPD";
|
||||||
string fullPath = Path.Combine(directoryPath, Status.GetProcessingWeldingData().APD.First().Date.ToString("yyyy-MM-dd"), fileName);
|
string fullPath = Path.Combine(directoryPath, Status.GetProcessingWeldingData().APD.First().Date.ToString("yyyy-MM-dd"), fileName);
|
||||||
@ -1215,8 +1089,7 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
private SequenceActionResult InitConditionError(SequenceContext context, string id, SequenceActionResult param)
|
private SequenceActionResult InitConditionError(SequenceContext context, string id, SequenceActionResult param)
|
||||||
{
|
{
|
||||||
context.TryGetValue(ContextKey.KEY_SEQUENCE_ERROR_CODE, out int InitializeCode);
|
context.TryGetValue(ContextKey.KEY_SEQUENCE_ERROR_CODE, out int InitializeCode);
|
||||||
switch (InitializeCode)
|
switch (InitializeCode) {
|
||||||
{
|
|
||||||
case (int)InitErrorList.PLC_AUTORUN_BIT_OFF:
|
case (int)InitErrorList.PLC_AUTORUN_BIT_OFF:
|
||||||
Log.D("AutoRun Sequence InitConditionError : PLC_AUTORUN_OFF");
|
Log.D("AutoRun Sequence InitConditionError : PLC_AUTORUN_OFF");
|
||||||
return SequenceAction.ForceStopByAlarm(AlarmCode.ALARM_SEQUENCE_AutoRun_CheckInitCondition_PLC_AUTORUN_OFF);
|
return SequenceAction.ForceStopByAlarm(AlarmCode.ALARM_SEQUENCE_AutoRun_CheckInitCondition_PLC_AUTORUN_OFF);
|
||||||
@ -1250,8 +1123,7 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
context.TryGetValue(ContextKey.KEY_SEQUENCE_RESULT, out bool seqResult);
|
context.TryGetValue(ContextKey.KEY_SEQUENCE_RESULT, out bool seqResult);
|
||||||
SeqAutoRunCCWH52A_OutParam result = new SeqAutoRunCCWH52A_OutParam() { Success = seqResult };
|
SeqAutoRunCCWH52A_OutParam result = new SeqAutoRunCCWH52A_OutParam() { Success = seqResult };
|
||||||
|
|
||||||
if (seqResult == false)
|
if (seqResult == false) {
|
||||||
{
|
|
||||||
//AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_AutoRun_ResultFailed);
|
//AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_AutoRun_ResultFailed);
|
||||||
}
|
}
|
||||||
Log.D("AutoRun Sequence Complete");
|
Log.D("AutoRun Sequence Complete");
|
||||||
@ -1263,8 +1135,7 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
private bool RestoreDeviceStatus()
|
private bool RestoreDeviceStatus()
|
||||||
{
|
{
|
||||||
//PLC All BIT OFF
|
//PLC All BIT OFF
|
||||||
for (int i = 0; i < _RotaryJigCount; i++)
|
for (int i = 0; i < _RotaryJigCount; i++) {
|
||||||
{
|
|
||||||
_PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE_1 + i, false);
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE_1 + i, false);
|
||||||
}
|
}
|
||||||
_PLC.WriteBit((int)eBitOutput.PC_AUTO_STATUS, false);
|
_PLC.WriteBit((int)eBitOutput.PC_AUTO_STATUS, false);
|
||||||
@ -1273,10 +1144,8 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
|
|
||||||
//LBAD Ready Off
|
//LBAD Ready Off
|
||||||
//_LBAD.SetReadybyAuto(false);
|
//_LBAD.SetReadybyAuto(false);
|
||||||
if (_SystemParameter.BypassModeLBAD == false)
|
if (_SystemParameter.BypassModeLBAD == false) {
|
||||||
{
|
if (_StreamLightLBAD.SendReadyStatus(eRequestData.Ready_Off) == false) {
|
||||||
if (_StreamLightLBAD.SendReadyStatus(eRequestData.Ready_Off) == false)
|
|
||||||
{
|
|
||||||
Log.I(string.Format($"[LBAD Interface]CheckReadyStatus null"));
|
Log.I(string.Format($"[LBAD Interface]CheckReadyStatus null"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1327,19 +1196,14 @@ namespace ILSOS_CCW_H52A.Sequences
|
|||||||
|
|
||||||
//PLC All BIT OFF
|
//PLC All BIT OFF
|
||||||
for (int i = 0; i < _RotaryJigCount; i++)
|
for (int i = 0; i < _RotaryJigCount; i++)
|
||||||
{
|
_PLC.WriteBit(eBitOutput.PC_WELD_COMPLETE_1 + i, false);
|
||||||
_PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE_1 + i, false);
|
_PLC.WriteBit(eBitOutput.PC_AUTO_STATUS, false);
|
||||||
}
|
Log.I("[PLCInterface]PC All Bit Off");
|
||||||
_PLC.WriteBit((int)eBitOutput.PC_AUTO_STATUS, false);
|
|
||||||
//_PLC.WriteBit((int)eBitOutput.PC_RECIPE_PARAM_UPLOAD_COMPLETE, false);
|
|
||||||
Log.I(string.Format("[PLCInterface]PC All Bit Off"));
|
|
||||||
|
|
||||||
//LBAD Ready Off
|
//LBAD Ready Off
|
||||||
//_LBAD.SetReadybyAuto(false);
|
//_LBAD.SetReadybyAuto(false);
|
||||||
if (_SystemParameter.BypassModeLBAD == false)
|
if (_SystemParameter.BypassModeLBAD == false) {
|
||||||
{
|
if (_StreamLightLBAD.SendReadyStatus(eRequestData.Ready_Off) == false) {
|
||||||
if (_StreamLightLBAD.SendReadyStatus(eRequestData.Ready_Off) == false)
|
|
||||||
{
|
|
||||||
Log.I(string.Format($"[LBAD Interface]CheckReadyStatus null"));
|
Log.I(string.Format($"[LBAD Interface]CheckReadyStatus null"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -236,7 +236,7 @@ namespace WeldingCommon
|
|||||||
//registry.Register(CommonDeviceIds.Laser, () => new Laser(CommonDeviceIds.Laser, isSimul), new LaserConfig(),
|
//registry.Register(CommonDeviceIds.Laser, () => new Laser(CommonDeviceIds.Laser, isSimul), new LaserConfig(),
|
||||||
// device => new UCLaserDevice() { DataContext = new UCLaserDeviceViewModel(AuroraEnv, CommonDeviceIds.Laser) });
|
// device => new UCLaserDevice() { DataContext = new UCLaserDeviceViewModel(AuroraEnv, CommonDeviceIds.Laser) });
|
||||||
|
|
||||||
registry.Register(CommonDeviceIds.Scanner, () => new Scanner(CommonDeviceIds.Scanner), new ScannerConfig());
|
//registry.Register(CommonDeviceIds.Scanner, () => new Scanner(CommonDeviceIds.Scanner), new ScannerConfig());
|
||||||
//registry.Register(CommonDeviceIds.SmcChiller, () => new SmcChiller(CommonDeviceIds.SmcChiller, 0, isSimul), new SmcChiller.Config(),
|
//registry.Register(CommonDeviceIds.SmcChiller, () => new SmcChiller(CommonDeviceIds.SmcChiller, 0, isSimul), new SmcChiller.Config(),
|
||||||
// device => new UCSMCChillerDevice() { DataContext = new UCSMCChillerDeviceViewModel(AuroraEnv, CommonDeviceIds.SmcChiller) });
|
// device => new UCSMCChillerDevice() { DataContext = new UCSMCChillerDeviceViewModel(AuroraEnv, CommonDeviceIds.SmcChiller) });
|
||||||
registry.Register(CommonDeviceIds.SmcChiller, () => new SmcChiller(CommonDeviceIds.SmcChiller), new SmcChillerConfig(),
|
registry.Register(CommonDeviceIds.SmcChiller, () => new SmcChiller(CommonDeviceIds.SmcChiller), new SmcChillerConfig(),
|
||||||
|
|||||||
@ -108,11 +108,11 @@
|
|||||||
public const string Laser = "Laser";
|
public const string Laser = "Laser";
|
||||||
public const string LaserIO = "LaserIO";
|
public const string LaserIO = "LaserIO";
|
||||||
|
|
||||||
public const string Scanner = "Scanner";
|
|
||||||
public const string SmcChiller = "SmcChiller";
|
public const string SmcChiller = "SmcChiller";
|
||||||
public const string PowerMeter = "PowerMeter";
|
public const string PowerMeter = "PowerMeter";
|
||||||
public const string Light = "Light"; // Camera Light Controller
|
public const string Light = "Light"; // Camera Light Controller
|
||||||
public const string PLCDevice = "PLC";
|
public const string PLCDevice = "PLC";
|
||||||
|
public const string Scanner = "Scanner";
|
||||||
public const string IODevice = "IO_Board";
|
public const string IODevice = "IO_Board";
|
||||||
|
|
||||||
public const string CellTracker = "CellTracker";
|
public const string CellTracker = "CellTracker";
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user