feat: Implement RunStep error reporting and refactor charge sequences

- Added RunStepErrorCode to Xbee status protocol and CResult.

- Defined detailed operational error codes in EnumData.cs.

- Updated _SM_RUN_*.cs to report specific error codes before proper error transitions.

- Renamed and refactored charge-related sequence files.
This commit is contained in:
backuppc
2026-01-28 15:41:03 +09:00
parent ffa6c2fb23
commit 5b4fdd33cf
16 changed files with 383 additions and 424 deletions

View File

@@ -304,16 +304,16 @@
<Compile Include="StateMachine\Step\_SM_RUN_BUFFER_OUT.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="StateMachine\Step\_SM_RUN_CHGOFF.cs">
<Compile Include="StateMachine\Step\_SM_RUN_CHARGE_GOFF.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="StateMachine\Step\_SM_RUN_GOTO.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="StateMachine\Step\_SM_RUN_GOCHARGECHECK.cs">
<Compile Include="StateMachine\Step\_SM_RUN_CHARGE_CHECK.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="StateMachine\Step\_SM_RUN_GOCHARGE.cs">
<Compile Include="StateMachine\Step\_SM_RUN_CHARGE_GO.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="StateMachine\Step\_SM_RUN_READY.cs">

View File

@@ -41,6 +41,7 @@ namespace Project
public string Memo;
public eResult ResultCode { get; set; }
public eECode ResultErrorCode;
public eECode RunStepErrorCode { get; set; }
public string ResultMessage { get; set; }
public Boolean isError { get; set; }
public int retry = 0;
@@ -192,6 +193,7 @@ namespace Project
Memo = string.Empty;
isError = false;
ResultCode = eResult.NoError;
RunStepErrorCode = eECode.NOERROR;
ResultMessage = string.Empty;
}

View File

