using Aurora.Api; using ILSOS_PrismaticRD_PTOP.Device; using ILSOS_PrismaticRD_PTOP.Settings; using static ILSOS_PrismaticRD_PTOP.Device.PLCControllerPTOP; using SystemParameter = WeldingCommon.Settings.SystemParameter; namespace ILSOS_PrismaticRD_PTOP.Sequences { // 카메라 헤드 각도(D70510)에 따라 Front/Down 발진 offset 을 선택한다. // thetaDeg = D70510 / PlcScale 가 (Front angle + Down angle)/2 보다 크면 Down, 아니면 Front. // PLC 미연결/미활성으로 각도를 못 읽으면 Front offset 적용(fallback). internal static class LaserAngleOffsetSelector { public static (double x, double y) Select( PLCControllerPTOP plc, SystemParameter sp, LaserInterlockSetting setting, Logger log, string tag) { double frontAngle = setting != null ? setting.HeadThetaFront : 0; double downAngle = setting != null ? setting.HeadThetaDown : 90; double avg = (frontAngle + downAngle) / 2.0; double scale = (setting != null && setting.HeadThetaPlcScale != 0) ? setting.HeadThetaPlcScale : 1; bool useDown = false; double thetaDeg = double.NaN; if (plc != null && plc.IsActivated) { short raw = plc.ReadWord(eWordInput.HEAD_THETA_POSITION).data; // D70510 thetaDeg = raw / scale; useDown = thetaDeg > avg; // 평균보다 높으면 Down } else { log.W($"[{tag}] 각도 offset: PLC 미연결/미활성 → Front offset 적용(fallback)"); } double selX = useDown ? sp.DownOffsetX : sp.FrontOffsetX; double selY = useDown ? sp.DownOffsetY : sp.FrontOffsetY; log.I($"[{tag}] 각도 offset 선택: D70510={thetaDeg:F1}deg, avg={avg:F1} " + $"(FrontAngle={frontAngle}, DownAngle={downAngle}) → {(useDown ? "Down" : "Front")} 적용 | " + $"FrontOffset=({sp.FrontOffsetX},{sp.FrontOffsetY}) DownOffset=({sp.DownOffsetX},{sp.DownOffsetY}) " + $"→ 적용=({selX},{selY})"); return (selX, selY); } } }