2026-01-26 14:51:28 +09:00

1961 lines
89 KiB
C#

using Aurora;
using Aurora.Api;
using Aurora.Api.Manager;
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 Hermes;
using ILSOS_KS.Models;
using ILSOS_KS.RMS;
using ILSOS_KS.Views.Dialog;
using Matrox.MatroxImagingLibrary;
using MilUI;
using OpenCvSharp;
using OpenCvSharp.Dnn;
using OpenCvSharp.WpfExtensions;
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.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.Forms;
using System.Windows.Forms.VisualStyles;
using System.Windows.Media.Imaging;
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.Service.StreamLightLBAD;
using static AuroraLBAD.Services.StreamLBADClient;
using static ILSOS_KS.Device.IOController_KS;
using static ILSOS_KS.Device.PLCControllerKS;
using Application = System.Windows.Application;
using Path = System.IO.Path;
using Point = OpenCvSharp.Point;
using SystemParameter = WeldingCommon.Settings.SystemParameter;
namespace ILSOS_KS.Sequences
{
public class SeqRCCTeachingRun
{
static readonly Logger Log = new Logger("SeqRCCTeachingRun");
const string SEQ_ENTER = "[SeqRCCTeachingRun] SEQ_ENTER"; // inputParam 으로 받자.
const string SEQ_CHECK_INIT_CONDITION = "[SeqRCCTeachingRun] Check Init Condition"; // Check Init Condition
// ADD jmj -> 메인페이지 레시피 넘버 확인하여 PLC에 전송후 메칭 확인
// Page 번호 가져오기.
const string SEQ_CHECK_PAGENO = "[SeqRCCTeachingRun] CHECK PageNo";
const string SEQ_CHECK_LOAD_COMPLETE = "[SeqRCCTeachingRun] Check Load Complete";
//const string SEQ_MEASURE_CELL_POSITION = "[SeqRCCTeachingRun] Measure CellPosition";
const string SEQ_SET_SCOUT_FLYING_VISION_SEQ = "[SeqRCCTeachingRun] Set Sequence Param (ScoutFlyingVision Seq)";
const string SEQ_DO_ID_SCOUT_FLYING_VISION_SEQ = "[SeqRCCTeachingRun] Process (ScoutFlyingVision Seq)";
const string SEQ_GET_SCOUT_FLYING_VISION_SEQ = "[SeqRCCTeachingRun] 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 = "[SeqRCCTeachingRun] Event Sender";
const string SEQ_EVENT_Q_SAVE_FILE = "[SeqRCCTeachingRun] EventQ Save File";
const string SEQ_SAVE_SCOUT_IMAGE = "[SeqRCCTeachingRun] Save ScoutImage";
const string SEQ_FIND_EDGE = "[SeqRCCTeachingRun] Find Edge";
const string SEQ_DECISION_RCC_ALGORITHM_TYPE = "[SeqRCCTeachingRun] Decision RCC Algorithm Type";
const string SEQ_APPLY_OFFSET_OBJECT = "[SeqRCCTeachingRun] Apply Offset Object";
const string SEQ_GENERATE_WELDING_OBJECT = "[SeqRCCTeachingRun] Generate WeldingObject";
const string SEQ_READY_SCANNER_LIST = "[SeqRCCTeachingRun] Ready ScannerList";
const string SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ = "[SeqRCCTeachingRun] Set Sequence Param (UploadWeldingList Seq)";
const string SEQ_DO_ID_UPLOAD_WELDING_LIST_SEQ = "[SeqRCCTeachingRun] Process (UploadWeldingList Seq)";
const string SEQ_GET_RESULT_UPLOAD_WELDING_LIST_SEQ = "[SeqRCCTeachingRun] Get Sequence Result (UploadWeldingList Seq)";
const string SEQ_WAIT_WELDING_START = "[SeqRCCTeachingRun] Wait Welding Start";
const string SEQ_SET_PARAMS_RECEIVE_CELL_INFO_SEQ = "[SeqRCCTeachingRun] Set Sequence Param (ReceiveCellInfo Seq)";
const string SEQ_DO_ID_RECEIVE_CELL_INFO_SEQ = "[SeqRCCTeachingRun] Process (ReceiveCellInfo Seq)";
const string SEQ_GET_PARAMS_RECEIVE_CELL_INFO_SEQ = "[SeqRCCTeachingRun] Get Sequence Result (ReceiveCellInfo Seq)";
const string SEQ_EXECUTE_WELDING = "[SeqRCCTeachingRun] Execute Welding";
const string SEQ_REQUEST_UNLOAD_CELL = "[SeqRCCTeachingRun] Request Unload Cell";
const string SEQ_WAIT_LBAD_JUDGE = "[SeqRCCTeachingRun] Wait LBAD Judge";
//const string SEQ_SET_PARAMS_REPORT_CELL_RESULT_SEQ = "[SeqRCCTeachingRun] Set Sequence Param (ReportCellResult Seq)";
//const string SEQ_DO_ID_REPORT_CELL_RESULT_SEQ = "[SeqRCCTeachingRun] Process (ReportCellResult Seq)";
//const string SEQ_GET_RESULT_REPORT_CELL_RESULT_SEQ = "[SeqRCCTeachingRun] Get Sequence Result (ReportCellResult Seq)";
const string SEQ_REPORT_CELLINFO_TO_PLC = "[SeqRCCTeachingRun] ReportCellInfoToPLC";
const string SEQ_CHECK_CYCLE_STOP = "[SeqRCCTeachingRun] Check Cycle Stop";
const string SEQ_SAVE_RESULT_DATA = "[SeqRCCTeachingRun] Save Result Data";
const string SEQ_WRITE_COMPLETION_PLC_BIT = "[SeqRCCTeachingRun] Write Completion PLC Bit";
const string SEQ_COMPLETE = "[SeqRCCTeachingRun] SEQ_COMPLETE"; // 완료
const string SEQ_BEFORE_WELD_MOVE_OBJECT = "[SeqRCCTeachingRun] Before Weld Move Object";
const string SEQ_AFTER_WELD_CHECK_BEAD = "[SeqRCCTeachingRun] After Weld Check Bead";
const string SEQ_CHECK_RCC_MODE = "[SeqRCCTeachingRun] 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_SeqRCCTeachingRun";
public const string KEY_SEQUENCE_START_TIME = "KEY_SEQUENCE_START_TIME_SeqRCCTeachingRun";
}
const int PLC_TIMEOUT = 60; // sec, Timeout은 시퀀스 정지가 아니라 타임아웃 시간마다 로그만 남기도록 한다
private SeqRCCTeachingRun_InitParam _InitParam;
private Scanner _Scanner;
private LaserDevice _Laser;
//private OCT _OCT;
private PLCController _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 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 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)
// 경신 검수용 LBAD 검사 결과 OK,NG 반전 ..
bool isOn = false;
eScoutType _ScoutType;
public SeqRCCTeachingRun()
{
var systemParameterks = Application.Current.AuroraEnv().SettingEntry[CommonSettingIds.SystemParameter] as SystemParameter;
_ScoutType = systemParameterks.ScoutType;
}
internal SequenceBuilder Builder()
{
var sb = new SequenceBuilder(50000, 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);
// 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.AddAction(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]);
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]);
// 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("SeqDryRun.pdf");
return sb;
}
#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 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 SequenceActionResult BeforeWeldMoveObject(SequenceContext context, string id, 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 * _PageNo;
_ObjGenerator.ConvertMILToMat(ScannerFieldImage, out _ConvMatImage);
//_ConvMatImage = Cv2.ImRead("D:\\RCC\\6_KS\\2025_7_3\\before1.PNG");
_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[_PageNo].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[_PageNo].Objects[i];
_ObjGenerator = new ObjectGenerator(dPixelResolution);
if (item is Arc)
{
arc_cnt += 1;
var procPatternInfo = VisionRecipeManager.GetProcPatternInfo(_FovInfo, $"Arc{_PageNo + 1}_{arc_cnt - 6 * _PageNo}", (eProcPatternId)arc_cnt - 1);
var patternInfo = _PatternAgent.GetPatternInfo(_FovInfo, procPatternInfo.PatternId);
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;
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);
offset = new UnitPoint(found_center_pixel_mm.X - center.X, found_center_pixel_mm.Y - center.Y);
}
else
{
Log.W("Pattern is not found.");
}
//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[_PageNo].Objects[i] = objclone;
IDrawObject objclone_line = _ScannerCanvasUserCtrl.Model.Layers[0].Objects[i + 1].Clone();
objclone_line.Move(offset);///
_ScannerCanvasUserCtrl.Model.Layers[_PageNo].Objects[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 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[_PageNo].Objects.Count; i++)
{
var item = _ScannerCanvasUserCtrl.Model.Layers[_PageNo].Objects[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 = 200;
ROI_H = (int)(my_radius * 0.5 / dPixelResolution);
ROI_X = (int)(center.X / dPixelResolution) + _ConvMatImage.Width / 2 - ROI_W;
ROI_Y = -(int)(center.Y / dPixelResolution) + _ConvMatImage.Height / 2 - ROI_H / 2;
search_size = (int)(ROI_W / 10);
//double size_margin = 10000;
//(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);
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, _ConvMatImage, new OpenCvSharp.Rect((int)ROI_X, (int)ROI_Y, ROI_W, ROI_H), type, search_size);
//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, 10);
if (Math.Abs(p1.X - p2.X) > Math.Abs(p1.Y - p2.Y))
{
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);
}
else
{
Cv2.Line(_ConvMatImage_after, new Point(p1.X + 10, p1.Y), new Point(p1.X - 10, p1.Y), Scalar.LimeGreen, 10);
Cv2.Line(_ConvMatImage_after, new Point(p2.X + 10, p2.Y), new Point(p2.X - 10, p2.Y), Scalar.LimeGreen, 10);
}
// 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)} mm", new Point(ROI_X + 100, ROI_Y + 400), HersheyFonts.HersheyComplexSmall, 9, Scalar.LimeGreen, 25);
Cv2.PutText(_ConvMatImage_after, $"AVG : {Math.Round(average_bead_size * dPixelResolution / bead_size_info.Length, 3)} mm", new Point(ROI_X + 100, ROI_Y + 600), HersheyFonts.HersheyComplexSmall, 9, Scalar.LimeGreen, 25);
bead_size1 = min_bead_size * 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(0);
else
bead_result_info.Add(bead_size1);
}
else if (item is Spline)
{
bead_result_info.Add(_SystemParameter.SpiralBeadMin);
bead_result_info.Add(_SystemParameter.SpiralBeadMax);
bead_result_info.Add(_SystemParameter.SpiralBeadMin);
bead_result_info.Add(_SystemParameter.SpiralBeadMax);
center = ((Spline)item).Center;
my_radius = ((Spline)item).Radius;
type = 1;
ROI_W = (int)(my_radius * 3 / 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;
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);
//(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);
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, _ConvMatImage, 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, 10);
Cv2.Line(_ConvMatImage_after, new Point(p1.X, p1.Y + bead_size2 / 2), new Point(p1.X, p1.Y - bead_size2 / 2), Scalar.LimeGreen, 10);
Cv2.Line(_ConvMatImage_after, new Point(p1.X - bead_size1 / 2, p1.Y + 10), new Point(p1.X - bead_size1 / 2, p1.Y - 10), Scalar.LimeGreen, 10);
Cv2.Line(_ConvMatImage_after, new Point(p1.X + bead_size1 / 2, p1.Y + 10), new Point(p1.X + bead_size1 / 2, p1.Y - 10), Scalar.LimeGreen, 10);
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, 10);
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, 10);
Cv2.PutText(_ConvMatImage_after, $"W : {Math.Round(bead_size1 * dPixelResolution, 3)} mm", new Point(p1.X + bead_size1 / 2, p1.Y), HersheyFonts.HersheyComplexSmall, 10, 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);
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(bead_size1);
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(0);
else bead_result_info.Add(1);
}
}
return SequenceAction.Ok();
}
#endregion
private SequenceActionResult Sequence_Enter(SequenceContext context, string id, SequenceActionResult param)
{
Log.I("SeqDryRun Start");
Status.SetWorkingPosition(eWorkingPosition.CHECKING_CONDITION);
_InitParam = param.Param as SeqRCCTeachingRun_InitParam;
_RecipeManager = Application.Current.AuroraEnv().RecipeManager;
_SystemParameter = context.GetSetting<SystemParameter>(CommonSettingIds.SystemParameter);
InitDev(context);
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;
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);
_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();
_PLC = context.GetPLC();
_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"));
//_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"));
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 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 void GETDATA_TEST()
{
var mainPage = WeldingRecipeManager.GetWeldingPage();
_ScannerCanvasUserCtrl = mainPage.ScannerCanvasCtrlTeaching;
_RecipeDrawObjects = _ScannerCanvasUserCtrl.Model.Layers[0].Objects;
var activatedRecipeId = Application.Current.AuroraEnv().RecipeManager.ActivatedRecipe().Id;
Arc _Arc = null;
Dot _Dot = null;
Line _Line = null;
Spline _Spline = null;
foreach (var item in _ScannerCanvasUserCtrl.Model.Layers[0].Objects)
{
if (item is Arc)
{
_Arc = (Arc)item;
}
else if (item is Dot)
{
_Dot = (Dot)item;
}
else if (item is Line)
{
_Line = (Line)item;
}
else if (item is Spline)
{
_Spline = (Spline)item;
}
}
if (_Arc != null)
{
ScannerParam _ArcParam = ScannerCanvasUserCtrl.ScannerParams[_Arc.ScannerParamNo];
uint Apower1 = _ArcParam.LaserPower1;
Thread.Sleep(1000);
Thread.Sleep(1000);
}
if (_Dot != null)
{
ScannerParam _DotParam = ScannerCanvasUserCtrl.ScannerParams[_Dot.ScannerParamNo];
uint Dpower1 = _DotParam.LaserPower1;
Thread.Sleep(1000);
Thread.Sleep(1000);
}
if (_Line != null)
{
ScannerParam _LineParam = ScannerCanvasUserCtrl.ScannerParams[_Line.ScannerParamNo];
uint Lpower1 = _LineParam.LaserPower1;
Thread.Sleep(1000);
Thread.Sleep(1000);
}
if (_Spline != null)
{
ScannerParam _SplineParam = ScannerCanvasUserCtrl.ScannerParams[_Spline.ScannerParamNo];
uint spower1 = _SplineParam.LaserPower1;
Thread.Sleep(1000);
Thread.Sleep(1000);
}
}
public List<double> Init_info()
{
List<double> info = new List<double>();
//Ring #1 _ bead 폭 하한
info.Add(1.234);
//Ring #1 _ bead 폭 상한
info.Add(1.234);
//Ring #1 _ bead 폭 OK/NG 0 OK 1 Ng
info.Add(1);
//Ring #2 _ bead 폭 하한
info.Add(2.234);
//Ring #2 _ bead 폭 상한
info.Add(2.234);
//Ring #2 _ bead 폭 OK/N
info.Add(1);
//Ring #3 _ bead 폭 하한
info.Add(3.234);
//Ring #3 _ bead 폭 상한
info.Add(3.234);
//Ring #3 _ bead 폭 OK/NG
info.Add(1);
//Ring #4 _ bead 폭 하한
info.Add(4.234);
//Ring #4 _ bead 폭 상한
info.Add(4.234);
//Ring #4 _ bead 폭 OK/NG
info.Add(1);
//Ring #5 _ bead 폭 하한
info.Add(5.234);
//Ring #5 _ bead 폭 상한
info.Add(5.234);
//Ring #5 _ bead 폭 OK/NG
info.Add(1);
//Ring #6 _ bead 폭 하한
info.Add(6.234);
//Ring #6 _ bead 폭 상한
info.Add(6.234);
//Ring #6 _ bead 폭 OK/NG
info.Add(1);
//Spiral #1 _ 가로 하한
info.Add(10.234);
//Spiral #1 _ 가로 상한
info.Add(10.234);
//Spiral #1 _ 세로 하한
info.Add(10.234);
//Spiral #1 _ 세로 상한
info.Add(10.234);
//Spiral #1 _ bead 폭 OK/NG
info.Add(1);
//Spiral #2 _ 가로 하한
info.Add(20.234);
//Spiral #2 _ 가로 상한
info.Add(20.234);
//Spiral #2 _ 세로 하한
info.Add(20.234);
//Spiral #2 _ 세로 상한
info.Add(20.234);
//Spiral #2 _ bead 폭 OK/NG
info.Add(1);
//Spiral #3 _ 가로 하한
info.Add(30.234);
//Spiral #3 _ 가로 상한
info.Add(30.234);
//Spiral #3 _ 세로 하한
info.Add(30.234);
//Spiral #3 _ 세로 상한
info.Add(30.234);
//Spiral #3 _ bead 폭 OK/NG
info.Add(1);
return info;
}
public static int ToIntThousand(double value)
{
decimal decValue = (decimal)value;
return (int)Math.Round(decValue * 100m, MidpointRounding.AwayFromZero);
}
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;
}
private void UpdatePLCMemoryArea(int startAddress, List<double> result_info)
{
Log.I($"[PLCInterface]Start Plc Write ...... Map {startAddress}");
List<int> resultList = new List<int>();
foreach (double info in result_info)
{
resultList.Add(ToIntThousand(info));
}
short[] resultShort = IntArrayToShortArray(resultList.ToArray());
Log.I($"[PLCInterface]SET resultShort: " + string.Join(", ", resultShort));
int start = 0;
for (int i = 0; i < resultShort.Length / 2; i++)
{
// 2개씩 잘라서 PLC에 쓰기
short[] block = new short[2] { resultShort[i * 2], resultShort[i * 2 + 1] };
start = startAddress + i * 2;
// 시작 주소를 2씩 증가시키면서 호출
_PLC.WriteWordBlock(start, 2, block);
Log.I($"[PLCInterface]SET {start} -> {block[0]}");
Log.I($"[PLCInterface]SET {start + 1} -> {block[1]}");
Thread.Sleep(5);
}
Log.I($"[PLCInterface]End Plc Write ...... Map {start + 2}");
}
// Add jmj ->
private SequenceActionResult CheckPageNo(SequenceContext context, string id, SequenceActionResult param)
{
Log.I("SeqDryRun CheckPageNo");
// RCC 들어가기전에 1로 바꿔있어야된다...
_Scanner.SelectCorrectionTable(1);
var mainPage = WeldingRecipeManager.GetWeldingPage();
_ScannerCanvasUserCtrl = mainPage.ScannerCanvasCtrlTeaching;
string str = InputService.Instance.RequestUserInput("출력 페이지를 입력하세요", "Page Number");
bool success = int.TryParse(str, out int number);
if (success)
{
_PageNo = number-1;
Log.I(string.Format($"[PLCInterface]GET PLC_SET_WELD_PAGE {0}", _PageNo));
int count = _ScannerCanvasUserCtrl.Model.Layers.Length;
if (_PageNo < count)
{
_RecipeDrawObjects = _ScannerCanvasUserCtrl.Model.Layers[_PageNo].Objects;
_WeldingScannerListNo = eListNo.LIST1;
}else
{
return null;
}
}
else
{
List<double> initinfo = Init_info();
//UpdatePLCMemoryArea((int)eWordOutput.PC_WeldingInspection1, initinfo);
//UpdatePLCMemoryArea((int)eWordOutput.PC_WeldingInspection2, initinfo);
Thread.Sleep(1000);
return null;
}
return SequenceAction.Ok();
}
// 지그 상태 확인
private string CheckLoadComplete(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
{
Log.I("SeqDryRun CheckLoadComplete");
Status.SetWorkingPosition(eWorkingPosition.LOADING_CELL);
TimeSpan spanTime;
DateTime startTime = DateTime.Now;
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_VISION_SEQ;
return SEQ_SET_SCOUT_FLYING_VISION_SEQ;
}
// 경신 프로젝트 예외 -> CheckPageNo 에서 PLC_JIG_LOAD_COMPLETE 채크하여 로직변경
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 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($"DryRun 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 = _RecipeDrawObjects,
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)
{
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().WorkCellId;
_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);
Log.I(string.Format($"SendCellData result :{sendresult}"));
//_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"));
#region 경신 공운전 검수 용접안함.
_WeldingStartTime = DateTime.Now;
Status.GetProcessingWeldingData().WeldStartTime = _WeldingStartTime.ToString("yyyyMMddHHmmss");
_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"));
#endregion
_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]SET PCWeldingStop true"));
return SequenceAction.Ok();
}
private SequenceActionResult RequestUnloadCell(SequenceContext context, string id, SequenceActionResult param)
{
UpdateProductCount(context);
UpdateProductInfoForView();
return SequenceAction.Ok();
}
private SequenceActionResult WaitLBADJudge(SequenceContext context, string id, SequenceActionResult param)
{
string judgeResult = "";
Int16 judgeFlag = 0;
// 1. LBAD 결과 수신, 확인 & 처리
//LBAD 결과 받아오는 부분 우선 여기서 추가하여 테스트하고 Sub 시퀀스로 빼자
_LBAD.IsSimul = true;
if (_LBAD.IsSimul)
{
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), false);
Log.I(string.Format($"[IOInterface]SET PCLBADWeldingStop false, LBAD is Simul"));
}
else
{
_InterfaceStartTime = DateTime.Now;
while (!context.Stopped)
{
if (_IO._iOUnit.ReadDiBit(Convert.ToInt32(eADIAddress.LBADJudgementComplete)))
{
Log.I(string.Format($"[IOInterface]SET LBADJudgementComplete true"));
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), false);
Log.I(string.Format($"[IOInterface]SET PCWeldingStop false"));
int result = _LBAD.GetResult(out judgeFlag);
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";
}
Log.I(string.Format($"LBAD Judge Flag : {judgeFlag} Result : {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;
}
_InterfaceSpanTime = DateTime.Now.Subtract(_InterfaceStartTime);
if (_InterfaceSpanTime.TotalMilliseconds > (PLC_TIMEOUT * 1000))
{
Log.E("TIMEOUT_DI_LBADJudgementComplete_TRUE");
_InterfaceStartTime = DateTime.Now;
}
Thread.Sleep(10);
}
// 2. LBAD 처리를 IO 에서 확인
_InterfaceStartTime = DateTime.Now;
while (!context.Stopped)
{
if (!_IO._iOUnit.ReadDiBit(Convert.ToInt32(eADIAddress.LBADJudgementComplete)))
{
Log.I(string.Format($"[IOInterface]GET LBADJudgementComplete false"));
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADJudgementCompleteAck), false);
Log.I(string.Format($"[IOInterface]SET PCJudgementCompleteAck false"));
break;
}
_InterfaceSpanTime = DateTime.Now.Subtract(_InterfaceStartTime);
if (_InterfaceSpanTime.TotalMilliseconds > (PLC_TIMEOUT * 1000))
{
Log.E("TIMEOUT_DI_LBADJudgementComplete_FALSE");
_InterfaceStartTime = DateTime.Now;
}
Thread.Sleep(10);
}
}
return SequenceAction.Ok();
}
private SequenceActionResult ReportCellInfoToPLC(SequenceContext context, string id, SequenceActionResult param)
{
string strLBADJudge = Status.GetProcessingWeldingData().LBAD_Judge;
// 다음 시퀀스 대기..
return SequenceAction.Ok();
}
private static string CheckCycleStop(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
{
Status.SetWorkingPosition(eWorkingPosition.CHECKING_CYCLE);
// TODO: 확인 필요, CybleStop 에 대한 내용, cycle stop 여부 가져오기
//bCycleStop = GetCycleStopRequest();
// TODO: 한번만 돌도록 설정함, PLC 로 받으면 좋음.
//Jin : cycleStop 명령을 용접 프로그램에서 할 경우가 현재는 없음..
// CheckCycleStop 노드와 Complete 노드 사이 다른 노드가 필요하다면 해당 노드를 CheckCycleStop 노드 위로 올리자
//bool cycleStop = false;
//if (cycleStop)
//{
// return SEQ_SAVE_RESULT_DATA;
//}
//else
//{
// //return SEQ_CHECK_LOAD_COMPLETE;
//}
return SEQ_SAVE_RESULT_DATA;
}
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;
Status.GetProcessingWeldingData().WeldingSpanTimeMilliseconds = _WeldingSpanTime.TotalMilliseconds.ToString();
Status.GetProcessingWeldingData().LotId = _LotId;
DateTime T1 = DateTime.Now;
string LBADSendBcrId = _BcrID;
if (LBADSendBcrId == "" && LBADSendBcrId.Equals(null))
LBADSendBcrId = T1.ToString("HH:mm:ss");
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"));
//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);
//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();
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"));
//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);
//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();
}
}
public class SeqRCCTeachingRun_InitParam : InitParam
{
public ScoutSeqParams ScoutSeqParams { get; set; }
}
public class SeqRCCTeachingRun_OutParam : OutParam
{
}
}