@@ -65,8 +65,20 @@ namespace Project
DION,
NOTALLOWUP,
}
// Operational Errors
CART_EXIST,
MARK_TIMEOUT,
MARK_SENSOR_FAIL,
LIFT_ERROR,
AGV_SPEED_FAIL,
AGV_STOP_FAIL,
PATH_INTEGRITY_FAIL,
TURN_FAIL,
NO_CHARGEPOINT,
NOTSET_CHARGEPOINT,
ALREADY_CHARGE,
}
public enum eResult : byte
{

View File

@@ -213,12 +213,15 @@ namespace Project.Device
/*
Mode[1] : 0=manual, 1=auto
RunSt[1] : 0=stop, 1=run, 2=error
Diection[1] : 0=straight, 1=left, 2=right, 3=markstop
Inposition[1] : 0=off, 1=on : 목적위치에 도달완료 시 설정 이동 이동시 OFF됨
RunStep[1] : (byte)PUB.sm.RunStep
RunStepSeq[1] : (byte)StepMC
MotorDir[1] : 0=F(Forward), 1=B(Backward)
MagnetDir[1] : 0=S(Straight), 1=L(Left), 2=R(Right)
ChargeSt[1] : 0=off, 1=on
CartSt[1] : 0=off, 1=on, 2=unknown
LiftSt[1] : 0=down , 1=up, 2=unknown
LastTag[6] : "000000"
ErrorCode[1] : (byte)PUB.Result.ResultErrorCode
LastTag[4] : "0000"
*/
try
{
@@ -288,6 +291,10 @@ namespace Project.Device
value = 2; // unknown (기본값)
data.Add(value);
// ErrorCode [New RunStepErrorCode]
value = (byte)PUB.Result.RunStepErrorCode;
data.Add(value);
// LastTag
string lastTag = PUB.AGV.data.TagNo.ToString("0000") ?? "0000";
byte[] tagBytes = Encoding.ASCII.GetBytes(lastTag.PadRight(4, '0'));

View File

@@ -102,7 +102,7 @@ namespace Project
switch (PUB.sm.RunStep)
{
case ERunStep.GOHOME:
if (_SM_RUN_GOHOME(runStepisFirst, PUB.sm.GetRunSteptime) == true)
if (_SM_RUN_GOTO_HOME(runStepisFirst, PUB.sm.GetRunSteptime) == true)
{
PUB.log.Add($"홈 이동이 완료되어 준비상태로 전환합니다");
PUB.sm.SetNewRunStep(ERunStep.READY);
@@ -185,7 +185,7 @@ namespace Project
PUB.sm.ResetRunStepSeq();
PUB.log.Add("충전 명령 시작");
}
else if (_SM_RUN_GOCHARGE(runStepisFirst, PUB.sm.GetRunSteptime))
else if (_SM_RUN_CHARGE_GO(runStepisFirst, PUB.sm.GetRunSteptime))
{
PUB.Speak(Lang.);
PUB.sm.SetNewRunStep(ERunStep.CHARGECHECK);
@@ -199,7 +199,7 @@ namespace Project
VAR.TIME.Update(eVarTime.ChargeStart);
LastCommandTime = DateTime.Now;
}
else if (_SM_RUN_GOCHARGECHECK(runStepisFirst, PUB.sm.GetRunSteptime))
else if (_SM_RUN_CHARGE_CHECK(runStepisFirst, PUB.sm.GetRunSteptime))
{
//충전상태가 활성화되었으므로 대기상태로 전환한다
PUB.sm.SetNewRunStep(ERunStep.READY);
@@ -216,7 +216,7 @@ namespace Project
else
{
//충전 상태가 OFF되어야 동작하게한다
if (_SM_RUN_CHGOFF(isFirst, stepTime) == true)
if (_SM_RUN_CHARGE_GOFF(isFirst, stepTime) == true)
{
//충전상태가 활성화되었으므로 대기상태로 전환한다
PUB.sm.ClearRunStep();

View File

@@ -19,7 +19,7 @@ namespace Project
var idx = 1;
//충전 상태가 OFF되어야 동작하게한다
if (_SM_RUN_CHGOFF(isFirst, seqtime) == false) return false;
if (_SM_RUN_CHARGE_GOFF(isFirst, seqtime) == false) return false;
//라이더멈춤이 설정되어있다면 음성으로 알려준다
if (CheckLiderStop() == false) return false;
@@ -83,6 +83,7 @@ namespace Project
PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE($"[{funcname}] 턴 방향 불일치(Current:{turnState}). 우회전 상태에서 좌회전을 시도할 수 없습니다.");
PUB._mapCanvas.SetAlertMessage("Turn 방향 오류");
PUB.Result.RunStepErrorCode = eECode.TURN_FAIL;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
}
else
@@ -120,6 +121,7 @@ namespace Project
PUB.AGV.AGVMoveStop($"[bufferin] {overtime}초이내 턴 감지 안됨");
PUB.log.AddE($"[{funcname}] {overtime}초이내 턴 감지 안됨");
PUB._mapCanvas.SetAlertMessage($"턴 완료 확인 불가(최대:{overtime}초)");
PUB.Result.RunStepErrorCode = eECode.TURN_FAIL;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
return false;
}
@@ -171,6 +173,7 @@ namespace Project
PUB.log.AddE($"[{funcname}] 리프트가 내려가지 않습니다");
PUB.AGV.LiftControl(arDev.Narumi.LiftCommand.STP);
PUB._mapCanvas.SetAlertMessage("리프트가 내려가지 않음");
PUB.Result.RunStepErrorCode = eECode.LIFT_ERROR;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
}
else PUB._mapCanvas.SetAlertMessage($"리프트 하강 확인 중({seqtime.TotalSeconds:N0}/20)");
@@ -209,6 +212,7 @@ namespace Project
PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE($"[{funcname}] AGV속도설정이 완료되지 않았습니다");
PUB._mapCanvas.SetAlertMessage("agv속도설정 실패");
PUB.Result.RunStepErrorCode = eECode.AGV_SPEED_FAIL;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
}
return false;
@@ -230,6 +234,7 @@ namespace Project
PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE($"[{funcname}] AGV이동이 확인되지 않습니다");
PUB._mapCanvas.SetAlertMessage($"[{funcname}] AGV이동이 확인되지 않습니다");
PUB.Result.RunStepErrorCode = eECode.AGV_SPEED_FAIL;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
}
return false;
@@ -255,6 +260,7 @@ namespace Project
PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE($"[{funcname}] MARK STOP신호가 확인되지 않습니다");
PUB._mapCanvas.SetAlertMessage("mark stop 신호 확인 안됨");
PUB.Result.RunStepErrorCode = eECode.MARK_TIMEOUT;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
return false;
}
@@ -274,6 +280,7 @@ namespace Project
PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE($"[{funcname}] AGV가 멈추지 않아 강제종료 합니다");
PUB._mapCanvas.SetAlertMessage("agv가 멈추지 않아 강제 종료");
PUB.Result.RunStepErrorCode = eECode.AGV_STOP_FAIL;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
return false;
}

