버퍼경로내의 오동작 확인 및 재시작 관련 코드 점검
This commit is contained in:
@@ -289,10 +289,10 @@
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="PUB.cs" />
|
||||
<Compile Include="CSetting.cs" />
|
||||
<Compile Include="StateMachine\Step\_SM_RUN_LOADER_IN.cs">
|
||||
<Compile Include="StateMachine\Step\_SM_RUN_ENTER.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="StateMachine\Step\_SM_RUN_LOADER_OUT.cs">
|
||||
<Compile Include="StateMachine\Step\_SM_RUN_EXIT.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="StateMachine\Step\_Util.cs">
|
||||
|
||||
@@ -231,7 +231,7 @@ namespace Project
|
||||
case ERunStep.CLEANER_IN: //클리너도킹
|
||||
case ERunStep.UNLOADER_IN: //언로더도킹
|
||||
case ERunStep.LOADER_IN: //로더도킹
|
||||
if (_SM_RUN_LOADER_IN(runStepisFirst, PUB.sm.GetRunSteptime))
|
||||
if (_SM_RUN_ENTER(runStepisFirst, PUB.sm.GetRunSteptime))
|
||||
{
|
||||
PUB.Speak(Lang.버퍼도킹이완료되었습니다);
|
||||
|
||||
@@ -246,7 +246,7 @@ namespace Project
|
||||
case ERunStep.CLEANER_OUT: //클리너아웃
|
||||
case ERunStep.UNLOADER_OUT: //언로더아웃
|
||||
case ERunStep.LOADER_OUT: //로더아웃
|
||||
if (_SM_RUN_LOADER_OUT(runStepisFirst, PUB.sm.GetRunSteptime))
|
||||
if (_SM_RUN_EXIT(runStepisFirst, PUB.sm.GetRunSteptime))
|
||||
{
|
||||
PUB.Speak(Lang.버퍼도킹해제완료);
|
||||
|
||||
|
||||
@@ -60,18 +60,52 @@ namespace Project
|
||||
}
|
||||
else if (PUB.sm.RunStepSeq == idx++)
|
||||
{
|
||||
if (PUB._virtualAGV.Turn != AGVNavigationCore.Models.AGVTurn.L90)
|
||||
//이미 턴이 되어있는지 확인한다 (재진입 시 중복 실행 방지)
|
||||
if (PUB._virtualAGV.Turn == AGVNavigationCore.Models.AGVTurn.L90)
|
||||
{
|
||||
PUB.log.Add($"[{funcname}] 이미 Left Turn 완료 상태입니다. 턴 명령을 건너뜁니다.");
|
||||
PUB.sm.UpdateRunStepSeq();
|
||||
}
|
||||
else
|
||||
{
|
||||
//하드웨어 상태 확인
|
||||
var turnState = PUB.AGV.TurnInformation?.State ?? arDev.eNarumiTurn.None;
|
||||
|
||||
if (turnState == arDev.eNarumiTurn.Left || turnState == arDev.eNarumiTurn.LeftIng)
|
||||
{
|
||||
//이미 좌회전 중이거나 완료된 하드웨어 상태
|
||||
PUB.log.Add($"[{funcname}] 하드웨어 좌회전 상태 확인됨({turnState}). 명령을 건너뜁니다.");
|
||||
PUB.sm.UpdateRunStepSeq();
|
||||
}
|
||||
else if (turnState == arDev.eNarumiTurn.Right || turnState == arDev.eNarumiTurn.RightIng)
|
||||
{
|
||||
//비정상 상태 (우회전 중?)
|
||||
PUB.AGV.AGVMoveStop(funcname);
|
||||
PUB.log.AddE($"[{funcname}] 턴 방향 불일치(Current:{turnState}). 우회전 상태에서 좌회전을 시도할 수 없습니다.");
|
||||
PUB._mapCanvas.SetAlertMessage("Turn 방향 오류");
|
||||
PUB.sm.SetNewRunStep(ERunStep.ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
//정상 (None) -> 턴 명령 실행
|
||||
PUB.AGV.AGVMoveLeft180Turn();
|
||||
PUB.log.Add("AGV Left Turn");
|
||||
VAR.TIME.Update(eVarTime.LastTurnCommandTime);
|
||||
PUB.sm.UpdateRunStepSeq();
|
||||
}
|
||||
}
|
||||
PUB._mapCanvas.SetAlertMessage($"턴 진행 중");
|
||||
PUB.sm.UpdateRunStepSeq(); //이미완료된상태이므로 다음으로 진행한다.
|
||||
return false;
|
||||
}
|
||||
else if (PUB.sm.RunStepSeq == idx++)
|
||||
{
|
||||
//이미 완료된 상태라면 대기 과정을 건너뛴다.
|
||||
if (PUB._virtualAGV.Turn == AGVNavigationCore.Models.AGVTurn.L90)
|
||||
{
|
||||
PUB.sm.UpdateRunStepSeq();
|
||||
return false;
|
||||
}
|
||||
|
||||
//왼쪽턴이 완료되지 않은경우
|
||||
if (PUB.AGV.TurnInformation.State != arDev.eNarumiTurn.Left)
|
||||
{
|
||||
@@ -82,7 +116,7 @@ namespace Project
|
||||
var overtime = 30;
|
||||
if (PUB.AGV.TurnInformation.Runtime.TotalSeconds > overtime)
|
||||
{
|
||||
//5초동안 AGV까 움직이지 않았다면 오류 처리한다.
|
||||
//30초동안 AGV까 움직이지 않았다면 오류 처리한다.
|
||||
PUB.AGV.AGVMoveStop($"[bufferin] {overtime}초이내 턴 감지 안됨");
|
||||
PUB.log.AddE($"[{funcname}] {overtime}초이내 턴 감지 안됨");
|
||||
PUB._mapCanvas.SetAlertMessage($"턴 완료 확인 불가(최대:{overtime}초)");
|
||||
@@ -148,6 +182,17 @@ namespace Project
|
||||
else if (PUB.sm.RunStepSeq == idx++)
|
||||
{
|
||||
//저속이동 (후진 진입)
|
||||
|
||||
// [Smart Restart] 재시작 시 안전 검사
|
||||
// 이미 턴을 완료했고(L90), 현재 마크 센서가 감지된다면(ON),
|
||||
// 이미 목적지(Mark 2)에 도착한 것으로 간주하여 후진을 생략한다.
|
||||
if (PUB._virtualAGV.Turn == AGVNavigationCore.Models.AGVTurn.L90 && PUB.AGV.signal1.mark_sensor == true)
|
||||
{
|
||||
PUB.log.Add($"[{funcname}] 이미 목적지 도착 확인됨(Turn:L90, Sensor:ON). 후진 이동을 생략합니다.");
|
||||
PUB.sm.UpdateRunStepSeq();
|
||||
return false;
|
||||
}
|
||||
|
||||
var ret = PUB.AGV.AGVMoveSet(new arDev.Narumi.BunkiData
|
||||
{
|
||||
Bunki = arDev.Narumi.eBunki.Strate,
|
||||
|
||||
@@ -116,16 +116,36 @@ namespace Project
|
||||
}
|
||||
else if (PUB.sm.RunStepSeq == idx++)
|
||||
{
|
||||
//마크스탑
|
||||
PUB.AGV.AGVMoveStop("buffer out", arDev.Narumi.eStopOpt.MarkStop);
|
||||
PUB.sm.UpdateRunStepSeq();
|
||||
return false;
|
||||
}
|
||||
else if (PUB.sm.RunStepSeq == idx++)
|
||||
{
|
||||
//이동확인
|
||||
//AGV구동을 확인하고 마크스탑을 설정한다.
|
||||
if (PUB.AGV.system1.agv_run == false)
|
||||
{
|
||||
if (seqtime.TotalSeconds > 3)
|
||||
{
|
||||
//구동이확인되지 않으면 오류처리를 한다.
|
||||
PUB.AGV.AGVMoveStop(funcname);
|
||||
PUB.log.AddE($"[{funcname}] AGV 전진 구동이 확인되지 않습니다");
|
||||
PUB._mapCanvas.SetAlertMessage("agv 전진실패");
|
||||
PUB.sm.SetNewRunStep(ERunStep.ERROR);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//마크스탑설정
|
||||
PUB.AGV.AGVMoveStop(funcname, arDev.Narumi.eStopOpt.MarkStop);
|
||||
PUB.sm.UpdateRunStepSeq();
|
||||
return false;
|
||||
}
|
||||
else if (PUB.sm.RunStepSeq == idx++)
|
||||
{
|
||||
//마크스탑신호가 3초이내로 들어와야 한다
|
||||
if (PUB.AGV.data.Speed != 'S')
|
||||
{
|
||||
if (seqtime.TotalSeconds > 3)
|
||||
{
|
||||
PUB.AGV.AGVMoveStop(funcname);
|
||||
PUB.log.AddE($"[{funcname}] MARK STOP신호가 확인되지 않습니다");
|
||||
PUB._mapCanvas.SetAlertMessage("mark stop 신호 확인 안됨");
|
||||
PUB.sm.SetNewRunStep(ERunStep.ERROR);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
PUB.sm.UpdateRunStepSeq();
|
||||
@@ -133,9 +153,16 @@ namespace Project
|
||||
}
|
||||
else if (PUB.sm.RunStepSeq == idx++)
|
||||
{
|
||||
//멈춤확인
|
||||
//AGV가 멈출때까지 기다린다.
|
||||
if (PUB.AGV.system1.agv_run == true)
|
||||
{
|
||||
if (seqtime.TotalSeconds > 15)
|
||||
{
|
||||
PUB.AGV.AGVMoveStop(funcname);
|
||||
PUB.log.AddE($"[{funcname}] AGV가 멈추지 않아 강제종료 합니다");
|
||||
PUB._mapCanvas.SetAlertMessage("agv가 멈추지 않아 강제 종료");
|
||||
PUB.sm.SetNewRunStep(ERunStep.ERROR);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
PUB.sm.UpdateRunStepSeq();
|
||||
@@ -144,8 +171,38 @@ namespace Project
|
||||
else if (PUB.sm.RunStepSeq == idx++)
|
||||
{
|
||||
//우측으로 180도 턴
|
||||
//이미 턴이 되어있는지 확인한다 (재진입 시 중복 실행 방지)
|
||||
if (PUB._virtualAGV.Turn == AGVNavigationCore.Models.AGVTurn.R90)
|
||||
{
|
||||
PUB.log.Add($"[{funcname}] 이미 Right Turn 완료 상태입니다. 턴 명령을 건너뜁니다.");
|
||||
PUB.sm.UpdateRunStepSeq();
|
||||
}
|
||||
else
|
||||
{
|
||||
//하드웨어 상태 확인
|
||||
var turnState = PUB.AGV.TurnInformation?.State ?? arDev.eNarumiTurn.None;
|
||||
|
||||
if (turnState == arDev.eNarumiTurn.Right || turnState == arDev.eNarumiTurn.RightIng)
|
||||
{
|
||||
//이미 우회전 중이거나 완료된 하드웨어 상태
|
||||
PUB.log.Add($"[{funcname}] 하드웨어 우회전 상태 확인됨({turnState}). 명령을 건너뜁니다.");
|
||||
PUB.sm.UpdateRunStepSeq();
|
||||
}
|
||||
else if (turnState == arDev.eNarumiTurn.Left || turnState == arDev.eNarumiTurn.LeftIng)
|
||||
{
|
||||
//비정상 상태 (좌회전 중?)
|
||||
PUB.AGV.AGVMoveStop(funcname);
|
||||
PUB.log.AddE($"[{funcname}] 턴 방향 불일치(Current:{turnState}). 좌회전 상태에서 우회전을 시도할 수 없습니다.");
|
||||
PUB._mapCanvas.SetAlertMessage("Turn 방향 오류");
|
||||
PUB.sm.SetNewRunStep(ERunStep.ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
//정상 (None) -> 턴 명령 실행
|
||||
PUB.AGV.AGVMoveRight180Turn();
|
||||
PUB.sm.UpdateRunStepSeq();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else if (PUB.sm.RunStepSeq == idx++)
|
||||
@@ -153,6 +210,27 @@ namespace Project
|
||||
//이동확인
|
||||
if (PUB.AGV.system1.agv_run == false)
|
||||
{
|
||||
if (seqtime.TotalSeconds > 3)
|
||||
{
|
||||
//만약 이미 완료된 상태라서 건너뛰었다면 run이 안될 수 있다.
|
||||
//하지만 위에서 건너뜀 -> UpdateRunStepSeq -> 바로 여기로 옴.
|
||||
//건너뛴 경우(Turn == R90), Run 확인을 할 필요가 없으므로...
|
||||
//로직 보완: 턴 상태가 이미 완료라면 이동확인도 스킵해야 함?
|
||||
//아니면 위 단계에서 완료 상태면 '다음 다음' 단계로 점프?
|
||||
//간단하게: Turn이 R90이면 그냥 통과시킴.
|
||||
|
||||
if (PUB._virtualAGV.Turn == AGVNavigationCore.Models.AGVTurn.R90)
|
||||
{
|
||||
//이미 완료된 상태이므로 이동 확인 패스
|
||||
PUB.sm.UpdateRunStepSeq();
|
||||
return false;
|
||||
}
|
||||
|
||||
PUB.AGV.AGVMoveStop(funcname);
|
||||
PUB.log.AddE($"[{funcname}] Turn 구동 실패");
|
||||
PUB._mapCanvas.SetAlertMessage("Turn 구동 실패");
|
||||
PUB.sm.SetNewRunStep(ERunStep.ERROR);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
PUB.sm.UpdateRunStepSeq();
|
||||
@@ -163,8 +241,23 @@ namespace Project
|
||||
//멈춤확인
|
||||
if (PUB.AGV.system1.agv_run == true)
|
||||
{
|
||||
if (seqtime.TotalSeconds > 25)
|
||||
{
|
||||
PUB.AGV.AGVMoveStop(funcname);
|
||||
PUB.log.AddE($"[{funcname}] Turn 완료 실패 (Timeout)");
|
||||
PUB._mapCanvas.SetAlertMessage("Turn 완료 실패");
|
||||
PUB.sm.SetNewRunStep(ERunStep.ERROR);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//턴 완료 상태 업데이트
|
||||
if (PUB._virtualAGV.Turn != AGVNavigationCore.Models.AGVTurn.R90)
|
||||
{
|
||||
PUB._virtualAGV.Turn = AGVNavigationCore.Models.AGVTurn.R90;
|
||||
PUB.log.Add($"[{funcname}] Turn State Updated to R90");
|
||||
}
|
||||
|
||||
PUB.sm.UpdateRunStepSeq();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -12,9 +12,9 @@ namespace Project
|
||||
public partial class fMain
|
||||
{
|
||||
/// <summary>
|
||||
/// 로더 진입
|
||||
/// 장비로 진입한다. -
|
||||
/// </summary>
|
||||
public Boolean _SM_RUN_LOADER_IN(bool isFirst, TimeSpan seqTime)
|
||||
public Boolean _SM_RUN_ENTER(bool isFirst, TimeSpan seqTime)
|
||||
{
|
||||
var idx = 1;
|
||||
var funcname = PUB.sm.RunStep.ToString();
|
||||
@@ -12,9 +12,9 @@ namespace Project
|
||||
public partial class fMain
|
||||
{
|
||||
/// <summary>
|
||||
/// 로더 배출
|
||||
/// 장비엣 빠젼나온다.
|
||||
/// </summary>
|
||||
public Boolean _SM_RUN_LOADER_OUT(bool isFirst, TimeSpan seqTime)
|
||||
public Boolean _SM_RUN_EXIT(bool isFirst, TimeSpan seqTime)
|
||||
{
|
||||
var idx = 1;
|
||||
var funcname = PUB.sm.RunStep.ToString();
|
||||
@@ -203,22 +203,28 @@ namespace Project
|
||||
{
|
||||
if (PUB.AGV.system1.agv_run == false)
|
||||
{
|
||||
//목적지도착완료시
|
||||
// 경로가 존재한다면, 경로의 마지막 노드에 도착했는지 확인한다.
|
||||
if (PUB._virtualAGV.CurrentPath != null && PUB._virtualAGV.CurrentPath.DetailedPath.Any())
|
||||
{
|
||||
var lastInfo = PUB._virtualAGV.CurrentPath.DetailedPath.Last();
|
||||
// 위치와 방향이 모두 일치해야 완료된 것으로 본다.
|
||||
if (PUB._virtualAGV.CurrentNode.Id == lastInfo.NodeId &&
|
||||
PUB._virtualAGV.CurrentDirection == lastInfo.MotorDirection)
|
||||
{
|
||||
var node = PUB._mapCanvas.Nodes.Where(t => t.Id == PUB._virtualAGV.CurrentNodeId).FirstOrDefault();
|
||||
var rfid = node?.ID2 ?? "(X)";
|
||||
PUB.log.AddI($"목표 도착 및 정지 확인됨(MarkStop 완료) Node:{rfid}, Dir:{PUB._virtualAGV.CurrentDirection}");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 경로 정보가 없다면 단순히 목적지 ID와 비교한다 (Fallback)
|
||||
if (PUB._virtualAGV.CurrentNode.Id == PUB._virtualAGV.TargetNode.Id)
|
||||
{
|
||||
var node = PUB._mapCanvas.Nodes.Where(t => t.Id == PUB._virtualAGV.CurrentNodeId).FirstOrDefault();
|
||||
var rfid = node?.ID2 ?? "(X)";
|
||||
PUB.log.AddI($"목표 도착 및 정지 확인됨(MarkStop 완료) Node:{rfid}");
|
||||
return true;
|
||||
}
|
||||
|
||||
//목적지가 버퍼라면 그 앞에 멈춘다
|
||||
if (PUB._virtualAGV.TargetNode.StationType == AGVNavigationCore.Models.StationType.Buffer &&
|
||||
PUB._virtualAGV.CurrentPath != null && PUB._virtualAGV.CurrentPath.DetailedPath.Any())
|
||||
{
|
||||
if (PUB._virtualAGV.CurrentNode.Id == PUB._virtualAGV.CurrentPath.DetailedPath.Last().NodeId)
|
||||
{
|
||||
PUB.log.AddI($"목표(버퍼) 도착 및 정지 확인됨(MarkStop 완료). Node:{PUB._virtualAGV.CurrentNodeID2}");
|
||||
PUB.log.AddI($"목표 도착 및 정지 확인됨(MarkStop 완료, No Path Info) Node:{rfid}");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user