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

365 lines
18 KiB
C#

using Aurora;
using Aurora.Api;
using Aurora.Api.Manager;
using Aurora.Api.Services;
using Aurora.View;
using Aurora.View.Alarm;
using Aurora.View.AutoBackup;
using AuroraCellTracker;
using AuroraCellTracker.Views;
using AuroraIO;
using AuroraIO.View;
using AuroraLaser;
using AuroraLBAD;
using AuroraLBAD.Services;
using AuroraOCT;
using AuroraOCT.Views;
using AuroraPLC;
using AuroraPLC.Views;
using CoreUnit.Scanner.UserControl.ScannerCanvas;
using DB;
using DB.Recipe;
using GUI;
using ILSOS_PrismaticScanner.Alarm;
using ILSOS_PrismaticScanner.Device;
using ILSOS_PrismaticScanner.Device.IO;
using ILSOS_PrismaticScanner.Models;
using ILSOS_PrismaticScanner.Recipes;
using ILSOS_PrismaticScanner.Sequences;
using ILSOS_PrismaticScanner.Settings;
using ILSOS_PrismaticScanner.Views;
using System;
using System.Linq;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Threading;
using WeldingCommon;
using WeldingCommon.Alarm;
using WeldingCommon.Devices.ACS;
using WeldingCommon.Recipes;
using WeldingCommon.Sequences;
using WeldingCommon.Settings;
using WeldingCommon.Utils;
using WeldingCommon.Views;
using WeldingCommon.Views.Manual;
using WeldingCommon.Views.Recipes.History;
using WeldingCommon.Vision.Factory;
using static WeldingCommon.Vision.Factory.VisionFactory;
// 26.04.06
using AuroraACS;
using AuroraACS.Views;
using AuroraMotor;
namespace ILSOS_PrismaticScanner
{
internal class EquipmentSetup : CommonEquipmentSetup, IEquipmentSetup
{
private SequenceBuilder _SeqAutoRunPrismaticScanner_Builder;
private SequenceBuilder _SeqAutoRunComponentWeld_Builder;
private SequenceBuilder _SeqAlarmMonitor_Builder;
public override void BuildMainStatusView(MainStatusBuilder builder)
{
base.BuildMainStatusView(builder);
builder.AddDeviceActiveStatus(CommonDeviceIds.CellTracker)
.AddDeviceActiveStatus(CommonDeviceIds.OCT);
}
public override string GetEquipmentName()
{
return "ILSOS PrismaticScanner";
}
public void OnSetAlarm(int code, bool isHeavy)
{
base.OnSetAlarm(code, isHeavy);
if (isHeavy) {
AlarmManager_PrismaticScanner.StopSequenceByAlarm(code);
}
}
public override async void OnStartUp()
{
var equipSetting = AuroraEnv.SettingEntry[AuroraSettings.Equipment] as EquipmentInfo;
if (equipSetting.AutomaticallyConnectDevices) {
await ActivateDevices();
}
AuroraEx.RegisterRmsHandler<RMSHandlerForScanner>();
AuroraEnv.RecipeManager.RmsHandler().RegistryDeviceHandler(AuroraEnv);
AuroraEnv.RecipeManager.RmsHandler().Start();
// [Singleton Instance] Recipe Change History
AuroraEnv.RecipeManager.RchHandler().RegistryDeviceHandler(AuroraEnv);
//AlarmMonitroing Seq Start
AuroraEnv.SequenceEntry[SequenceIds.SeqAlarmMonitor].Start();
AuroraEnv.SequenceEntry[SequenceIds.SeqStatusMonitor].Start();
AuroraEnv.SequenceEntry[CommonSequenceIds.PLCMonitor].Start();
base.OnStartUp();
}
public override void OnShutDown()
{
// 모니터링 시퀀스 먼저 종료
AuroraEnv.SequenceEntry[SequenceIds.SeqAlarmMonitor].Stop();
AuroraEnv.SequenceEntry[SequenceIds.SeqStatusMonitor].Stop();
AuroraEnv.SequenceEntry[CommonSequenceIds.PLCMonitor].Stop();
Thread.Sleep(200);
base.OnShutDown();
}
public override void OnPostDeviceActivated(string dev)
{
base.OnPostDeviceActivated(dev);
switch (dev) {
case DeviceIds.IODevice:
var io = AuroraEnv.DeviceManager[dev] as IODevice;
io._iOUnit.WriteDoBit((int)PAIX_PrismaticScanner.ePrismaticDOAddress.AirKnifeRegulator, true);
break;
case DeviceIds.PLCDevice:
var plc = AuroraEnv.DeviceManager[dev] as PLCControllerPrismaticScanner;
plc.WriteBit(PLCControllerPrismaticScanner.eBitOutput.PC_AUTO_STATUS, false);
break;
}
}
public override void RegisterDevices(IDeviceRegistry registry)
{
base.RegisterDevices(registry);
var isSimul = ApplicationExt.IsSimulation;
//registry.Register(CommonDeviceIds.OCT, () => new OCT(CommonDeviceIds.OCT, isSimul), new OCTConfig(),
// device => new UCOCTDevice() { DataContext = new UCOCTDeviceViewModel(AuroraEnv, CommonDeviceIds.OCT) });
//registry.Register(CommonDeviceIds.LBAD, () => new LBAD(CommonDeviceIds.LBAD, isSimul), new LBADConfig());
//registry.Register(CommonDeviceIds.CellTracker, () => new CellTracker(CommonDeviceIds.CellTracker, eCellTrackerType.Daekhon, isSimul), new CellTrackerConfig(),
// device => new UCCellTrackerDevice() { DataContext = new UCCellTrackerDeviceViewModel(AuroraEnv, CommonDeviceIds.CellTracker) });
//IODevice는 AjinIO가 아니라 IOUnit으로 받아오는것으로 수정해야 함
registry.Register(CommonDeviceIds.IODevice, () => new PAIX_PrismaticScanner(AuroraEnv, CommonDeviceIds.IODevice, isSimul), new IOUnitConfig());
registry.Register(CommonDeviceIds.Laser, () => new Laser(CommonDeviceIds.Laser, isSimul), new LaserConfig(),
device => new UCLaserDevice() { DataContext = new UCLaserDeviceViewModel(AuroraEnv, CommonDeviceIds.Laser) });
var _plc = new PLCControllerPrismaticScanner(CommonDeviceIds.PLCDevice, ePLCNetType.MXComponent, ApplicationExt.IsSimulation, PLCMMapFileType.CSV, AuroraEnv);
registry.Register(CommonDeviceIds.PLCDevice,
() => _plc, PLCMxComponentConfig.GetDefaultConfig(),
device => new UCPLCDevice() { DataContext = new UCPLCDeviceViewModel(AuroraEnv, _plc) });
AlarmManager.Init(AuroraEnv);
#region Common에 있는 Device를 등록한다. 26.04.06
// ↓ ACS 등록 추가
var ACS = new ScannerACS(isSimul);
registry.Register(DeviceIds.ACS, () => ACS, new ACSDeviceConfig());
// TODO: 축 번호는 이정인 선임 변수 맵 수신 후 검증
var motorX2 = new ACSMotor(MotorIds.AxisX2, ACS, 1, (int)MotorIds.eMotorIdx.AxisX2);
registry.Register(MotorIds.AxisX2, () => motorX2,
new ACSMotorConfig(MotorIds.AxisX2),
motor => new UCACSMotor(AuroraEnv.DeviceManager, motor.DeviceId));
var motorY1 = new ACSMotor(MotorIds.AxisY1, ACS, 3, (int)MotorIds.eMotorIdx.AxisY1);
registry.Register(MotorIds.AxisY1, () => motorY1,
new ACSMotorConfig(MotorIds.AxisY1),
motor => new UCACSMotor(AuroraEnv.DeviceManager, motor.DeviceId));
var motorY2 = new ACSMotor(MotorIds.AxisY2, ACS, 4, (int)MotorIds.eMotorIdx.AxisY2);
registry.Register(MotorIds.AxisY2, () => motorY2,
new ACSMotorConfig(MotorIds.AxisY2),
motor => new UCACSMotor(AuroraEnv.DeviceManager, motor.DeviceId));
var motorZ = new ACSMotor(MotorIds.AxisZ, ACS, 5, (int)MotorIds.eMotorIdx.AxisZ);
registry.Register(MotorIds.AxisZ, () => motorZ,
new ACSMotorConfig(MotorIds.AxisZ),
motor => new UCACSMotor(AuroraEnv.DeviceManager, motor.DeviceId));
#endregion
}
public override void RegisterRecipes(RecipeRegister register)
{
register(CommonRecipeIds.ScannerObjectTeaching, new ScannerObjectTeachingRecipe(),
(id, item) => new UCScannerObjectTeaching(AuroraEnv));
base.RegisterRecipes(register);
}
public override void RegisterModels(ModelRegister register)
{
register(CommonModelIds.EquipmentSpecificModel, new EquipmentSpecificModel_PrismaticScanner(),
(id, item) => new UCModelEditor(new UCModelEditorViewModel(AuroraEnv), ModelExternalDelegate.ExternalCreateEquipmentSpecificEditor));
base.RegisterModels(register);
}
public override void RegisterSequences(SequenceRegister register)
{
// Common Sequences register
SequenceManager.RegisterSequence(AuroraEnv, register);
base.RegisterSequences(register);
var equipSetting = AuroraEnv.SettingEntry[AuroraSettings.Equipment] as EquipmentInfo;
register(SequenceIds.SeqStreamTest, SeqStreamTest.Builder());
// Event Q Test 추가
var seqEventQTest = new SeqEventQTest();
register(SequenceIds.SeqEventQTest, seqEventQTest.Builder());
var seqAutoRunPrismaticScanner = new SeqAutoRunPrismaticScanner();
var seqAutoRunComponentWeld = new SeqAutoRunComponentWeld();
var seqAlarmMonitor = new SeqAlarmMonitor();
_SeqAutoRunPrismaticScanner_Builder = seqAutoRunPrismaticScanner.Builder();
_SeqAutoRunComponentWeld_Builder = seqAutoRunComponentWeld.Builder();
_SeqAlarmMonitor_Builder = seqAlarmMonitor.Builder();
register(SequenceIds.SeqAutoRun, _SeqAutoRunPrismaticScanner_Builder);
register(SequenceIds.SeqAutoRunComponentWeld, _SeqAutoRunComponentWeld_Builder);
register(SequenceIds.SeqAlarmMonitor, _SeqAlarmMonitor_Builder);
register(SequenceIds.SeqStatusMonitor, SeqStatusMonitor.Builder());
// SequenceManager.RegisterSequence(AuroraEnv, register);
}
public override void RegisterSettings(SettingRegister register) {
base.RegisterSettings(register);
register(CommonSettingIds.UploadDatas, new SettingUploadDataListForScanner());
}
public override void RegisterServices(IServiceRegistry register)
{
//Stream 사용 시에만 등록하도록 하자
var equipSetting = AuroraEnv.SettingEntry[AuroraSettings.Equipment] as EquipmentInfo;
if (equipSetting.UseStream) {
//LBAD
register.Register(CommonServiceIds.StreamLBADClient, () => new StreamLBADClient(CommonStreamServiceNames.LBADRPC), new StreamClientConfig());
#region StreamTest
//PubSub
register.Register(CommonServiceIds.StreamPubTest, () => new StreamPub(CommonStreamServiceNames.PubSubTest), new StreamPubConfig());
register.Register(CommonServiceIds.StreamSubTest, () => new StreamSub(CommonStreamServiceNames.PubSubTest), new StreamSubConfig());
//RPC
register.Register(CommonServiceIds.StreamServerTest, () => new StreamServer(CommonStreamServiceNames.LBADRPC), new StreamServerConfig());
register.Register(CommonServiceIds.StreamClientTest, () => new StreamClient(CommonStreamServiceNames.LBADRPC), new StreamClientConfig());
//MessageBroadcasting
register.Register(CommonServiceIds.StreamBroadcastPub, () => new StreamBroadcastPub(), new StreamBroadcastPubConfig());
register.Register(CommonServiceIds.StreamBroadcastSub, () => new StreamBroadcastSub(), new StreamBroadcastSubConfig());
#endregion
}
}
// Views는 장비별로 별도로 등록하자.
public override void RegisterViews(IViewManager manager)
{
base.RegisterViews(manager);
// Auto Run
var MainAutoRun = new MainMenu(CommonViewIds.AutoRun, MenuIcon.GetMenuIcon(eMenuIcon.HOME), PermissionLevel.NONE, false);
MainAutoRun.AddSubMenu(CommonViewIds.AutoRun, new UCMainAutoRun(new UCMainAutoRunViewModel(AuroraEnv, SequenceIds.SeqAutoRun)));
manager.RegisterMainMenu(MainAutoRun);
// Recipe
MainMenu recipe = new MainMenu(CommonViewIds.Recipe, MenuIcon.GetMenuIcon(eMenuIcon.RECIPE), PermissionLevel.NONE, true);
recipe.AddSubMenu(CommonViewIds.Recipe, new UCRecipe());
recipe.AddSubMenu(CommonViewIds.RecipeChangeHistory, new UCRecipeChangeHistory() { DataContext = new UCRecipeChangeHistoryViewModel(AuroraEnv) });
recipe.AddSubMenu(CommonViewIds.ModelEditor, new UCModel());
manager.RegisterMainMenu(recipe);
AuroraEnv.EventObservable.AsObservable(CommonEventIds.EVENT_EQUIPMENT_STATUS_CHANGE)
.Select(msg => (eEqpStatus)msg.Param)
.ObserveOnDispatcher()
.Subscribe(status => {
if (status == eEqpStatus.Auto) {
AuroraEnv.ViewManager.ChangeMenu(CommonViewIds.AutoRun);
AuroraEnv.ViewManager.MainMenuEnable(false, CommonViewIds.Recipe);
RecipeHelper.OnActiveReloaded();
} else {
AuroraEnv.ViewManager.MainMenuAllEnable(true);
//RecipeHelper.RollbackRecipe();
}
//recipe.SubViews.Where(view => view.SubName == CommonViewIds.Recipe).First().View.IsEnabled = !isAuto;
});
// Manual
//var manual = new MainMenu(CommonViewIds.Manual, MenuIcon.GetMenuIcon(eMenuIcon.DEVICE), PermissionLevel.LEVEL4, true); // Level4 가 맞으나, 개발때는 None 으로 뒀다가 완료되면 풀자.
var manual = new MainMenu(CommonViewIds.Manual, MenuIcon.GetMenuIcon(eMenuIcon.CAMERA), PermissionLevel.NONE, true);
manual.AddSubMenu(CommonViewIds.ScannerOperation, new UCManualScannerOperation(new UCManualScannerOperationViewModel(AuroraEnv, CommonDeviceIds.Scanner, false)));
//manual.AddSubMenu(CommonViewIds.OCT, new UCOCTManualMotion(AuroraEnv, CommonDeviceIds.OCT));
//manual.AddSubMenu(CommonViewIds.LBAD, new UCLBADDevice(AuroraEnv, CommonDeviceIds.LBAD, CommonDeviceIds.IODevice));
//manual.AddSubMenu(CommonViewIds.ConvEdgeObject, new UCConvEdgeObject(AuroraEnv));
manual.AddSubMenu(CommonViewIds.ModelFinder, new UCManualModelFinder(new UCManualModelFinderViewModel(AuroraEnv)));
#region 26.04.06 ACS 모션 스테이지 메뉴얼 추가 - 진행 예정이였으나, Gun 에 속해서 사용 애매함. View 자체를 전부 가져오지는 못함.
#endregion
// Manual - For Test
//manual.AddSubMenu(CommonViewIds.TestDevice, new UCTestDevice(new UCTestDeviceViewModel(AuroraEnv)));
//manual.AddSubMenu(CommonViewIds.TestSequence, new UCTestSequence(new UCTestSequenceViewModel(AuroraEnv)));
manager.RegisterMainMenu(manual);
//Calibration
var calibration = new MainMenu(CommonViewIds.Calibration, MenuIcon.GetMenuIcon(eMenuIcon.SCANNER), PermissionLevel.LEVEL3, true);
calibration.AddSubMenu(CommonViewIds.Scanner, new UCScannerCalibration(new UCScannerCalibrationViewModel(AuroraEnv)));
//calibration.AddSubMenu(CommonViewIds.Power, new UCPowerCalibration(AuroraEnv)); // 불필요
//calibration.AddSubMenu(CommonViewIds.PowerCalProfile, new UCPowerProfile(AuroraEnv, CommonDeviceIds.Laser)); // 불필요
calibration.AddSubMenu(CommonViewIds.PixelResolution, new UCCameraPixelResolution(new UCCameraPixelResolutionViewModel(AuroraEnv)));
manager.RegisterMainMenu(calibration);
// Monitoring
#region 26 04 06 주석처리 PLCBitMonitoring PLCWordMonitoring IOInterfaceView (o) PLCInterfaceView (원래부터 주석처리)
//var monitoring = new MainMenu(CommonViewIds.Monitoring, MenuIcon.GetMenuIcon(eMenuIcon.MONITORING), PermissionLevel.NONE, true);
////manual.AddSubMenu(CommonViewIds.PLCInterfaceView, new UCPLCInterfaceView(AuroraEnv, CommonDeviceIds.PLCDevice));
//monitoring.AddSubMenu(CommonViewIds.PLCBitMonitoring, new UCPLCBit() { DataContext = PLCStatic.GetInstanceBitVM(AuroraEnv, CommonDeviceIds.PLCDevice, ePLCNetType.MXComponent, PLCBase.ePLCDevice.M) });
//monitoring.AddSubMenu(CommonViewIds.PLCWordMonitoring, new UCPLCWord() { DataContext = PLCStatic.GetInstanceWordVM(AuroraEnv, CommonDeviceIds.PLCDevice, ePLCNetType.MXComponent, PLCBase.ePLCDevice.D) });
//monitoring.AddSubMenu(CommonViewIds.IOInterfaceView, new UCIOInterfaceView(AuroraEnv, CommonDeviceIds.IODevice));
//manager.RegisterMainMenu(monitoring);
#endregion
// Device
var device = new MainMenu(CommonViewIds.Device, MenuIcon.GetMenuIcon(eMenuIcon.GEAR), PermissionLevel.LEVEL3, false);
device.AddSubMenu(CommonViewIds.Device, new DeviceSettingView()); // "CommonViewIds.Setting" 는 EquipDef.cs 에서 정의한 ViewId
manager.RegisterMainMenu(device);
//Setting
var setting = new MainMenu(CommonViewIds.Setting, MenuIcon.GetMenuIcon(eMenuIcon.SETTING), PermissionLevel.LEVEL1, true);
setting.AddSubMenu(CommonViewIds.Setting, new EquipSettingView());
setting.AddSubMenu(CommonViewIds.LogSetting, new LogSettingView());
setting.AddSubMenu(CommonViewIds.AutoBackupView, new AutoBackupView2() { DataContext = new AutoBackupViewModel() });
manager.RegisterMainMenu(setting);
// Alarm
MainMenu alarm = new MainMenu(CommonViewIds.Alarm, MenuIcon.GetMenuIcon(eMenuIcon.BARCODE), PermissionLevel.NONE, true)
.AddSubMenu(CommonViewIds.History, new AlarmHistoryView())
.AddSubMenu(CommonViewIds.Description, new AlarmDescView());
manager.RegisterMainMenu(alarm);
var equipSetting = AuroraEnv.SettingEntry[AuroraSettings.Equipment] as EquipmentInfo;
if (equipSetting.UseStream) {
MainMenu service = new MainMenu(CommonViewIds.StreamDevice, MenuIcon.GetMenuIcon(eMenuIcon.DEVICE))
.AddSubMenu(CommonViewIds.StreamDevice, new UCServiceSettingView());
manager.RegisterMainMenu(service);
}
// Vision (미사용)
//VisionFactory.RegisterViews(manager);
}
}
}