View File

@@ -17,7 +17,7 @@ namespace Project
var idx = 1;
//충전 상태가 OFF되어야 동작하게한다
if (_SM_RUN_CHGOFF(isFirst, seqtime) == false) return false;
if (_SM_RUN_CHARGE_GOFF(isFirst, seqtime) == false) return false;
//라이더멈춤이 설정되어있다면 음성으로 알려준다
if (CheckLiderStop() == false) return false;
@@ -73,6 +73,7 @@ namespace Project
PUB.log.AddE($"[{funcname}] 리프트가 동작하지 않습니다");
PUB.AGV.LiftControl(arDev.Narumi.LiftCommand.STP);
PUB._mapCanvas.SetAlertMessage("LIft 동작오류");
PUB.Result.RunStepErrorCode = eECode.LIFT_ERROR;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
}
return false;
@@ -98,6 +99,7 @@ namespace Project
PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE($"[{funcname}] AGV속도설정이 완료되지 않았습니다");
PUB._mapCanvas.SetAlertMessage("agv 속도설정실패");
PUB.Result.RunStepErrorCode = eECode.AGV_SPEED_FAIL;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
}
return false;
@@ -125,6 +127,7 @@ namespace Project
PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE($"[{funcname}] AGV 전진 구동이 확인되지 않습니다");
PUB._mapCanvas.SetAlertMessage("agv 전진실패");
PUB.Result.RunStepErrorCode = eECode.AGV_SPEED_FAIL;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
}
return false;
@@ -144,6 +147,7 @@ namespace Project
PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE($"[{funcname}] MARK STOP신호가 확인되지 않습니다");
PUB._mapCanvas.SetAlertMessage("mark stop 신호 확인 안됨");
PUB.Result.RunStepErrorCode = eECode.MARK_TIMEOUT;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
}
return false;
@@ -161,6 +165,7 @@ namespace Project
PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE($"[{funcname}] AGV가 멈추지 않아 강제종료 합니다");
PUB._mapCanvas.SetAlertMessage("agv가 멈추지 않아 강제 종료");
PUB.Result.RunStepErrorCode = eECode.AGV_STOP_FAIL;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
}
return false;
@@ -194,6 +199,7 @@ namespace Project
PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE($"[{funcname}] 턴 방향 불일치(Current:{turnState}). 좌회전 상태에서 우회전을 시도할 수 없습니다.");
PUB._mapCanvas.SetAlertMessage("Turn 방향 오류");
PUB.Result.RunStepErrorCode = eECode.TURN_FAIL;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
}
else
@@ -229,6 +235,7 @@ namespace Project
PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE($"[{funcname}] Turn 구동 실패");
PUB._mapCanvas.SetAlertMessage("Turn 구동 실패");
PUB.Result.RunStepErrorCode = eECode.TURN_FAIL;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
}
return false;
@@ -246,6 +253,7 @@ namespace Project
PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE($"[{funcname}] Turn 완료 실패 (Timeout)");
PUB._mapCanvas.SetAlertMessage("Turn 완료 실패");
PUB.Result.RunStepErrorCode = eECode.TURN_FAIL;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
}
return false;

View File

