Files
ENIG/Cs_HMI/Project/StateMachine/Step/_SM_RUN.cs
backuppc 5801137d63 ..
2026-01-12 17:37:37 +09:00

352 lines
15 KiB
C#

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using Project.StateMachine;
using COMM;
using AR;
namespace Project
{
public partial class fMain
{
DateTime LastSpeakTime = DateTime.Now;
DateTime CoverControlTime = DateTime.Now;
DateTime LastCommandTime = DateTime.Now;
DateTime LastCommandTimeNextStop = DateTime.Now;
bool runStepisFirst = false;
private void _SM_RUN(Boolean isFirst, TimeSpan stepTime)
{
//HW 연결오류
if (PUB.AGV.IsOpen == false)
{
PUB.Result.SetResultMessage(eResult.Hardware, eECode.AGVCONN, eNextStep.ERROR);
PUB.sm.SetNewStep(eSMStep.IDLE);
return;
}
//가동불가 조건 확인
if (CheckStopCondition() == false) return;
//중단기능이 동작이라면 처리하지 않는다.
if (PUB.sm.bPause)
{
System.Threading.Thread.Sleep(200);
return;
}
//스텝이 변경되었다면?
if (PUB.sm.RunStep != PUB.sm.RunStepNew)
{
runStepisFirst = true;
PUB.sm.ApplyRunStep();
}
else runStepisFirst = false;
//처음시작이라면 시작시간을 설정한다
if (isFirst)
{
if (PUB.sm.RunStep == ERunStep.READY)
VAR.TIME.Update(eVarTime.ReadyStart);
else
VAR.TIME.Update(eVarTime.RunStart);
VAR.I32[eVarInt32.PathValidationError] = 0;
}
//자동모드에서 대기상태 (추가동작없음)
if (PUB.sm.RunStep == ERunStep.READY)
{
_SM_RUN_READY(runStepisFirst, PUB.sm.GetRunSteptime);
return;
}
//#############################################
//## 이 후에는 모든 동작루틴이 온다
//#############################################
//라이더 센서에서 멈춘경우 처리
if (PUB.AGV.system1.stop_by_front_detect == true)
{
var tsSpeak = DateTime.Now - LastSpeakTime;
if (tsSpeak.TotalSeconds >= PUB.setting.alarmSoundTerm)
{
PUB.Speak(Lang.);
LastSpeakTime = DateTime.Now;
}
return;
}
//선로이탈감지
if (PUB.AGV.error.runerror_by_no_magent_line == true)
{
var tsSpeak = DateTime.Now - LastSpeakTime;
if (tsSpeak.TotalSeconds >= PUB.setting.alarmSoundTerm)
{
PUB.Speak(Lang.);
LastSpeakTime = DateTime.Now;
}
return;
}
//현재위치를 모르는 상태라면 이동하여 현재 위치를 찾는다
if (_SM_RUN_POSCHK(isFirst, stepTime) == false)
{
PUB.Result.result_message = "현재 위치 확인 중";
PUB.Result.result_progressmax = 0;
return;
}
//나머지 상황체크
switch (PUB.sm.RunStep)
{
case ERunStep.GOHOME:
if (_SM_RUN_GOHOME(runStepisFirst, PUB.sm.GetRunSteptime) == true)
{
PUB.log.Add($"홈 이동이 완료되어 준비상태로 전환합니다");
PUB.sm.SetNewRunStep(ERunStep.READY);
}
break;
case ERunStep.GOTO: //목적지까지 이동하는 경우
if (_SM_RUN_GOTO(runStepisFirst, PUB.sm.GetRunSteptime) == true)
{
//목적지가 BUFFER라면 버퍼투입대기위치까지 완료했다는 시그널을 보낸다.
var target = PUB._virtualAGV.TargetNode;
PUB.log.Add($"목적지({target.RfidId}) 도착완료 타입:{target.Type}, 출발지:{PUB._virtualAGV.StartNode.RfidId}");
PUB.XBE.StepLoader = Device.eDocStep.NotSet;
PUB.XBE.StepCleaner = Device.eDocStep.NotSet;
PUB.XBE.StepUnloader = Device.eDocStep.NotSet;
PUB.XBE.StepBuffer = Device.eDocStep.NotSet;
switch (target.StationType)
{
case AGVNavigationCore.Models.StationType.Buffer:
var lastPath = PUB._virtualAGV.CurrentPath.DetailedPath.LastOrDefault();
if (lastPath.NodeId.Equals(PUB._virtualAGV.CurrentNode.Id))
{
//버퍼진입전 노드에 도착완료했따
PUB.XBE.StepBuffer = Device.eDocStep.InReady;
}
else
{
//마지막위치가 아닌 다른 위치에 있으니 버퍼 작업을 할 수없다
PUB.XBE.StepBuffer = Device.eDocStep.NotSet;
PUB.log.AddE($"목적지가 버퍼이나 노드가 불일치 한다 오류사항");
PUB._mapCanvas.SetAlertMessage("목적지가 버퍼이나 노드 불일치 오류");
PUB.sm.SetNewRunStep(ERunStep.ERROR);
}
break;
case AGVNavigationCore.Models.StationType.Charger1:
case AGVNavigationCore.Models.StationType.Charger2:
break;
case AGVNavigationCore.Models.StationType.Loader:
PUB.XBE.StepLoader = Device.eDocStep.InReady;
break;
case AGVNavigationCore.Models.StationType.Clearner:
PUB.XBE.StepCleaner = Device.eDocStep.InReady;
break;
case AGVNavigationCore.Models.StationType.UnLoader:
PUB.XBE.StepUnloader = Device.eDocStep.InReady;
break;
default:
PUB.log.Add($"정의되지 않은 스테이션 입니다({target.StationType}) ");
break;
}
PUB._virtualAGV.Turn = AGVNavigationCore.Models.AGVTurn.None;
PUB.sm.SetNewRunStep(ERunStep.READY);
}
break;
case ERunStep.MARKSTOPB: //후진방향으로 마크스탑
case ERunStep.MARKSTOPF: //전진방향으로 마크스탑
//이동중이지 않다면 먼저 이동을 진행한다
var agvDir = PUB.sm.RunStep == ERunStep.MARKSTOPF ? arDev.Narumi.eRunOpt.Forward : arDev.Narumi.eRunOpt.Backward;
PUB.AGV.AGVMoveRun(agvDir);
//이동중이라면 마크스탑을 입력한다
PUB.AGV.AGVMoveStop("run-markstropb", arDev.Narumi.eStopOpt.MarkStop);
//마크스탑신호를 확인한다.(최대 5초)
//신호가 확인되지 않으면 오류로 정지한다
break;
case ERunStep.GOCHARGE: //충전위치로 이동
if (runStepisFirst)
{
VAR.TIME[eVarTime.ChargeTry] = DateTime.Now;
PUB.sm.ResetRunStepSeq();
PUB.log.Add("충전 명령 시작");
}
else if (_SM_RUN_GOCHARGE(runStepisFirst, PUB.sm.GetRunSteptime))
{
PUB.Speak(Lang.);
PUB.sm.SetNewRunStep(ERunStep.CHARGECHECK);
return;
}
break;
case ERunStep.CHARGECHECK: //충전중
if (runStepisFirst)
{
VAR.TIME.Update(eVarTime.ChargeStart);
LastCommandTime = DateTime.Now;
}
else if (_SM_RUN_GOCHARGECHECK(runStepisFirst, PUB.sm.GetRunSteptime))
{
//충전상태가 활성화되었으므로 대기상태로 전환한다
PUB.sm.SetNewRunStep(ERunStep.READY);
PUB.log.AddAT("충전상태 확인 완료로 인해 대기 합니다");
}
break;
case ERunStep.CHARGEOFF:
if (runStepisFirst)
{
VAR.TIME.Update(eVarTime.ChargeEnd);
LastCommandTime = DateTime.Now;
}
else
{
//충전 상태가 OFF되어야 동작하게한다
if (_SM_RUN_CHGOFF(isFirst, stepTime) == true)
{
//충전상태가 활성화되었으므로 대기상태로 전환한다
PUB.sm.ClearRunStep();
//대기상태로 전환
PUB.sm.SetNewRunStep(ERunStep.READY);
PUB.log.AddAT("충전 해제로 대기상태로 전환 합니다");
}
}
break;
case ERunStep.LOADER_OUT: //로더아웃
if (_SM_RUN_LOADER_OUT(runStepisFirst, PUB.sm.GetRunSteptime))
{
PUB.Speak(Lang.);
//도킹완료상태를 업데이트한다.
PUB.XBE.StepLoader = Device.eDocStep.OutComplete;
//대기상태로 전환
PUB.sm.SetNewRunStep(ERunStep.READY);
return;
}
break;
case ERunStep.LOADER_IN: //로더도킹
if (_SM_RUN_LOADER_IN(runStepisFirst, PUB.sm.GetRunSteptime))
{
PUB.Speak(Lang.);
//도킹완료상태를 업데이트한다.
PUB.XBE.StepLoader = Device.eDocStep.InComplete;
//대기상태로 전환
PUB.sm.SetNewRunStep(ERunStep.READY);
return;
}
break;
case ERunStep.UNLOADER_OUT: //언로더아웃
if (_SM_RUN_UNLOADER_OUT(runStepisFirst, PUB.sm.GetRunSteptime))
{
PUB.Speak(Lang.);
//도킹완료상태를 업데이트한다.
PUB.XBE.StepUnloader = Device.eDocStep.OutComplete;
//대기상태로 전환
PUB.sm.SetNewRunStep(ERunStep.READY);
return;
}
break;
case ERunStep.UNLOADER_IN: //언로더도킹
if (_SM_RUN_UNLOADER_IN(runStepisFirst, PUB.sm.GetRunSteptime))
{
PUB.Speak(Lang.);
//도킹완료상태를 업데이트한다.
PUB.XBE.StepUnloader = Device.eDocStep.InComplete;
//대기상태로 전환
PUB.sm.SetNewRunStep(ERunStep.READY);
return;
}
break;
case ERunStep.CLEANER_OUT: //클리너아웃
if (_SM_RUN_CLEANER_OUT(runStepisFirst, PUB.sm.GetRunSteptime))
{
PUB.Speak(Lang.);
//도킹완료상태를 업데이트한다.
PUB.XBE.StepCleaner = Device.eDocStep.OutComplete;
//대기상태로 전환
PUB.sm.SetNewRunStep(ERunStep.READY);
return;
}
break;
case ERunStep.CLEANER_IN: //클리너도킹
if (_SM_RUN_CLEANER_IN(runStepisFirst, PUB.sm.GetRunSteptime))
{
PUB.Speak(Lang.);
//도킹완료상태를 업데이트한다.
PUB.XBE.StepCleaner = Device.eDocStep.InComplete;
//클리너아웃으로 자동 진행하지 않음
PUB.sm.SetNewRunStep(ERunStep.READY);
return;
}
break;
case ERunStep.BUFFER_OUT: //버퍼아웃
if (_SM_RUN_BUFFER_OUT(runStepisFirst, PUB.sm.GetRunSteptime))
{
PUB.Speak(Lang.);
//도킹완료상태를 업데이트한다.
PUB.XBE.StepBuffer = Device.eDocStep.OutComplete;
//대기상태로 전환
PUB.sm.SetNewRunStep(ERunStep.READY);
return;
}
else PUB.XBE.StepBuffer = Device.eDocStep.OutIng;
break;
case ERunStep.BUFFER_IN: //버퍼도킹
if (_SM_RUN_BUFFER_IN(runStepisFirst, PUB.sm.GetRunSteptime))
{
PUB.Speak(Lang.);
//도킹완료상태를 업데이트한다.
PUB.XBE.StepBuffer = Device.eDocStep.InComplete;
//대기상태로 전환
PUB.sm.SetNewRunStep(ERunStep.READY);
return;
}
else PUB.XBE.StepBuffer = Device.eDocStep.InIng;
break;
}
}
}//cvass
}