initial commit

This commit is contained in:
chi
2025-01-07 16:08:02 +09:00
parent 9e657e2558
commit 0a93a54a6f
268 changed files with 50767 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Windows.Forms;
using System.Management;
using COMM;
namespace Project
{
public static partial class UTIL
{
public static string GetResultCodeMessage(eResult err)
{
return err.ToString().ToUpper();
}
public static string GetErrorMessage(eECode err, params object[] values)
{
switch (err)
{
case eECode.NOTALLOWUP:
return "상차 허용 위치가 아닙니다";
case eECode.AGVCONN:
return Lang.AGV연결실패;
case eECode.PLCCONN:
return Lang.PLC통신실패;
default:
return err.ToString();
}
}
}
}

View File

@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows.Forms;
namespace Project
{
public partial class fMain
{
delegate void UpdateControlTextHandler(Control ctl, string value);
void UpdateControlText(Control ctl, string value)
{
if (ctl.InvokeRequired)
{
ctl.BeginInvoke(new UpdateControlTextHandler(UpdateControlText), new object[] { ctl, value });
}
else
{
ctl.Text = value;
}
}
}
}

View File

@@ -0,0 +1,550 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using static Project.StateMachine;
using COMM;
namespace Project
{
public partial class fMain
{
DateTime LastSpeakTime = DateTime.Now;
DateTime CoverControlTime = DateTime.Now;
DateTime LastCommandTime = DateTime.Now;
DateTime LastCommandTimeNextStop = DateTime.Now;
bool runStepisFirst = false;
private void _SM_RUN(Boolean isFirst, TimeSpan stepTime)
{
//중단기능이 동작이라면 처리하지 않는다.
if (PUB.sm.bPause)
{
System.Threading.Thread.Sleep(200);
return;
}
//사용자 스텝처리가 아닌경우에만 검사
//if (Pub.flag.get(eFlag.UserStepCheck) == false)
{
//가동불가 조건 확인
if (CheckStopCondition() == false)
{
PUB.sm.SetNewStep(eSMStep.PAUSE);
return;
}
}
//이머전시상태라면 stop 처리한다.
if (PUB.AGV.error.Emergency && PUB.AGV.system1.agv_stop == true &&
PUB.AGV.system1.stop_by_front_detect == false)
{
PUB.Speak(Lang.);
PUB.sm.SetNewStep(eSMStep.IDLE);
}
//실행스텝보정
//if (Pub.sm.runStep == eRunStep.NOTSET && Pub.sm.runStepNew == eRunStep.NOTSET)
//{
// Pub.sm.setNewRunStep(eRunStep.IDLE);
// Pub.log.Add("RUnStep Initialize");
//}
//스텝이 변경되었다면?
if (PUB.sm.RunStep != PUB.sm.RunStepNew)
{
runStepisFirst = true;
PUB.sm.ApplyRunStep();
}
else runStepisFirst = false;
if (isFirst)
{
if (PUB.sm.RunStep == ERunStep.READY)
VAR.TIME.Set(eVarTime.ReadyStart);
else
VAR.TIME.Set(eVarTime.RunStart);
}
switch (PUB.sm.RunStep)
{
case ERunStep.READY:
_SM_RUN_READY(runStepisFirst, PUB.sm.GetRunSteptime);
break;
case ERunStep.GOCHARGE: //충전위치로 이동
if (runStepisFirst)
{
VAR.TIME[eVarTime.ChargeTry] = DateTime.Now;
PUB.sm.ResetRunStepSeq();
PUB.log.Add("충전 명령 시작");
}
else if (_SM_RUN_GOCHARGE(runStepisFirst, PUB.sm.GetRunSteptime))
{
//230601
//if (PUB.Result != null && PUB.sm != null)
// EEMStatus.AddEEDBSQL(PUB.sm.Step, PUB.sm.RunStep.ToString(), PUB.Result.TargetPos.ToString());
PUB.Speak(Lang.) ;
PUB.sm.SetNewRunStep(ERunStep.CHARGECHECK);
return;
}
break;
case ERunStep.CHARGECHECK: //충전중
if (runStepisFirst)
{
VAR.TIME.Set(eVarTime.ChargeStart);
LastCommandTime = DateTime.Now;
}
else if (_SM_RUN_GOCHARGECHECK(runStepisFirst, PUB.sm.GetRunSteptime))
{
//충전상태가 활성화되었으므로 대기상태로 전환한다
PUB.sm.SetNewRunStep(ERunStep.READY);
PUB.log.AddAT("충전상태 확인 완료로 인해 대기 합니다");
}
break;
case ERunStep.CHARGEOFF:
if (runStepisFirst)
{
VAR.TIME.Set(eVarTime.ChargeEnd);
LastCommandTime = DateTime.Now;
}
else
{
//충전 상태가 OFF되어야 동작하게한다
if (_SM_RUN_CHGOFF(isFirst, stepTime) == true)
{
//충전상태가 활성화되었으므로 대기상태로 전환한다
PUB.sm.ClearRunStep();
//충전기위치에서 OFF를 한 경우이다
if (PUB.Result.CurrentPos != ePosition.CHARGE || PUB.Result.TargetPos != ePosition.CHARGE)
{
PUB.Result.CurrentPos = ePosition.NONE;
}
else
{
PUB.Result.TargetPos = ePosition.QC;
}
PUB.Result.CurrentPosCW = "1";
PUB.sm.SetNewRunStep(ERunStep.GOHOME);
PUB.log.AddAT("충전 해제로 홈으로 이동");
}
}
break;
case ERunStep.GOUP: //상차이동
if (_SM_RUN_GOUP(runStepisFirst, PUB.sm.GetRunSteptime))
{
PUB.Speak(Lang.);
//230601
// if (PUB.Result != null && PUB.sm != null)
// EEMStatus.AddEEDBSQL(PUB.sm.Step, PUB.sm.RunStep.ToString(), PUB.Result.TargetPos.ToString());
//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.Set(eVarTime.ChargeTry);
PUB.PLC.ZMot(arDev.FakePLC.ZMotDirection.Down);// (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);
}
else
{
//홈 이동 명령처리
PUB.sm.ClearRunStep();
PUB.Result.TargetPos = ePosition.QC;
PUB.sm.SetNewRunStep(ERunStep.GOHOME);
PUB.Speak( Lang.);
}
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.Set(eVarTime.ChargeTry);
PUB.sm.SetNewRunStep(ERunStep.READY); //대기상태로 전환한다
return;
}
break;
}
}
bool CheckStopCondition()
{
return true;
}
void CheckAGVMoveTo(eGoDir dir)
{
//계속내려간다
if (dir == eGoDir.Down)
{
var tsCmd = DateTime.Now - LastCommandTime;
if (tsCmd.TotalMilliseconds >= 1999)
{
//현재 동작중인상태에서 방향이 맞지 않다면 일단 움직임을 멈춘다
if (PUB.AGV.system1.agv_run)
{
if (PUB.AGV.data.Direction == 'B')
{
PUB.log.Add($"방향이 맞지 않아 정지 합니다({dir})");
PUB.AGV.AGVMoveStop("CheckAGVMoveTo");
}
else if (PUB.AGV.data.Speed == 'S')
{
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 + ")");
}
LastCommandTime = DateTime.Now;
}
}
else
{
var tsCmd = DateTime.Now - LastCommandTime;
if (tsCmd.TotalMilliseconds >= 1999)
{
if (PUB.AGV.system1.agv_run)
{
if (PUB.AGV.data.Direction == 'F')
{
PUB.log.Add($"방향이 맞지 않아 정지 합니다({dir})");
PUB.AGV.AGVMoveStop("CheckAGVMoveTo");
}
else if (PUB.AGV.data.Speed == 'S')
{
PUB.log.Add($"마크정지를 해제하기 위해 장비를 멈춥니다");
}
}
else
{
PUB.log.Add($"AGV 기동 방향(UP):{dir}");
PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Backward);//PUB.PLC.Move(Device.PLC.Rundirection.Backward, "UpdateMotionPosition(" + sender + ")");
}
LastCommandTime = DateTime.Now;
}
}
}
void CheckAGVStopbyMARK(string sender)
{
//계속내려간다
var tsCmd = DateTime.Now - LastCommandTime;
if (VAR.BOOL[eVarBool.NEXTSTOP_MARK] == false || tsCmd.TotalMilliseconds >= 1500)
{
PUB.AGV.AGVMoveStop("CheckAGVStopbyMARK", arDev.Narumi.eStopOpt.MarkStop);
LastCommandTime = DateTime.Now;
PUB.log.Add($"[{sender}] MARK신호에 멈춤 설정");
}
}
Boolean UpdateMotionPositionForMark(string sender)
{
//이머전시상태에서는 처리하지 않는다.
if (VAR.BOOL[eVarBool.EMERGENCY]) return false;
//DOWN 작업
// if (goDIR == eGoDir.Down)
{
//1. 현재위치 > 대상위치
if (PUB.Result.CurrentPos > PUB.Result.TargetPos)
{
//계속내려간다
if (PUB.setting.AGV_Direction_FVI_Backward)
CheckAGVMoveTo(eGoDir.Down);
else
CheckAGVMoveTo(eGoDir.Up);
}
//2. 현재위치 < 대상위치
else if (PUB.Result.CurrentPos < PUB.Result.TargetPos)
{
//올라가야한다
if (PUB.setting.AGV_Direction_FVI_Backward)
CheckAGVMoveTo(eGoDir.Up);
else
CheckAGVMoveTo(eGoDir.Down);
}
//3. 현재위치 = 대상위치
else
{
//현재위치가 확정되었는가?
var actpos = ctlPos1.GetPositionActive(PUB.Result.CurrentPos);
if (actpos == false && PUB.AGV.system1.agv_stop == true)
{
//위치확정이되지 않았다면 AGV멈춤시에 기동하게 한다.
var lastcom = DateTime.Now - LastCommandTime;
if (lastcom.TotalSeconds > 3)
{
if (PUB.Result.CurrentPosCW == "1")
{
if (PUB.setting.AGV_Direction_FVI_Backward)
PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Forward);
else
PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Backward);
}
else
{
if (PUB.setting.AGV_Direction_FVI_Backward)
PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Backward);
else
PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Forward);
}
LastCommandTime = DateTime.Now;
PUB.logagv.Add($"AGV가 멈춰있다 동작을 재개 합니다");
}
}
else
{
//마크센서가 들어와잇고, 위치가 act 되어있다면 해당 위치에 있는 것이다
if (PUB.AGV.error.Emergency == false &&
PUB.AGV.system1.agv_stop &&
PUB.AGV.signal.mark_sensor && actpos &&
PUB.Result.CurrentPos == PUB.Result.TargetPos)
{
//PUB.AGV.AGVMoveStop();
return true;
}
if (PUB.AGV.system1.agv_stop == true && PUB.AGV.system1.agv_run == false)
{
PUB.log.Add($"멈춰있으므로 이동을 시작 합니다");
if (PUB.Result.CurrentPosCW == "1")
{
if (PUB.setting.AGV_Direction_FVI_Backward)
PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Backward);
else
PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Forward);
}
else
{
if (PUB.setting.AGV_Direction_FVI_Backward)
PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Forward);
else
PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Backward);
}
}
//AGV는 아래로 FVI방향으로 내려가고 있다
if (VAR.BOOL[eVarBool.AGVDIR_UP] == false)
{
if (PUB.Result.CurrentPosCW == "0")
{
//장비가 마크센서에의해 멈췃다면 완료이다
if (PUB.AGV.error.Emergency == false && PUB.AGV.signal.mark_sensor)
{
PUB.AGV.AGVMoveStop("UPdateMotionPositionForMark");
return true;
}
else CheckAGVStopbyMARK(sender);
}
else if (PUB.Result.CurrentPosCW == "1")
{
//내려가는 작업이고 AGV는 올라가고 있는데 RFID는 위졲이 감지되었다면 아래로 내려가야한다
CheckAGVMoveTo(eGoDir.Up);
}
else
{
PUB.Result.CurrentPosCW = "1";
CheckAGVMoveTo(eGoDir.Up);
}
}
//AGV는 Qc방향으로 올라가고 있다
else
{
if (PUB.Result.CurrentPosCW == "1")
{
//네려가는 방향에서 내려가는 위치가 인식되었다면 마크에서 멈춰야 한다
if (PUB.AGV.error.Emergency == false && PUB.AGV.signal.mark_sensor)
{
PUB.AGV.AGVMoveStop("UPdateMotionPositionForMark");
return true;
}
else CheckAGVStopbyMARK(sender);
}
else if (PUB.Result.CurrentPosCW == "0")
{
//내려가는 작업이고 AGV는 올라가고 있는데 RFID는 위졲이 감지되었다면 아래로 내려가야한다
CheckAGVMoveTo(eGoDir.Down);
}
else
{
PUB.Result.CurrentPosCW = "0";
CheckAGVMoveTo(eGoDir.Down);
}
}
}
}
}
//UP 작업
//else
//{
// //1. 현재위치 > 대상위치
// if (PUB.Result.CurrentPos > PUB.Result.TargetPos)
// {
// //계속내려간다
// CheckAGVMoveTo(eGoDir.Down);
// }
// //2. 현재위치 < 대상위치
// else if (PUB.Result.CurrentPos < PUB.Result.TargetPos)
// {
// //올라가야한다
// CheckAGVMoveTo(eGoDir.Up);
// }
// //3. 현재위치 = 대상위치
// else
// {
// //AGV는 위로가고 있다
// if (VAR.BOOL[eVarBool.AGVDIR_UP] == true)
// {
// if (PUB.Result.CurrentPosCW == "0")
// {
// //장비가 마크센서에의해 멈췃다면 완료이다
// if (PUB.AGV.system1.agv_stop && PUB.AGV.system1.stop_by_front_detect == false && PUB.AGV.error.Emergency == false && PUB.AGV.signal.mark_sensor)
// {
// return true;
// }
// else CheckAGVStopbyMARK();
// }
// else if (PUB.Result.CurrentPosCW == "1")
// {
// //내려가는 작업이고 AGV는 올라가고 있는데 RFID는 위졲이 감지되었다면 아래로 내려가야한다
// CheckAGVMoveTo(eGoDir.Down);
// }
// }
// //AGV는 내려가고 있다
// else if (VAR.BOOL[eVarBool.AGVDIR_UP] == false)
// {
// if (PUB.Result.CurrentPosCW == "1")
// {
// //네려가는 방향에서 내려가는 위치가 인식되었다면 마크에서 멈춰야 한다
// if (PUB.AGV.system1.agv_stop && PUB.AGV.system1.stop_by_front_detect == false && PUB.AGV.error.Emergency == false && PUB.AGV.signal.mark_sensor)
// {
// return true;
// }
// else CheckAGVStopbyMARK();
// }
// else if (PUB.Result.CurrentPosCW == "0")
// {
// //내려가는 작업이고 AGV는 올라가고 있는데 RFID는 위졲이 감지되었다면 아래로 내려가야한다
// CheckAGVMoveTo(eGoDir.Up);
// }
// }
// }
//}
return false;
}
Boolean UpdateMotionPositionForCharger(string sender)
{
if (VAR.BOOL[eVarBool.AGVDIR_UP] == false)// PUB.flag.get(EFlag.FLAG_DIR_BW) == true)
{
//충전기 검색은 항상 뒤로 검색한다
var tsCmd = DateTime.Now - tm_gocharge_command;
if (tsCmd.TotalMilliseconds >= 1999 &&
PUB.AGV.error.Emergency == false &&
PUB.AGV.system1.agv_run == false)
{
//PUB.PLC.Move(Device.PLC.Rundirection.Backward, "UpdateMotionPosition(" + sender + ")");
PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Backward);//
tm_gocharge_command = DateTime.Now;
}
}
else
{
//CCW (역방향 )
//if (Pub.Result.RFIDPos < ePosition.CHARGE || Pub.Result.RFIDPos > ePosition.QC)
//{
// //정상적이라면 RFID값은 QC + 혹은 QC - 에 있어야 하므로 항상 차저보다 높이 있다
// //그렇지 않다면 초기화해서 QC검색부터 다시 실행하게 한다
// //여기는 비정상 위치 값이다.
// Pub.sm.SetStepSeq(1);
//}
//else
//{
//현재위치가 충전위치이고, 움직이지 않았다면 완료된 경우라 할수 있따
if (PUB.Result.CurrentPos == ePosition.CHARGE &&
PUB.AGV.signal.mark_sensor == true)
{
PUB.log.AddI("충전위치 검색 완료");
return true;
}
else
{
//이동중이지 않다면 항상 이동을 해줘야한다
var tsCmd = DateTime.Now - LastCommandTime;
if (tsCmd.TotalMilliseconds >= 1999 &&
PUB.AGV.error.Emergency == false &&
PUB.AGV.system1.agv_run == false)
{
//PUB.PLC.Move(Device.PLC.Rundirection.Backward, "UpdateMotionPosition #1(" + sender + ")");
PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Backward);//
LastCommandTime = DateTime.Now;
}
}
//}
}
return false;
}
}//cvass
}