@@ -12,7 +12,7 @@ namespace Project
public partial class fMain
{
public Boolean _SM_RUN_GOCHARGECHECK(bool isFirst, TimeSpan stepTime)
public Boolean _SM_RUN_CHARGE_CHECK(bool isFirst, TimeSpan stepTime)
{
//충전상태체크를 확인합니다
//10초안에 충전 플래그가 활성화되지 않으면 QC상태로 이동한다

View File

@@ -0,0 +1,131 @@
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 tm_gocharge_command = DateTime.Now;
public Boolean _SM_RUN_CHARGE_GO(bool isFirst, TimeSpan stepTime)
{
var funcname = "GOCHARGE";
if (runStepisFirst)
{
//홈을 찾도록 항상 위치를 지워버리자
PUB.Result.CurrentPos = ePosition.NONE;
}
//HW 연결오류
if (PUB.AGV.IsOpen == false)
{
PUB.Result.SetResultMessage(eResult.Hardware, eECode.AGVCONN, eNextStep.ERROR);
return false;
}
//이미 충전중이라면 바로 완료 처리한다 (사용자 요청)
if (VAR.BOOL[eVarBool.FLAG_CHARGEONA] == true || PUB.AGV.system1.Battery_charging == true ||
VAR.BOOL[eVarBool.FLAG_CHARGEONM] == true)
{
var ermsg = $"현재 충전중이므로 충전시퀀스를 시작할 수 없습니다";
SetRunStepError(ermsg, eECode.ALREADY_CHARGE);
return false;
}
//충전 상태가 OFF되어야 동작하게한다
if (_SM_RUN_CHARGE_GOFF(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.alarmSoundTerm)
{
PUB.Speak(Lang.);
LastSpeakTime = DateTime.Now;
}
return false;
}
var idx = 1;
if (PUB.sm.RunStepSeq == idx++)
{
var targetnode = PUB.FindByRFID(PUB.setting.NodeMAP_RFID_Charger);
if (targetnode == null)
{
var ermsg = ($"충전기 노드가 설정되지 않았습니다");
SetRunStepError(ermsg, eECode.NOTSET_CHARGEPOINT);
return false;
}
//현재위치가 충전기위치이고 마크센서가 감지되었다면 충전기위치로 인지하고
//그렇지 못하면 충전위치가 아니라는 오류를 발생한다
if (PUB.AGV.signal1.mark_sensor == false || PUB._virtualAGV.CurrentNode.Id != targetnode.Id)
{
var ermsg = $"충전기위치가 아니므로 충전을 시작할 수 없습니다(현재위치:{PUB._virtualAGV.CurrentNode.RfidId})";
SetRunStepError(ermsg, eECode.NO_CHARGEPOINT);
return false;
}
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//충전시작 명령을 전송한다
PUB.log.Add($"충전:충전명령전송");
PUB.Speak(Lang.);
PUB.AGV.AGVCharge(PUB.setting.ChargerID, true);
VAR.BOOL[eVarBool.WAIT_CHARGEACK] = true;
LastCommandTime = DateTime.Now;
VAR.BYTE[eVarByte.CHARGE_CMDCNT] = 0;
PUB.sm.UpdateRunStepSeq();
return false;
}
//충전시작명령의 ACK를 체크합니다
else if (PUB.sm.RunStepSeq == idx++)
{
//충전시작 명령을 전송한다
if (PUB.AGV.ACKData.Equals("CBT"))
{
PUB.log.Add($"충전명령 회신 확인");
PUB.sm.UpdateRunStepSeq();
}
else
{
var ts = DateTime.Now - LastCommandTime;
if (ts.TotalSeconds > 3)
{
if (VAR.BYTE[eVarByte.CHARGE_CMDCNT] > 5)
{
PUB.counter.CountChargeE += 1;
PUB.counter.Save();
VAR.BYTE[eVarByte.CHARGE_CMDCNT] = 0;
var ermsg = $"충전명령 재전송 횟수 초과";
SetRunStepError(ermsg, eECode.NO_CHARGEPOINT);
return false;
}
else
{
PUB.logagv.Add($"충전시작명령 재전송");
VAR.BYTE.Add(eVarByte.CHARGE_CMDCNT, 1);
PUB.AGV.AGVCharge(PUB.setting.ChargerID, true);
LastCommandTime = DateTime.Now;
}
}
}
return false;
}
return true;
}
}
}

View File

