This commit is contained in:
chi
2025-04-24 11:51:55 +09:00
parent 0a93a54a6f
commit f71b963851
62 changed files with 1748 additions and 4105 deletions

View File

@@ -0,0 +1,145 @@
using System;
using System.Collections.Generic;
namespace Project.StateMachine
{
public class AGVPosition
{
public enum PositionType
{
None,
Tops1,
Sstron1,
Sstron2,
Path
}
public class Position
{
public int RFID { get; set; }
public PositionType Type { get; set; }
public string Name { get; set; }
public string Direction { get; set; }
public List<int> ConnectedPositions { get; set; }
public Position(int rfid, PositionType type, string name, string direction)
{
RFID = rfid;
Type = type;
Name = name;
Direction = direction;
ConnectedPositions = new List<int>();
}
}
private Dictionary<int, Position> positionMap;
private static AGVPosition instance;
private AGVPosition()
{
positionMap = new Dictionary<int, Position>();
InitializePositions();
}
public static AGVPosition Instance
{
get
{
if (instance == null)
{
instance = new AGVPosition();
}
return instance;
}
}
private void InitializePositions()
{
// Tops 1 관련 위치
AddPosition(100, PositionType.Tops1, "Tops 1", "0");
AddPosition(101, PositionType.Path, "Tops1-Sstron1 Path 1", "0");
AddPosition(102, PositionType.Path, "Tops1-Sstron1 Path 2", "0");
// Sstron 1 관련 위치
AddPosition(200, PositionType.Sstron1, "Sstron 1", "0");
AddPosition(201, PositionType.Path, "Sstron1-Sstron2 Path 1", "0");
AddPosition(202, PositionType.Path, "Sstron1-Sstron2 Path 2", "0");
// Sstron 2 관련 위치
AddPosition(300, PositionType.Sstron2, "Sstron 2", "0");
// 경로 연결 설정
ConnectPositions(100, 101);
ConnectPositions(101, 102);
ConnectPositions(102, 200);
ConnectPositions(200, 201);
ConnectPositions(201, 202);
ConnectPositions(202, 300);
}
private void AddPosition(int rfid, PositionType type, string name, string direction)
{
positionMap[rfid] = new Position(rfid, type, name, direction);
}
private void ConnectPositions(int pos1, int pos2)
{
if (positionMap.ContainsKey(pos1) && positionMap.ContainsKey(pos2))
{
positionMap[pos1].ConnectedPositions.Add(pos2);
positionMap[pos2].ConnectedPositions.Add(pos1);
}
}
public Position GetPosition(int rfid)
{
if (positionMap.ContainsKey(rfid))
{
return positionMap[rfid];
}
return null;
}
public List<int> FindPath(int startRfid, int endRfid)
{
if (!positionMap.ContainsKey(startRfid) || !positionMap.ContainsKey(endRfid))
{
return null;
}
var visited = new HashSet<int>();
var path = new List<int>();
if (FindPathDFS(startRfid, endRfid, visited, path))
{
return path;
}
return null;
}
private bool FindPathDFS(int current, int end, HashSet<int> visited, List<int> path)
{
if (current == end)
{
path.Add(current);
return true;
}
visited.Add(current);
path.Add(current);
foreach (var next in positionMap[current].ConnectedPositions)
{
if (!visited.Contains(next))
{
if (FindPathDFS(next, end, visited, path))
{
return true;
}
}
}
path.RemoveAt(path.Count - 1);
return false;
}
}
}

View File

@@ -0,0 +1,107 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace Project.StateMachine
{
public class AGVProtocolHandler
{
private static AGVProtocolHandler instance;
private AGVStateManager stateManager;
private AGVProtocolHandler()
{
stateManager = AGVStateManager.Instance;
}
public static AGVProtocolHandler Instance
{
get
{
if (instance == null)
{
instance = new AGVProtocolHandler();
}
return instance;
}
}
public bool ProcessProtocol(string protocol)
{
try
{
// 프로토콜 형식: COMMAND:DESTINATION
var parts = protocol.Split(':');
if (parts.Length != 2)
{
return false;
}
var command = parts[0].ToUpper();
var destination = parts[1].ToUpper();
switch (command)
{
case "MOVE_TO":
return HandleMoveToCommand(destination);
case "PICKUP":
return HandlePickupCommand(destination);
case "DROPOFF":
return HandleDropoffCommand(destination);
case "EMERGENCY_STOP":
return HandleEmergencyStopCommand();
default:
return false;
}
}
catch (Exception)
{
return false;
}
}
private bool HandleMoveToCommand(string destination)
{
switch (destination)
{
case "T1":
return stateManager.ProcessCommand(AGVStateManager.AGVCommand.MoveToTops1);
case "S1":
return stateManager.ProcessCommand(AGVStateManager.AGVCommand.MoveToSstron1);
case "S2":
return stateManager.ProcessCommand(AGVStateManager.AGVCommand.MoveToSstron2);
default:
return false;
}
}
private bool HandlePickupCommand(string destination)
{
if (destination != "T1")
{
return false;
}
return stateManager.ProcessCommand(AGVStateManager.AGVCommand.PickupCart);
}
private bool HandleDropoffCommand(string destination)
{
if (destination != "S1" && destination != "S2")
{
return false;
}
return stateManager.ProcessCommand(AGVStateManager.AGVCommand.DropoffCart);
}
private bool HandleEmergencyStopCommand()
{
return stateManager.ProcessCommand(AGVStateManager.AGVCommand.EmergencyStop);
}
public string GetCurrentStatus()
{
var state = stateManager.CurrentState;
return $"Current State: {state}";
}
}
}