View File

@@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using static Project.StateMachine;
using COMM;
namespace Project
{
public partial class fMain
{
public Boolean _SM_RUN_CHGOFF(bool isFirst, TimeSpan stepTime)
{
//
if (VAR.BOOL[eVarBool.FLAG_CHARGEONA] == true || PUB.AGV.system1.Battery_charging == true)
{
if (isFirst)
{
VAR.TIME.Set(eVarTime.ChargeEnd);
if (VAR.BOOL[eVarBool.FLAG_CHARGEONA])
{
PUB.Speak(Lang.);
}
}
//AGV는 충전을 해제한 상태이다
if (PUB.AGV.system1.Battery_charging == false)
{
//너무빨리 처리되지 않도록 5초후에 완료 처리를 한다
var ts1 = VAR.TIME.RUN(eVarTime.ChargeEnd);
var ts2 = VAR.TIME.RUN(eVarTime.SendChargeOff);
if (ts1.TotalSeconds >= 5 && ts2.TotalSeconds > 5) VAR.BOOL[eVarBool.FLAG_CHARGEONA] = false;
}
else
{
//OFF전송이 처음이라면 시간 섲렁
if (VAR.TIME.IsSet(eVarTime.SendChargeOff)==false)
VAR.TIME[eVarTime.SendChargeOff] = DateTime.Now.AddSeconds(-10);
var tsChgOff = VAR.TIME.RUN(eVarTime.SendChargeOff);
if (tsChgOff.TotalSeconds >= 3)
{
PUB.log.Add("충전 해제 전송");
PUB.AGV.AGVCharge(PUB.setting.ChargerID, false);
VAR.TIME.Set(eVarTime.SendChargeOff);
}
}
return false;
}
else
{
//PUB.logsys.Add($"충전OFF확인완료");
return true;
}
}
}
}

View File

@@ -0,0 +1,264 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using static Project.StateMachine;
using COMM;
namespace Project
{
public partial class fMain
{
DateTime tm_gocharge_command = DateTime.Now;
public Boolean _SM_RUN_GOCHARGE(bool isFirst, TimeSpan stepTime)
{
if (runStepisFirst)
{
//홈을 찾도록 항상 위치를 지워버리자
PUB.Result.CurrentPos = ePosition.NONE;
PUB.Result.CurrentPos = ePosition.NONE;
}
//HW 연결오류
if (PUB.AGV.IsOpen == false)
{
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)
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)
{
PUB.Result.result_message = "충전기 검색 전 현재 위치 검색";
PUB.Result.result_progressmax = 0;
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++)
{
PUB.Speak(Lang.);
PUB.Result.TargetPos = ePosition.QC;
VAR.TIME.Set(eVarTime.ChargeSearch);
PUB.sm.UpdateRunStepSeq();
PUB.log.Add($"충전:대상위치 QC 시작");
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//모션 전후진 제어
if (UpdateMotionPositionForMark("GOCHARGE #1") == true)
{
PUB.log.Add($"충전:충전기 검색 전 QC위치 확인 완료");
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++)
{
if (PUB.setting.chargerpos == 0) //down search
{
PUB.log.Add($"충전:충전기 검색을 위한 전진시작");
PUB.Speak(Lang.);
PUB.AGV.AGVMoveSet(new arDev.Narumi.BunkiData
{
Speed = arDev.Narumi.eMoveSpd.Low,
Bunki = arDev.Narumi.eBunki.Strate,
Direction = arDev.Narumi.eMoveDir.Forward,
PBSSensor = 1,
});
PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Forward);
//PUB.Result.TargetPos = ePosition.CHARGE;
VAR.TIME.Set(eVarTime.ChargeSearch);
}
else if (PUB.setting.chargerpos == 2) //up search
{
PUB.log.Add($"충전:충전기 검색을 위한 전진시작");
PUB.Speak(Lang.);
PUB.AGV.AGVMoveSet(new arDev.Narumi.BunkiData
{
Speed = arDev.Narumi.eMoveSpd.Low,
Bunki = arDev.Narumi.eBunki.Strate,
Direction = arDev.Narumi.eMoveDir.Backward,
PBSSensor = 1,
});
PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Backward);
//PUB.Result.TargetPos = ePosition.CHARGE;
VAR.TIME.Set(eVarTime.ChargeSearch);
}
else
{
PUB.log.Add($"충전기위치가 QC위치로 설정되어 있습니다");
}
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
if (PUB.setting.chargerpos != 1)
{
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.Set(eVarTime.ChargeSearch);
PUB.sm.UpdateRunStepSeq();
}
else
{
if (VAR.TIME.RUN(eVarTime.ChargeSearch).TotalSeconds > 5)
{
//5초이상 이곳에서 대기한다면 다시 돌려준다
PUB.sm.UpdateRunStepSeq(-1);
PUB.log.Add($"충전:AGV기동확인 안됨, 롤백 다시 이동할 수 있게 함");
}
}
}
else
{
VAR.TIME.Set(eVarTime.ChargeSearch);
PUB.sm.UpdateRunStepSeq();
}
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";
ctlPos1.SetPosition(ePosition.CHARGE);
ctlPos1.SetPositionActive(ePosition.CHARGE);
ctlPos1.Invalidate();
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

@@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using static Project.StateMachine;
using COMM;
namespace Project
{
public partial class fMain
{
public Boolean _SM_RUN_GOCHARGECHECK(bool isFirst, TimeSpan stepTime)
{
//충전상태체크를 확인합니다
//10초안에 충전 플래그가 활성화되지 않으면 QC상태로 이동한다
if (PUB.AGV.system1.Battery_charging == false || VAR.BOOL[eVarBool.FLAG_CHARGEONA] == false)
{
if (PUB.AGV.error.Charger_pos_error)
{
PUB.Speak(Lang., true);
PUB.sm.ClearRunStep();
PUB.sm.SetNewRunStep(ERunStep.CHARGEOFF);
PUB.sm.SetNewStep(eSMStep.RUN);
}
else if (PUB.AGV.error.Charger_run_error)
{
PUB.Speak(Lang., true);
PUB.sm.ClearRunStep();
PUB.sm.SetNewRunStep(ERunStep.CHARGEOFF);
PUB.sm.SetNewStep(eSMStep.RUN);
}
else
{
var tsCmd = DateTime.Now - LastCommandTime;
if (tsCmd.TotalSeconds >= 30)
{
PUB.log.AddE( Lang.);
PUB.AGV.AGVCharge(PUB.setting.ChargerID, false);
PUB.sm.ClearRunStep();
PUB.sm.SetNewRunStep(ERunStep.CHARGEOFF);
PUB.sm.SetNewStep(eSMStep.RUN);
}
else
{
PUB.Result.result_message = string.Format("충전기 활성화 수신 확인 중({0:N1}/{1})", tsCmd.TotalSeconds, 30);
PUB.Result.result_progressmax = 15;
PUB.Result.result_progressvalue = tsCmd.TotalSeconds;
}
}
return false;
}
else return true;
}
}
}

View File

@@ -0,0 +1,226 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using static Project.StateMachine;
using COMM;
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;
}
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)
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.PLC.ZMot(arDev.FakePLC.ZMotDirection.Down);//
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

@@ -0,0 +1,94 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using static Project.StateMachine;
using COMM;
namespace Project
{
public partial class fMain
{
public Boolean _SM_RUN_GOHOME(bool isFirst, TimeSpan stepTime)
{
if (runStepisFirst)
{
// PUB.flag.set(EFlag.FLAG_NEXTSTOP_ALIGN, false);
//VAR.BOOL[eVarBool.FLAG_NEXTSTOP_MARK] = false;//);
VAR.BOOL[eVarBool.FLAG_NEXTSTOP_ALIGN] = false;//);
}
//220629
// if(PUB.flag.get(EFlag.FLAG_GO_CHAGER_TEMP))
//{
// PUB.flag.set(EFlag.FLAG_GO_CHAGER_TEMP, false);
//}
//HW 연결오류
if (PUB.AGV.IsOpen == false)
{
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)
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.Speak(Lang.);
//홈은 무조건 QC위치로 간다
PUB.AddEEDB($"홈검색시작({PUB.Result.TargetPos})");
PUB.Result.TargetPos = ePosition.QC;
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//모션 전후진 제어
if (UpdateMotionPositionForMark("GOHOME"))
{
PUB.AGV.AGVMoveStop("SM_RUN_GOHOME");
PUB.sm.UpdateRunStepSeq();
}
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//QC까지 모두 완료되었다.(완전히 정차할때까지 기다린다)
PUB.Speak(Lang., true);
PUB.AddEEDB($"홈검색완료({PUB.Result.TargetPos})");
PUB.sm.UpdateRunStepSeq();
return false;
}
return true;
}
}
}

View File

