buffer in/out 시퀀스 작성중

This commit is contained in:
backuppc
2025-12-11 08:22:52 +09:00
parent 9a0a389e07
commit 6024f372d3
23 changed files with 671 additions and 806 deletions

View File

@@ -38,6 +38,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AGVSimulator", "AGVLogic\AG
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "arCommUtil", "SubProject\commutil\arCommUtil.csproj", "{14E8C9A5-013E-49BA-B435-FFFFFF7DD623}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Supertonic.Netfx48", "SubProject\SuperTonic\Supertonic.Netfx48.csproj", "{19675E19-EB91-493E-88C3-32B3C094B749}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -180,6 +182,18 @@ Global
{14E8C9A5-013E-49BA-B435-FFFFFF7DD623}.Release|x64.Build.0 = Release|Any CPU
{14E8C9A5-013E-49BA-B435-FFFFFF7DD623}.Release|x86.ActiveCfg = Release|x86
{14E8C9A5-013E-49BA-B435-FFFFFF7DD623}.Release|x86.Build.0 = Release|x86
{19675E19-EB91-493E-88C3-32B3C094B749}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19675E19-EB91-493E-88C3-32B3C094B749}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19675E19-EB91-493E-88C3-32B3C094B749}.Debug|x64.ActiveCfg = Debug|x64
{19675E19-EB91-493E-88C3-32B3C094B749}.Debug|x64.Build.0 = Debug|x64
{19675E19-EB91-493E-88C3-32B3C094B749}.Debug|x86.ActiveCfg = Debug|Win32
{19675E19-EB91-493E-88C3-32B3C094B749}.Debug|x86.Build.0 = Debug|Win32
{19675E19-EB91-493E-88C3-32B3C094B749}.Release|Any CPU.ActiveCfg = Release|Any CPU
{19675E19-EB91-493E-88C3-32B3C094B749}.Release|Any CPU.Build.0 = Release|Any CPU
{19675E19-EB91-493E-88C3-32B3C094B749}.Release|x64.ActiveCfg = Release|x64
{19675E19-EB91-493E-88C3-32B3C094B749}.Release|x64.Build.0 = Release|x64
{19675E19-EB91-493E-88C3-32B3C094B749}.Release|x86.ActiveCfg = Release|Win32
{19675E19-EB91-493E-88C3-32B3C094B749}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -193,6 +207,7 @@ Global
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890} = {E5C75D32-5AD6-44DD-8F27-E32023206EBB}
{B2C3D4E5-0000-0000-0000-000000000000} = {E5C75D32-5AD6-44DD-8F27-E32023206EBB}
{14E8C9A5-013E-49BA-B435-FFFFFF7DD623} = {C423C39A-44E7-4F09-B2F7-7943975FF948}
{19675E19-EB91-493E-88C3-32B3C094B749} = {C423C39A-44E7-4F09-B2F7-7943975FF948}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B5B1FD72-356F-4840-83E8-B070AC21C8D9}

View File

@@ -43,6 +43,8 @@ namespace AGVNavigationCore.Models
/// </summary>
public event EventHandler<string> ErrorOccurred;
#endregion
#region Fields
@@ -83,6 +85,8 @@ namespace AGVNavigationCore.Models
#region Properties
public bool Turn180 { get; set; } = false;
/// <summary>
/// 대상 이동시 모터 방향
/// </summary>
@@ -647,6 +651,19 @@ namespace AGVNavigationCore.Models
#endregion
/// <summary>
/// 노드 ID를 RFID 값으로 변환 (NodeResolver 사용)
/// </summary>
public string GetRfidByNodeId(List<MapNode> _mapNodes, string nodeId)
{
var node = _mapNodes?.FirstOrDefault(n => n.NodeId == nodeId);
return node?.HasRfid() == true ? node.RfidId : nodeId;
}
#region Private Methods
/// <summary>
@@ -799,6 +816,9 @@ namespace AGVNavigationCore.Models
BatteryLevel = Math.Max(0, BatteryLevel);
}
public MapNode StartNode { get; set; } = null;
public MapNode TargetNode { get; set; } = null;
private void ProcessNextNode()
{
if (_remainingNodes == null || _currentNodeIndex >= _remainingNodes.Count - 1)

View File

@@ -195,12 +195,6 @@
<Compile Include="Dialog\fCounter.Designer.cs">
<DependentUpon>fCounter.cs</DependentUpon>
</Compile>
<Compile Include="Dialog\fQuestionBox.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Dialog\fQuestionBox.Designer.cs">
<DependentUpon>fQuestionBox.cs</DependentUpon>
</Compile>
<Compile Include="Dialog\fStateMachineDebug.cs">
<SubType>Form</SubType>
</Compile>
@@ -311,10 +305,10 @@
<Compile Include="StateMachine\Step\_SM_RUN_GOHOME.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="StateMachine\Step\_SM_RUN_GOUP.cs">
<Compile Include="StateMachine\Step\_SM_RUN_BUFFER_OUT.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="StateMachine\Step\_SM_RUN_GODOWN.cs">
<Compile Include="StateMachine\Step\_SM_RUN_BUFFER_IN.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="StateMachine\Step\_SM_RUN_SYNC.cs">

View File

@@ -333,6 +333,11 @@ namespace Project
public Single interval_xbe { get; set; }
[Browsable(false)]
public int interval_bms { get; set; }
/// <summary>
/// 스피커출력 간격
/// </summary>
[DisplayName("Speak Term")]
public int doorSoundTerm { get; set; }
[Browsable(false)]

View File

@@ -51,8 +51,7 @@ namespace Project
public static string AGV연결실패 { get { return string.Format("AGV {0}", ); } }
public static string = "이동 예측이 동작하지 않습니다. 개발부서에 문의 하세요";
public static string = "목적지 이동 이 완료 되었습니다";
public static string = "홈검색을시작합니다";
public static string FindCurrentPisition = "현재 위치를 검색 합니다";
public static string = "상차";
public static string = "하차";
@@ -70,8 +69,8 @@ namespace Project
public static string = "커버를 올립니다";
public static string = "홈 위치로 이동 합니다";
public static string = "하차 작업이 완료 되었습니다";
public static string = "상차 작업이 완료 되었습니다";
public static string = "버퍼 도킹이 완료 되었습니다";
public static string = "버퍼 도킹이 해제 되었습니다";
public static string = "커버 업 대기 상태가 아닙니다";
public static string QC이동버튼은상하차에서만사용가능합니다 = "QC이동 버튼은 상,하차 에서만 사용 가능합니다";
public static string QA이동버튼은상하차에서만사용가능합니다 = "QA이동 버튼은 상,하차 에서만 사용 가능합니다";

View File

@@ -154,6 +154,10 @@ namespace Project.Device
Send(packet);
}
public bool BufferInReady { get; set; }
public bool BufferInComplete { get; set; }
public bool BufferOutComplete { get; set; }
public bool BufferReadyError { get; set; }
/// <summary>

View File