View File

@@ -0,0 +1,159 @@
using System;
using System.Collections.Generic;
namespace Project.StateMachine
{
public class AGVStateManager
{
public enum AGVState
{
Idle,
Moving,
Loading,
Unloading,
Error
}
public enum AGVCommand
{
MoveToTops1,
MoveToSstron1,
MoveToSstron2,
PickupCart,
DropoffCart,
EmergencyStop
}
private AGVState currentState;
private static AGVStateManager instance;
private AGVPosition positionManager;
private AGVStateManager()
{
currentState = AGVState.Idle;
positionManager = AGVPosition.Instance;
}
public static AGVStateManager Instance
{
get
{
if (instance == null)
{
instance = new AGVStateManager();
}
return instance;
}
}
public AGVState CurrentState
{
get { return currentState; }
}
public bool ProcessCommand(AGVCommand command)
{
switch (command)
{
case AGVCommand.MoveToTops1:
return HandleMoveCommand(100); // Tops 1 RFID
case AGVCommand.MoveToSstron1:
return HandleMoveCommand(200); // Sstron 1 RFID
case AGVCommand.MoveToSstron2:
return HandleMoveCommand(300); // Sstron 2 RFID
case AGVCommand.PickupCart:
return HandlePickupCommand();
case AGVCommand.DropoffCart:
return HandleDropoffCommand();
case AGVCommand.EmergencyStop:
return HandleEmergencyStop();
default:
return false;
}
}
private bool HandleMoveCommand(int targetRfid)
{
if (currentState != AGVState.Idle && currentState != AGVState.Moving)
{
return false;
}
// 현재 위치에서 목표 위치까지의 경로를 찾음
var currentRfid = GetCurrentRfid(); // 실제 구현에서는 현재 RFID 값을 가져와야 함
var path = positionManager.FindPath(currentRfid, targetRfid);
if (path == null)
{
return false;
}
currentState = AGVState.Moving;
// 경로를 따라 이동하는 로직 구현
return true;
}
private bool HandlePickupCommand()
{
if (currentState != AGVState.Moving)
{
return false;
}
// 현재 위치가 Tops 1인지 확인
var currentRfid = GetCurrentRfid();
var position = positionManager.GetPosition(currentRfid);
if (position == null || position.Type != AGVPosition.PositionType.Tops1)
{
return false;
}
currentState = AGVState.Loading;
// 카트 적재 로직 구현
return true;
}
private bool HandleDropoffCommand()
{
if (currentState != AGVState.Moving)
{
return false;
}
// 현재 위치가 Sstron 1 또는 Sstron 2인지 확인
var currentRfid = GetCurrentRfid();
var position = positionManager.GetPosition(currentRfid);
if (position == null ||
(position.Type != AGVPosition.PositionType.Sstron1 &&
position.Type != AGVPosition.PositionType.Sstron2))
{
return false;
}
currentState = AGVState.Unloading;
// 카트 하역 로직 구현
return true;
}
private bool HandleEmergencyStop()
{
currentState = AGVState.Error;
// 비상 정지 로직 구현
return true;
}
private int GetCurrentRfid()
{
// 실제 구현에서는 AGV의 현재 RFID 값을 반환해야 함
// 예시로 100(Tops 1)을 반환
return 100;
}
public void UpdateState(AGVState newState)
{
currentState = newState;
}
}
}

View File