@@ -0,0 +1,272 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using static Project.StateMachine;
using COMM;
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;
}
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)
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.PLC.ZMot(arDev.FakePLC.ZMotDirection.Down);
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 (PUB.PLC.IsLimitDn() == 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

@@ -0,0 +1,121 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Media;
namespace Project
{
public partial class fMain
{
/// <summary>
/// 웨이퍼를 집기 위해 지정된 위치로 이동을 합니다.
/// </summary>
/// <returns></returns>
private bool _SM_RUN_INIT(Boolean firstRun, TimeSpan RunTime)
{
//result message
int progress = 0;
var ProgressMax = 13;
//setting socket
UpdateProgressStatus(++progress, ProgressMax, "소켓 초기화"); System.Threading.Thread.Sleep(5);
if (PUB.sock_debug.Listen(PUB.setting.listenPort))
PUB.log.AddI("Socket Listen : " + PUB.setting.listenPort);
else
PUB.log.AddE("Socket Listen : " + PUB.sock_debug.errorMessage);
//UpdateProgressStatus(++progress, ProgressMax, "PLC 확인"); System.Threading.Thread.Sleep(5);
//if (PUB.setting.Port_PLC != "")
//{
// if (PUB.PLC.Init(PUB.setting.Port_PLC, PUB.setting.Baud_PLC))
// {
// //VAR.BOOL[eVarBool.FLAG_SETUP] = true;
// PUB.log.Add("Entering Setup Mode (Main)");
// }
// else PUB.log.AddE("PLC Init error : " + PUB.PLC.GetErrorMessage());
//}
//UpdateProgressStatus("PLC #2 확인", ++progress, ProgressMax); System.Threading.Thread.Sleep(5);
//if (Pub.setting.Port_PLC2 != "")
//{
// if (Pub.plcS.Init(Pub.setting.Port_PLC2, Pub.setting.Baud_plc2))
// {
// Pub.plcS.SetFlag(Device.PLC2.PLCFlag.FLAG_SETUP, true);
// Pub.log.Add("Entering Setup Mode (Sub)");
// }
// else Pub.log.AddE("DIO #S Init error : " + Pub.plcS.GetErrorMessage());
//}
//setting Port_Xbee
//UpdateProgressStatus(++progress, ProgressMax, "Port_Xbee 확인"); System.Threading.Thread.Sleep(5);
//if (PUB.setting.Port_XBE.isEmpty() == false)
//{
// PUB.XBE.PortName = PUB.setting.Port_XBE;
// if (PUB.XBE.Open() == false)
// PUB.log.AddE(string.Format("Barcode Port({0}) Open Error: {1}", PUB.setting.Port_XBE, PUB.XBE.errorMessage));
//}
//else
//{
// PUB.log.AddAT("NOT-SET Port_Xbee PORTNAME");
// PUB.XBE.errorMessage = "NOT-SET Port_Xbee PORTNAME";
//}
////setting Port_Xbee
//UpdateProgressStatus(++progress, ProgressMax, "Port_AGV 확인"); System.Threading.Thread.Sleep(5);
//if (PUB.setting.Port_AGV.isEmpty() == false)
//{
// PUB.AGV.PortName = PUB.setting.Port_AGV;
// PUB.AGV.BaudRate = PUB.setting.Baud_AGV;
// if (PUB.AGV.Open() == false)
// PUB.log.AddE(string.Format("RFID Host:{0} Open Error: {1}", PUB.setting.Port_AGV, PUB.AGV.errorMessage));
//}
//else
//{
// PUB.log.AddAT("NOT-SET Port_AGV PORTNAME");
// PUB.AGV.errorMessage = "NOT-SET Port_AGV PORTNAME";
//}
////setting Port_Xbee
//UpdateProgressStatus(++progress, ProgressMax, "Port_BMS 확인"); System.Threading.Thread.Sleep(5);
//if (!PUB.setting.Port_BAT.isEmpty())
//{
// PUB.BAT.PortName = PUB.setting.Port_BAT;//.Port_BMS;
// PUB.BAT.BaudRate = PUB.setting.Baud_BAT;//
// PUB.BAT.ScanInterval = 1000;// Pub.setting.interval_bms;
// var binit_bms = PUB.BAT.Open();
// if (binit_bms == false) PUB.log.AddE(string.Format("binit_bms Port({0}) Open Error: {1}", PUB.setting.Port_BAT, PUB.BAT.errorMessage));
//}
//else
//{
// PUB.log.AddAT("NOT-SET binit_bms PORTNAME");
//}
//남은 공간
UpdateProgressStatus(++progress, ProgressMax, "공간 확인"); System.Threading.Thread.Sleep(5);
CheckFreeSpace(); //181225
//시스템 오류가 있다면 경고 메시지를 표싷ㄴ다.
UpdateProgressStatus(++progress, ProgressMax, "오류 수집"); System.Threading.Thread.Sleep(5);
//var AlertMessage = new System.Text.StringBuilder();
//if (Pub.Xbee.IsInit == false) AlertMessage.AppendLine(string.Format("BARCODE : {0}", Pub.Xbee.errorMessage));
if (freeSpaceRate < PUB.setting.AutoDeleteThreshold)
{
PUB.Speak(string.Format("디스크 용량이 {0:N0}% 남았습니다", freeSpaceRate));
}
//if (AlertMessage.Length > 1)
//{
// AlertMessage.Insert(0, "SYSTEM ALERT\n");
// Pub.popup.setMessage(AlertMessage.ToString());
//}
UpdateProgressStatus(++progress, ProgressMax, "--"); System.Threading.Thread.Sleep(5);
PUB.log.Add("초기화 완료");
return true;
}
}
}

View File

@@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
namespace Project
{
public partial class fMain
{
public Boolean _SM_RUN_POSCHK(bool isFirst, TimeSpan stepTime)
{
//현재 위치가 찾아지지 않았다면. 먼저 위치를 찾는다. 위로 이동시켜서 찾는다.
if (PUB.Result.CurrentPos == ePosition.NONE)
{
if (isFirst)
{
PUB.Speak( Lang.);
}
if (PUB.AGV.system1.agv_run)
{
//방향을 체크한다
var basedir = PUB.setting.AGV_Direction_FVI_Backward ? 'F' : 'B';
if (PUB.AGV.data.Direction == basedir)
{
var ts = DateTime.Now - LastCommandTime;
if (ts.TotalMilliseconds >= 1999)
{
PUB.AGV.AGVMoveStop("SM_RUN_POSCHK",arDev.Narumi.eStopOpt.Stop);
LastCommandTime = DateTime.Now;
}
}
}
else if (PUB.AGV.system1.agv_run == false)
{
//전진이동한다
var ts = DateTime.Now - LastCommandTime;
if (ts.TotalMilliseconds >= 1999)
{
if (PUB.setting.AGV_Direction_FVI_Backward)
PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Backward);//
else
PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Forward);//
LastCommandTime = DateTime.Now;
}
}
return false;
}
else return true;
}
}
}

View File

@@ -0,0 +1,144 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using COMM;
using static Project.StateMachine;
namespace Project
{
public partial class fMain
{
public Boolean _SM_RUN_READY(bool isFirst, TimeSpan stepTime)
{
//이동 불가 조건이 걸려있다면 충전을 하지 못하게 한다.
Boolean bAutoChageOn = true;
if (PUB.AGV.system1.stop_by_front_detect) bAutoChageOn = false;
else if (PUB.AGV.error.Emergency) bAutoChageOn = false;
else if (VAR.BOOL[eVarBool.FLAG_CHARGEONA]) bAutoChageOn = false;
else if (VAR.BOOL[eVarBool.FLAG_CHARGEONM]) bAutoChageOn = false;
//자동 충전 중이라면 최대 충전시간과 레벨을 체크한다
if (VAR.BOOL[eVarBool.FLAG_CHARGEONA] == true)
{
if (VAR.TIME.IsSet(eVarTime.ChargeStart) == false)
VAR.TIME.Set(eVarTime.ChargeStart);
//충전중이라면 최대 충전 시간을 체크한다.
var tsChargeRunTime = VAR.TIME.RUN(eVarTime.ChargeStart);
if (PUB.BMS.Current_Level >= PUB.setting.ChargeMaxLevel)
{
PUB.AGV.AGVCharge(PUB.setting.ChargerID, false);
PUB.sm.ClearRunStep();
PUB.sm.SetNewRunStep(ERunStep.CHARGEOFF);
PUB.sm.SetNewStep(eSMStep.RUN);
PUB.log.Add($"최대충전레벨 OVER로 인한 자동 해제(레벨:{PUB.setting.ChargeMaxLevel})");
PUB.AddEEDB($"최대충전레벨 OVER로 인한 자동 해제(레벨:{PUB.setting.ChargeMaxLevel})");
PUB.Speak(Lang.);
}
else if (PUB.setting.ChargeMaxTime > 1 && tsChargeRunTime.TotalSeconds >= PUB.setting.ChargeMaxTime)
{
PUB.AGV.AGVCharge(PUB.setting.ChargerID, false);
PUB.sm.ClearRunStep();
PUB.sm.SetNewRunStep(ERunStep.CHARGEOFF);
PUB.sm.SetNewStep(eSMStep.RUN);
PUB.log.Add($"최대충전시간 OVER로 인한 자동 해제(시간:{PUB.setting.ChargeMaxTime})");
PUB.AddEEDB($"최대충전시간 OVER로 인한 자동 해제(시간:{PUB.setting.ChargeMaxTime})");
PUB.Speak(Lang.);
}
VAR.STR[eVarString.ChargeCheckMsg] = "자동 충전 중";
}
else if (VAR.BOOL[eVarBool.FLAG_CHARGEONM] == true)
{
if (VAR.TIME.IsSet(eVarTime.ChargeStart) == false)
VAR.TIME.Set(eVarTime.ChargeStart);
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)
{
var ts = VAR.TIME.RUN(eVarTime.IdleStopTime);
if(ts.TotalSeconds > 1)
{
PUB.log.Add($"대기상태에서는 정차");
PUB.AGV.AGVMoveStop("대기상태에서는 정차");
VAR.TIME.Set(eVarTime.IdleStopTime);
}
}
return false;
}
}
}

View File

@@ -0,0 +1,163 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using static Project.StateMachine;
using COMM;
namespace Project
{
public partial class fMain
{
public Boolean _SM_RUN_RESET(bool isFirst, TimeSpan stepTime)
{
if (runStepisFirst)
{
PUB.Speak(Lang.);
//충전기검색시퀀스 OFF
//PUB.flag.set(EFlag.FLAG_GO_CHAGER_TEMP, false);
}
var idx = 1;
if (PUB.sm.RunStepSeq == idx++)
{
//충전중이라면 충전off코드를 넣는다
PUB.AGV.AGVCharge(PUB.setting.ChargerID, false,PUB.setting.ChargetWaitSec);
LastCommandTime = DateTime.Now;
PUB.AddEEDB($"초기화");
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
UpdateProgressStatus(stepTime.TotalSeconds, 5, "SYNC : 수동 모드 확인 중");
if (VAR.BOOL[eVarBool.FLAG_AUTORUN] == false)
PUB.sm.UpdateRunStepSeq();
else
{
//일정시간동안 명령을 재전송한다
var tsCmd = DateTime.Now - LastCommandTime;
if (tsCmd.TotalMilliseconds >= 1999)
{
VAR.BOOL[eVarBool.FLAG_AUTORUN] = false;
LastCommandTime = DateTime.Now;
}
}
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//모션을 멈춥니다
//PUB.PLC.Move(Device.PLC.Rundirection.Stop,"RESET");
PUB.AGV.AGVMoveStop("_sm_run_reset");
LastCommandTime = DateTime.Now;
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//모션이 멈출때까지 기다린다
if (PUB.AGV.system1.agv_stop == false)
{
PUB.sm.UpdateRunStepSeq();
}
else
{
//모션이 멈추지 않는다면 멈춤코드를 계속 넣는다
var tsCmd = DateTime.Now - LastCommandTime;
if (tsCmd.TotalMilliseconds >= 1999)
{
//PUB.PLC.Move(Device.PLC.Rundirection.Stop,"RESET(Re)");
PUB.AGV.AGVMoveStop("_sm_run_reset");
LastCommandTime = DateTime.Now;
}
}
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//대상위치 초기화
PUB.Result.TargetPos = ePosition.NONE;
PUB.Result.CurrentPos = ePosition.NONE;
PUB.Result.CurrentPosCW = "0";
ctlPos1.SetPositionDeActive();
ctlPos1.SetPosition(ePosition.NONE);
ctlPos1.SetDirection("0");
ctlPos1.Invalidate();
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//자동 스탑 플래그 해제
//VAR.BOOL[eVarBool.FLAG_NEXTSTOP_ALIGN] = false;//"reset #6");
VAR.BOOL[eVarBool.FLAG_NEXTSTOP_ALIGN] = false;
LastCommandTime = DateTime.Now;
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
UpdateProgressStatus(stepTime.TotalSeconds, 5, "자동멈춤해제(ALIGN)");
if (VAR.BOOL[eVarBool.FLAG_NEXTSTOP_ALIGN] == false)
PUB.sm.UpdateRunStepSeq();
else
{
//일정시간동안 명령을 재전송한다
var tsCmd = DateTime.Now - LastCommandTime;
if (tsCmd.TotalMilliseconds >= 1999)
{
VAR.BOOL[eVarBool.FLAG_NEXTSTOP_ALIGN] = false;// "reset #7");
//VAR.BOOL[eVarBool.FLAG_NEXTSTOP_ALIGN] = false;//
LastCommandTime = DateTime.Now;
}
}
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//자동 스탑 플래그 해제
//VAR.BOOL[eVarBool.FLAG_NEXTSTOP_MARK] = false;// "reset #8");
LastCommandTime = DateTime.Now;
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//설정모드가 되어있다면 해제 해준다
VAR.BOOL[eVarBool.FLAG_SETUP] = false;
VAR.BOOL[eVarBool.ITEMON] = false;
VAR.BOOL[eVarBool.WAIT_COVER_DOWN] = false;
VAR.BOOL[eVarBool.WAIT_COVER_UP] = false;
LastCommandTime = DateTime.Now;
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
UpdateProgressStatus(stepTime.TotalSeconds, 5, "설정모드해제(MARK)");
if (VAR.BOOL[eVarBool.FLAG_SETUP] == false)
PUB.sm.UpdateRunStepSeq();
else
{
//일정시간동안 명령을 재전송한다
var tsCmd = DateTime.Now - LastCommandTime;
if (tsCmd.TotalMilliseconds >= 1999)
{
VAR.BOOL[eVarBool.FLAG_SETUP] = false;
LastCommandTime = DateTime.Now;
}
}
return false;
}
return true;
}
}
}

View File

@@ -0,0 +1,148 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using static Project.StateMachine;
using COMM;
using System.Diagnostics;
namespace Project
{
public partial class fMain
{
Dictionary<string, string> synlist;
int synidx;
public Boolean _SM_RUN_SYNC(bool isFirst, TimeSpan stepTime)
{
var idx = 1;
if (PUB.sm.RunStepSeq == idx++)
{
// return true;
UpdateProgressStatus(stepTime.TotalSeconds, 5, "SYNC : 장치 연결(MAIN) 확인 중");
if (PUB.AGV.IsOpen == false)
{
//agv connect
ConnectSerialPort(PUB.AGV, PUB.setting.Port_AGV, PUB.setting.Baud_AGV,
eVarTime.LastConn_AGV, eVarTime.LastConnTry_AGV, eVarTime.LastRecv_AGV);
}
else if (PUB.AGV.IsValid == true)
{
//설정모드 진입
VAR.BOOL[eVarBool.FLAG_SETUP] = true;
LastCommandTime = DateTime.Now;
PUB.sm.UpdateRunStepSeq();
}
else
{
UpdateProgressStatus(stepTime.TotalMilliseconds, 10000.0, "wait");
if (stepTime.TotalSeconds >= 10)
{
PUB.log.AddE("시간초과로 인해 Sync 작업이 실패되었습니다");
PUB.sm.SetNewStep(eSMStep.IDLE);
}
}
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//동기화 명령 생성
synlist = new Dictionary<string, string>();
synlist.Add("SSH", PUB.setting.SPD_H.ToString("0000")); // PUB.AGV.AGVCommand(item.Key, item.Value);
synlist.Add("SSM", PUB.setting.SPD_M.ToString("0000"));
synlist.Add("SSL", PUB.setting.SPD_L.ToString("0000"));
synlist.Add("SSS", PUB.setting.SPD_S.ToString("0000"));
synlist.Add("SRS", PUB.setting.SPD_R.ToString("0000"));
synlist.Add("SPK", PUB.setting.PID_PH.ToString("0000"));
synlist.Add("SPM", PUB.setting.PID_PM.ToString("0000"));
synlist.Add("SPL", PUB.setting.PID_PL.ToString("0000"));
synlist.Add("SIK", PUB.setting.PID_IH.ToString("0000"));
synlist.Add("SIM", PUB.setting.PID_IM.ToString("0000"));
synlist.Add("SIL", PUB.setting.PID_IL.ToString("0000"));
synlist.Add("SDK", PUB.setting.PID_DH.ToString("0000"));
synlist.Add("SDM", PUB.setting.PID_DM.ToString("0000"));
synlist.Add("SDL", PUB.setting.PID_DL.ToString("0000"));
synlist.Add("SPS", PUB.setting.PID_PS.ToString("0000"));
synlist.Add("SIS", PUB.setting.PID_IS.ToString("0000"));
synlist.Add("SDS", PUB.setting.PID_DS.ToString("0000"));
//추가 230110
synlist.Add("SCK", PUB.setting.SCK.ToString("0000"));
synlist.Add("SSK", PUB.setting.SSK.ToString("0000"));
synlist.Add("STT", PUB.setting.STT.ToString("0000"));
//synlist.Add("SBN", PUB.setting.ChargerID.ToString("0000"));
PUB.AddEEDB($"SYNC시작({PUB.Result.TargetPos})");
synidx = 0;
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//잠시 대기
var ts = DateTime.Now - LastCommandTime;
if (ts.TotalSeconds > 0.15)
{
PUB.sm.UpdateRunStepSeq();
}
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
//통신 확인되었으므로 스피드를 전송한다.
if (synidx < synlist.Count)
{
var item = synlist.ElementAt(synidx);
UpdateProgressStatus(stepTime.TotalSeconds, 5, $"SYNC :{item.Key}");
PUB.AGV.AGVCommand(item.Key, item.Value);
}
LastCommandTime = DateTime.Now;
PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
if (synidx < synlist.Count)
{
var ts = DateTime.Now - LastCommandTime;
var item = synlist.ElementAt(synidx);
UpdateProgressStatus(stepTime.TotalSeconds, 5, $"SYNC 변경 확인 중 :{item.Key}");
if (PUB.AGV.ACKData.Equals(item.Key))
{
synidx += 1;
if(ts.TotalSeconds < 0.15) PUB.sm.UpdateRunStepSeq(-2); //싱크중에 추가 지연시간 확보
else PUB.sm.UpdateRunStepSeq(-1);
LastCommandTime = DateTime.Now;
}
else
{
if (ts.TotalSeconds > 1)
{
PUB.AGV.AGVCommand(item.Key, item.Value);
LastCommandTime = DateTime.Now;
Console.WriteLine($"RE.send Sync : {item.Key}:{item.Value}");
}
}
}
else PUB.sm.UpdateRunStepSeq();
return false;
}
else if (PUB.sm.RunStepSeq == idx++)
{
PUB.AddEEDB($"SYNC완료({PUB.Result.TargetPos})");
UpdateProgressStatus(stepTime.TotalSeconds, 5, "SYNC : 완료");
LastCommandTime = DateTime.Now;
PUB.sm.UpdateRunStepSeq();
return false;
}
return true;
}
}
}

