to3796zw 2871db6e8f feat: 카메라 각도(D70510) 기반 Laser 발진 offset 분기
각도에 따라 발진 위치가 달라져, Front/Down angle 평균을 임계값으로
Front/Down offset을 자동 선택해 적용(자동·수동 발진 공통).

- LaserInterlock: Horizontal/Vertical → Front/Down angle 로 변경
- SystemParameter: CellCenterOffset X/Y → Front/Down offset X/Y (4개)
- LaserAngleOffsetSelector 헬퍼 신규 + 선택값 LOG
- PLC 미연결 시 Front offset fallback

주의: 설정 프로퍼티명 변경으로 기존 저장값 자동 이관 안 됨(재입력 필요)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 17:34:46 +09:00

47 lines
2.1 KiB
C#

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);
}
}
}