764 lines
34 KiB
C#
764 lines
34 KiB
C#
using Aurora.Api;
|
|
using Aurora.Api.Devices;
|
|
using Aurora.Api.Manager;
|
|
using Aurora.View;
|
|
using AuroraACS;
|
|
using AuroraLaser;
|
|
using AuroraLaser.Trumpf;
|
|
using AuroraMassFlowMeter;
|
|
using AuroraMotionBoard.Ajin;
|
|
using AuroraOCT.Trumpf;
|
|
using Hermes;
|
|
using ILSOS_PrismaticGun.Alarm;
|
|
using ILSOS_PrismaticGun.Device.ACS;
|
|
using ILSOS_PrismaticGun.Process;
|
|
using ILSOS_PrismaticGun.Recipes;
|
|
using ILSOS_PrismaticGun.Sequences.SubSequence.StageA;
|
|
using ILSOS_PrismaticGun.Settings;
|
|
using ILSOS_PrismaticGun.Tools;
|
|
using OpenCvSharp;
|
|
using OpenCvSharp.Dnn;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.Data;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using VisionCommon;
|
|
using WeldingCommon;
|
|
using WeldingCommon.Settings;
|
|
using static AuroraOCT.Trumpf.OCT;
|
|
|
|
namespace ILSOS_PrismaticGun.Sequences
|
|
{
|
|
class SeqSplitLine
|
|
{
|
|
static readonly Logger Log = new Logger("SplitLineSequence");
|
|
const int SLEEP_TIME_MS = 50;
|
|
const int SEQ_CHECK_TIMER = 100;
|
|
const int SEQ_TIMEOUT = 30 * 1000;
|
|
|
|
const int MOTION_TIMEOUT = 10 * 1000;
|
|
const int MOTION_INTERVAL = 20;
|
|
const int WELDING_TIMEOUT = 30 * 1000;
|
|
|
|
const string SEQ_ENTER = "SEQ_ENTER";
|
|
const string SEQ_CHECK_INIT_CONDITION = "Check Init Condition";
|
|
const string SEQ_PREPARE_MOTION = "Prepare Motion";
|
|
const string SEQ_CHECK_LINE_COUNT = "Check Line Counting";
|
|
const string SEQ_SET_MFC_PARAM = "Set MFC Parameter";
|
|
const string SEQ_TARGET_POS_MOVE = "Target Position Move";
|
|
const string SEQ_REQUEST_LASER_USE_WAIT = "Request Laser Use & Wait";
|
|
const string SEQ_SET_OCT_PARAM = "Set Oct Parameter"; // Laser Interface >> OCT 관련 파라미터 셋팅
|
|
const string SEQ_WELDING_MOTION = "Welding Motion";
|
|
const string SEQ_CHECK_INTERLOCK = "Check Interlock";
|
|
const string SEQ_MOTION_INTERLOCK = "Motion Interlock";
|
|
const string SEQ_LINE_PROCESS_COMPLETE = "SplitSequence Complete";
|
|
|
|
|
|
private static ObservableCollection<LineShotItem> _data;
|
|
|
|
private static int LineInLinesCount;
|
|
private static int LineInLinesIndex = 0;
|
|
|
|
private static eStage _stage;
|
|
private static MainRecipe _mainRecipe;
|
|
|
|
private static PrismaticGunACS _acs;
|
|
private static IPrismaticGunACS _acsMotion;
|
|
private static MassFlowMeter _mfc;
|
|
private static Laser _laser;
|
|
private static LaserTruFiber _laserCore;
|
|
private static LaserPowerCalParam _laserCal;
|
|
private static ACSMotor _AxisX, _AxisY;
|
|
private static AJINMotor _AxisZ;
|
|
private static PrismaticGunACSIO _io;
|
|
private static AuroraOCT.Trumpf.OCT _oct;
|
|
private static AuroraACS.Speed _spd = AuroraACS.Speed.M;
|
|
private static TeachingPositionSetting _setting;
|
|
|
|
public static SequenceBuilder Builder()
|
|
{
|
|
SequenceBuilder sb = new SequenceBuilder(1000, true);
|
|
|
|
sb.AddAction(SEQ_ENTER, Sequence_Enter);
|
|
sb.AddAction(SEQ_CHECK_INIT_CONDITION, CheckInitCondition);
|
|
sb.AddAction(SEQ_PREPARE_MOTION, PrepareMotion);
|
|
sb.AddAction(SEQ_SET_MFC_PARAM, SetMFCParam);
|
|
sb.AddDecision(SEQ_CHECK_LINE_COUNT, CheckLineCount);
|
|
sb.AddAction(SEQ_TARGET_POS_MOVE, TargetPositionMove);
|
|
sb.AddAction(SEQ_REQUEST_LASER_USE_WAIT, RequestLaserUseWait);
|
|
sb.AddAction(SEQ_SET_OCT_PARAM, SetOCTParam);
|
|
sb.AddAction(SEQ_WELDING_MOTION, WeldingMotion);
|
|
sb.AddAction(SEQ_CHECK_INTERLOCK, CheckInterlock);
|
|
|
|
sb.AddAction(SEQ_MOTION_INTERLOCK, MotionInterlock);
|
|
sb.AddAction(SEQ_LINE_PROCESS_COMPLETE, LineProcessComplete);
|
|
|
|
sb.OnStopped(OnStopped);
|
|
sb.OnForceError(OnForceError);
|
|
|
|
sb.Flows(sb.Init > sb[SEQ_ENTER] > sb[SEQ_CHECK_INIT_CONDITION] > sb[SEQ_PREPARE_MOTION] > sb[SEQ_SET_MFC_PARAM]
|
|
> sb[SEQ_CHECK_LINE_COUNT]);
|
|
|
|
sb.Flows(sb[SEQ_CHECK_LINE_COUNT] > sb[SEQ_TARGET_POS_MOVE] > sb[SEQ_REQUEST_LASER_USE_WAIT] > sb[SEQ_SET_OCT_PARAM] > sb[SEQ_WELDING_MOTION] > sb[SEQ_CHECK_INTERLOCK] > sb[SEQ_CHECK_LINE_COUNT]);
|
|
|
|
sb.Flows(sb[SEQ_CHECK_LINE_COUNT] > sb[SEQ_MOTION_INTERLOCK] > sb[SEQ_LINE_PROCESS_COMPLETE] > sb.Final);
|
|
|
|
//sb.Draw("SplitLineSequence.pdf");
|
|
|
|
return sb;
|
|
}
|
|
|
|
private static SequenceActionResult Sequence_Enter(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
context.RetryUntilSuccess(() => true, 1000 * 100, 100);
|
|
(_stage, _data) = ((eStage, ObservableCollection<LineShotItem>))param.Param;
|
|
|
|
if (_acsMotion is null)
|
|
_acsMotion = _acs = context.Devices[DeviceIds.ACS] as PrismaticGunACS;
|
|
|
|
if (_stage == eStage.A)
|
|
_mfc = context.Devices[DeviceIds.MassFlowMeterStageA] as MassFlowMeter;
|
|
else
|
|
_mfc = context.Devices[DeviceIds.MassFlowMeterStageB] as MassFlowMeter;
|
|
|
|
if (_laser is null)
|
|
_laser = context.Devices[CommonDeviceIds.Laser] as Laser;
|
|
_laserCore = _laser.getCore() as LaserTruFiber;
|
|
_laserCal = context.Settings[CommonSettingIds.LaserPowerCalParam] as LaserPowerCalParam;
|
|
|
|
if (_io is null)
|
|
_io = context.Devices[DeviceIds.IODevice] as PrismaticGunACSIO;
|
|
|
|
if (_setting is null)
|
|
_setting = context.Settings[SettingIds.TeachingPos] as TeachingPositionSetting;
|
|
|
|
if (_stage == eStage.A)
|
|
_AxisX = context.Devices[MotorIds.ALineX] as ACSMotor;
|
|
else
|
|
_AxisX = context.Devices[MotorIds.BLineX] as ACSMotor;
|
|
|
|
if (_stage == eStage.A)
|
|
_AxisY = context.Devices[MotorIds.ALineY] as ACSMotor;
|
|
else
|
|
_AxisY = context.Devices[MotorIds.BLineY] as ACSMotor;
|
|
|
|
if (_stage == eStage.A)
|
|
_AxisZ = context.Devices[MotorIds.ALineZ] as AJINMotor;
|
|
else
|
|
_AxisZ = context.Devices[MotorIds.BLineZ] as AJINMotor;
|
|
|
|
if (_oct is null)
|
|
_oct = context.Devices[CommonDeviceIds.OCT] as OCT;
|
|
|
|
LineInLinesCount = _data.Count;
|
|
LineInLinesIndex = 0;
|
|
Thread.Sleep(SLEEP_TIME_MS);
|
|
Log.V(">> SeqSplitLIne - Start");
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
private static SequenceActionResult CheckInitCondition(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
if (!_AxisX.IsActivated) {
|
|
if (_stage == eStage.A)
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.DEVICE_STAGE_A_AXISX_DEACTIVATED);
|
|
else
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.DEVICE_STAGE_B_AXISX_DEACTIVATED);
|
|
return null;
|
|
}
|
|
|
|
if (!_AxisY.IsActivated) {
|
|
if (_stage == eStage.A)
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.DEVICE_STAGE_A_AXISY_DEACTIVATED);
|
|
else
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.DEVICE_STAGE_B_AXISY_DEACTIVATED);
|
|
return null;
|
|
}
|
|
|
|
if (!_AxisZ.IsActivated) {
|
|
if (_stage == eStage.A)
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.DEVICE_STAGE_A_AXISZ_DEACTIVATED);
|
|
else
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.DEVICE_STAGE_B_AXISZ_DEACTIVATED);
|
|
return null;
|
|
}
|
|
|
|
if (!(_mfc.IsActivated && !_mfc.IsCommError)) {
|
|
Log.E($"[MFC activated({_mfc.IsActivated}) / connected({!_mfc.IsCommError})]");
|
|
if (_stage == eStage.A)
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.STAGE_A_MFC_DEACTIVATED_DISCONNECTED);
|
|
else
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.STAGE_B_MFC_DEACTIVATED_DISCONNECTED);
|
|
return null;
|
|
}
|
|
|
|
if (!((_acsMotion as PrismaticGunACS).IsActivated)) {
|
|
Log.E($"[ACS activated({(_acsMotion as PrismaticGunACS).IsActivated})]");
|
|
if (_stage == eStage.A)
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.STAGE_A_DEACTIVATED_DISCONNECTED);
|
|
else
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.STAGE_B_DEACTIVATED_DISCONNECTED);
|
|
return null;
|
|
}
|
|
|
|
if (!(_laser.IsActivated && _laser.GetConnected())) {
|
|
Log.E($"[Laser activated({_laser.IsActivated}) / connected({_laser.GetConnected()})]");
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.DEVICE_LASER_DEACTIVATED_DISCONNECTED);
|
|
return null;
|
|
}
|
|
|
|
if (!(_io.IsActivated && _io.IsConnected())) {
|
|
Log.E($"[IO activated({_io.IsActivated}) / connected({_io.IsConnected()})]");
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.DEVICE_ACSIO_DEACTIVATED_DISCONNECTED);
|
|
return null;
|
|
}
|
|
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
private static SequenceActionResult PrepareMotion(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
// Jig Up
|
|
Log.V($"{_stage} Check Jig Up");
|
|
if (!_io.CheckJigUp(_stage)) {
|
|
Log.V($"{_stage} Jig Up Start");
|
|
_io.JigUp(_stage);
|
|
|
|
var res = context.RetryUntilSuccess(() => _io.CheckJigUp(_stage), MOTION_TIMEOUT, MOTION_INTERVAL);
|
|
if (res == E2.TIMEOUT) {
|
|
if (_stage == eStage.A)
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.STAGE_A_JIG_UP_TIMEOUT);
|
|
else
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.STAGE_B_JIG_UP_TIMEOUT);
|
|
return null;
|
|
} else if (res == E2.CANCELLED) {
|
|
context.PutValue<int>("AlarmCode", 0);
|
|
return null;
|
|
}
|
|
}
|
|
Log.V($"{_stage} Jig Up Complete");
|
|
|
|
// Clamp
|
|
Log.V($"{_stage} Check Clamp");
|
|
if (!_io.CheckClampComp(_stage)) {
|
|
Log.V($"{_stage} Clamp Start");
|
|
_acsMotion.ClampStart(_stage);
|
|
|
|
var _res = context.RetryUntilSuccess(() => _io.CheckClampComp(_stage), MOTION_TIMEOUT, MOTION_INTERVAL);
|
|
if (_res == E2.TIMEOUT) {
|
|
if (_stage == eStage.A)
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.STAGE_A_CLAMP_TIMEOUT);
|
|
else
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.STAGE_B_CLAMP_TIMEOUT);
|
|
return null;
|
|
} else if (_res == E2.CANCELLED) {
|
|
context.PutValue<int>("AlarmCode", 0);
|
|
return null;
|
|
}
|
|
}
|
|
Log.V($"{_stage} Clamp Comp");
|
|
|
|
|
|
return SequenceAction.Ok();
|
|
}
|
|
private static SequenceActionResult SetMFCParam(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
var MfcPercent = _data[LineInLinesIndex].N2PressMFC.ToPersent();
|
|
_mfc.WriteSetPoint(MfcPercent);
|
|
//Log.V($">> Line {LineInLinesIndex} MFC Param Set({_mainRecipe.N2PressMFC})");
|
|
|
|
// N2를 내가 조작한 비율(MfcPercent)로 세팅
|
|
var res = context.RetryUntilSuccess(() => _mfc.SetPercent.CheckInside(MfcPercent, 0.1), SEQ_TIMEOUT, SEQ_CHECK_TIMER);
|
|
if (res == E2.TIMEOUT) {
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.MFC_CHECKINSIDE);
|
|
Log.FuncE($">> Line {LineInLinesIndex} MFC Setting{_data[LineInLinesIndex].N2PressMFC}) Timeout");
|
|
return null;
|
|
}
|
|
Log.V($">> Line {LineInLinesIndex} MFC Param Setting ({_data[LineInLinesIndex].N2PressMFC})");
|
|
|
|
// N2가 세팅한대로 나오는지 확인
|
|
res = context.RetryUntilSuccess(() => _mfc.CurrentFlow.CheckInside(MfcPercent, 0.1), SEQ_TIMEOUT, SEQ_CHECK_TIMER);
|
|
if (res == E2.TIMEOUT) {
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.MFC_CHECKINSIDE);
|
|
Log.FuncE($"Line {LineInLinesIndex} MFC Param Set({_data[LineInLinesIndex].N2PressMFC}) Timeout");
|
|
return null;
|
|
}
|
|
Log.V($">> Line {LineInLinesIndex} MFC Param Set({_data[LineInLinesIndex].N2PressMFC}) Complete");
|
|
Thread.Sleep(SLEEP_TIME_MS);
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
private static string CheckLineCount(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
|
|
{
|
|
if (LineInLinesCount > LineInLinesIndex){
|
|
Log.FuncV($">> LineShot Count ({LineInLinesIndex + 1} / {LineInLinesCount})");
|
|
return SEQ_TARGET_POS_MOVE;
|
|
}
|
|
|
|
Thread.Sleep(SLEEP_TIME_MS);
|
|
return SEQ_MOTION_INTERLOCK;
|
|
}
|
|
|
|
private static SequenceActionResult TargetPositionMove(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
var LineData = _data;
|
|
LineData[LineInLinesIndex].State = "Working";
|
|
var _startX = LineData[LineInLinesIndex].StartX;
|
|
var _startY = LineData[LineInLinesIndex].StartY;
|
|
var _positionZ = LineData[LineInLinesIndex].PositionZ;
|
|
|
|
// PositionZ 위치로 이동
|
|
_AxisZ.Move(_positionZ, (AuroraMotionBoard.Ajin.Speed)_spd, TargetPosType.ABS);
|
|
Thread.Sleep(500);
|
|
|
|
var res = context.RetryUntilSuccess(() => _AxisZ.IsReachedTargetPosition(_positionZ), SEQ_TIMEOUT, SEQ_CHECK_TIMER);
|
|
if (res == E2.TIMEOUT) {
|
|
if (_stage == eStage.A)
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.STAGE_A_Z_MOVE_TIMEOUT);
|
|
else
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.STAGE_B_Z_MOVE_TIMEOUT);
|
|
Log.FuncE(">> Start Z Position Move Fail");
|
|
return null;
|
|
}
|
|
Log.FuncV($">> PositionZ : {_positionZ}");
|
|
|
|
// StartX 위치로 이동
|
|
_AxisX.SetTargetPos(_startX, TargetPosType.ABS);
|
|
_AxisX.SetMoveVelocityImm(_spd);
|
|
_AxisX.AccelerationImm(_spd);
|
|
_AxisX.DecelerationImm(_spd);
|
|
_AxisX.JerkImm(_spd);
|
|
_AxisX.Move();
|
|
res = context.RetryUntilSuccess(() => _AxisX.IsReachedTargetPosition(_startX), SEQ_TIMEOUT, SEQ_CHECK_TIMER);
|
|
if (res == E2.TIMEOUT) {
|
|
if (_stage == eStage.A)
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.STAGE_A_X_MOVE_TIMEOUT);
|
|
else
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.STAGE_B_X_MOVE_TIMEOUT);
|
|
Log.FuncE(">> Start X Position Move Fail");
|
|
return null;
|
|
}
|
|
|
|
// StartY 위치로 이동
|
|
_AxisY.SetTargetPos(_startY, TargetPosType.ABS);
|
|
_AxisY.SetMoveVelocityImm(_spd);
|
|
_AxisY.AccelerationImm(_spd);
|
|
_AxisY.DecelerationImm(_spd);
|
|
_AxisY.JerkImm(_spd);
|
|
_AxisY.Move();
|
|
res = context.RetryUntilSuccess(() => _AxisY.IsReachedTargetPosition(_startY), SEQ_TIMEOUT, SEQ_CHECK_TIMER);
|
|
if (res == E2.TIMEOUT) {
|
|
if (_stage == eStage.A)
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.STAGE_A_Y_MOVE_TIMEOUT);
|
|
else
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.STAGE_B_Y_MOVE_TIMEOUT);
|
|
Log.FuncE(">> Start Y Position Move Fail");
|
|
return null;
|
|
}
|
|
|
|
Log.FuncV(">> Start Position Move Complete");
|
|
Thread.Sleep(SLEEP_TIME_MS);
|
|
return SequenceAction.Ok();
|
|
}
|
|
private static SequenceActionResult RequestLaserUseWait(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
// 상대편 라인에서 레이저 사용중인지 체크
|
|
var res = context.RetryUntilSuccess(() => ProcessManager.Instance.IsEnableLaserUse(), WELDING_TIMEOUT, MOTION_INTERVAL);
|
|
if (res == E2.TIMEOUT) {
|
|
context.PutValue<int>("AlarmCode", _stage == eStage.A ?
|
|
AlarmCode_PrismaticGun.ACS_STAGE_A_ENBALE_LASER_USE : AlarmCode_PrismaticGun.ACS_STAGE_B_ENBALE_LASER_USE);
|
|
return null;
|
|
} else if (res == E2.CANCELLED) {
|
|
context.PutValue<int>("AlarmCode", 0);
|
|
return null;
|
|
}
|
|
ProcessManager.Instance.EnableLaserUse(false);
|
|
|
|
// ACS에서 Welding준비가 됐는지 확인
|
|
// 해당 스테이지에서 용접 시작 조건이 비활성화인지 확인
|
|
res = context.RetryUntilSuccess(() => _acsMotion.CheckACSWeldingEnable(_stage), WELDING_TIMEOUT, MOTION_INTERVAL);
|
|
if (res == E2.TIMEOUT) {
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.ACS_WELDING_ENABLE);
|
|
return null;
|
|
} else if (res == E2.CANCELLED) {
|
|
context.PutValue<int>("AlarmCode", 0);
|
|
return null;
|
|
}
|
|
Log.V($"{_stage} Check ACS Welding Enable Complete");
|
|
|
|
|
|
// 상대편 라인에서 레이저를 쓰지도 않고, ACS도 레이저를 동작할 준비가 됐으므로
|
|
// 레이저 스탠바이
|
|
if (!_laser.GetLaserReady()) {
|
|
_laser.LaserOn();
|
|
Thread.Sleep(500);
|
|
}
|
|
|
|
Log.V($"Laser Program Update Start");
|
|
res = context.RetryUntilSuccess(() => _laser.GetLaserReady(), WELDING_TIMEOUT, MOTION_INTERVAL);
|
|
if (res == E2.TIMEOUT) {
|
|
Log.FuncE("Laser Ready Check Timeout!");
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.GET_LASER_READY);
|
|
return null;
|
|
} else if (res == E2.CANCELLED) {
|
|
Log.FuncE("Laser Ready Check Cancel!");
|
|
context.PutValue<int>("AlarmCode", 0);
|
|
return null;
|
|
}
|
|
|
|
|
|
var CoreRatio = (int)((_data[LineInLinesIndex].Core / (_data[LineInLinesIndex].Core + _data[LineInLinesIndex].Ring)) * 100);
|
|
List<(int wordNo, int input, bool isWriteValue)> datas = new List<(int wordNo, int input, bool isWriteValue)>();
|
|
// OCT 미사용 >> A(1) / B(2)
|
|
// OCT 사용 >> A(3) B(4)
|
|
var programNo = (int)_stage + (_oct.IsActivated ? 3 : 1);
|
|
datas.Add((csWriteNodeNo.PROGRAM_NO, programNo, true));
|
|
datas.Add((csWriteNodeNo.IW05, CoreRatio, true));
|
|
|
|
if (_oct.IsActivated) {
|
|
datas.Add((csWriteNodeNo.LIGHT_PATH_NO, (int)_stage, true));
|
|
_oct.LightPath = (int)_stage;
|
|
}
|
|
|
|
if (_laserCore.UpdatesDatasIfChanged(datas)) {
|
|
res = context.RetryUntilSuccess(() => _laserCore.GetProgramCompleted(), MOTION_TIMEOUT, MOTION_INTERVAL);
|
|
if (res == E2.TIMEOUT) {
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.LASER_READY);
|
|
return null;
|
|
} else if (res == E2.CANCELLED) {
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.LASER_READY);
|
|
return null;
|
|
}
|
|
}
|
|
Log.V($"Laser Program Update Complete [Ratio : {CoreRatio}] [Program No : {(int)_stage + 1}]");
|
|
res = context.RetryUntilSuccess(() => _laserCore.GetLaserReady() && _laserCore.GetProgramNo() == (int)programNo, MOTION_TIMEOUT, MOTION_INTERVAL);
|
|
if (res == E2.TIMEOUT) {
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.LASER_READY_PROGRAM_ACTIVATED_TIMEOUT);
|
|
return null;
|
|
} else if (res == E2.CANCELLED) {
|
|
context.PutValue<int>("AlarmCode", 0);
|
|
return null;
|
|
}
|
|
|
|
Log.V($"Laser Setting Complete {_stage}");
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
private static SequenceActionResult SetOCTParam(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
if (!_oct.IsActivated) {
|
|
Log.I("OCT Deactivated >> Setting Skip");
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
var res = context.RetryUntilSuccess(() => _oct.IsSensoricReady(), MOTION_TIMEOUT, MOTION_INTERVAL);
|
|
if (res == E2.TIMEOUT) {
|
|
Log.FuncE($"Sensoric Ready ON Timeout");
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.STAGE_A_OCT_SENSORIC_READY_ON_TIMEOUT);
|
|
return null;
|
|
}
|
|
Log.V($"Sensoric Ready ON Check OK");
|
|
|
|
_oct.SetInquiry1(true);
|
|
Log.V($"Laser Program Update Complete [INQUIRY_1 : true]");
|
|
Thread.Sleep(250);
|
|
|
|
_oct.SetPosGen(true);
|
|
Log.V($"SetPosGen : true");
|
|
Thread.Sleep(250);
|
|
|
|
_oct.SetPreTrigger(true);
|
|
Log.V($"SetPreTrigger : true");
|
|
Thread.Sleep(250);
|
|
|
|
|
|
res = context.RetryUntilSuccess(() => _oct.IsMeasureActive(), MOTION_TIMEOUT, MOTION_INTERVAL);
|
|
if (res == E2.TIMEOUT) {
|
|
Log.FuncE($"Measure Active ON Timeout");
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.STAGE_A_OCT_MEASURE_ACTIVATE_TIMEOUT);
|
|
return null;
|
|
}
|
|
Log.V($"Measure Active ON Check OK");
|
|
|
|
_oct.SetInTrigger(true);
|
|
Thread.Sleep(250);
|
|
Log.V($"SetInTrigger : true");
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
private static SequenceActionResult WeldingMotion(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
var coreRatio = (int)((_data[LineInLinesIndex].Core / (_data[LineInLinesIndex].Core + _data[LineInLinesIndex].Ring)) * 100);
|
|
var Max = 4000;
|
|
var CoreMax = Max * coreRatio;
|
|
var StraightVoltage = (_data[LineInLinesIndex].Core / CoreMax) * 1000;
|
|
|
|
// 볼트 켈 정도를 가져오기 위해 10을 곱해서 검색한다
|
|
_laserCal.Initialize(_laserCal.PowerCalibrationCenterBeamCSVFile, _laserCal.PowerCalibrationRingBeamCSVFile);
|
|
var RealStraightVoltage = (_laserCal.CalibratePercentToMeasuredVoltage((StraightVoltage * 10), (uint)LaserPowerCalibrationParam.beamMode.Center));
|
|
|
|
if (double.IsNaN(RealStraightVoltage) || RealStraightVoltage < 0.0)
|
|
RealStraightVoltage = 0.0;
|
|
|
|
var _startX = _data[LineInLinesIndex].StartX;
|
|
var _endX = _data[LineInLinesIndex].EndX;
|
|
var _velocity = _data[LineInLinesIndex].Velocity;
|
|
|
|
if (double.IsNaN(RealStraightVoltage) || RealStraightVoltage < 0.0)
|
|
RealStraightVoltage = 0.0;
|
|
|
|
_acsMotion.SetLCILserOn(_stage, RealStraightVoltage > 0);
|
|
_acsMotion.SetLineShot(_stage, RealStraightVoltage, _startX, _endX, _velocity);
|
|
if (_acsMotion.LineShotStart(_stage))
|
|
Log.V($">> {LineInLinesIndex} LineShot Start");
|
|
|
|
Thread.Sleep(500);
|
|
var res = context.RetryUntilSuccess(() => _acsMotion.CheckLineShotComp(_stage), SEQ_TIMEOUT, SEQ_CHECK_TIMER);
|
|
if (res == E2.TIMEOUT) {
|
|
Log.FuncV($">> {LineInLinesIndex} LineShot Fail");
|
|
return null;
|
|
} else if(res == E2.CANCELLED) {
|
|
Log.FuncV($">> {LineInLinesIndex} LineShot Cancel");
|
|
return null;
|
|
}
|
|
|
|
_data[LineInLinesIndex].State = "Done";
|
|
|
|
Log.V($"Laser Interlock Start");
|
|
_acsMotion.SetLCILserOn(_stage, false);
|
|
ProcessManager.Instance.EnableLaserUse(true);
|
|
Log.FuncV($">> {LineInLinesIndex++} : LineShot Complete");
|
|
|
|
Thread.Sleep(SLEEP_TIME_MS);
|
|
return SequenceAction.Ok();
|
|
}
|
|
private static SequenceActionResult CheckInterlock(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
if (_oct.IsActivated) {
|
|
_oct.SetInquiry1(false);
|
|
Log.V($"Laser Program Update Complete [INQUIRY_1 : false]");
|
|
Thread.Sleep(500);
|
|
|
|
var res = context.RetryUntilSuccess(() => _oct.IsMeasureActive(), MOTION_TIMEOUT, WELDING_TIMEOUT, false);
|
|
if (res == E2.TIMEOUT) {
|
|
Log.FuncE("Measure Active Off Check Timeout");
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.STAGE_A_OCT_SENSORIC_READY_OFF_TIMEOUT);
|
|
return null;
|
|
} else if (res == E2.CANCELLED) {
|
|
Log.FuncE("Measure Active Off Check Cancel");
|
|
context.PutValue<int>("AlarmCode", 0);
|
|
return null;
|
|
}
|
|
Log.V($"Measure Active Off Check OK");
|
|
|
|
_oct.SetOctReady(preTrigger: false, inTrigger: false, posGen: false);
|
|
Log.V($"OctReady(PreTrigger, InTrigger, PosGen) Parameter Off");
|
|
|
|
eOctControlOutputBit result = eOctControlOutputBit.ProcedureFaultSeam;
|
|
res = context.RetryUntilSuccess(() => {
|
|
var item = _oct.GetSeamResult();
|
|
result = item.result;
|
|
return item.success;
|
|
}, MOTION_TIMEOUT, MOTION_INTERVAL);
|
|
if (res == E2.TIMEOUT) {
|
|
Log.FuncE("Get Seam Result Timeout");
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.STAGE_A_OCT_GET_SEAM_RESULT_TIMEOUT);
|
|
return null;
|
|
} else if (res == E2.CANCELLED) {
|
|
Log.FuncE("Get Seam Result Cancel");
|
|
context.PutValue<int>("AlarmCode", 0);
|
|
return null;
|
|
}
|
|
if (result != eOctControlOutputBit.SeamOk)
|
|
Log.E($"Seam Result NG");
|
|
|
|
Log.W($"Seam Result value[{Enum.GetName(typeof(eOctControlOutputBit), result)}]");
|
|
|
|
res = context.RetryUntilSuccess(() => _oct.IsSensoricReady(), MOTION_TIMEOUT, MOTION_INTERVAL, false);
|
|
if (res == E2.TIMEOUT) {
|
|
Log.FuncE("Sensoric Ready Off Check Timeout");
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.STAGE_A_OCT_SENSORIC_READY_OFF_TIMEOUT);
|
|
return null;
|
|
} else if (res == E2.CANCELLED) {
|
|
Log.FuncE("Sensoric Ready Off Check Cancel");
|
|
context.PutValue<int>("AlarmCode", 0);
|
|
return null;
|
|
}
|
|
Log.V($"Sensoric Ready Off Check OK");
|
|
|
|
res = context.RetryUntilSuccess(() => _laserCore.GetProgramCompleted(), MOTION_TIMEOUT, MOTION_INTERVAL);
|
|
if (res == E2.TIMEOUT) {
|
|
Log.FuncE("Get Program Completed Check Timeout");
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.LASER_READY);
|
|
return null;
|
|
} else if (res == E2.CANCELLED) {
|
|
Log.FuncE("Get Program Completed Check Cancel");
|
|
context.PutValue<int>("AlarmCode", 0);
|
|
return null;
|
|
}
|
|
Log.V($"Get Program Completed Check OK");
|
|
|
|
//List<(int wordNo, int input, bool isWriteValue)> _datas = new List<(int wordNo, int input, bool isWriteValue)>();
|
|
//_datas.Add((csWriteNodeNo.PROGRAM_NO, 0, true));
|
|
//_datas.Add((csWriteNodeNo.LIGHT_PATH_NO, 0, true));
|
|
|
|
//if (_laserCore.UpdatesDatasIfChanged(_datas)) {
|
|
// res = context.RetryUntilSuccess(() => _laserCore.GetProgramCompleted(), MOTION_TIMEOUT, MOTION_INTERVAL);
|
|
// if (res == E2.TIMEOUT) {
|
|
// Log.FuncE("Laser Program Update Timeout");
|
|
// context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.LASER_READY);
|
|
// return null;
|
|
// } else if (res == E2.CANCELLED) {
|
|
// Log.FuncE("Laser Program Update Cancel");
|
|
// context.PutValue<int>("AlarmCode", 0);
|
|
// return null;
|
|
// }
|
|
//}
|
|
//Log.V($"Laser Program Update Complete [Program No : 0] [Light Path No : 0]");
|
|
_laserCore.SetData(csWriteNodeNo.PSTART_STATICAL, 0);
|
|
Log.V($"Laser Program [PStatic : 0]");
|
|
Thread.Sleep(250);
|
|
|
|
//res = context.RetryUntilSuccess(() => _laserCore.GetLaserReady(), MOTION_TIMEOUT, MOTION_INTERVAL);
|
|
//if (res == E2.TIMEOUT) {
|
|
// Log.FuncE("Get Laser Ready True Timeout");
|
|
// context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.LASER_READY);
|
|
// return null;
|
|
//} else if (res == E2.CANCELLED) {
|
|
// Log.FuncE("Get Laser Ready True Cancel");
|
|
// context.PutValue<int>("AlarmCode", 0);
|
|
// return null;
|
|
//}
|
|
//Log.FuncE("Get Laser Ready True OK");
|
|
|
|
_laserCore.SetData(csWriteNodeNo.PROGRAM_NO, 0);
|
|
_laserCore.SetData(csWriteNodeNo.LIGHT_PATH_NO, 0);
|
|
Log.V($"Laser Program [Program No : 0] [Light Path No : 0]");
|
|
Thread.Sleep(250);
|
|
|
|
_laserCore.SetData(csWriteNodeNo.EXT_ACTIVATION, 0);
|
|
_laserCore.SetData(csWriteNodeNo.LASER_ON, 0);
|
|
_laserCore.SetData(csWriteNodeNo.REQUEST_LASER, 0);
|
|
Log.V($"Laser Program [ExtActivation: 0] [LaserOn : 0] [RequestLaser : 0]");
|
|
|
|
res = context.RetryUntilSuccess(() => _laserCore.GetLaserReady(), MOTION_TIMEOUT, MOTION_INTERVAL, false);
|
|
if (res == E2.TIMEOUT) {
|
|
Log.FuncE("Get Program Completed Check Timeout");
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.LASER_READY);
|
|
return null;
|
|
} else if (res == E2.CANCELLED) {
|
|
Log.FuncE("Get Program Completed Check Cancel");
|
|
context.PutValue<int>("AlarmCode", 0);
|
|
return null;
|
|
}
|
|
Log.FuncE("Get Laser Ready False OK");
|
|
//Thread.Sleep(100);
|
|
//result = eOctControlOutputBit.ProcedureFaultPart;
|
|
//res = context.RetryUntilSuccess(() => {
|
|
// var item = _oct.GetPartResult();
|
|
// result = item.result;
|
|
// return item.success;
|
|
//}, MOTION_TIMEOUT, MOTION_INTERVAL);
|
|
//if (res == E2.TIMEOUT) {
|
|
// context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.STAGE_A_OCT_GET_PART_RESULT_TIMEOUT);
|
|
// return null;
|
|
//}
|
|
//if (result != eOctControlOutputBit.PartOk)
|
|
// _targetCell.weldingData.NgJudge = (int)JudgeType.OCT_MEASURE;
|
|
//Log.W($"{_targetCell.ToString()} Part Result value[{Enum.GetName(typeof(eOctControlOutputBit), result)}]");
|
|
|
|
Thread.Sleep(100);
|
|
}
|
|
|
|
return SequenceAction.Ok();
|
|
}
|
|
private static SequenceActionResult MotionInterlock(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
if (Status.EquipmentStatus == eEqpStatus.Manual) {
|
|
_laserCore.LaserOff();
|
|
Log.I("Manual Laser Off");
|
|
}
|
|
|
|
// UnClamp
|
|
Log.V($"{_stage} Unclamp Start");
|
|
if (!_io.CheckUnclampComp(_stage)){
|
|
_acsMotion.UnClampStart(_stage);
|
|
|
|
var _res = context.RetryUntilSuccess(() => _io.CheckUnclampComp(_stage), MOTION_TIMEOUT, MOTION_INTERVAL);
|
|
if (_res == E2.TIMEOUT) {
|
|
if (_stage == eStage.A)
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.STAGE_A_CLAMP_TIMEOUT);
|
|
else
|
|
context.PutValue<int>("AlarmCode", AlarmCode_PrismaticGun.STAGE_B_CLAMP_TIMEOUT);
|
|
return null;
|
|
} else if (_res == E2.CANCELLED) {
|
|
context.PutValue<int>("AlarmCode", 0);
|
|
return null;
|
|
}
|
|
}
|
|
Log.V($"{_stage} Unclamp Complete");
|
|
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
|
|
private static SequenceActionResult LineProcessComplete(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
LineInLinesIndex = 0;
|
|
ProcessManager.Instance.EnableLaserUse(true);
|
|
_mfc.WriteSetPoint(0); // MFC
|
|
_laser.LaserOff();
|
|
_acsMotion.SetLCILserOn(_stage, false);
|
|
Log.FuncV(">> All LineShot Complete");
|
|
MessageUtil.ShowSuccessToast(">> All LineShot Complete");
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
private static void OnStopped(SequenceContext context)
|
|
{
|
|
LineInLinesIndex = 0;
|
|
ProcessManager.Instance.EnableLaserUse(true);
|
|
_mfc.WriteSetPoint(0); // MFC
|
|
_laser.LaserOff();
|
|
_acsMotion.SetLCILserOn(_stage, false);
|
|
|
|
if (_oct.IsActivated) {
|
|
_oct.SetInquiry1(false);
|
|
Thread.Sleep(500);
|
|
|
|
_oct.SetOctReady(preTrigger: false, inTrigger: false, posGen: false);
|
|
Thread.Sleep(500);
|
|
}
|
|
|
|
Log.FuncV(">> All LineShot Fail");
|
|
MessageUtil.ShowWarningToast(">> Sequence Stop");
|
|
return;
|
|
}
|
|
|
|
private static void OnForceError(SequenceContext context, string arg2)
|
|
{
|
|
LineInLinesIndex = 0;
|
|
ProcessManager.Instance.EnableLaserUse(true);
|
|
_mfc.WriteSetPoint(0); // MFC
|
|
_laser.LaserOff();
|
|
_acsMotion.SetLCILserOn(_stage, false);
|
|
|
|
if (_oct.IsActivated) {
|
|
_oct.SetInquiry1(false);
|
|
Thread.Sleep(500);
|
|
|
|
_oct.SetOctReady(preTrigger: false, inTrigger: false, posGen: false);
|
|
Thread.Sleep(500);
|
|
}
|
|
|
|
Log.FuncV(">> All LineShot Fail");
|
|
MessageUtil.ShowErrorToast(">> Sequence Fail");
|
|
return;
|
|
}
|
|
}
|
|
}
|