View File

@@ -0,0 +1,63 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using static Project.StateMachine;
namespace Project
{
public partial class fMain
{
/// <summary>
/// 프로그램을 닫을때 1회 실행되는 함수
/// </summary>
private void _STEP_CLOSING_START(eSMStep step)
{
PUB.bShutdown = true;
if (PUB.PLC != null) PUB.PLC.Dispose();
PUB.AddEEDB("프로그램 종료");
PUB.log.Add("Program Close");
PUB.log.Flush();
PUB.logagv.Flush();
PUB.logplc.Flush();
PUB.logbms.Flush();
PUB.logcal.Flush();
// PUB.sm.Stop();
}
public StepResult _STEP_CLOSING(eSMStep step, TimeSpan stepTime, TimeSpan seqTime)
{
//############################
//#### 사용자 전용 코드
//############################
//############################
//#### 개발자 권장코드
//############################
PUB.sm.SetNewStep(eSMStep.CLOSED);
return StepResult.Complete;
}
public void _STEP_CLOSED_START(eSMStep step)
{
try
{
this.BeginInvoke(new Action(() =>
{
//화면을 닫는다
PUB.sm.Stop();
this.Close();
}));
}
catch { }
}
public StepResult _STEP_CLOSED(eSMStep step, TimeSpan stepTime, TimeSpan seqTime)
{
return StepResult.Wait;
}
}
}

View File

@@ -0,0 +1,258 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using arCtl;
using static Project.StateMachine;
using COMM;
namespace Project
{
public partial class fMain
{
private void AGV_Message(object sender, arDev.Narumi.MessageEventArgs e)
{
if (e.MsgType == arDev.arRS232.MessageType.Normal)
PUB.logagv.AddE(e.Message);
else if (e.MsgType == arDev.arRS232.MessageType.Normal)
PUB.logagv.Add(e.Message);
else if (e.MsgType == arDev.arRS232.MessageType.Recv)
{
if (e.Message.Substring(1).StartsWith("STS") == false)
PUB.logagv.Add("AGV-RX", e.Message);
}
else if (e.MsgType == arDev.arRS232.MessageType.Send)
PUB.logagv.Add("AGV-TX", e.Message);
else
{
PUB.logagv.Add(e.MsgType.ToString(), e.Message);
}
}
ePosition ParsePosition(int tag, out string dirBW)
{
var tagstr = tag.ToString();
var tagno = tagstr.Substring(0, tagstr.Length - 1);
if (tag == PUB.setting.TAGNOT) { dirBW = "0"; return ePosition.NOT; }
else if (tag == PUB.setting.TAG_QA_QC) { dirBW = "0"; return ePosition.QA_QC; }
else if (tag == PUB.setting.TAG_QC_F1) { dirBW = "0"; return ePosition.QC_F1; }
else if (tag == PUB.setting.TAG_F1_F2) { dirBW = "0"; return ePosition.F1_F2; }
else if (tag == PUB.setting.TAG_F2_F3) { dirBW = "0"; return ePosition.F2_F3; }
else if (tag == PUB.setting.TAG_F3_F4) { dirBW = "0"; return ePosition.F3_F4; }
else if (tag == PUB.setting.TAG_F4_F5) { dirBW = "0"; return ePosition.F4_F5; }
else if (tag == PUB.setting.TAGQAB) { dirBW = "0"; return ePosition.QA; }
else if (tag == PUB.setting.TAGQCB) { dirBW = "0"; return ePosition.QC; }
else if (tag == PUB.setting.TAGF1B) { dirBW = "0"; return ePosition.F1; }
else if (tag == PUB.setting.TAGF2B) { dirBW = "0"; return ePosition.F2; }
else if (tag == PUB.setting.TAGF3B) { dirBW = "0"; return ePosition.F3; }
else if (tag == PUB.setting.TAGF4B) { dirBW = "0"; return ePosition.F4; }
else if (tag == PUB.setting.TAGF5B) { dirBW = "0"; return ePosition.F5; }
//else if (tag == PUB.setting.TAGQAA) { dirBW = "1"; return ePosition.QA; }
//else if (tag == PUB.setting.TAGCHA) { dirBW = "1"; return ePosition.CHARGE; }
else if (tag == PUB.setting.TAGQAA) { dirBW = "1"; return ePosition.QA; }
else if (tag == PUB.setting.TAGQCA) { dirBW = "1"; return ePosition.QC; }
else if (tag == PUB.setting.TAGF1A) { dirBW = "1"; return ePosition.F1; }
else if (tag == PUB.setting.TAGF2A) { dirBW = "1"; return ePosition.F2; }
else if (tag == PUB.setting.TAGF3A) { dirBW = "1"; return ePosition.F3; }
else if (tag == PUB.setting.TAGF4A) { dirBW = "1"; return ePosition.F4; }
else if (tag == PUB.setting.TAGF5A) { dirBW = "1"; return ePosition.F5; }
else if (tag == PUB.setting.TAGPOT) { dirBW = "0"; return ePosition.POT; }
else
{
if (tag > 9350 && tag < 9400)
{
dirBW = "0"; return ePosition.QC_F1;
}
else if (tag > 9250 && tag < 9300)
{
dirBW = "0"; return ePosition.QA_QC;
}
else if (tag > 9000 && tag < 9100)
{
dirBW = "0"; return ePosition.NOT;
}
else
{
dirBW = "0"; return ePosition.NONE;
}
}
}
bool _charging = false;
private void AGV_DataReceive(object sender, arDev.Narumi.DataEventArgs e)
{
switch (e.DataType)
{
case arDev.Narumi.DataType.STS:
{
//마크센서 확인
var chg_mark1 = PUB.AGV.signal.GetChanged(arDev.Narumi.Signal.eflag.mark_sensor_1);
var chg_mark2 = PUB.AGV.signal.GetChanged(arDev.Narumi.Signal.eflag.mark_sensor_1);
var chg_run = PUB.AGV.system1.GetChanged(arDev.Narumi.SystemFlag1.eflag.agv_run);
var chg_stop = PUB.AGV.system1.GetChanged(arDev.Narumi.SystemFlag1.eflag.agv_stop);
//if (chg_run && PUB.AGV.system1.agv_run) PUB.Speak("이동을 시작 합니다");
VAR.BOOL[eVarBool.AGVDIR_UP] = PUB.AGV.data.Direction == 'B';
// PUB.AGV.signal.mark_sensor = PUB.AGV.signal.mark_sensor;
VAR.BOOL[eVarBool.AGV_ERROR] = PUB.AGV.error.Value > 0;
VAR.BOOL[eVarBool.EMERGENCY] = PUB.AGV.error.Emergency;
if (PUB.AGV.signal.mark_sensor == false)
{
if (VAR.BOOL[eVarBool.MARK_SENSOROFF] == false)
{
VAR.BOOL[eVarBool.MARK_SENSOROFF] = true;
VAR.TIME[eVarTime.MarkSensorOff] = DateTime.Now;
PUB.log.Add($"마크센서off를 설정");
}
}
else
{
if (VAR.BOOL[eVarBool.MARK_SENSOROFF] == true)
{
VAR.BOOL[eVarBool.MARK_SENSOROFF] = false;
VAR.TIME[eVarTime.MarkSensorOff] = DateTime.Now;
PUB.log.Add($"마크센서off를 해제");
}
}
//차징상태변경
if (_charging != PUB.AGV.system1.Battery_charging)
{
if (PUB.AGV.system1.Battery_charging)
{
VAR.TIME[eVarTime.ChargeStart] = DateTime.Now;
PUB.logagv.Add($"충전시작:{VAR.TIME[eVarTime.ChargeStart]}");
}
_charging = PUB.AGV.system1.Battery_charging;
}
//배터리충전상태
if (VAR.BOOL[eVarBool.FLAG_CHARGEONA] != PUB.AGV.system1.Battery_charging)
{
PUB.log.Add($"충전상태전환 {PUB.AGV.system1.Battery_charging}");
VAR.BOOL[eVarBool.FLAG_CHARGEONA] = PUB.AGV.system1.Battery_charging;
}
//자동충전해제시 곧바로 수동 충전되는 경우가 있어 자동 상태를 BMS에 넣는다 230118
PUB.BMS.AutoCharge = PUB.AGV.system1.Battery_charging;
if (PUB.AGV.error.Charger_pos_error != VAR.BOOL[eVarBool.CHG_POSERR])
{
if (PUB.AGV.error.Charger_pos_error)
{
PUB.Speak(Lang.);
}
VAR.BOOL[eVarBool.CHG_POSERR] = PUB.AGV.error.Charger_pos_error;
}
if (VAR.BOOL[eVarBool.MARK_SENSOROFF] == true && PUB.AGV.signal.mark_sensor == false)
{
//현재 활성화된 위치를 꺼준다
if (this.ctlPos1.GetPositionActive(PUB.Result.CurrentPos))
{
var ts = VAR.TIME.RUN(eVarTime.MarkSensorOff);
if (ts.TotalSeconds >= 2)
{
ctlPos1.SetPositionDeActive();
PUB.log.Add($"현재 활성위치를 해제 함");
}
}
}
//나르미가 멈췄다면 다음 마크 이동 기능이 OFF 된다
if (PUB.AGV.system1.agv_stop)
VAR.BOOL[eVarBool.NEXTSTOP_MARK] = false;
if (VAR.BOOL[eVarBool.MARK_SENSOR] != PUB.AGV.signal.mark_sensor)
{
if (PUB.AGV.signal.mark_sensor)
{
//현재위치를 확정한다
var curact = ctlPos1.GetPositionActive(PUB.Result.CurrentPos);
if (curact == false)
{
PUB.log.Add($"마크센서로인해 현재위치 설정완료:{PUB.Result.CurrentPos}");
ctlPos1.SetPositionActive(PUB.Result.CurrentPos);
ctlPos1.SetDirection("");
ctlPos1.Invalidate();
}
}
VAR.BOOL[eVarBool.MARK_SENSOR] = PUB.AGV.signal.mark_sensor;
}
}
break;
case arDev.Narumi.DataType.TAG:
{
//자동 실행 중이다.
PUB.log.Add($"RFID값에서 위치정보를 추출할 수 있도록 해야한다");
PUB.Result.LastTAG = PUB.AGV.data.TagNo.ToString();
var curpos = ParsePosition(PUB.AGV.data.TagNo, out string dirForward);
if (curpos != PUB.Result.CurrentPos)
{
PUB.log.Add($"현재위치변경 {PUB.Result.CurrentPos} -> {curpos}");
PUB.Result.CurrentPos = curpos;
}
PUB.Result.CurrentPosCW = dirForward;
ctlPos1.SetPositionDeActive();
ctlPos1.SetPosition(PUB.Result.CurrentPos);
ctlPos1.SetDirection(dirForward);
ctlPos1.Invalidate();
//pot not를 보면 일단 바로 멈추게한다
if (PUB.Result.CurrentPos == ePosition.POT || PUB.Result.CurrentPos == ePosition.NOT)
{
PUB.AGV.AGVMoveStop("TAG:pot/not 발견으로 즉시 멈춤");
}
//자동, 상하차 모드일때 RFID 가 타겟위치에 올때는 - 멈춤을 설정해준다
if (VAR.BOOL[eVarBool.FLAG_AUTORUN] == true &&
PUB.Result.CurrentPos == PUB.Result.TargetPos &&
PUB.Result.TargetPos != ePosition.NONE &&
(PUB.sm.RunStep == ERunStep.GODOWN ||
PUB.sm.RunStep == ERunStep.GOUP ||
PUB.sm.RunStep == ERunStep.GOHOME ||
PUB.sm.RunStep == ERunStep.GOCHARGE))
{
if (PUB.AGV.data.Sts == 'F' && dirForward == "0") //아래로 내려오고있음
{
PUB.AGV.AGVMoveStop("AGV_DataReceive", arDev.Narumi.eStopOpt.MarkStop);
PUB.Speak( Lang.);
}
else if (PUB.AGV.data.Sts == 'B' && dirForward == "1")
{
//VAR.BOOL[eVarBool.FLAG_NEXTSTOP_MARK] = true;
PUB.AGV.AGVMoveStop("AGV_DataReceive", arDev.Narumi.eStopOpt.MarkStop);
PUB.Speak(Lang.);
}
}
}
break;
case arDev.Narumi.DataType.ACK:
PUB.logagv.Add($"AGV_[ACK]Receive : {PUB.AGV.ACKData}");
break;
default:
PUB.logagv.Add($"AGV_DataReceive : {e.DataType}");
break;
}
}
}
}