@@ -118,7 +118,7 @@ namespace Project
if (VAR.BOOL[eVarBool.FLAG_AUTORUN] &&
VAR.BOOL[eVarBool.FLAG_CHARGEONM] == false &&
PUB.BMS.Current_Level > PUB.setting.ChargeEmergencyLevel &&
PUB.sm.RunStep != StateMachine.ERunStep.GOUP &&
PUB.sm.RunStep != StateMachine.ERunStep.BUFFER_OUT &&
VAR.BOOL[eVarBool.WAIT_COVER_DOWN] == false &&
VAR.BOOL[eVarBool.WAIT_COVER_UP] == false)
{

View File

@@ -92,11 +92,110 @@ namespace Project
return;
}
//선로이탈감지
if (PUB.AGV.error.runerror_by_no_magent_line == true)
{
var tsSpeak = DateTime.Now - LastSpeakTime;
if (tsSpeak.TotalSeconds >= PUB.setting.doorSoundTerm)
{
PUB.Speak(Lang.);
LastSpeakTime = DateTime.Now;
}
return;
}
//현재위치를 모르는 상태라면 이동하여 현재 위치를 찾는다
if (PUB._virtualAGV.CurrentNodeId.isEmpty())// .cur. . CurrentPos == ePosition.NONE)
{
//이동중이지 않거나 홈이동상태가 아니라면?
if (PUB.AGV.system1.agv_run == false || PUB.sm.RunStep != ERunStep.GOHOME)
{
//현재위치를 검색해야함
PUB.sm.ClearRunStep();
PUB.sm.SetNewRunStep(ERunStep.GOHOME);
PUB.AddEEDB($"READY상태에서 현재위치를 몰라 홈으로 이동 백업스텝:{PUB.sm.RunStep}");
PUB.sm.BackupRunStep.Push(PUB.sm.RunStep); //현재 상태를 백업
return;
}
VAR.STR[eVarString.ChargeCheckMsg] = "현재 위치 모름";
}
//나머지 상황체크
switch (PUB.sm.RunStep)
{
case ERunStep.GOHOME:
if (runStepisFirst)
{
PUB.Speak(Lang.FindCurrentPisition);
}
else if (_SM_RUN_GOHOME(runStepisFirst, PUB.sm.GetRunSteptime))
{
//230601
PUB.Speak(Lang.);
VAR.TIME.Update(eVarTime.ChargeTry);
ERunStep NextStep = ERunStep.READY;
if (PUB.sm.BackupRunStep.Count > 0)
NextStep = PUB.sm.BackupRunStep.Pop();
PUB.log.Add($"현재위치 검색완료로 {NextStep} 으로 RUNSTEP값을 변경 합니다");
PUB.sm.SetNewRunStep(NextStep); //대기상태로 전환한다
return;
}
break;
case ERunStep.GOTO: //목적지까지 이동하는 경우
_SM_RUN_GOTO(runStepisFirst, PUB.sm.GetRunSteptime);
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}");
if (target.Type == AGVNavigationCore.Models.NodeType.Buffer)
{
//현재위치가 마지막경로의 NODEID와 일치해야한다
var lastPath = PUB._virtualAGV.CurrentPath.DetailedPath.LastOrDefault();
if(lastPath.NodeId.Equals(PUB._virtualAGV.CurrentNodeId))
{
//버퍼진입전 노드에 도착완료했따
PUB.XBE.BufferInReady = true;
PUB.XBE.BufferReadyError = false;
}
else
{
//마지막위치가 아닌 다른 위치에 있으니 버퍼 작업을 할 수없다
PUB.log.AddAT("목적지 버퍼이동완료 했지만 마지막 노드가 아닙니다");
PUB.XBE.BufferInReady = false;
PUB.XBE.BufferReadyError = true;
}
PUB.XBE.BufferInComplete = false;
PUB.XBE.BufferOutComplete = false;
}
else if(target.Type == AGVNavigationCore.Models.NodeType.Charging)
{
}
else if (target.Type == AGVNavigationCore.Models.NodeType.Loader)
{
}
else if (target.Type == AGVNavigationCore.Models.NodeType.Clearner)
{
}
else if (target.Type == AGVNavigationCore.Models.NodeType.UnLoader)
{
}
else
{
//목적지다 다른 형태이다
}
PUB._virtualAGV.Turn = AGVNavigationCore.Models.AGVTurn.None;
PUB.sm.SetNewRunStep(ERunStep.READY);
}
break;
case ERunStep.MARKSTROPB: //후진방향으로 마크스탑
@@ -177,76 +276,37 @@ namespace Project
}
}
break;
case ERunStep.GOUP: //상차이동
if (_SM_RUN_GOUP(runStepisFirst, PUB.sm.GetRunSteptime))
case ERunStep.BUFFER_OUT: //버퍼아웃
if (_SM_RUN_BUFFER_OUT(runStepisFirst, PUB.sm.GetRunSteptime))
{
PUB.Speak(Lang.);
PUB.Speak(Lang.);
//230601
// if (PUB.Result != null && PUB.sm != null)
// EEMStatus.AddEEDBSQL(PUB.sm.Step, PUB.sm.RunStep.ToString(), PUB.Result.TargetPos.ToString());
//도킹완료상태를 업데이트한다.
PUB.XBE.BufferInComplete = false;
PUB.XBE.BufferOutComplete = true;
//QA를 제외한 경우에는 기본 QC로 이동한다
if (PUB.Result.NextPos == ePosition.QA)
PUB.Result.TargetPos = ePosition.QA;
else
PUB.Result.TargetPos = ePosition.QC;
PUB.sm.SetNewRunStep(ERunStep.GODOWN); //하차작업으로 전환
return;
}
break;
case ERunStep.GODOWN: //하차이동
if (_SM_RUN_GODOWN(runStepisFirst, PUB.sm.GetRunSteptime))
{
PUB.Speak(Lang.);
VAR.TIME.Update(eVarTime.ChargeTry);
PUB.AGV.LiftControl(arDev.Narumi.LiftCommand.DN);// (Device.PLC.ZMotDirection.Down); //하차작업이 완료되면 커버를 내려서 바로 작업할 수 있게 한다.
//230601
//if (PUB.Result != null && PUB.sm != null)
// EEMStatus.AddEEDBSQL(PUB.sm.Step, PUB.sm.RunStep.ToString(), PUB.Result.TargetPos.ToString());
//하차가 완료되면 충전대기시간을 30초 남겨두고 없데이트한다
//충전이 필요할 경우 바로 될수있도록 220118
VAR.TIME[eVarTime.ChargeTry] = DateTime.Now.AddSeconds(-1 * PUB.setting.ChargeRetryTerm + 30);
if (PUB.Result.CurrentPos == ePosition.QC)
{
PUB.Speak(Lang.);
//대기상태로 전환
PUB.sm.SetNewRunStep(ERunStep.READY);
return;
}
else
break;
case ERunStep.BUFFER_IN: //버퍼도킹
if (_SM_RUN_BUFFER_IN(runStepisFirst, PUB.sm.GetRunSteptime))
{
//홈 이동 명령처리
PUB.Speak(Lang.);
//도킹완료상태를 업데이트한다.
PUB.XBE.BufferInComplete = true;
//버퍼아웃으로 자동 진행 합니다
PUB.sm.ClearRunStep();
PUB.Result.TargetPos = ePosition.QC;
PUB.sm.SetNewRunStep(ERunStep.GOHOME);
PUB.Speak(Lang.);
}
PUB.sm.SetNewRunStep(ERunStep.BUFFER_OUT);
return;
}
break;
case ERunStep.GOHOME:
if (runStepisFirst)
{
PUB.Speak(Lang.);
}
else if (_SM_RUN_GOHOME(runStepisFirst, PUB.sm.GetRunSteptime))
{
//230601
// if (PUB.Result != null && PUB.sm != null)
// EEMStatus.AddEEDBSQL(PUB.sm.Step, PUB.sm.RunStep.ToString(), PUB.Result.TargetPos.ToString());
PUB.Speak(Lang.);
VAR.TIME.Update(eVarTime.ChargeTry);
PUB.sm.SetNewRunStep(ERunStep.READY); //대기상태로 전환한다
return;
}
break;
}