@@ -5,6 +5,7 @@ using System.Linq;
using System.Text;
using static Project.StateMachine;
using COMM;
using AR;
namespace Project
{
@@ -15,6 +16,7 @@ namespace Project
DateTime LastCommandTime = DateTime.Now;
DateTime LastCommandTimeNextStop = DateTime.Now;
bool runStepisFirst = false;
private void _SM_RUN(Boolean isFirst, TimeSpan stepTime)
{
//중단기능이 동작이라면 처리하지 않는다.
@@ -62,9 +64,9 @@ namespace Project
if (isFirst)
{
if (PUB.sm.RunStep == ERunStep.READY)
VAR.TIME.Set(eVarTime.ReadyStart);
VAR.TIME.Update(eVarTime.ReadyStart);
else
VAR.TIME.Set(eVarTime.RunStart);
VAR.TIME.Update(eVarTime.RunStart);
}
switch (PUB.sm.RunStep)
@@ -95,7 +97,7 @@ namespace Project
case ERunStep.CHARGECHECK: //충전중
if (runStepisFirst)
{
VAR.TIME.Set(eVarTime.ChargeStart);
VAR.TIME.Update(eVarTime.ChargeStart);
LastCommandTime = DateTime.Now;
}
else if (_SM_RUN_GOCHARGECHECK(runStepisFirst, PUB.sm.GetRunSteptime))
@@ -109,7 +111,7 @@ namespace Project
case ERunStep.CHARGEOFF:
if (runStepisFirst)
{
VAR.TIME.Set(eVarTime.ChargeEnd);
VAR.TIME.Update(eVarTime.ChargeEnd);
LastCommandTime = DateTime.Now;
}
else
@@ -160,8 +162,8 @@ namespace Project
if (_SM_RUN_GODOWN(runStepisFirst, PUB.sm.GetRunSteptime))
{
PUB.Speak(Lang.);
VAR.TIME.Set(eVarTime.ChargeTry);
PUB.PLC.ZMot(arDev.FakePLC.ZMotDirection.Down);// (Device.PLC.ZMotDirection.Down); //하차작업이 완료되면 커버를 내려서 바로 작업할 수 있게 한다.
VAR.TIME.Update(eVarTime.ChargeTry);
PUB.AGV.LiftControl(arDev.Narumi.LiftCommand.DN);// (Device.PLC.ZMotDirection.Down); //하차작업이 완료되면 커버를 내려서 바로 작업할 수 있게 한다.
//230601
//if (PUB.Result != null && PUB.sm != null)
@@ -200,7 +202,7 @@ namespace Project
// EEMStatus.AddEEDBSQL(PUB.sm.Step, PUB.sm.RunStep.ToString(), PUB.Result.TargetPos.ToString());
PUB.Speak(Lang.);
VAR.TIME.Set(eVarTime.ChargeTry);
VAR.TIME.Update(eVarTime.ChargeTry);
PUB.sm.SetNewRunStep(ERunStep.READY); //대기상태로 전환한다
return;
}
@@ -213,6 +215,7 @@ namespace Project
return true;
}
void CheckAGVMoveTo(eGoDir dir)
{
//계속내려간다
@@ -233,15 +236,12 @@ namespace Project
{
PUB.log.Add($"마크정지를 해제하기 위해 장비를 멈춥니다");
}
//이동해야하는데 마크 스탑이 되어있다면 일단 멈춘다
}
else
{
//움직이지 않으므로 전진하도록 한다
PUB.log.Add($"AGV 기동 방향(DOWN):{dir}");
PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Forward);//PUB.PLC.Move(Device.PLC.Rundirection.Backward, "UpdateMotionPosition(" + sender + ")");
PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Forward);
}
LastCommandTime = DateTime.Now;
}
@@ -266,8 +266,7 @@ namespace Project
else
{
PUB.log.Add($"AGV 기동 방향(UP):{dir}");
PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Backward);//PUB.PLC.Move(Device.PLC.Rundirection.Backward, "UpdateMotionPosition(" + sender + ")");
PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Backward);
}
LastCommandTime = DateTime.Now;
}
@@ -546,5 +545,7 @@ namespace Project
return false;
}
}//cvass
}

View File