View File

@@ -0,0 +1,181 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using arCtl;
using static Project.StateMachine;
using COMM;
namespace Project
{
public partial class fMain
{
string lastbms03 = "";
string lastbms04 = "";
string lastbmsA03 = "";
string lastbmsA04 = "";
string lastbms = "";
DateTime lastbmstime03 = DateTime.Now;
DateTime lastbmstime04 = DateTime.Now;
DateTime lastbmstimeA03 = DateTime.Now;
DateTime lastbmstimeA04 = DateTime.Now;
DateTime lastbmstime = DateTime.Now;
private void Bms_Message(object sender, arDev.BMS.MessageEventArgs e)
{
if (e.MsgType == arDev.arRS232.MessageType.Error) PUB.logbms.AddE( e.Message);
else
{
var hexstr = e.Data.GetHexString().Trim();
bool addlog = false;
var logtimesec = 30;
if (hexstr.StartsWith("DD 04"))
{
if (lastbms04.Equals(hexstr.Substring(0,5)) == false)
{
addlog = true;
lastbms04 = "DD 04";
lastbmstime04 = DateTime.Now;
}
else
{
var ts = DateTime.Now - lastbmstime04;
if (ts.TotalSeconds > logtimesec)
{
addlog = true;
lastbms04 = "DD 04";
lastbmstime04 = DateTime.Now;
}
}
}
else if (hexstr.StartsWith("DD 03"))
{
if (lastbms03.Equals(hexstr.Substring(0, 5)) == false)
{
addlog = true;
lastbms03 = "DD 03";
lastbmstime03 = DateTime.Now;
}
else
{
var ts = DateTime.Now - lastbmstime03;
if (ts.TotalSeconds > logtimesec)
{
addlog = true;
lastbms03 = "DD 03";
lastbmstime03 = DateTime.Now;
}
}
}
else if (hexstr.StartsWith("DD A5 04"))
{
if (lastbmsA04.Equals(hexstr.Substring(0, 8)) == false)
{
addlog = true;
lastbmsA04 = "DD A5 04";
lastbmstimeA04 = DateTime.Now;
}
else
{
var ts = DateTime.Now - lastbmstimeA04;
if (ts.TotalSeconds > logtimesec)
{
addlog = true;
lastbmsA04 = "DD A5 04";
lastbmstimeA04 = DateTime.Now;
}
}
}
else if (hexstr.StartsWith("DD A5 03"))
{
if (lastbmsA03.Equals(hexstr.Substring(0, 8)) == false)
{
addlog = true;
lastbmsA03 = "DD A5 03";
lastbmstimeA03 = DateTime.Now;
}
else
{
var ts = DateTime.Now - lastbmstimeA03;
if (ts.TotalSeconds > logtimesec)
{
addlog = true;
lastbmsA03 = "DD A5 03";
lastbmstimeA03 = DateTime.Now;
}
}
}
else if (hexstr.isEmpty() == false)
{
if (lastbms.Equals(hexstr) == false)
{
lastbms = hexstr;
lastbmstime = DateTime.Now;
addlog = true;
}
else
{
var ts = DateTime.Now - lastbmstime;
if (ts.TotalSeconds > logtimesec)
{
addlog = true;
lastbms = hexstr;
lastbmstime = DateTime.Now;
}
}
}
if(addlog)
PUB.logbms.Add("BMS:" + hexstr);
}
}
private void BMS_ChargeDetect(object sender, arDev.ChargetDetectArgs e)
{
//자동충전중이아니고 멈춰있다면 수동 충전으로 전환한다
if (PUB.AGV.system1.Battery_charging == false && PUB.AGV.system1.agv_stop == true && VAR.BOOL[eVarBool.FLAG_CHARGEONM] == false)
{
if (PUB.setting.DetectManualCharge)
{
VAR.BOOL[eVarBool.FLAG_CHARGEONM] = true;
PUB.Speak(Lang.);
}
else
{
PUB.log.Add($"충전이 감지되었지만 메뉴얼 전환 비활성화됨");
}
}
}
private void Bms_BMSDataReceive(object sender, EventArgs e)
{
if (PUB.BMS.Current_Level <= PUB.setting.ChargeStartLevel)
{
//배터리 레벨이 기준보다 낮다면 경고를 활성화 한다
if (VAR.BOOL[eVarBool.BATTERY_LOW] == false)
{
VAR.BOOL[eVarBool.BATTERY_LOW] = true;
PUB.log.AddAT("배터리 부족 경고 활성화");
}
}
else
{
//배터리 경고를 해제한다
if (VAR.BOOL[eVarBool.BATTERY_LOW] == true)
{
VAR.BOOL[eVarBool.BATTERY_LOW] = false;
PUB.log.AddAT("배터리 부족 경고 비활성화");
}
}
}
}
}

View File