View File

@@ -0,0 +1,263 @@
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
{
/// <summary>
/// 버퍼도킹
/// </summary>
/// <param name="isFirst"></param>
/// <param name="stepTime"></param>
/// <returns></returns>
public Boolean _SM_RUN_BUFFER_IN(bool isFirst, TimeSpan stepTime)
{
var funcname = "_SM_RUN_BUFFER_IN";
var idx = 1;
if (runStepisFirst)
{
//PUB.flag.set(EFlag.FLAG_NEXTSTOP_ALIGN, false);
VAR.BOOL[eVarBool.FLAG_NEXTSTOP_ALIGN] = false;//
//VAR.BOOL[eVarBool.FLAG_NEXTSTOP_MARK] = false;//);
}
//HW 연결오류
if (PUB.AGV.IsOpen == false)
{
PUB.Result.SetResultMessage(eResult.Hardware, eECode.AGVCONN, eNextStep.ERROR);
return false;
}
//충전 상태가 OFF되어야 동작하게한다
if (_SM_RUN_CHGOFF(isFirst, stepTime) == false)
return false;
//라이더멈춤이 설정되어있다면 음성으로 알려준다 200409
if (PUB.AGV.system1.stop_by_front_detect == true)
{
var tsSpeak = DateTime.Now - LastSpeakTime;
if (tsSpeak.TotalSeconds >= PUB.setting.doorSoundTerm)
{
PUB.Speak(Lang.);
LastSpeakTime = DateTime.Now;
}
return false;
}
//현재 위치가 결정되어있는지 체크한다
if (_SM_RUN_POSCHK(isFirst, stepTime) == false)
return false;
/*
* 버퍼IN시퀀스
* 1. 회전이 진행되지 않았다면 회전을 진행한다.
* 2. LIFT DOWN
* 3. 후진-저속-마크다운 실행
*/
if (PUB.sm.RunStepSeq == idx++)
{
PUB.log.Add("버퍼도킹시작");
PUB.Speak(Lang.);
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//모션 전후진 제어
if (PUB._virtualAGV.Turn != AGVNavigationCore.Models.AGVTurn.L90)
{
//동작중이면 동작을 멈춘다
if (PUB.AGV.system1.agv_run == true)
{
var ts = VAR.TIME.RUN(eVarTime.LastStopCommandTime);
if (ts.TotalSeconds > 3)
{
PUB.AGV.AGVMoveStop(funcname);
VAR.TIME.Update(eVarTime.LastStopCommandTime);
}
}
else PUB.sm.UpdateRunStepSeq(); //agv가 멈춰있으므로 턴을 진행해야 한다
}
else PUB.sm.UpdateRunStepSeq(); //이미완료된상태이므로 다음으로 진행한다.
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
if (PUB._virtualAGV.Turn != AGVNavigationCore.Models.AGVTurn.L90)
{
VAR.TIME.Update(eVarTime.LastTurnCommandTime);
PUB.AGV.AGVMoveLeft180Turn();
PUB.log.Add("AGV Left Turn");
PUB.sm.UpdateRunStepSeq();
}
else PUB.sm.UpdateRunStepSeq(); //이미완료된상태이므로 다음으로 진행한다.
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
if (PUB._virtualAGV.Turn != AGVNavigationCore.Models.AGVTurn.L90)
{
//5초이내에 턴이동 상태가 확인되어야 한다.
if (PUB.AGV.system1.agv_run == false)
{
var ts = VAR.TIME.RUN(eVarTime.LastTurnCommandTime);
if (ts.TotalSeconds > 5)
{
//5초동안 AGV까 움직이지 않았다면 오류 처리한다.
PUB.AGV.AGVMoveStop("5초이내 턴 감지 안됨");
PUB.log.AddE("5초이내 턴 감지 안됨");
PUB.sm.SetNewRunStep(ERunStep.ERROR);
return false;
}
return false;
}
}
PUB.sm.UpdateRunStepSeq(); //이미완료된상태이므로 다음으로 진행한다.
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//턴이완료되었느닞 확인한다.
if (PUB._virtualAGV.Turn != AGVNavigationCore.Models.AGVTurn.L90)
{
//10초 이상 가동하고 있다면 문제이다
if (PUB.AGV.system1.agv_run == true)
{
var ts = VAR.TIME.RUN(eVarTime.LastTurnCommandTime);
if (ts.TotalSeconds > 15)
{
PUB.AGV.AGVMoveStop("15초이내 턴 이 완료되지 않음");
PUB.log.AddE("5초이내 턴 완료 확인 안됨");
PUB.sm.SetNewRunStep(ERunStep.ERROR);
return false;
}
return false;
}
else PUB._virtualAGV.Turn = AGVNavigationCore.Models.AGVTurn.L90;
}
PUB.sm.UpdateRunStepSeq(); //이미완료된상태이므로 다음으로 진행한다.
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//리프트를 내린다.
PUB.AGV.LiftControl(arDev.Narumi.LiftCommand.DN);
VAR.TIME.Update(eVarTime.LastTurnCommandTime);
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//리프트다운센서를 확인한다.
var liftdown = true;
if (liftdown == false)
{
var ts = VAR.TIME.RUN(eVarTime.LastTurnCommandTime);
if (ts.TotalSeconds > 10)
{
PUB.AGV.LiftControl(arDev.Narumi.LiftCommand.STP);
PUB.log.AddE("리프트 하강이 확인되지 않습니다(10초)");
PUB.sm.SetNewRunStep(ERunStep.ERROR);
return false;
}
}
PUB.log.Add("리프트 하강 완료");
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//마크스탑셋팅
PUB.AGV.AGVMoveStop(funcname, arDev.Narumi.eStopOpt.MarkStop);
VAR.TIME.Update(eVarTime.LastTurnCommandTime);
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//저속이동
var moveset = PUB.AGV.AGVMoveSet(new arDev.Narumi.BunkiData
{
Bunki = arDev.Narumi.eBunki.Strate,
Direction = arDev.Narumi.eMoveDir.Backward,
PBSSensor = 0,
Speed = arDev.Narumi.eMoveSpd.Low,
});
if (moveset == false)
{
var ts = VAR.TIME.RUN(eVarTime.LastTurnCommandTime);
if (ts.TotalSeconds > 10)
{
PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE("AGV속도설정이 완료되지 않았습니다");
PUB.sm.SetNewRunStep(ERunStep.ERROR);
return false;
}
}
PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Backward);
PUB.AGV.AGVMoveStop(funcname, arDev.Narumi.eStopOpt.MarkStop);
VAR.TIME.Update(eVarTime.LastTurnCommandTime);
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//마크스탑신호가 3초이내로 들어와야 한다
if (PUB.AGV.signal.mark_sensor == false)
{
var ts = VAR.TIME.RUN(eVarTime.LastTurnCommandTime);
if (ts.TotalSeconds > 3)
{
PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE("MARK STOP신호가 확인되지 않습니다");
PUB.sm.SetNewRunStep(ERunStep.ERROR);
return false;
}
}
VAR.TIME.Update(eVarTime.LastTurnCommandTime);
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//AGV가 멈출때까지 기다린다.
if (PUB.AGV.system1.agv_run == true)
{
var ts = VAR.TIME.RUN(eVarTime.LastTurnCommandTime);
if (ts.TotalSeconds > 10)
{
PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE("AGV가 멈추지 않아 강제종료 합니다");
PUB.sm.SetNewRunStep(ERunStep.ERROR);
return false;
}
return false;
}
VAR.TIME.Update(eVarTime.LastTurnCommandTime);
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//완료되었다. (ACS에 보내야함)
PUB.log.Add("버퍼투입완료");
PUB.sm.UpdateRunStepSeq();
return false;
}
PUB.AddEEDB($"버퍼투입완료({PUB.Result.TargetPos})");
return true;
}
}
}