@@ -12,10 +12,15 @@ namespace Project
public partial class fMain
{
public Boolean _SM_RUN_CHGOFF(bool isFirst, TimeSpan stepTime)
/// <summary>
/// 충전시퀀스를 모두 해제하고 본래위치로 이동한다.
/// </summary>
/// <param name="isFirst"></param>
/// <param name="stepTime"></param>
/// <returns></returns>
public Boolean _SM_RUN_CHARGE_GOFF(bool isFirst, TimeSpan stepTime)
{
//충전중인지 확인한다.
if (VAR.BOOL[eVarBool.FLAG_CHARGEONA] == true || PUB.AGV.system1.Battery_charging == true)
{

View File

@@ -20,7 +20,7 @@ namespace Project
var funcname = PUB.sm.RunStep.ToString();
//충전 상태가 OFF되어야 동작하게한다
if (_SM_RUN_CHGOFF(isFirst, seqTime) == false) return false;
if (_SM_RUN_CHARGE_GOFF(isFirst, seqTime) == false) return false;
//라이더멈춤이 설정되어있다면 음성으로 알려준다
if (CheckLiderStop() == false) return false;
@@ -42,6 +42,7 @@ namespace Project
PUB.AGV.AGVMoveStop(errmsg);
PUB.log.AddE(errmsg);
PUB._mapCanvas.SetAlertMessage(errmsg);
PUB.Result.RunStepErrorCode = eECode.MARK_SENSOR_FAIL;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
}
PUB.sm.UpdateRunStepSeq();
@@ -59,7 +60,9 @@ namespace Project
PUB.AGV.AGVMoveStop(errmsg);
PUB.log.AddE(errmsg);
PUB._mapCanvas.SetAlertMessage(errmsg);
PUB.Result.RunStepErrorCode = eECode.CART_EXIST;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
return false;
}
}
else if (PUB.NextWorkCmd == ENIGProtocol.AGVCommandHE.PickOffEnter)
@@ -71,7 +74,9 @@ namespace Project
PUB.AGV.AGVMoveStop(errmsg);
PUB.log.AddE(errmsg);
PUB._mapCanvas.SetAlertMessage(errmsg);
PUB.Result.RunStepErrorCode = eECode.CART_EXIST;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
return false;
}
}
else
@@ -80,7 +85,9 @@ namespace Project
PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE(errmsg);
PUB._mapCanvas.SetAlertMessage(errmsg);
PUB.Result.RunStepErrorCode = eECode.NOMODELV; // Unknown work command
PUB.sm.SetNewRunStep(ERunStep.ERROR);
return false;
}
PUB.sm.UpdateRunStepSeq();
@@ -107,8 +114,10 @@ namespace Project
PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE(errmsg);
PUB._mapCanvas.SetAlertMessage(errmsg);
PUB.Result.RunStepErrorCode = eECode.LIFT_ERROR;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
}
return false;
}
else
{
@@ -135,6 +144,7 @@ namespace Project
PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE("AGV속도설정이 완료되지 않았습니다");
PUB._mapCanvas.SetAlertMessage("agv 속도 설정 실패");
PUB.Result.RunStepErrorCode = eECode.AGV_SPEED_FAIL;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
}
return false;
@@ -162,6 +172,7 @@ namespace Project
PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE("AGV속도설정이 완료되지 않았습니다");
PUB._mapCanvas.SetAlertMessage("agv 속도 설정 실패");
PUB.Result.RunStepErrorCode = eECode.AGV_SPEED_FAIL;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
}
return false;
@@ -181,6 +192,7 @@ namespace Project
PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE("MARK STOP신호가 확인되지 않습니다");
PUB._mapCanvas.SetAlertMessage("mark stop 신호 확인 불가");
PUB.Result.RunStepErrorCode = eECode.MARK_TIMEOUT;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
}
return false;
@@ -198,6 +210,7 @@ namespace Project
PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE("AGV가 멈추지 않아 강제종료 합니다");
PUB._mapCanvas.SetAlertMessage("agv 가 멈추지 않아 강제 종료");
PUB.Result.RunStepErrorCode = eECode.AGV_STOP_FAIL;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
}
return false;
@@ -216,6 +229,7 @@ namespace Project
PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE("마크센서가 감지되지 않았습니다");
PUB._mapCanvas.SetAlertMessage("마크센서가 감지되지 않았습니다");
PUB.Result.RunStepErrorCode = eECode.MARK_SENSOR_FAIL;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
}
return false;

View File