@@ -0,0 +1,297 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using arDev;
using COMM;
namespace Project
{
public partial class fMain
{
private void PLC_DioChanged(object sender, arDev.FakePLC.IOValueEventArgs e)
{
if (e.Direction == arDev.Arduino.IODirection.Input)
{
var diName = (arDev.FakePLC.DIName)e.ArrIDX;
Console.WriteLine(string.Format("[DI:{1}]{0}=>{2}", diName, e.ArrIDX, e.NewValue));
if (diName == arDev.FakePLC.DIName.PINI_BTN_1) //reset
{
if (e.NewValue == true)
{
PUB.log.Add($"버튼({diName}) 눌림(AGV_RESET)");
PUB.AGV.AGVErrorReset();
//241203
if(PUB.AGV.system1.agv_run || PUB.AGV.system1.agv_run_manual)
{
PUB.AGV.AGVMoveStop("button1");
}
//PUB.XBE.NewMsgEvent('0', '1');
}
}
else if (diName == arDev.FakePLC.DIName.PINI_BTN_2) //auto -> QC //230424
{
if (e.NewValue == true)
{
PUB.log.Add($"버튼({diName}) 눌림");
if (VAR.BOOL[eVarBool.FLAG_AUTORUN] == true)
{
if (PUB.sm.RunStep == StateMachine.ERunStep.GOUP)
{
//zup을 자동으로 해준다
if (VAR.BOOL[eVarBool.WAIT_COVER_UP])
{
PUB.log.Add($"버튼({diName}) 눌림");
PUB.PLC.ZMot(FakePLC.ZMotDirection.Up);
PUB.Result.NextPos = ePosition.QC;
}
else PUB.Speak(Lang.);
}
else if (PUB.sm.RunStep == StateMachine.ERunStep.GODOWN)
{
//이미 하차진행중에 누른 경우이다
PUB.Result.NextPos = ePosition.QC;
PUB.Result.TargetPos = ePosition.QC;
}
else
{
PUB.log.Add(Lang.QC이동버튼은상하차에서만사용가능합니다);
PUB.Speak(Lang.);
}
}
else PUB.Speak(Lang.);
//if (VAR.BOOL[eVarBool.FLAG_AUTORUN]==false)
//{
// PUB.sm.ClearRunStep();
// PUB.sm.SetNewRunStep(StateMachine.ERunStep.READY);
// PUB.sm.SetNewStep(StateMachine.eSMStep.RUN);
// PUB.Speak("자동 상태로 전환 합니다");
//}
//else
//{
// PUB.Speak("현재 자동 상태 입니다");
//}
}
}
else if (diName == arDev.FakePLC.DIName.PINI_BTN_3) //z-down -> QA //230424
{
if (e.NewValue == true)
{
//Z-dn기능으로 업데이트 230119
PUB.log.Add($"버튼({diName}) 눌림");
if (VAR.BOOL[eVarBool.FLAG_AUTORUN] == true)
{
if (PUB.sm.RunStep == StateMachine.ERunStep.GOUP)
{
//zup.을 자동으로 해준다
if (VAR.BOOL[eVarBool.WAIT_COVER_UP])
{
PUB.log.Add($"버튼({diName}) 눌림");
PUB.PLC.ZMot(FakePLC.ZMotDirection.Up);
PUB.Result.NextPos = ePosition.QA;
}
else PUB.Speak(Lang.);
}
else if (PUB.sm.RunStep == StateMachine.ERunStep.GODOWN)
{
//이미 하차진행중에 누른 경우이다
PUB.Result.NextPos = ePosition.QA;
PUB.Result.TargetPos = ePosition.QA;
}
else
{
PUB.log.Add($"QA이동 버튼은 상/하차에서만 사용 가능합니다");
PUB.Speak(Lang.);
}
}
else PUB.Speak(Lang.);
//PUB.PLC.ZMot(FakePLC.ZMotDirection.Down);
}
}
else if (diName == arDev.FakePLC.DIName.PINI_BTN_4) //z-up
{
if (e.NewValue == true)
{
//Z-up기능으로 업데이트 230119
PUB.log.Add($"버튼({diName}) 눌림");
PUB.PLC.ZMot(FakePLC.ZMotDirection.Up);
}
}
else if (diName == arDev.FakePLC.DIName.PINI_EMG)
{
if (e.NewValue == true)
{
PUB.log.Add($"버튼({diName}) 눌림");
PUB.Speak(Lang.);
}
//else Pub.Speak("비상 정지 해제");
}
else if (diName == arDev.FakePLC.DIName.PINI_OVERLOADL)
{
if (e.NewValue == true)
{
PUB.log.Add($"버튼({diName}) 눌림");
PUB.Speak(Lang.);
}
VAR.BOOL[eVarBool.OVERLOADL] = e.NewValue;
}
else if (diName == arDev.FakePLC.DIName.PINI_OVERLOADR)
{
if (e.NewValue == true)
{
PUB.log.Add($"버튼({diName}) 눌림");
PUB.Speak(Lang.);
}
VAR.BOOL[eVarBool.OVERLOADR] = e.NewValue;
}
//else if (diName == FakePLC.DIName.PINI_LIMIT_LU)
//{
// PUB.flag.set(EFlag.FLAG_LIMITHIGHL, e.NewValue);
//}
//else if (diName == FakePLC.DIName.PINI_LIMIT_RU)
//{
// PUB.flag.set(EFlag.FLAG_LIMITHIGHR, e.NewValue);
//}
//else if (diName == FakePLC.DIName.PINI_LIMIT_LD)
//{
// PUB.flag.set(EFlag.FLAG_LIMITLOWL, e.NewValue);
//}
//else if (diName == FakePLC.DIName.PINI_LIMIT_RD)
//{
// PUB.flag.set(EFlag.FLAG_LIMITLOWR, e.NewValue);
//}
//else
//{
// //처리하지 않음
//}
//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.OVERLOAD] = (VAR.BOOL[eVarBool.OVERLOADL] || VAR.BOOL[eVarBool.OVERLOADR]);
}
else
{
//출력포트값 변경
var doName = (arDev.FakePLC.DOName)e.ArrIDX;
PUB.logplc.Add($"출력({doName}) {(e.NewValue ? "O" : "X")}");
}
}
//string oldflagmessage = string.Empty;
string lastplclogmessage = "";
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

@@ -0,0 +1,107 @@
using COMM;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
namespace Project
{
public partial class fMain
{
void gridView2_ItemClick(object sender, arFrame.Control.GridView.ItemClickEventArgs e)
{
//메인화면 하단의 플래그 상태창에서 클릭된 경우
//var gv = sender as arFrame.Control.GridView;
//var flagIndex = gv.getNameItem(e.idx);
//if(flagIndex != "")
//{
// var fidx = int.Parse(flagIndex);
// var flag = (eFlag)fidx;
// var curValue = Pub.flag.get(flag);
// Pub.flag.set(flag, !curValue);
//}
}
private void BOOL_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
var buf = e.PropertyName.Split('|');
var flag = (COMM.eVarBool)int.Parse(buf[0]);
var NewValue = buf[1].ToUpper() == "TRUE";
if (flag == COMM.eVarBool.FLAG_AUTORUN)
{
//자동운전이 해제되면 현재위치값을 삭제한다
if (NewValue == false && PUB.setting.AutoModeOffAndClearPosition == true)
{
if (PUB.Result.CurrentPos != ePosition.NONE)
{
PUB.log.AddAT($"자동운전이 해제되어 현재 위치를 제거합니다");
PUB.Result.CurrentPos = ePosition.NONE;
PUB.Result.CurrentPosCW = "1";
}
}
// Pub.mplayer.Stop();
//if (NewValue == true)
//{
// btAutoRun.BackColor = Color.Lime;
// btAutoRun.BackColor2 = Color.Green;
// btAutoRun.Text = "자동 실행 상태";
// //if (Pub.sm.Step >= StateMachine.eSMStep.IDLE) Pub.Speak("자동 실행 모드");
//}
//else
//{
// btAutoRun.BackColor2 = Color.DimGray;
// btAutoRun.BackColor = Color.FromArgb(100, 100, 100);
// btAutoRun.Text = "수동 조작 상태";
// //if (Pub.sm.Step >= StateMachine.eSMStep.IDLE) Pub.Speak("수동 조작 모드");
//}
}
else if (flag == COMM.eVarBool.FLAG_CHARGEONA)
{
if (NewValue)
{
VAR.TIME.Set(eVarTime.ChargeStart);
PUB.counter.CountChargeA += 1;
PUB.counter.Save();
PUB.Speak(Lang.);
}
else
{
PUB.Speak(Lang.);
}
}
else if (flag == COMM.eVarBool.FLAG_CHARGEONM)
{
if (NewValue)
{
VAR.TIME.Set(eVarTime.ChargeStart);
PUB.counter.CountChargeM += 1;
PUB.counter.Save();
PUB.Speak(Lang.);
}
else
{
PUB.Speak(Lang.);
}
}
else if (flag == COMM.eVarBool.NEXTSTOP_MARK)
{
if (NewValue)
{
//PUB.Speak("다음 위치에서 멈춥니다");
PUB.log.Add($"마크인식시 멈춤 신호 변경 : {NewValue}");
}
}
}
void PLC_FlagChanged(object sender, arDev.Arduino.DIO.FlagValueEventArgs e)
{
//플래그 상태표시는 메인의 타이머를 이용한다
// var flag = (arDev.FakePLC.PLCFlag)e.ArrIDX;
PUB.log.Add($"PLC Flag Changed {e.ArrIDX} : {e.NewValue}");
}
}
}

View File

@@ -0,0 +1,405 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using arCtl;
using static Project.StateMachine;
using COMM;
using System.Windows.Forms;
using Project.ViewForm;
namespace Project
{
public partial class fMain
{
DateTime lastDeleteTime = DateTime.Now;
DateTime startuptime = new DateTime(1982, 11, 23);
enum EScreen
{
Auto = 0,
Manual,
IO,
Flag
}
void SetScreen(System.Windows.Forms.Form newscreen)
{
if (newscreen == null)
throw new Exception("화면전용용 폼이 Null 입니다. SM_RUN_INIT 에서 해당 폼이 초기화 되었는지 확인하세요");
//작업시작
if (this.InvokeRequired)
{
this.BeginInvoke(new Action(() =>
{
SetScreen(newscreen);
}));
}
else
{
if (newscreen.GetType() == typeof(fManual))
{
}
else if (PUB.DriveSpeed)
{
var rlt = PUB.AGV.AGVCommand("SSH", PUB.setting.SPD_H.ToString("0000"));
if (rlt) PUB.DriveSpeed = false;
PUB.log.Add($"Screen Change and DriveSpeed Off:{rlt}");
}
MenuAuto.ForeColor = Color.FromArgb(180, 180, 180);
MenuFlag.ForeColor = Color.FromArgb(180, 180, 180);
MenuLift.ForeColor = Color.FromArgb(180, 180, 180);
MenuLog.ForeColor = Color.FromArgb(180, 180, 180);
MenuMAN.ForeColor = Color.FromArgb(180, 180, 180);
MenuAGV.ForeColor = Color.FromArgb(180, 180, 180);
MenuBMS.ForeColor = Color.FromArgb(180, 180, 180);
if (panDlg.Controls.Count > 0)
{
var f = panDlg.Controls[0] as System.Windows.Forms.Form;
if (f.GetType() == newscreen.GetType()) return;
else f.Hide(); //숨김처리
}
panDlg.Controls.Clear();
panDlg.Controls.Add(newscreen);
newscreen.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
newscreen.WindowState = System.Windows.Forms.FormWindowState.Maximized;
newscreen.Show();
}
}
void sm_Running(object sender, StateMachine.RunningEventArgs e)
{
//창을 닫아야하는 상황에는 처리하지 않는다.
if (PUB.popup.needClose)
{
System.Threading.Thread.Sleep(10); //팝업이 닫힐때까지 기다린다.
PUB.sm.WaitFirstRun = true;
return;
}
else PUB.sm.WaitFirstRun = false;
//main loop
switch (e.Step)
{
case eSMStep.CLOSING:
_STEP_CLOSING_START(e.Step);
PUB.sm.SetNewStep(eSMStep.CLOSED);
break;
case eSMStep.CLOSED:
if (e.isFirst) _STEP_CLOSED_START(e.Step);
else _STEP_CLOSED(e.Step, e.StepTime, e.StepTime);
break;
case eSMStep.NOTSET:
PUB.log.Add("S/M Initialize Start");
PUB.sm.SetNewStep(eSMStep.INIT);
break;
case eSMStep.INIT: //최초실행이다.
if (_SM_RUN_INIT(e.isFirst, PUB.sm.StepRunTime))
{
//메인화면을 설정한다
form_auto = new ViewForm.fAuto();
form_manu = new ViewForm.fManual();
form_zlift = new ViewForm.fIO();
form_flag = new ViewForm.fFlag();
form_bms = new ViewForm.fBms();
form_agv = new ViewForm.fAgv();
form_auto.TopLevel = false;
form_manu.TopLevel = false;
form_zlift.TopLevel = false;
form_flag.TopLevel = false;
form_bms.TopLevel = false;
form_agv.TopLevel = false;
form_auto.Dock = System.Windows.Forms.DockStyle.Fill;
form_manu.Dock = System.Windows.Forms.DockStyle.Fill;
form_zlift.Dock = System.Windows.Forms.DockStyle.Fill;
form_flag.Dock = System.Windows.Forms.DockStyle.Fill;
form_bms.Dock = System.Windows.Forms.DockStyle.Fill;
form_agv.Dock = System.Windows.Forms.DockStyle.Fill;
SetScreen(form_auto);
PUB.sm.ResetRunStepSeq();
PUB.sm.SetNewStep(eSMStep.SYNC);
PUB.Speak(Lang.);
}
break;
case eSMStep.IDLE:
if (e.isFirst)
{
PUB.sm.bPause = false;
//Pub.flag.set(eFlag.UserStepCheck, false);
PUB.sm.ClearRunStep();
// Util_DO.SetMGZMotor(false);
PUB.Result.SMSG_ProgressEnable = false;
UpdateStatusMessage("준비 완료", Color.Red, Color.Gold);
if (startuptime.Year == 1982) startuptime = DateTime.Now;
}
//자동소거기능
if (PUB.setting.AutoDeleteDay > 0)
{
if (VAR.BOOL[eVarBool.MINSPACE] == true)
{
var ts = DateTime.Now - lastDeleteTime;
if (ts.TotalSeconds > 1)
{
//파일을 찾아서 소거한다.
if (System.IO.Directory.Exists(PUB.path.FullName))
DeleteFile(PUB.path.FullName);
lastDeleteTime = DateTime.Now;
}
}
}
break;
case eSMStep.SYNC:
if (_SM_RUN_SYNC(runStepisFirst, PUB.sm.GetRunSteptime))
{
var b1 = PUB.XBE.IsOpen;
var b2 = PUB.AGV.IsOpen;
var b3 = PUB.PLC.IsOpen;
var b4 = PUB.BMS.IsOpen;
if (b1 == false || b2 == false || b3 == false || b4 == false)
PUB.Speak(Lang.);
else
PUB.Speak( Lang.);
PUB.sm.SetNewStep(eSMStep.IDLE);
return;
}
break;
case eSMStep.RUN:
_SM_RUN(e.isFirst, e.StepTime);
break;
case eSMStep.PAUSE:
case eSMStep.EMERGENCY:
case eSMStep.ERROR:
//창을 닫아야하는 상황에는 처리하지 않는다.
if (PUB.popup.needClose)
{
System.Threading.Thread.Sleep(10); //팝업이 닫힐때까지 기다린다.
PUB.sm.WaitFirstRun = true;
return;
}
else PUB.sm.WaitFirstRun = false;
if (e.isFirst)
{
if (PUB.Result.ResultCode != eResult.NoError)
{
//에러메세지가 있는 경우에만 표시함
if (PUB.Result.ResultMessage != "")
PUB.popup.setMessage(PUB.Result.ResultMessage);
if (PUB.Result.ResultCode == eResult.Hardware)
{
PUB.Speak(Lang.);
}
else PUB.Speak(PUB.Result.ResultMessage);
}
if (e.Step == eSMStep.EMERGENCY) PUB.log.AddE("Enter Emergency Step");
else if (e.Step == eSMStep.PAUSE) PUB.log.AddE("Enter Pause Step : " + PUB.Result.ResultMessage);
else PUB.log.AddE(string.Format("Enter Error Step : {0}", PUB.Result.ResultMessage));
PUB.sm.bPause = false;
PUB.sm.ClearRunStep();
PUB.sm.SetNewStep(eSMStep.IDLE);
}
break;
case eSMStep.RESET:
if (e.isFirst)
{
Resultclear();
PUB.sm.bPause = false;
}
else
{
if (_SM_RUN_RESET(runStepisFirst, PUB.sm.GetRunSteptime))
PUB.sm.SetNewStep(eSMStep.IDLE);
}
break;
}
}
void DeleteFile(string path)
{
var basetime = DateTime.Now.AddDays(-1 * PUB.setting.AutoDeleteDay);
var di = new System.IO.DirectoryInfo(path);
if (di.Exists)
{
var dirYear = di.GetDirectories().OrderBy(t => t.Name).FirstOrDefault();
if (dirYear != null)
{
var dirMon = dirYear.GetDirectories().OrderBy(t => t.Name).FirstOrDefault();
if (dirMon != null)
{
var dirDay = dirMon.GetDirectories().OrderBy(t => t.Name).FirstOrDefault();
if (dirDay != null)
{
var curDay = DateTime.Parse(string.Format("{0}-{1}-{2} 00:00:00", dirYear.ToString(), dirMon.ToString(), dirDay.ToString()));
if (curDay < basetime)
{
var dirLot = dirDay.GetDirectories().OrderBy(t => t.Name).FirstOrDefault();
if (dirLot != null)
{
var delfile = dirLot.GetFiles().FirstOrDefault();
if (delfile != null)
{
try
{
PUB.log.AddI("Remove Fle : " + delfile.FullName + ",time=" + delfile.LastWriteTime.ToString());
delfile.Delete();
}
catch (Exception ex)
{
PUB.log.AddE("deleete error : " + ex.Message);
}
}
else
{
string delpath = dirLot.FullName;
try
{
dirLot.Delete(true);
}
catch (Exception ex)
{
PUB.log.AddE("remove dir" + ex.Message + "," + delpath);
}
}
}
else
{
//이 폴더아래에 다른 폴더가 하나도 없다 즉 비어 있따.
string delpath = dirDay.FullName;
try
{
dirDay.Delete(true);
}
catch (Exception ex)
{
PUB.log.AddE("remove dir" + ex.Message + "," + delpath);
}
}
}
}
else
{
//날짜에 해당하는 폴더가 하나도 없다. 월 폴더를 제거한다.
string delpath = dirMon.FullName;
try
{
dirMon.Delete(true);
}
catch (Exception ex)
{
PUB.log.AddE("remove dir" + ex.Message + "," + delpath);
}
}
}
else
{
//이 달에 해당하는 데이터가 없다. 이 년도를 삭제한다.
string delpath = dirYear.FullName;
try
{
dirYear.Delete(true);
}
catch (Exception ex)
{
PUB.log.AddE("remove dir" + ex.Message + "," + delpath);
}
}
}
//년도별폴더목록을 정리함
//가장작은 년도를 기준으로 파일을 검색해서 1개씩 삭제함
}
}
void sm_Message(object sender, StateMachine.StateMachineMessageEventArgs e)
{
//상태머신에서 발생한 메세지
if (e.Header != "SM-STEP")
PUB.log.Add(e.Header, e.Message);
}
void sm_StepChanged(object sender, StateMachine.StepChangeEventArgs e)
{
//상태머신의 스텝이 변경될때 발생함
//Pub.log.Add(string.Format("SM:Step Changed {0} to {1}",e.Old,e.New));
VAR.BOOL[eVarBool.FLAG_AUTORUN] = e.New == eSMStep.RUN;
VAR.BOOL[eVarBool.FLAG_SYNC] = (e.New == eSMStep.SYNC);
//230313
var n = (eSMStep)e.New;
EEMStatus.AddStatusSQL(n, extrun: true);
if (e.New == eSMStep.IDLE)
{
VAR.TIME[eVarTime.IdleStart] = DateTime.Now;
PUB.AGV.AGVMoveStop("_sm_stepchange", arDev.Narumi.eStopOpt.Stop);
if (VAR.BOOL[eVarBool.FLAG_CHARGEONA] || VAR.BOOL[eVarBool.FLAG_CHARGEONM])
PUB.AGV.AGVCharge(PUB.setting.ChargerID, false);
if (VAR.BOOL[eVarBool.FLAG_AUTORUN])
{
PUB.logagv.Add($"IDLE 전환으로인해 autorun 해제");
VAR.BOOL[eVarBool.FLAG_AUTORUN] = false;
}
}
}
//void uploadForm_FormClosed(object sender, System.Windows.Forms.FormClosedEventArgs e)
//{
// //이벤트 해제
// if (uploadForm != null)
// uploadForm.FormClosed -= uploadForm_FormClosed;
// //업로드 창이 닫히면 그 결과를 화면에 표시 해준다.
// //foreach (System.Windows.Forms.ListViewItem lv in uploadForm.listView1.Items)
// //{
// // string slot = lv.SubItems[0].Text;
// // string wafer = lv.SubItems[2].Text;
// // string state = lv.SubItems[3].Text;
// //}
//}
}
}

View File

@@ -0,0 +1,105 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using arCtl;
using COMM;
using static Project.StateMachine;
namespace Project
{
public partial class fMain
{
DateTime chargesynctime = DateTime.Now;
DateTime agvsendstarttime = DateTime.Now;
void ConnectSerialPort(arDev.arRS232 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.Set(conntry);
try
{
VAR.TIME.Set(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.Set(conn);
VAR.TIME.Set(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.Set(conntry);
}
}
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);
//xbee connect
ConnectSerialPort(PUB.XBE, PUB.setting.Port_XBE, PUB.setting.Baud_XBE,
eVarTime.LastConn_XBE, eVarTime.LastConnTry_XBE, eVarTime.LastRecv_XBE);
//bms connect
ConnectSerialPort(PUB.BMS, PUB.setting.Port_BAT, PUB.setting.Baud_BAT,
eVarTime.LastConn_BAT, eVarTime.LastConnTry_BAT, eVarTime.LastRecv_BAT);
//지그비상태전송
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 (ts.TotalSeconds >= PUB.setting.interval_xbe)
{
var statusMsg = PUB.XBE.GetStatusString();
PUB.XBE.SendStatus(statusMsg);
}
}
//배터리쿼리
if (PUB.BMS != null && PUB.BMS.IsOpen)
{
if (PUB.BMS.lastSendTime.Year == 1982) PUB.BMS.lastSendTime = DateTime.Now.AddSeconds(1);
var ts = DateTime.Now - PUB.BMS.lastSendTime;
if (ts.TotalMilliseconds >= PUB.setting.interval_bms)
{
PUB.BMS.SendQuery();
}
Update_BatteryWarnSpeak();
}
}
}
}

View File