View File

@@ -0,0 +1,135 @@
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
{
public Boolean _SM_RUN_BUFFER_OUT(bool isFirst, TimeSpan stepTime)
{
if (runStepisFirst)
{
}
//HW 연결오류
if (PUB.AGV.IsOpen == false)
{
PUB.Result.SetResultMessage(eResult.Hardware, eECode.AGVCONN, eNextStep.ERROR);
return false;
}
//충전 상태가 OFF되어야 동작하게한다
if (_SM_RUN_CHGOFF(isFirst, stepTime) == false)
return false;
//라이더멈춤이 설정되어있다면 음성으로 알려준다 200409
if (PUB.AGV.system1.stop_by_front_detect == true)
{
var tsSpeak = DateTime.Now - LastSpeakTime;
if (tsSpeak.TotalSeconds >= PUB.setting.doorSoundTerm)
{
PUB.Speak(Lang.);
LastSpeakTime = DateTime.Now;
}
return false;
}
//현재 위치가 결정되어있는지 체크한다
if (_SM_RUN_POSCHK(isFirst, stepTime) == false)
return false;
var idx = 1;
if (PUB.sm.RunStepSeq == idx++)
{
//빈 상태로 아웃해야한다.
PUB.AGV.AGVMoveSet(new arDev.Narumi.BunkiData
{
Bunki = arDev.Narumi.eBunki.Strate,
Direction = arDev.Narumi.eMoveDir.Forward,
PBSSensor = 0,
Speed = arDev.Narumi.eMoveSpd.Low,
});
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//전진이동
PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Forward);
PUB.sm.UpdateRunStepSeq();
return false;
}
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++)
{
//이동확인
if (PUB.AGV.system1.agv_run == false)
{
return false;
}
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//멈춤확인
if (PUB.AGV.system1.agv_run == true)
{
return false;
}
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//우측으로 180도 턴
PUB.AGV.AGVMoveRight180Turn();
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//이동확인
if (PUB.AGV.system1.agv_run == false)
{
return false;
}
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//멈춤확인
if (PUB.AGV.system1.agv_run == true)
{
return false;
}
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
PUB.log.Add("BufferOut Complete");
PUB.sm.UpdateRunStepSeq();
return false;
}
PUB.AddEEDB($"bufferout 완료({PUB.Result.TargetPos})");
return true;
}
}
}

View File

@@ -1,223 +0,0 @@
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
{
public Boolean _SM_RUN_GODOWN(bool isFirst, TimeSpan stepTime)
{
if (runStepisFirst)
{
//PUB.flag.set(EFlag.FLAG_NEXTSTOP_ALIGN, false);
VAR.BOOL[eVarBool.FLAG_NEXTSTOP_ALIGN] = false;//
//VAR.BOOL[eVarBool.FLAG_NEXTSTOP_MARK] = false;//);
}
//HW 연결오류
if (PUB.AGV.IsOpen == false)
{
PUB.Result.SetResultMessage(eResult.Hardware, eECode.AGVCONN, eNextStep.ERROR);
return false;
}
//충전 상태가 OFF되어야 동작하게한다
if (_SM_RUN_CHGOFF(isFirst, stepTime) == false)
return false;
//라이더멈춤이 설정되어있다면 음성으로 알려준다 200409
if (PUB.AGV.system1.stop_by_front_detect == true)
{
var tsSpeak = DateTime.Now - LastSpeakTime;
if (tsSpeak.TotalSeconds >= PUB.setting.doorSoundTerm)
{
PUB.Speak(Lang.);
LastSpeakTime = DateTime.Now;
}
return false;
}
//현재 위치가 결정되어있는지 체크한다
if (_SM_RUN_POSCHK(isFirst, stepTime) == false)
return false;
if (PUB.sm.RunStepSeq == 1)
{
//하차는 무조건 대상이 QC가 된다
if (PUB.Result.TargetPos == ePosition.NONE)
PUB.Result.TargetPos = ePosition.QC;
//if (PUB.Result.TargetPos == ePosition.QA &&
// PUB.Result.CurrentPos == ePosition.QC &&
// (PUB.PLC.IsLimitDn()))
//{
// PUB.Speak("안전 커버를 올리고 다시 시도하세요", true);
// PUB.sm.ClearRunStep();
// PUB.sm.SetNewRunStep(ERunStep.READY);
//}
PUB.AddEEDB($"하차작업시작({PUB.Result.TargetPos})");
PUB.Speak(Lang.);
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == 2)
{
//모션 전후진 제어
if (UpdateMotionPositionForMark("GODOWN"))
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == 3)
{
//위치 확정이 완료될때까지 대기
if (PUB.Result.CurrentPos == PUB.Result.TargetPos)
{
//PUB.PLC.Move(Device.PLC.Rundirection.Stop, "GODOWN:위치확정");
PUB.AGV.AGVMoveStop("sm_run_godown");
PUB.sm.UpdateRunStepSeq();
}
else if (PUB.AGV.system1.agv_run == false)
{
//움직이지않으면 방향을 다시 조정한다
PUB.sm.SetStepSeq(2);
}
return false;
}
else if (PUB.sm.RunStepSeq == 4)
{
//대상까지 모두 완료되었다.(완전히 정차할때까지 기다린다)
if (PUB.AGV.system1.agv_run == false)
{
PUB.log.Add("이동 정지 확인");
PUB.sm.UpdateRunStepSeq();
}
return false;
}
else if (PUB.sm.RunStepSeq == 5)
{
//하차수량증가
if (PUB.Result.TargetPos == ePosition.QA)
PUB.counter.CountQA += 1;
else
PUB.counter.CountQC += 1;
PUB.counter.Save();
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == 6)
{
//커버를 자동으로 내려준다
CoverControlTime = DateTime.Now;
UpdateProgressStatus(stepTime.TotalSeconds, 5, Lang.);
VAR.BOOL[eVarBool.WAIT_COVER_DOWN] = true;
PUB.AGV.LiftControl(arDev.Narumi.LiftCommand.DN);//
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == 7)
{
//커버 내림이 완료될때까지 기다린다
//if (PUB.PLC.IsLimitDn() == true)
//{
// VAR.BOOL[eVarBool.WAIT_COVER_DOWN] = false;
// PUB.sm.UpdateRunStepSeq();
//}
//else
{
//경과시간이 10초가 지나면 5초마다 음성을 출력한다
var tsCover = DateTime.Now - CoverControlTime;
if (tsCover.TotalSeconds >= 7)
{
PUB.Speak(Lang.);
CoverControlTime = DateTime.Now;
}
}
return false;
}
else if (PUB.sm.RunStepSeq == 8)
{
//IO업데이트 간격 전송
UpdateProgressStatus(stepTime.TotalSeconds, 5, Lang.);
//PUB.Speak(Lang.안전커버를올리면하차가완료됩니다);
VAR.BOOL[eVarBool.WAIT_COVER_UP] = true;
CoverControlTime = DateTime.Now;
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == 9)
{
//커버 올림이 완료될때까지 기다린다
if (VAR.BOOL[eVarBool.FLAG_LIMITHIGH] == true)
{
VAR.BOOL[eVarBool.WAIT_COVER_UP] = false;
VAR.BOOL[eVarBool.ITEMON] = false;
PUB.sm.UpdateRunStepSeq();
}
else
{
//경과시간이 10초가 지나면 5초마다 음성을 출력한다
var tsCover = DateTime.Now - CoverControlTime;
if (tsCover.TotalSeconds >= PUB.setting.doorSoundTerm)
{
PUB.Speak(Lang.);
CoverControlTime = DateTime.Now;
////한쪽이 올라가 있는 상태에..
//if (PUB.PLC.GetValueI(arDev.FakePLC.DIName.PINI_LIMIT_LU) == true)
//{
// //모터는 올리는 방향일때에...
// if (PUB.PLC.GetValueO(arDev.FakePLC.DOName.PINO_GUIDEMOTOR_LDIR) == true)
// {
// //모터가 멈춰있을때에..
// if (PUB.PLC.GetValueO(arDev.FakePLC.DOName.PINO_GUIDEMOTOR_LRUN) == false)
// {
// //자동으로 올려준다 (센서가 간혹 인식이 안되어서 .대기하는 경우가 잇음)
// //왼쪽이 올라가 있지 않은 경우
// if (PUB.PLC.GetValueI(arDev.FakePLC.DIName.PINI_LIMIT_LU) == false)
// PUB.PLC.ZMot_Left(arDev.FakePLC.ZMotDirection.Up);
// }
// }
//}
//if (PUB.PLC.GetValueI(arDev.FakePLC.DIName.PINI_LIMIT_RU) == true)
//{
// //모터는 올리는 방향일때에...
// if (PUB.PLC.GetValueO(arDev.FakePLC.DOName.PINO_GUIDEMOTOR_RDIR) == true)
// {
// //모터가 멈춰있을때에..
// if (PUB.PLC.GetValueO(arDev.FakePLC.DOName.PINO_GUIDEMOTOR_RRUN) == false)
// {
// //자동으로 올려준다 (센서가 간혹 인식이 안되어서 .대기하는 경우가 잇음)
// //왼쪽이 올라가 있지 않은 경우
// if (PUB.PLC.GetValueI(arDev.FakePLC.DIName.PINI_LIMIT_RU) == false)
// PUB.PLC.ZMot_Right(arDev.FakePLC.ZMotDirection.Up);
// }
// }
//}
}
}
return false;
}
PUB.AddEEDB($"하차작업완료({PUB.Result.TargetPos})");
EEMStatus.AddStatusCount(1, PUB.Result.TargetPos.ToString()); //230620
return true;
}
}
}

