LGES-2170-ACW_CCW-Welder/Doc/ToNDH/ScannerACS_작업가이드_26.04.06.md
NohDoyeon241104 e309230949 feat: MOTF(Mark On The Fly) 구현 준비 - ACS Stage X 연동
- WeldingCommon/Devices/ACS/ ScannerACS 독립 구현 (Gun 참조 제거)
- Scanner EquipmentSetup.RegisterDevices()에 ScannerACS + 모터 등록
- EquipDef.cs MotorIds 추가
- UCScannerMotionViewModel Stage X 조그 필드/커맨드/모니터링 추가
- UCScannerMotion.xaml Stage X Motion 섹션 추가
- SeqComponentTeachingRun MOTF 자리 확보
  (_ACS 필드 선언, InitDev() 취득, MOTFStart/CheckMOTFComp 주석 준비)
- AuroraEx Device 네임스페이스 충돌 수정

TODO: 이정인 선임 ACS 변수 맵 수신 후
  - ScannerACS.Parameter.cs 변수명/버퍼 번호 교체
  - MOTFStart() / CheckMOTFComp() 주석 해제
  - 축 번호 검증
2026-04-06 14:51:27 +09:00

11 KiB
Raw Blame History

ILSOS PrismaticScanner - ACS 작업 가이드

작성일: 2026-04-06 | 작성자: NDY


목차

  1. 현재까지 완료된 작업
  2. 변수 맵 수신 후 교체할 곳
  3. 홈/서보/알람 버튼 추가 작업
  4. MOTF 시퀀스 흐름
  5. 캘리브레이션
  6. TODO 체크리스트

1. 현재까지 완료된 작업

1-1. 프로젝트 구조

WeldingCommon
    └── Devices/ACS/
            ├── ScannerACS.cs           ← Gun과 독립된 Scanner 전용 ACS
            ├── ScannerACS.Parameter.cs ← ACS 변수명 상수 (TODO: 변수 맵 교체 필요)
            └── MotionVariable.cs       ← 모터 상태값

ILSOS_PrismaticScanner
    └── EquipmentSetup.RegisterDevices()
            ├── ScannerACS 등록
            ├── MotorX2 등록 (Stage X)
            ├── MotorY1, Y2, Z 등록 (TODO: 축 번호 검증 필요)
            └── EquipDef.cs에 MotorIds 추가

1-2. WeldingCommon - UCScannerMotionViewModel.cs 수정 완료

  • _MotorX (ACSMotor) 필드 추가 및 연결
  • StageXPos, IsStageXActivated 프로퍼티 추가
  • CMD_JogMove에 Stage_X_Left, Stage_X_Right 케이스 추가
  • MoveStageX() 메서드 추가 (현재: 직접 모터 명령 방식)
  • OnMonitoring()에 Stage X 위치 갱신 추가

1-3. WeldingCommon - UCScannerMotion.xaml 수정 완료

  • Stage X Motion (ACS) GroupBox 추가 (Grid.Row="2")
  • Stage X[mm] 위치 표시
  • ◀ − / + ▶ 조그 버튼

2. 변수 맵 수신 후 교체할 곳

2-1. ScannerACS.Parameter.cs

// 현재 placeholder → 실제 변수명으로 교체
const string iMOTFStart    = "iPCset_SCANNER_MOTF_START";   // TODO
const string iMOTFComplete = "iPCget_SCANNER_MOTF_COMP";    // TODO
const string rMOTFVelocity = "rPCset_SCANNER_MOTF_VEL";     // TODO
const string rMOTFAcc      = "rPCset_SCANNER_MOTF_ACC";     // TODO
const string iAllAxisHomeComplete = "iPCget_ALLAXIS_HOMECOMP"; // TODO
const string AlarmReset    = "iAlarmreset";                  // TODO
const string HeavyAlarm    = "iAlarm";                       // TODO
const string LightAlarm    = "iLightAlarm";                  // TODO

private enum eBuffer
{
    All_Axis_Home = 0,   // TODO: 실제 버퍼 번호로 교체
    MOTF_Start    = 11,  // TODO: 실제 버퍼 번호로 교체
}

2-2. EquipDef.cs - MotorIds 축 번호 검증

public enum eMotorIdx
{
    AxisX2 = 1,  // TODO: 실제 ACS 채널 번호 확인
    AxisY1 = 3,  // TODO: 실제 ACS 채널 번호 확인
    AxisY2 = 4,  // TODO: 실제 ACS 채널 번호 확인
    AxisZ  = 5,  // TODO: 실제 ACS 채널 번호 확인
}

2-3. UCScannerMotionViewModel.cs - MoveStageX() 교체