@@ -5,6 +5,7 @@ using System.Linq;
using System.Text;
using static Project.StateMachine;
using COMM;
using AR;
namespace Project
{
@@ -18,7 +19,7 @@ namespace Project
{
if (isFirst)
{
VAR.TIME.Set(eVarTime.ChargeEnd);
VAR.TIME.Update(eVarTime.ChargeEnd);
if (VAR.BOOL[eVarBool.FLAG_CHARGEONA])
{
PUB.Speak(Lang.);
@@ -44,7 +45,7 @@ namespace Project
{
PUB.log.Add("충전 해제 전송");
PUB.AGV.AGVCharge(PUB.setting.ChargerID, false);
VAR.TIME.Set(eVarTime.SendChargeOff);
VAR.TIME.Update(eVarTime.SendChargeOff);
}
}

View File

@@ -5,6 +5,7 @@ using System.Linq;
using System.Text;
using static Project.StateMachine;
using COMM;
using AR;
namespace Project
{
@@ -26,11 +27,7 @@ namespace Project
PUB.Result.SetResultMessage(eResult.Hardware, eECode.AGVCONN, eNextStep.ERROR);
return false;
}
else if (PUB.PLC.IsValid == false)
{
PUB.Result.SetResultMessage(eResult.Hardware, eECode.PLCCONN, eNextStep.ERROR);
return false;
}
//충전 상태가 OFF되어야 동작하게한다
if (_SM_RUN_CHGOFF(isFirst, stepTime) == false)
@@ -68,7 +65,7 @@ namespace Project
{
PUB.Speak(Lang.);
PUB.Result.TargetPos = ePosition.QC;
VAR.TIME.Set(eVarTime.ChargeSearch);
VAR.TIME.Update(eVarTime.ChargeSearch);
PUB.sm.UpdateRunStepSeq();
PUB.log.Add($"충전:대상위치 QC 시작");
return false;
@@ -114,7 +111,7 @@ namespace Project
});
PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Forward);
//PUB.Result.TargetPos = ePosition.CHARGE;
VAR.TIME.Set(eVarTime.ChargeSearch);
VAR.TIME.Update(eVarTime.ChargeSearch);
}
else if (PUB.setting.chargerpos == 2) //up search
{
@@ -129,7 +126,7 @@ namespace Project
});
PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Backward);
//PUB.Result.TargetPos = ePosition.CHARGE;
VAR.TIME.Set(eVarTime.ChargeSearch);
VAR.TIME.Update(eVarTime.ChargeSearch);
}
else
{
@@ -148,7 +145,7 @@ namespace Project
PUB.log.Add($"충전:AGV기동확인으로 마크정지신호설정");
PUB.Speak(Lang.);
PUB.AGV.AGVMoveStop("SM_RUN_GOCHARGE", arDev.Narumi.eStopOpt.MarkStop);
VAR.TIME.Set(eVarTime.ChargeSearch);
VAR.TIME.Update(eVarTime.ChargeSearch);
PUB.sm.UpdateRunStepSeq();
}
else
@@ -163,7 +160,7 @@ namespace Project
}
else
{
VAR.TIME.Set(eVarTime.ChargeSearch);
VAR.TIME.Update(eVarTime.ChargeSearch);
PUB.sm.UpdateRunStepSeq();
}

View File

@@ -5,6 +5,7 @@ using System.Linq;
using System.Text;
using static Project.StateMachine;
using COMM;
using AR;
namespace Project
{

View File

@@ -5,6 +5,7 @@ using System.Linq;
using System.Text;
using static Project.StateMachine;
using COMM;
using AR;
namespace Project
{
@@ -25,11 +26,7 @@ namespace Project
PUB.Result.SetResultMessage(eResult.Hardware, eECode.AGVCONN, eNextStep.ERROR);
return false;
}
else if (PUB.PLC.IsValid == false)
{
PUB.Result.SetResultMessage(eResult.Hardware, eECode.PLCCONN, eNextStep.ERROR);
return false;
}
//충전 상태가 OFF되어야 동작하게한다
if (_SM_RUN_CHGOFF(isFirst, stepTime) == false)
@@ -124,19 +121,19 @@ namespace Project
CoverControlTime = DateTime.Now;
UpdateProgressStatus(stepTime.TotalSeconds, 5, Lang.);
VAR.BOOL[eVarBool.WAIT_COVER_DOWN] = true;
PUB.PLC.ZMot(arDev.FakePLC.ZMotDirection.Down);//
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
//if (PUB.PLC.IsLimitDn() == true)
//{
// VAR.BOOL[eVarBool.WAIT_COVER_DOWN] = false;
// PUB.sm.UpdateRunStepSeq();
//}
//else
{
//경과시간이 10초가 지나면 5초마다 음성을 출력한다
var tsCover = DateTime.Now - CoverControlTime;
@@ -177,39 +174,39 @@ namespace Project
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) == 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_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);
}
}
}
// //왼쪽이 올라가 있지 않은 경우
// if (PUB.PLC.GetValueI(arDev.FakePLC.DIName.PINI_LIMIT_RU) == false)
// PUB.PLC.ZMot_Right(arDev.FakePLC.ZMotDirection.Up);
// }
// }
//}
}

View File

@@ -5,6 +5,7 @@ using System.Linq;
using System.Text;
using static Project.StateMachine;
using COMM;
using AR;
namespace Project
{
@@ -32,11 +33,7 @@ namespace Project
PUB.Result.SetResultMessage(eResult.Hardware, eECode.AGVCONN, eNextStep.ERROR);
return false;
}
else if (PUB.PLC.IsValid == false)
{
PUB.Result.SetResultMessage(eResult.Hardware, eECode.PLCCONN, eNextStep.ERROR);
return false;
}
//충전 상태가 OFF되어야 동작하게한다
if (_SM_RUN_CHGOFF(isFirst, stepTime) == false)

View File