View File

@@ -29,6 +29,8 @@ namespace Project
VAR.TIME.Update(eVarTime.CheckGotoTargetSet);
}
//PUB._virtualAGV.
//목적지가 설정되었는지 체크한다.
//Z if (PUB.mapctl.Manager.agv.TargetRFID.IsEmpty)
// {

View File

@@ -1,269 +0,0 @@
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
{
public Boolean _SM_RUN_GOUP(bool isFirst, TimeSpan stepTime)
{
if (runStepisFirst)
{
// VAR.BOOL[eVarBool.FLAG_NEXTSTOP_MARK] = false;//);
VAR.BOOL[eVarBool.FLAG_NEXTSTOP_ALIGN] = false;
}
//HW 연결오류
if (PUB.AGV.IsOpen == false)
{
PUB.Result.SetResultMessage(eResult.Hardware, eECode.AGVCONN, eNextStep.ERROR);
return false;
}
//충전 상태가 OFF되어야 동작하게한다
if (_SM_RUN_CHGOFF(isFirst, stepTime) == false)
return false;
//라이더멈춤이 설정되어있다면 음성으로 알려준다 200409
if (PUB.AGV.system1.stop_by_front_detect == true)
{
var tsSpeak = DateTime.Now - LastSpeakTime;
if (tsSpeak.TotalSeconds >= PUB.setting.doorSoundTerm)
{
PUB.Speak(Lang.);
LastSpeakTime = DateTime.Now;
}
return false;
}
//현재 위치가 결정되어있는지 체크한다
if (_SM_RUN_POSCHK(isFirst, stepTime) == false)
return false;
var idx = 1;
if (PUB.sm.RunStepSeq == idx++)
{
//상차 가능 조건 확인
if (PUB.Result.TargetPos == ePosition.NONE)
{
PUB.Result.SetResultMessage(eResult.Hardware, eECode.NOTALLOWUP, eNextStep.ERROR);
}
else
{
PUB.AddEEDB($"상차작업시작({PUB.Result.TargetPos})");
PUB.Speak(Lang.);
PUB.sm.UpdateRunStepSeq();
}
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//모션 전후진 제어
if (UpdateMotionPositionForMark("GOUP"))
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//장비멈춤확인
if (PUB.AGV.system1.agv_run == true)
{
var ts = DateTime.Now - LastCommandTime;
if (ts.TotalMilliseconds > 2000)
{
PUB.AGV.AGVMoveStop("SM_RUN_GOUP");// PUB.PLC.Move(Device.PLC.Rundirection.Stop, "GOUP:위치확정");
LastCommandTime = DateTime.Now;
}
}
else
{
//움직이지 않고 있다면 다시 이동을 시켜준다.
PUB.log.Add("이동 정지 확인");
PUB.sm.UpdateRunStepSeq();
}
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
if (PUB.AGV.system1.agv_run == true)
{
var ts = DateTime.Now - LastCommandTime;
if (ts.TotalMilliseconds > 2000)
{
PUB.AGV.AGVMoveStop("SM_RUN_GOUP");// PUB.PLC.Move(Device.PLC.Rundirection.Stop, "GOUP:위치확정");
LastCommandTime = DateTime.Now;
}
}
//커버를 자동으로 내려준다
CoverControlTime = DateTime.Now;
UpdateProgressStatus(stepTime.TotalSeconds, 5, Lang.);
PUB.AGV.LiftControl(arDev.Narumi.LiftCommand.DN);
VAR.BOOL[eVarBool.WAIT_COVER_DOWN] = true;
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
if (PUB.AGV.system1.agv_run == true)
{
var ts = DateTime.Now - LastCommandTime;
if (ts.TotalMilliseconds > 2000)
{
PUB.AGV.AGVMoveStop("SM_RUN_GOUP");// PUB.PLC.Move(Device.PLC.Rundirection.Stop, "GOUP:위치확정");
LastCommandTime = DateTime.Now;
}
}
//커버 내림이 완료될때까지 기다린다
if (true)
{
VAR.BOOL[eVarBool.WAIT_COVER_DOWN] = false;
PUB.Result.NextPos = ePosition.NONE;
PUB.sm.UpdateRunStepSeq();
}
else
{
//경과시간이 10초가 지나면 5초마다 음성을 출력한다
var tsCover = DateTime.Now - CoverControlTime;
if (tsCover.TotalSeconds >= 7)
{
PUB.Speak(Lang.);
CoverControlTime = DateTime.Now;
}
}
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
if (PUB.AGV.system1.agv_run == true)
{
var ts = DateTime.Now - LastCommandTime;
if (ts.TotalMilliseconds > 2000)
{
PUB.AGV.AGVMoveStop("SM_RUN_GOUP");// PUB.PLC.Move(Device.PLC.Rundirection.Stop, "GOUP:위치확정");
LastCommandTime = DateTime.Now;
}
return false;
}
//상차는 여기서 수량확인한다
if (PUB.Result.TargetPos == ePosition.F1)
PUB.counter.CountUp1 += 1;
else if (PUB.Result.TargetPos == ePosition.F2)
PUB.counter.CountUp2 += 1;
else if (PUB.Result.TargetPos == ePosition.F3)
PUB.counter.CountUp3 += 1;
else if (PUB.Result.TargetPos == ePosition.F4)
PUB.counter.CountUp4 += 1;
//else if (PUB.Result.TargetPos == ePosition.QA)
// PUB.counter.CountQA += 1;
PUB.counter.Save();
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//IO업데이트 간격 전송
UpdateProgressStatus(stepTime.TotalSeconds, 5, Lang.);
PUB.Speak(Lang.);
PUB.sm.UpdateRunStepSeq();
VAR.BOOL[eVarBool.WAIT_COVER_UP] = true;
PUB.Result.NextPos = ePosition.NONE;
CoverControlTime = DateTime.Now;
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
if (PUB.AGV.system1.agv_run == true)
{
var ts = DateTime.Now - LastCommandTime;
if (ts.TotalMilliseconds > 2000)
{
PUB.AGV.AGVMoveStop("SM_RUN_GOUP");// PUB.PLC.Move(Device.PLC.Rundirection.Stop, "GOUP:위치확정");
LastCommandTime = DateTime.Now;
}
}
//커버 올림이 완료될때까지 기다린다
if (VAR.BOOL[eVarBool.FLAG_LIMITHIGH] == true)
{
VAR.BOOL[eVarBool.WAIT_COVER_UP] = false;
VAR.BOOL[eVarBool.ITEMON] = true;
PUB.sm.UpdateRunStepSeq();
}
else
{
//경과시간이 10초가 지나면 5초마다 음성을 출력한다
var tsCover = DateTime.Now - CoverControlTime;
if (tsCover.TotalSeconds >= PUB.setting.doorSoundTerm)
{
PUB.Speak(Lang.);
CoverControlTime = DateTime.Now;
////한쪽이 올라가 있는 상태에..
//if (PUB.PLC.GetValueI(arDev.FakePLC.DIName.PINI_LIMIT_LU) == true)
//{
// //모터는 올리는 방향일때에...
// if (PUB.PLC.GetValueO(arDev.FakePLC.DOName.PINO_GUIDEMOTOR_LDIR) == true)
// {
// //모터가 멈춰있을때에..
// if (PUB.PLC.GetValueO(arDev.FakePLC.DOName.PINO_GUIDEMOTOR_LRUN) == false)
// {
// //자동으로 올려준다 (센서가 간혹 인식이 안되어서 .대기하는 경우가 잇음)
// //왼쪽이 올라가 있지 않은 경우
// if (PUB.PLC.GetValueI(arDev.FakePLC.DIName.PINI_LIMIT_LU) == false)
// PUB.PLC.ZMot_Left(arDev.FakePLC.ZMotDirection.Up);
// //오른쪽이 올라가 있지 않은 경우
// if (PUB.PLC.GetValueI(arDev.FakePLC.DIName.PINI_LIMIT_RU) == false)
// PUB.PLC.ZMot_Right(arDev.FakePLC.ZMotDirection.Up);
// }
// }
//}
//if (PUB.PLC.GetValueI(arDev.FakePLC.DIName.PINI_LIMIT_RU) == true)
//{
// //모터는 올리는 방향일때에...
// if (PUB.PLC.GetValueO(arDev.FakePLC.DOName.PINO_GUIDEMOTOR_RDIR) == true)
// {
// //모터가 멈춰있을때에..
// if (PUB.PLC.GetValueO(arDev.FakePLC.DOName.PINO_GUIDEMOTOR_RRUN) == false)
// {
// //자동으로 올려준다 (센서가 간혹 인식이 안되어서 .대기하는 경우가 잇음)
// //왼쪽이 올라가 있지 않은 경우
// if (PUB.PLC.GetValueI(arDev.FakePLC.DIName.PINI_LIMIT_LU) == false)
// PUB.PLC.ZMot_Left(arDev.FakePLC.ZMotDirection.Up);
// //오른쪽이 올라가 있지 않은 경우
// if (PUB.PLC.GetValueI(arDev.FakePLC.DIName.PINI_LIMIT_RU) == false)
// PUB.PLC.ZMot_Right(arDev.FakePLC.ZMotDirection.Up);
// }
// }
//}
}
}
return false;
}
PUB.AddEEDB($"상차작업완료({PUB.Result.TargetPos})");
return true;
}
}
}