@@ -20,7 +20,7 @@ namespace Project
var funcname = PUB.sm.RunStep.ToString();
//충전 상태가 OFF되어야 동작하게한다
if (_SM_RUN_CHGOFF(isFirst, seqTime) == false) return false;
if (_SM_RUN_CHARGE_GOFF(isFirst, seqTime) == false) return false;
//라이더멈춤이 설정되어있다면 음성으로 알려준다
if (CheckLiderStop() == false) return false;
@@ -69,6 +69,7 @@ namespace Project
PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE(errmsg);
PUB._mapCanvas.SetAlertMessage(errmsg);
PUB.Result.RunStepErrorCode = eECode.LIFT_ERROR;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
}
return false;
@@ -96,6 +97,7 @@ namespace Project
PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE($"[{funcname}] AGV속도설정이 완료되지 않았습니다");
PUB._mapCanvas.SetAlertMessage("agv 속도 설정 실패");
PUB.Result.RunStepErrorCode = eECode.AGV_SPEED_FAIL;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
}
return false;
@@ -122,6 +124,7 @@ namespace Project
PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE("AGV속도설정이 완료되지 않았습니다");
PUB._mapCanvas.SetAlertMessage("agv 속도 설정 실패");
PUB.Result.RunStepErrorCode = eECode.AGV_SPEED_FAIL;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
}
return false;
@@ -141,6 +144,7 @@ namespace Project
PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE("MARK STOP신호가 확인되지 않습니다");
PUB._mapCanvas.SetAlertMessage("mark stop 신호 확인 불가");
PUB.Result.RunStepErrorCode = eECode.MARK_TIMEOUT;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
}
return false;
@@ -158,6 +162,7 @@ namespace Project
PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE("AGV가 멈추지 않아 강제종료 합니다");
PUB._mapCanvas.SetAlertMessage("agv 가 멈추지 않아 강제 종료");
PUB.Result.RunStepErrorCode = eECode.AGV_STOP_FAIL;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
}
return false;
@@ -175,6 +180,7 @@ namespace Project
PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE("마크센서가 감지되지 않았습니다");
PUB._mapCanvas.SetAlertMessage("마크센서가 감지되지 않았습니다");
PUB.Result.RunStepErrorCode = eECode.MARK_SENSOR_FAIL;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
}
return false;

View File