@@ -5,6 +5,7 @@ using System.Linq;
using System.Text;
using static Project.StateMachine;
using COMM;
using AR;
namespace Project
{
@@ -25,12 +26,6 @@ namespace Project
PUB.Result.SetResultMessage(eResult.Hardware, eECode.AGVCONN, eNextStep.ERROR);
return false;
}
else if (PUB.PLC.IsValid == false)
{
PUB.Result.SetResultMessage(eResult.Hardware, eECode.PLCCONN, eNextStep.ERROR);
return false;
}
//충전 상태가 OFF되어야 동작하게한다
if (_SM_RUN_CHGOFF(isFirst, stepTime) == false)
@@ -111,7 +106,7 @@ namespace Project
//커버를 자동으로 내려준다
CoverControlTime = DateTime.Now;
UpdateProgressStatus(stepTime.TotalSeconds, 5, Lang.);
PUB.PLC.ZMot(arDev.FakePLC.ZMotDirection.Down);
PUB.AGV.LiftControl(arDev.Narumi.LiftCommand.DN);
VAR.BOOL[eVarBool.WAIT_COVER_DOWN] = true;
PUB.sm.UpdateRunStepSeq();
return false;
@@ -130,7 +125,7 @@ namespace Project
//커버 내림이 완료될때까지 기다린다
if (PUB.PLC.IsLimitDn() == true)
if (true)
{
VAR.BOOL[eVarBool.WAIT_COVER_DOWN] = false;
PUB.Result.NextPos = ePosition.NONE;
@@ -138,6 +133,8 @@ namespace Project
}
else
{
//경과시간이 10초가 지나면 5초마다 음성을 출력한다
var tsCover = DateTime.Now - CoverControlTime;
if (tsCover.TotalSeconds >= 7)
@@ -179,7 +176,7 @@ namespace Project
}
else if (PUB.sm.RunStepSeq == idx++)
{
//IO업데이트 간격 전송
UpdateProgressStatus(stepTime.TotalSeconds, 5, Lang.);
PUB.Speak(Lang.);
@@ -219,47 +216,47 @@ namespace Project
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) == 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_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_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_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) == false)
// PUB.PLC.ZMot_Right(arDev.FakePLC.ZMotDirection.Up);
// }
// }
//}
}
}
return false;

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AR;
using COMM;
using static Project.StateMachine;
@@ -24,7 +25,7 @@ namespace Project
if (VAR.BOOL[eVarBool.FLAG_CHARGEONA] == true)
{
if (VAR.TIME.IsSet(eVarTime.ChargeStart) == false)
VAR.TIME.Set(eVarTime.ChargeStart);
VAR.TIME.Update(eVarTime.ChargeStart);
//충전중이라면 최대 충전 시간을 체크한다.
var tsChargeRunTime = VAR.TIME.RUN(eVarTime.ChargeStart);
@@ -53,7 +54,7 @@ namespace Project
else if (VAR.BOOL[eVarBool.FLAG_CHARGEONM] == true)
{
if (VAR.TIME.IsSet(eVarTime.ChargeStart) == false)
VAR.TIME.Set(eVarTime.ChargeStart);
VAR.TIME.Update(eVarTime.ChargeStart);
VAR.STR[eVarString.ChargeCheckMsg] = "수동 충전";
}
@@ -133,7 +134,7 @@ namespace Project
{
PUB.log.Add($"대기상태에서는 정차");
PUB.AGV.AGVMoveStop("대기상태에서는 정차");
VAR.TIME.Set(eVarTime.IdleStopTime);
VAR.TIME.Update(eVarTime.IdleStopTime);
}
}

View File