View File

@@ -58,74 +58,6 @@ namespace Project
VAR.STR[eVarString.ChargeCheckMsg] = "수동 충전";
}
//현재위치를 모르는 상태라면 이동하여 현재 위치를 찾는다
else if (PUB.Result.CurrentPos == ePosition.NONE)
{
if (PUB.AGV.system1.agv_run == false &&
PUB.AGV.error.Emergency == false &&
PUB.AGV.error.runerror_by_no_magent_line == false)
{
//현재위치를 검색해야함
PUB.sm.ClearRunStep();
PUB.sm.SetNewRunStep(ERunStep.GOHOME);
PUB.sm.SetNewStep(eSMStep.RUN);
PUB.AddEEDB($"READY상태에서 현재위치를 몰라 홈으로 이동");
}
VAR.STR[eVarString.ChargeCheckMsg] = "현재 위치 모름";
}
//else if (PUB.setting.Enable_AutoCharge == true )
//{
// if(bAutoChageOn)
// {
// VAR.BOOL[eVarBool.CHARGE_READY] = true;
// if (PUB.BMS.Current_Level < PUB.setting.ChargeStartLevel)
// {
// //레벨에 의한 자동 충전간격은
// var ts = VAR.TIME.RUN(eVarTime.ChargeTry);
// if (ts.TotalSeconds >= PUB.setting.ChargeRetryTerm)
// {
// VAR.I32[eVarInt32.ChargeWaitSec] = 0;
// VAR.BOOL[eVarBool.CHARGE_WAIT] = false;
// PUB.log.Add($"자동충전레벨시작 {PUB.BMS.Current_Level}/{PUB.setting.ChargeStartLevel}");
// PUB.sm.ClearRunStep();
// PUB.sm.SetNewRunStep(ERunStep.GOCHARGE);
// PUB.sm.SetNewStep(eSMStep.RUN);
// PUB.AddEEDB($"자동충전레벨시작 {PUB.BMS.Current_Level}/{PUB.setting.ChargeStartLevel}");
// }
// else
// {
// VAR.I32[eVarInt32.ChargeWaitSec] = (int)(PUB.setting.ChargeRetryTerm - ts.TotalSeconds);
// VAR.BOOL[eVarBool.CHARGE_WAIT] = true;
// }
// VAR.STR[eVarString.ChargeCheckMsg] = "배터리 충전 레벨 필요";
// }
// else
// {
// //아직 레벨이 높다
// VAR.BOOL[eVarBool.CHARGE_READY] = false;
// VAR.I32[eVarInt32.ChargeWaitSec] = 0;
// VAR.BOOL[eVarBool.CHARGE_WAIT] = false;
// VAR.STR[eVarString.ChargeCheckMsg] = "배터리 레벨상 충전 불필요";
// }
// }
// else
// {
// VAR.BOOL[eVarBool.CHARGE_READY] = false;
// VAR.I32[eVarInt32.ChargeWaitSec] = 0;
// VAR.BOOL[eVarBool.CHARGE_WAIT] = false;
// VAR.STR[eVarString.ChargeCheckMsg] = "충전 불가 조건";
// //충전조건이 맞지 않는다
// }
//}
//else
//{
// VAR.BOOL[eVarBool.CHARGE_READY] = false;
// VAR.I32[eVarInt32.ChargeWaitSec] = 0;
// VAR.BOOL[eVarBool.CHARGE_WAIT] = false;
// //자동충전이 해제된 상태이므로 처리하지 않는다
// VAR.STR[eVarString.ChargeCheckMsg] = "자동 충전 해제 됨";
//}
//대기모드에서는 움직이지 않게 한다
if(PUB.AGV.system1.agv_run)
{

View File

@@ -697,7 +697,7 @@ namespace Project
}
else
{
if (PUB.sm.RunStep == ERunStep.GODOWN)
if (PUB.sm.RunStep == ERunStep.BUFFER_IN)
{
if (PUB.sm.RunStepSeq == 1)
{
@@ -705,7 +705,7 @@ namespace Project
}
else UpdateStatusMessage(String.Format("하차 이동 중 ({0})", PUB.Result.TargetPos), Color.Lime, Color.Black);
}
else if (PUB.sm.RunStep == ERunStep.GOUP)
else if (PUB.sm.RunStep == ERunStep.BUFFER_OUT)
{
if (PUB.sm.RunStepSeq == 1)
{

View File

@@ -53,7 +53,8 @@ namespace Project
PUB.log.AddE($"[{logPrefix}-SetCurrent] 노드정보를 찾을 수 없습니다 RFID:{currTag}");
PUB.XBE.SendError(ENIGProtocol.AGVErrorCode.EmptyNode, $"{currTag}");
return;
}else
}
else
{
PUB.log.AddI($"XBEE:현재위치설정:[{node.RfidId}]{node.NodeId}");
}
@@ -69,6 +70,17 @@ namespace Project
{
var currTag = System.Text.Encoding.Default.GetString(data, 1, data.Length - 1);
var targetNode = PUB._mapNodes.FirstOrDefault(t => t.RfidId == currTag);
//자동상태가아니라면 처리하지 않는다.
if (VAR.BOOL[eVarBool.FLAG_AUTORUN] == false)
{
PUB.log.AddE($"[{logPrefix}-Goto] 자동실행상태가 아닙니다");
PUB.XBE.SendError(ENIGProtocol.AGVErrorCode.ManualMode, $"{currTag}");
}
//목적지
PUB._virtualAGV.TargetNode = targetNode;
if (targetNode == null)
{
PUB.log.AddE($"[{logPrefix}-Goto] 노드정보를 찾을 수 없습니다 RFID:{currTag}");
@@ -76,24 +88,37 @@ namespace Project
return;
}
///출발지
var startNode = PUB._mapNodes.FirstOrDefault(t => t.RfidId == PUB._virtualAGV.CurrentNodeId);
PUB._virtualAGV.StartNode = startNode;
if (startNode == null)
{
PUB.log.AddE($"[{logPrefix}-Goto] 노드정보를 찾을 수 없습니다 RFID:{PUB._virtualAGV.CurrentNodeId}");
PUB.XBE.SendError(ENIGProtocol.AGVErrorCode.EmptyNode, $"{PUB._virtualAGV.CurrentNodeId}");
return;
PUB.log.AddE($"[{logPrefix}-Goto] 시작노드가 없습니다(현재위치 없음) NodeID:{PUB._virtualAGV.CurrentNodeId}");
}
var rltGoto = CalcPath(startNode, targetNode);
if (rltGoto.result == false)
if (startNode != null)
{
PUB.log.AddE($"[{logPrefix}-Goto] {rltGoto.message}");
PUB.XBE.SendError(ENIGProtocol.AGVErrorCode.Goto, rltGoto.message);
return;
//시작위치가 존재한다면 경로를 예측한다.
var rltGoto = CalcPath(startNode, targetNode);
if (rltGoto.result == null)
{
PUB.log.AddE($"[{logPrefix}-Goto] 경로예측실패 {rltGoto.message}");
}
else
{
//경로예측을 화면에 표시해준다.
PUB._virtualAGV.SetPath(rltGoto.result);
var pathWithRfid = rltGoto.result.GetSimplePath().Select(nodeId => PUB._virtualAGV.GetRfidByNodeId(PUB._mapNodes, nodeId)).ToList();
PUB.log.Add($"경로예측결과:{pathWithRfid}");
}
}
//대상이동으로 처리한다.
PUB.sm.SetNewRunStep(StateMachine.ERunStep.GOTO);
//Move to
PUB.log.Add($"[{logPrefix}-Goto] {startNode.RfidId} -> {targetNode.RfidId}");
}
else PUB.log.AddE($"[{logPrefix}-Goto] TagString Lenght Errorr:{data.Length}");
break;
@@ -191,12 +216,12 @@ namespace Project
}
AGVNavigationCore.PathFinding.Planning.AGVPathfinder _advancedPathfinder = null;
(bool result, string message) CalcPath(MapNode startNode, MapNode targetNode)
(AGVNavigationCore.PathFinding.Core.AGVPathResult result, string message) CalcPath(MapNode startNode, MapNode targetNode)
{
var _mapNodes = PUB._mapNodes;
// 시작 RFID가 없으면 AGV 현재 위치로 설정
if (startNode == null || targetNode == null)
return (false, "시작 RFID와 목표 RFID를 선택해주세요.");
return (null, "시작 RFID와 목표 RFID를 선택해주세요.");
//경로계산기확인
if (_advancedPathfinder == null)
@@ -216,6 +241,7 @@ namespace Project
var _simulatorCanvas = PUB._mapCanvas;
_simulatorCanvas.FitToNodes();
string Message = string.Empty;
if (advancedResult.Success)
{
// 도킹 검증이 없는 경우 추가 검증 수행
@@ -234,14 +260,17 @@ namespace Project
// 고급 경로 디버깅 정보 표시
//UpdateAdvancedPathDebugInfo(advancedResult);
return (true, string.Empty);
}
else
{
// 경로 실패시 디버깅 정보 초기화
//_pathDebugLabel.Text = $"경로: 실패 - {advancedResult.ErrorMessage}";
return (false, $"경로를 찾을 수 없습니다:\n{advancedResult.ErrorMessage}");
advancedResult = null;
Message = $"경로를 찾을 수 없습니다:\n{advancedResult.ErrorMessage}";
}
return (advancedResult, Message);
}

