3759 lines
173 KiB
C#
3759 lines
173 KiB
C#
using Aurora;
|
|
using Aurora.Api;
|
|
using Aurora.Api.Control;
|
|
using Aurora.Api.Devices;
|
|
using Aurora.Api.Manager;
|
|
using Aurora.Util.HislogPlus;
|
|
using Aurora.View;
|
|
using AuroraCellTracker;
|
|
using AuroraIO;
|
|
using AuroraLaser;
|
|
using AuroraLaserScanner;
|
|
using AuroraLBAD;
|
|
using AuroraLBAD.Service;
|
|
using AuroraOCT;
|
|
using AuroraPLC;
|
|
using CoreUnit.Control.UserControl.Canvas;
|
|
using CoreUnit.Scanner.UserControl.ScannerCanvas;
|
|
using DB;
|
|
using DB.Recipe;
|
|
using ExcelImageHelper;
|
|
using Hermes;
|
|
using ILSOS_KS.Device;
|
|
using ILSOS_KS.Models;
|
|
using ILSOS_KS.RMS;
|
|
using ILSOS_KS.Views.Dialog;
|
|
using ILSOS_KS.Views.PopUP;
|
|
using Matrox.MatroxImagingLibrary;
|
|
using MilUI;
|
|
using NPOI.SS.Formula.Functions;
|
|
using NPOI.SS.Formula.PTG;
|
|
using NPOI.Util;
|
|
using OpenCvSharp;
|
|
using OpenCvSharp.Dnn;
|
|
using OpenCvSharp.Text;
|
|
using OpenCvSharp.WpfExtensions;
|
|
using Org.BouncyCastle.Asn1.Tsp;
|
|
using System;
|
|
using System.CodeDom.Compiler;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.Configuration;
|
|
using System.Diagnostics;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Net.NetworkInformation;
|
|
using System.Runtime.InteropServices.ComTypes;
|
|
using System.Runtime.Remoting.Contexts;
|
|
using System.Runtime.Remoting.Metadata.W3cXsd2001;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using System.Windows.Controls.Primitives;
|
|
using System.Windows.Forms;
|
|
using System.Windows.Forms.VisualStyles;
|
|
using System.Windows.Media.Imaging;
|
|
using System.Windows.Shapes;
|
|
using System.Xml.Linq;
|
|
using VisionCommon;
|
|
using WeldingCommon;
|
|
using WeldingCommon.Alarm;
|
|
using WeldingCommon.Data;
|
|
using WeldingCommon.Devices;
|
|
using WeldingCommon.Recipes;
|
|
using WeldingCommon.Sequences;
|
|
using WeldingCommon.Settings;
|
|
using WeldingCommon.Utils;
|
|
using WeldingCommon.Views;
|
|
using WeldingCommon.Vision.WeldingObjectGenerator;
|
|
//using System.Windows.Shapes;
|
|
using WeldingCommon.Vision.WeldingObjectGenerator.GeometryLibrary;
|
|
using WeldingCommon.Vision.WeldingObjectGenerator.PathEditorLibrary;
|
|
using static Aurora.Api.SequenceBuilder;
|
|
using static AuroraIO.AJINEXTEK.AjinIO.IOModuleInfo;
|
|
using static AuroraLBAD.Device.LBAD_PILOT;
|
|
using static AuroraLBAD.Service.StreamLightLBAD;
|
|
using static AuroraLBAD.Services.StreamLBADClient;
|
|
using static ILSOS_KS.Device.IOController_KS;
|
|
using static ILSOS_KS.Device.PLCControllerKS;
|
|
using static WeldingCommon.Views.UCLBADDeviceViewModel;
|
|
using Application = System.Windows.Application;
|
|
using Line = CoreUnit.Control.UserControl.Canvas.Line;
|
|
using Path = System.IO.Path;
|
|
using Point = OpenCvSharp.Point;
|
|
using SystemParameter = WeldingCommon.Settings.SystemParameter;
|
|
|
|
namespace ILSOS_KS.Sequences
|
|
{
|
|
class SeqAutoRunKS
|
|
{
|
|
static readonly Logger Log = new Logger("SeqAutoRunKS_New");
|
|
|
|
const string SEQ_ENTER = "[SeqAutoRunKS] SEQ_ENTER"; // inputParam 으로 받자.
|
|
const string SEQ_CHECK_INIT_CONDITION = "[SeqAutoRunKS] Check Init Condition"; // Check Init Condition
|
|
|
|
// ADD jmj -> 메인페이지 레시피 넘버 확인하여 PLC에 전송후 메칭 확인
|
|
// Page 번호 가져오기.
|
|
const string SEQ_CHECK_PAGENO = "[SeqAutoRunKS] CHECK PageNo";
|
|
|
|
const string SEQ_CHECK_LOAD_COMPLETE = "[SeqAutoRunKS] Check Load Complete";
|
|
|
|
// 양선전 사전검사 로직 추가(용접후 검사 결과를 보고 하구 나서 양산 시작)
|
|
const string SEQ_KS_WAIT_VISION = "[SeqAutoRunKS] Ks Wait Vision";
|
|
const string SEQ_KS_COMPLETE_VISION = "[SeqAutoRunKS] Ks Complete Vision";
|
|
|
|
//const string SEQ_MEASURE_CELL_POSITION = "[SeqAutoRunKS] Measure CellPosition";
|
|
|
|
const string SEQ_SET_SCOUT_FLYING_VISION_SEQ = "[SeqAutoRunKS] Set Sequence Param (ScoutFlyingVision Seq)";
|
|
const string SEQ_DO_ID_SCOUT_FLYING_VISION_SEQ = "[SeqAutoRunKS] Process (ScoutFlyingVision Seq)";
|
|
const string SEQ_GET_SCOUT_FLYING_VISION_SEQ = "[SeqAutoRunKS] Get Sequence Result (ScoutFlyingVision Seq)";
|
|
|
|
const string SEQ_SET_SCOUT_NORMAL_VISION_SEQ = "[SeqRCCTeachingRun] Set Sequence Param (ScoutNormalVision Seq)";
|
|
const string SEQ_DO_ID_SCOUT_NORMAL_VISION_SEQ = "[SeqRCCTeachingRun] Process (ScoutNormalVision Seq)";
|
|
const string SEQ_GET_SCOUT_NORMAL_VISION_SEQ = "[SeqRCCTeachingRun] Get Sequence Result (ScoutNormalVision Seq)";
|
|
|
|
const string SEQ_SEND_EVENT_SENDER = "[SeqAutoRunKS] Event Sender";
|
|
const string SEQ_EVENT_Q_SAVE_FILE = "[SeqAutoRunKS] EventQ Save File";
|
|
const string SEQ_SAVE_SCOUT_IMAGE = "[SeqAutoRunKS] Save ScoutImage";
|
|
|
|
const string SEQ_FIND_EDGE = "[SeqAutoRunKS] Find Edge";
|
|
const string SEQ_DECISION_RCC_ALGORITHM_TYPE = "[SeqAutoRunKS] Decision RCC Algorithm Type";
|
|
const string SEQ_APPLY_OFFSET_OBJECT = "[SeqAutoRunKS] Apply Offset Object";
|
|
const string SEQ_GENERATE_WELDING_OBJECT = "[SeqAutoRunKS] Generate WeldingObject";
|
|
|
|
const string SEQ_READY_SCANNER_LIST = "[SeqAutoRunKS] Ready ScannerList";
|
|
const string SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ = "[SeqAutoRunKS] Set Sequence Param (UploadWeldingList Seq)";
|
|
const string SEQ_DO_ID_UPLOAD_WELDING_LIST_SEQ = "[SeqAutoRunKS] Process (UploadWeldingList Seq)";
|
|
const string SEQ_GET_RESULT_UPLOAD_WELDING_LIST_SEQ = "[SeqAutoRunKS] Get Sequence Result (UploadWeldingList Seq)";
|
|
|
|
const string SEQ_WAIT_WELDING_START = "[SeqAutoRunKS] Wait Welding Start";
|
|
|
|
const string SEQ_SET_PARAMS_RECEIVE_CELL_INFO_SEQ = "[SeqAutoRunKS] Set Sequence Param (ReceiveCellInfo Seq)";
|
|
const string SEQ_DO_ID_RECEIVE_CELL_INFO_SEQ = "[SeqAutoRunKS] Process (ReceiveCellInfo Seq)";
|
|
const string SEQ_GET_PARAMS_RECEIVE_CELL_INFO_SEQ = "[SeqAutoRunKS] Get Sequence Result (ReceiveCellInfo Seq)";
|
|
|
|
const string SEQ_EXECUTE_WELDING = "[SeqAutoRunKS] Execute Welding";
|
|
const string SEQ_REQUEST_UNLOAD_CELL = "[SeqAutoRunKS] Request Unload Cell";
|
|
const string SEQ_WAIT_LBAD_JUDGE = "[SeqAutoRunKS] Wait LBAD Judge";
|
|
|
|
//const string SEQ_SET_PARAMS_REPORT_CELL_RESULT_SEQ = "[SeqAutoRunKS] Set Sequence Param (ReportCellResult Seq)";
|
|
//const string SEQ_DO_ID_REPORT_CELL_RESULT_SEQ = "[SeqAutoRunKS] Process (ReportCellResult Seq)";
|
|
//const string SEQ_GET_RESULT_REPORT_CELL_RESULT_SEQ = "[SeqAutoRunKS] Get Sequence Result (ReportCellResult Seq)";
|
|
|
|
const string SEQ_REPORT_CELLINFO_TO_PLC = "[SeqAutoRunKS] ReportCellInfoToPLC";
|
|
const string SEQ_CHECK_CYCLE_STOP = "[SeqAutoRunKS] Check Cycle Stop";
|
|
|
|
const string SEQ_SAVE_RESULT_DATA = "[SeqAutoRunKS] Save Result Data";
|
|
|
|
const string SEQ_WRITE_COMPLETION_PLC_BIT = "[SeqAutoRunKS] Write Completion PLC Bit";
|
|
const string SEQ_COMPLETE = "[SeqAutoRunKS] SEQ_COMPLETE"; // 완료
|
|
|
|
const string SEQ_BEFORE_WELD_MOVE_OBJECT = "[SeqAutoRunKS] Before Weld Move Object";
|
|
const string SEQ_AFTER_WELD_CHECK_BEAD = "[SeqAutoRunKS] After Weld Check Bead";
|
|
const string SEQ_CHECK_RCC_MODE = "[SeqAutoRunKS] Check RCC Mode";
|
|
const string SEQ_CHECK_BEFORE_OR_AFTER = "[SeqRCCTeachingRun] Check before or after";
|
|
|
|
static class ContextKey
|
|
{
|
|
public const string KEY_SEQUENCE_RESULT = "KEY_SEQUENCE_RESULT_SeqAutoRunKS";
|
|
public const string KEY_SEQUENCE_START_TIME = "KEY_SEQUENCE_START_TIME_SeqAutoRunKS";
|
|
}
|
|
|
|
const int PLC_TIMEOUT = 60; // sec, Timeout은 시퀀스 정지가 아니라 타임아웃 시간마다 로그만 남기도록 한다
|
|
|
|
private SeqAutoRunKS_New_InitParam _InitParam;
|
|
|
|
private Scanner _Scanner;
|
|
private LaserDevice _Laser;
|
|
//private OCT _OCT;
|
|
private PLCControllerKS _PLC;
|
|
private IODevice _IO;
|
|
private LBAD _LBAD;
|
|
//private StreamLightLBAD _StreamLightLBAD;
|
|
private SystemParameter _SystemParameter;
|
|
private IRecipeManager _RecipeManager;
|
|
private ScannerCanvasUserCtrl _ScannerCanvasUserCtrl; //스캐너 동작관련 객체 선언
|
|
|
|
private FovRecipe _FovRecipe;
|
|
private CameraAgentBase _CameraAgent;
|
|
private ICameraDisplay _CameraDisplay;
|
|
private CamConfig _CamConfig;
|
|
|
|
private eListNo _WeldingScannerListNo;
|
|
private List<IDrawObject> _SelectedDrawObjectList;
|
|
|
|
private MIL_ID _GrabImage = MIL.M_NULL;
|
|
private ObjectGenerator _ObjGenerator;
|
|
private Mat _ConvMatImage;
|
|
private Mat _ConvMatImage_after;
|
|
|
|
private Mat[] _WeldingImage = new Mat[4];
|
|
|
|
private uint _TodayProduct;
|
|
private uint _TotalProduct;
|
|
private uint _OCT_QA_ERROR_COUNT;
|
|
|
|
private DateTime _AutoRunStartTime;
|
|
private DateTime _WeldingStartTime;
|
|
private TimeSpan _WeldingSpanTime;
|
|
private DateTime _WeldEndTime;
|
|
private TimeSpan _InterfaceSpanTime;
|
|
private DateTime _InterfaceStartTime;
|
|
|
|
private string _LotId = "N/A";
|
|
private string _CellId = "N/A";
|
|
|
|
private bool _IncludeListStartEnd = false; // ==> local
|
|
|
|
private int _SeqRunCount;
|
|
|
|
// For RCC
|
|
private List<IDrawObject> _GeneratedDrawObjects;
|
|
private List<IDrawObject> _RecipeDrawObjects; // ==> local
|
|
|
|
private Stopwatch _StopwatchGenObj;
|
|
|
|
private int _Radius_Pixel;
|
|
// End For RCC
|
|
|
|
private int _ModelNo;
|
|
|
|
private int _PageNo = 0;
|
|
private int _PageNoRcc = 0;
|
|
private string _BcrID;
|
|
|
|
private bool _IsRealTimeScout;
|
|
private double _CellMeasureCenterOffsetX;
|
|
private double _CellMeasureCenterOffsetY;
|
|
|
|
public string EVENT_TRIGGER_SAVE_FILE = "EventTriggerSaveFile";
|
|
private UnitPoint _DetectedContourCenter;
|
|
private Point[][] _MaxContour;
|
|
private List<TPoint> _Polygon;
|
|
private List<PathItem> _Paths;
|
|
private List<Arc> _SelectedArcs;
|
|
private bool pre_welding = true;
|
|
private List<double> bead_result_info; //상위보고를 위한 비드 사이즈 저장 리스트 (OK:0, NG:1)
|
|
private List<double>[] result_info = new List<double>[4];
|
|
// 경신 검수용 LBAD 검사 결과 OK,NG 반전 ..
|
|
bool weldingResult = false;
|
|
|
|
eScoutType _ScoutType;
|
|
|
|
int[] LBADResultPage = new int[4];
|
|
|
|
IPopupService popup;
|
|
|
|
public bool RecipeChange = false;
|
|
|
|
ScannerObjectInfo arcinfo = new ScannerObjectInfo();
|
|
ScannerObjectInfo lineinfo = new ScannerObjectInfo();
|
|
ScannerObjectInfo splineinfo = new ScannerObjectInfo();
|
|
ScannerObjectInfo dotinfo = new ScannerObjectInfo();
|
|
|
|
string StepLBAD = "";
|
|
string StepWELDING = "";
|
|
|
|
short recipeRequestId = 1;
|
|
|
|
bool ksExit = false;
|
|
|
|
int[] ResultDataList = new int[4];
|
|
|
|
public SeqAutoRunKS()
|
|
{
|
|
var systemParameterks = Application.Current.AuroraEnv().SettingEntry[CommonSettingIds.SystemParameter] as SystemParameter;
|
|
_ScoutType = systemParameterks.ScoutType;
|
|
|
|
Application.Current.AuroraEnv().EventObservable.AsObservable("Pre_Test").Subscribe(OnPre_Test);
|
|
|
|
|
|
string Path = System.IO.Path.Combine(ConfigurationManager.AppSettings.Get("DATA_PATH"), "_vision", "RealTimeScout",
|
|
string.Format($"{DateTime.Now.Year}_{DateTime.Now.Month}_{DateTime.Now.Day}/"));
|
|
AsyncLog.Init(Path);
|
|
|
|
PopupService.Init();
|
|
popup = PopupService.Instance;
|
|
}
|
|
|
|
public SequenceBuilder Builder()
|
|
{
|
|
var sb = new SequenceBuilder(100000, true);
|
|
////var sb = new SequenceBuilder(1000, false); // With log
|
|
|
|
sb.AddAction(SEQ_ENTER, Sequence_Enter);
|
|
sb.AddDecision(SEQ_CHECK_INIT_CONDITION, CheckInitCondition); //분기
|
|
|
|
sb.AddAction(SEQ_CHECK_PAGENO, CheckPageNo);
|
|
|
|
sb.AddDecision(SEQ_CHECK_LOAD_COMPLETE, CheckLoadComplete);
|
|
|
|
sb.AddAction(SEQ_KS_WAIT_VISION, KSWaitVisionSquence);
|
|
sb.AddAction(SEQ_KS_COMPLETE_VISION, KSCompleteVisionSquence);
|
|
|
|
// RCC FlyingVision
|
|
sb.AddAction(SEQ_SET_SCOUT_FLYING_VISION_SEQ, SetScoutFlyingVision_SeqParams);
|
|
sb.AddSubsequence(SEQ_DO_ID_SCOUT_FLYING_VISION_SEQ, SequenceManager.GetSeqBuilder_SeqScoutFlyingVision());
|
|
sb.AddAction(SEQ_GET_SCOUT_FLYING_VISION_SEQ, GetScoutFlyingVision_SeqResult);
|
|
//sb.AddDecision(SEQ_GET_SCOUT_FLYING_VISION_SEQ, GetScoutFlyingVision_SeqResult);
|
|
|
|
|
|
|
|
|
|
sb.AddEventSender(SEQ_SEND_EVENT_SENDER, SendEvent);
|
|
sb.AddEventQ(SEQ_EVENT_Q_SAVE_FILE, 2);
|
|
sb.AddAction(SEQ_SAVE_SCOUT_IMAGE, SaveScoutImageEvent);
|
|
|
|
sb.AddAction(SEQ_FIND_EDGE, FindEdge);
|
|
sb.AddDecision(SEQ_DECISION_RCC_ALGORITHM_TYPE, DecisionRCCAlgorithmType);
|
|
sb.AddAction(SEQ_APPLY_OFFSET_OBJECT, ApplyOffsetObejct);
|
|
sb.AddAction(SEQ_GENERATE_WELDING_OBJECT, GenerateWeldingObject);
|
|
|
|
//Image Processing
|
|
sb.AddDecision(SEQ_BEFORE_WELD_MOVE_OBJECT, BeforeWeldMoveObject);
|
|
sb.AddAction(SEQ_AFTER_WELD_CHECK_BEAD, AfterWeldCheckBead);
|
|
sb.AddDecision(SEQ_CHECK_RCC_MODE, CheckRCCMode);
|
|
sb.AddDecision(SEQ_CHECK_BEFORE_OR_AFTER, CheckBeforeOrAfter);
|
|
|
|
|
|
// ALL (Normal & RCC & CellCenterOffset)
|
|
sb.AddAction(SEQ_READY_SCANNER_LIST, ReadyScannerList);
|
|
sb.AddAction(SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ, SetUploadWeldingList_SeqParams);
|
|
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_WAIT_WELDING_START, WaitWeldingStart);
|
|
|
|
sb.AddAction(SEQ_SET_PARAMS_RECEIVE_CELL_INFO_SEQ, SetReceiveCellInfo_SeqParams);
|
|
sb.AddSubsequence(SEQ_DO_ID_RECEIVE_CELL_INFO_SEQ, SequenceManager.GetSeqBuilder_SeqReceiveCellInfo());
|
|
sb.AddAction(SEQ_GET_PARAMS_RECEIVE_CELL_INFO_SEQ, GetReceiveCellInfo_SeqResult);
|
|
|
|
sb.AddAction(SEQ_EXECUTE_WELDING, ExecuteWelding);
|
|
sb.AddAction(SEQ_REQUEST_UNLOAD_CELL, RequestUnloadCell);
|
|
sb.AddAction(SEQ_WAIT_LBAD_JUDGE, WaitLBADJudge);
|
|
|
|
sb.AddAction(SEQ_REPORT_CELLINFO_TO_PLC, ReportCellInfoToPLC);
|
|
|
|
sb.AddDecision(SEQ_CHECK_CYCLE_STOP, CheckCycleStop);
|
|
|
|
sb.AddAction(SEQ_SAVE_RESULT_DATA, SaveResultData); // 해당 공정의 정보를 기록 함.
|
|
sb.AddAction(SEQ_WRITE_COMPLETION_PLC_BIT, WriteCompletionPLCBit); // 정상적으로 종료 되면, complete bit write
|
|
sb.AddAction(SEQ_COMPLETE, Complete);
|
|
|
|
|
|
sb.Flows(sb.Init > sb[SEQ_ENTER] > sb[SEQ_CHECK_INIT_CONDITION]
|
|
> sb[SEQ_CHECK_PAGENO]
|
|
> sb[SEQ_CHECK_LOAD_COMPLETE] > sb[SEQ_READY_SCANNER_LIST]
|
|
> sb[SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ] > sb[SEQ_DO_ID_UPLOAD_WELDING_LIST_SEQ] > sb[SEQ_GET_RESULT_UPLOAD_WELDING_LIST_SEQ]
|
|
> sb[SEQ_WAIT_WELDING_START]
|
|
> sb[SEQ_SET_PARAMS_RECEIVE_CELL_INFO_SEQ] > sb[SEQ_DO_ID_RECEIVE_CELL_INFO_SEQ] > sb[SEQ_GET_PARAMS_RECEIVE_CELL_INFO_SEQ]
|
|
> sb[SEQ_EXECUTE_WELDING]
|
|
> sb[SEQ_CHECK_RCC_MODE]
|
|
> sb[SEQ_REQUEST_UNLOAD_CELL] > sb[SEQ_WAIT_LBAD_JUDGE]
|
|
// 상위 보고 추가 해야된다.
|
|
//> sb[SEQ_SET_PARAMS_REPORT_CELL_RESULT_SEQ] > sb[SEQ_DO_ID_REPORT_CELL_RESULT_SEQ] > sb[SEQ_GET_RESULT_REPORT_CELL_RESULT_SEQ]
|
|
|
|
> sb[SEQ_REPORT_CELLINFO_TO_PLC] > sb[SEQ_CHECK_CYCLE_STOP]
|
|
> sb[SEQ_SAVE_RESULT_DATA] > sb[SEQ_WRITE_COMPLETION_PLC_BIT] > sb[SEQ_COMPLETE]);
|
|
|
|
// CellCenterOffset
|
|
//sb.Flows(sb[SEQ_CHECK_LOAD_COMPLETE] > sb[SEQ_MEASURE_CELL_POSITION] > sb[SEQ_READY_SCANNER_LIST]);
|
|
|
|
|
|
// RCC
|
|
sb.Flows(sb[SEQ_CHECK_LOAD_COMPLETE]
|
|
// RCC FlyingVision
|
|
> sb[SEQ_SET_SCOUT_FLYING_VISION_SEQ] > sb[SEQ_DO_ID_SCOUT_FLYING_VISION_SEQ] > sb[SEQ_GET_SCOUT_FLYING_VISION_SEQ]
|
|
> sb[SEQ_SEND_EVENT_SENDER].Send(EVENT_TRIGGER_SAVE_FILE) > sb[SEQ_CHECK_BEFORE_OR_AFTER]
|
|
> sb[SEQ_BEFORE_WELD_MOVE_OBJECT] > sb[SEQ_READY_SCANNER_LIST]);
|
|
|
|
// RCC NG인 경우
|
|
sb.Flows(sb[SEQ_BEFORE_WELD_MOVE_OBJECT] > sb[SEQ_CHECK_PAGENO]);
|
|
|
|
sb.Flows(sb[SEQ_CHECK_RCC_MODE]
|
|
// RCC FlyingVision
|
|
> sb[SEQ_SET_SCOUT_FLYING_VISION_SEQ] > sb[SEQ_DO_ID_SCOUT_FLYING_VISION_SEQ] > sb[SEQ_GET_SCOUT_FLYING_VISION_SEQ]
|
|
> sb[SEQ_SEND_EVENT_SENDER].Send(EVENT_TRIGGER_SAVE_FILE) > sb[SEQ_CHECK_BEFORE_OR_AFTER]
|
|
> sb[SEQ_AFTER_WELD_CHECK_BEAD] > sb[SEQ_REQUEST_UNLOAD_CELL]);
|
|
|
|
// 사전 검사 프로세스 추가
|
|
sb.Flows(sb[SEQ_CHECK_LOAD_COMPLETE]
|
|
> sb[SEQ_KS_WAIT_VISION]
|
|
//> sb[SEQ_SET_SCOUT_FLYING_VISION_SEQ] > sb[SEQ_DO_ID_SCOUT_FLYING_VISION_SEQ] > sb[SEQ_GET_SCOUT_FLYING_VISION_SEQ]
|
|
//> sb[SEQ_SEND_EVENT_SENDER].Send(EVENT_TRIGGER_SAVE_FILE) > sb[SEQ_CHECK_BEFORE_OR_AFTER] > sb[SEQ_AFTER_WELD_CHECK_BEAD]
|
|
> sb[SEQ_KS_COMPLETE_VISION]
|
|
> sb[SEQ_CHECK_PAGENO]);
|
|
|
|
|
|
// Scout Image Save Event Seq
|
|
sb.Flows(sb[SEQ_EVENT_Q_SAVE_FILE].On(EVENT_TRIGGER_SAVE_FILE) > sb[SEQ_SAVE_SCOUT_IMAGE] > sb.FlowFinal);
|
|
|
|
//sb.Flows(sb[SEQ_CHECK_CYCLE_STOP] > sb[SEQ_CHECK_LOAD_COMPLETE]);
|
|
sb.Flows(sb[SEQ_CHECK_CYCLE_STOP] > sb[SEQ_CHECK_PAGENO]);
|
|
|
|
sb.Flows(sb[SEQ_CHECK_INIT_CONDITION] > sb[SEQ_COMPLETE] > sb.Final);
|
|
|
|
|
|
sb.OnStopped(OnStopped);
|
|
sb.OnForceError(OnForceError);
|
|
|
|
|
|
sb.Draw("SeqAutoRunKS_New.pdf");
|
|
|
|
//popup.Generation();
|
|
|
|
return sb;
|
|
}
|
|
|
|
#region 양선전 사전검사 로직 추가(용접후 검사 결과를 보고 하구 나서 양산 시작)
|
|
private void OnPre_Test(EventMessage message)
|
|
{
|
|
Log.I("OnPre_Test");
|
|
}
|
|
|
|
private SequenceActionResult KSWaitVisionSquence(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_READY, true);
|
|
Log.I(string.Format($"[PLCInterface]SET PC_WELD_READY True"));
|
|
|
|
Thread.Sleep(200);
|
|
|
|
_InterfaceStartTime = DateTime.Now;
|
|
while (!context.Stopped)
|
|
{
|
|
if (_PLC.ReadBit((int)eBitInput.PLC_WELD_REQEUST).data)
|
|
{
|
|
Log.I(string.Format($"[PLCInterface]GET PLC_WELD_REQEUST True"));
|
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_REQEUST_ACK, true);
|
|
Log.I(string.Format($"[PLCInterface]SET PC_WELD_REQEUST_ACK True"));
|
|
|
|
break;
|
|
}
|
|
|
|
_InterfaceSpanTime = DateTime.Now.Subtract(_InterfaceStartTime);
|
|
if (_InterfaceSpanTime.TotalMilliseconds > (PLC_TIMEOUT * 1000))
|
|
{
|
|
Log.E("TIMEOUT_PLC_WELD_REQEUST");
|
|
_InterfaceStartTime = DateTime.Now;
|
|
}
|
|
Thread.Sleep(10);
|
|
}
|
|
|
|
Thread.Sleep(200);
|
|
|
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_REQEUST_ACK, false);
|
|
Log.I(string.Format($"[PLCInterface]SET PC_WELD_REQEUST_ACK False"));
|
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_READY, false);
|
|
Log.I(string.Format($"[PLCInterface]SET PC_WELD_READY False"));
|
|
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
private SequenceActionResult KSCompleteVisionSquence(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE, true);
|
|
Log.I(string.Format($"[PLCInterface]SET PC_WELD_COMPLETE True"));
|
|
|
|
Thread.Sleep(200);
|
|
|
|
_InterfaceStartTime = DateTime.Now;
|
|
while (!context.Stopped)
|
|
{
|
|
if (_PLC.ReadBit((int)eBitInput.PLC_WELD_COMPLETE_ACK).data)
|
|
{
|
|
Log.I(string.Format($"[PLCInterface]GET PLC_WELD_COMPLETE_ACK True"));
|
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE, false);
|
|
Log.I(string.Format($"[PLCInterface]SET PC_WELD_COMPLETE False"));
|
|
break;
|
|
}
|
|
_InterfaceSpanTime = DateTime.Now.Subtract(_InterfaceStartTime);
|
|
if (_InterfaceSpanTime.TotalMilliseconds > (PLC_TIMEOUT * 1000))
|
|
{
|
|
Log.E("TIMEOUT_PLC_WELD_COMPLETE_ACK");
|
|
_InterfaceStartTime = DateTime.Now;
|
|
}
|
|
Thread.Sleep(10);
|
|
}
|
|
|
|
while (!context.Stopped)
|
|
{
|
|
// 다음 페이지용 PLC 읽기
|
|
_PageNo = GetPagePlc();
|
|
SetPagePlc(_PageNo);
|
|
|
|
// 다음 시퀀스 대기..
|
|
Thread.Sleep(100);
|
|
|
|
if (_PLC.ReadBit((int)eBitInput.PLC_WELD_REQEUST).data)
|
|
{
|
|
Log.I(string.Format($"[IOInterface]Get PLC_WELD_REQEUST True"));
|
|
|
|
bool[] Page = new bool[4];
|
|
Page = new bool[4] { false, false, false, false };
|
|
_PLC.WriteBitBlock((int)eBitOutput.PC_WELD_PAGE_CHANGE_COMPLETE_1, 4, Page);
|
|
Log.I(string.Format("[PLCInterface]Pgae Reset"));
|
|
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if (_PLC.ReadBit((int)eBitInput.PLC_RESULT_REQUEST).data)
|
|
{
|
|
Log.I(string.Format($"[IOInterface]Get PLC_RESULT_REQUEST True"));
|
|
|
|
bool[] Page = new bool[4];
|
|
Page = new bool[4] { false, false, false, false };
|
|
_PLC.WriteBitBlock((int)eBitOutput.PC_WELD_PAGE_CHANGE_COMPLETE_1, 4, Page);
|
|
Log.I(string.Format("[PLCInterface]Pgae Reset"));
|
|
|
|
break;
|
|
}
|
|
|
|
Thread.Sleep(100);
|
|
}
|
|
}
|
|
|
|
return SequenceAction.Ok();
|
|
}
|
|
#endregion
|
|
|
|
#region 경신 용접 RCC 추가
|
|
private string CheckRCCMode(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
|
|
{
|
|
_SystemParameter = context.GetSetting<SystemParameter>(CommonSettingIds.SystemParameter);
|
|
if (_SystemParameter.SequenceType == eSequenceType.Normal)
|
|
{
|
|
return SEQ_REQUEST_UNLOAD_CELL;
|
|
}
|
|
else
|
|
{
|
|
|
|
return SEQ_SET_SCOUT_FLYING_VISION_SEQ;
|
|
|
|
}
|
|
}
|
|
private string BeforeWeldMoveObject(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
|
|
{
|
|
|
|
|
|
MIL_ID ScannerFieldImage = Status.GetProcessingWeldingData().ScannerFiledImage;
|
|
|
|
//RCC Error로 인해 시퀀스를 종료하고 있는데, NG배출해야 될지 확인 필요
|
|
_StopwatchGenObj = Stopwatch.StartNew();
|
|
double dPixelResolution = ((_SystemParameter.CameraPixelSize) / _SystemParameter.LensMagnification) / 1000.0;
|
|
|
|
_ObjGenerator = new ObjectGenerator(dPixelResolution);
|
|
int arc_cnt = 6 * (_PageNoRcc / 2);
|
|
|
|
_ObjGenerator.ConvertMILToMat(ScannerFieldImage, out _ConvMatImage);
|
|
//_ConvMatImage = Cv2.ImRead("D:\\RCC\\6_KS\\2025_7_3\\before1.PNG");
|
|
|
|
|
|
//string baseDir = @"D:\ImagesTT";
|
|
////// 원본 이미지 저장
|
|
//string origFileName = $"Before{_PageNoRcc}_{DateTime.Now:HHmmss}.png";
|
|
//string origPath = Path.Combine(baseDir, origFileName);
|
|
//Cv2.ImWrite(origPath, _ConvMatImage);
|
|
|
|
|
|
// 4 Page 시퀀스 사용으로 spiral 페이지 사용시 RCC 사용안함
|
|
if (_PageNoRcc % 2 == 1)
|
|
return SEQ_READY_SCANNER_LIST;
|
|
|
|
_SystemParameter = context.GetSetting<SystemParameter>(CommonSettingIds.SystemParameter);
|
|
var mainPage = WeldingRecipeManager.GetWeldingPage();
|
|
_ScannerCanvasUserCtrl = mainPage.ScannerCanvasCtrlTeaching;
|
|
UnitPoint offset = new UnitPoint(0, 0);
|
|
for (int i = 0; i < _ScannerCanvasUserCtrl.Model.Layers[_PageNoRcc].Objects.Count; i += 2)
|
|
{
|
|
int[] threshold_array = new int[] { _SystemParameter.CVThresholdCircle1, _SystemParameter.CVThresholdCircle2, _SystemParameter.CVThresholdCircle3, _SystemParameter.CVThresholdCircle4, _SystemParameter.CVThresholdCircle5, _SystemParameter.CVThresholdCircle6 };
|
|
//if (_ScannerCanvasUserCtrl.Model.Layers[0].Objects.Count < 13) return;
|
|
//if (!(_ScannerCanvasUserCtrl.Model.Layers[0].Objects[12] is Spline)) return;
|
|
//if (((Spline)_ScannerCanvasUserCtrl.Model.Layers[0].Objects[12]).Center.Y < 0)
|
|
// threshold_array = new int[] { _SystemParameter.CVThresholdCircle2_1, _SystemParameter.CVThresholdCircle2_2, _SystemParameter.CVThresholdCircle2_3, _SystemParameter.CVThresholdCircle2_4, _SystemParameter.CVThresholdCircle2_5, _SystemParameter.CVThresholdCircle2_6 };
|
|
FovInfo _FovInfo = VisionRecipeManager.GetFovInfos().FirstOrDefault();
|
|
PatternAgentBase _PatternAgent = PatternAgentManager.GetAgent(_FovInfo);
|
|
var item = _ScannerCanvasUserCtrl.Model.Layers[_PageNoRcc].Objects[i];
|
|
_ObjGenerator = new ObjectGenerator(dPixelResolution);
|
|
|
|
if (item is Arc)
|
|
{
|
|
arc_cnt += 1;
|
|
var procPatternInfo = VisionRecipeManager.GetProcPatternInfo(_FovInfo, $"Arc{(_PageNoRcc / 2) + 1}_{arc_cnt - 6 * (_PageNoRcc/2)}", (eProcPatternId)arc_cnt - 1);
|
|
var patternInfo = _PatternAgent.GetPatternInfo(_FovInfo, procPatternInfo.PatternId);
|
|
//Log.I($"Finding pattern info procid : Arc{(_PageNoRcc / 2) + 1}_{arc_cnt - 6 * (_PageNoRcc / 2)}, patternid : {(eProcPatternId)arc_cnt - 1}, {patternInfo}");
|
|
|
|
UnitPoint center = ((Arc)item).Center;
|
|
double my_radius = ((Arc)item).Radius;
|
|
//int roi_height = _PatternAgent.GetFindROI(patternInfo).Height;
|
|
//int roi_width = _PatternAgent.GetFindROI(patternInfo).Width;
|
|
int roi_height = 736;
|
|
int roi_width = 1472;
|
|
OpenCvSharp.Rect my_ROI = new OpenCvSharp.Rect((int)(center.X / dPixelResolution + _ConvMatImage.Width / 2 - roi_width / 2), (int)(_ConvMatImage.Height / 2 - center.Y / dPixelResolution - roi_height / 2), roi_width, roi_height);
|
|
Mat roi_img = new Mat(_ConvMatImage, my_ROI);
|
|
Cv2.CvtColor(roi_img, roi_img, ColorConversionCodes.GRAY2BGR);
|
|
Cv2.CvtColor(roi_img, roi_img, ColorConversionCodes.BGR2GRAY);
|
|
//MIL.MbufAllocColor(MilEnvironment.Instance.GetSystem(_cameraAgent._CamConfig.CamConnConfig.BoardSlotPos), 3, loadImg.Width, loadImg.Height, 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_DISP + MIL.M_PROC, ref mil_roi_img);
|
|
MIL_ID mil_roi_img = _ObjGenerator.ConvertMatToMilID(roi_img);
|
|
|
|
//MIL.MbufLoad($"D:/test_{arc_cnt}.png", mil_roi_img);
|
|
//Mat roi_img_img;
|
|
//_ObjGenerator.ConvertMILToMat(mil_roi_img, out roi_img_img);
|
|
//Cv2.ImWrite($"D:/test_convert_{arc_cnt}.png", roi_img_img);
|
|
Point2d found_center_pixel, found_center_pixel_mm;
|
|
var cameraDisplay = CameraDisplayManager.GetDisplay(_FovInfo, eDisplayType.Pattern) as CameraDisplay;
|
|
|
|
PatternResult _PatternResult = _PatternAgent.Find(patternInfo, mil_roi_img, _CameraDisplay);
|
|
MIL.MbufFree(mil_roi_img);
|
|
if (_PatternResult.Status == eFoundStatus.FoundOK)
|
|
{
|
|
Log.W("Pattern is found.");
|
|
var resultsList = _PatternResult.Results.ToList();
|
|
found_center_pixel = new Point2d(resultsList[0].ImagePosition.X + my_ROI.X, resultsList[0].ImagePosition.Y + my_ROI.Y);
|
|
found_center_pixel_mm = new Point2d((found_center_pixel.X - _ConvMatImage.Width / 2) * dPixelResolution, (_ConvMatImage.Height / 2 - found_center_pixel.Y) * dPixelResolution);
|
|
if ( _SystemParameter.OffsetInterlock>0 && Math.Abs(found_center_pixel_mm.X - center.X)< _SystemParameter.OffsetInterlock && Math.Abs(found_center_pixel_mm.Y - center.Y) < _SystemParameter.OffsetInterlock)
|
|
offset = new UnitPoint(found_center_pixel_mm.X - center.X, found_center_pixel_mm.Y - center.Y);
|
|
else if (_SystemParameter.OffsetInterlock == 0 && Math.Abs(found_center_pixel_mm.X - center.X) < 1 && Math.Abs(found_center_pixel_mm.Y - center.Y) < 1)
|
|
offset = new UnitPoint(found_center_pixel_mm.X - center.X, found_center_pixel_mm.Y - center.Y);
|
|
else
|
|
Log.W($"Offset is too large (x : {found_center_pixel_mm.X - center.X} y : {found_center_pixel_mm.Y - center.Y})");
|
|
|
|
}
|
|
else
|
|
{
|
|
Log.W("RCC Pattern is not found. NG Process");
|
|
_PLC.WriteBit((int)eBitOutput.PC_LBAD_RESULT_NG, true);
|
|
pre_welding = true;
|
|
context.Wait(1000);
|
|
return SEQ_CHECK_PAGENO;
|
|
}
|
|
|
|
|
|
//var ROI_X = (center.X - my_radius * 2) / dPixelResolution + _ConvMatImage.Width / 2;
|
|
//var ROI_Y = -(center.Y + my_radius * 2) / dPixelResolution + _ConvMatImage.Height / 2;
|
|
//var ROI_size = my_radius * 4 / dPixelResolution;
|
|
//Point2f circle = _ObjGenerator.find_circle_center(_ConvMatImage, new OpenCvSharp.Rect((int)ROI_X, (int)ROI_Y, (int)ROI_size, (int)ROI_size), threshold_array[circle_cnt], _SystemParameter.CVRadiusMargin, my_radius / dPixelResolution);
|
|
//circle_cnt += 1;
|
|
//circle = new Point2f((float)(circle.X + ROI_X), (float)(circle.Y + ROI_Y));
|
|
////Point2f circle = _ObjectGenerator.find_circle_center(_DetectImageMat, new OpenCvSharp.Rect(3325, 4250, 500, 500), threshold, my_radius, my_radius / dPixelResolution);
|
|
////Cv2.Circle(_DetectImageMat, new Point(circle.X, circle.Y), (int)(my_radius / dPixelResolution), Scalar.Red, 8);
|
|
//circle = new Point2f((float)((circle.X - _ConvMatImage.Width / 2) * dPixelResolution), (float)((-circle.Y + _ConvMatImage.Height / 2) * dPixelResolution));
|
|
|
|
Log.I($"Offset : {offset.X},{offset.Y}");
|
|
IDrawObject objclone = item.Clone();
|
|
objclone.Move(offset);
|
|
//_ScannerCanvasUserCtrl.Model.Layers[_PageNoRcc].Objects[i] = objclone;
|
|
_SelectedDrawObjectList[i] = objclone;
|
|
//IDrawObject objclone_line = _ScannerCanvasUserCtrl.Model.Layers[0].Objects[i + 1].Clone();
|
|
IDrawObject objclone_line = _ScannerCanvasUserCtrl.Model.Layers[_PageNoRcc].Objects[i + 1].Clone();
|
|
objclone_line.Move(offset);///
|
|
//_ScannerCanvasUserCtrl.Model.Layers[_PageNoRcc].Objects[i + 1] = objclone_line;
|
|
_SelectedDrawObjectList[i + 1] = objclone_line;
|
|
}
|
|
else if (item is Line)
|
|
{
|
|
//var line_length = Math.Abs(((Line)item).PF1.Y - ((Line)item).PF2.Y);
|
|
//if (line_length < 2) continue;
|
|
//int ROI_size = (int)(line_length * 1.5 / dPixelResolution);
|
|
//int ROI_X = (int)(((Line)item).PF1.X / dPixelResolution + _ConvMatImage.Width / 2) - ROI_size / 2;
|
|
//int ROI_Y = (int)(-Math.Max(((Line)item).PF1.Y, ((Line)item).PF2.Y) / dPixelResolution + _ConvMatImage.Height / 2) - ROI_size / 4;
|
|
//RotatedRect r = _ObjGenerator.find_line_center(_ConvMatImage, new OpenCvSharp.Rect((int)ROI_X, (int)ROI_Y, (int)ROI_size, (int)ROI_size),
|
|
// _SystemParameter.CVThresholdLine1, _SystemParameter.CVThresholdLine2);
|
|
//Point[] intVertices = new Point[4];
|
|
//for (int j = 0; j < 4; j++)
|
|
//{
|
|
// intVertices[j] = new Point(r.Points()[j].X + ROI_X, r.Points()[j].Y + ROI_Y);
|
|
//}
|
|
//UnitPoint LineCenter = new UnitPoint((r.Center.X + ROI_X - _ConvMatImage.Width / 2) * dPixelResolution, (-r.Center.Y - ROI_Y + _ConvMatImage.Height / 2) * dPixelResolution);
|
|
|
|
//UnitPoint offset = new UnitPoint(LineCenter.X - (((Line)item).PF1.X + ((Line)item).PF2.X) / 2, LineCenter.Y - (((Line)item).PF1.Y + ((Line)item).PF2.Y) / 2);
|
|
//IDrawObject objclone = item.Clone();
|
|
//float angle = Math.Min(r.Angle, 90 - r.Angle);
|
|
//objclone.Rotate(angle, LineCenter);
|
|
//objclone.Move(offset);
|
|
//_ScannerCanvasUserCtrl.Model.Layers[0].Objects[i] = objclone;
|
|
}
|
|
}
|
|
|
|
return SEQ_READY_SCANNER_LIST;
|
|
}
|
|
//private SequenceActionResult AfterWeldCheckBead(SequenceContext context, string id, SequenceActionResult param)
|
|
//{
|
|
|
|
// //if (_SystemParameter.SequenceType == eSequenceType.Normal) return SequenceAction.Ok();
|
|
// MIL_ID ScannerFieldImage = Status.GetProcessingWeldingData().ScannerFiledImage;
|
|
// //RCC Error로 인해 시퀀스를 종료하고 있는데, NG배출해야 될지 확인 필요
|
|
// if (_ConvMatImage.Type() == MatType.CV_8UC1)
|
|
// Cv2.CvtColor(_ConvMatImage, _ConvMatImage, ColorConversionCodes.GRAY2BGR);
|
|
|
|
// _StopwatchGenObj = Stopwatch.StartNew();
|
|
// _ObjGenerator.ConvertMILToMat(ScannerFieldImage, out _ConvMatImage_after);
|
|
// if (_ConvMatImage_after.Type() == MatType.CV_8UC1)
|
|
// Cv2.CvtColor(_ConvMatImage_after, _ConvMatImage_after, ColorConversionCodes.GRAY2BGR);
|
|
// _SystemParameter = context.GetSetting<SystemParameter>(CommonSettingIds.SystemParameter);
|
|
// double dPixelResolution = ((_SystemParameter.CameraPixelSize) / _SystemParameter.LensMagnification) / 1000.0;
|
|
// _ObjGenerator = new ObjectGenerator(dPixelResolution);
|
|
// var mainPage = WeldingRecipeManager.GetWeldingPage();
|
|
// _ScannerCanvasUserCtrl = mainPage.ScannerCanvasCtrlTeaching;
|
|
// bead_result_info = new List<double>();
|
|
|
|
// //for (int i = 0; i < _ScannerCanvasUserCtrl.Model.Layers[_PageNoRcc].Objects.Count; i++)
|
|
// for (int i = 0; i < _SelectedDrawObjectList.Count; i++)
|
|
// {
|
|
// //var item = _ScannerCanvasUserCtrl.Model.Layers[_PageNoRcc].Objects[i];
|
|
// var item = _SelectedDrawObjectList[i];
|
|
|
|
// double my_radius = 0;
|
|
// int ROI_X = 0;
|
|
// int ROI_Y = 0;
|
|
// int ROI_W = 0;
|
|
// int ROI_H = 0;
|
|
// double bead_size1 = 0;
|
|
// double bead_size2 = 0;
|
|
// int search_size = 0;
|
|
// UnitPoint center = new UnitPoint(0, 0);
|
|
// OpenCvSharp.Point p1 = new OpenCvSharp.Point();
|
|
// OpenCvSharp.Point p2 = new OpenCvSharp.Point();
|
|
// Point[][] contour;
|
|
// int type = -1;
|
|
// if (item is Arc)
|
|
// {
|
|
// bead_result_info.Add(_SystemParameter.ArcBeadSizeMin);
|
|
// bead_result_info.Add(_SystemParameter.ArcBeadSizeMax);
|
|
// center = ((Arc)item).Center;
|
|
// my_radius = ((Arc)item).Radius;
|
|
// type = 0;
|
|
// //ROI_W = (int)(my_radius * 2 / dPixelResolution);
|
|
// ROI_W = 779;
|
|
// ROI_H = 779;
|
|
// ROI_X = (int)(center.X / dPixelResolution) + _ConvMatImage.Width / 2 - ROI_W / 2;
|
|
// ROI_Y = -(int)(center.Y / dPixelResolution) + _ConvMatImage.Height / 2 - ROI_H / 2;
|
|
// //if (center.Y > 0 && center.X > 15) ROI_Y -= 20; //우측 상단 비드 missalign이 있어 ROI영역 조절하도록 하드코딩
|
|
// search_size = (int)(ROI_W / 10);
|
|
// //double size_margin = 10000;
|
|
// int[] bead_size_info = new int[3];
|
|
// Point[] start_bead_point_info = new Point[3];
|
|
// Point[] end_bead_point_info = new Point[3];
|
|
// (bead_size_info, start_bead_point_info, end_bead_point_info, contour) = _ObjGenerator.check_bead_size(_ConvMatImage_after, _ConvMatImage_after, new OpenCvSharp.Rect((int)ROI_X, (int)ROI_Y, ROI_W, ROI_H), type, search_size);
|
|
|
|
// //(bead_size1, bead_size2, p1, p2, contour) = _ObjGenerator.check_bead_size(_ConvMatImage, _ConvMatImage_after, new OpenCvSharp.Rect((int)ROI_X, (int)ROI_Y, ROI_W, ROI_H), type, _SystemParameter.CVSearchSize);
|
|
// //Cv2.Line(_ConvMatImage_after, p1, p2, Scalar.LimeGreen, 10);
|
|
// //Cv2.Line(_ConvMatImage_after, new Point(p1.X, p1.Y + 10), new Point(p1.X, p1.Y - 10), Scalar.LimeGreen, 10);
|
|
// //Cv2.Line(_ConvMatImage_after, new Point(p2.X, p2.Y + 10), new Point(p2.X, p2.Y - 10), Scalar.LimeGreen, 10);
|
|
// //Cv2.PutText(_ConvMatImage_after, $"{Math.Round(bead_size1 * dPixelResolution, 3)} mm", new Point(p1.X + 10, p1.Y + 220), HersheyFonts.HersheyComplexSmall, 10, Scalar.LimeGreen, 25);
|
|
// int min_bead_size = int.MaxValue;
|
|
// int average_bead_size = 0;
|
|
// for (int li = 0; li < bead_size_info.Length; li++)
|
|
// {
|
|
// p1 = start_bead_point_info[li];
|
|
// p2 = end_bead_point_info[li];
|
|
// Cv2.Line(_ConvMatImage_after, p1, p2, Scalar.LimeGreen, 12);
|
|
// if (Math.Abs(p1.X - p2.X) > Math.Abs(p1.Y - p2.Y))
|
|
// {
|
|
// Cv2.Line(_ConvMatImage_after, new Point(p1.X, p1.Y + 12), new Point(p1.X, p1.Y - 12), Scalar.LimeGreen, 12);
|
|
// Cv2.Line(_ConvMatImage_after, new Point(p2.X, p2.Y + 12), new Point(p2.X, p2.Y - 12), Scalar.LimeGreen, 12);
|
|
// }
|
|
// else
|
|
// {
|
|
// Cv2.Line(_ConvMatImage_after, new Point(p1.X + 12, p1.Y), new Point(p1.X - 12, p1.Y), Scalar.LimeGreen, 12);
|
|
// Cv2.Line(_ConvMatImage_after, new Point(p2.X + 12, p2.Y), new Point(p2.X - 12, p2.Y), Scalar.LimeGreen, 12);
|
|
// }
|
|
// // Cv2.PutText(_DetectImageMat, $"{Math.Round(bead_size_info[li] * dPixelResolution, 3)} mm", new Point(p1.X + 10, p1.Y + 220), HersheyFonts.HersheyComplexSmall, 10, Scalar.LimeGreen, 25);
|
|
// average_bead_size += bead_size_info[li];
|
|
// if (min_bead_size > bead_size_info[li]) min_bead_size = bead_size_info[li];
|
|
// }
|
|
// Cv2.PutText(_ConvMatImage_after, $"MIN : {Math.Round(min_bead_size * dPixelResolution, 3)}", new Point(ROI_X - 600, ROI_Y + 800), HersheyFonts.HersheyComplexSmall, 11, Scalar.LimeGreen, 25);
|
|
// Cv2.PutText(_ConvMatImage_after, $"AVG : {Math.Round(average_bead_size * dPixelResolution / bead_size_info.Length, 3)}", new Point(ROI_X - 600, ROI_Y + 1000), HersheyFonts.HersheyComplexSmall, 11, Scalar.LimeGreen, 25);
|
|
// bead_size1 = average_bead_size / bead_size_info.Length * dPixelResolution;
|
|
// //bead_size1 = bead_size1 * dPixelResolution;
|
|
// Log.I($"arc length : {bead_size1}");
|
|
// bead_result_info.Add(bead_size1);
|
|
|
|
// if (bead_size1 <= _SystemParameter.ArcBeadSizeMax && bead_size1 >= _SystemParameter.ArcBeadSizeMin)
|
|
// {
|
|
// bead_result_info.Add(1); // OK -> 1
|
|
// }
|
|
// else
|
|
// {
|
|
// bead_result_info.Add(2); // NG -> 2
|
|
// }
|
|
|
|
|
|
// }
|
|
// else if (item is Spline)
|
|
// {
|
|
// //bead_result_info.Add(_SystemParameter.SpiralBeadWidthMin);
|
|
// //bead_result_info.Add(_SystemParameter.SpiralBeadWidthMax);
|
|
// //bead_result_info.Add(_SystemParameter.SpiralBeadHeightMin);
|
|
// //bead_result_info.Add(_SystemParameter.SpiralBeadHeightMax);
|
|
// center = ((Spline)item).Center;
|
|
// my_radius = ((Spline)item).Radius;
|
|
// type = 1;
|
|
|
|
// /*
|
|
// ROI_W = (int)(my_radius * 4 / dPixelResolution);
|
|
// ROI_X = (int)(center.X / dPixelResolution) + _ConvMatImage.Width / 2 - ROI_W / 2;
|
|
// ROI_Y = -(int)(center.Y / dPixelResolution) + _ConvMatImage.Height / 2 - ROI_W / 2;
|
|
// (bead_size1, bead_size2, p1, p2, contour) = _ObjGenerator.check_bead_size(_ConvMatImage, _ConvMatImage_after, new OpenCvSharp.Rect((int)ROI_X, (int)ROI_Y, ROI_W, ROI_W), type, 0);
|
|
// */
|
|
|
|
// ROI_W = 492;
|
|
// ROI_X = (int)(center.X / dPixelResolution) + _ConvMatImage.Width / 2 - ROI_W / 2;
|
|
// ROI_Y = -(int)(center.Y / dPixelResolution) + _ConvMatImage.Height / 2 - ROI_W / 2;
|
|
// //double size_margin = 10000;
|
|
// double[] spline_y = new double[3];
|
|
|
|
// //spline_y[0] = ((Spline)_ScannerCanvasUserCtrl.Model.Layers[0].Objects[0]).Center.Y;
|
|
// spline_y[0] = ((Spline)_SelectedDrawObjectList[0]).Center.Y;
|
|
// //spline_y[1] = ((Spline)_ScannerCanvasUserCtrl.Model.Layers[0].Objects[1]).Center.Y;
|
|
// spline_y[1] = ((Spline)_SelectedDrawObjectList[1]).Center.Y;
|
|
// //spline_y[2] = ((Spline)_ScannerCanvasUserCtrl.Model.Layers[0].Objects[2]).Center.Y;
|
|
// spline_y[2] = ((Spline)_SelectedDrawObjectList[2]).Center.Y;
|
|
// Array.Sort(spline_y);
|
|
// //int spline_empty_spot_y = (int)(_ConvMatImage.Height / 2 - (spline_y[0] - ((Spline)_ScannerCanvasUserCtrl.Model.Layers[0].Objects[0]).Radius * 1.5) / dPixelResolution);
|
|
// int spline_empty_spot_y = (int)(_ConvMatImage.Height / 2 - (spline_y[0] - ((Spline)_SelectedDrawObjectList[0]).Radius * 1.5) / dPixelResolution);
|
|
// //(bead_size1, bead_size2, p1, p2, contour) = _ObjGenerator.check_bead_size(_ConvMatImage, _ConvMatImage, new OpenCvSharp.Rect((int)ROI_X, (int)ROI_Y, ROI_W, ROI_W), type, spline_empty_spot_y);
|
|
// int[] bead_size_info = new int[3];
|
|
// Point[] start_bead_point_info = new Point[3];
|
|
// Point[] end_bead_point_info = new Point[3];
|
|
// (bead_size_info, start_bead_point_info, end_bead_point_info, contour) = _ObjGenerator.check_bead_size(_ConvMatImage_after, _ConvMatImage_after, new OpenCvSharp.Rect((int)ROI_X, (int)ROI_Y, ROI_W, ROI_W), type, spline_empty_spot_y);
|
|
// bead_size1 = bead_size_info[0];
|
|
// bead_size2 = bead_size_info[1];
|
|
// p1 = start_bead_point_info[0];
|
|
// Cv2.Line(_ConvMatImage_after, new Point(p1.X - bead_size1 / 2, p1.Y), new Point(p1.X + bead_size1 / 2, p1.Y), Scalar.LimeGreen, 12);
|
|
// Cv2.Line(_ConvMatImage_after, new Point(p1.X, p1.Y + bead_size2 / 2), new Point(p1.X, p1.Y - bead_size2 / 2), Scalar.LimeGreen, 12);
|
|
// Cv2.Line(_ConvMatImage_after, new Point(p1.X - bead_size1 / 2, p1.Y + 12), new Point(p1.X - bead_size1 / 2, p1.Y - 12), Scalar.LimeGreen, 12);
|
|
// Cv2.Line(_ConvMatImage_after, new Point(p1.X + bead_size1 / 2, p1.Y + 12), new Point(p1.X + bead_size1 / 2, p1.Y - 12), Scalar.LimeGreen, 12);
|
|
|
|
// Cv2.Line(_ConvMatImage_after, new Point(p1.X - 10, p1.Y - bead_size2 / 2), new Point(p1.X + 10 / 2, p1.Y - bead_size2 / 2), Scalar.LimeGreen, 12);
|
|
// Cv2.Line(_ConvMatImage_after, new Point(p1.X - 10, p1.Y + bead_size2 / 2), new Point(p1.X + 10 / 2, p1.Y + bead_size2 / 2), Scalar.LimeGreen, 12);
|
|
|
|
// Cv2.PutText(_ConvMatImage_after, $"W : {Math.Round(bead_size1 * dPixelResolution, 3)} ", new Point(p1.X + bead_size1 / 2, p1.Y), HersheyFonts.HersheyComplexSmall, 11, Scalar.LimeGreen, 25);
|
|
// //Cv2.PutText(_ConvMatImage_after, $"H : {Math.Round(bead_size2 * dPixelResolution, 3)} mm", new Point(p1.X + bead_size1 / 2, p1.Y + bead_size2 / 2 + 50), HersheyFonts.HersheyComplexSmall, 10, Scalar.LimeGreen, 25);
|
|
// Cv2.PutText(_ConvMatImage_after, $"H: {Math.Round(bead_size2 * dPixelResolution, 3)} ", new Point(p1.X + bead_size1 / 2, p1.Y + 200), HersheyFonts.HersheyComplexSmall, 11, Scalar.LimeGreen, 25);
|
|
// bead_size1 = bead_size1 * dPixelResolution;
|
|
// bead_size2 = bead_size2 * dPixelResolution;
|
|
// Log.I($"spiral length : {bead_size1}, {bead_size2}");
|
|
|
|
// ScannerParam _SplineParam = ScannerCanvasUserCtrl.ScannerParams[((Spline)item).ScannerParamNo];
|
|
// Log.I($"ScannerParam ->{_SplineParam.LaserPower1}, {_SplineParam.LaserPower2}");
|
|
|
|
// bead_result_info.Add(_SystemParameter.SpiralBeadWidthMin);
|
|
// bead_result_info.Add(_SystemParameter.SpiralBeadWidthMax);
|
|
// bead_result_info.Add(bead_size1);
|
|
|
|
// bead_result_info.Add(_SystemParameter.SpiralBeadHeightMin);
|
|
// bead_result_info.Add(_SystemParameter.SpiralBeadHeightMax);
|
|
// bead_result_info.Add(bead_size2);
|
|
|
|
// if (bead_size1 <= _SystemParameter.SpiralBeadWidthMax && bead_size1 >= _SystemParameter.SpiralBeadWidthMin
|
|
// && bead_size2 <= _SystemParameter.SpiralBeadHeightMax && bead_size2 >= _SystemParameter.SpiralBeadHeightMin)
|
|
// {
|
|
// bead_result_info.Add(1); // OK -> 1
|
|
// }
|
|
// else
|
|
// {
|
|
// bead_result_info.Add(2); // NG -> 2
|
|
// }
|
|
// }
|
|
// }
|
|
// return SequenceAction.Ok();
|
|
//}
|
|
|
|
|
|
private SequenceActionResult AfterWeldCheckBead(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
|
|
//if (_SystemParameter.SequenceType == eSequenceType.Normal) return SequenceAction.Ok();
|
|
MIL_ID ScannerFieldImage = Status.GetProcessingWeldingData().ScannerFiledImage;
|
|
//RCC Error로 인해 시퀀스를 종료하고 있는데, NG배출해야 될지 확인 필요
|
|
if (_ConvMatImage.Type() == MatType.CV_8UC1)
|
|
Cv2.CvtColor(_ConvMatImage, _ConvMatImage, ColorConversionCodes.GRAY2BGR);
|
|
|
|
_StopwatchGenObj = Stopwatch.StartNew();
|
|
_ObjGenerator.ConvertMILToMat(ScannerFieldImage, out _ConvMatImage_after);
|
|
if (_ConvMatImage_after.Type() == MatType.CV_8UC1)
|
|
Cv2.CvtColor(_ConvMatImage_after, _ConvMatImage_after, ColorConversionCodes.GRAY2BGR);
|
|
_SystemParameter = context.GetSetting<SystemParameter>(CommonSettingIds.SystemParameter);
|
|
double dPixelResolution = ((_SystemParameter.CameraPixelSize) / _SystemParameter.LensMagnification) / 1000.0;
|
|
_ObjGenerator = new ObjectGenerator(dPixelResolution);
|
|
var mainPage = WeldingRecipeManager.GetWeldingPage();
|
|
_ScannerCanvasUserCtrl = mainPage.ScannerCanvasCtrlTeaching;
|
|
bead_result_info = new List<double>();
|
|
|
|
//for (int i = 0; i < _ScannerCanvasUserCtrl.Model.Layers[_PageNoRcc].Objects.Count; i++)
|
|
for (int i = 0; i < _SelectedDrawObjectList.Count; i++)
|
|
{
|
|
//var item = _ScannerCanvasUserCtrl.Model.Layers[_PageNoRcc].Objects[i];
|
|
var item = _SelectedDrawObjectList[i];
|
|
|
|
double my_radius = 0;
|
|
int ROI_X = 0;
|
|
int ROI_Y = 0;
|
|
int ROI_W = 0;
|
|
int ROI_H = 0;
|
|
double bead_size1 = 0;
|
|
double bead_size2 = 0;
|
|
int search_size = 0;
|
|
UnitPoint center = new UnitPoint(0, 0);
|
|
OpenCvSharp.Point p1 = new OpenCvSharp.Point();
|
|
OpenCvSharp.Point p2 = new OpenCvSharp.Point();
|
|
Point[][] contour;
|
|
int type = -1;
|
|
if (item is Arc)
|
|
{
|
|
bead_result_info.Add(_SystemParameter.ArcBeadSizeMin);
|
|
bead_result_info.Add(_SystemParameter.ArcBeadSizeMax);
|
|
center = ((Arc)item).Center;
|
|
my_radius = ((Arc)item).Radius;
|
|
type = 0;
|
|
//ROI_W = (int)(my_radius * 2 / dPixelResolution);
|
|
ROI_W = 779;
|
|
ROI_H = 779;
|
|
ROI_X = (int)(center.X / dPixelResolution) + _ConvMatImage.Width / 2 - ROI_W / 2;
|
|
ROI_Y = -(int)(center.Y / dPixelResolution) + _ConvMatImage.Height / 2 - ROI_H / 2;
|
|
//if (center.Y > 0 && center.X > 15) ROI_Y -= 20; //우측 상단 비드 missalign이 있어 ROI영역 조절하도록 하드코딩
|
|
search_size = (int)(ROI_W / 10);
|
|
//double size_margin = 10000;
|
|
int[] bead_size_info = new int[3];
|
|
Point[] start_bead_point_info = new Point[3];
|
|
Point[] end_bead_point_info = new Point[3];
|
|
(bead_size_info, start_bead_point_info, end_bead_point_info, contour) = _ObjGenerator.check_bead_size(_ConvMatImage_after, _ConvMatImage_after, new OpenCvSharp.Rect((int)ROI_X, (int)ROI_Y, ROI_W, ROI_H), type, search_size);
|
|
|
|
//(bead_size1, bead_size2, p1, p2, contour) = _ObjGenerator.check_bead_size(_ConvMatImage, _ConvMatImage_after, new OpenCvSharp.Rect((int)ROI_X, (int)ROI_Y, ROI_W, ROI_H), type, _SystemParameter.CVSearchSize);
|
|
//Cv2.Line(_ConvMatImage_after, p1, p2, Scalar.LimeGreen, 10);
|
|
//Cv2.Line(_ConvMatImage_after, new Point(p1.X, p1.Y + 10), new Point(p1.X, p1.Y - 10), Scalar.LimeGreen, 10);
|
|
//Cv2.Line(_ConvMatImage_after, new Point(p2.X, p2.Y + 10), new Point(p2.X, p2.Y - 10), Scalar.LimeGreen, 10);
|
|
//Cv2.PutText(_ConvMatImage_after, $"{Math.Round(bead_size1 * dPixelResolution, 3)} mm", new Point(p1.X + 10, p1.Y + 220), HersheyFonts.HersheyComplexSmall, 10, Scalar.LimeGreen, 25);
|
|
int min_bead_size = int.MaxValue;
|
|
int max_bead_size = int.MinValue;
|
|
|
|
int average_bead_size = 0;
|
|
for (int li = 0; li < bead_size_info.Length; li++)
|
|
{
|
|
p1 = start_bead_point_info[li];
|
|
p2 = end_bead_point_info[li];
|
|
Cv2.Line(_ConvMatImage_after, p1, p2, Scalar.LimeGreen, 12);
|
|
if (Math.Abs(p1.X - p2.X) > Math.Abs(p1.Y - p2.Y))
|
|
{
|
|
Cv2.Line(_ConvMatImage_after, new Point(p1.X, p1.Y + 12), new Point(p1.X, p1.Y - 12), Scalar.LimeGreen, 12);
|
|
Cv2.Line(_ConvMatImage_after, new Point(p2.X, p2.Y + 12), new Point(p2.X, p2.Y - 12), Scalar.LimeGreen, 12);
|
|
}
|
|
else
|
|
{
|
|
Cv2.Line(_ConvMatImage_after, new Point(p1.X + 12, p1.Y), new Point(p1.X - 12, p1.Y), Scalar.LimeGreen, 12);
|
|
Cv2.Line(_ConvMatImage_after, new Point(p2.X + 12, p2.Y), new Point(p2.X - 12, p2.Y), Scalar.LimeGreen, 12);
|
|
}
|
|
// Cv2.PutText(_DetectImageMat, $"{Math.Round(bead_size_info[li] * dPixelResolution, 3)} mm", new Point(p1.X + 10, p1.Y + 220), HersheyFonts.HersheyComplexSmall, 10, Scalar.LimeGreen, 25);
|
|
average_bead_size += bead_size_info[li];
|
|
if (min_bead_size > bead_size_info[li]) min_bead_size = bead_size_info[li];
|
|
if (max_bead_size < bead_size_info[li]) max_bead_size = bead_size_info[li];
|
|
|
|
bead_result_info.Add(Math.Round(bead_size_info[li] * dPixelResolution, 3));
|
|
Log.I($"Bead Size : {Math.Round(bead_size_info[li] * dPixelResolution, 3)}");
|
|
}
|
|
//Cv2.PutText(_ConvMatImage_after, $"MIN : {Math.Round(min_bead_size * dPixelResolution, 3)}", new Point(ROI_X - 600, ROI_Y + 800), HersheyFonts.HersheyComplexSmall, 11, Scalar.LimeGreen, 25);
|
|
//Cv2.PutText(_ConvMatImage_after, $"AVG : {Math.Round(average_bead_size * dPixelResolution / bead_size_info.Length, 3)}", new Point(ROI_X - 600, ROI_Y + 1000), HersheyFonts.HersheyComplexSmall, 11, Scalar.LimeGreen, 25);
|
|
if (_ConvMatImage_after.Height / 2 > ROI_Y)
|
|
{
|
|
Cv2.PutText(_ConvMatImage_after, $"1 : {Math.Round(bead_size_info[0] * dPixelResolution, 3)}", new Point(ROI_X - 200, ROI_Y + 1200), HersheyFonts.HersheyComplexSmall, 11, Scalar.LimeGreen, 25);
|
|
Cv2.PutText(_ConvMatImage_after, $"2 : {Math.Round(bead_size_info[1] * dPixelResolution, 3)}", new Point(ROI_X - 200, ROI_Y + 1400), HersheyFonts.HersheyComplexSmall, 11, Scalar.LimeGreen, 25);
|
|
Cv2.PutText(_ConvMatImage_after, $"3 : {Math.Round(bead_size_info[2] * dPixelResolution, 3)}", new Point(ROI_X - 200, ROI_Y + 1600), HersheyFonts.HersheyComplexSmall, 11, Scalar.LimeGreen, 25);
|
|
Cv2.PutText(_ConvMatImage_after, $"4 : {Math.Round(bead_size_info[3] * dPixelResolution, 3)}", new Point(ROI_X - 200, ROI_Y + 1800), HersheyFonts.HersheyComplexSmall, 11, Scalar.LimeGreen, 25);
|
|
Log.I($"1:{bead_size_info[0]}, 2:{bead_size_info[1]}, 3:{bead_size_info[2]}, 4:{bead_size_info[3]}");
|
|
}
|
|
else
|
|
{
|
|
Cv2.PutText(_ConvMatImage_after, $"1 : {Math.Round(bead_size_info[0] * dPixelResolution, 3)}", new Point(ROI_X - 200, ROI_Y - 200), HersheyFonts.HersheyComplexSmall, 11, Scalar.LimeGreen, 25);
|
|
Cv2.PutText(_ConvMatImage_after, $"2 : {Math.Round(bead_size_info[1] * dPixelResolution, 3)}", new Point(ROI_X - 200, ROI_Y - 400), HersheyFonts.HersheyComplexSmall, 11, Scalar.LimeGreen, 25);
|
|
Cv2.PutText(_ConvMatImage_after, $"3 : {Math.Round(bead_size_info[2] * dPixelResolution, 3)}", new Point(ROI_X - 200, ROI_Y - 600), HersheyFonts.HersheyComplexSmall, 11, Scalar.LimeGreen, 25);
|
|
Cv2.PutText(_ConvMatImage_after, $"4 : {Math.Round(bead_size_info[3] * dPixelResolution, 3)}", new Point(ROI_X - 200, ROI_Y - 800), HersheyFonts.HersheyComplexSmall, 11, Scalar.LimeGreen, 25);
|
|
Log.I($"1:{bead_size_info[0]}, 2:{bead_size_info[1]}, 3:{bead_size_info[2]}, 4:{bead_size_info[3]}");
|
|
}
|
|
|
|
bead_size1 = average_bead_size / bead_size_info.Length * dPixelResolution;
|
|
var edit_bead_size_min = Math.Round(min_bead_size * dPixelResolution, 3);
|
|
var edit_bead_size_max = Math.Round(max_bead_size * dPixelResolution, 3);
|
|
//bead_size1 = bead_size1 * dPixelResolution;
|
|
Log.I($"arc length : {bead_size1}");
|
|
// 260113 Bead Avr, Min, Max -> Bead1,2,3,4
|
|
//bead_result_info.Add(bead_size1);
|
|
// 251223 Bead Size Min / Max 값을 변경함
|
|
//bead_result_info.Add(min_bead_size);
|
|
//bead_result_info.Add(max_bead_size);
|
|
//bead_result_info.Add(edit_bead_size_min);
|
|
//bead_result_info.Add(edit_bead_size_max);
|
|
Log.D($"Bead Size [min({edit_bead_size_min}) / max({edit_bead_size_max})]");
|
|
|
|
// 260113 조건 수정
|
|
// 네 개 항목이 모두 OK range 안에 들어올 때만 OK로 판단하도록 하는건 지난번 말씀드린 것 처럼 한줄만 수정하면 적용 가능합니다.
|
|
//if (bead_size1 <= _SystemParameter.ArcBeadSizeMax && bead_size1 >= _SystemParameter.ArcBeadSizeMin)
|
|
if (edit_bead_size_max <= _SystemParameter.ArcBeadSizeMax && edit_bead_size_min >= _SystemParameter.ArcBeadSizeMin)
|
|
{
|
|
bead_result_info.Add(1); // OK -> 1
|
|
}
|
|
else
|
|
{
|
|
bead_result_info.Add(2); // NG -> 2
|
|
}
|
|
|
|
|
|
}
|
|
else if (item is Spline)
|
|
{
|
|
//bead_result_info.Add(_SystemParameter.SpiralBeadWidthMin);
|
|
//bead_result_info.Add(_SystemParameter.SpiralBeadWidthMax);
|
|
//bead_result_info.Add(_SystemParameter.SpiralBeadHeightMin);
|
|
//bead_result_info.Add(_SystemParameter.SpiralBeadHeightMax);
|
|
center = ((Spline)item).Center;
|
|
my_radius = ((Spline)item).Radius;
|
|
type = 1;
|
|
|
|
/*
|
|
ROI_W = (int)(my_radius * 4 / dPixelResolution);
|
|
ROI_X = (int)(center.X / dPixelResolution) + _ConvMatImage.Width / 2 - ROI_W / 2;
|
|
ROI_Y = -(int)(center.Y / dPixelResolution) + _ConvMatImage.Height / 2 - ROI_W / 2;
|
|
(bead_size1, bead_size2, p1, p2, contour) = _ObjGenerator.check_bead_size(_ConvMatImage, _ConvMatImage_after, new OpenCvSharp.Rect((int)ROI_X, (int)ROI_Y, ROI_W, ROI_W), type, 0);
|
|
*/
|
|
|
|
ROI_W = 492;
|
|
ROI_X = (int)(center.X / dPixelResolution) + _ConvMatImage.Width / 2 - ROI_W / 2;
|
|
ROI_Y = -(int)(center.Y / dPixelResolution) + _ConvMatImage.Height / 2 - ROI_W / 2;
|
|
//double size_margin = 10000;
|
|
double[] spline_y = new double[3];
|
|
|
|
//spline_y[0] = ((Spline)_ScannerCanvasUserCtrl.Model.Layers[0].Objects[0]).Center.Y;
|
|
spline_y[0] = ((Spline)_SelectedDrawObjectList[0]).Center.Y;
|
|
//spline_y[1] = ((Spline)_ScannerCanvasUserCtrl.Model.Layers[0].Objects[1]).Center.Y;
|
|
spline_y[1] = ((Spline)_SelectedDrawObjectList[1]).Center.Y;
|
|
//spline_y[2] = ((Spline)_ScannerCanvasUserCtrl.Model.Layers[0].Objects[2]).Center.Y;
|
|
spline_y[2] = ((Spline)_SelectedDrawObjectList[2]).Center.Y;
|
|
Array.Sort(spline_y);
|
|
//int spline_empty_spot_y = (int)(_ConvMatImage.Height / 2 - (spline_y[0] - ((Spline)_ScannerCanvasUserCtrl.Model.Layers[0].Objects[0]).Radius * 1.5) / dPixelResolution);
|
|
int spline_empty_spot_y = (int)(_ConvMatImage.Height / 2 - (spline_y[0] - ((Spline)_SelectedDrawObjectList[0]).Radius * 1.5) / dPixelResolution);
|
|
//(bead_size1, bead_size2, p1, p2, contour) = _ObjGenerator.check_bead_size(_ConvMatImage, _ConvMatImage, new OpenCvSharp.Rect((int)ROI_X, (int)ROI_Y, ROI_W, ROI_W), type, spline_empty_spot_y);
|
|
int[] bead_size_info = new int[3];
|
|
Point[] start_bead_point_info = new Point[3];
|
|
Point[] end_bead_point_info = new Point[3];
|
|
(bead_size_info, start_bead_point_info, end_bead_point_info, contour) = _ObjGenerator.check_bead_size(_ConvMatImage_after, _ConvMatImage_after, new OpenCvSharp.Rect((int)ROI_X, (int)ROI_Y, ROI_W, ROI_W), type, spline_empty_spot_y);
|
|
bead_size1 = bead_size_info[0];
|
|
bead_size2 = bead_size_info[1];
|
|
p1 = start_bead_point_info[0];
|
|
Cv2.Line(_ConvMatImage_after, new Point(p1.X - bead_size1 / 2, p1.Y), new Point(p1.X + bead_size1 / 2, p1.Y), Scalar.LimeGreen, 12);
|
|
Cv2.Line(_ConvMatImage_after, new Point(p1.X, p1.Y + bead_size2 / 2), new Point(p1.X, p1.Y - bead_size2 / 2), Scalar.LimeGreen, 12);
|
|
Cv2.Line(_ConvMatImage_after, new Point(p1.X - bead_size1 / 2, p1.Y + 12), new Point(p1.X - bead_size1 / 2, p1.Y - 12), Scalar.LimeGreen, 12);
|
|
Cv2.Line(_ConvMatImage_after, new Point(p1.X + bead_size1 / 2, p1.Y + 12), new Point(p1.X + bead_size1 / 2, p1.Y - 12), Scalar.LimeGreen, 12);
|
|
|
|
Cv2.Line(_ConvMatImage_after, new Point(p1.X - 10, p1.Y - bead_size2 / 2), new Point(p1.X + 10 / 2, p1.Y - bead_size2 / 2), Scalar.LimeGreen, 12);
|
|
Cv2.Line(_ConvMatImage_after, new Point(p1.X - 10, p1.Y + bead_size2 / 2), new Point(p1.X + 10 / 2, p1.Y + bead_size2 / 2), Scalar.LimeGreen, 12);
|
|
|
|
Cv2.PutText(_ConvMatImage_after, $"W : {Math.Round(bead_size1 * dPixelResolution, 3)} ", new Point(p1.X + bead_size1 / 2, p1.Y), HersheyFonts.HersheyComplexSmall, 11, Scalar.LimeGreen, 25);
|
|
//Cv2.PutText(_ConvMatImage_after, $"H : {Math.Round(bead_size2 * dPixelResolution, 3)} mm", new Point(p1.X + bead_size1 / 2, p1.Y + bead_size2 / 2 + 50), HersheyFonts.HersheyComplexSmall, 10, Scalar.LimeGreen, 25);
|
|
Cv2.PutText(_ConvMatImage_after, $"H: {Math.Round(bead_size2 * dPixelResolution, 3)} ", new Point(p1.X + bead_size1 / 2, p1.Y + 200), HersheyFonts.HersheyComplexSmall, 11, Scalar.LimeGreen, 25);
|
|
bead_size1 = bead_size1 * dPixelResolution;
|
|
bead_size2 = bead_size2 * dPixelResolution;
|
|
Log.I($"spiral length : {bead_size1}, {bead_size2}");
|
|
|
|
ScannerParam _SplineParam = ScannerCanvasUserCtrl.ScannerParams[((Spline)item).ScannerParamNo];
|
|
Log.I($"ScannerParam ->{_SplineParam.LaserPower1}, {_SplineParam.LaserPower2}");
|
|
|
|
bead_result_info.Add(_SystemParameter.SpiralBeadMin);
|
|
bead_result_info.Add(_SystemParameter.SpiralBeadMax);
|
|
bead_result_info.Add(bead_size1);
|
|
|
|
bead_result_info.Add(_SystemParameter.SpiralBeadMin);
|
|
bead_result_info.Add(_SystemParameter.SpiralBeadMax);
|
|
bead_result_info.Add(bead_size2);
|
|
|
|
if (bead_size1 <= _SystemParameter.SpiralBeadMax && bead_size1 >= _SystemParameter.SpiralBeadMin
|
|
&& bead_size2 <= _SystemParameter.SpiralBeadMax && bead_size2 >= _SystemParameter.SpiralBeadMin)
|
|
{
|
|
bead_result_info.Add(1); // OK -> 1
|
|
}
|
|
else
|
|
{
|
|
bead_result_info.Add(2); // NG -> 2
|
|
}
|
|
}
|
|
}
|
|
return SequenceAction.Ok();
|
|
}
|
|
#endregion
|
|
|
|
#region TT
|
|
public List<double> Init_ArcInfo()
|
|
{
|
|
List<double> info = new List<double>();
|
|
|
|
Random rnd = new Random();
|
|
|
|
int sets = 6; // 6개 세트
|
|
|
|
for (int i = 0; i < sets; i++)
|
|
{
|
|
// LowerLimit, UpperLimit, Result (-3 ~ 3)
|
|
info.Add(Math.Round(rnd.NextDouble() * 6 - 3, 3)); // -3 ~ 3, 소수점 3자리
|
|
info.Add(Math.Round(rnd.NextDouble() * 6 - 3, 3));
|
|
info.Add(Math.Round(rnd.NextDouble() * 6 - 3, 3));
|
|
|
|
// OK_NG (1 또는 2)
|
|
info.Add(rnd.Next(1, 3)); // 1 또는 2
|
|
}
|
|
|
|
return info;
|
|
}
|
|
|
|
public List<double> Init_SpiralInfo()
|
|
{
|
|
List<double> info = new List<double>();
|
|
|
|
Random rnd = new Random();
|
|
|
|
int sets = 3; // Spiral 3세트
|
|
|
|
for (int i = 1; i <= sets; i++)
|
|
{
|
|
// Horizontal
|
|
info.Add(Math.Round(rnd.NextDouble() * 6 - 3, 3)); // LowerLimit
|
|
info.Add(Math.Round(rnd.NextDouble() * 6 - 3, 3)); // UpperLimit
|
|
info.Add(Math.Round(rnd.NextDouble() * 6 - 3, 3)); // Result
|
|
|
|
// Vertical
|
|
info.Add(Math.Round(rnd.NextDouble() * 6 - 3, 3)); // LowerLimit
|
|
info.Add(Math.Round(rnd.NextDouble() * 6 - 3, 3)); // UpperLimit
|
|
info.Add(Math.Round(rnd.NextDouble() * 6 - 3, 3)); // Result
|
|
|
|
// Width OK/NG (1 또는 2)
|
|
info.Add(rnd.Next(1, 3));
|
|
}
|
|
|
|
return info;
|
|
}
|
|
|
|
private void SaveExcelFileRing(Mat img, string ExcelFile, int Count, List<double> data)
|
|
{
|
|
List<string> RingLable = new List<string>();
|
|
for (int i = 1; i <= 6; i++)
|
|
{
|
|
RingLable.Add($"Ring #{i} _ BeadWidthLowerLimit");
|
|
RingLable.Add($"Ring #{i} _ BeadWidthUpperLimit");
|
|
RingLable.Add($"Ring #{i} _ BeadWidthResult");
|
|
RingLable.Add($"Ring #{i} _ BeadWidthOK_NG");
|
|
}
|
|
|
|
List<string> RingData = new List<string>();
|
|
for (int i = 0; i < data.Count; i++) { RingData.Add(ToIntThousand(data[i]).ToString()); }
|
|
|
|
var inserter = new ExcelImageInserter(ExcelFile);
|
|
|
|
var entry = new ExcelEntry
|
|
{
|
|
Name = string.Format("그림{0}", Count),
|
|
Image = img,
|
|
ParametersSets = new List<List<string>>
|
|
{
|
|
RingLable,
|
|
RingData
|
|
},
|
|
Content = "추가 내용"
|
|
};
|
|
|
|
inserter.AddEntry(entry, string.Format("MySheet{0}", Count), widthCm: 8, heightCm: 8);
|
|
|
|
inserter.Save();
|
|
|
|
string fileName = Path.GetFileName(ExcelFile);
|
|
string directory = Path.GetDirectoryName(ExcelFile);
|
|
|
|
AsyncLog.I($"{Count} SaveExcelFile.... {directory}{fileName}");
|
|
}
|
|
|
|
private void SaveExcelFileSpiral(Mat img, string ExcelFile, int Count, List<double> data)
|
|
{
|
|
List<string> SpiralLable = new List<string>();
|
|
for (int i = 1; i <= 3; i++)
|
|
{
|
|
SpiralLable.Add($"Spiral #{i} _ HorizontalLowerLimit");
|
|
SpiralLable.Add($"Spiral #{i} _ HorizontalUpperLimit");
|
|
SpiralLable.Add($"Spiral #{i} _ HorizontalResult");
|
|
SpiralLable.Add($"Spiral #{i} _ VerticalLowerLimit");
|
|
SpiralLable.Add($"Spiral #{i} _ VerticalUpperLimit");
|
|
SpiralLable.Add($"Spiral #{i} _ VerticalResult");
|
|
SpiralLable.Add($"Spiral #{i} _ WidthOK_NG");
|
|
}
|
|
|
|
List<string> SpiralData = new List<string>();
|
|
for (int i = 0; i < data.Count; i++) { SpiralData.Add(ToIntThousand(data[i]).ToString()); }
|
|
|
|
var inserter = new ExcelImageInserter(ExcelFile);
|
|
|
|
var entry = new ExcelEntry
|
|
{
|
|
Name = string.Format("그림{0}", Count),
|
|
Image = img,
|
|
ParametersSets = new List<List<string>>
|
|
{
|
|
SpiralLable,
|
|
SpiralData
|
|
},
|
|
Content = "추가 내용"
|
|
};
|
|
|
|
inserter.AddEntry(entry, string.Format("MySheet{0}", Count), widthCm: 8, heightCm: 8);
|
|
|
|
inserter.Save();
|
|
|
|
string fileName = Path.GetFileName(ExcelFile);
|
|
string directory = Path.GetDirectoryName(ExcelFile);
|
|
|
|
AsyncLog.I($"{Count} SaveExcelFile.... {directory}{fileName}");
|
|
}
|
|
#endregion
|
|
|
|
Mat matLeftTop;
|
|
Mat matRightTop;
|
|
Mat matLeftBottom;
|
|
Mat matRightBottom;
|
|
|
|
OpenCvSharp.Rect rectT;
|
|
private void TestopupWin(SequenceContext context)
|
|
{
|
|
// OpenCV Version 4.9.0
|
|
//D:\ILSOSConfig\_vision\Def
|
|
string Png1 = string.Format("D:\\ILSOSConfig\\_vision\\Def\\1.png");
|
|
string Png2 = string.Format("D:\\ILSOSConfig\\_vision\\Def\\2.png");
|
|
string Png3 = string.Format("D:\\ILSOSConfig\\_vision\\Def\\3.png");
|
|
string Png4 = string.Format("D:\\ILSOSConfig\\_vision\\Def\\4.png");
|
|
matLeftTop = Cv2.ImRead(Png1);
|
|
matRightTop = Cv2.ImRead(Png2);
|
|
matLeftBottom = Cv2.ImRead(Png3);
|
|
matRightBottom = Cv2.ImRead(Png4);
|
|
|
|
// Width 10368, Height 9856 // 1153 896 6918 8056
|
|
rectT = new OpenCvSharp.Rect(1153, 896, 6918, 8056);
|
|
popup.Show();
|
|
|
|
popup.UpdateImages1(matLeftTop, rectT);
|
|
popup.UpdateImages2(matRightTop, rectT);
|
|
popup.UpdateImages3(matLeftBottom, rectT);
|
|
popup.UpdateImages4(matRightBottom, rectT);
|
|
|
|
List<double> infoArc = Init_ArcInfo();
|
|
List<double> infoSpiral = Init_SpiralInfo();
|
|
|
|
popup.SetParameters1(infoArc); // 24
|
|
popup.SetParameters2(infoSpiral); // 21
|
|
popup.SetParameters3(infoArc);
|
|
popup.SetParameters4(infoSpiral);
|
|
|
|
popup.SetStepLBAD("OK");
|
|
popup.SetStepWELDING("OK");
|
|
|
|
_AutoRunStartTime = DateTime.Now;
|
|
|
|
string ExcelFile = System.IO.Path.Combine(ConfigurationManager.AppSettings.Get("DATA_PATH"), "_vision", "RealTimeScout",
|
|
string.Format($"{DateTime.Now.Year}_{DateTime.Now.Month}_{DateTime.Now.Day}/out/{_AutoRunStartTime.ToString("HHmmss")}.xlsx"));
|
|
|
|
SaveExcelFileRing(matLeftTop, ExcelFile, 1, infoArc); // 24
|
|
SaveExcelFileSpiral(matRightTop, ExcelFile, 2, infoSpiral); // 21
|
|
SaveExcelFileRing(matLeftBottom, ExcelFile, 3, infoArc);
|
|
SaveExcelFileSpiral(matRightBottom, ExcelFile, 4, infoSpiral);
|
|
|
|
result_info[0] = infoArc;
|
|
result_info[1] = infoSpiral;
|
|
result_info[2] = infoArc;
|
|
result_info[3] = infoSpiral;
|
|
|
|
// 레시피 값 가져오기 : 9 + 2 -> 총 11개
|
|
//List<short> recipe = Get_Recipe_Info(); // Recipe : 9
|
|
//WeldingInfoSendPLC(recipe, "OK", "OK");
|
|
|
|
|
|
//KS_WeldingInfo weldingInfo = new KS_WeldingInfo();
|
|
//List<string> Info = weldingInfo.MakeData(infoArc, infoSpiral, infoArc, infoSpiral, recipe, "OK", "OK");
|
|
|
|
while (!context.Stopped)
|
|
{
|
|
Thread.Sleep(100);
|
|
}
|
|
}
|
|
|
|
private SequenceActionResult Sequence_Enter(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
|
|
var activatedRecipeId = Application.Current.AuroraEnv().RecipeManager.ActivatedRecipe().Id;
|
|
var recipeName = WeldingRecipeManager.SearchRecipeItem(activatedRecipeId);
|
|
|
|
Status.GetProcessingWeldingData().ActRecipe = recipeName;
|
|
//Status.GetProcessingWeldingData().PageNO = _PageNoRcc.ToString();
|
|
|
|
//Status.GetProcessingWeldingData().BcrID = "PRD-9X7K2M5Q8T1Z4L6R3W0VYCNJHBDGFZ";
|
|
|
|
//TestopupWin(context);
|
|
|
|
//while (true) { };
|
|
|
|
Log.I("SeqAutoRunKS_New Start");
|
|
Status.SetWorkingPosition(eWorkingPosition.CHECKING_CONDITION);
|
|
|
|
_InitParam = param.Param as SeqAutoRunKS_New_InitParam;
|
|
_RecipeManager = Application.Current.AuroraEnv().RecipeManager;
|
|
_SystemParameter = context.GetSetting<SystemParameter>(CommonSettingIds.SystemParameter);
|
|
|
|
InitDev(context);
|
|
if (!CheckDeviceReady(context))
|
|
{ //Check Device
|
|
AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_AutoRun_DeviceNotReady);
|
|
Log.E("The devices are not active.");
|
|
return null;
|
|
}
|
|
|
|
|
|
if (InitSequenceVariable(context) == false)
|
|
{
|
|
AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_AutoRun_InitVariableError);
|
|
return null;
|
|
}
|
|
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
private bool InitSequenceVariable(SequenceContext context)
|
|
{
|
|
_AutoRunStartTime = DateTime.Now;
|
|
_SeqRunCount = 0;
|
|
_TodayProduct = _SystemParameter.TodayProductCount;
|
|
_TotalProduct = _SystemParameter.TotalProductCount;
|
|
//_SelectedDrawObjectList = _ScannerCanvasUserCtrl.Model.Layers[0].Objects;
|
|
|
|
if (_SystemParameter.SequenceType == eSequenceType.Normal)
|
|
{
|
|
_IsRealTimeScout = false;
|
|
}
|
|
else if (_SystemParameter.SequenceType == eSequenceType.RCC)
|
|
{
|
|
double dPixelResolution = ((_SystemParameter.CameraPixelSize) / _SystemParameter.LensMagnification) / 1000.0;
|
|
//ConvEdgeObjectViewModel에서도 생성되지만.. Seq에서 재생성하고 쓰고 버리자
|
|
_ObjGenerator = new ObjectGenerator(dPixelResolution);
|
|
|
|
if (_SystemParameter.OffsetType == eOffsetType.manual)
|
|
_ObjGenerator.SetOffsetType("Manual");
|
|
else
|
|
{
|
|
_ObjGenerator.SetOffsetType("CSV");
|
|
_ObjGenerator.SetOffsetTable(_SystemParameter.OffsetCSVFile, _SystemParameter.LensMagnification, _SystemParameter.CameraPixelSize);
|
|
}
|
|
_ObjGenerator.SetInterlockProperties(_SystemParameter.DrawObjectDistanceRange, _SystemParameter.DrawObjectArcLengthMax, _SystemParameter.DrawObjectLengthSumDiffRange, _SystemParameter.DrawObjectCenterXYDiffRange, _SystemParameter.MaxMinDiffHigh, _SystemParameter.MaxMinDiffLow, _SystemParameter.CheckCenterDiff, _SystemParameter.DistortionCenterDiff, _SystemParameter.AutoMissAlignHigh, _SystemParameter.AutoMissAlignLow);
|
|
|
|
//if (!_ObjGenerator.GetArcInfoFromRecipe(_RecipeDrawObjects, out _SelectedArcs)) {
|
|
// Log.E(string.Format("Recipe Infomation Register Error"));
|
|
// return false;
|
|
//}
|
|
|
|
_IsRealTimeScout = true;
|
|
|
|
}
|
|
else if (_SystemParameter.SequenceType == eSequenceType.CellCenterOffset)
|
|
{
|
|
// VisionDevice 추가
|
|
// InitializeCameraDevice
|
|
_FovRecipe = VisionRecipeManager.GetFovRecipe(_InitParam.ScoutSeqParams.FovInfo);
|
|
_CameraAgent = CameraAgentManager.GetCameraAgent(_InitParam.ScoutSeqParams.FovInfo);
|
|
_CameraDisplay = CameraDisplayManager.GetDisplay(_InitParam.ScoutSeqParams.FovInfo, _InitParam.ScoutSeqParams.DisplayType);
|
|
|
|
// InitGrabImageBuffer 함수
|
|
try
|
|
{
|
|
IpAdapter.Instance.IpEnvironment.FreeImage(_GrabImage);
|
|
_GrabImage = (MIL_ID)_CameraAgent.CloneImageBuffer();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Log.E(e.Message);
|
|
}
|
|
|
|
_IsRealTimeScout = false;
|
|
|
|
}
|
|
else
|
|
{
|
|
Log.E("Invalid SequenceType.");
|
|
return false;
|
|
}
|
|
|
|
var mainPage = WeldingRecipeManager.GetWeldingPage();
|
|
_ScannerCanvasUserCtrl = mainPage.ScannerCanvasCtrlTeaching;
|
|
_RecipeDrawObjects = _ScannerCanvasUserCtrl.Model.Layers[0].Objects;
|
|
_WeldingScannerListNo = eListNo.LIST1;
|
|
|
|
_CellMeasureCenterOffsetX = 0.0;
|
|
_CellMeasureCenterOffsetY = 0.0;
|
|
|
|
var currentModelName = context.Recipes.ActivatedModelName();
|
|
var modelItem = context.GetModel<EquipmentSpecificModel_KS>(currentModelName, CommonModelIds.EquipmentSpecificModel);
|
|
_ModelNo = modelItem.Model_No;
|
|
|
|
return true;
|
|
}
|
|
private void InitDev(SequenceContext context)
|
|
{
|
|
//Device Init
|
|
_Scanner = context.GetLaserScanner();
|
|
_Laser = context.GetLaser();
|
|
|
|
//_StreamLightLBAD._Client = context.GetStreamLightClient();
|
|
|
|
_PLC = context.Devices[DeviceIds.PLCDevice] as PLCControllerKS;
|
|
_IO = context.GetIOUnit();
|
|
|
|
_LBAD = context.GetLBAD();
|
|
}
|
|
|
|
private bool CheckDeviceReady(SequenceContext context)
|
|
{
|
|
List<string> deviceListToCheck = new List<string>() { CommonDeviceIds.Scanner, CommonDeviceIds.Laser,
|
|
CommonDeviceIds.PLCDevice, CommonDeviceIds.IODevice, CommonDeviceIds.LBAD };
|
|
bool isAllDeviceActivated = true;
|
|
foreach (string item in deviceListToCheck)
|
|
{
|
|
if (!context.Devices[item].IsActivated)
|
|
{
|
|
isAllDeviceActivated = isAllDeviceActivated && false;
|
|
}
|
|
}
|
|
|
|
return isAllDeviceActivated;
|
|
}
|
|
|
|
private bool CheckCondition(SequenceContext context)
|
|
{
|
|
if (CheckCondition_Interlock())
|
|
{
|
|
if (InitializeDeviceStatus(context))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private bool CheckCondition_Interlock()
|
|
{
|
|
// PLC, Data, IO 등 Interlock checking
|
|
return true;
|
|
}
|
|
|
|
private bool InitializeDeviceStatus(SequenceContext context)
|
|
{
|
|
// PLC Interface AutoStatus Start
|
|
InitAutoRunBit();
|
|
|
|
// Laser Initialize
|
|
_Laser.PilotLaserOff();
|
|
_Laser.LaserOn();
|
|
Thread.Sleep(100);
|
|
if (!_Laser.GetLaserReady())
|
|
{
|
|
Log.E("ERROR Initialize Laser");
|
|
return false;
|
|
}
|
|
|
|
// Scanner Initialize
|
|
// Scanner 없음.
|
|
|
|
// OCT Initialize
|
|
// TODO: EnterSequenceModeOCT 와 함께 Initialize 하는 것을 재구현 필요함. 초반에 한번만 check 하고 돌아 갈수 있도록
|
|
|
|
// PLC Initialize
|
|
if (_PLC.ReadBit((int)eBitInput.PLC_AUTO_STATUS).data == false)
|
|
{
|
|
Log.E(string.Format("ERROR Initialize PLC, Bit Off PLC_AUTO_STATUS"));
|
|
return false;
|
|
}
|
|
|
|
// LBAD Initialize
|
|
// LBAD 는 server 이기 때문에, 만약 끊어졌으면 다시 접속이 필요함
|
|
if (!_LBAD.GetConnected())
|
|
{
|
|
_LBAD.DisConnect();
|
|
Thread.Sleep(500);
|
|
int ret = _LBAD.Open(_LBAD.Config);
|
|
if (ret == -1)
|
|
{
|
|
Log.E($"LBAD Open Error : {ret}");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADReadyStatus), true);
|
|
Log.I(string.Format($"[IOInterface]SET PCLBADReadyStatus true"));
|
|
|
|
if (_SystemParameter.SequenceType == eSequenceType.Normal)
|
|
{
|
|
_Scanner.SelectCorrectionTable(2);
|
|
Log.I(string.Format("Normal, Select Laser Correction File"));
|
|
}
|
|
else if (_SystemParameter.SequenceType == eSequenceType.RCC)
|
|
{
|
|
_Scanner.SelectCorrectionTable(1);
|
|
Log.I(string.Format("RCC, Select Vision Correction File"));
|
|
}
|
|
else if (_SystemParameter.SequenceType == eSequenceType.CellCenterOffset)
|
|
{
|
|
_Scanner.SelectCorrectionTable(1);
|
|
Log.I(string.Format("CellCenterOffset, Select Vision Correction File"));
|
|
}
|
|
else
|
|
{
|
|
Log.I(string.Format("Invalid SequenceType."));
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private void InitAutoRunBit()
|
|
{
|
|
Log.I(string.Format($"[PLCInterface] Start AutoRun PLC Bit Initialize"));
|
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_REQEUST_ACK, false);
|
|
Log.I(string.Format($"[PLCInterface]SET PC_WELD_REQEUST_ACK False"));
|
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE, false);
|
|
Log.I(string.Format($"[PLCInterface]SET PC_WELD_COMPLETE False"));
|
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_READY, false);
|
|
Log.I(string.Format($"[PLCInterface]SET PC_WELD_READY False"));
|
|
_PLC.WriteBit((int)eBitOutput.PC_AUTO_STATUS, true);
|
|
Log.I(string.Format($"[PLCInterface]SET PC_AUTO_STATUS True"));
|
|
// Page Rrset
|
|
bool[] Page = new bool[4];
|
|
Page = new bool[4] { false, false, false, false };
|
|
_PLC.WriteBitBlock((int)eBitOutput.PC_WELD_PAGE_CHANGE_COMPLETE_1, 4, Page);
|
|
Log.I(string.Format("[PLCInterface]Pgae Reset"));
|
|
|
|
_PLC.WriteBit((int)eBitOutput.PC_LBAD_RESULT_NG, false);
|
|
Log.I(string.Format($"[PLCInterface]SET PC_LBAD_RESULT_NG False"));
|
|
|
|
_PLC.WriteBit((int)eBitOutput.PC_LBAD_RESULT_OK, false);
|
|
Log.I(string.Format($"[PLCInterface]SET PC_LBAD_RESULT_OK False"));
|
|
|
|
|
|
_PLC.WriteBit((int)eBitOutput.PC_RECIPE_PARAM_UPLOAD_COMPLETE, false);
|
|
Log.I(string.Format($"[PLCInterface]SET PC_RECIPE_PARAM_UPLOAD_COMPLETE false"));
|
|
|
|
UpdatePLCMemoryAreaCls((int)eWordOutput.STEP1_Arc1_LowerLimit, (int)eWordOutput.WeldingOK_NG);
|
|
|
|
Log.I(string.Format($"[IOInterface] Start AutoRun IO Bit Initialize"));
|
|
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADReadyStatus), false);
|
|
Log.I(string.Format($"[IOInterface]SET PCLBADReadyStatus False"));
|
|
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingTrigger), false);
|
|
Log.I(string.Format($"[IOInterface]SET PCLBADWeldingTrigger False"));
|
|
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), false);
|
|
Log.I(string.Format($"[IOInterface]SET PCLBADWeldingStop False"));
|
|
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADJudgementCompleteAck), false);
|
|
Log.I(string.Format($"[IOInterface]SET PCLBADJudgementCompleteAck False"));
|
|
Log.I(string.Format($"[IOInterface] Complete AutoRun IO Bit Initialize"));
|
|
}
|
|
|
|
private string CheckBeforeOrAfter(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
|
|
{
|
|
_SystemParameter = context.GetSetting<SystemParameter>(CommonSettingIds.SystemParameter);
|
|
|
|
var resultOutParam = param.Param as SeqScoutFlyingVision_OutParam;
|
|
//return SequenceAction.Ok();
|
|
|
|
if (pre_welding)
|
|
{
|
|
pre_welding = !pre_welding;
|
|
return SEQ_BEFORE_WELD_MOVE_OBJECT;
|
|
|
|
}
|
|
else
|
|
{
|
|
pre_welding = !pre_welding;
|
|
return SEQ_AFTER_WELD_CHECK_BEAD;
|
|
}
|
|
|
|
}
|
|
|
|
private string CheckInitCondition(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
|
|
{
|
|
if (!CheckCondition(context))
|
|
{
|
|
AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_AutoRun_CheckInitCondition);
|
|
Log.E("Condition is not in state to start sequence.");
|
|
context.PutValue(ContextKey.KEY_SEQUENCE_RESULT, false);
|
|
return SEQ_COMPLETE;
|
|
}
|
|
|
|
var startTime = DateTime.Now;
|
|
context.PutValue(ContextKey.KEY_SEQUENCE_START_TIME, startTime);
|
|
|
|
Log.D("ReceiveCellInfo Sequence CheckInitCondition");
|
|
//return SEQ_CHECK_LOAD_COMPLETE;
|
|
|
|
return SEQ_CHECK_PAGENO;
|
|
}
|
|
|
|
//private string GetPLC_WordDataToString(short[] rawData)
|
|
//{
|
|
// byte[] bytes = new byte[rawData.Length * 2];
|
|
// for (int i = 0; i < rawData.Length; i++)
|
|
// {
|
|
// bytes[i * 2] = (byte)(rawData[i] & 0xFF); // 하위 바이트
|
|
// bytes[i * 2 + 1] = (byte)((rawData[i] >> 8) & 0xFF); // 상위 바이트
|
|
// }
|
|
|
|
// string result = Encoding.ASCII.GetString(bytes);
|
|
|
|
// return result;
|
|
//}
|
|
|
|
private short[] SetPLC_StringDataToWord(string dataString)
|
|
{
|
|
List<short> shorts = new List<short>();
|
|
|
|
for (int i = 0; i < dataString.Length; i += 2)
|
|
{
|
|
byte first = (byte)dataString[i];
|
|
byte second = (i + 1 < dataString.Length) ? (byte)dataString[i + 1] : (byte)0;
|
|
|
|
// 반전하여 저장: second first
|
|
short combined = (short)((second << 8) | first);
|
|
shorts.Add(combined);
|
|
}
|
|
|
|
|
|
return shorts.ToArray();
|
|
}
|
|
|
|
public static short[] IntArrayToShortArray(int[] intArray)
|
|
{
|
|
// short 범위 -> -32768 ~ 32767
|
|
short[] shortArray = new short[intArray.Length * 2];
|
|
for (int i = 0; i < intArray.Length; i++)
|
|
{
|
|
shortArray[i * 2] = (short)((intArray[i] >> 16) & 0xFFFF); // 상위 16비트
|
|
shortArray[i * 2 + 1] = (short)(intArray[i] & 0xFFFF); // 하위 16비트
|
|
}
|
|
return shortArray;
|
|
}
|
|
|
|
public static int[] ShortArrayToIntArray(short[] shortArray)
|
|
{
|
|
if (shortArray.Length % 2 != 0)
|
|
throw new ArgumentException("short 배열 길이는 반드시 짝수여야 합니다.");
|
|
|
|
int[] intArray = new int[shortArray.Length / 2];
|
|
for (int i = 0; i < intArray.Length; i++)
|
|
{
|
|
int high = (ushort)shortArray[i * 2]; // 부호 없는 16비트로 캐스팅
|
|
int low = (ushort)shortArray[i * 2 + 1];
|
|
intArray[i] = (high << 16) | low;
|
|
}
|
|
return intArray;
|
|
}
|
|
|
|
|
|
public void SetBCRID(string id)
|
|
{
|
|
//string TestString = "ABCDEFG";
|
|
//short[] data = SetPLC_StringDataToWord(TestString);
|
|
//string hexString1 = string.Join(" ", Array.ConvertAll(data, s => s.ToString("X4")));
|
|
|
|
////short[] WordData = new short[] { 0x00A0, 0x00B0 };
|
|
//_PLC.WriteWordBlock((int)eWordOutput.PC_RECIPE_NO, 2, data);
|
|
//var Red = _PLC.ReadWordBlock((int)eWordOutput.PC_RECIPE_NO, 2).data;
|
|
//Log.I(string.Format($"[PLCInterface]SET PLC_BCR_ID {0}", _BcrID));
|
|
}
|
|
|
|
//public string GetBCRID()
|
|
//{
|
|
// string id = "";
|
|
|
|
// var bcrid = _PLC.ReadWordBlock((int)eWordInput.PLC_BCR_ID, 16).data;
|
|
|
|
// string hexString = string.Join(" ", Array.ConvertAll(bcrid, s => s.ToString("X4")));
|
|
// // 4241 4443 4645 4847 4A49 4C4B 4E4D 504F 5251 5453 3130 3332 3534 3736 3938 0000
|
|
// id = GetPLC_WordDataToString(bcrid);
|
|
// Log.I(string.Format($"[PLCInterface]GET PLC_BCR_ID {0}", id));
|
|
|
|
// return id;
|
|
//}
|
|
|
|
public void SetPagePlc(int num)
|
|
{
|
|
bool[] Page = new bool[4];
|
|
|
|
switch (num)
|
|
{
|
|
case 0:
|
|
{
|
|
Page = new bool[4] { false, false, false, false };
|
|
_PLC.WriteBitBlock((int)eBitOutput.PC_WELD_PAGE_CHANGE_COMPLETE_1, 4, Page);
|
|
}
|
|
break;
|
|
|
|
case 1:
|
|
{
|
|
Page = new bool[4] { true, false, false, false };
|
|
_PLC.WriteBitBlock((int)eBitOutput.PC_WELD_PAGE_CHANGE_COMPLETE_1, 4, Page);
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
{
|
|
Page = new bool[4] { false, true, false, false };
|
|
_PLC.WriteBitBlock((int)eBitOutput.PC_WELD_PAGE_CHANGE_COMPLETE_1, 4, Page);
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
{
|
|
Page = new bool[4] { false, false, true, false };
|
|
_PLC.WriteBitBlock((int)eBitOutput.PC_WELD_PAGE_CHANGE_COMPLETE_1, 4, Page);
|
|
}
|
|
break;
|
|
|
|
case 4:
|
|
{
|
|
Page = new bool[4] { false, false, false, true };
|
|
_PLC.WriteBitBlock((int)eBitOutput.PC_WELD_PAGE_CHANGE_COMPLETE_1, 4, Page);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
public int GetPagePlc()
|
|
{
|
|
int num = 0;
|
|
|
|
bool[] page = _PLC.ReadBitBlock((int)eBitInput.PLC_SET_WELD_PAGE_1, 4).data;
|
|
if (page[0]) num = 1;
|
|
if (page[1]) num = 2;
|
|
if (page[2]) num = 3;
|
|
if (page[3]) num = 4;
|
|
|
|
return num;
|
|
}
|
|
|
|
// Add jmj ->
|
|
private SequenceActionResult CheckPageNo(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
Status.SetWorkingPosition(eWorkingPosition.LOADING_CELL);
|
|
|
|
#region ex
|
|
//UpdatePLCMemoryArea_test();
|
|
|
|
//int nRecipeNo = _RecipeManager.ActivatedRecipe().Id;
|
|
//int recipeRequestId = 18;
|
|
|
|
//if (nRecipeNo != recipeRequestId)
|
|
//{
|
|
// var recipeName = WeldingRecipeManager.SearchRecipeItem(recipeRequestId);
|
|
|
|
// if (recipeName != string.Empty)
|
|
// {
|
|
// Application.Current.AuroraEnv().EventPublisher.Publish(new EventMessage(SequenceIds.SeqAutoRunKS_New, "Autorun_Recipe_Change", (recipeRequestId, recipeName)));
|
|
// Thread.Sleep(500);
|
|
// }
|
|
|
|
// nRecipeNo = _RecipeManager.ActivatedRecipe().Id;
|
|
//}
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
// Cell 이 Load 완료되어서 Scout 가 가능한 상태인지 확인
|
|
#region Whie -> PLC_JIG_LOAD_COMPLETE
|
|
_InterfaceStartTime = DateTime.Now;
|
|
while (!context.Stopped)
|
|
{
|
|
if (_PLC.ReadBit((int)eBitInput.PLC_JIG_LOAD_COMPLETE).data)
|
|
{
|
|
Log.I(string.Format("Cell Loading is completed."));
|
|
|
|
break;
|
|
}
|
|
_InterfaceSpanTime = DateTime.Now.Subtract(_InterfaceStartTime);
|
|
|
|
if (_InterfaceSpanTime.TotalMilliseconds > (PLC_TIMEOUT * 1000))
|
|
{
|
|
Log.E("TIMEOUT_PLC_JIG_LOAD_COMPLETE");
|
|
_InterfaceStartTime = DateTime.Now;
|
|
}
|
|
Thread.Sleep(10);
|
|
}
|
|
#endregion
|
|
|
|
|
|
_PLC.WriteBit((int)eBitOutput.PC_LBAD_RESULT_OK, false);
|
|
Log.I(string.Format($"[PLCInterface]SET PC_LBAD_RESULT_OK False"));
|
|
|
|
_PLC.WriteBit((int)eBitOutput.PC_LBAD_RESULT_NG, false);
|
|
Log.I(string.Format($"[PLCInterface]SET PC_LBAD_RESULT_NG False"));
|
|
|
|
// 이전 셀의 LBAD 판정값이 남아있으면 이번 셀에서 판정을 못했을 때 그대로 재전송되므로 여기서 초기화한다.
|
|
Status.GetProcessingWeldingData().LBAD_Judge = string.Empty;
|
|
Log.I(string.Format($"[PLCInterface]CLEAR LBAD_Judge"));
|
|
|
|
|
|
_InterfaceStartTime = DateTime.Now;
|
|
while (!context.Stopped)
|
|
{
|
|
#region PLC 에서 PAGE 정보 가져오기 ( BIT 영역 )
|
|
_PageNo = GetPagePlc();
|
|
#endregion
|
|
|
|
if (_PageNo != 0) break;
|
|
|
|
_InterfaceSpanTime = DateTime.Now.Subtract(_InterfaceStartTime);
|
|
|
|
if (_InterfaceSpanTime.TotalMilliseconds > (PLC_TIMEOUT * 1000))
|
|
{
|
|
Log.E("TIMEOUT_PLC_PAGENO");
|
|
_InterfaceStartTime = DateTime.Now;
|
|
}
|
|
Thread.Sleep(10);
|
|
}
|
|
|
|
if (_PageNo != 0)
|
|
{
|
|
if (ksExit)
|
|
{
|
|
UpdatePLCMemoryAreaCls((int)eWordOutput.STEP1_Arc1_LowerLimit, (int)eWordOutput.WeldingOK_NG);
|
|
popup.Hide();
|
|
}
|
|
|
|
_BcrID = _PLC.GetBcrCode();// GetBCRID();
|
|
Log.I($"Bcr Id : {_BcrID}");
|
|
Status.GetProcessingWeldingData().BcrID = _BcrID;
|
|
|
|
|
|
// RCC 들어가기전에 1로 바꿔있어야된다...
|
|
_Scanner.SelectCorrectionTable(1);
|
|
|
|
var mainPage = WeldingRecipeManager.GetWeldingPage();
|
|
_ScannerCanvasUserCtrl = mainPage.ScannerCanvasCtrlTeaching;
|
|
_RecipeDrawObjects = _ScannerCanvasUserCtrl.Model.Layers[_PageNo - 1].Objects;
|
|
List<IDrawObject> tempobject = new List<IDrawObject>();
|
|
int startindex = 0; int nCount = _RecipeDrawObjects.Count;
|
|
for (int i = startindex; i < _RecipeDrawObjects.Count; i++)
|
|
{
|
|
if (i >= startindex + nCount)
|
|
break;
|
|
tempobject.Add(_RecipeDrawObjects[i]);
|
|
}
|
|
_SelectedDrawObjectList = tempobject;
|
|
_WeldingScannerListNo = eListNo.LIST1;
|
|
|
|
SetPagePlc(_PageNo);
|
|
|
|
_PageNoRcc = _PageNo - 1;
|
|
|
|
var activatedRecipeId = Application.Current.AuroraEnv().RecipeManager.ActivatedRecipe().Id;
|
|
var recipeName = WeldingRecipeManager.SearchRecipeItem(activatedRecipeId);
|
|
|
|
Status.GetProcessingWeldingData().ActRecipe = recipeName;
|
|
Status.GetProcessingWeldingData().PageNO = (_PageNoRcc + 1).ToString();
|
|
|
|
//Status.GetProcessingWeldingData().BcrID = "PRD-9X7K2M5Q8T1Z4L6R3W0VYCNJHBDGFZ";
|
|
Status.GetProcessingWeldingData().BcrID = _BcrID;
|
|
}
|
|
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
// 지그 상태 확인
|
|
private string CheckLoadComplete(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
|
|
{
|
|
Status.SetWorkingPosition(eWorkingPosition.LOADING_CELL);
|
|
|
|
TimeSpan spanTime;
|
|
DateTime startTime = DateTime.Now;
|
|
|
|
if (RecipeChange) { return SEQ_KS_WAIT_VISION; }
|
|
else
|
|
{
|
|
if (_SystemParameter.SequenceType == eSequenceType.Normal)
|
|
{
|
|
// CorrectionTable ==> 2
|
|
return SEQ_READY_SCANNER_LIST;
|
|
}
|
|
else
|
|
{
|
|
_CamConfig = Application.Current.AuroraEnv().DeviceManager.GetDeviceConfig(eCamId.CAM1.ToString()) as CamConfig;
|
|
// RCC, CellCenterOffset
|
|
// RCC의 경우 LoadCompleteCheck 전 Scout 첫번째 위치로 스캐너 이동 해놓는게 시간을 벌듯..
|
|
// CellCenterOffset은 중심위치에서 그랩하니깐 해당 기능 필요없을 것이라 우선 여기서 if문 처리하자
|
|
// 즉 정리하면, RCC 만 이동하고, CellCenterOffset은 이동 하지 않음.
|
|
if (_SystemParameter.SequenceType == eSequenceType.RCC)
|
|
{
|
|
int scoutNo = 0;
|
|
if (_CamConfig.ChildImage.ChildBufRowCols[scoutNo].Enabled)
|
|
{
|
|
double XPos = _CamConfig.ChildImage.ChildBufRowCols[scoutNo].MotorPos.X + _CamConfig.ChildImage.ChildBufRowCols[scoutNo].MotorPosOffset.X; //카메라 위치에 대한 보정값 입력
|
|
double YPos = _CamConfig.ChildImage.ChildBufRowCols[scoutNo].MotorPos.Y + _CamConfig.ChildImage.ChildBufRowCols[scoutNo].MotorPosOffset.Y; //카메라 위치에 대한 보정값 입력
|
|
Log.I(string.Format($"Move No.{scoutNo + 1} Field Scan Pos(X,Y:{XPos},{YPos})"));
|
|
|
|
//1.스캐너 필드 위치 이동(Jump)
|
|
_Scanner.JumpAbs(XPos, YPos, eFunctionType.COMMAND);
|
|
}
|
|
|
|
|
|
return SEQ_SET_SCOUT_FLYING_VISION_SEQ;
|
|
|
|
}
|
|
|
|
return SEQ_READY_SCANNER_LIST;
|
|
}
|
|
}
|
|
}
|
|
|
|
private SequenceActionResult SetReceiveCellInfo_SeqParams(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
SeqReceiveCellInfo_InitParam seqParams = new SeqReceiveCellInfo_InitParam()
|
|
{
|
|
};
|
|
|
|
return SequenceAction.Ok(seqParams);
|
|
}
|
|
|
|
private SequenceActionResult GetReceiveCellInfo_SeqResult(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
var resultOutParam = param.Param as SeqReceiveCellInfo_OutParam;
|
|
if (resultOutParam.Success == false)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
public MIL_ID DoGrab()
|
|
{
|
|
var image = (object)_GrabImage;
|
|
_CameraAgent.GrabSync(_CameraDisplay, ref image);
|
|
_GrabImage = (MIL_ID)image;
|
|
|
|
return _GrabImage;
|
|
}
|
|
|
|
// RCC FlyingVision
|
|
#region RCC FlyingVision
|
|
private SequenceActionResult SetScoutFlyingVision_SeqParams(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
Log.I($"AutoRun Seq Run Count : {_SeqRunCount}");
|
|
var scoutSeqParams = new ScoutSeqParams(VisionRecipeManager.GetFovInfos()[0], eDisplayType.Machine_B);
|
|
|
|
SeqScoutFlyingVision_InitParam seqParams = new SeqScoutFlyingVision_InitParam()
|
|
{
|
|
IsRealTimeScout = _IsRealTimeScout,
|
|
ScoutSeqParams = scoutSeqParams,
|
|
SequenceAutoRunCount = _SeqRunCount,
|
|
WeldingScannerListNo = eListNo.LIST2,
|
|
};
|
|
|
|
return SequenceAction.Ok(seqParams);
|
|
}
|
|
|
|
//private string GetScoutFlyingVision_SeqResult(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
|
|
//{
|
|
// var resultOutParam = param.Param as SeqScoutFlyingVision_OutParam;
|
|
// if (pre_welding)
|
|
// {
|
|
// pre_welding = !pre_welding;
|
|
// return SEQ_BEFORE_WELD_MOVE_OBJECT;
|
|
|
|
// }
|
|
// else
|
|
// {
|
|
// pre_welding = !pre_welding;
|
|
// return SEQ_AFTER_WELD_CHECK_BEAD;
|
|
// }
|
|
|
|
// if (resultOutParam.Success == false)
|
|
// {
|
|
// return null;
|
|
// }
|
|
//}
|
|
private SequenceActionResult GetScoutFlyingVision_SeqResult(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
|
|
var resultOutParam = param.Param as SeqScoutFlyingVision_OutParam;
|
|
return SequenceAction.Ok();
|
|
|
|
//if (pre_welding)
|
|
//{
|
|
// pre_welding = !pre_welding;
|
|
// return SEQ_BEFORE_WELD_MOVE_OBJECT;
|
|
|
|
//}
|
|
//else
|
|
//{
|
|
// pre_welding = !pre_welding;
|
|
// return SEQ_AFTER_WELD_CHECK_BEAD;
|
|
//}
|
|
|
|
if (resultOutParam.Success == false)
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
// RCC Normal Vision
|
|
#region RCC Normal Vision
|
|
private SequenceActionResult SetScoutNORMALVision_SeqParams(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
Log.I($"AutoRun Seq Run Count : {_SeqRunCount}");
|
|
var scoutSeqParams = new ScoutSeqParams(VisionRecipeManager.GetFovInfos()[0], eDisplayType.Machine_B);
|
|
|
|
SeqScoutFlyingVision_InitParam seqParams = new SeqScoutFlyingVision_InitParam()
|
|
{
|
|
IsRealTimeScout = _IsRealTimeScout,
|
|
ScoutSeqParams = scoutSeqParams,
|
|
SequenceAutoRunCount = _SeqRunCount,
|
|
WeldingScannerListNo = eListNo.LIST2,
|
|
};
|
|
|
|
return SequenceAction.Ok(seqParams);
|
|
}
|
|
|
|
private SequenceActionResult GetScoutNORMALVision_SeqResult(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
var resultOutParam = param.Param as SeqScoutFlyingVision_OutParam;
|
|
if (resultOutParam.Success == false)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return SequenceAction.Ok();
|
|
}
|
|
#endregion
|
|
|
|
// For RCC Only
|
|
private SequenceActionResult SaveScoutImageEvent(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
MIL_ID ScannerFieldImage = Status.GetProcessingWeldingData().ScannerFiledImage;
|
|
if (ScannerFieldImage != null)
|
|
{
|
|
SaveScoutImage(ScannerFieldImage);
|
|
}
|
|
else
|
|
{
|
|
Log.E("ScannerFieldImage is Null");
|
|
}
|
|
return SequenceAction.Ok();
|
|
}
|
|
private object SendEvent(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
//Event로 넘겨줄 Param은 따로 없다.
|
|
return null;
|
|
}
|
|
private SequenceActionResult FindEdge(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
MIL_ID ScannerFieldImage = Status.GetProcessingWeldingData().ScannerFiledImage;
|
|
|
|
//RCC Error로 인해 시퀀스를 종료하고 있는데, NG배출해야 될지 확인 필요
|
|
_StopwatchGenObj = Stopwatch.StartNew();
|
|
#region Find Edge
|
|
_ObjGenerator.ConvertMILToMat(ScannerFieldImage, out _ConvMatImage);
|
|
if (_ConvMatImage == null)
|
|
{
|
|
Log.E(string.Format("[GenerateWeldingObject] Scout Image is empty. Check Camera or Cell."));
|
|
return null;
|
|
}
|
|
var (centerX, centerY) = FindCenterReicpeSingleArc(_ConvMatImage);
|
|
if (_ObjGenerator.FindEdge(_ConvMatImage, _Radius_Pixel, _SystemParameter.Margin, _SystemParameter.PointNum, _SystemParameter.CVThreshold, centerX, centerY, _SystemParameter.DetectPointPercent, _SystemParameter.CVJigSize, out Point[][] maxContour, out _DetectedContourCenter) == false)
|
|
{
|
|
Log.E(string.Format("[GenerateWeldingObject] Edge Detection Interlock."));
|
|
return null;
|
|
}
|
|
if (maxContour[0].Count() < 1 || maxContour == null)
|
|
{
|
|
Log.E(string.Format("[GenerateWeldingObject] MaxContour is Null. Check Scout Image."));
|
|
return null;
|
|
}
|
|
context.PutValue("MAX_CONTOUR_FIND_EDGE", maxContour);
|
|
_StopwatchGenObj.Stop();
|
|
Log.I(string.Format($"[GenerateWeldingObject] Find Edge Complete Time : {_StopwatchGenObj.ElapsedMilliseconds} msec"));
|
|
#endregion
|
|
|
|
return SequenceAction.Ok();
|
|
}
|
|
private (int centerX, int centerY) FindCenterReicpeSingleArc(Mat image)
|
|
{
|
|
int centerX = 0, centerY = 0;
|
|
foreach (var item in _RecipeDrawObjects)
|
|
{
|
|
if (item is Arc)
|
|
{
|
|
Arc arc = (Arc)item;
|
|
centerX = (int)(arc.Center.X * 1000.0 / _SystemParameter.CameraPixelSize * _SystemParameter.LensMagnification + image.Width / 2);
|
|
centerY = (int)(-arc.Center.Y * 1000.0 / _SystemParameter.CameraPixelSize * _SystemParameter.LensMagnification + image.Height / 2);
|
|
break;
|
|
}
|
|
}
|
|
return (centerX, centerY);
|
|
}
|
|
private string DecisionRCCAlgorithmType(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
|
|
{
|
|
// FindEdge의 maxContour를 param으로 받아오기
|
|
Point[][] maxContour = context.GetValue<Point[][]>("MAX_CONTOUR_FIND_EDGE");
|
|
// CheckEdge의 Return 결과를 param 으로 받아와서 현재 노드에서 4가지 경우로 분류하자
|
|
var (centerX, centerY) = FindCenterReicpeSingleArc(_ConvMatImage);
|
|
int[] shrinkList = new int[] { _SystemParameter.CVShrinkPixel, _SystemParameter.CVShrinkPixel2, _SystemParameter.CVShrinkPixel3, _SystemParameter.CVShrinkPixel4 };
|
|
int resultCheckEdge = _ObjGenerator.CheckEdge(maxContour, shrinkList, _ConvMatImage.Height, _ConvMatImage.Width, centerX, centerY, _SystemParameter.EnableAutoMissAlign, out _MaxContour);
|
|
if (resultCheckEdge == 3)
|
|
{
|
|
Log.E("Error Check Edge. Check EdgeDetect Center or Over LocalMaxMinDiff Upper");
|
|
return null;
|
|
}
|
|
|
|
if (_SystemParameter.RCCAlgorithmType == eRCCAlgorithmType.OnlyGenObject)
|
|
{
|
|
return SEQ_GENERATE_WELDING_OBJECT;
|
|
}
|
|
else if (_SystemParameter.RCCAlgorithmType == eRCCAlgorithmType.OnlyOffsetObject)
|
|
{
|
|
return SEQ_APPLY_OFFSET_OBJECT;
|
|
}
|
|
else
|
|
{
|
|
if (resultCheckEdge == 0)
|
|
{
|
|
return SEQ_READY_SCANNER_LIST;
|
|
}
|
|
else if (resultCheckEdge == 1)
|
|
{
|
|
return SEQ_APPLY_OFFSET_OBJECT;
|
|
}
|
|
else if (resultCheckEdge == 2)
|
|
{
|
|
return SEQ_GENERATE_WELDING_OBJECT;
|
|
}
|
|
else
|
|
{
|
|
Log.E("Error Check Edge. Check EdgeDetect Center or Over LocalMaxMinDiff Upper");
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
private SequenceActionResult ApplyOffsetObejct(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
var (centerX, centerY) = FindCenterReicpeSingleArc(_ConvMatImage);
|
|
// Recipe 객체는 그대로 사용하고 CetnerOffset 값을 SeqUploadWeldingList에서 사용할 수 있도록 넣어준다
|
|
double centerOffsetX = _DetectedContourCenter.X - centerX;
|
|
double centerOffsetY = _DetectedContourCenter.Y - centerY;
|
|
|
|
_CellMeasureCenterOffsetX = centerOffsetX;
|
|
_CellMeasureCenterOffsetY = centerOffsetY;
|
|
Log.I(string.Format($"Object CenterOffsetX : {centerOffsetX}, CenterOffsetY : {centerOffsetY}"));
|
|
|
|
return SequenceAction.Ok();
|
|
}
|
|
private SequenceActionResult GenerateWeldingObject(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
#region Generate Object
|
|
_StopwatchGenObj.Restart();
|
|
_ObjGenerator.SetPolygonFromList(_MaxContour, out _Polygon);
|
|
if (_SystemParameter.ObjectGenType == eObjectGenType.FitArcsAndLines)
|
|
{
|
|
_ObjGenerator.CalculateAutoPath(_ConvMatImage, _SelectedArcs[0], _Polygon, _SystemParameter.dMergeDist, _SystemParameter.nMaxArcRadius, _SystemParameter.nLineTolerance, _SystemParameter.nArcTolerance, _DetectedContourCenter, out _Paths);
|
|
}
|
|
else
|
|
{
|
|
_ObjGenerator.CalculateAutoPathAngle(_ConvMatImage, _SelectedArcs[0], _Polygon, _SystemParameter.dMergeDist, _SystemParameter.ObjectNumber, _DetectedContourCenter, out _Paths);
|
|
}
|
|
//Generate 한 object 를 SelectedDrawObjects 에 넣어두고 쓴다.
|
|
_ObjGenerator.ConvertPathItemToDrawingObjects(_Paths, _SystemParameter.fLineDefualtWidth, _ConvMatImage, _SelectedArcs[0], out _GeneratedDrawObjects);
|
|
//objGenerator.SaveDrawingObjectsToCSV(GeneratedDrawObjects, "SeqAutoRunKS_RCC_before");
|
|
if (_ObjGenerator.CheckInterlockDrawingObjectPosition(_GeneratedDrawObjects, _DetectedContourCenter, _SelectedArcs[0]) == false)
|
|
{
|
|
Log.E(string.Format("[GenerateWeldingObject]Interlock DrawingObject."));
|
|
return null;
|
|
}
|
|
List<IDrawObject> tempobject = new List<IDrawObject>();
|
|
int startindex = 0; int nCount = _RecipeDrawObjects.Count;
|
|
for (int i = startindex; i < _RecipeDrawObjects.Count; i++)
|
|
{
|
|
if (i >= startindex + nCount)
|
|
break;
|
|
tempobject.Add(_RecipeDrawObjects[i]);
|
|
}
|
|
_SelectedDrawObjectList = tempobject;
|
|
|
|
//현재 Recipe의 Arc객체를 RCC로 생성된 객체로 대체하면서 Group화 해준다
|
|
_ObjGenerator.ReplaceRCCObject(eArcCount.FirstArc, _SelectedDrawObjectList, _GeneratedDrawObjects, _DetectedContourCenter);
|
|
|
|
_ObjGenerator.SaveDrawingObjectsToCSV(_GeneratedDrawObjects, "SeqAutoRunKS_RCC");
|
|
|
|
_StopwatchGenObj.Stop();
|
|
Log.I(string.Format($"[GenerateWeldingObject] Generate Object Complete Time : {_StopwatchGenObj.ElapsedMilliseconds} msec"));
|
|
#endregion
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
private SequenceActionResult ReadyScannerList(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
Status.SetWorkingPosition(eWorkingPosition.UPLOADING_WELD_LIST);
|
|
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
private SequenceActionResult SetUploadWeldingList_SeqParams(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
Log.I("SeqDryRun SetUploadWeldingList_SeqParams");
|
|
SeqUploadWeldingList_InitParam seqParams = new SeqUploadWeldingList_InitParam()
|
|
{
|
|
NeedSetLaserTiming = false,
|
|
IncludeListStartEnd = true,
|
|
CellMeasureCenterOffsetX = _CellMeasureCenterOffsetX,
|
|
CellMeasureCenterOffsetY = _CellMeasureCenterOffsetY,
|
|
SelectedDrawObjectList = _SelectedDrawObjectList,
|
|
WeldingScannerListNo = _WeldingScannerListNo,
|
|
};
|
|
|
|
return SequenceAction.Ok(seqParams);
|
|
}
|
|
|
|
private SequenceActionResult GetUploadWeldingList_SeqResult(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
var resultOutParam = param.Param as SeqUploadWeldingList_OutParam;
|
|
if (resultOutParam.Success == false)
|
|
{
|
|
AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_UploadWeldingList_ResultFailed);
|
|
return null;
|
|
}
|
|
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
private SequenceActionResult WaitWeldingStart(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_READY, true);
|
|
Log.I(string.Format($"[PLCInterface]SET PC_WELD_READY True"));
|
|
|
|
Thread.Sleep(500);
|
|
|
|
#region PLC_WELD_REQEUST 채크로직
|
|
_InterfaceStartTime = DateTime.Now;
|
|
while (!context.Stopped)
|
|
{
|
|
if (_PLC.ReadBit((int)eBitInput.PLC_WELD_REQEUST).data)
|
|
{
|
|
Log.I(string.Format($"[PLCInterface]GET PLC_WELD_REQEUST True"));
|
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_REQEUST_ACK, true);
|
|
Log.I(string.Format($"[PLCInterface]SET PC_WELD_REQEUST_ACK True"));
|
|
|
|
break;
|
|
}
|
|
|
|
_InterfaceSpanTime = DateTime.Now.Subtract(_InterfaceStartTime);
|
|
if (_InterfaceSpanTime.TotalMilliseconds > (PLC_TIMEOUT * 1000))
|
|
{
|
|
Log.E("TIMEOUT_PLC_WELD_REQEUST");
|
|
_InterfaceStartTime = DateTime.Now;
|
|
}
|
|
Thread.Sleep(10);
|
|
}
|
|
#endregion
|
|
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
private SequenceActionResult ExecuteWelding(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
Status.SetWorkingPosition(eWorkingPosition.EXECUTING_WELD);
|
|
|
|
// Laser Correction 파일로 변경, 레이저를 사용해야 하므로 2
|
|
_Scanner.SelectCorrectionTable(2);
|
|
_CellId = Status.GetProcessingWeldingData().BcrID;
|
|
_LotId = Status.GetProcessingWeldingData().WorkLotId;
|
|
|
|
int recipeNo = _RecipeManager.ActivatedRecipe().Id;
|
|
|
|
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingTrigger), true);
|
|
|
|
//int sendresult = _LBAD.SendCellData(_LotId, _CellId, recipeNo, _ModelNo);
|
|
if (_BcrID.Contains(""))
|
|
{
|
|
DateTime T1 = DateTime.Now;
|
|
string s1 = T1.ToString("yyyyMMdd");
|
|
|
|
string s2 = _LotId;
|
|
string s3 = recipeNo.ToString();
|
|
string s4 = _ModelNo.ToString();
|
|
|
|
string LBADSendBcrId = _BcrID;
|
|
if (LBADSendBcrId == "" || LBADSendBcrId.Equals(null))
|
|
LBADSendBcrId = T1.ToString("HHmmss");
|
|
|
|
// 바코드가 안 읽히면 임의 값 보내기
|
|
int sendresult = _LBAD.SendCellData("LBM" + s1, LBADSendBcrId, recipeNo, _ModelNo);
|
|
Log.I(string.Format($"SendCellData result :{sendresult}"));
|
|
}
|
|
else
|
|
{
|
|
DateTime T1 = DateTime.Now;
|
|
string s1 = T1.ToString("yyyyMMdd");
|
|
|
|
string LBADSendBcrId = _BcrID;
|
|
if (LBADSendBcrId == "" || LBADSendBcrId.Equals(null))
|
|
LBADSendBcrId = T1.ToString("HHmmss");
|
|
|
|
// PLC 에 바코드 값이 있으면
|
|
int sendresult = _LBAD.SendCellData("LBM" + s1, LBADSendBcrId, recipeNo, _ModelNo);
|
|
Log.I(string.Format($"SendCellData result :{sendresult}"));
|
|
}
|
|
|
|
_WeldingStartTime = DateTime.Now;
|
|
Status.GetProcessingWeldingData().WeldStartTime = _WeldingStartTime.ToString("yyyyMMddHHmmss");
|
|
|
|
recipeRequestId = (short)_PLC.ReadDWord((int)eWordOutput.PC_RECIPE_NO, isInput:false).data;
|
|
Log.I(string.Format($"PLC recipe NO {recipeRequestId}"));
|
|
|
|
if (recipeRequestId == 21)
|
|
{
|
|
Log.I(string.Format($"TEST!! Welding : ExecuteList_{_WeldingScannerListNo}"));
|
|
}
|
|
else
|
|
{
|
|
_Scanner.ExecuteList(_WeldingScannerListNo);
|
|
Log.I(string.Format($"START Welding : ExecuteList_{_WeldingScannerListNo}"));
|
|
}
|
|
|
|
//WaitForListTaskCompleted 함수에서 List 완료 여부를 Check함, List실행이 끝나면 while문을 빠져나옴
|
|
_Scanner.WaitForListTaskCompleted(_SystemParameter.WeldLinesTaskTimeOut, context);
|
|
_WeldEndTime = DateTime.Now;
|
|
_WeldingSpanTime = DateTime.Now.Subtract(_WeldingStartTime);
|
|
Log.I(string.Format($"Welding Complete Time : {_WeldingSpanTime.TotalMilliseconds} msec"));
|
|
Status.GetProcessingWeldingData().WeldTime = _WeldingSpanTime.TotalSeconds.ToString();
|
|
|
|
double dExecuteListTime = _Scanner.GetTime();
|
|
Log.I(string.Format($"ExecuteList Time : {dExecuteListTime * 1000} msec"));
|
|
|
|
|
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_REQEUST_ACK, false);
|
|
Log.I(string.Format($"[PLCInterface]SET PC_WELD_REQEUST_ACK False"));
|
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_READY, false);
|
|
Log.I(string.Format($"[PLCInterface]SET PC_WELD_READY False"));
|
|
|
|
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingTrigger), false);
|
|
Log.I(string.Format($"[IOInterface]SET PCWeldingTrigger false"));
|
|
|
|
|
|
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), true);
|
|
Log.I(string.Format($"[IOInterface]{_PageNo} setp --> SET PCWeldingStop true"));
|
|
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
private SequenceActionResult RequestUnloadCell(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
Status.SetWorkingPosition(eWorkingPosition.UNLOADING_CELL);
|
|
|
|
// PC → PLC , Unload Cell Request
|
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE, true);
|
|
Log.I(string.Format($"[PLCInterface]SET PC_WELD_COMPLETE True"));
|
|
|
|
_InterfaceStartTime = DateTime.Now;
|
|
while (!context.Stopped)
|
|
{
|
|
if (_PLC.ReadBit((int)eBitInput.PLC_WELD_COMPLETE_ACK).data)
|
|
{
|
|
Log.I(string.Format($"[PLCInterface]GET PLC_WELD_COMPLETE_ACK True"));
|
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE, false);
|
|
Log.I(string.Format($"[PLCInterface]SET PC_WELD_COMPLETE False"));
|
|
break;
|
|
}
|
|
_InterfaceSpanTime = DateTime.Now.Subtract(_InterfaceStartTime);
|
|
if (_InterfaceSpanTime.TotalMilliseconds > (PLC_TIMEOUT * 1000))
|
|
{
|
|
Log.E("TIMEOUT_PLC_WELD_COMPLETE_ACK");
|
|
_InterfaceStartTime = DateTime.Now;
|
|
}
|
|
Thread.Sleep(10);
|
|
}
|
|
|
|
UpdateProductCount(context);
|
|
UpdateProductInfoForView();
|
|
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
private SequenceActionResult WaitLBADJudge(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
// 1. LBAD 결과 수신, 확인 & 처리
|
|
//LBAD 결과 받아오는 부분 우선 여기서 추가하여 테스트하고 Sub 시퀀스로 빼자
|
|
if (_LBAD.IsSimul)
|
|
{
|
|
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), false);
|
|
Log.I(string.Format($"[IOInterface]SET PCLBADWeldingStop false, LBAD is Simul"));
|
|
}
|
|
else
|
|
{
|
|
|
|
}
|
|
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 소수점 3제자리 까지 int 반환
|
|
/// </summary>
|
|
/// <param name="value"></param>
|
|
/// <returns>소수점 3제자리까지만 int 변환 </returns>
|
|
public static int ToIntThousand(double value)
|
|
{
|
|
decimal decValue = (decimal)value;
|
|
//return (int)Math.Round(decValue * 100m, MidpointRounding.AwayFromZero);
|
|
return (int)Math.Round(decValue * 100m);
|
|
}
|
|
|
|
public static short[] IntArrayToCatShortArray(int[] intArray)
|
|
{
|
|
short[] shortArray = new short[intArray.Length];
|
|
|
|
for (int i = 0; i < intArray.Length; i++)
|
|
{
|
|
shortArray[i] = (short)intArray[i];
|
|
}
|
|
|
|
return shortArray;
|
|
}
|
|
|
|
private SequenceActionResult ReportCellInfoToPLC(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
|
|
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
|
|
private void UpdatePLCMemoryAreaCls(int startAddress, int endAddress)
|
|
{
|
|
int start = 0;
|
|
|
|
int entcount = (endAddress - startAddress) + 1;
|
|
|
|
for (int i = 0; i < entcount; i++)
|
|
{
|
|
start = startAddress + i;
|
|
|
|
_PLC.WriteWord(start, 0);
|
|
Log.I(string.Format("[PLCInterface]SET {0:X4} -> {1:X4}", 0x2500 + start, 0));
|
|
//Log.I(string.Format("[PLCInterface]SET {0:X4} -> {1:X4}", startAddress + i, 0));
|
|
Thread.Sleep(2);
|
|
}
|
|
}
|
|
|
|
private void UpdatePLCMemoryArea(int startAddress, List<double> result_info)
|
|
{
|
|
//Log.I($"[INFO] UpdatePLCMemoryArea : {string.Join(", ", result_info)} \n Count : {result_info.Count}");
|
|
|
|
|
|
Log.I(string.Format("[PLCInterface]Start Plc Write ...... Map W{0:X4}", 0x2500 + startAddress));
|
|
|
|
List<int> resultList = new List<int>();
|
|
|
|
foreach (double info in result_info)
|
|
{
|
|
resultList.Add(ToIntThousand(info));
|
|
}
|
|
|
|
short[] resultShort = IntArrayToCatShortArray(resultList.ToArray());
|
|
//Log.I($"[PLCInterface]SET resultShort: " + string.Join(", ", resultShort));
|
|
|
|
int start = 0;
|
|
|
|
for (int i = 0; i < resultShort.Length; i++)
|
|
{
|
|
start = startAddress + i;
|
|
|
|
_PLC.WriteWord(start, resultShort[i]);
|
|
Log.I(string.Format("[PLCInterface]SET {0:X4} -> {1:X4} : {2}", 0x2500 + start, resultShort[i], resultShort[i]));
|
|
Thread.Sleep(2);
|
|
}
|
|
|
|
Log.I(string.Format("[PLCInterface]End Plc Write ...... Map W{0:X4} / Lenght {1}", 0x2500 + start, resultShort.Length));
|
|
}
|
|
|
|
private void UpdatePLCMemoryAreaRecipe(int startAddress, List<short> result_info)
|
|
{
|
|
//Log.I($"[INFO] UpdatePLCMemoryArea : {string.Join(", ", result_info)} \n Count : {result_info.Count}");
|
|
|
|
short[] info = result_info.ToArray();
|
|
|
|
Log.I(string.Format("[PLCInterface]Start Plc Write ...... Map {0:X4}", 0x2500 + startAddress));
|
|
|
|
int start = 0;
|
|
|
|
for (int i = 0; i < info.Length; i++)
|
|
{
|
|
start = startAddress + i;
|
|
_PLC.WriteWord(start, info[i]);
|
|
Log.I(string.Format("[PLCInterface]SET {0:X4} -> {1:X4} : {2}", 0x2500 + start, info[i], info[i]));
|
|
Thread.Sleep(2);
|
|
}
|
|
|
|
Log.I(string.Format("[PLCInterface]End Plc Write ...... Map {0:X4} / Lenght {1}", 0x2500 + start, info.Length));
|
|
}
|
|
|
|
public List<short> Get_Recipe_Info()
|
|
{
|
|
var mainPage = WeldingRecipeManager.GetWeldingPage();
|
|
_ScannerCanvasUserCtrl = mainPage.ScannerCanvasCtrlTeaching;
|
|
_RecipeDrawObjects = _ScannerCanvasUserCtrl.Model.Layers[0].Objects;
|
|
|
|
var activatedRecipeId = Application.Current.AuroraEnv().RecipeManager.ActivatedRecipe().Id;
|
|
|
|
var scannerObjects = new List<ScannerObjectInfo>();
|
|
|
|
for (int i = 0; i < _ScannerCanvasUserCtrl.Model.Layers.Length; i++)
|
|
{
|
|
foreach (var item in _ScannerCanvasUserCtrl.Model.Layers[i].Objects)
|
|
{
|
|
ScannerParam param = null;
|
|
|
|
if (item is Arc arc)
|
|
{
|
|
param = ScannerCanvasUserCtrl.ScannerParams[arc.ScannerParamNo];
|
|
if (param != null)
|
|
arcinfo = (new ScannerObjectInfo
|
|
{
|
|
Object = arc,
|
|
LaserPower1 = param.LaserPower1,
|
|
LaserPower2 = param.LaserPower2,
|
|
JumpSpeed = param.JumpSpeed,
|
|
MarkSpeed = param.MarkSpeed
|
|
});
|
|
}
|
|
else if (item is Line line)
|
|
{
|
|
param = ScannerCanvasUserCtrl.ScannerParams[line.ScannerParamNo];
|
|
if (param != null)
|
|
lineinfo = new ScannerObjectInfo
|
|
{
|
|
Object = line,
|
|
LaserPower1 = param.LaserPower1,
|
|
LaserPower2 = param.LaserPower2,
|
|
JumpSpeed = param.JumpSpeed,
|
|
MarkSpeed = param.MarkSpeed
|
|
};
|
|
}
|
|
else if (item is Spline spline)
|
|
{
|
|
param = ScannerCanvasUserCtrl.ScannerParams[spline.ScannerParamNo];
|
|
if (param != null)
|
|
splineinfo = new ScannerObjectInfo
|
|
{
|
|
Object = spline,
|
|
LaserPower1 = param.LaserPower1,
|
|
LaserPower2 = param.LaserPower2,
|
|
JumpSpeed = param.JumpSpeed,
|
|
MarkSpeed = param.MarkSpeed
|
|
};
|
|
}
|
|
else if (item is Dot dot)
|
|
{
|
|
param = ScannerCanvasUserCtrl.ScannerParams[dot.ScannerParamNo];
|
|
if (param != null)
|
|
dotinfo = new ScannerObjectInfo
|
|
{
|
|
Object = dot,
|
|
LaserPower1 = param.LaserPower1,
|
|
LaserPower2 = param.LaserPower2,
|
|
JumpSpeed = param.JumpSpeed,
|
|
MarkSpeed = param.MarkSpeed
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
List<short> Recipe = new List<short>();
|
|
|
|
Recipe.Add((short)lineinfo.LaserPower1);
|
|
Recipe.Add((short)lineinfo.LaserPower2);
|
|
Recipe.Add((short)lineinfo.MarkSpeed);
|
|
|
|
Recipe.Add((short)arcinfo.LaserPower1);
|
|
Recipe.Add((short)arcinfo.LaserPower2);
|
|
Recipe.Add((short)arcinfo.MarkSpeed);
|
|
|
|
Recipe.Add((short)splineinfo.LaserPower1);
|
|
Recipe.Add((short)splineinfo.LaserPower2);
|
|
Recipe.Add((short)splineinfo.MarkSpeed);
|
|
|
|
return Recipe;
|
|
}
|
|
|
|
//private void WeldingInfoSendPLC(List<short> recipe, string LBAD, string WELDING)
|
|
//{
|
|
// // PLC 영역쓰기 : 0
|
|
// if (result_info[0].Count == 24)
|
|
// {
|
|
// UpdatePLCMemoryArea((int)eWordOutput.STEP1_Arc1_LowerLimit, result_info[0]); // Ring : 24
|
|
// }
|
|
// else
|
|
// {
|
|
// Log.I($"[INFO] WeldingInfoSendPLC: Err -> {string.Join(", ", result_info[0])} \n Count : {result_info[0].Count}");
|
|
// }
|
|
|
|
// // PLC 영역쓰기 : 1
|
|
// if (result_info[1].Count == 21)
|
|
// {
|
|
// UpdatePLCMemoryArea((int)eWordOutput.STEP2_Spiral1_HorizontalLowerLimit, result_info[1]); // Spiral : 21
|
|
// }
|
|
// else
|
|
// {
|
|
// Log.I($"[INFO] WeldingInfoSendPLC: Err -> {string.Join(", ", result_info[1])} \n Count : {result_info[1].Count}");
|
|
// }
|
|
|
|
// // PLC 영역쓰기 : 2
|
|
// if (result_info[2].Count == 24)
|
|
// {
|
|
// UpdatePLCMemoryArea((int)eWordOutput.STEP3_Arc1_LowerLimit, result_info[2]); // Ring : 24
|
|
// }
|
|
// else
|
|
// {
|
|
// Log.I($"[INFO] WeldingInfoSendPLC: Err -> {string.Join(", ", result_info[2])} \n Count : {result_info[2].Count}");
|
|
// }
|
|
|
|
// // PLC 영역쓰기 : 3
|
|
// if (result_info[3].Count == 21)
|
|
// {
|
|
// UpdatePLCMemoryArea((int)eWordOutput.STEP4_Spiral1_HorizontalLowerLimit, result_info[3]); // Spiral : 21
|
|
// }
|
|
// else
|
|
// {
|
|
// Log.I($"[INFO] WeldingInfoSendPLC: Err -> {string.Join(", ", result_info[3])} \n Count : {result_info[3].Count}");
|
|
// }
|
|
|
|
// UpdatePLCMemoryAreaRecipe((int)eWordOutput.Line_LaserPower1, recipe);
|
|
|
|
// // LBAD 검사 결과 확인
|
|
// if (string.Equals(LBAD, "OK"))
|
|
// {
|
|
// _PLC.WriteWord((int)eWordOutput.LBADOK_NG, 100);
|
|
// }
|
|
// else
|
|
// {
|
|
// _PLC.WriteWord((int)eWordOutput.LBADOK_NG, 200);
|
|
// }
|
|
|
|
// // 용접후 검사 결과 확인
|
|
// if (string.Equals(WELDING, "OK"))
|
|
// {
|
|
// _PLC.WriteWord((int)eWordOutput.WeldingOK_NG, 100);
|
|
// }
|
|
// else
|
|
// {
|
|
// _PLC.WriteWord((int)eWordOutput.WeldingOK_NG, 200);
|
|
// }
|
|
//}
|
|
|
|
private void WeldingInfoSendPLC(List<short> recipe, string LBAD, string WELDING)
|
|
{
|
|
// PLC 영역쓰기 : 0
|
|
if (result_info[0].Count == 42)
|
|
{
|
|
UpdatePLCMemoryArea((int)eWordOutput.STEP1_Arc1_LowerLimit, result_info[0]); // Ring : 24 -> 36 -> 42
|
|
}
|
|
else
|
|
{
|
|
Log.I($"[INFO] WeldingInfoSendPLC: Err -> {string.Join(", ", result_info[0])} \n Count : {result_info[0].Count}");
|
|
}
|
|
|
|
// PLC 영역쓰기 : 1
|
|
if (result_info[1].Count == 21)
|
|
{
|
|
UpdatePLCMemoryArea((int)eWordOutput.STEP2_Spiral1_HorizontalLowerLimit, result_info[1]); // Spiral : 21
|
|
}
|
|
else
|
|
{
|
|
Log.I($"[INFO] WeldingInfoSendPLC: Err -> {string.Join(", ", result_info[1])} \n Count : {result_info[1].Count}");
|
|
}
|
|
|
|
// PLC 영역쓰기 : 2
|
|
if (result_info[2].Count == 42)
|
|
{
|
|
UpdatePLCMemoryArea((int)eWordOutput.STEP3_Arc1_LowerLimit, result_info[2]); // Ring : 24 -> 36 -> 42
|
|
}
|
|
else
|
|
{
|
|
Log.I($"[INFO] WeldingInfoSendPLC: Err -> {string.Join(", ", result_info[2])} \n Count : {result_info[2].Count}");
|
|
}
|
|
|
|
// PLC 영역쓰기 : 3
|
|
if (result_info[3].Count == 21)
|
|
{
|
|
UpdatePLCMemoryArea((int)eWordOutput.STEP4_Spiral1_HorizontalLowerLimit, result_info[3]); // Spiral : 21
|
|
}
|
|
else
|
|
{
|
|
Log.I($"[INFO] WeldingInfoSendPLC: Err -> {string.Join(", ", result_info[3])} \n Count : {result_info[3].Count}");
|
|
}
|
|
|
|
UpdatePLCMemoryAreaRecipe((int)eWordOutput.Line_LaserPower1, recipe);
|
|
|
|
|
|
|
|
Log.I($"Channel 0: {ResultDataList[0]}, Channel 1: {ResultDataList[1]}, Channel 2: {ResultDataList[2]}, Channel 3: {ResultDataList[3]}");
|
|
|
|
_PLC.WriteDWord((int)eWordOutput.LBAD_Total_Power_Average_H, ResultDataList[0]);
|
|
_PLC.WriteDWord((int)eWordOutput.LBAD_Total_Power_Max_H, ResultDataList[1]);
|
|
_PLC.WriteDWord((int)eWordOutput.LBAD_Total_Power_Min_H, ResultDataList[2]);
|
|
|
|
// LBAD 검사 결과 확인
|
|
if (string.Equals(LBAD, "OK"))
|
|
{
|
|
_PLC.WriteWord((int)eWordOutput.LBADOK_NG, 100);
|
|
}
|
|
else
|
|
{
|
|
_PLC.WriteWord((int)eWordOutput.LBADOK_NG, 200);
|
|
}
|
|
|
|
// 용접후 검사 결과 확인
|
|
if (string.Equals(WELDING, "OK"))
|
|
{
|
|
_PLC.WriteWord((int)eWordOutput.WeldingOK_NG, 100);
|
|
}
|
|
else
|
|
{
|
|
_PLC.WriteWord((int)eWordOutput.WeldingOK_NG, 200);
|
|
}
|
|
}
|
|
|
|
private void SaveExcelFile(Mat img, string ExcelFile)
|
|
{
|
|
//string ImgFile = string.Format("D:\\ILSOSConfig\\_vision\\Def\\1.png");
|
|
//Mat img = Cv2.ImRead(ImgFile);
|
|
//string ExcelFile = string.Format("D:\\ILSOSConfig\\_vision\\Def\\Test.xlsx");
|
|
|
|
var inserter = new ExcelImageInserter(ExcelFile);
|
|
|
|
var entry = new ExcelEntry
|
|
{
|
|
Name = "그림1",
|
|
Image = img,
|
|
ParametersSets = new List<List<string>>
|
|
{
|
|
new List<string> { "파라A", "파라B" }, // 1행
|
|
new List<string> { "뉴욕A", "뉴욕B" } // 2행
|
|
},
|
|
Content = "추가 내용"
|
|
};
|
|
|
|
inserter.AddEntry(entry, "MySheet", widthCm: 8, heightCm: 8);
|
|
|
|
inserter.Save();
|
|
}
|
|
|
|
public bool StepWELDING_Get()
|
|
{
|
|
bool WELDING = false;
|
|
|
|
List<int> _weding = new List<int>();
|
|
|
|
_weding.Add((int)result_info[0][(int)EWeldingStepRing.Ring1_BeadWidthOK_NG]);
|
|
_weding.Add((int)result_info[0][(int)EWeldingStepRing.Ring2_BeadWidthOK_NG]);
|
|
_weding.Add((int)result_info[0][(int)EWeldingStepRing.Ring3_BeadWidthOK_NG]);
|
|
_weding.Add((int)result_info[0][(int)EWeldingStepRing.Ring4_BeadWidthOK_NG]);
|
|
_weding.Add((int)result_info[0][(int)EWeldingStepRing.Ring5_BeadWidthOK_NG]);
|
|
_weding.Add((int)result_info[0][(int)EWeldingStepRing.Ring6_BeadWidthOK_NG]);
|
|
|
|
_weding.Add((int)result_info[1][(int)EWeldingStepSpiral.Spiral1_BeadWidthOK_NG]);
|
|
_weding.Add((int)result_info[1][(int)EWeldingStepSpiral.Spiral2_BeadWidthOK_NG]);
|
|
_weding.Add((int)result_info[1][(int)EWeldingStepSpiral.Spiral3_BeadWidthOK_NG]);
|
|
|
|
_weding.Add((int)result_info[2][(int)EWeldingStepRing.Ring1_BeadWidthOK_NG]);
|
|
_weding.Add((int)result_info[2][(int)EWeldingStepRing.Ring2_BeadWidthOK_NG]);
|
|
_weding.Add((int)result_info[2][(int)EWeldingStepRing.Ring3_BeadWidthOK_NG]);
|
|
_weding.Add((int)result_info[2][(int)EWeldingStepRing.Ring4_BeadWidthOK_NG]);
|
|
_weding.Add((int)result_info[2][(int)EWeldingStepRing.Ring5_BeadWidthOK_NG]);
|
|
_weding.Add((int)result_info[2][(int)EWeldingStepRing.Ring6_BeadWidthOK_NG]);
|
|
|
|
_weding.Add((int)result_info[3][(int)EWeldingStepSpiral.Spiral1_BeadWidthOK_NG]);
|
|
_weding.Add((int)result_info[3][(int)EWeldingStepSpiral.Spiral2_BeadWidthOK_NG]);
|
|
_weding.Add((int)result_info[3][(int)EWeldingStepSpiral.Spiral3_BeadWidthOK_NG]);
|
|
|
|
for (int i = 0; i < _weding.Count; i++)
|
|
{
|
|
// NG 일경우
|
|
if (_weding[i] == 2)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private void SaveFile(string Dir, List<string> res, string num)
|
|
{
|
|
string fullPath = Path.Combine(Dir, $"{DateTime.Now.ToString("HHmmss")}_{num}.txt");
|
|
|
|
string fileName = System.IO.Path.GetFileName(fullPath);
|
|
string directory = Path.GetDirectoryName(fullPath);
|
|
|
|
// 디렉토리 존재 여부 확인 후 없으면 생성
|
|
if (!Directory.Exists(directory))
|
|
{
|
|
Directory.CreateDirectory(directory);
|
|
}
|
|
|
|
// using으로 StreamWriter 사용
|
|
using (StreamWriter writer = new StreamWriter(fullPath))
|
|
{
|
|
writer.WriteLine(string.Join(", ",res));
|
|
}
|
|
|
|
Log.I(string.Format($"{num} -> {fileName}"));
|
|
}
|
|
|
|
private void SaveWImage(string Dir, Mat img, string num)
|
|
{
|
|
string fullPath = Path.Combine(Dir, $"{ DateTime.Now.ToString("HHmmss")}_{ num}.PNG");
|
|
|
|
string fileName = System.IO.Path.GetFileName(fullPath);
|
|
|
|
string dirPath = Path.GetDirectoryName(fullPath);
|
|
|
|
if (!string.IsNullOrEmpty(dirPath))
|
|
{
|
|
Directory.CreateDirectory(dirPath);
|
|
}
|
|
|
|
Cv2.ImWrite(fullPath, img);
|
|
|
|
Log.I(string.Format($"{num} -> {fileName}"));
|
|
}
|
|
|
|
//private string CheckCycleStop(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
|
|
//{
|
|
// Status.SetWorkingPosition(eWorkingPosition.CHECKING_CYCLE);
|
|
|
|
// string strLBADJudge = Status.GetProcessingWeldingData().LBAD_Judge;
|
|
// Int16 judgeFlag = 0;
|
|
// string judgeResult = "";
|
|
|
|
// DateTime timeoutTime = new DateTime();
|
|
|
|
// bool WeldingEnd = false;
|
|
|
|
// int count = 0;
|
|
|
|
// _WeldingImage[_PageNoRcc] = new Mat();
|
|
// _WeldingImage[_PageNoRcc] = _ConvMatImage_after;
|
|
// result_info[_PageNoRcc] = new List<double>();
|
|
// result_info[_PageNoRcc] = bead_result_info;
|
|
|
|
// switch (_PageNoRcc)
|
|
// {
|
|
// case 0: if (bead_result_info.Count != 24) // 변경 -> 36
|
|
// {
|
|
// Log.I($"[INFO] WeldingInfoSendPLC: Err -> {string.Join(", ", bead_result_info)} \n Count : {bead_result_info.Count}");
|
|
// }
|
|
// break;
|
|
|
|
// case 1: if (bead_result_info.Count != 21) { Log.I($"[INFO] WeldingInfoSendPLC: Err -> {string.Join(", ", bead_result_info)} \n Count : {bead_result_info.Count}"); } break;
|
|
|
|
// case 2: if (bead_result_info.Count != 24) // 변경 -> 36
|
|
// {
|
|
// Log.I($"[INFO] WeldingInfoSendPLC: Err -> {string.Join(", ", bead_result_info)} \n Count : {bead_result_info.Count}");
|
|
// }
|
|
// break;
|
|
|
|
// case 3: if (bead_result_info.Count != 21) { Log.I($"[INFO] WeldingInfoSendPLC: Err -> {string.Join(", ", bead_result_info)} \n Count : {bead_result_info.Count}"); } break;
|
|
// }
|
|
|
|
|
|
// Log.I($"[INFO] bead_result_info: {string.Join(", ", bead_result_info)} \n Count : {bead_result_info.Count}");
|
|
|
|
// while (!context.Stopped)
|
|
// {
|
|
// // 다음 페이지용 PLC 읽기
|
|
// _PageNo = GetPagePlc();
|
|
|
|
// //Log.I(string.Format($"[PLCInterface]GET PLC_SET_WELD_PAGE {0}", _PageNo));
|
|
|
|
// // PLC 에 페이지 써줘야 넘어간다.
|
|
// SetPagePlc(_PageNo);
|
|
|
|
// // 다음 시퀀스 대기..
|
|
// Thread.Sleep(100);
|
|
|
|
// if (_PLC.ReadBit((int)eBitInput.PLC_WELD_REQEUST).data)
|
|
// {
|
|
// Log.I(string.Format($"[IOInterface]Get PLC_WELD_REQEUST True"));
|
|
|
|
// _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), false);
|
|
// Log.I(string.Format($"[IOInterface]LBAD {_PageNoRcc} setp --> SET PCWeldingStop false"));
|
|
|
|
// bool[] Page = new bool[4];
|
|
// Page = new bool[4] { false, false, false, false };
|
|
// _PLC.WriteBitBlock((int)eBitOutput.PC_WELD_PAGE_CHANGE_COMPLETE_1, 4, Page);
|
|
|
|
// recipeRequestId = (short)_PLC.ReadDWord((int)eWordOutput.PC_RECIPE_NO, isInput: false).data;
|
|
// Log.I(string.Format($"PLC recipe NO {recipeRequestId}"));
|
|
|
|
// if(recipeRequestId == 21)
|
|
// {
|
|
// if (_PageNoRcc == 3)
|
|
// {
|
|
// WeldingEnd = true;
|
|
// StepLBAD = "OK";
|
|
// break;
|
|
// }
|
|
// else
|
|
// {
|
|
// Log.I(string.Format($"STEP{_PageNoRcc} / Again : CheckCycleStop -> SEQ_CHECK_PAGENO"));
|
|
// ksExit = false;
|
|
// WeldingEnd = false;
|
|
// return SEQ_CHECK_PAGENO;
|
|
// }
|
|
// }
|
|
// else
|
|
// {
|
|
// Log.I(string.Format($"STEP{_PageNoRcc} / Again : CheckCycleStop -> SEQ_CHECK_PAGENO"));
|
|
// ksExit = false;
|
|
// WeldingEnd = false;
|
|
// return SEQ_CHECK_PAGENO;
|
|
// }
|
|
|
|
|
|
// }
|
|
// else
|
|
// {
|
|
// if (_PLC.ReadBit((int)eBitInput.PLC_RESULT_REQUEST).data)
|
|
// {
|
|
// Log.I(string.Format($"[IOInterface]Get PLC_RESULT_REQUEST True"));
|
|
|
|
// WeldingEnd = true;
|
|
|
|
// _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), false);
|
|
// Log.I(string.Format($"[IOInterface]LBAD {_PageNoRcc} setp --> SET PCWeldingStop false"));
|
|
|
|
// DateTime startTime = DateTime.Now;
|
|
// TimeSpan timeoutDuration = TimeSpan.FromSeconds(5);
|
|
|
|
// while (!context.Stopped)
|
|
// {
|
|
// if (_IO._iOUnit.ReadDiBit(Convert.ToInt32(eADIAddress.LBADJudgementComplete)))
|
|
// {
|
|
// Log.I(string.Format($"[IOInterface]SET LBADJudgementComplete true"));
|
|
|
|
// int result = _LBAD.GetResult(out judgeFlag);
|
|
|
|
// List<stReceiveData> ResultList;
|
|
|
|
// int result1 = _LBAD.GetResultDataList(out ResultList);
|
|
|
|
// if (result == E1.OK)
|
|
// {
|
|
// switch (judgeFlag)
|
|
// {
|
|
// case 0:
|
|
// judgeResult = "OK";
|
|
// break;
|
|
// case 1:
|
|
// judgeResult = "WARNING";
|
|
// break;
|
|
// case 2:
|
|
// judgeResult = "NA";
|
|
// break;
|
|
// case 3:
|
|
// judgeResult = "NG";
|
|
// break;
|
|
// case 4:
|
|
// judgeResult = "ERROR";
|
|
// break;
|
|
// default:
|
|
// judgeResult = "NG";
|
|
// break;
|
|
// }
|
|
// }
|
|
// else
|
|
// {
|
|
// // TODO: LBAD 가 not Activated 인 상황이다. error 로 보내야 할꺼 같음.
|
|
// judgeFlag = 3;
|
|
// judgeResult = "NG";
|
|
// }
|
|
|
|
// // 경신 페이지 추가하여 검사 내용 추가
|
|
// //LBADResultPage[_PageNo - 1] = judgeFlag;
|
|
|
|
// Log.I(string.Format($"LBAD Judge Flag [kS] : {judgeFlag} PageResult : {judgeResult}"));
|
|
// _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADJudgementCompleteAck), true);
|
|
// Status.GetProcessingWeldingData().LBAD_Judge = (judgeFlag + 1).ToString();
|
|
// Log.I(string.Format($"[IOInterface]SET PCJudgementCompleteAck true"));
|
|
// break;
|
|
// }
|
|
|
|
|
|
// Log.I(string.Format($"---> LBAD Sleep..... {count}"));
|
|
// DateTime tto = startTime + timeoutDuration;
|
|
|
|
// if (count >= 300)
|
|
// {
|
|
// count = 0;
|
|
// Log.I(string.Format($"---> LBAD Sleep..... {count} Break !!!!"));
|
|
|
|
// judgeFlag = 3;
|
|
// judgeResult = "NG";
|
|
|
|
// break;
|
|
// }
|
|
|
|
// count++;
|
|
// Thread.Sleep(100);
|
|
// }
|
|
|
|
// _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADJudgementCompleteAck), false);
|
|
// Log.I(string.Format($"[IOInterface]SET PCJudgementCompleteAck false"));
|
|
|
|
// //return SEQ_CHECK_PAGENO;
|
|
// }
|
|
|
|
// Thread.Sleep(100);
|
|
// }
|
|
|
|
|
|
// if (WeldingEnd) { break; }
|
|
// }
|
|
|
|
|
|
// // if (_PLC.ReadBit((int)eBitInput.PLC_RESULT_REQUEST).data)
|
|
// while (!context.Stopped)
|
|
// {
|
|
// if (_PLC.ReadBit((int)eBitInput.PLC_RESULT_REQUEST).data)
|
|
// {
|
|
// try
|
|
// {
|
|
// popup.Hide();
|
|
// Thread.Sleep(100);
|
|
// }
|
|
// catch (Exception e)
|
|
// {
|
|
// Log.I(string.Format($"Popup Hide ERR !!!!"));
|
|
// }
|
|
// // 검사 결화 화면 띠운다..
|
|
// popup.Show();
|
|
// popup.UpdateImages1(_WeldingImage[0], new OpenCvSharp.Rect(1153, 1296, 7000, 8156)); //
|
|
// popup.UpdateImages2(_WeldingImage[1], new OpenCvSharp.Rect(1153, 1296, 7000, 8156)); // 6918
|
|
// popup.UpdateImages3(_WeldingImage[2], new OpenCvSharp.Rect(1153, 1296, 7000, 8156)); // 6918
|
|
// popup.UpdateImages4(_WeldingImage[3], new OpenCvSharp.Rect(1153, 1296, 7000, 8156)); // 6918
|
|
|
|
// if (result_info[0].Count == 24) popup.SetParameters1(result_info[0]);
|
|
// if (result_info[1].Count == 21) popup.SetParameters2(result_info[1]);
|
|
// if (result_info[2].Count == 24) popup.SetParameters3(result_info[2]);
|
|
// if (result_info[3].Count == 21) popup.SetParameters4(result_info[3]);
|
|
|
|
// switch (judgeFlag)
|
|
// {
|
|
// case 0:
|
|
// popup.SetStepLBAD("OK");
|
|
// StepLBAD = "OK";
|
|
// break;
|
|
|
|
// case 3:
|
|
// popup.SetStepLBAD("NG");
|
|
// StepLBAD = "NG";
|
|
// break;
|
|
|
|
// default:
|
|
// popup.SetStepLBAD("NG");
|
|
// StepLBAD = "NG";
|
|
// break;
|
|
// }
|
|
|
|
// if (StepWELDING_Get())
|
|
// {
|
|
// popup.SetStepWELDING("OK");
|
|
// StepWELDING = "OK";
|
|
// }
|
|
// else
|
|
// {
|
|
// popup.SetStepWELDING("NG");
|
|
// StepWELDING = "NG";
|
|
// }
|
|
|
|
// // 레시피 값 가져오기 : 9 + 2 -> 총 11개
|
|
// List<short> recipe = Get_Recipe_Info(); // Recipe : 9
|
|
// WeldingInfoSendPLC(recipe, StepLBAD, StepWELDING);
|
|
|
|
// if (strLBADJudge == "4" || StepWELDING.Contains("NG"))
|
|
// {
|
|
// _PLC.WriteBit((int)eBitOutput.PC_LBAD_RESULT_NG, true);
|
|
// Log.I(string.Format($"[PLCInterface]SET PC_LBAD_RESULT_NG True, LBAD Result : {strLBADJudge}"));
|
|
// }
|
|
// else if (strLBADJudge != "4")
|
|
// {
|
|
// _PLC.WriteBit((int)eBitOutput.PC_LBAD_RESULT_OK, true);
|
|
// Log.I(string.Format($"[PLCInterface]SET PC_LBAD_RESULT_OK True, LBAD Result : {strLBADJudge}"));
|
|
// }
|
|
|
|
// bool[] Page = new bool[4];
|
|
// Page = new bool[4] { false, false, false, false };
|
|
// _PLC.WriteBitBlock((int)eBitOutput.PC_WELD_PAGE_CHANGE_COMPLETE_1, 4, Page);
|
|
|
|
|
|
// string Dir = System.IO.Path.Combine(ConfigurationManager.AppSettings.Get("DATA_PATH"), "_vision", "QualityResults",
|
|
// string.Format($"{DateTime.Now.Year}_{DateTime.Now.Month}_{DateTime.Now.Day}"));
|
|
|
|
// SaveWImage(Dir, _WeldingImage[0], "Step1");
|
|
// SaveWImage(Dir, _WeldingImage[1], "Step2");
|
|
// SaveWImage(Dir, _WeldingImage[2], "Step3");
|
|
// SaveWImage(Dir, _WeldingImage[3], "Step4");
|
|
|
|
// KS_WeldingInfo weldingInfo = new KS_WeldingInfo();
|
|
// List<string> Info = weldingInfo.MakeData(result_info[0], result_info[1], result_info[2], result_info[3], recipe, "OK", "OK");
|
|
|
|
// SaveFile(Dir, Info, "result");
|
|
|
|
// //KS_WeldingInfo weldingInfo = weldingInfo.MakeData()
|
|
|
|
// Log.I(string.Format($"STEP{_PageNoRcc} / End : CheckCycleStop -> SEQ_CHECK_PAGENO"));
|
|
|
|
// ksExit = true;
|
|
|
|
// WeldingEnd = false;
|
|
|
|
// return SEQ_CHECK_PAGENO;
|
|
// }
|
|
|
|
// Log.I("---> PLC_RESULT_REQUEST W");
|
|
// Thread.Sleep(100);
|
|
// }
|
|
|
|
|
|
// return SEQ_CHECK_PAGENO;
|
|
//}
|
|
|
|
private string CheckCycleStop(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
|
|
{
|
|
Status.SetWorkingPosition(eWorkingPosition.CHECKING_CYCLE);
|
|
|
|
string strLBADJudge = Status.GetProcessingWeldingData().LBAD_Judge;
|
|
Int16 judgeFlag = 0;
|
|
string judgeResult = "";
|
|
|
|
DateTime timeoutTime = new DateTime();
|
|
|
|
bool WeldingEnd = false;
|
|
|
|
int count = 0;
|
|
|
|
_WeldingImage[_PageNoRcc] = new Mat();
|
|
_WeldingImage[_PageNoRcc] = _ConvMatImage_after;
|
|
result_info[_PageNoRcc] = new List<double>();
|
|
result_info[_PageNoRcc] = bead_result_info;
|
|
|
|
switch (_PageNoRcc)
|
|
{
|
|
case 0: if (bead_result_info.Count != 42) { Log.I($"[INFO] WeldingInfoSendPLC: Err -> {string.Join(", ", bead_result_info)} \n Count : {bead_result_info.Count}"); } break;
|
|
case 1: if (bead_result_info.Count != 21) { Log.I($"[INFO] WeldingInfoSendPLC: Err -> {string.Join(", ", bead_result_info)} \n Count : {bead_result_info.Count}"); } break;
|
|
case 2: if (bead_result_info.Count != 42) { Log.I($"[INFO] WeldingInfoSendPLC: Err -> {string.Join(", ", bead_result_info)} \n Count : {bead_result_info.Count}"); } break;
|
|
case 3: if (bead_result_info.Count != 21) { Log.I($"[INFO] WeldingInfoSendPLC: Err -> {string.Join(", ", bead_result_info)} \n Count : {bead_result_info.Count}"); } break;
|
|
}
|
|
|
|
|
|
Log.I($"[INFO] bead_result_info: {string.Join(", ", bead_result_info)} \n Count : {bead_result_info.Count}");
|
|
|
|
while (!context.Stopped)
|
|
{
|
|
// 다음 페이지용 PLC 읽기
|
|
_PageNo = GetPagePlc();
|
|
|
|
//Log.I(string.Format($"[PLCInterface]GET PLC_SET_WELD_PAGE {0}", _PageNo));
|
|
|
|
// PLC 에 페이지 써줘야 넘어간다.
|
|
SetPagePlc(_PageNo);
|
|
|
|
// 다음 시퀀스 대기..
|
|
Thread.Sleep(100);
|
|
|
|
if (_PLC.ReadBit((int)eBitInput.PLC_WELD_REQEUST).data)
|
|
{
|
|
Log.I(string.Format($"[IOInterface]Get PLC_WELD_REQEUST True"));
|
|
|
|
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), false);
|
|
Log.I(string.Format($"[IOInterface]LBAD {_PageNoRcc} setp --> SET PCWeldingStop false"));
|
|
|
|
bool[] Page = new bool[4];
|
|
Page = new bool[4] { false, false, false, false };
|
|
_PLC.WriteBitBlock((int)eBitOutput.PC_WELD_PAGE_CHANGE_COMPLETE_1, 4, Page);
|
|
|
|
recipeRequestId = (short)_PLC.ReadDWord((int)eWordOutput.PC_RECIPE_NO, isInput: false).data;
|
|
Log.I(string.Format($"PLC recipe NO {recipeRequestId}"));
|
|
|
|
if (recipeRequestId == 21)
|
|
{
|
|
if (_PageNoRcc == 3)
|
|
{
|
|
WeldingEnd = true;
|
|
StepLBAD = "OK";
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
Log.I(string.Format($"STEP{_PageNoRcc} / Again : CheckCycleStop -> SEQ_CHECK_PAGENO"));
|
|
ksExit = false;
|
|
WeldingEnd = false;
|
|
return SEQ_CHECK_PAGENO;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Log.I(string.Format($"STEP{_PageNoRcc} / Again : CheckCycleStop -> SEQ_CHECK_PAGENO"));
|
|
ksExit = false;
|
|
WeldingEnd = false;
|
|
return SEQ_CHECK_PAGENO;
|
|
}
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
if (_PLC.ReadBit((int)eBitInput.PLC_RESULT_REQUEST).data)
|
|
{
|
|
Log.I(string.Format($"[IOInterface]Get PLC_RESULT_REQUEST True"));
|
|
|
|
WeldingEnd = true;
|
|
|
|
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), false);
|
|
Log.I(string.Format($"[IOInterface]LBAD {_PageNoRcc} setp --> SET PCWeldingStop false"));
|
|
|
|
DateTime startTime = DateTime.Now;
|
|
TimeSpan timeoutDuration = TimeSpan.FromSeconds(5);
|
|
|
|
while (!context.Stopped)
|
|
{
|
|
if (_IO._iOUnit.ReadDiBit(Convert.ToInt32(eADIAddress.LBADJudgementComplete)))
|
|
{
|
|
Log.I(string.Format($"[IOInterface]SET LBADJudgementComplete true"));
|
|
|
|
//int result = _LBAD.GetResult(out judgeFlag);
|
|
|
|
//Thread.Sleep(500);
|
|
|
|
|
|
List<stReceiveData> ResultList = new List<stReceiveData>();
|
|
int result = _LBAD.GetResultDataList(out ResultList);
|
|
|
|
Thread.Sleep(20);
|
|
|
|
if (result == E1.OK)
|
|
{
|
|
Log.I($"before Clear >> Result Item Count[{ResultList.Count}]");
|
|
stReceiveData tt = ResultList.Last();
|
|
// fixed double 배열에 접근하기 위해 unsafe 블록 사용
|
|
unsafe
|
|
{
|
|
int val1 = (int)tt.arrAverage[0]; // input power
|
|
int val2 = (int)tt.arrMax[0];
|
|
int val3 = (int)tt.arrMin[0];
|
|
|
|
ResultDataList[0] = (int)tt.arrAverage[0]; // input power
|
|
ResultDataList[1] = (int)tt.arrMax[0];
|
|
ResultDataList[2] = (int)tt.arrMin[0];
|
|
|
|
//ResultDataList[0] = (int)tt.arrAverage[0]; // 첫 번째 채널
|
|
//ResultDataList[1] = (int)tt.arrAverage[1]; // 두 번째 채널
|
|
//ResultDataList[2] = (int)tt.arrAverage[2]; // 세 번째 채널
|
|
//ResultDataList[3] = (int)tt.arrAverage[3]; // 네 번째 채널
|
|
|
|
// 필요한 값을 사용하세요
|
|
Log.I($"Channel 0: {ResultDataList[0]}, Channel 1: {ResultDataList[1]}, Channel 2: {ResultDataList[2]}, Channel 3: {ResultDataList[3]}");
|
|
}
|
|
|
|
judgeFlag = tt.nResultFlag;
|
|
|
|
Log.I(string.Format($"[LBAD] stReceiveData[0] {tt.nResultFlag} "));
|
|
|
|
|
|
switch (judgeFlag)
|
|
{
|
|
case 0:
|
|
judgeResult = "OK";
|
|
break;
|
|
case 1:
|
|
judgeResult = "WARNING";
|
|
break;
|
|
case 2:
|
|
judgeResult = "NA";
|
|
break;
|
|
case 3:
|
|
judgeResult = "NG";
|
|
break;
|
|
case 4:
|
|
judgeResult = "ERROR";
|
|
break;
|
|
default:
|
|
judgeResult = "NG";
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// TODO: LBAD 가 not Activated 인 상황이다. error 로 보내야 할꺼 같음.
|
|
judgeFlag = 3;
|
|
judgeResult = "NG";
|
|
}
|
|
_LBAD.ClearResultDataList();
|
|
Log.I($"after Clear >> Result Item Count[{ResultList.Count}]");
|
|
|
|
// 경신 페이지 추가하여 검사 내용 추가
|
|
//LBADResultPage[_PageNo - 1] = judgeFlag;
|
|
|
|
Log.I(string.Format($"LBAD Judge Flag [kS] : {judgeFlag} PageResult : {judgeResult}"));
|
|
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADJudgementCompleteAck), true);
|
|
Status.GetProcessingWeldingData().LBAD_Judge = (judgeFlag + 1).ToString();
|
|
Log.I(string.Format($"[IOInterface]SET PCJudgementCompleteAck true"));
|
|
break;
|
|
}
|
|
|
|
|
|
Log.I(string.Format($"---> LBAD Sleep..... {count}"));
|
|
DateTime tto = startTime + timeoutDuration;
|
|
|
|
if (count >= 300)
|
|
{
|
|
count = 0;
|
|
Log.I(string.Format($"---> LBAD Sleep..... {count} Break !!!!"));
|
|
|
|
judgeFlag = 3;
|
|
judgeResult = "NG";
|
|
|
|
break;
|
|
}
|
|
|
|
count++;
|
|
Thread.Sleep(100);
|
|
}
|
|
|
|
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADJudgementCompleteAck), false);
|
|
Log.I(string.Format($"[IOInterface]SET PCJudgementCompleteAck false"));
|
|
|
|
//return SEQ_CHECK_PAGENO;
|
|
}
|
|
|
|
Thread.Sleep(100);
|
|
}
|
|
|
|
|
|
if (WeldingEnd) { break; }
|
|
}
|
|
|
|
|
|
// if (_PLC.ReadBit((int)eBitInput.PLC_RESULT_REQUEST).data)
|
|
while (!context.Stopped)
|
|
{
|
|
if (_PLC.ReadBit((int)eBitInput.PLC_RESULT_REQUEST).data)
|
|
{
|
|
try
|
|
{
|
|
popup.Hide();
|
|
Thread.Sleep(100);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Log.I(string.Format($"Popup Hide ERR !!!!"));
|
|
}
|
|
// 검사 결과 화면 표시
|
|
popup.Show();
|
|
popup.UpdateImages1(_WeldingImage[0], new OpenCvSharp.Rect(1153, 896, 7000, 8156)); //
|
|
popup.UpdateImages2(_WeldingImage[1], new OpenCvSharp.Rect(1153, 896, 7000, 8156)); // 6918
|
|
popup.UpdateImages3(_WeldingImage[2], new OpenCvSharp.Rect(1153, 896, 7000, 8156)); // 6918
|
|
popup.UpdateImages4(_WeldingImage[3], new OpenCvSharp.Rect(1153, 896, 7000, 8156)); // 6918
|
|
|
|
if (result_info[0].Count == 42) popup.SetParameters1(result_info[0]);
|
|
else
|
|
{
|
|
Log.I(string.Format($"Popup SetParameters1 ERR !!!!"));
|
|
}
|
|
if (result_info[1].Count == 21) popup.SetParameters2(result_info[1]);
|
|
else
|
|
{
|
|
Log.I(string.Format($"Popup SetParameters2 ERR !!!!"));
|
|
}
|
|
if (result_info[2].Count == 42) popup.SetParameters3(result_info[2]);
|
|
else
|
|
{
|
|
Log.I(string.Format($"Popup SetParameters3 ERR !!!!"));
|
|
}
|
|
if (result_info[3].Count == 21) popup.SetParameters4(result_info[3]);
|
|
else
|
|
{
|
|
Log.I(string.Format($"Popup SetParameters4 ERR !!!!"));
|
|
}
|
|
|
|
switch (judgeFlag)
|
|
{
|
|
case 0:
|
|
popup.SetStepLBAD("OK");
|
|
StepLBAD = "OK";
|
|
break;
|
|
|
|
case 3:
|
|
popup.SetStepLBAD("NG");
|
|
StepLBAD = "NG";
|
|
break;
|
|
|
|
default:
|
|
popup.SetStepLBAD("NG");
|
|
StepLBAD = "NG";
|
|
break;
|
|
}
|
|
|
|
if (StepWELDING_Get())
|
|
{
|
|
popup.SetStepWELDING("OK");
|
|
StepWELDING = "OK";
|
|
}
|
|
else
|
|
{
|
|
popup.SetStepWELDING("NG");
|
|
StepWELDING = "NG";
|
|
}
|
|
|
|
// 레시피 값 가져오기 : 9 + 2 -> 총 11개
|
|
List<short> recipe = Get_Recipe_Info(); // Recipe : 9
|
|
WeldingInfoSendPLC(recipe, StepLBAD, StepWELDING);
|
|
|
|
if (Status.GetProcessingWeldingData().LBAD_Judge == "4" || StepWELDING.Contains("NG"))
|
|
{
|
|
_PLC.WriteBit((int)eBitOutput.PC_LBAD_RESULT_NG, true);
|
|
Log.I(string.Format($"[PLCInterface]SET PC_LBAD_RESULT_NG True, LBAD Result : {Status.GetProcessingWeldingData().LBAD_Judge}"));
|
|
}
|
|
else if (Status.GetProcessingWeldingData().LBAD_Judge != "4" || recipeRequestId == 21)
|
|
{
|
|
_PLC.WriteBit((int)eBitOutput.PC_LBAD_RESULT_OK, true);
|
|
Log.I(string.Format($"[PLCInterface]SET PC_LBAD_RESULT_OK True, LBAD Result : {Status.GetProcessingWeldingData().LBAD_Judge}"));
|
|
}
|
|
|
|
bool[] Page = new bool[4];
|
|
Page = new bool[4] { false, false, false, false };
|
|
_PLC.WriteBitBlock((int)eBitOutput.PC_WELD_PAGE_CHANGE_COMPLETE_1, 4, Page);
|
|
|
|
|
|
string Dir = System.IO.Path.Combine(ConfigurationManager.AppSettings.Get("DATA_PATH"), "_vision", "QualityResults",
|
|
string.Format($"{DateTime.Now.Year}_{DateTime.Now.Month}_{DateTime.Now.Day}"));
|
|
|
|
SaveWImage(Dir, _WeldingImage[0], "Step1");
|
|
SaveWImage(Dir, _WeldingImage[1], "Step2");
|
|
SaveWImage(Dir, _WeldingImage[2], "Step3");
|
|
SaveWImage(Dir, _WeldingImage[3], "Step4");
|
|
|
|
KS_WeldingInfo weldingInfo = new KS_WeldingInfo();
|
|
List<string> Info = weldingInfo.MakeData(result_info[0], result_info[1], result_info[2], result_info[3], recipe, "OK", "OK");
|
|
|
|
SaveFile(Dir, Info, "result");
|
|
|
|
//KS_WeldingInfo weldingInfo = weldingInfo.MakeData()
|
|
|
|
Log.I(string.Format($"STEP{_PageNoRcc} / End : CheckCycleStop -> SEQ_CHECK_PAGENO"));
|
|
|
|
ksExit = true;
|
|
|
|
WeldingEnd = false;
|
|
|
|
return SEQ_CHECK_PAGENO;
|
|
}
|
|
|
|
Log.I("---> PLC_RESULT_REQUEST W");
|
|
Thread.Sleep(100);
|
|
}
|
|
|
|
|
|
return SEQ_CHECK_PAGENO;
|
|
}
|
|
|
|
private void UpdateProductCount(SequenceContext context)
|
|
{
|
|
string currentDate = DateTime.Now.ToString("yyyy-MM-dd");
|
|
if (_SystemParameter.CurrentDate != currentDate)
|
|
{
|
|
_TodayProduct = 0;
|
|
_SystemParameter.CurrentDate = currentDate;
|
|
}
|
|
else
|
|
{
|
|
_TodayProduct = _SystemParameter.TodayProductCount;
|
|
}
|
|
if (_TodayProduct < uint.MaxValue)
|
|
{
|
|
_TodayProduct++;
|
|
}
|
|
if (_TotalProduct < uint.MaxValue)
|
|
{
|
|
_TotalProduct++;
|
|
}
|
|
_SystemParameter.TodayProductCount = _TodayProduct;
|
|
_SystemParameter.TotalProductCount = _TotalProduct;
|
|
|
|
//Systemparameter Save
|
|
context.Settings.Save(CommonSettingIds.SystemParameter, _SystemParameter, "SeqAutoRunKS_New");
|
|
}
|
|
|
|
private void UpdateProductInfoForView()
|
|
{
|
|
Status.GetProcessingWeldingData().TotalProduct = _TotalProduct;
|
|
Status.GetProcessingWeldingData().TodayProduct = _TodayProduct;
|
|
|
|
Status.GetProcessingWeldingData().AutoRunStartTime = _AutoRunStartTime;
|
|
|
|
Status.GetProcessingWeldingData().WeldingStartTime = _WeldingStartTime;
|
|
Status.GetProcessingWeldingData().WeldingEndTime = _WeldEndTime;
|
|
|
|
int totalSeconds = (int)_WeldingSpanTime.TotalSeconds;
|
|
|
|
string temp = totalSeconds.ToString();
|
|
|
|
//Status.GetProcessingWeldingData().WeldingSpanTimeMilliseconds = _WeldingSpanTime.TotalMilliseconds.ToString();
|
|
Status.GetProcessingWeldingData().WeldingSpanTimeMilliseconds = totalSeconds.ToString() + " Sec";
|
|
|
|
Status.GetProcessingWeldingData().LotId = _LotId;
|
|
|
|
DateTime T1 = DateTime.Now;
|
|
string LBADSendBcrId = _BcrID;
|
|
if (LBADSendBcrId == "" || LBADSendBcrId.Equals(null))
|
|
LBADSendBcrId = T1.ToString("HHmmss");
|
|
|
|
Status.GetProcessingWeldingData().CellId = LBADSendBcrId;
|
|
}
|
|
|
|
// TODO: ImageUtil 에 있는 함수를 사용하도록 수정 필요
|
|
private void SaveScoutImage(MIL_ID imageID)
|
|
{
|
|
// 테스트를 위해서 저장한다. 테스트 끝나고 삭제할것
|
|
Log.I(string.Format($"Start to store completed field scan image"));
|
|
string fieldScanImageFile = "";
|
|
|
|
//4.스캐너 필드 이미지 파일 저장
|
|
fieldScanImageFile = System.IO.Path.Combine(ConfigurationManager.AppSettings.Get("DATA_PATH"), "_vision", "RealTimeScout",
|
|
string.Format($"{DateTime.Now.Year}_{DateTime.Now.Month}_{DateTime.Now.Day}/{DateTime.Now.ToString("HHmmss")}.PNG"));
|
|
|
|
//5.압축하여 저장
|
|
//CompressSaveImage(imageID, fieldScanImageFile, MIL.M_JPEG_LOSSY, 10);
|
|
SaveImage(imageID, fieldScanImageFile, MIL.M_PNG);
|
|
}
|
|
|
|
private bool SaveImage(MIL_ID image, string filePath, MIL_INT format)
|
|
{
|
|
string directoryName = Path.GetDirectoryName(filePath);
|
|
if (Directory.Exists(directoryName) == false)
|
|
{
|
|
Directory.CreateDirectory(directoryName);
|
|
}
|
|
|
|
MIL.MbufExport(filePath, format, image);
|
|
|
|
return true;
|
|
}
|
|
|
|
private SequenceActionResult SaveResultData(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
context.PutValue(ContextKey.KEY_SEQUENCE_RESULT, true);
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
private SequenceActionResult WriteCompletionPLCBit(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
// 완료 비트 write 하는 Node 추가 필요. format 유지, ReceiveCellInfo 없음
|
|
Log.D("AutoRun Sequence WriteCompletionPLCBit");
|
|
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
private SequenceActionResult Complete(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
RestoreDeviceStatus();
|
|
Log.I("AutoRun Complete");
|
|
|
|
context.TryGetValue(ContextKey.KEY_SEQUENCE_RESULT, out bool seqResult);
|
|
SeqAutoRunKS_New_OutParam result = new SeqAutoRunKS_New_OutParam() { Success = seqResult };
|
|
|
|
if (seqResult == false)
|
|
{
|
|
AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_AutoRun_ResultFailed);
|
|
}
|
|
|
|
Log.D("AutoRun Sequence Complete");
|
|
Status.SetWorkingPosition(eWorkingPosition.DONE);
|
|
|
|
return SequenceAction.Ok(result);
|
|
}
|
|
|
|
private bool RestoreDeviceStatus()
|
|
{
|
|
//PLC All BIT OFF
|
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_REQEUST_ACK, false);
|
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE, false);
|
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_READY, false);
|
|
_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"));
|
|
|
|
bool[] Page = new bool[4];
|
|
Page = new bool[4] { false, false, false, false };
|
|
_PLC.WriteBitBlock((int)eBitOutput.PC_WELD_PAGE_CHANGE_COMPLETE_1, 4, Page);
|
|
Log.I(string.Format("[PLCInterface]Pgae Reset"));
|
|
|
|
UpdatePLCMemoryAreaCls((int)eWordOutput.STEP1_Arc1_LowerLimit, (int)eWordOutput.WeldingOK_NG);
|
|
|
|
//LBAD IO All BIT OFF
|
|
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingTrigger), false);
|
|
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADReadyStatus), false);
|
|
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), false);
|
|
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADJudgementCompleteAck), false);
|
|
Log.I(string.Format("[IOInterface]PC All Bit Off"));
|
|
|
|
_LBAD.SetReadybyAuto(false);
|
|
|
|
#region _StreamLightLBAD
|
|
//LBAD Ready Off
|
|
////_LBAD.SetReadybyAuto(false);
|
|
//if (_StreamLightLBAD.SendReadyStatus(eRequestData.Ready_Off) == false) {
|
|
// Log.I(string.Format($"[LBAD Interface]CheckReadyStatus null"));
|
|
//}
|
|
#endregion
|
|
|
|
//Laser Off
|
|
_Laser.LaserOff();
|
|
|
|
//List 실행 종료
|
|
_Scanner.StopExecution();
|
|
|
|
//Anlog 출력 0으로 변경, efunctiontype을 command로 변경해주면 list가 아니라 직접 변경됨
|
|
_Scanner.WriteDA((uint)eAnalogPortOut.DA1, 0, eFunctionType.COMMAND);
|
|
_Scanner.WriteDA((uint)eAnalogPortOut.DA2, 0, eFunctionType.COMMAND);
|
|
|
|
//Scanner 원점 복귀
|
|
_Scanner.JumpAbs(0, 0, eFunctionType.COMMAND);
|
|
|
|
//Vision Correctiong 파일 변경
|
|
_Scanner.SelectCorrectionTable(1);
|
|
|
|
//Recipe를 기존에 Manual에서 작업하던 화면으로 rollback
|
|
WeldingRecipeManager.RollbackRecipe();
|
|
|
|
ksExit = false;
|
|
Status.GetProcessingWeldingData().ActRecipe = "";
|
|
Status.GetProcessingWeldingData().PageNO = "";
|
|
Status.GetProcessingWeldingData().BcrID = "";
|
|
|
|
return true;
|
|
}
|
|
|
|
private void OnForceError(SequenceContext arg1, string arg2)
|
|
{
|
|
OnSeqActionStop();
|
|
|
|
Log.I("SequenceAction Ok : OnForceError");
|
|
}
|
|
|
|
private void OnStopped(SequenceContext obj)
|
|
{
|
|
OnSeqActionStop();
|
|
|
|
Log.I("SequenceAction Ok : OnStopped");
|
|
}
|
|
|
|
private void OnSeqActionStop()
|
|
{
|
|
//PLC All BIT OFF
|
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_REQEUST_ACK, false);
|
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE, false);
|
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_READY, false);
|
|
_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"));
|
|
|
|
bool[] Page = new bool[4];
|
|
Page = new bool[4] { false, false, false, false };
|
|
_PLC.WriteBitBlock((int)eBitOutput.PC_WELD_PAGE_CHANGE_COMPLETE_1, 4, Page);
|
|
Log.I(string.Format("[PLCInterface]Pgae Reset"));
|
|
|
|
UpdatePLCMemoryAreaCls((int)eWordOutput.STEP1_Arc1_LowerLimit, (int)eWordOutput.WeldingOK_NG);
|
|
|
|
//LBAD IO All BIT OFF
|
|
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingTrigger), false);
|
|
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADReadyStatus), false);
|
|
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), false);
|
|
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADJudgementCompleteAck), false);
|
|
Log.I(string.Format("[IOInterface]PC All Bit Off"));
|
|
|
|
_LBAD.SetReadybyAuto(false);
|
|
|
|
#region _StreamLightLBAD
|
|
//LBAD Ready Off
|
|
////_LBAD.SetReadybyAuto(false);
|
|
//if (_StreamLightLBAD.SendReadyStatus(eRequestData.Ready_Off) == false)
|
|
//{
|
|
// Log.I(string.Format($"[LBAD Interface]CheckReadyStatus null"));
|
|
//}
|
|
#endregion
|
|
|
|
//Laser Off
|
|
_Laser.LaserOff();
|
|
|
|
//List 실행 종료
|
|
_Scanner.StopExecution();
|
|
|
|
//Anlog 출력 0으로 변경, efunctiontype을 command로 변경해주면 list가 아니라 직접 변경됨
|
|
_Scanner.WriteDA((uint)eAnalogPortOut.DA1, 0, eFunctionType.COMMAND);
|
|
_Scanner.WriteDA((uint)eAnalogPortOut.DA2, 0, eFunctionType.COMMAND);
|
|
|
|
//Scanner 원점 복귀
|
|
_Scanner.JumpAbs(0, 0, eFunctionType.COMMAND);
|
|
|
|
//Vision Correctiong 파일 변경
|
|
_Scanner.SelectCorrectionTable(1);
|
|
|
|
//Recipe를 기존에 Manual에서 작업하던 화면으로 rollback
|
|
WeldingRecipeManager.RollbackRecipe();
|
|
|
|
ksExit = false;
|
|
Status.GetProcessingWeldingData().ActRecipe = "";
|
|
Status.GetProcessingWeldingData().PageNO = "";
|
|
Status.GetProcessingWeldingData().BcrID = "";
|
|
}
|
|
|
|
}
|
|
// For CSV 저장용
|
|
public class CenterPositionData : NotifyPropertyChangedBase
|
|
{
|
|
private double _CenterX;
|
|
public double CenterX { get => _CenterX; set => SetProperty(ref _CenterX, value); }
|
|
private double _CenterY;
|
|
public double CenterY { get => _CenterY; set => SetProperty(ref _CenterY, value); }
|
|
}
|
|
|
|
public class SeqAutoRunKS_New_InitParam : InitParam
|
|
{
|
|
public ScoutSeqParams ScoutSeqParams { get; set; }
|
|
|
|
}
|
|
|
|
public class SeqAutoRunKS_New_OutParam : OutParam
|
|
{
|
|
|
|
}
|
|
|
|
public class ScannerObjectInfo
|
|
{
|
|
public object Object { get; set; } // Arc, Line, Spline, Dot
|
|
public uint LaserPower1 { get; set; }
|
|
public uint LaserPower2 { get; set; }
|
|
public double JumpSpeed { get; set; }
|
|
public double MarkSpeed { get; set; }
|
|
}
|
|
} |