@@ -0,0 +1,798 @@
using COMM;
using System;
using System.Drawing;
using static Project.StateMachine;
namespace Project
{
public partial class fMain
{
void BlinkGridViewItem(arFrame.Control.GridView ctl, int row, int col, int value1, int value2)
{
var curValue = ctl.getValue(row, col);
ctl.setValue(row, col, (byte)(curValue == value1 ? value2 : value1)); //
}
void BlinkLabel(arCtl.arLabel ctl, bool Statue
, Color onColor1, Color onColor2, Color ofColor1, Color ofColor2,
String onText = "", String OffText = "")
{
if (Statue == false)
{
ctl.BackColor2 = ofColor2;
ctl.BackColor = ofColor1;
if (OffText != "" && ctl.Text != OffText) ctl.Text = OffText;
}
else
{
if (onText != "" && ctl.Text != onText) ctl.Text = onText;
//깜박인다
if (ctl.BackColor2 == Color.DimGray)
{
ctl.BackColor = onColor1;
ctl.BackColor2 = onColor2;
}
else
{
ctl.BackColor2 = Color.DimGray;
ctl.BackColor = Color.FromArgb(100, 100, 100);
}
}
}
Boolean displayOn = false;
private void tmDisplay_Tick(object sender, EventArgs e)
{
if (displayOn == false) displayOn = true;
else
{
PUB.log.AddAT("Display Timer Overlab");// Console.WriteLine("display overlab");
return;
}
if (PUB.sm.Step > eSMStep.INIT &&
panTopMenu.Enabled == false) panTopMenu.Enabled = true;
//배터리정보표시
lbBat.VLevel = PUB.BMS.Current_Level;
lbBat.Volt = PUB.BMS.Current_Volt;
lbBat.MaxA = PUB.BMS.Current_MaxAmp;
lbBat.CurA = PUB.BMS.Current_Amp;
lbBat.IsOpen = PUB.BMS.IsOpen;
//쓰레드로인해서 메인에서 진행하게한다. SPS는 메인쓰레드에서 진행 됨
//팝을 제거 혹은 표시하는 기능
if (PUB.popup.needShow) PUB.popup.showMessage();
else if (PUB.popup.needClose) PUB.popup.Visible = false; // .setVision(false)();
//자동 리부트 코드 실행 (230710)
var chargeon = VAR.BOOL[eVarBool.FLAG_CHARGEONA] || VAR.BOOL[eVarBool.FLAG_CHARGEONM];
if (PUB.sm.Step == eSMStep.RUN & PUB.sm.RunStep == ERunStep.READY && chargeon == false &&
PUB.setting.AutoRebootTimeStart.isEmpty() == false && startuptime.Year != 1982 &&
PUB.Automodeonreboot == false && PUB.setting.SetAutoModeOn == false && PUB.AutRebootAlreay == false)
{
var strbuf = PUB.setting.AutoRebootTimeStart.Split('~');
if (strbuf.Length == 2)
{
strbuf[0] = strbuf[0].Trim();
strbuf[1] = strbuf[1].Trim();
var btimes = DateTime.TryParse(DateTime.Now.ToString("yyyy-MM-dd ") + strbuf[0], out DateTime TimeS);
var btimee = DateTime.TryParse(DateTime.Now.ToString("yyyy-MM-dd ") + strbuf[1], out DateTime TimeE);
//이미 재부팅을 했는지 확인한다
if (PUB.setting.AutoRebootTimeStart.isEmpty() == false)
{
if (DateTime.TryParse(PUB.setting.AutoRebootTimeStart, out DateTime RebootLast))
{
//지정된 시간내에서 재부팅이 되었다
if (RebootLast >= TimeS.AddMinutes(-1) && RebootLast <= TimeE.AddMinutes(1))
{
//재부팅이 완료됨
PUB.log.Add($"이미 재부팅을 진행 했습니다");
PUB.AutRebootAlreay = true;
}
}
}
if (PUB.AutRebootAlreay == false && btimes && btimee && TimeS <= TimeE && DateTime.Now >= TimeS && DateTime.Now <= TimeE) //둘다시간조건에 맞아야한다
{
//기록을 남긴다.(확인용)
EEMStatus.AddStatusSQL(eSMStep.IDLE, $"자동재부팅실행({strbuf[0]}~{strbuf[1]})", DateTime.Now, true);
//자동모드도 해제 해준다(다른 일이 발생하지 않도록)
VAR.BOOL[eVarBool.FLAG_AUTORUN] = false;
PUB.AGV.AGVCharge(PUB.setting.ChargerID, false);
PUB.AGV.AGVMoveStop("autoreboot");
PUB.sm.SetNewStep(eSMStep.IDLE);
if (System.Diagnostics.Debugger.IsAttached == false)
{
PUB.Speak(Lang.);
Util.SystemReboot(5, true);
}
else PUB.setting.SetAutoModeOn = true;
}
}
}
//자동실행-230710 - 프로그램이 켜진 후 5분안에만 동작한다
if (startuptime.Year != 1982 && PUB.setting.SetAutoModeOn && PUB.sm.Step == eSMStep.IDLE && PUB.Automodeonreboot == false)
{
if (VAR.BOOL[eVarBool.FLAG_AUTORUN] == true) //이미 자동상태라면
{
//이미 켜져있으니 처리하지 않는다
PUB.setting.SetAutoModeOn = false;
PUB.setting.Save();
}
else
{
var tsStartup = DateTime.Now - startuptime;
if (tsStartup.TotalMinutes < 3)
{
if (tsStartup.TotalSeconds > 10) //5초이전에는동작하지 말자
{
PUB.log.Add($"자동 오토런 실행");
func_sw_start(false);
PUB.setting.SetAutoModeOn = false;
PUB.setting.Save();
}
}
else
{
//5분을 넘어선 데이터는 쓸모없다 폐기
PUB.setting.SetAutoModeOn = false;
PUB.setting.Save();
}
}
}
lbTime.Text = PUB.sm.UpdateTime.ToString("yyyy-MM-dd HH:mm:ss");
//자동충전중이다(프로그램에 의해 충전이 진행된 상태)
if (VAR.BOOL[eVarBool.FLAG_CHARGEONA] == true || VAR.BOOL[eVarBool.FLAG_CHARGEONM] == true)
{
lbStStep.Text = VAR.BOOL[eVarBool.FLAG_CHARGEONA] ? "자동충전" : "수동충전";
lbIDLE.ProgressForeColor = Color.Tomato;
if (lbIDLE.ProgressEnable == false)
lbIDLE.ProgressEnable = true;
//lbIDLE.ForeColor = Color.Gold;
lbIDLE.ProgressForeColor = Color.Gold;
if (PUB.sm.Step != eSMStep.RUN)
{
var tsIdle = VAR.TIME.RUN(eVarTime.ChargeStart);
lbIDLE.ProgressMax = 100;// PUB.setting.ChargeMaxLevel;
lbIDLE.ProgressMin = 0;
lbIDLE.Text = $"{PUB.BMS.Current_Level:N0}%";
lbIDLE.ProgressValue = (float)PUB.BMS.Current_Level;
}
else
{
//if (PUB.setting.ChargeMaxTime < 1)
//{/
var tsIdle = VAR.TIME.RUN(eVarTime.ChargeStart);
lbIDLE.ProgressMax = PUB.setting.ChargeMaxLevel;
lbIDLE.ProgressMin = 0;
lbIDLE.Text = $"({PUB.BMS.Current_Level:N0}/{PUB.setting.ChargeMaxLevel})%";
lbIDLE.ProgressValue = (float)PUB.BMS.Current_Level;
//}
//else
//{
// var tsIdle = VAR.TIME.RUN(eVarTime.ChargeStart);
// lbIDLE.ProgressMax = PUB.setting.ChargeMaxTime;
// lbIDLE.ProgressMin = 0;
// lbIDLE.Text = string.Format("{0:N0}/{1} 초 충전 중", tsIdle.TotalSeconds, PUB.setting.ChargeMaxTime);
// lbIDLE.ProgressValue = (float)tsIdle.TotalSeconds;
//}
}
}
else
{
TimeSpan timerun;
if (PUB.sm.Step == eSMStep.RUN)
{
if (PUB.sm.RunStep == ERunStep.READY)
{
//대기시간
lbStStep.Text = "대기중";
timerun = VAR.TIME.RUN(eVarTime.ReadyStart);
}
else
{
//가동시간
lbStStep.Text = "가동중";
timerun = VAR.TIME.RUN(eVarTime.RunStart);
}
}
else
{
lbStStep.Text = "장비멈춤";
timerun = VAR.TIME.RUN(eVarTime.IdleStart);
}
lbIDLE.Text = string.Format("{0}일 {1}시 {2}분 {3}초", timerun.Days, timerun.Hours, timerun.Minutes, timerun.Seconds);
if (lbIDLE.ProgressEnable == true)
lbIDLE.ProgressEnable = false;
}
//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;
btChargeA.Enabled = !VAR.BOOL[eVarBool.FLAG_CHARGEONM];
btHome.Enabled = btChargeA.Enabled;
btAutoRun.Enabled = btChargeA.Enabled;
var bCharge =
(PUB.sm.RunStep == ERunStep.GOCHARGE || PUB.sm.RunStep == ERunStep.CHARGECHECK || VAR.BOOL[eVarBool.FLAG_CHARGEONA] == true);
var bHome = PUB.sm.Step == eSMStep.RUN && (PUB.sm.RunStep == ERunStep.GOHOME);
//var bChargeM = PUB.flag.get(EFlag.FLAG_CHARGEONM);
var bAuto = VAR.BOOL[eVarBool.FLAG_AUTORUN];
//if(batu)
var bChargeM = VAR.BOOL[eVarBool.FLAG_CHARGEONM];
if (btHome.Enabled == false)
{
btHome.BackColor2 = Color.Gray;
btHome.BackColor = Color.DimGray;
}
else BlinkLabel(this.btHome, bHome, Color.Aqua, Color.Teal, Color.Aqua, Color.Teal, "홈\n취소", "홈\n이동");
if (btChargeA.Enabled == false)
{
btChargeA.BackColor2 = Color.Gray;
btChargeA.BackColor = Color.DimGray;
}
else
{
//충전가능요건이라면 해당 시간을 표시해준다.
BlinkLabel(this.btChargeA, bCharge, Color.LightSalmon, Color.Tomato, Color.LightSalmon, Color.Tomato, "자동충전취소", "자동충전\n실행(" + PUB.counter.CountChargeA.ToString() + ")");
}
BlinkLabel(this.btChargeM, bChargeM, Color.LightSalmon, Color.Tomato, Color.LightSalmon, Color.Tomato, "수동충전취소", "수동충전\n실행(" + PUB.counter.CountChargeM.ToString() + ")");
//BlinkLabel(this.btChargeM, bChargeM, Color.LightSalmon, Color.Tomato, "수동충전취소", "수동충전\n실행(" + Pub.counter.CountChargeM.ToString() + ")");
if (btAutoRun.Enabled == false)
{
btAutoRun.BackColor2 = Color.Gray;
btAutoRun.BackColor = Color.DimGray;
}
else BlinkLabel(this.btAutoRun, bAuto == false, Color.DarkMagenta, Color.BlueViolet, Color.Lime, Color.Green, "수동\n조작중", "자동\n실행중");
//상태 표시
Update_SSStatus();
//IO상태(상단줄) 표시
Update_IOStatus();
//display mesasge
Update_StatusMessage();
//음악 on/off 처리
Update_Music();
//HWState.Invalidate();
SSInfo.Invalidate();
IOState.Invalidate();
#region retgion"1분 time 루틴"
var ts = DateTime.Now - tm1minute;
if (ts.TotalMinutes >= 1)
{
//리셋카운트
_AutoResetCount();
//상태를 DB에 저장한다. 230314
var tsrun = COMM.VAR.TIME.RUN(eVarTime.StatusReporttime);
if (tsrun.TotalSeconds >= PUB.setting.StatusInterval) EEMStatus.UpdateStatusSQL(PUB.sm.Step, _extrun: true);
tm1minute = DateTime.Now;
}
#endregion
#region retgion"5분 time 루틴"
ts = DateTime.Now - tm5minute;
if (ts.TotalMinutes >= 5)
{
//남은디스크확인
CheckFreeSpace();
tm5minute = DateTime.Now;
}
#endregion
//wat.Stop();
//Console.WriteLine("disp time : " + wat.ElapsedMilliseconds.ToString() + "ms");
displayOn = false;
}
void Update_Count()
{
if (this.InvokeRequired)
{
this.BeginInvoke(new System.Windows.Forms.MethodInvoker(Update_Count), null);
}
else
{
lbCntDN.Text = PUB.counter.CountDn.ToString();
lbCNtUP.Text = PUB.counter.CountUp.ToString();
lbCntQA.Text = PUB.counter.CountQA.ToString();
lbCntQC.Text = PUB.counter.CountQC.ToString();
// lbCntPk.Text = PUB.counter.CountQa2.ToString();
}
}
void Update_IOStatus()
{
int inputrow = 0;
int inputcol = 0;
////비상정지는 깜박임으로 알려준다
if (VAR.BOOL[eVarBool.EMERGENCY]) BlinkGridViewItem(IOState, inputrow, inputcol++, 2, 0);
else IOState.setValue(inputrow, inputcol++, 0);
IOState.setTitle(inputrow, inputcol, "DIR:" + PUB.AGV.data.Direction.ToString()); IOState.setValue(inputrow, inputcol++, 0);
IOState.setTitle(inputrow, inputcol, "MOV:" + PUB.AGV.data.Sts.ToString()); IOState.setValue(inputrow, inputcol++, 0);
IOState.setTitle(inputrow, inputcol, "SPD:" + PUB.AGV.data.Speed.ToString()); IOState.setValue(inputrow, inputcol++, 0);
IOState.setTitle(inputrow, inputcol, $"PBS:{PUB.AGV.data.guidesensor}"); IOState.setValue(inputrow, inputcol++, 0);
if (PUB.AGV.data.TagNo < 0)
{
IOState.setTitle(inputrow, inputcol, "(TAG)"); IOState.setValue(inputrow, inputcol++, 0);
}
else
{
IOState.setTitle(inputrow, inputcol, "T" + PUB.AGV.data.TagNo.ToString()); IOState.setValue(inputrow, inputcol++, 0);
}
if (PUB.AGV.data.CallNo < 0)
{
IOState.setTitle(inputrow, inputcol, "(CAL)");
IOState.setValue(inputrow, inputcol++, 0);
}
else
{
IOState.setTitle(inputrow, inputcol, "CAL:" + PUB.AGV.data.CallNo.ToString());
IOState.setValue(inputrow, inputcol++, 0);
}
IOState.setTitle(inputrow, inputcol, "RUN"); IOState.setValue(inputrow, inputcol++, (PUB.AGV.system1.agv_run ? 1 : 0));
IOState.setTitle(inputrow, inputcol, "MARK"); IOState.setValue(inputrow, inputcol++, (PUB.AGV.signal.mark_sensor ? 1 : (VAR.BOOL[eVarBool.NEXTSTOP_MARK] ? 2 : 0)));
IOState.setTitle(inputrow, inputcol, "CHG"); IOState.setValue(inputrow, inputcol++, (PUB.AGV.system1.Battery_charging ? 1 : 0));
IOState.setTitle(inputrow, inputcol, "ITM"); IOState.setValue(inputrow, inputcol++, (VAR.BOOL[eVarBool.ITEMON] ? 1 : 0));
IOState.Invalidate();
}
/// <summary>
/// 가동중 40% 미만에서는 배터리 경고 메세지를 추가한다(리더)
/// </summary>
void Update_BatteryWarnSpeak()
{
if (PUB.BMS == null || PUB.BMS.Current_Level > 40) return;
//가동중이거나 수동모드에서는 메세지 알림한다
if (PUB.AGV.system1.agv_run || VAR.BOOL[eVarBool.FLAG_AUTORUN] == false)
{
var timeoutsec = 15;
if (PUB.BMS.IsValid == false) timeoutsec = 30;
var tswarnmsg = VAR.TIME.RUN(eVarTime.BatWarnTime);
if (tswarnmsg.TotalSeconds >= timeoutsec)
{
if (VAR.BOOL[eVarBool.FLAG_CHARGEONM]==false && VAR.BOOL[eVarBool.FLAG_CHARGEONA] == false)
{
if (PUB.BMS.IsValid == false)
{
PUB.Speak(Lang.);
}
else
{
if (VAR.BOOL[eVarBool.FLAG_AUTORUN] == false)
PUB.Speak(Lang.);
else
PUB.Speak(Lang.);
}
}
else
{
//충전중이므로 메세지처리를 하지 않는다
}
VAR.TIME.Set(eVarTime.BatWarnTime);
}
}
}
/// <summary>
/// 가동중일때 음악이 나오게 한다
/// </summary>
void Update_Music()
{
if (PUB.mplayer != null && PUB.mplayer.HasAudio && PUB.bPlayMusic)
{
if (PUB.AGV.system1.agv_run == false)
{
if (PUB.bPlayMusic)
{
PUB.mplayer.Stop();
PUB.bPlayMusic = false;
}
}
}
else if (PUB.setting.Enable_Music && PUB.mplayer != null && PUB.mplayer.HasAudio)
{
if (PUB.AGV.system1.agv_run == true)
{
if (PUB.bPlayMusic == false)
{
PUB.mplayer.Play();
PUB.bPlayMusic = true;
}
}
}
}
void Update_SSStatus()
{
if (PUB.sm.IsThreadRun) SSInfo.setValue(0, 0, 0);
else SSInfo.setValue(0, 0, 2);
var runspeed = PUB.sm.RunSpeed.TotalMilliseconds;
SSInfo.setTitle(0, 0, $"{PUB.sm.Step}\n{runspeed:N1} ms");
if (runspeed > 9)
SSInfo.setValue(0, 0, 2);
else if (runspeed > 4)
SSInfo.setValue(0, 0, 3);
else
SSInfo.setValue(0, 0, 0);
SSInfo.setTitle(1, 0, string.Format("{0}({1})", PUB.sm.RunStep, PUB.sm.RunStepSeq));
if (PUB.sm.Step == eSMStep.RUN)
SSInfo.setTitle(1, 1, string.Format("{0:N1} sec", PUB.sm.GetRunSteptime.TotalSeconds));
else
SSInfo.setTitle(1, 1, "--");
}
/// <summary>
/// 환경설정에따른 카운트를 리셋처리한다. 171128
/// </summary>
void _AutoResetCount()
{
if (PUB.setting.datetime_Check_1 && PUB.setting.datetime_Reset_1 != "") //오전
{
try
{
DateTime SetTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " " + PUB.setting.datetime_Reset_1 + ":00");
DateTime LastClearTime = PUB.counter.CountReset;
//현재 시간이 클리어대상 시간보다 크고, 마지막으로 클리어한 시간이 지정시간보다 작아야함
if (DateTime.Now > SetTime && LastClearTime < SetTime)
{
PUB.log.AddI("Count Reset #1");
PUB.counter.CountClear();
}
}
catch { }
}
if (PUB.setting.datetime_Check_2 && PUB.setting.datetime_Reset_2 != "") //오후
{
try
{
DateTime SetTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " " + PUB.setting.datetime_Reset_2 + ":00");
DateTime LastClearTime = PUB.counter.CountReset;
//현재 시간이 클리어대상 시간보다 크고, 마지막으로 클리어한 시간이 지정시간보다 작아야함
if (DateTime.Now > SetTime && LastClearTime < SetTime)
{
PUB.log.AddI("Count Reset #2");
PUB.counter.CountClear();
}
}
catch { }
}
}
DateTime tm1minute = DateTime.Now.AddDays(-1);
DateTime tm5minute = DateTime.Now;
void UpdateProgressStatus(double value, double max, string title)
{
UpdateProgressStatus((float)value, (float)max, title);
}
void UpdateProgressStatus(float value, float max, string title = "")
{
if (PUB.Result.SMSG_ProgressEnable == false) PUB.Result.SMSG_ProgressEnable = true;
if (PUB.Result.SMSG_ProgressMax != max) PUB.Result.SMSG_ProgressMax = max;
if (PUB.Result.SMSG_ProgressValue != value)
{
if (value < max) PUB.Result.SMSG_ProgressValue = value;
else PUB.Result.SMSG_ProgressValue = max;
}
if (PUB.Result.SMSG_ProgressForeColor != Color.White)
PUB.Result.SMSG_ProgressForeColor = Color.White;
if (title != "")
if (VAR.STR[eVarString.StatusMessage].Equals(title) == false) VAR.STR[eVarString.StatusMessage] = title;
}
void UpdateStatusMessage(string dispmsg, Color fcolor, Color shadow)
{
UpdateStatusMessage(dispmsg, Color.DimGray, Color.Gray, fcolor, shadow);
}
void UpdateStatusMessage(string dispmsg, Color bColor, Color bColor2, Color fcolor, Color shadow, Boolean blank = false)
{
//if (lbMsg.ProgressEnable == true) lbMsg.ProgressEnable = false;
if (dispmsg != VAR.STR[eVarString.StatusMessage] || PUB.Result.SMSG_ForeColor != fcolor ||
PUB.Result.SMSG_ShadowColor != shadow
|| (PUB.Result.SMSG_BackColor != bColor && PUB.Result.SMSG_BackColor2 != bColor))
{
PUB.Result.SMSG_BackColor = bColor;
PUB.Result.SMSG_BackColor2 = bColor2;
PUB.Result.SMSG_ForeColor = fcolor;
PUB.Result.SMSG_ShadowColor = shadow;
VAR.STR[eVarString.StatusMessage] = dispmsg;
if (blank) PUB.Result.SMSG_Tag = "BLANK";
else PUB.Result.SMSG_Tag = null;
//PUB.Result.UpdateStatusMessage();
}
}
void Update_StatusMessage()
{
//최우선 점검 사항 표시
if (PUB.sm.Step > eSMStep.INIT)
{
//오류가 있다면 오류를 표시해준다.
if (PUB.AGV.IsOpen == false)
{
UpdateStatusMessage("AGV 연결실패", Color.Tomato, Color.Black);
}
else if (PUB.AGV.error.Emergency)
{
if (PUB.AGV.error.runerror_by_no_magent_line)
{
UpdateStatusMessage("마그넷이 감지 되지 않습니다", Color.Tomato, Color.Black);
}
else
{
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 (VAR.BOOL[eVarBool.FLAG_CHARGEONA] == true)
{
//남은 충전시간 계산
string msg = string.Empty;
if (PUB.BMS.Current_Level < PUB.setting.ChargeEmergencyLevel)
{
msg = $"충전 진행 중(이동 불가)\n저전압으로 인해 사용이 불가 합니다";
}
else
{
var remaintime = VAR.TIME.RUN(eVarTime.ChargeStart);
var remainsec = PUB.setting.ChargeMaxTime - remaintime.TotalSeconds;
msg = "충전 진행 중 (이동 불가) " + remainsec.ToString("N0") + "초 후 충전이 자동 OFF 됩니다";
}
UpdateStatusMessage(msg, Color.Orange, Color.Black);
}
else if (VAR.BOOL[eVarBool.FLAG_CHARGEONM] == true)// PUB.flag.get(EFlag.FLAG_CHARGEONM) == true)
{
UpdateStatusMessage("충전(수동) 진행 중 (이동 불가)", Color.Orange, Color.Black);
}
else if (PUB.AGV.IsOpen == false)
{
UpdateStatusMessage(Lang.AGV연결실패, Color.Tomato, Color.Black);
}
else
{
if (PUB.sm.Step == eSMStep.IDLE)
{
if (PUB.AGV.system1.agv_run)
{
if (PUB.AGV.system1.stop_by_front_detect)
UpdateStatusMessage("장애물로 인한 일시 정지", Color.SkyBlue, Color.Black);
else
UpdateStatusMessage("AGV 이동 중", Color.SkyBlue, Color.Black);
}
else if (PUB.AGV.error.Emergency)
{
if (PUB.AGV.error.runerror_by_no_magent_line)
{
UpdateStatusMessage("비상 정지 : 마그넷 라인이 감지 안됨", Color.SkyBlue, Color.Black);
}
else
{
UpdateStatusMessage("비상 정지", Color.SkyBlue, Color.Black);
}
}
else
{
var smg = "(작업을 시작 하려면 [AUTO]로 전환 하세요)";
UpdateStatusMessage(smg, Color.SkyBlue, Color.Black);
}
}
else if (PUB.sm.Step == eSMStep.RUN)
{
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.AGV.signal.front_gate_out == true)
stMsg = Lang.;
else if (PUB.AGV.error.runerror_by_no_magent_line)
stMsg = "마그네틱 라인을 벗어났습니다";
else
{
stMsg = "자동 대기";
if (PUB.setting.Enable_AutoCharge)
{
var tsIdle = VAR.TIME.RUN(eVarTime.ReadyStart);
var remainTry = (int)(PUB.setting.ChargeRetryTerm - tsIdle.TotalSeconds);
var progMax = PUB.setting.ChargeRetryTerm;
stMsg += " / (" + remainTry.ToString() + ") 초 후 충전을 시작 합니다";
UpdateProgressStatus(tsIdle.TotalSeconds, progMax, "");
}
else
{
stMsg += "(자동충전 해제됨)";
}
}
UpdateStatusMessage(stMsg, Color.SkyBlue, Color.Black);
//자동 충전 대기상태를 프로그레시브로 표시한다
if (PUB.AGV.system1.stop_by_front_detect == true)
{
UpdateStatusMessage("이동 방향 근접거리 물체 감지(이동 불가 - 일시정지)", Color.Tomato, Color.Black);
}
else if (VAR.BOOL[eVarBool.OVERLOAD] == true)
{
UpdateStatusMessage("오버로드 감지(안전커버를 확인하세요)", Color.Tomato, Color.Black);
}
else if (PUB.AGV.error.runerror_by_no_magent_line)
{
UpdateStatusMessage("마그네틱 라인을 벗어 났습니다", Color.Black, Color.White);
}
else
{
if (VAR.BOOL[eVarBool.WAIT_COVER_DOWN] == true)
{
UpdateStatusMessage(Lang., Color.Lime, Color.Black);
}
else if (VAR.BOOL[eVarBool.WAIT_COVER_UP] == true)
{
UpdateStatusMessage(Lang., Color.Lime, Color.Black);
}
else
{
if (PUB.sm.RunStep == ERunStep.GODOWN)
{
if (PUB.sm.RunStepSeq == 1)
{
UpdateStatusMessage(String.Format("하차 이동 전 (현재 위치 검색)", PUB.Result.TargetPos), Color.Lime, Color.Black);
}
else UpdateStatusMessage(String.Format("하차 이동 중 ({0})", PUB.Result.TargetPos), Color.Lime, Color.Black);
}
else if (PUB.sm.RunStep == ERunStep.GOUP)
{
if (PUB.sm.RunStepSeq == 1)
{
UpdateStatusMessage(String.Format("상차 이동 전 (현재 위치 검색)", PUB.Result.TargetPos), Color.Lime, Color.Black);
}
else UpdateStatusMessage(String.Format("상차 이동 중 ({0})", PUB.Result.TargetPos), Color.Lime, Color.Black);
}
else if (PUB.sm.RunStep == ERunStep.GOCHARGE)
{
if (PUB.Result.result_message.isEmpty() == true)
{
UpdateStatusMessage(String.Format("충전기로 이동 중"), Color.Lime, Color.Black);
}
else
{
if (PUB.Result.result_progressmax > 0)
UpdateProgressStatus(PUB.Result.result_progressvalue, PUB.Result.result_progressmax, PUB.Result.result_message);
else
UpdateStatusMessage(PUB.Result.result_message, Color.Lime, Color.Black);
}
}
else if (PUB.sm.RunStep == ERunStep.CHARGECHECK)
{
if (PUB.Result.result_message.isEmpty() == true)
{
UpdateStatusMessage(String.Format("충전기 작동 확인 중"), Color.Lime, Color.Black);
}
else
{
if (PUB.Result.result_progressmax > 0)
UpdateProgressStatus(PUB.Result.result_progressvalue, PUB.Result.result_progressmax, PUB.Result.result_message);
else
UpdateStatusMessage(PUB.Result.result_message, Color.Lime, Color.Black);
}
}
else if (PUB.sm.RunStep == ERunStep.GOHOME)
{
UpdateStatusMessage(String.Format("홈(QC) 이동 중", PUB.Result.TargetPos), Color.Lime, Color.Black);
}
else
{
//충전준비상태라면 관련 정보를 표시한다 230117
if (VAR.BOOL[eVarBool.CHARGE_READY])
{
var sec = VAR.I32[eVarInt32.ChargeWaitSec];
UpdateStatusMessage($"{sec} 초 후 충전이 시작 됩니다", Color.Lime, Color.Black);
}
else
{
var msg = $"대기상태(현재위치:{PUB.Result.CurrentPos}/대상위치:{PUB.Result.TargetPos})";
if (PUB.setting.Enable_AutoCharge) msg += "(자동충전:ON)";
else msg += "(자동충전:OFF)";
UpdateStatusMessage(msg, Color.Lime, Color.Black);
}
//UpdateStatusMessage(String.Format("--", Pub.Result.TargetPos), Color.White, Color.Black);
}
}
}
}
else if (PUB.sm.Step == eSMStep.ERROR)
{
UpdateStatusMessage("오류 발생", Color.Red, Color.Black);
}
else if (PUB.sm.Step == eSMStep.PAUSE)
{
UpdateStatusMessage("정지 됨", Color.Tomato, Color.Black);
}
else if (PUB.sm.Step == eSMStep.FINISH)
{
UpdateStatusMessage("작업 완료", Color.Lime, Color.Black);
}
else if (PUB.sm.bPause == true)
{
UpdateStatusMessage("[START]를 누르면 시작 됩니다", Color.Yellow, Color.Black);
}
else
{
string msg = "진행 중";
UpdateStatusMessage(msg, Color.Lime, Color.Black);
}
}
}
}
}
}