View File

@@ -417,12 +417,12 @@ namespace Project
void func_sw_start(bool Prompt = false)
{
if(PUB.sm.Step == eSMStep.SYNC)
if (PUB.sm.Step < eSMStep.IDLE)
{
UTIL.MsgE("초기화 중에는 사용할 수 없습니다\n초기화가 완료 된 후 시도하세요");
return;
}
if (VAR.BOOL[eVarBool.FLAG_AUTORUN] == false) //자동상태가 아니라면
if (VAR.BOOL[eVarBool.FLAG_AUTORUN] == false || PUB.sm.Step != eSMStep.RUN) //자동상태가 아니라면
{
PUB.AGV.AGVErrorReset();
if (Prompt)
@@ -507,136 +507,8 @@ namespace Project
PUB.log.Add("사용자 임의 위치 클릭 : " + e.Item.Title);
switch (e.Item.Position)
{
case ePosition.QA:
//아이템을 가지고 있었으니 하차를 해야한다
if (VAR.BOOL[eVarBool.ITEMON])
{
dlg.setMessage("작업 실행\n" +
"(QA) 위치로 하차를 진행 할까요?\n" +
"대상위치 : QA\n" +
"현재위치 : " + PUB.Result.CurrentPos.ToString());
if (dlg.ShowDialog() == DialogResult.Yes)
{
//아이템이 있으면 하차이고 없으면 상차이다
PUB.sm.ClearRunStep();
PUB.Result.TargetPos = ePosition.QA;
PUB.sm.SetNewRunStep(ERunStep.GODOWN);
PUB.sm.SetNewStep(eSMStep.RUN);
}
}
else
{
dlg.setMessage("작업 실행\n" +
"(QA) 위치로 이동을 실행 할까요?\n" +
"대상위치 : QA\n" +
"현재위치 : " + PUB.Result.CurrentPos.ToString());
if (dlg.ShowDialog() == DialogResult.Yes)
{
//아이템이 있으면 하차이고 없으면 상차이다
PUB.sm.ClearRunStep();
PUB.Result.TargetPos = ePosition.QA;
PUB.sm.SetNewRunStep(ERunStep.GOHOME);
PUB.sm.SetNewStep(eSMStep.RUN);
}
}
break;
case ePosition.QC:
//아이템을 가지고 있었으니 하차를 해야한다
if (VAR.BOOL[eVarBool.ITEMON])
{
dlg.setMessage("작업 실행\n" +
"홈(QC) 위치로 하차를 진행 할까요?\n" +
"대상위치 : QC\n" +
"현재위치 : " + PUB.Result.CurrentPos.ToString());
if (dlg.ShowDialog() == DialogResult.Yes)
{
//아이템이 있으면 하차이고 없으면 상차이다
PUB.sm.ClearRunStep();
PUB.Result.TargetPos = ePosition.QC;
PUB.sm.SetNewRunStep(ERunStep.GODOWN);
PUB.sm.SetNewStep(eSMStep.RUN);
}
}
else
{
dlg.setMessage("작업 실행\n" +
"홈(QC) 위치로 이동을 실행 할까요?\n" +
"대상위치 : QC\n" +
"현재위치 : " + PUB.Result.CurrentPos.ToString());
if (dlg.ShowDialog() == DialogResult.Yes)
{
//아이템이 있으면 하차이고 없으면 상차이다
PUB.sm.ClearRunStep();
PUB.Result.TargetPos = ePosition.QC;
PUB.sm.SetNewRunStep(ERunStep.GOHOME);
PUB.sm.SetNewStep(eSMStep.RUN);
}
}
break;
case ePosition.F1: //FVI영역은 모두 상차이동
dlg.setMessage("작업 실행\n" +
"(상차) 작업을 실행 할까요?\n" +
"대상위치 : FVI-1\n" +
"현재위치 : " + PUB.Result.CurrentPos.ToString());
if (dlg.ShowDialog() == DialogResult.Yes)
{
PUB.Result.TargetPos = ePosition.F1;
PUB.sm.SetNewRunStep(ERunStep.GOUP);
PUB.sm.SetNewStep(eSMStep.RUN);
}
break;
case ePosition.F2:
dlg.setMessage("작업 실행\n" +
"(상차) 작업을 실행 할까요?\n" +
"대상위치 : FVI-2\n" +
"현재위치 : " + PUB.Result.CurrentPos.ToString());
if (dlg.ShowDialog() == DialogResult.Yes)
{
PUB.Result.TargetPos = ePosition.F2;
PUB.sm.SetNewRunStep(ERunStep.GOUP);
PUB.sm.SetNewStep(eSMStep.RUN);
}
break;
case ePosition.F3:
dlg.setMessage("작업 실행\n" +
"(상차) 작업을 실행 할까요?\n" +
"대상위치 : FVI-3\n" +
"현재위치 : " + PUB.Result.CurrentPos.ToString());
if (dlg.ShowDialog() == DialogResult.Yes)
{
PUB.Result.TargetPos = ePosition.F3;
PUB.sm.SetNewRunStep(ERunStep.GOUP);
PUB.sm.SetNewStep(eSMStep.RUN);
//VAR.BOOL[eVarBool.FLAG_AUTORUN] = true;
}
break;
case ePosition.F4:
dlg.setMessage("작업 실행\n" +
"(상차) 작업을 실행 할까요?\n" +
"대상위치 : FVI-4\n" +
"현재위치 : " + PUB.Result.CurrentPos.ToString());
if (dlg.ShowDialog() == DialogResult.Yes)
{
PUB.Result.TargetPos = ePosition.F4;
PUB.sm.SetNewRunStep(ERunStep.GOUP);
PUB.sm.SetNewStep(eSMStep.RUN);
}
break;
}
if (dlg != null) dlg.Dispose();
@@ -705,7 +577,6 @@ namespace Project
}
VAR.BOOL[eVarBool.FLAG_SETUP] = false;// VAR.BOOL[eVarBool.FLAG_SETUP] = false;//VAR.BOOL[eVarBool.FLAG_SETUP] = false;
if (popmsg) PUB.popup.Visible = true;
}