@@ -5,6 +5,7 @@ using System.Linq;
using System.Text;
using static Project.StateMachine;
using COMM;
using AR;
namespace Project
{

View File

@@ -6,6 +6,7 @@ using System.Text;
using static Project.StateMachine;
using COMM;
using System.Diagnostics;
using AR;
namespace Project
{

View File

@@ -15,7 +15,7 @@ namespace Project
private void _STEP_CLOSING_START(eSMStep step)
{
PUB.bShutdown = true;
if (PUB.PLC != null) PUB.PLC.Dispose();
//if (PUB.PLC != null) PUB.PLC.Dispose();
PUB.AddEEDB("프로그램 종료");
PUB.log.Add("Program Close");
@@ -23,7 +23,7 @@ namespace Project
PUB.logagv.Flush();
PUB.logplc.Flush();
PUB.logbms.Flush();
PUB.logcal.Flush();
PUB.logxbee.Flush();
// PUB.sm.Stop();
}

View File

@@ -7,6 +7,7 @@ using System.Text;
using arCtl;
using static Project.StateMachine;
using COMM;
using AR;
namespace Project
{

View File

@@ -7,6 +7,7 @@ using System.Text;
using arCtl;
using static Project.StateMachine;
using COMM;
using AR;
namespace Project
{

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
using arDev;
using COMM;
@@ -46,7 +47,7 @@ namespace Project
if (VAR.BOOL[eVarBool.WAIT_COVER_UP])
{
PUB.log.Add($"버튼({diName}) 눌림");
PUB.PLC.ZMot(FakePLC.ZMotDirection.Up);
PUB.AGV.LiftControl(arDev.Narumi.LiftCommand.UP);
PUB.Result.NextPos = ePosition.QC;
}
else PUB.Speak(Lang.);
@@ -92,7 +93,7 @@ namespace Project
if (VAR.BOOL[eVarBool.WAIT_COVER_UP])
{
PUB.log.Add($"버튼({diName}) 눌림");
PUB.PLC.ZMot(FakePLC.ZMotDirection.Up);
PUB.AGV.LiftControl(arDev.Narumi.LiftCommand.UP);
PUB.Result.NextPos = ePosition.QA;
}
else PUB.Speak(Lang.);
@@ -120,7 +121,7 @@ namespace Project
{
//Z-up기능으로 업데이트 230119
PUB.log.Add($"버튼({diName}) 눌림");
PUB.PLC.ZMot(FakePLC.ZMotDirection.Up);
PUB.AGV.LiftControl(arDev.Narumi.LiftCommand.UP);
}
}
else if (diName == arDev.FakePLC.DIName.PINI_EMG)
@@ -172,8 +173,8 @@ namespace Project
//}
//PUB.flag.set(EFlag.FLAG_LIMITHIGH, (PUB.flag.get(EFlag.FLAG_LIMITHIGHL) && PUB.flag.get(EFlag.FLAG_LIMITHIGHR)));
//PUB.flag.set(EFlag.FLAG_LIMITLOW, (PUB.flag.get(EFlag.FLAG_LIMITLOWL) && PUB.flag.get(EFlag.FLAG_LIMITLOWR)));
VAR.BOOL[eVarBool.FLAG_LIMITHIGH] = PUB.PLC.GetValueI(arDev.FakePLC.DIName.PINI_LIMIT_LU) || PUB.PLC.GetValueI(arDev.FakePLC.DIName.PINI_LIMIT_RU);
VAR.BOOL[eVarBool.FLAG_LIMITLOW] = PUB.PLC.GetValueI(arDev.FakePLC.DIName.PINI_LIMIT_LD) || PUB.PLC.GetValueI(arDev.FakePLC.DIName.PINI_LIMIT_RD);
VAR.BOOL[eVarBool.FLAG_LIMITHIGH] = false;// PUB.PLC.GetValueI(arDev.FakePLC.DIName.PINI_LIMIT_LU) || PUB.PLC.GetValueI(arDev.FakePLC.DIName.PINI_LIMIT_RU);
VAR.BOOL[eVarBool.FLAG_LIMITLOW] = false;//PUB.PLC.GetValueI(arDev.FakePLC.DIName.PINI_LIMIT_LD) || PUB.PLC.GetValueI(arDev.FakePLC.DIName.PINI_LIMIT_RD);
VAR.BOOL[eVarBool.OVERLOAD] = (VAR.BOOL[eVarBool.OVERLOADL] || VAR.BOOL[eVarBool.OVERLOADR]);
}
else
@@ -189,109 +190,7 @@ namespace Project
DateTime lastplclogtime = DateTime.Now;
string logmessage = "";
bool logerror = false;
void PLC_Message(object sender, FakePLC.MessageEventArgs e)
{
if (e.MsgType == arRS232.MessageType.Error)
{
PUB.logplc.Add("ERROR-MAIN", e.Message);
}
else if (e.MsgType == arRS232.MessageType.Normal)
{
//내부클래스에서 발생한 메세지(이 프로그램)
if (e.Message.StartsWith("@STP:") && e.Message.Length > 5)
{
PUB.Result.StopMessageSWR = e.Message.Substring(5);
PUB.Result.StopMessageTimeSWR = DateTime.Now;
}
PUB.logplc.Add("MOT", "[Inner Msg]" + e.Message);
}
else
{
//PLC에서 수신된 메세지
if (e.Message.StartsWith("@STP|") && e.Message.Length > 5)
{
PUB.Result.StopMessagePLC = e.Message.Substring(5);
PUB.Result.StopMessageTimePLC = DateTime.Now;
PUB.logplc.Add("PLC", "[" + e.MsgType.ToString() + "]" + e.Message);
}
else if (e.Message.StartsWith("@FLAG|") && e.Message.Length > 6)
{
var flagData = e.Message.Split('|')[1].Split(',');
var flag = (COMM.eVarBool)(byte.Parse(flagData[0]));
var flagmsg = "[" + flag.ToString() + "] = " + flagData[1];
//플래그값이 바뀌면 로깅한다
var fValueTrue = flagData[1] == "1";
if (PUB.PLC.GetFlag(flag) != fValueTrue)
{
PUB.logplc.Add("MFLAG", flagmsg);
}
}
else if (e.Message.StartsWith("@SET|") && e.Message.Length > 5)
{
//셋팅관련 정보이다
var flagData = e.Message.Split('|')[1];
var splBuf = flagData.Split(':');
if (splBuf[0] == "SAVE") PUB.PLC.SaveTime = DateTime.Now;
PUB.logplc.Add("SETUP", "[SETTING] " + flagData);
}
else
{
if (e.Message.StartsWith("ERR"))
{
logmessage = e.Message;
logerror = true;
}
else if (e.Message.StartsWith("@@") & e.Data.Length == 16)
{
//표시하지 말자
logerror = false;
var hexstr = e.Data.GetHexString();
logmessage = "[" + e.MsgType.ToString() + "]" + hexstr;
}
else
{
logmessage = "[" + e.MsgType.ToString() + "]" + e.Message;
logerror = false;
}
bool addlog = false;
if (lastplclogmessage.StartsWith("[Recv] 40 40"))
{
if (lastplclogmessage.Length > 40)
{
var st = lastplclogmessage.Substring(0, 40);
var cr = logmessage.Substring(0, 40);
addlog = st.Equals(cr) == false;
if (addlog == false)
{
var ts = DateTime.Now - lastplclogtime;
if (ts.TotalSeconds > 5) addlog = true;
}
}
else addlog = true;
}
else if (logmessage.Equals(lastplclogmessage) == false) addlog = true;
else
{
var ts = DateTime.Now - lastplclogtime;
if (ts.TotalSeconds > 30) addlog = true;
}
if (addlog)
{
if (logerror) PUB.logplc.AddE(logmessage);
else PUB.logplc.Add("PLC", logmessage);
lastplclogmessage = logmessage;
lastplclogtime = DateTime.Now;
}
}
}
}
}
}