@@ -1,249 +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
{
DateTime tm_gocharge_command = DateTime.Now;
public Boolean _SM_RUN_GOCHARGE(bool isFirst, TimeSpan stepTime)
{
var funcname = "GOCHARGE";
if (runStepisFirst)
{
//홈을 찾도록 항상 위치를 지워버리자
PUB.Result.CurrentPos = ePosition.NONE;
}
//HW 연결오류
if (PUB.AGV.IsOpen == false)
{
PUB.Result.SetResultMessage(eResult.Hardware, eECode.AGVCONN, eNextStep.ERROR);
return false;
}
//이미 충전중이라면 바로 완료 처리한다 (사용자 요청)
if (VAR.BOOL[eVarBool.FLAG_CHARGEONA] == true || PUB.AGV.system1.Battery_charging == true)
{
if (isFirst)
{
PUB.log.Add("이미 충전 중이므로 충전 시퀀스를 종료하고 준비 상태로 전환합니다.");
PUB.sm.SetNewRunStep(ERunStep.READY);
}
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.alarmSoundTerm)
{
PUB.Speak(Lang.);
LastSpeakTime = DateTime.Now;
}
return false;
}
//충전작업진행상태 //220629
//if (PUB.flag.get(EFlag.FLAG_GO_CHAGER_TEMP) == false)
//{
// PUB.flag.set(EFlag.FLAG_GO_CHAGER_TEMP, true);
//}
var idx = 1;
if (PUB.sm.RunStepSeq == idx++)
{
var targetnode = PUB.FindByRFID(PUB.setting.NodeMAP_RFID_Charger);
if (targetnode == null)
{
PUB.log.AddE($"충전기 노드가 설정되지 않았습니다");
PUB.sm.SetNewRunStep(ERunStep.READY);
return false;
}
//충전기로 대상을 설정한다
PUB._virtualAGV.TargetNode = targetnode;
VAR.TIME.Update(eVarTime.ChargeSearch);
PUB.sm.UpdateRunStepSeq();
PUB.log.Add($"충전기 위치로 이동 목표:{targetnode.RfidId}");
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//모션 전후진 제어
if (UpdateMotionPositionForCharger("GOCHARGE #1") == true)
{
PUB.log.Add($"충전기 목표위치 이동 완료");
PUB.sm.UpdateRunStepSeq();
}
else
{
//아직 충진기 위치를 찾지 못했다
var ts = VAR.TIME.RUN(eVarTime.ChargeSearch);
if (ts.TotalSeconds > PUB.setting.ChargeSearchTime)
{
PUB.log.Add($"충전:충전검색시간초과({ts.TotalSeconds}/{PUB.setting.ChargeSearchTime})");
PUB.Speak(Lang.);
VAR.BOOL[eVarBool.WAIT_CHARGEACK] = false;
PUB.sm.ClearRunStep();
PUB.sm.SetNewRunStep(ERunStep.CHARGEOFF);
PUB.sm.SetNewStep(eSMStep.RUN);
PUB.counter.CountChargeE += 1;
PUB.counter.Save();
}
}
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
PUB.log.Add($"충전:충전기 검색을 위한 전진시작");
PUB.Speak(Lang.);
var ret = PUB.AGV.AGVMoveSet(new arDev.Narumi.BunkiData
{
Speed = arDev.Narumi.eMoveSpd.Low,
Bunki = arDev.Narumi.eBunki.Strate,
Direction = arDev.Narumi.eMoveDir.Forward,
PBSSensor = 1,
});
if(ret != arDev.eNarumiCommandResult.Success)
{
if(ret >= arDev.eNarumiCommandResult.Error)
{
PUB.log.AddE($"[{funcname}] AGV속도설정 실패");
PUB.AGV.AGVMoveStop("err");
PUB._mapCanvas.SetAlertMessage("agv 속더 설정 실패");
PUB.sm.SetNewRunStep(ERunStep.ERROR);
}
return false;
}
PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Forward);
VAR.TIME.Update(eVarTime.ChargeSearch);
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
if (PUB.AGV.system1.agv_run)
{
PUB.log.Add($"충전:AGV기동확인으로 마크정지신호설정");
PUB.Speak(Lang.);
PUB.AGV.AGVMoveStop("SM_RUN_GOCHARGE", arDev.Narumi.eStopOpt.MarkStop);
VAR.TIME.Update(eVarTime.ChargeSearch);
PUB.sm.UpdateRunStepSeq();
}
else
{
if (VAR.TIME.RUN(eVarTime.ChargeSearch).TotalSeconds > 5)
{
//5초이상 이곳에서 대기한다면 다시 돌려준다
PUB.sm.UpdateRunStepSeq(-1);
PUB.log.Add($"충전:AGV기동확인 안됨, 롤백 다시 이동할 수 있게 함");
}
}
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
if (PUB.AGV.system1.agv_stop)
{
PUB.log.Add($"충전:충전기멈춤확인 다음진행");
PUB.logagv.Add("충전 위치에 멈췄습니다");
PUB.sm.UpdateRunStepSeq();
}
else
{
if (VAR.TIME.RUN(eVarTime.ChargeSearch).TotalSeconds > 60)
{
PUB.log.Add($"충전:멈춤 확인 60초 초과로 전체 취소함");
PUB.sm.ClearRunStep();
PUB.sm.SetNewRunStep(ERunStep.CHARGEOFF);
PUB.sm.SetNewStep(eSMStep.RUN);
PUB.counter.CountChargeE += 1;
PUB.counter.Save();
VAR.BOOL[eVarBool.WAIT_CHARGEACK] = false;
PUB.AddEEDB("충전실패로 인한 취소");
}
}
return false;
}
//충전기위치까지 왔다
else if (PUB.sm.RunStepSeq == idx++)
{
//센서가 안정화되기 위한 5초간 기다려준다
if (stepTime.TotalSeconds <= 3) return false;
PUB.log.Add($"충전:충전기위치정지완료");
PUB.Result.CurrentPos = ePosition.CHARGE; //현재위치를 충전기로 한다
PUB.Result.TargetPos = ePosition.CHARGE;
PUB.Result.CurrentPosCW = "1";
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//충전시작 명령을 전송한다
PUB.log.Add($"충전:충전명령전송");
PUB.Speak(Lang.);
PUB.AGV.AGVCharge(PUB.setting.ChargerID, true);
VAR.BOOL[eVarBool.WAIT_CHARGEACK] = true;
LastCommandTime = DateTime.Now;
VAR.BYTE[eVarByte.CHARGE_CMDCNT] = 0;
PUB.sm.UpdateRunStepSeq();
return false;
}
//충전시작명령의 ACK를 체크합니다
else if (PUB.sm.RunStepSeq == idx++)
{
//충전시작 명령을 전송한다
if (PUB.AGV.ACKData.Equals("CBT"))
{
PUB.log.Add($"충전명령 회신 확인");
PUB.sm.UpdateRunStepSeq();
}
else
{
var ts = DateTime.Now - LastCommandTime;
if (ts.TotalSeconds > 3)
{
if (VAR.BYTE[eVarByte.CHARGE_CMDCNT] > 5)
{
PUB.logagv.Add($"충전명령 재전송 5회초과로 전체 취소함");
PUB.sm.ClearRunStep();
PUB.sm.SetNewRunStep(ERunStep.CHARGEOFF);
PUB.sm.SetNewStep(eSMStep.RUN);
PUB.counter.CountChargeE += 1;
PUB.counter.Save();
VAR.BOOL[eVarBool.WAIT_CHARGEACK] = false;
PUB.AddEEDB("충전실패로 인한 취소");
}
else
{
PUB.logagv.Add($"충전시작명령 재전송");
VAR.BYTE.Add(eVarByte.CHARGE_CMDCNT, 1);
PUB.AGV.AGVCharge(PUB.setting.ChargerID, true);
LastCommandTime = DateTime.Now;
}
}
}
return false;
}
return true;
}
}
}