View File

@@ -75,13 +75,13 @@ namespace Project.StateMachine
/// <summary>
/// 상차이동
/// </summary>
GOUP,
BUFFER_OUT,
/// <summary>
/// 하차이동
/// </summary>
GODOWN,
BUFFER_IN,
@@ -100,6 +100,10 @@ namespace Project.StateMachine
/// </summary>
MARKSTROPB,
/// <summary>
/// 에러발생
/// </summary>
ERROR,
}

View File

@@ -283,6 +283,8 @@ namespace Project.StateMachine
private int _runStepSeq = 0;
public int RunStepSeq { get { return _runStepSeq; } }
public Stack<ERunStep> BackupRunStep = new Stack<ERunStep>();
private DateTime runStepStartTime = DateTime.Parse("1982-11-23");
private ERunStep _runstepn = ERunStep.READY;
private ERunStep _runstepo = ERunStep.READY;

View File

@@ -167,16 +167,26 @@ namespace arDev
return AddCommand( cmds);
}
/// <summary>
/// 전송을시도한 시간
/// </summary>
//public Dictionary<String,DateTime> LastCommandTime { get; set; }
/// <summary>
/// 전송에 성공한 명령시간
/// </summary>
//public Dictionary<String, DateTime> LastCommandOKTime { get; set; }
protected bool AddCommand(params string[] cmds)
{
bool ret = true;
ACKData = string.Empty; //회신값 제거
//LastCommandTime.Add(cmd, DateTime.Now);
foreach (var cmdline in cmds)
{
var fullcmd = MakeCheckSum(cmdline);
//commandQueue.Enqueue(fullcmd);
if (WriteData(fullcmd) == false) ret = false;
//else LastCommandOKTime.Add(cmd, DateTime.Now);
System.Threading.Thread.Sleep(1);
}
return ret;

View File

@@ -194,8 +194,20 @@ namespace COMM
CheckGotoTargetSet,
SendGotoCommand,
/// <summary>
/// 마지막으로 멈춤 명령을 전송한 시간
/// </summary>
LastStopCommandTime,
/// <summary>
/// 마지막으로 멈춤(마크스탑) 명령을 전송한 시간
/// </summary>
LastMarkStopCommandTime,
/// <summary>
/// 마지막으로 턴 명령을 전송한 시간
/// </summary>
LastTurnCommandTime,
}
}

Submodule Cs_HMI/SubProject/CommUtil updated: 632b087c5b...ed05439991

Submodule Cs_HMI/SubProject/EnigProtocol updated: 8877cb1a9d...82bca1c90b