// 현재 (직접 모터 명령)
private void MoveStageX(eJogDirection direction)
{
    if (_MotorX == null || !_MotorX.IsActivated) return;
    double step = direction == eJogDirection.PLUS ? -StepValue : +StepValue;
    _MotorX.SetTargetPos(step, TargetPosType.REL);
    _MotorX.Move();
}

// TODO: 변수 맵 수신 후 ACS 버퍼 방식으로 교체
// private void MoveStageX(eJogDirection direction)
// {
//     double velocity = GetStageXVelocity(); // Setting에서 가져오기
//     double acc      = GetStageXAcc();
//     _acs?.StageXJogStart(velocity, acc);
// }

3. 홈/서보/알람 버튼 추가 작업

3-1. IScannerACS 인터페이스 추가 항목

// WeldingCommon/Devices/ACS/ScannerACS.cs
public interface IScannerACS
{
    bool IsActivated();

    // 홈
    bool AllAxisHomeStart();
    bool AllAxisHomeStop();
    bool CheckAllAxisHome();

    // Stage X 조그 (ACS 버퍼 방식) - TODO: 변수 맵 수신 후 구현
    bool StageXJogStart(double velocity, double acc);
    bool StageXJogStop();

    // MOTF
    bool MOTFStart();
    bool MOTFStop();
    bool CheckMOTFComp();

    // 레이저
    bool SetLaserIOUse(bool on);
    bool IsLaserOn();

    // 알람
    bool ResetAlarm();
    void AllAxisServoOff();
}

3-2. UCScannerMotionViewModel.cs - 추가할 코드

// 필드 추가
private ScannerACS _acs;

// 커맨드 추가
public ICommand CMD_HomeStart  { get; }
public ICommand CMD_HomeStop   { get; }
public ICommand CMD_AlarmReset { get; }
public ICommand CMD_ServoOff   { get; }

// 생성자에서 추가
try { _acs = _Aurora.DeviceManager["ACS"] as ScannerACS; }
catch { _acs = null; }

CMD_HomeStart  = new DelegateCommand(_ => _acs?.AllAxisHomeStart());
CMD_HomeStop   = new DelegateCommand(_ => _acs?.AllAxisHomeStop());
CMD_AlarmReset = new DelegateCommand(_ => _acs?.ResetAlarm());
CMD_ServoOff   = new DelegateCommand(_ => _acs?.AllAxisServoOff());

3-3. UCScannerMotion.xaml - Stage X GroupBox 교체

<!-- 26.04.06 NDY Stage X Motion 섹션 -->
<GroupBox Grid.Row="2" Header="Stage X Motion (ACS)" Margin="0 3 3 0"
          IsEnabled="{Binding IsStageXActivated}">
    <Grid Margin="5">
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="auto"/>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="1*"/>
        </Grid.ColumnDefinitions>

        <!-- Row 0: 위치 표시 + 조그 버튼 -->
        <GroupBox Grid.Row="0" Grid.Column="0" Header="Stage X[mm]"
                  Style="{StaticResource StGBMonitor}" Margin="0 0 5 0" MinWidth="120">
            <TextBlock FontSize="18" FontWeight="Bold"
                       HorizontalAlignment="Center" VerticalAlignment="Center"
                       Text="{Binding StageXPos, StringFormat={}{0:0.000}}"/>
        </GroupBox>
        <Button Grid.Row="0" Grid.Column="1" FontWeight="Bold" Margin="3"
                Command="{Binding CMD_JogMove}"
                CommandParameter="Stage_X_Left">◀ −</Button>
        <Button Grid.Row="0" Grid.Column="2" FontWeight="Bold" Margin="3"
                Command="{Binding CMD_JogMove}"
                CommandParameter="Stage_X_Right">+ ▶</Button>
        <TextBlock Grid.Row="0" Grid.Column="3" FontSize="10" Foreground="Gray"
                   VerticalAlignment="Center" HorizontalAlignment="Center"
                   Text="* 이미지 방향 반전 적용"/>

        <!-- Row 1: 홈/서보/알람 버튼 (TODO: 변수 맵 수신 후 활성화) -->
        <UniformGrid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="4"
                     Rows="1" Margin="3">
            <Button Margin="3" Content="Home Start"
                    Command="{Binding CMD_HomeStart}"
                    Style="{StaticResource StButtonAccentBlue}"/>
            <Button Margin="3" Content="Home Stop"
                    Command="{Binding CMD_HomeStop}"
                    Background="DarkSlateGray"/>
            <Button Margin="3" Content="Servo Off"
                    Command="{Binding CMD_ServoOff}"
                    Background="DarkOrange"/>
            <Button Margin="3" Content="Alarm Reset"
                    Command="{Binding CMD_AlarmReset}"
                    Background="DarkRed"/>
        </UniformGrid>
    </Grid>