View File

@@ -20,7 +20,7 @@ namespace Project
var funcName = "_SM_RUN_GOTO";
//충전 상태가 OFF되어야 동작하게한다
if (_SM_RUN_CHGOFF(isFirst, stepTime) == false)
if (_SM_RUN_CHARGE_GOFF(isFirst, stepTime) == false)
return false;
//최초시작이라면 시간변수 초기화

View File

@@ -11,7 +11,7 @@ namespace Project
{
public partial class fMain
{
public Boolean _SM_RUN_GOHOME(bool isFirst, TimeSpan stepTime)
public Boolean _SM_RUN_GOTO_HOME(bool isFirst, TimeSpan stepTime)
{
var funcName = "_SM_RUN_GOHOME";
if (runStepisFirst)
@@ -27,7 +27,7 @@ namespace Project
}
//충전 상태가 OFF되어야 동작하게한다
if (_SM_RUN_CHGOFF(isFirst, stepTime) == false)
if (_SM_RUN_CHARGE_GOFF(isFirst, stepTime) == false)
return false;
//라이더멈춤이 설정되어있다면 음성으로 알려준다 200409

View File

@@ -38,6 +38,21 @@ namespace Project
return true;
}
/// <summary>
/// 실행스텝을 오류로 전환합니다.
/// 로그메세지(에러)가 추가됩니다.
/// 맵캔버스오류경고메세지가 설정됩니다
/// </summary>
/// <param name="ermsg"></param>
/// <param name="ecode"></param>
public void SetRunStepError(string ermsg, eECode ecode)
{
PUB.log.AddE(ermsg);
PUB._mapCanvas.SetAlertMessage(ermsg);
PUB.Result.RunStepErrorCode = ecode;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
}
/// <summary>
/// 라이더멈춤이 설정되어있다면 음성으로 알려준다
/// </summary>
@@ -138,6 +153,7 @@ namespace Project
{
PUB.log.AddE($"연속 경로 무결성 오류로 인해 중지 합니다");
PUB._mapCanvas.SetAlertMessage($"연속 경로 무결성 오류로 인해 중지 합니다");
PUB.Result.RunStepErrorCode = eECode.PATH_INTEGRITY_FAIL;
PUB.sm.SetNewRunStep(ERunStep.ERROR);
}
return false;