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

348 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ILSOS PrismaticScanner - ACS 작업 가이드
> 작성일: 2026-04-06 | 작성자: NDY
---
## 목차
1. [현재까지 완료된 작업](#1-현재까지-완료된-작업)
2. [변수 맵 수신 후 교체할 곳](#2-변수-맵-수신-후-교체할-곳)
3. [홈/서보/알람 버튼 추가 작업](#3-홈서보알람-버튼-추가-작업)
4. [MOTF 시퀀스 흐름](#4-motf-시퀀스-흐름)
5. [캘리브레이션](#5-캘리브레이션)
6. [TODO 체크리스트](#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
```csharp
// 현재 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 축 번호 검증
```csharp
public enum eMotorIdx
{
AxisX2 = 1, // TODO: 실제 ACS 채널 번호 확인
AxisY1 = 3, // TODO: 실제 ACS 채널 번호 확인
AxisY2 = 4, // TODO: 실제 ACS 채널 번호 확인
AxisZ = 5, // TODO: 실제 ACS 채널 번호 확인
}
```
### 2-3. UCScannerMotionViewModel.cs - MoveStageX() 교체
```csharp
// 현재 (직접 모터 명령)
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 인터페이스 추가 항목
```csharp
// 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 - 추가할 코드
```csharp
// 필드 추가
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 교체
```xml
<!-- 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. 구현 예정 시퀀스 클래스 구조
```csharp
// 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 상태
```csharp
// 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 통합 컨트롤러 클래스 설계