View File

@@ -1,4 +1,5 @@
using COMM;
using AR;
using COMM;
using System;
using System.Collections.Generic;
using System.ComponentModel;
@@ -62,7 +63,7 @@ namespace Project
{
if (NewValue)
{
VAR.TIME.Set(eVarTime.ChargeStart);
VAR.TIME.Update(eVarTime.ChargeStart);
PUB.counter.CountChargeA += 1;
PUB.counter.Save();
PUB.Speak(Lang.);
@@ -76,7 +77,7 @@ namespace Project
{
if (NewValue)
{
VAR.TIME.Set(eVarTime.ChargeStart);
VAR.TIME.Update(eVarTime.ChargeStart);
PUB.counter.CountChargeM += 1;
PUB.counter.Save();
PUB.Speak(Lang.);

View File

@@ -9,6 +9,7 @@ using static Project.StateMachine;
using COMM;
using System.Windows.Forms;
using Project.ViewForm;
using AR;
namespace Project
{
@@ -179,7 +180,7 @@ namespace Project
{
var b1 = PUB.XBE.IsOpen;
var b2 = PUB.AGV.IsOpen;
var b3 = PUB.PLC.IsOpen;
var b3 = true;// PUB.PLC.IsOpen;
var b4 = PUB.BMS.IsOpen;
if (b1 == false || b2 == false || b3 == false || b4 == false)

View File

@@ -4,6 +4,7 @@ using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
using arCtl;
using COMM;
using static Project.StateMachine;
@@ -23,10 +24,10 @@ namespace Project
var tsPLC = VAR.TIME.RUN(conntry);
if (tsPLC.TotalSeconds > 5)
{
VAR.TIME.Set(conntry);
VAR.TIME.Update(conntry);
try
{
VAR.TIME.Set(recvtime); //this.LastReceiveTime = DateTime.Now;
VAR.TIME.Update(recvtime); //this.LastReceiveTime = DateTime.Now;
dev.PortName = port;
dev.BaudRate = baud;
if (dev.Open())
@@ -38,8 +39,8 @@ namespace Project
var errmessage = dev.errorMessage;
PUB.log.Add("ERROR-" + port, errmessage);
}
VAR.TIME.Set(conn);
VAR.TIME.Set(conntry);
VAR.TIME.Update(conn);
VAR.TIME.Update(conntry);
}
catch (Exception ex)
{
@@ -51,17 +52,53 @@ namespace Project
{
PUB.log.Add(port, $"포트변경({dev.PortName}->{port})으로 연결 종료");
dev.Close();
VAR.TIME.Set(conntry);
VAR.TIME.Update(conntry);
}
}
void ConnectSerialPort(Device.Xbee dev, string port, int baud, eVarTime conn, eVarTime conntry, eVarTime recvtime)
{
if (dev.IsOpen == false && port.isEmpty() == false)
{
var tsPLC = VAR.TIME.RUN(conntry);
if (tsPLC.TotalSeconds > 5)
{
VAR.TIME.Update(conntry);
try
{
VAR.TIME.Update(recvtime); //this.LastReceiveTime = DateTime.Now;
dev.PortName = port;
dev.BaudRate = baud;
if (dev.Open())
{
PUB.log.Add(port, "연결완료");
}
else
{
var errmessage = dev.errorMessage;
PUB.log.Add("ERROR-" + port, errmessage);
}
VAR.TIME.Update(conn);
VAR.TIME.Update(conntry);
}
catch (Exception ex)
{
PUB.log.AddE(ex.Message);
}
}
}
else if (dev.PortName.Equals(port) == false)
{
PUB.log.Add(port, $"포트변경({dev.PortName}->{port})으로 연결 종료");
dev.Close();
VAR.TIME[(int)conntry] = DateTime.Now; ;
}
}
void sm_SPS(object sender, EventArgs e)
{
if (PUB.sm.Step < eSMStep.IDLE || PUB.sm.Step >= eSMStep.CLOSING) return;
//plc connect
ConnectSerialPort(PUB.PLC, PUB.setting.Port_PLC, PUB.setting.Baud_PLC,
eVarTime.LastConn_PLC, eVarTime.LastConnTry_PLC, eVarTime.LastRecv_PLC);
//agv connect
ConnectSerialPort(PUB.AGV, PUB.setting.Port_AGV, PUB.setting.Baud_AGV,
eVarTime.LastConn_AGV, eVarTime.LastConnTry_AGV, eVarTime.LastRecv_AGV);
@@ -78,14 +115,14 @@ namespace Project
if (PUB.XBE != null && PUB.XBE.IsOpen)
{
//일정간격으로 상태를 전송한다
if (PUB.XBE.lastSendTime.Year == 1982) PUB.XBE.lastSendTime = DateTime.Now.AddSeconds(1);
var ts = DateTime.Now - PUB.XBE.lastSendTime;
if (PUB.XBE.LastStatusSendTime.Year == 1982) PUB.XBE.LastStatusSendTime = DateTime.Now.AddSeconds(1);
var ts = DateTime.Now - PUB.XBE.LastStatusSendTime;
if (ts.TotalSeconds >= PUB.setting.interval_xbe)
{
var statusMsg = PUB.XBE.GetStatusString();
PUB.XBE.SendStatus(statusMsg);
PUB.XBE.SendStatus();
}
}
//배터리쿼리
if (PUB.BMS != null && PUB.BMS.IsOpen)
{

View File

@@ -1,4 +1,5 @@
using COMM;
using AR;
using COMM;
using System;
using System.Drawing;
using static Project.StateMachine;
@@ -231,7 +232,7 @@ namespace Project
//hw접속상태 표시
MenuAGV.BackColor = PUB.AGV.IsValid ? Color.FromArgb(40, 40, 40) : Color.Brown;
MenuBMS.BackColor = PUB.BMS.IsValid ? Color.FromArgb(40, 40, 40) : Color.Brown;
MenuMAN.BackColor = PUB.PLC.IsValid ? Color.FromArgb(40, 40, 40) : Color.Brown;
MenuMAN.BackColor = PUB.AGV.IsValid ? Color.FromArgb(40, 40, 40) : Color.Brown;
btChargeA.Enabled = !VAR.BOOL[eVarBool.FLAG_CHARGEONM];
@@ -296,7 +297,7 @@ namespace Project
_AutoResetCount();
//상태를 DB에 저장한다. 230314
var tsrun = COMM.VAR.TIME.RUN(eVarTime.StatusReporttime);
var tsrun = VAR.TIME.RUN(eVarTime.StatusReporttime);
if (tsrun.TotalSeconds >= PUB.setting.StatusInterval) EEMStatus.UpdateStatusSQL(PUB.sm.Step, _extrun: true);
tm1minute = DateTime.Now;
@@ -410,7 +411,7 @@ namespace Project
}
VAR.TIME.Set(eVarTime.BatWarnTime);
VAR.TIME.Update(eVarTime.BatWarnTime);
}
}
}
@@ -580,14 +581,14 @@ namespace Project
UpdateStatusMessage("비상 정지", Color.Tomato, Color.Black);
}
}
else if (PUB.PLC.IsOpen == false)
{
UpdateStatusMessage(Lang.PLC연결실패, Color.Tomato, Color.Black);
}
else if (PUB.PLC.IsValid == false)
{
UpdateStatusMessage(Lang.PLC통신실패, Color.Tomato, Color.Black);
}
//else if (PUB.PLC.IsOpen == false)
//{
// UpdateStatusMessage(Lang.PLC연결실패, Color.Tomato, Color.Black);
//}
//else if (PUB.PLC.IsValid == false)
//{
// UpdateStatusMessage(Lang.PLC통신실패, Color.Tomato, Color.Black);
//}
else if (VAR.BOOL[eVarBool.FLAG_CHARGEONA] == true)
{
//남은 충전시간 계산
@@ -646,8 +647,8 @@ namespace Project
string stMsg;
if (PUB.AGV.system1.stop_by_front_detect)//.GetValueI(arDev.FakePLC.DIName.PINI_LIDAR_STOP))
stMsg = Lang.;
else if (PUB.PLC.GetValueI(arDev.FakePLC.DIName.PINI_EMG))
stMsg = Lang.;
//else if (PUB.PLC.GetValueI(arDev.FakePLC.DIName.PINI_EMG))
// stMsg = Lang.비상정지신호가감지되었습니다;
else if (PUB.AGV.signal.front_gate_out == true)
stMsg = Lang.;
else if (PUB.AGV.error.runerror_by_no_magent_line)