</GroupBox>

4. MOTF 시퀀스 흐름

4-1. 개념

MOTF (Mark On The Fly)
= Stage X가 이동하는 동안 갈바노 스캐너가 레이저 마킹

트리거: Stage X 엔코더 위치 기반
        → 특정 위치 도달 시 갈바노가 마킹 시작

4-2. 시퀀스 흐름 (사수 피드백 기준)

[Step 1] Scanner List 채우기
    LASA 레시피 기반으로 마킹 좌표 목록 생성
    → ScannerList에 마킹할 X, Y 좌표 순서대로 입력

[Step 2] ACS에 파라미터 전송
    → 시작 위치, 속도, 가속도 설정
    → 레이저 ON/OFF 위치 설정
    → MOTF 트리거 조건 설정

[Step 3] ACS MOTF 시작
    → RunBuffer(eBuffer.MOTF_Start)
    → Stage X 이동 시작
    → 엔코더 트리거로 갈바노 동기화

[Step 4] 완료 확인
    → ReadVariableInt(iMOTFComplete) > 0

4-3. 참조할 기존 소스

CCW 웰더 프로젝트
    └── SeqAutoRunCCWH52A.cs  ← MOTF 시퀀스 구현 참조

4-4. 구현 예정 시퀀스 클래스 구조

// ILSOS_PrismaticScanner/Sequences/SeqAutoRunPrismaticScanner.cs
public class SeqAutoRunPrismaticScanner : ISequence
{
    private ScannerACS _acs;
    private Scanner _scanner;

    protected override void DoProcess()
    {
        // Step 1. Scanner List 채우기 (LASA 레시피 기반)
        FillScannerList();

        // Step 2. ACS 파라미터 전송
        SetMOTFParameters();

        // Step 3. MOTF 시작
        _acs.MOTFStart();

        // Step 4. 완료 대기
        WaitForComplete();
    }

    private void FillScannerList()
    {
        // TODO: LASA 레시피에서 마킹 좌표 가져오기
        // var recipe = ... (MainRecipe)
        // scanner.SetMarkList(recipe.MarkPoints);
    }

    private void SetMOTFParameters()
    {
        // TODO: 변수 맵 수신 후 실제 변수명으로 구현
        // _acs.SetMOTFVelocity(velocity);
        // _acs.SetMOTFAcc(acc);
        // _acs.SetLaserOnOffPosition(onPos, offPos);
    }

    private void WaitForComplete()
    {
        // TODO: Timeout 처리 포함
        // while (!_acs.CheckMOTFComp()) { Thread.Sleep(10); }
    }
}

4-5. MOTF 좌표 오류 주의사항

주의: MOTF 트리거는 Stage X 엔코더만 기준
      → 헤드 유닛 Y축 이동은 미반영
      → R-section(라운드 코너)에서 위치 오차 발생 가능

원인:
  Stage X + 갈바노 X + 갈바노 Y 조합으로 실제 마킹 위치 결정
  → Stage X 엔코더 트리거만으로는 Y 성분 누락

해결: 이정인 선임과 R-section 처리 방법 협의 필요

5. 캘리브레이션

5-1. 방향

기존 소스와 동일하게 진행 (사수 피드백)
→ WeldingCommon의 LaserPowerCalParam 그대로 사용
→ ScannerACS.DoActivate()에서 이미 참조 구조 잡혀있음

5-2. 현재 ScannerACS.cs 상태

// DoActivate()에서 캘리브레이션 참조 준비됨
// TODO: Scanner용 SettingIds 확정 후 연결
// _calibration = env.SettingEntry[CommonSettingIds.LaserPowerCalParam]
//                as LaserPowerCalParam;

6. TODO 체크리스트

이정인 선임 변수 맵 수신 전

  • 홈/서보/알람 버튼 XAML 추가
  • UCScannerMotionViewModel에 CMD_HomeStart 등 커맨드 추가
  • SeqAutoRunPrismaticScanner 클래스 골격 작성

이정인 선임 변수 맵 수신 후

  • ScannerACS.Parameter.cs 변수명 교체
  • eBuffer 번호 교체
  • MotorIds.eMotorIdx 축 번호 검증
  • MoveStageX() → ACS 버퍼 방식으로 교체
  • MOTF 파라미터 전송 구현
  • 실제 장비에서 동작 확인

장기 과제

  • R-section 위치 오차 처리 방법 협의
  • 캘리브레이션 연결
  • Scanner + ACS 통합 컨트롤러 클래스 설계