This commit is contained in:
chi
2025-06-30 13:48:19 +09:00
parent 02e71d7446
commit 00dd50192b
29 changed files with 2397 additions and 1136 deletions

View File

@@ -19,7 +19,7 @@ namespace Project.Device
public string buffer = string.Empty; public string buffer = string.Empty;
public System.Text.StringBuilder newbuffer = new StringBuilder(); public System.Text.StringBuilder newbuffer = new StringBuilder();
public string errorMessage = string.Empty; public string errorMessage = string.Empty;
public DateTime LastStatusSendTime = DateTime.Now; public DateTime LastStatusSendTime { get; set; } = DateTime.Now;
private EEProtocol proto; private EEProtocol proto;
public class MessageArgs : EventArgs public class MessageArgs : EventArgs

View File

@@ -26,16 +26,11 @@ namespace Project
return; return;
} }
//사용자 스텝처리가 아닌경우에만 검사 //가동불가 조건 확인
//if (Pub.flag.get(eFlag.UserStepCheck) == false) if (CheckStopCondition() == false)
{ {
PUB.sm.SetNewStep(eSMStep.PAUSE);
//가동불가 조건 확인 return;
if (CheckStopCondition() == false)
{
PUB.sm.SetNewStep(eSMStep.PAUSE);
return;
}
} }
//이머전시상태라면 stop 처리한다. //이머전시상태라면 stop 처리한다.
@@ -46,13 +41,6 @@ namespace Project
PUB.sm.SetNewStep(eSMStep.IDLE); 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) if (PUB.sm.RunStep != PUB.sm.RunStepNew)
{ {
@@ -88,7 +76,7 @@ namespace Project
//if (PUB.Result != null && PUB.sm != null) //if (PUB.Result != null && PUB.sm != null)
// EEMStatus.AddEEDBSQL(PUB.sm.Step, PUB.sm.RunStep.ToString(), PUB.Result.TargetPos.ToString()); // EEMStatus.AddEEDBSQL(PUB.sm.Step, PUB.sm.RunStep.ToString(), PUB.Result.TargetPos.ToString());
PUB.Speak(Lang.) ; PUB.Speak(Lang.);
PUB.sm.SetNewRunStep(ERunStep.CHARGECHECK); PUB.sm.SetNewRunStep(ERunStep.CHARGECHECK);
return; return;
} }
@@ -143,8 +131,8 @@ namespace Project
PUB.Speak(Lang.); PUB.Speak(Lang.);
//230601 //230601
// if (PUB.Result != null && PUB.sm != null) // if (PUB.Result != null && PUB.sm != null)
// EEMStatus.AddEEDBSQL(PUB.sm.Step, PUB.sm.RunStep.ToString(), PUB.Result.TargetPos.ToString()); // EEMStatus.AddEEDBSQL(PUB.sm.Step, PUB.sm.RunStep.ToString(), PUB.Result.TargetPos.ToString());
//QA를 제외한 경우에는 기본 QC로 이동한다 //QA를 제외한 경우에는 기본 QC로 이동한다
if (PUB.Result.NextPos == ePosition.QA) if (PUB.Result.NextPos == ePosition.QA)
@@ -184,7 +172,7 @@ namespace Project
PUB.sm.ClearRunStep(); PUB.sm.ClearRunStep();
PUB.Result.TargetPos = ePosition.QC; PUB.Result.TargetPos = ePosition.QC;
PUB.sm.SetNewRunStep(ERunStep.GOHOME); PUB.sm.SetNewRunStep(ERunStep.GOHOME);
PUB.Speak( Lang.); PUB.Speak(Lang.);
} }
return; return;
} }
@@ -198,7 +186,7 @@ namespace Project
else if (_SM_RUN_GOHOME(runStepisFirst, PUB.sm.GetRunSteptime)) else if (_SM_RUN_GOHOME(runStepisFirst, PUB.sm.GetRunSteptime))
{ {
//230601 //230601
// if (PUB.Result != null && PUB.sm != null) // if (PUB.Result != null && PUB.sm != null)
// EEMStatus.AddEEDBSQL(PUB.sm.Step, PUB.sm.RunStep.ToString(), PUB.Result.TargetPos.ToString()); // EEMStatus.AddEEDBSQL(PUB.sm.Step, PUB.sm.RunStep.ToString(), PUB.Result.TargetPos.ToString());
PUB.Speak(Lang.); PUB.Speak(Lang.);
@@ -215,7 +203,7 @@ namespace Project
return true; return true;
} }
void CheckAGVMoveTo(eGoDir dir) void CheckAGVMoveTo(eGoDir dir)
{ {
//계속내려간다 //계속내려간다
@@ -545,7 +533,7 @@ namespace Project
return false; return false;
} }
}//cvass }//cvass
} }

View File

@@ -13,12 +13,12 @@ namespace Project
{ {
public Boolean _SM_RUN_READY(bool isFirst, TimeSpan stepTime) public Boolean _SM_RUN_READY(bool isFirst, TimeSpan stepTime)
{ {
//이동 불가 조건이 걸려있다면 충전을 하지 못하게 한다. ////이동 불가 조건이 걸려있다면 충전을 하지 못하게 한다.
Boolean bAutoChageOn = true; //Boolean bAutoChageOn = true;
if (PUB.AGV.system1.stop_by_front_detect) bAutoChageOn = false; //if (PUB.AGV.system1.stop_by_front_detect) bAutoChageOn = false;
else if (PUB.AGV.error.Emergency) 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_CHARGEONA]) bAutoChageOn = false;
else if (VAR.BOOL[eVarBool.FLAG_CHARGEONM]) bAutoChageOn = false; //else if (VAR.BOOL[eVarBool.FLAG_CHARGEONM]) bAutoChageOn = false;
//자동 충전 중이라면 최대 충전시간과 레벨을 체크한다 //자동 충전 중이라면 최대 충전시간과 레벨을 체크한다
@@ -73,58 +73,58 @@ namespace Project
} }
VAR.STR[eVarString.ChargeCheckMsg] = "현재 위치 모름"; VAR.STR[eVarString.ChargeCheckMsg] = "현재 위치 모름";
} }
else if (PUB.setting.Enable_AutoCharge == true ) //else if (PUB.setting.Enable_AutoCharge == true )
{ //{
if(bAutoChageOn) // if(bAutoChageOn)
{ // {
VAR.BOOL[eVarBool.CHARGE_READY] = true; // VAR.BOOL[eVarBool.CHARGE_READY] = true;
if (PUB.BMS.Current_Level < PUB.setting.ChargeStartLevel) // if (PUB.BMS.Current_Level < PUB.setting.ChargeStartLevel)
{ // {
//레벨에 의한 자동 충전간격은 // //레벨에 의한 자동 충전간격은
var ts = VAR.TIME.RUN(eVarTime.ChargeTry); // var ts = VAR.TIME.RUN(eVarTime.ChargeTry);
if (ts.TotalSeconds >= PUB.setting.ChargeRetryTerm) // if (ts.TotalSeconds >= PUB.setting.ChargeRetryTerm)
{ // {
VAR.I32[eVarInt32.ChargeWaitSec] = 0; // VAR.I32[eVarInt32.ChargeWaitSec] = 0;
VAR.BOOL[eVarBool.CHARGE_WAIT] = false; // VAR.BOOL[eVarBool.CHARGE_WAIT] = false;
PUB.log.Add($"자동충전레벨시작 {PUB.BMS.Current_Level}/{PUB.setting.ChargeStartLevel}"); // PUB.log.Add($"자동충전레벨시작 {PUB.BMS.Current_Level}/{PUB.setting.ChargeStartLevel}");
PUB.sm.ClearRunStep(); // PUB.sm.ClearRunStep();
PUB.sm.SetNewRunStep(ERunStep.GOCHARGE); // PUB.sm.SetNewRunStep(ERunStep.GOCHARGE);
PUB.sm.SetNewStep(eSMStep.RUN); // PUB.sm.SetNewStep(eSMStep.RUN);
PUB.AddEEDB($"자동충전레벨시작 {PUB.BMS.Current_Level}/{PUB.setting.ChargeStartLevel}"); // PUB.AddEEDB($"자동충전레벨시작 {PUB.BMS.Current_Level}/{PUB.setting.ChargeStartLevel}");
} // }
else // else
{ // {
VAR.I32[eVarInt32.ChargeWaitSec] = (int)(PUB.setting.ChargeRetryTerm - ts.TotalSeconds); // VAR.I32[eVarInt32.ChargeWaitSec] = (int)(PUB.setting.ChargeRetryTerm - ts.TotalSeconds);
VAR.BOOL[eVarBool.CHARGE_WAIT] = true; // VAR.BOOL[eVarBool.CHARGE_WAIT] = true;
} // }
VAR.STR[eVarString.ChargeCheckMsg] = "배터리 충전 레벨 필요"; // VAR.STR[eVarString.ChargeCheckMsg] = "배터리 충전 레벨 필요";
} // }
else // else
{ // {
//아직 레벨이 높다 // //아직 레벨이 높다
VAR.BOOL[eVarBool.CHARGE_READY] = false; // VAR.BOOL[eVarBool.CHARGE_READY] = false;
VAR.I32[eVarInt32.ChargeWaitSec] = 0; // VAR.I32[eVarInt32.ChargeWaitSec] = 0;
VAR.BOOL[eVarBool.CHARGE_WAIT] = false; // VAR.BOOL[eVarBool.CHARGE_WAIT] = false;
VAR.STR[eVarString.ChargeCheckMsg] = "배터리 레벨상 충전 불필요"; // VAR.STR[eVarString.ChargeCheckMsg] = "배터리 레벨상 충전 불필요";
} // }
} // }
else // else
{ // {
VAR.BOOL[eVarBool.CHARGE_READY] = false; // VAR.BOOL[eVarBool.CHARGE_READY] = false;
VAR.I32[eVarInt32.ChargeWaitSec] = 0; // VAR.I32[eVarInt32.ChargeWaitSec] = 0;
VAR.BOOL[eVarBool.CHARGE_WAIT] = false; // VAR.BOOL[eVarBool.CHARGE_WAIT] = false;
VAR.STR[eVarString.ChargeCheckMsg] = "충전 불가 조건"; // VAR.STR[eVarString.ChargeCheckMsg] = "충전 불가 조건";
//충전조건이 맞지 않는다 // //충전조건이 맞지 않는다
} // }
} //}
else //else
{ //{
VAR.BOOL[eVarBool.CHARGE_READY] = false; // VAR.BOOL[eVarBool.CHARGE_READY] = false;
VAR.I32[eVarInt32.ChargeWaitSec] = 0; // VAR.I32[eVarInt32.ChargeWaitSec] = 0;
VAR.BOOL[eVarBool.CHARGE_WAIT] = false; // VAR.BOOL[eVarBool.CHARGE_WAIT] = false;
//자동충전이 해제된 상태이므로 처리하지 않는다 // //자동충전이 해제된 상태이므로 처리하지 않는다
VAR.STR[eVarString.ChargeCheckMsg] = "자동 충전 해제 됨"; // VAR.STR[eVarString.ChargeCheckMsg] = "자동 충전 해제 됨";
} //}
//대기모드에서는 움직이지 않게 한다 //대기모드에서는 움직이지 않게 한다
if(PUB.AGV.system1.agv_run) if(PUB.AGV.system1.agv_run)

View File

@@ -41,31 +41,7 @@ namespace Project
{ {
try try
{ {
if (PUB.mapctl != null) //데이터 파싱
{
var rlt = AGVControl.MapControlManager.PredictNextAction();
if (rlt.ReasonCode == AGVControl.AGVActionReasonCode.busy)
{
//var premsg = $"이전 예측작업이 완료되지 않았습니다";
//PUB.log.AddE(premsg);
//PUB.log.AddE(premsg);
//Console.WriteLine(premsg);
//predicterr += 1;
//if (predicterr > 10)
//{
// var premsg = $"행동예측 오류카운트 초과";
// PUB.AGV.AGVMoveStop(premsg);
// PUB.log.AddE(premsg);
// PUB.logagv.AddE(premsg);
// Console.WriteLine(premsg);
//}
}
}
switch (e.DataType) switch (e.DataType)
{ {
case arDev.Narumi.DataType.STS: case arDev.Narumi.DataType.STS:
@@ -83,12 +59,12 @@ namespace Project
//모터방향 입력 //모터방향 입력
if (PUB.AGV.data.Direction == 'B') if (PUB.AGV.data.Direction == 'B')
AGVControl.MapControlManager.agv.CurrentMOTDirection = AGVControl.Models.Direction.Backward; PUB.mapctl.Manager.agv.CurrentMOTDirection = AGVControl.Direction.Backward;
else else
AGVControl.MapControlManager.agv.CurrentMOTDirection = AGVControl.Models.Direction.Forward; PUB.mapctl.Manager.agv.CurrentMOTDirection = AGVControl.Direction.Forward;
AGVControl.MapControlManager.agv.IsMoving = PUB.AGV.system1.agv_run; PUB.mapctl.Manager.agv.IsMoving = PUB.AGV.system1.agv_run;
AGVControl.MapControlManager.agv.IsMarkCheck = PUB.AGV.system1.Mark1_check || PUB.AGV.system1.Mark2_check; PUB.mapctl.Manager.agv.IsMarkCheck = PUB.AGV.system1.Mark1_check || PUB.AGV.system1.Mark2_check;
if (PUB.AGV.signal.mark_sensor == false) if (PUB.AGV.signal.mark_sensor == false)
{ {
@@ -201,10 +177,8 @@ namespace Project
else else
{ {
//위치는 찾았다 해당 위치가 내 목적지라면 mark stop기능으로 전환한다 //위치는 찾았다 해당 위치가 내 목적지라면 mark stop기능으로 전환한다
} }
////자동, 상하차 모드일때 RFID 가 타겟위치에 올때는 - 멈춤을 설정해준다 ////자동, 상하차 모드일때 RFID 가 타겟위치에 올때는 - 멈춤을 설정해준다
//if (VAR.BOOL[eVarBool.FLAG_AUTORUN] == true && //if (VAR.BOOL[eVarBool.FLAG_AUTORUN] == true &&
// PUB.Result.CurrentPos == PUB.Result.TargetPos && // PUB.Result.CurrentPos == PUB.Result.TargetPos &&
@@ -237,12 +211,19 @@ namespace Project
break; break;
} }
//이 후 상황을 예측한다
if (PUB.mapctl != null)
{
var rlt = PUB.mapctl.Manager.PredictNextAction();
if (rlt.Changed)
Console.WriteLine($"[new] predict idx:{rlt.Idx}");
}
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine($"[AGV_DataReceive] {ex.Message}"); Console.WriteLine($"[AGV_DataReceive] {ex.Message}");
} }
} }
} }
} }

View File

@@ -158,9 +158,10 @@ namespace Project
private void Bms_BMSDataReceive(object sender, EventArgs e) private void Bms_BMSDataReceive(object sender, EventArgs e)
{ {
AGVControl.MapControlManager.agv.BatteryLevel = PUB.BMS.Current_Level;
AGVControl.MapControlManager.agv.BatteryTemp1 = PUB.BMS.Current_temp1; PUB.mapctl.Manager.agv.BatteryLevel = PUB.BMS.Current_Level;
AGVControl.MapControlManager.agv.BatteryTemp2 = PUB.BMS.Current_temp2; PUB.mapctl.Manager.agv.BatteryTemp1 = PUB.BMS.Current_temp1;
PUB.mapctl.Manager.agv.BatteryTemp2 = PUB.BMS.Current_temp2;
if (PUB.BMS.Current_Level <= PUB.setting.ChargeStartLevel) if (PUB.BMS.Current_Level <= PUB.setting.ChargeStartLevel)
{ {
//배터리 레벨이 기준보다 낮다면 경고를 활성화 한다 //배터리 레벨이 기준보다 낮다면 경고를 활성화 한다

View File

@@ -163,10 +163,7 @@ namespace Project
{ {
PUB.BMS.SendQuery(); PUB.BMS.SendQuery();
} }
Update_BatteryWarnSpeak(); Update_BatteryWarnSpeak();
} }
} }
} }

View File

@@ -25,6 +25,25 @@ namespace Project
var data = e.ReceivedPacket.Data; var data = e.ReceivedPacket.Data;
var dataStr = System.Text.Encoding.Default.GetString(data); var dataStr = System.Text.Encoding.Default.GetString(data);
var cmd = (ENIGProtocol.AGVCommands)e.ReceivedPacket.Command; var cmd = (ENIGProtocol.AGVCommands)e.ReceivedPacket.Command;
var TargetID = 0;
if (dataStr.Length >= 2)
{
//대상디바이스
TargetID = Convert.ToByte(dataStr.Substring(0, 2), 16);
//데이터영역을 다시 설정
if (dataStr.Length > 2) dataStr = dataStr.Substring(2);
else dataStr = string.Empty;
}
else
{
PUB.log.Add($"ACS 데이터에서 TARGET ID가 없습니다(data : first byte)");
}
if (PUB.setting.XBE_ID != TargetID)
return;
switch (cmd) switch (cmd)
{ {
@@ -60,7 +79,7 @@ namespace Project
case ENIGProtocol.AGVCommands.Goto: //move to tag case ENIGProtocol.AGVCommands.Goto: //move to tag
if (uint.TryParse(dataStr, out uint tagno2)) if (uint.TryParse(dataStr, out uint tagno2))
{ {
var currPos = AGVControl.MapControlManager.agv.CurrentRFID;///.AGVMoveToRFID(; var currPos = PUB.mapctl.Manager.agv.CurrentRFID;///.AGVMoveToRFID(;
if (PUB.mapctl.SetTargetPosition(tagno2)) if (PUB.mapctl.SetTargetPosition(tagno2))
PUB.log.AddI($"New Target {tagno2}"); PUB.log.AddI($"New Target {tagno2}");
else else

View File

@@ -172,7 +172,7 @@ namespace Project
MenuLift.Text = "LIFT"; MenuLift.Text = "LIFT";
toolTip1.SetToolTip(MenuLift, "I/O 및 FLAG를 확인 합니다"); toolTip1.SetToolTip(MenuLift, "I/O 및 FLAG를 확인 합니다");
MenuLift.UseVisualStyleBackColor = true; MenuLift.UseVisualStyleBackColor = true;
MenuLift.Click += button3_Click; MenuLift.Click += MenuLift_Click;
// //
// MenuMAN // MenuMAN
// //
@@ -189,7 +189,7 @@ namespace Project
MenuMAN.Text = "MANUAL"; MenuMAN.Text = "MANUAL";
toolTip1.SetToolTip(MenuMAN, "작업 내역을 확인 합니다"); toolTip1.SetToolTip(MenuMAN, "작업 내역을 확인 합니다");
MenuMAN.UseVisualStyleBackColor = true; MenuMAN.UseVisualStyleBackColor = true;
MenuMAN.Click += button4_Click; MenuMAN.Click += ManualMan_Click;
// //
// MenuFlag // MenuFlag
// //
@@ -206,7 +206,7 @@ namespace Project
MenuFlag.Text = "FLAG"; MenuFlag.Text = "FLAG";
toolTip1.SetToolTip(MenuFlag, "I/O 및 FLAG를 확인 합니다"); toolTip1.SetToolTip(MenuFlag, "I/O 및 FLAG를 확인 합니다");
MenuFlag.UseVisualStyleBackColor = true; MenuFlag.UseVisualStyleBackColor = true;
MenuFlag.Click += button1_Click; MenuFlag.Click += btMenuFlag_Click;
// //
// MenuAuto // MenuAuto
// //
@@ -223,7 +223,7 @@ namespace Project
MenuAuto.Text = "AUTO"; MenuAuto.Text = "AUTO";
toolTip1.SetToolTip(MenuAuto, "작업 내역을 확인 합니다"); toolTip1.SetToolTip(MenuAuto, "작업 내역을 확인 합니다");
MenuAuto.UseVisualStyleBackColor = true; MenuAuto.UseVisualStyleBackColor = true;
MenuAuto.Click += button2_Click; MenuAuto.Click += btMenuAuto_Click;
// //
// MenuLog // MenuLog
// //
@@ -258,7 +258,7 @@ namespace Project
MenuAGV.Text = "AGV"; MenuAGV.Text = "AGV";
toolTip1.SetToolTip(MenuAGV, "I/O 및 FLAG를 확인 합니다"); toolTip1.SetToolTip(MenuAGV, "I/O 및 FLAG를 확인 합니다");
MenuAGV.UseVisualStyleBackColor = false; MenuAGV.UseVisualStyleBackColor = false;
MenuAGV.Click += button1_Click_1; MenuAGV.Click += btMenuAGV_Click_1;
// //
// MenuBMS // MenuBMS
// //
@@ -275,7 +275,7 @@ namespace Project
MenuBMS.Text = "BMS"; MenuBMS.Text = "BMS";
toolTip1.SetToolTip(MenuBMS, "I/O 및 FLAG를 확인 합니다"); toolTip1.SetToolTip(MenuBMS, "I/O 및 FLAG를 확인 합니다");
MenuBMS.UseVisualStyleBackColor = true; MenuBMS.UseVisualStyleBackColor = true;
MenuBMS.Click += button2_Click_1; MenuBMS.Click += btMenuBMS_Click_1;
// //
// btAutoRun // btAutoRun
// //
@@ -323,7 +323,7 @@ namespace Project
btAutoRun.TextShadow = true; btAutoRun.TextShadow = true;
btAutoRun.TextVisible = true; btAutoRun.TextVisible = true;
toolTip1.SetToolTip(btAutoRun, "작업상태(자동/수동)를 표시 합니다"); toolTip1.SetToolTip(btAutoRun, "작업상태(자동/수동)를 표시 합니다");
btAutoRun.Click += btStart_Click; btAutoRun.Click += btAutorun_Click;
// //
// btChargeA // btChargeA
// //
@@ -837,14 +837,12 @@ namespace Project
gridviewTestToolStripMenuItem.Name = "gridviewTestToolStripMenuItem"; gridviewTestToolStripMenuItem.Name = "gridviewTestToolStripMenuItem";
gridviewTestToolStripMenuItem.Size = new Size(228, 22); gridviewTestToolStripMenuItem.Size = new Size(228, 22);
gridviewTestToolStripMenuItem.Text = "GridviewTest"; gridviewTestToolStripMenuItem.Text = "GridviewTest";
gridviewTestToolStripMenuItem.Click += gridviewTestToolStripMenuItem_Click;
// //
// 으ㅆㄷㄴㅅToolStripMenuItem // 으ㅆㄷㄴㅅToolStripMenuItem
// //
ToolStripMenuItem.Name = "으ㅆㄷㄴㅅToolStripMenuItem"; ToolStripMenuItem.Name = "으ㅆㄷㄴㅅToolStripMenuItem";
ToolStripMenuItem.Size = new Size(228, 22); ToolStripMenuItem.Size = new Size(228, 22);
ToolStripMenuItem.Text = "Test DataMatrix StripID"; ToolStripMenuItem.Text = "Test DataMatrix StripID";
ToolStripMenuItem.Click += ToolStripMenuItem_Click;
// //
// messageToolStripMenuItem // messageToolStripMenuItem
// //
@@ -879,7 +877,6 @@ namespace Project
reloadLotListToolStripMenuItem.Name = "reloadLotListToolStripMenuItem"; reloadLotListToolStripMenuItem.Name = "reloadLotListToolStripMenuItem";
reloadLotListToolStripMenuItem.Size = new Size(228, 22); reloadLotListToolStripMenuItem.Size = new Size(228, 22);
reloadLotListToolStripMenuItem.Text = "Reload Lot List"; reloadLotListToolStripMenuItem.Text = "Reload Lot List";
reloadLotListToolStripMenuItem.Click += reloadLotListToolStripMenuItem_Click;
// //
// moveSourceListToDestListToolStripMenuItem // moveSourceListToDestListToolStripMenuItem
// //
@@ -1044,7 +1041,7 @@ namespace Project
btHome.TextAlign = ContentAlignment.MiddleCenter; btHome.TextAlign = ContentAlignment.MiddleCenter;
btHome.TextShadow = true; btHome.TextShadow = true;
btHome.TextVisible = true; btHome.TextVisible = true;
btHome.Click += arLabel1_Click; btHome.Click += brHome_Click;
// //
// btChargeM // btChargeM
// //

View File

@@ -26,6 +26,7 @@ namespace Project
ViewForm.fFlag form_flag = null; ViewForm.fFlag form_flag = null;
ViewForm.fAgv form_agv = null; ViewForm.fAgv form_agv = null;
ViewForm.fBms form_bms = null; ViewForm.fBms form_bms = null;
Dialog.fLog form_log = null;
readonly usbdetect.DriveDetector usbdet; readonly usbdetect.DriveDetector usbdet;
public fMain() public fMain()
@@ -59,6 +60,10 @@ namespace Project
this.FormClosing += __Closing; this.FormClosing += __Closing;
if (PUB.setting.FullScreen) this.WindowState = FormWindowState.Maximized; if (PUB.setting.FullScreen) this.WindowState = FormWindowState.Maximized;
lbTime.Click += (s1,e1) => {
PUB.mapctl.ShowDesign();
};
} }
protected override void WndProc(ref Message m) protected override void WndProc(ref Message m)
@@ -240,10 +245,10 @@ namespace Project
this.btDebug.Visible = PUB.setting.UseDebugMode; this.btDebug.Visible = PUB.setting.UseDebugMode;
PUB.log.Add("Program Start"); PUB.log.Add("Program Start");
UpdateControlText();
//수량표시 //수량표시
PUB.counter.PropertyChanged += Counter_PropertyChanged; PUB.counter.PropertyChanged += (s1, e1) => Update_Count();
Update_Count(); Update_Count();
PUB.log.Add("프로그램 실행 기록 추가"); PUB.log.Add("프로그램 실행 기록 추가");
@@ -256,15 +261,6 @@ namespace Project
} }
private void Counter_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
//수량에 변화가 잇다면 업데이트 한다
Update_Count();
}
#region "Mouse Form Move" #region "Mouse Form Move"
private Boolean fMove = false; private Boolean fMove = false;
@@ -296,6 +292,137 @@ namespace Project
} }
#endregion #endregion
void socket_SendMessage(object sender, Device.Socket.SocketMessageEventArgs e)
{
//핑로그가 꺼져있는 상황일때 핑로그는 로그를 기록하지 않는다. 181205
if (!PUB.setting.Log_Ping && e.Message.Type == Device.Socket.eType.REPLY && e.Message.SType == Device.Socket.eSType.STATUS)
{
return;
}
PUB.log.Add("WS << " + e.rawData);
}
void socket_RecvMessage(object sender, Device.Socket.SocketMessageEventArgs e)
{
if (e.Message.isError)
PUB.log.AddE("WS >> " + e.Message.ErrorMessage + ",RAW=" + e.rawData);
else
{
switch (e.Message.Type)
{
case Device.Socket.eType.REQUEST:
if (e.Message.SType == Device.Socket.eSType.STATUS)
{
var packet = PUB.sock_debug.makeReplyStatus(Device.Socket.eStatus.IDLE);
var rlt = PUB.sock_debug.Send(PUB.setting.Asset, Device.Socket.eType.REPLY, Device.Socket.eSType.STATUS, packet);
if (!rlt)
{
PUB.log.AddE("Status Reply Error");
}
else
{
if (PUB.setting.Log_Ping) PUB.log.AddI("Server Status Reply OK");
}
}
else
{
PUB.log.Add("WS >> " + e.rawData);
}
break;
}
}
}
void socket_GetMessage(object sender, Device.Socket.MesasgeEventArgs e)
{
if (e.isError) PUB.log.AddE("WS:" + e.Message);
else PUB.log.Add("WS:" + e.Message);
}
delegate void SelectModelHandler(string modelName);
void SelectModelM(string modelName)
{
if (this.InvokeRequired)
{
this.Invoke(new SelectModelHandler(SelectModelM), new object[] { modelName });
return;
}
}
void func_sw_start(bool Prompt = false)
{
if (VAR.BOOL[eVarBool.FLAG_AUTORUN] == false) //자동상태가 아니라면
{
PUB.AGV.AGVErrorReset();
if (Prompt)
{
if (UTIL.MsgQ("AGV상태를 자동으로 전환 할까요?") != DialogResult.Yes) return;
}
//충전상태확인
if (PUB.CheckManualChargeMode() == false) return;
PUB.popup.needClose = true;
PUB.sm.bPause = false;
PUB.sm.SetNewStep(eSMStep.RUN);
if (PUB.Result.CurrentPos == ePosition.NONE || PUB.Result.TargetPos == ePosition.NONE)
{
PUB.sm.SetNewRunStep(ERunStep.GOHOME);
}
PUB.Speak(Lang.);
}
else
{
PUB.AGV.AGVCharge(PUB.setting.ChargerID, false); //230425 수동전환하면 충전 해제한다
PUB.sm.SetNewStep(eSMStep.IDLE);
PUB.Speak(Lang.);
}
}
void Resultclear()
{
PUB.Result.Clear();
PUB.log.AddI("Clear Resultclear");
}
void CheckFreeSpace()
{
try
{
if (PUB.path.FullName.StartsWith("\\"))
{
SSInfo.setTitle(0, 1, "UNC Path Detected");
SSInfo.setValue(0, 1, 2);
}
else
{
double freeSpaceRate_ = PUB.GetFreeSpace();
this.freeSpaceRate = freeSpaceRate_;
SSInfo.setTitle(0, 1, "FREE(" + PUB.path.FullName.Substring(0, 1) + ") : " + freeSpaceRate.ToString("N2") + "%");
if (freeSpaceRate < PUB.setting.AutoDeleteThreshold)
{
VAR.BOOL[eVarBool.MINSPACE] = true;
SSInfo.setValue(0, 1, 2); //lbFreeSpace.ForeColor = Color.Tomato;
}
else
{
VAR.BOOL[eVarBool.MINSPACE] = false;
SSInfo.setValue(0, 1, 3);// lbFreeSpace.ForeColor = Color.White;
}
}
//Pub.log.Add("남은디스크공간확인:" + freeSpaceRate.ToString("N2") + "%"); 190129
}
catch (Exception ex)
{
SSInfo.setTitle(0, 1, "FREE SPACE : -ERROR-");
PUB.log.AddE("check free space : " + ex.Message);
}
}
private void CtlPos1_ItemClick(object sender, CtlPos.ItemClickEventArgs e) private void CtlPos1_ItemClick(object sender, CtlPos.ItemClickEventArgs e)
@@ -451,191 +578,16 @@ namespace Project
if (dlg != null) dlg.Dispose(); if (dlg != null) dlg.Dispose();
} }
void socket_SendMessage(object sender, Device.Socket.SocketMessageEventArgs e)
{
//핑로그가 꺼져있는 상황일때 핑로그는 로그를 기록하지 않는다. 181205
if (!PUB.setting.Log_Ping && e.Message.Type == Device.Socket.eType.REPLY && e.Message.SType == Device.Socket.eSType.STATUS)
{
return;
}
PUB.log.Add("WS << " + e.rawData);
}
void socket_RecvMessage(object sender, Device.Socket.SocketMessageEventArgs e)
{
if (e.Message.isError)
PUB.log.AddE("WS >> " + e.Message.ErrorMessage + ",RAW=" + e.rawData);
else
{
switch (e.Message.Type)
{
case Device.Socket.eType.REQUEST:
if (e.Message.SType == Device.Socket.eSType.STATUS)
{
var packet = PUB.sock_debug.makeReplyStatus(Device.Socket.eStatus.IDLE);
var rlt = PUB.sock_debug.Send(PUB.setting.Asset, Device.Socket.eType.REPLY, Device.Socket.eSType.STATUS, packet);
if (!rlt)
{
PUB.log.AddE("Status Reply Error");
}
else
{
if (PUB.setting.Log_Ping) PUB.log.AddI("Server Status Reply OK");
}
}
else
{
PUB.log.Add("WS >> " + e.rawData);
}
break;
}
}
}
void socket_GetMessage(object sender, Device.Socket.MesasgeEventArgs e)
{
if (e.isError) PUB.log.AddE("WS:" + e.Message);
else PUB.log.Add("WS:" + e.Message);
}
delegate void SelectModelHandler(string modelName);
void SelectModelM(string modelName)
{
if (this.InvokeRequired)
{
this.Invoke(new SelectModelHandler(SelectModelM), new object[] { modelName });
return;
}
}
void func_sw_start(bool Prompt = false)
{
if (VAR.BOOL[eVarBool.FLAG_AUTORUN] == false) //자동상태가 아니라면
{
PUB.AGV.AGVErrorReset();
if (Prompt)
{
if (UTIL.MsgQ("AGV상태를 자동으로 전환 할까요?") != DialogResult.Yes) return;
}
//충전상태확인
if (PUB.CheckManualChargeMode() == false) return;
PUB.popup.needClose = true;
PUB.sm.bPause = false;
PUB.sm.SetNewStep(eSMStep.RUN);
if (PUB.Result.CurrentPos == ePosition.NONE || PUB.Result.TargetPos == ePosition.NONE)
{
PUB.sm.SetNewRunStep(ERunStep.GOHOME);
}
PUB.Speak(Lang.);
}
else
{
PUB.AGV.AGVCharge(PUB.setting.ChargerID, false); //230425 수동전환하면 충전 해제한다
PUB.sm.SetNewStep(eSMStep.IDLE);
PUB.Speak(Lang.);
}
}
void Resultclear()
{
PUB.Result.Clear();
PUB.log.AddI("Clear Resultclear");
}
void CheckFreeSpace()
{
try
{
if (PUB.path.FullName.StartsWith("\\"))
{
SSInfo.setTitle(0, 1, "UNC Path Detected");
SSInfo.setValue(0, 1, 2);
}
else
{
double freeSpaceRate_ = PUB.GetFreeSpace();
this.freeSpaceRate = freeSpaceRate_;
SSInfo.setTitle(0, 1, "FREE(" + PUB.path.FullName.Substring(0, 1) + ") : " + freeSpaceRate.ToString("N2") + "%");
if (freeSpaceRate < PUB.setting.AutoDeleteThreshold)
{
VAR.BOOL[eVarBool.MINSPACE] = true;
SSInfo.setValue(0, 1, 2); //lbFreeSpace.ForeColor = Color.Tomato;
}
else
{
VAR.BOOL[eVarBool.MINSPACE] = false;
SSInfo.setValue(0, 1, 3);// lbFreeSpace.ForeColor = Color.White;
}
}
//Pub.log.Add("남은디스크공간확인:" + freeSpaceRate.ToString("N2") + "%"); 190129
}
catch (Exception ex)
{
SSInfo.setTitle(0, 1, "FREE SPACE : -ERROR-");
PUB.log.AddE("check free space : " + ex.Message);
}
}
private void demoRunToolStripMenuItem_Click(object sender, EventArgs e) private void demoRunToolStripMenuItem_Click(object sender, EventArgs e)
{ {
PUB.Result.JobEndTime = DateTime.Now; PUB.Result.JobEndTime = DateTime.Now;
// Pub.flag.Toggle(eFlag.DemoRun);
// Pub.log.AddAT(string.Format("데모변경: {0}", Pub.flag.get(eFlag.DemoRun)));
} }
private void openMapFileToolStripMenuItem_Click(object sender, EventArgs e)
{
using (OpenFileDialog od = new OpenFileDialog())
if (od.ShowDialog() != System.Windows.Forms.DialogResult.OK) return;
//if (orgImage != null) orgImage.Dispose();
}
private void setZValidToolStripMenuItem_Click(object sender, EventArgs e) private void setZValidToolStripMenuItem_Click(object sender, EventArgs e)
{ {
PUB.log.Add("user set z-home set on"); PUB.log.Add("user set z-home set on");
} }
private void gridviewTestToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
/////HB9225-4280A 0901
//var striplist = new string[]{
// "HB9125-7560A 0704",
//"HB9125-7800A 0104",
//"HB9125-8480A 0701",
//"HB9130-8550A 5108",
//"HB9130-8620A 0701",
//"HB9131-9340A 0201",
//"HB9206-0810A 5301",
//"HB9206-0820A 0902",
//"HB9222-3020A 0208",
//"HB9222-3020A 0508",
//"HB9222-3720A 0205",
//"HB9222-3720A 0902",
//"HB9225-3790A 0604",
//"HB9225-4280A 0901",
//"HB9228-4840A 0104",
//"HB9228-4840A 5908",
//"HB9313-7600A 1006",
//"HB9319-9540A 6003",
//"ZGP490510700 1305"
//};
}
private void errorToolStripMenuItem_Click(object sender, EventArgs e) private void errorToolStripMenuItem_Click(object sender, EventArgs e)
{ {
PUB.popup.setMessage("error\berror message"); PUB.popup.setMessage("error\berror message");
@@ -651,12 +603,6 @@ namespace Project
PUB.popup.setMessage("attention\nattention message", MessageWindow.eWindowType.attention); PUB.popup.setMessage("attention\nattention message", MessageWindow.eWindowType.attention);
} }
private void reloadLotListToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void arLabel3_Click(object sender, EventArgs e) private void arLabel3_Click(object sender, EventArgs e)
{ {
@@ -676,11 +622,6 @@ namespace Project
this.Close(); this.Close();
} }
void UpdateControlText()
{
}
private void arLabel5_Click(object sender, EventArgs e) private void arLabel5_Click(object sender, EventArgs e)
{ {
//SetScreen(form_setup); //SetScreen(form_setup);
@@ -700,7 +641,7 @@ namespace Project
} }
VAR.BOOL[eVarBool.FLAG_SETUP] = false;// VAR.BOOL[eVarBool.FLAG_SETUP] = false;//VAR.BOOL[eVarBool.FLAG_SETUP] = false; VAR.BOOL[eVarBool.FLAG_SETUP] = false;// VAR.BOOL[eVarBool.FLAG_SETUP] = false;//VAR.BOOL[eVarBool.FLAG_SETUP] = false;
UpdateControlText();
if (popmsg) PUB.popup.Visible = true; if (popmsg) PUB.popup.Visible = true;
} }
@@ -737,13 +678,13 @@ namespace Project
UTIL.RunExplorer(UTIL.CurrentPath); UTIL.RunExplorer(UTIL.CurrentPath);
} }
private void button4_Click(object sender, EventArgs e) private void ManualMan_Click(object sender, EventArgs e)
{ {
SetScreen(form_manu); SetScreen(form_manu);
MenuMAN.ForeColor = Color.Gold; MenuMAN.ForeColor = Color.Gold;
} }
private void button3_Click(object sender, EventArgs e) private void MenuLift_Click(object sender, EventArgs e)
{ {
SetScreen(form_zlift); SetScreen(form_zlift);
MenuLift.ForeColor = Color.Gold; MenuLift.ForeColor = Color.Gold;
@@ -755,7 +696,7 @@ namespace Project
this.cmDebug.Show(ctl, new Point((int)(ctl.Width / 1.5), (int)(ctl.Height / 1.5))); this.cmDebug.Show(ctl, new Point((int)(ctl.Width / 1.5), (int)(ctl.Height / 1.5)));
} }
private void btStart_Click(object sender, EventArgs e) private void btAutorun_Click(object sender, EventArgs e)
{ {
var ctl = sender as arCtl.arLabel; var ctl = sender as arCtl.arLabel;
if (ctl.Enabled == false) return; if (ctl.Enabled == false) return;
@@ -763,20 +704,18 @@ namespace Project
func_sw_start(true); func_sw_start(true);
} }
private void button2_Click(object sender, EventArgs e) private void btMenuAuto_Click(object sender, EventArgs e)
{ {
SetScreen(form_auto); SetScreen(form_auto);
MenuAuto.ForeColor = Color.Gold; MenuAuto.ForeColor = Color.Gold;
} }
private void button1_Click(object sender, EventArgs e) private void btMenuFlag_Click(object sender, EventArgs e)
{ {
SetScreen(form_flag); SetScreen(form_flag);
MenuFlag.ForeColor = Color.Gold; MenuFlag.ForeColor = Color.Gold;
} }
Dialog.fLog form_log = null;
private void btLog_Click(object sender, EventArgs e) private void btLog_Click(object sender, EventArgs e)
{ {
if (form_log == null || form_log.IsDisposed || form_log.Disposing) if (form_log == null || form_log.IsDisposed || form_log.Disposing)
@@ -844,8 +783,7 @@ namespace Project
PUB.Speak("고경석 수석님 밥은 드셨습니까?", true); PUB.Speak("고경석 수석님 밥은 드셨습니까?", true);
UpdateProgressStatus(20, 100, "progre"); UpdateProgressStatus(20, 100, "progre");
} }
private void brHome_Click(object sender, EventArgs e)
private void arLabel1_Click(object sender, EventArgs e)
{ {
var bCharge = PUB.sm.Step == eSMStep.RUN && var bCharge = PUB.sm.Step == eSMStep.RUN &&
(PUB.sm.RunStep == ERunStep.GOHOME); (PUB.sm.RunStep == ERunStep.GOHOME);
@@ -878,30 +816,6 @@ namespace Project
} }
//private void btChargeM_Click(object sender, EventArgs e)
//{
// var bCharge = PUB.flag.get(EFlag.FLAG_CHARGEONM);
// //충전을 시작해라ㅏ
// if (bCharge == true)
// {
// var dlg = Util.MsgQ("수동 충전 상태를 해제 할까요?");
// if (dlg == DialogResult.Yes)
// {
// PUB.flag.set(EFlag.FLAG_CHARGEONM, false);
// Pub.log.Add("수동 충전 상태 해제");
// }
// }
// else
// {
// var dlg = Util.MsgQ("수동 충전 상태를 설정 할까요?\n수동충전이 설정되면 AGV는 움직지 않습니다");
// if (dlg == DialogResult.Yes)
// {
// PUB.flag.set(EFlag.FLAG_CHARGEONM, true);
// Pub.log.Add("수동 충전 상태 설정");
// }
// }
//}
private void arLabel2_Click_1(object sender, EventArgs e) private void arLabel2_Click_1(object sender, EventArgs e)
{ {
@@ -911,17 +825,18 @@ namespace Project
private void lbCNtUp_Click(object sender, EventArgs e) private void lbCNtUp_Click(object sender, EventArgs e)
{ {
//down,up둘다 연결해야함
using (var f = new Dialog.fCounter()) using (var f = new Dialog.fCounter())
f.ShowDialog(); f.ShowDialog();
} }
private void button1_Click_1(object sender, EventArgs e) private void btMenuAGV_Click_1(object sender, EventArgs e)
{ {
SetScreen(form_agv); SetScreen(form_agv);
MenuAGV.ForeColor = Color.Gold; MenuAGV.ForeColor = Color.Gold;
} }
private void button2_Click_1(object sender, EventArgs e) private void btMenuBMS_Click_1(object sender, EventArgs e)
{ {
SetScreen(form_bms); SetScreen(form_bms);
MenuBMS.ForeColor = Color.Gold; MenuBMS.ForeColor = Color.Gold;
@@ -971,5 +886,10 @@ namespace Project
PUB.log.Add("수동 충전 실행"); PUB.log.Add("수동 충전 실행");
} }
} }
private void lbTime_Click(object sender, EventArgs e)
{
PUB.mapctl.ShowDesign();
}
} }
} }

View File

@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<root> <root>
<!-- <!--
Microsoft ResX Schema Microsoft ResX Schema
Version 2.0 Version 2.0
The primary goals of this format is to allow a simple XML format The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes various data types are done through the TypeConverter classes
associated with the data types. associated with the data types.
Example: Example:
... ado.net/XML headers & schema ... ... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader> <resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader> <resheader name="version">2.0</resheader>
@@ -26,36 +26,36 @@
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment> <comment>This is a comment</comment>
</data> </data>
There are any number of "resheader" rows that contain simple There are any number of "resheader" rows that contain simple
name/value pairs. name/value pairs.
Each data row contains a name, and value. The row also contains a Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture. text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the Classes that don't support this are serialized and stored with the
mimetype set. mimetype set.
The mimetype is used for serialized objects, and tells the The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly: extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below. read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64 mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64 mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64 mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter : using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
--> -->

View File

@@ -1,105 +1,152 @@
[RFID_POINTS] [RFID_POINTS]
100,486,517 100,486,517,False,,False
173,488,516 162,487,516,False,,False
230,493,515 230,493,515,False,,False
309,489,514 309,489,514,False,,False
370,490,513 370,490,513,False,,False
437,487,512 429,487,512,False,Forward,False
483,459,511 488,476,511,False,,False
511,421,510 538,445,510,False,,False
543,371,509 576,393,509,False,,False
569,329,508 598,343,508,False,,False
608,289,507 621,287,507,True,,False
661,279,506 671,293,506,False,,False
701,297,505 702,314,505,False,,False
698,349,504 711,354,504,False,,False
698,391,503 711,396,503,False,,False
699,449,502 707,454,502,False,,False
691,491,501 685,499,501,False,Forward,False
570,275,400 566,281,400,False,,False
517,264,401 504,274,401,False,,False
454,264,402 439,271,402,False,,False
388,262,403 383,267,403,False,,False
315,258,404 311,260,404,False,Forward,False
639,234,600 633,237,600,False,,False
621,182,601 609,186,601,False,,False
641,183,602 639,184,602,False,,False
657,101,603 657,101,603,False,,False
627,82,604 627,82,604,False,,False
560,73,605 560,73,605,False,,False
499,65,606 499,65,606,False,,False
432,65,607 432,65,607,False,Forward,False
264,232,405 242,239,405,False,Forward,True
363,60,608 363,60,608,False,Forward,True
654,508,500 633,547,500,False,Forward,True
96,542,100 96,542,100,False,Forward,True
159,542,101 159,542,101,False,Forward,True
226,542,102 226,542,102,False,Forward,True
309,541,103 310,541,103,False,Forward,True
369,542,104 369,542,104,False,Forward,True
483,165,753 397,166,753,False,Backward,True
735,163,700 847,152,700,False,Backward,True
523,170,752 484,169,752,False,Backward,False
565,175,751 535,176,751,False,,False
597,182,750 573,184,750,False,,False
665,181,703 665,181,703,False,,False
700,176,702 714,174,702,False,,False
722,170,701 756,165,701,False,Backward,False
[RFID_LINES] [RFID_LINES]
100,486,173,488,517,516,False,73.02739 100,486,162,487,[RFIDPoint] 517,P:100,486,[RFIDPoint] 516,P:162,487,false,false,0
173,488,230,493,516,515,False,57.21888 162,487,230,493,[RFIDPoint] 516,P:162,487,[RFIDPoint] 515,P:230,493,false,false,0
230,493,309,489,515,514,False,79.1012 230,493,309,489,[RFIDPoint] 515,P:230,493,[RFIDPoint] 514,P:309,489,false,false,0
309,489,370,490,514,513,False,61.0082 309,489,370,490,[RFIDPoint] 514,P:309,489,[RFIDPoint] 513,P:370,490,false,false,0
370,490,437,487,513,512,False,67.06713 370,490,429,487,[RFIDPoint] 513,P:370,490,[RFIDPoint] 512,P:429,487,false,false,0
437,487,483,459,512,511,False,53.85165 429,487,488,476,[RFIDPoint] 512,P:429,487,[RFIDPoint] 511,P:488,476,false,false,0
483,459,511,421,511,510,False,47.20169 488,476,538,445,[RFIDPoint] 511,P:488,476,[RFIDPoint] 510,P:538,445,false,false,0
511,421,543,371,510,509,False,59.36329 538,445,576,393,[RFIDPoint] 510,P:538,445,[RFIDPoint] 509,P:576,393,false,false,0
543,371,569,329,509,508,False,49.39635 576,393,598,343,[RFIDPoint] 509,P:576,393,[RFIDPoint] 508,P:598,343,false,false,0
569,329,608,289,508,507,False,55.86591 598,343,621,287,[RFIDPoint] 508,P:598,343,[RFIDPoint] 507,P:621,287,false,false,0
608,289,639,234,507,600,False,63.13478 621,287,633,237,[RFIDPoint] 507,P:621,287,[RFIDPoint] 600,P:633,237,false,false,0
639,234,665,181,600,703,False,59.03389 633,237,665,181,[RFIDPoint] 600,P:633,237,[RFIDPoint] 703,P:665,181,false,false,0
665,181,657,101,703,603,False,80.399 665,181,657,101,[RFIDPoint] 703,P:665,181,[RFIDPoint] 603,P:657,101,false,false,0
657,101,627,82,603,604,False,35.51056 657,101,627,82,[RFIDPoint] 603,P:657,101,[RFIDPoint] 604,P:627,82,false,false,0
627,82,560,73,604,605,False,67.60178 627,82,560,73,[RFIDPoint] 604,P:627,82,[RFIDPoint] 605,P:560,73,false,false,0
560,73,499,65,605,606,False,61.52235 560,73,499,65,[RFIDPoint] 605,P:560,73,[RFIDPoint] 606,P:499,65,false,false,0
499,65,432,65,606,607,False,67 499,65,432,65,[RFIDPoint] 606,P:499,65,[RFIDPoint] 607,P:432,65,false,false,0
432,65,363,60,607,608,False,69.18092 432,65,363,60,[RFIDPoint] 607,P:432,65,[RFIDPoint] 608,P:363,60,false,false,0
641,183,665,181,602,703,False,24.08319 639,184,665,181,[RFIDPoint] 602,P:639,184,[RFIDPoint] 703,P:665,181,false,false,0
665,181,700,176,703,702,False,35.35534 665,181,714,174,[RFIDPoint] 703,P:665,181,[RFIDPoint] 702,P:714,174,false,false,0
700,176,722,170,702,701,False,22.80351 714,174,756,165,[RFIDPoint] 702,P:714,174,[RFIDPoint] 701,P:756,165,false,false,0
722,170,735,163,701,700,False,14.76482 756,165,847,152,[RFIDPoint] 701,P:756,165,[RFIDPoint] 700,P:847,152,false,false,0
641,183,621,182,602,601,False,20.02498 639,184,609,186,[RFIDPoint] 602,P:639,184,[RFIDPoint] 601,P:609,186,false,false,0
621,182,597,182,601,750,False,24 609,186,573,184,[RFIDPoint] 601,P:609,186,[RFIDPoint] 750,P:573,184,false,false,0
597,182,565,175,750,751,False,32.75668 573,184,535,176,[RFIDPoint] 750,P:573,184,[RFIDPoint] 751,P:535,176,false,false,0
565,175,523,170,751,752,False,42.29657 535,176,484,169,[RFIDPoint] 751,P:535,176,[RFIDPoint] 752,P:484,169,false,false,0
523,170,483,165,752,753,False,40.31129 484,169,397,166,[RFIDPoint] 752,P:484,169,[RFIDPoint] 753,P:397,166,false,false,0
264,232,315,258,405,404,False,57.24509 242,239,311,260,[RFIDPoint] 405,P:242,239,[RFIDPoint] 404,P:311,260,false,false,0
315,258,388,262,404,403,False,73.1095 311,260,383,267,[RFIDPoint] 404,P:311,260,[RFIDPoint] 403,P:383,267,false,false,0
388,262,454,264,403,402,False,66.0303 383,267,439,271,[RFIDPoint] 403,P:383,267,[RFIDPoint] 402,P:439,271,false,false,0
454,264,517,264,402,401,False,63 439,271,504,274,[RFIDPoint] 402,P:439,271,[RFIDPoint] 401,P:504,274,false,false,0
517,264,570,275,401,400,False,54.12947 504,274,566,281,[RFIDPoint] 401,P:504,274,[RFIDPoint] 400,P:566,281,false,false,0
570,275,608,289,400,507,False,40.49691 566,281,621,287,[RFIDPoint] 400,P:566,281,[RFIDPoint] 507,P:621,287,false,false,0
608,289,661,279,507,506,False,53.93515 621,287,671,293,[RFIDPoint] 507,P:621,287,[RFIDPoint] 506,P:671,293,false,false,0
661,279,701,297,506,505,False,43.86343 671,293,702,314,[RFIDPoint] 506,P:671,293,[RFIDPoint] 505,P:702,314,false,false,0
701,297,698,349,505,504,False,52.08647 702,314,711,354,[RFIDPoint] 505,P:702,314,[RFIDPoint] 504,P:711,354,false,false,0
698,349,698,391,504,503,False,42 711,354,711,396,[RFIDPoint] 504,P:711,354,[RFIDPoint] 503,P:711,396,false,false,0
698,391,699,449,503,502,False,58.00862 711,396,707,454,[RFIDPoint] 503,P:711,396,[RFIDPoint] 502,P:707,454,false,false,0
699,449,691,491,502,501,False,42.75512 707,454,685,499,[RFIDPoint] 502,P:707,454,[RFIDPoint] 501,P:685,499,false,false,0
691,491,654,508,501,500,False,40.71855 685,499,633,547,[RFIDPoint] 501,P:685,499,[RFIDPoint] 500,P:633,547,false,false,0
96,542,100,486,100,517,False,56.14267 96,542,100,486,[RFIDPoint] 100,P:96,542,[RFIDPoint] 517,P:100,486,false,false,0
159,542,173,488,101,516,False,55.7853 159,542,162,487,[RFIDPoint] 101,P:159,542,[RFIDPoint] 516,P:162,487,false,false,0
226,542,230,493,102,515,False,49.16299 226,542,230,493,[RFIDPoint] 102,P:226,542,[RFIDPoint] 515,P:230,493,false,false,0
309,541,309,489,103,514,False,52 310,541,309,489,[RFIDPoint] 103,P:310,541,[RFIDPoint] 514,P:309,489,false,false,0
369,542,370,490,104,513,False,52.00961 369,542,370,490,[RFIDPoint] 104,P:369,542,[RFIDPoint] 513,P:370,490,false,false,0
[RFID_CONNECTION]
100,486,162,487,517,516,1,,,
162,487,230,493,516,515,1,,,
230,493,309,489,515,514,1,,,
309,489,370,490,514,513,1,,,
370,490,429,487,513,512,1,,,
429,487,488,476,512,511,1,,,
488,476,538,445,511,510,1,,,
538,445,576,393,510,509,1,,,
576,393,598,343,509,508,1,,,
598,343,621,287,508,507,1,,,
621,287,633,237,507,600,1,,,
633,237,665,181,600,703,1,,,
665,181,657,101,703,603,1,,,
657,101,627,82,603,604,1,,,
627,82,560,73,604,605,1,,,
560,73,499,65,605,606,1,,,
499,65,432,65,606,607,1,,,
432,65,363,60,607,608,1,,,
639,184,665,181,602,703,1,,,
665,181,714,174,703,702,1,,,
714,174,756,165,702,701,1,,,
756,165,847,152,701,700,1,,,
639,184,609,186,602,601,1,,,
609,186,573,184,601,750,1,,,
573,184,535,176,750,751,1,,,
535,176,484,169,751,752,1,,,
484,169,397,166,752,753,1,,,
242,239,311,260,405,404,1,,,
311,260,383,267,404,403,1,,,
383,267,439,271,403,402,1,,,
439,271,504,274,402,401,1,,,
504,274,566,281,401,400,1,,,
566,281,621,287,400,507,1,,,
621,287,671,293,507,506,1,,,
671,293,702,314,506,505,1,,,
702,314,711,354,505,504,1,,,
711,354,711,396,504,503,1,,,
711,396,707,454,503,502,1,,,
707,454,685,499,502,501,1,,,
685,499,633,547,501,500,1,,,
96,542,100,486,100,517,1,,,
159,542,162,487,101,516,1,,,
226,542,230,493,102,515,1,,,
310,541,309,489,103,514,1,,,
369,542,370,490,104,513,1,,,
[MAP_TEXTS] [MAP_TEXTS]
179,251,-1,-16777216,Arial,12,OPS-2 231,193,-16777216,-2448096,Arial,12,TOPS-2
239,52,-256,-65408,Arial,12,SSOTRON-3 315,25,-256,-65408,Arial,12,SSOTRON-3
617,527,-16711936,-16777216,Arial,12,SSOTRON-1 586,577,-16711936,-16777216,Arial,12,SSOTRON-1
87,551,-16777216,16777215,Arial,12,B1 81,564,-16777216,-1,Arial,12,B1
150,550,-16777216,16777215,Arial,12,B2 144,563,-16777216,-1,Arial,12,B2
227,553,-16777216,16777215,Arial,12,B3 214,561,-16777216,-1,Arial,12,B3
299,555,-16777216,16777215,Arial,12,B4 301,562,-16777216,-1,Arial,12,B4
367,554,-16777216,16777215,Arial,12,B5 359,562,-16777216,-1,Arial,12,B5
453,128,-16777216,-8323073,Arial,12,CHG1 371,115,-16777216,-8323073,Arial,12,CHG1
725,124,-16777216,-8323073,Arial,12,CHG2 822,110,-16777216,-8323073,Arial,12,CHG2
[CUSTOM_LINES]
[CUSTOM_LINES] [CUSTOM_LINES]

View File

@@ -0,0 +1,103 @@
namespace AGVControl.Dialog
{
partial class fMapDesign
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(fMapDesign));
this.panel1 = new System.Windows.Forms.Panel();
this.toolStrip1 = new System.Windows.Forms.ToolStrip();
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
this.btOK = new System.Windows.Forms.ToolStripButton();
this.toolStrip1.SuspendLayout();
this.SuspendLayout();
//
// panel1
//
this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel1.Font = new System.Drawing.Font("Tahoma", 8F, System.Drawing.FontStyle.Bold);
this.panel1.Location = new System.Drawing.Point(0, 47);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(888, 547);
this.panel1.TabIndex = 22;
//
// toolStrip1
//
this.toolStrip1.ImageScalingSize = new System.Drawing.Size(40, 40);
this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.btOK});
this.toolStrip1.Location = new System.Drawing.Point(0, 0);
this.toolStrip1.Name = "toolStrip1";
this.toolStrip1.Size = new System.Drawing.Size(888, 47);
this.toolStrip1.TabIndex = 23;
this.toolStrip1.Text = "toolStrip1";
//
// statusStrip1
//
this.statusStrip1.Location = new System.Drawing.Point(0, 594);
this.statusStrip1.Name = "statusStrip1";
this.statusStrip1.Size = new System.Drawing.Size(888, 22);
this.statusStrip1.TabIndex = 24;
this.statusStrip1.Text = "statusStrip1";
//
// btOK
//
this.btOK.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
this.btOK.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.btOK.Image = ((System.Drawing.Image)(resources.GetObject("btOK.Image")));
this.btOK.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btOK.Name = "btOK";
this.btOK.Size = new System.Drawing.Size(44, 44);
this.btOK.Text = "toolStripButton1";
this.btOK.Click += new System.EventHandler(this.btOK_Click);
//
// fMapDesign
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(888, 616);
this.Controls.Add(this.panel1);
this.Controls.Add(this.statusStrip1);
this.Controls.Add(this.toolStrip1);
this.Name = "fMapDesign";
this.Text = "fMapDesign";
this.Load += new System.EventHandler(this.fMapDesign_Load);
this.toolStrip1.ResumeLayout(false);
this.toolStrip1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.ToolStrip toolStrip1;
private System.Windows.Forms.ToolStripButton btOK;
private System.Windows.Forms.StatusStrip statusStrip1;
}
}

View File

@@ -0,0 +1,48 @@
using AR;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AGVControl.Dialog
{
public partial class fMapDesign : Form
{
AGVControl.MapControl mapctl;
public fMapDesign(string fn)
{
InitializeComponent();
mapctl = new AGVControl.MapControl();
mapctl.Dock = DockStyle.Fill;
mapctl.Visible = true;
mapctl.Font = this.panel1.Font;
mapctl.BackColor = Color.FromArgb(32, 32, 32);
this.panel1.Controls.Add(mapctl);
if (System.IO.File.Exists(fn))
{
//auto load
var rlt = mapctl.LoadFromFile(fn, out string errmsg);
if (rlt == false) AR.UTIL.MsgE(errmsg);
}
}
private void fMapDesign_Load(object sender, EventArgs e)
{
}
private void btOK_Click(object sender, EventArgs e)
{
this.mapctl.SaveToFile(this.mapctl.Filename);
DialogResult = DialogResult.OK;
}
}
}

View File

@@ -0,0 +1,142 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="toolStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="btOK.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG
YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9
0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw
bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc
VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9
c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32
Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo
mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+
kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D
TgDQASA1MVpwzwAAAABJRU5ErkJggg==
</value>
</data>
<metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>124, 17</value>
</metadata>
</root>

View File

@@ -0,0 +1,158 @@
namespace AGVControl.Dialog
{
partial class fPropertyRFIDPoint
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.propertyGrid1 = new System.Windows.Forms.PropertyGrid();
this.comboBox1 = new System.Windows.Forms.ComboBox();
this.propertyGrid2 = new System.Windows.Forms.PropertyGrid();
this.panel1 = new System.Windows.Forms.Panel();
this.label2 = new System.Windows.Forms.Label();
this.panel2 = new System.Windows.Forms.Panel();
this.label1 = new System.Windows.Forms.Label();
this.button1 = new System.Windows.Forms.Button();
this.panel1.SuspendLayout();
this.panel2.SuspendLayout();
this.SuspendLayout();
//
// propertyGrid1
//
this.propertyGrid1.Dock = System.Windows.Forms.DockStyle.Fill;
this.propertyGrid1.Location = new System.Drawing.Point(0, 31);
this.propertyGrid1.Name = "propertyGrid1";
this.propertyGrid1.Size = new System.Drawing.Size(346, 456);
this.propertyGrid1.TabIndex = 0;
//
// comboBox1
//
this.comboBox1.Dock = System.Windows.Forms.DockStyle.Top;
this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboBox1.Font = new System.Drawing.Font("굴림", 18F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
this.comboBox1.FormattingEnabled = true;
this.comboBox1.Location = new System.Drawing.Point(1, 32);
this.comboBox1.Name = "comboBox1";
this.comboBox1.Size = new System.Drawing.Size(519, 32);
this.comboBox1.TabIndex = 1;
this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
//
// propertyGrid2
//
this.propertyGrid2.Dock = System.Windows.Forms.DockStyle.Fill;
this.propertyGrid2.Location = new System.Drawing.Point(1, 64);
this.propertyGrid2.Name = "propertyGrid2";
this.propertyGrid2.Size = new System.Drawing.Size(519, 362);
this.propertyGrid2.TabIndex = 2;
//
// panel1
//
this.panel1.BackColor = System.Drawing.Color.Gray;
this.panel1.Controls.Add(this.propertyGrid2);
this.panel1.Controls.Add(this.button1);
this.panel1.Controls.Add(this.comboBox1);
this.panel1.Controls.Add(this.label2);
this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel1.Location = new System.Drawing.Point(346, 0);
this.panel1.Name = "panel1";
this.panel1.Padding = new System.Windows.Forms.Padding(1);
this.panel1.Size = new System.Drawing.Size(521, 487);
this.panel1.TabIndex = 3;
//
// label2
//
this.label2.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
this.label2.Dock = System.Windows.Forms.DockStyle.Top;
this.label2.Font = new System.Drawing.Font("굴림", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
this.label2.Location = new System.Drawing.Point(1, 1);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(519, 31);
this.label2.TabIndex = 3;
this.label2.Text = "Connection Information";
this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// panel2
//
this.panel2.Controls.Add(this.propertyGrid1);
this.panel2.Controls.Add(this.label1);
this.panel2.Dock = System.Windows.Forms.DockStyle.Left;
this.panel2.Location = new System.Drawing.Point(0, 0);
this.panel2.Name = "panel2";
this.panel2.Size = new System.Drawing.Size(346, 487);
this.panel2.TabIndex = 4;
//
// label1
//
this.label1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
this.label1.Dock = System.Windows.Forms.DockStyle.Top;
this.label1.Font = new System.Drawing.Font("굴림", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
this.label1.Location = new System.Drawing.Point(0, 0);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(346, 31);
this.label1.TabIndex = 0;
this.label1.Text = "Point Information";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// button1
//
this.button1.Dock = System.Windows.Forms.DockStyle.Bottom;
this.button1.Font = new System.Drawing.Font("Arial Rounded MT Bold", 27.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.button1.Location = new System.Drawing.Point(1, 426);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(519, 60);
this.button1.TabIndex = 4;
this.button1.Text = "P1 ↔ P2";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// fPropertyRFIDPoint
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(867, 487);
this.Controls.Add(this.panel1);
this.Controls.Add(this.panel2);
this.Name = "fPropertyRFIDPoint";
this.Text = "fPropertyRFIDPoint";
this.Load += new System.EventHandler(this.fPropertyRFIDPoint_Load);
this.panel1.ResumeLayout(false);
this.panel2.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.PropertyGrid propertyGrid1;
private System.Windows.Forms.ComboBox comboBox1;
private System.Windows.Forms.PropertyGrid propertyGrid2;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Panel panel2;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Button button1;
}
}

View File

@@ -0,0 +1,55 @@
using AGVControl.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AGVControl.Dialog
{
public partial class fPropertyRFIDPoint : Form
{
RFIDPoint RFIDPt;
List<RFIDConnection> Connections;
public fPropertyRFIDPoint(RFIDPoint point, List<RFIDConnection> connection)
{
InitializeComponent();
this.RFIDPt = point;
this.Connections = connection;
this.propertyGrid1.SelectedObject = point;
this.KeyPreview = true;
this.KeyDown += (s1, e1) => {
if (e1.KeyCode == Keys.Escape) this.Close();
};
}
private void fPropertyRFIDPoint_Load(object sender, EventArgs e)
{
foreach (var item in Connections)
comboBox1.Items.Add($"{item.P1.Value} ↔ {item.P2.Value}");
if(comboBox1.Items.Count > 0)
comboBox1.SelectedIndex = 0;
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
this.propertyGrid2.SelectedObject = this.Connections[this.comboBox1.SelectedIndex];
}
private void button1_Click(object sender, EventArgs e)
{
var item = this.Connections[this.comboBox1.SelectedIndex];
var p1 = item.P1;
var p2 = item.P2;
item.P2 = p1;// item.P1;
item.P1 = p2;// p1;
this.propertyGrid2.SelectedObject = item;
this.Validate();
}
}
}

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

File diff suppressed because it is too large Load Diff

View File

@@ -3,25 +3,37 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Linq; using System.Linq;
using System.Runtime.CompilerServices;
using System.Security.Cryptography.X509Certificates;
using System.Threading; using System.Threading;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.TextBox;
namespace AGVControl namespace AGVControl
{ {
public static class MapControlManager public class MapControlManager
{ {
public static AGVActionPrediction PredictResult = null; public AGVActionPrediction PredictResult = null;
public static AGV agv = new AGV(); public AGV agv = new AGV();
public static List<RFIDPoint> RFIDPoints = new List<RFIDPoint>(); public List<RFIDPoint> RFIDPoints = new List<RFIDPoint>();
public static HashSet<RFIDConnection> rfidConnections = new HashSet<RFIDConnection>(); public HashSet<RFIDConnection> rfidConnections = new HashSet<RFIDConnection>();
private static ManualResetEvent mrepredict = new ManualResetEvent(true); private ManualResetEvent mrepredict = new ManualResetEvent(true);
public MapControlManager()
{
}
~MapControlManager()
{
}
/// <summary> /// <summary>
/// 목표지정으로 모터방향이 이동하고 있는가? /// 목표지정으로 모터방향이 이동하고 있는가?
/// history 데이터가 있어야 하며 기준데이터가 없는 경우 null 반환 /// history 데이터가 있어야 하며 기준데이터가 없는 경우 null 반환
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public static bool? IsMotDirection_To_Target() public bool? IsMotDirection_To_Target()
{ {
if (agv.MovementHistory.Any() == false || agv.MovementHistory.Count < 2) return null; if (agv.MovementHistory.Any() == false || agv.MovementHistory.Count < 2) return null;
if (agv.MainPath.Any() == false) return null; if (agv.MainPath.Any() == false) return null;
@@ -38,27 +50,24 @@ namespace AGVControl
//지정된경로 반대방향으로 이동하고 있다 //지정된경로 반대방향으로 이동하고 있다
return preidx < curidx; return preidx < curidx;
} }
public static float GetDistance(Point p1, Point p2) public float GetDistance(Point p1, Point p2)
{ {
float dx = p1.X - p2.X; float dx = p1.X - p2.X;
float dy = p1.Y - p2.Y; float dy = p1.Y - p2.Y;
return (float)Math.Sqrt(dx * dx + dy * dy); // double을 float로 명시적 캐스팅 return (float)Math.Sqrt(dx * dx + dy * dy); // double을 float로 명시적 캐스팅
} }
public static AGVActionPrediction PredictNextAction() public AGVActionPrediction PredictNextAction()
{ {
if (mrepredict.WaitOne(1) == false) if (mrepredict.WaitOne(1) == false)
{ {
PredictResult = new AGVActionPrediction PredictResult = CreatePrediction("이전 작업이 완료되지 않았습니다",
{ AGVActionReasonCode.busy,
Reason = "이전 작업이 완료되지 않았습니다", AGVMoveState.Stop,
ReasonCode = AGVActionReasonCode.busy, agv.CurrentMOTDirection, false);
MoveState = AGVMoveState.Stop,
Direction = agv.CurrentMOTDirection,
};
return PredictResult; return PredictResult;
} }
mrepredict.Reset(); mrepredict.Reset();
try try
{ {
@@ -68,58 +77,70 @@ namespace AGVControl
// 1. 위치를 모를 때 (CurrentRFID가 0 또는 미설정) // 1. 위치를 모를 때 (CurrentRFID가 0 또는 미설정)
if (agv.CurrentRFID.Value == 0) if (agv.CurrentRFID.Value == 0)
{ {
PredictResult = new AGVActionPrediction PredictResult = CreatePrediction("AGV 위치 미확정(처음 기동)",
{ AGVActionReasonCode.NoPosition,
Direction = Direction.Backward, AGVMoveState.Run,
NextRFID = null, Direction.Backward, true,
Reason = "AGV 위치 미확정(처음 기동)", moveSpeed: AgvSpeed.Low,
ReasonCode = AGVActionReasonCode.NoPosition, moveDiv: AgvRunDirection.Straight);
MoveState = AGVMoveState.Run
};
return PredictResult; return PredictResult;
} }
//2. 이동방향을 모른다 //2. 이동방향을 모른다
if (agv.MovementHistory.Any() == false || agv.MovementHistory.Count < 2) if (agv.MovementHistory.Any() == false || agv.MovementHistory.Count < 2)
{ {
PredictResult = new AGVActionPrediction PredictResult = CreatePrediction("AGV이동방향 알수없음",
{ AGVActionReasonCode.NoDirection,
Direction = Direction.Backward, AGVMoveState.Run,
NextRFID = null, Direction.Backward, true,
Reason = "AGV이동방향 알수없음", moveSpeed: AgvSpeed.Low,
ReasonCode = AGVActionReasonCode.NoDirection, moveDiv: AgvRunDirection.Straight);
MoveState = AGVMoveState.Run
};
return PredictResult; return PredictResult;
} }
// 3. 경로가 없거나 현재 위치가 경로에 없음 // 3. 경로가 없거나 현재 위치가 경로에 없음
if ((agv.MainPath?.Count ?? 0) < 2) if ((agv.MainPath?.Count ?? 0) < 2 || agv.MainPath.Last().Value != agv.TargetRFID.Value)
{ {
PredictResult = new AGVActionPrediction //목적지가 없다면 진행할 수 없다
if (agv.TargetRFID == null)
{ {
Direction = agv.CurrentMOTDirection, PredictResult = CreatePrediction("경로 없음 또는 현재 위치 미확정",
NextRFID = null, AGVActionReasonCode.NoPath,
Reason = "경로 없음 또는 현재 위치 미확정", AGVMoveState.Stop,
ReasonCode = AGVActionReasonCode.NoPath, agv.CurrentMOTDirection, true);
MoveState = AGVMoveState.Stop return PredictResult;
}; }
return PredictResult; else
{
//목적지가 있는데 경로가 없다면 경로 예측을 진행해야한다.
var CurPt = agv.MovementHistory.Last();
var prlt = CalculatePath(CurPt, agv.TargetRFID);
if (prlt.Success == false)
{
PredictResult = CreatePrediction("목적지 경로 예측 실패",
AGVActionReasonCode.Unknown,
AGVMoveState.Stop,
agv.CurrentMOTDirection, true,
nextRFID: agv.TargetRFID);
return PredictResult;
}
else
{
//신규목적지에 대한 경로예측이 성공했다
agv.SubPath.Clear();
agv.MainPath = prlt.Path;
}
}
} }
// 4. 경로상에서 다음 RFID 예측 // 4. 경로상에서 다음 RFID 예측
int idx = agv.MainPath.FindIndex(p => p.Value == agv.CurrentRFID.Value); int idx = agv.MainPath.FindIndex(p => p.Value == agv.CurrentRFID.Value);
if (idx < 0) if (idx < 0)
{ {
PredictResult = new AGVActionPrediction PredictResult = CreatePrediction("현재 위치가 경로에 없음",
{ AGVActionReasonCode.NotOnPath,
Direction = agv.CurrentMOTDirection, AGVMoveState.Stop,
NextRFID = null, agv.CurrentMOTDirection, true);
Reason = "현재 위치가 경로에 없음",
ReasonCode = AGVActionReasonCode.NotOnPath,
MoveState = AGVMoveState.Stop
};
return PredictResult; return PredictResult;
} }
@@ -135,30 +156,25 @@ namespace AGVControl
//모션이동방향이 맞는가? //모션이동방향이 맞는가?
var IsMotDir = IsMotDirection_To_Target() ?? false; var IsMotDir = IsMotDirection_To_Target() ?? false;
var PrePT = agv.MovementHistory.Skip(agv.MovementHistory.Count - 1).First(); var PrePT = agv.MovementHistory.Skip(agv.MovementHistory.Count - 2).First();
var curPT = agv.MovementHistory.Last(); var curPT = agv.MovementHistory.Last();
//리프트방향이 맞지 않다면 회전가능한 위치로 이동을 해야한다 //리프트방향이 맞지 않다면 회전가능한 위치로 이동을 해야한다
if (IsLiftDir == false) if (IsLiftDir == false)
{ {
AgvSpeed? agv_spd = null;
AgvRunDirection? agv_dir = null;
//회전가능한 위치로 이동을 해야한다 //회전가능한 위치로 이동을 해야한다
//1. 가까운 회전위치를 찾는다 //1. 가까운 회전위치를 찾는다
var nearTurnPoint = RFIDPoints.Where(t => t.IsRotatable)?.OrderBy(t => GetDistance(t.Location, agv.CurrentRFID.Location)).FirstOrDefault() ?? null; var nearTurnPoint = RFIDPoints.Where(t => t.IsRotatable)?.OrderBy(t => GetDistance(t.Location, agv.CurrentRFID.Location)).FirstOrDefault() ?? null;
if (nearTurnPoint == null) if (nearTurnPoint == null)
{ {
PredictResult= new AGVActionPrediction PredictResult = CreatePrediction("회전 가능한 위치가 없습니다",
{ AGVActionReasonCode.NoTurnPoint,
Direction = agv.CurrentMOTDirection, AGVMoveState.Stop,
NextRFID = null, agv.CurrentMOTDirection, true);
Reason = "회전 가능한 위치가 없습니다",
ReasonCode = AGVActionReasonCode.NoTurnPoint,
MoveState = AGVMoveState.Stop
};
return PredictResult; return PredictResult;
} }
@@ -168,22 +184,19 @@ namespace AGVControl
if (agv.CurrentRFID.Value != nearTurnPoint.Value) if (agv.CurrentRFID.Value != nearTurnPoint.Value)
{ {
if (agv.SubPath.Any() == false || agv.SubPath.Count < 2 || if (agv.SubPath.Any() == false || agv.SubPath.Count < 2 ||
agv.SubPath.First().Value != PrePT.Value || agv.SubPath.First().Value != agv.CurrentRFID.Value ||
agv.SubPath.Last().Value != nearTurnPoint.Value) agv.SubPath.Last().Value != nearTurnPoint.Value)
{ {
var rlt = CalculatePath(PrePT, nearTurnPoint, true); //이전포인트도 추가를 해준다 var rlt = CalculatePath(agv.CurrentRFID, nearTurnPoint); //이전포인트도 추가를 해준다
if (rlt.Success) agv.SubPath = rlt.Path; if (rlt.Success) agv.SubPath = rlt.Path;
else else
{ {
agv.SubPath.Clear(); agv.SubPath.Clear();
PredictResult= new AGVActionPrediction PredictResult = CreatePrediction("회전 위치까지의 경로를 계산할 수 없습니다",
{ AGVActionReasonCode.PathCalcError,
Direction = agv.CurrentMOTDirection, AGVMoveState.Stop,
NextRFID = nearTurnPoint, agv.CurrentMOTDirection, true,
Reason = "회전 위치까지의 경로를 계산할 수 없습니다", nextRFID: nearTurnPoint);
ReasonCode = AGVActionReasonCode.PathCalcError,
MoveState = AGVMoveState.Stop
};
return PredictResult; return PredictResult;
} }
} }
@@ -194,6 +207,9 @@ namespace AGVControl
var preidx = agv.SubPath.FindIndex(t => t.Value == PrePT.Value); var preidx = agv.SubPath.FindIndex(t => t.Value == PrePT.Value);
Direction newdirection = agv.CurrentMOTDirection; Direction newdirection = agv.CurrentMOTDirection;
string message = "턴위치로 이동중"; string message = "턴위치로 이동중";
if (preidx > curidx) if (preidx > curidx)
{ {
//지정경로를 거꾸로 이동하고 있다 //지정경로를 거꾸로 이동하고 있다
@@ -202,31 +218,44 @@ namespace AGVControl
else else
newdirection = Direction.Forward; newdirection = Direction.Forward;
message += "(방향전환)"; message += "(방향전환)";
} }
PredictResult= new AGVActionPrediction //도로정보를 확인하여 속도와 분기명령을 실행한다
{ var roadinfo = GetRoadInfo(agv.SubPath, curPT);
Direction = newdirection, agv_spd = roadinfo.spd;
NextRFID = nearTurnPoint, agv_dir = roadinfo.dir;
Reason = message,
ReasonCode = AGVActionReasonCode.MoveForTurn, PredictResult = CreatePrediction(message,
MoveState = AGVMoveState.Run, AGVActionReasonCode.MoveForTurn,
}; AGVMoveState.Run,
newdirection, true,
moveSpeed: agv_spd,
moveDiv: agv_dir,
nextRFID: nearTurnPoint);
return PredictResult; return PredictResult;
} }
var roadinfo2 = GetRoadInfo(agv.SubPath.Any() ? agv.SubPath : agv.MainPath, curPT);
agv_spd = roadinfo2.spd;
agv_dir = roadinfo2.dir;
PredictResult = new AGVActionPrediction
{ PredictResult = CreatePrediction("턴 완료 대기",
Direction = agv.CurrentMOTDirection, AGVActionReasonCode.NeedTurn,
NextRFID = nearTurnPoint, AGVMoveState.Stop,
Reason = "턴 완료 대기", agv.CurrentMOTDirection, true,
ReasonCode = AGVActionReasonCode.NeedTurn, moveSpeed: agv_spd,
MoveState = AGVMoveState.Stop moveDiv: agv_dir,
}; nextRFID: nearTurnPoint);
return PredictResult; return PredictResult;
} }
//보조이동선제거
if (agv.SubPath != null && agv.SubPath.Any())
agv.SubPath.Clear();
//3. 목적지위치까지 이동이 완료되지 않았다면 계속 이동을 하게한다 //3. 목적지위치까지 이동이 완료되지 않았다면 계속 이동을 하게한다
if (agv.CurrentRFID.Value != destRFID.Value) if (agv.CurrentRFID.Value != destRFID.Value)
{ {
@@ -247,39 +276,35 @@ namespace AGVControl
//경로상 바로 다음 위치를 확인한다 //경로상 바로 다음 위치를 확인한다
var nexstRFID = agv.MainPath.Skip(agv.MainPath.FindIndex(t => t.Value == curPT.Value) + 1).First(); var nexstRFID = agv.MainPath.Skip(agv.MainPath.FindIndex(t => t.Value == curPT.Value) + 1).First();
PredictResult = new AGVActionPrediction var roadinfo = GetRoadInfo(agv.MainPath, curPT);
{
Direction = newdirection,
NextRFID = nexstRFID, PredictResult = CreatePrediction(message,
Reason = message, AGVActionReasonCode.Normal,
ReasonCode = AGVActionReasonCode.Normal, AGVMoveState.Run,
MoveState = AGVMoveState.Run, newdirection, true,
}; moveSpeed: roadinfo.spd,
moveDiv: roadinfo.dir,
nextRFID: nexstRFID);
return PredictResult; return PredictResult;
} }
// 5. 목적지 도달 시 // 5. 목적지 도달 시
PredictResult = new AGVActionPrediction PredictResult = CreatePrediction("경로의 마지막 지점(목적지 도달)",
{ AGVActionReasonCode.Arrived,
Direction = agv.CurrentMOTDirection, AGVMoveState.Stop,
NextRFID = destRFID, agv.CurrentMOTDirection, true,
Reason = "경로의 마지막 지점(목적지 도달)", nextRFID: destRFID);
ReasonCode = AGVActionReasonCode.Arrived,
MoveState = AGVMoveState.Stop
};
return PredictResult; return PredictResult;
} }
catch (Exception ex) catch (Exception ex)
{ {
PredictResult = new AGVActionPrediction
{ PredictResult = CreatePrediction($"ERR:{ex.Message}",
Direction = agv.CurrentMOTDirection, AGVActionReasonCode.Unknown,
NextRFID = null, AGVMoveState.Stop,
Reason = $"ERR:{ex.Message}", agv.CurrentMOTDirection, true);
ReasonCode = AGVActionReasonCode.Unknown,
MoveState = AGVMoveState.Stop
};
return PredictResult; return PredictResult;
} }
finally finally
@@ -289,13 +314,43 @@ namespace AGVControl
} }
(AgvSpeed? spd, AgvRunDirection? dir, RFIDConnection info) GetRoadInfo(List<RFIDPoint> paths, RFIDPoint curPT)
{
//도로정보를 확인하여 속도와 분기명령을 실행한다
AgvSpeed? agv_spd = null;
AgvRunDirection? agv_div = null;
RFIDConnection info = null;
var nextpt = paths.Skip(paths.FindIndex(t => t.Value == curPT.Value) + 1).FirstOrDefault();
if (nextpt != null)
{
var p1 = rfidConnections.Where(t => t.P1.Value == curPT.Value && t.P2.Value == nextpt.Value).FirstOrDefault();
if (p1 != null)
{
//positive
agv_spd = p1.MoveSpeedP;
agv_div = p1.MoveDirectionP;
info = p1;
}
var p2 = rfidConnections.Where(t => t.P2.Value == curPT.Value && t.P1.Value == nextpt.Value).FirstOrDefault();
if (p2 != null)
{
//negative
agv_spd = p2.MoveSpeedN;
agv_div = p2.MoveDirectionN;
info = p2;
}
}
return (agv_spd, agv_div, info);
}
/// <summary> /// <summary>
/// 이웃포인터를 반환합니다 /// 이웃포인터를 반환합니다
/// </summary> /// </summary>
/// <param name="point"></param> /// <param name="point"></param>
/// <returns></returns> /// <returns></returns>
public static List<RFIDPoint> GetNeighbors(RFIDPoint pt) public List<RFIDPoint> GetNeighbors(RFIDPoint pt)
{ {
var neighbors = new List<RFIDPoint>(); var neighbors = new List<RFIDPoint>();
@@ -322,17 +377,17 @@ namespace AGVControl
return neighbors.Distinct().ToList(); return neighbors.Distinct().ToList();
} }
public static RFIDPoint FindRFIDPoint(uint rfidValue) public RFIDPoint FindRFIDPoint(uint rfidValue)
{ {
if (RFIDPoints == null || RFIDPoints.Any() == false) return null; if (RFIDPoints == null || RFIDPoints.Any() == false) return null;
return RFIDPoints.FirstOrDefault(r => r.Value == rfidValue); return RFIDPoints.FirstOrDefault(r => r.Value == rfidValue);
} }
private static float Heuristic(Point a, Point b) private float Heuristic(Point a, Point b)
{ {
return (float)Math.Sqrt(Math.Pow(a.X - b.X, 2) + Math.Pow(a.Y - b.Y, 2)); return (float)Math.Sqrt(Math.Pow(a.X - b.X, 2) + Math.Pow(a.Y - b.Y, 2));
} }
private static PathResult ReconstructPath(Dictionary<uint, RFIDPoint> cameFrom, RFIDPoint current) private PathResult ReconstructPath(Dictionary<uint, RFIDPoint> cameFrom, RFIDPoint current)
{ {
var path = new List<RFIDPoint> { current }; var path = new List<RFIDPoint> { current };
while (cameFrom.ContainsKey(current.Value)) while (cameFrom.ContainsKey(current.Value))
@@ -348,7 +403,7 @@ namespace AGVControl
Path = path, Path = path,
}; };
} }
public static PathResult CalculatePath(RFIDPoint start, RFIDPoint end, bool autorun) public PathResult CalculatePath(RFIDPoint start, RFIDPoint end)
{ {
var openList = new List<RFIDPoint> { start }; var openList = new List<RFIDPoint> { start };
var closedList = new List<RFIDPoint>(); var closedList = new List<RFIDPoint>();
@@ -410,7 +465,7 @@ namespace AGVControl
}; };
} }
public static PathResult CalculatePath(uint tagStrt, uint tagEnd) public PathResult CalculatePath(uint tagStrt, uint tagEnd)
{ {
var retval = new PathResult var retval = new PathResult
{ {
@@ -426,7 +481,7 @@ namespace AGVControl
return retval; return retval;
} }
retval = CalculatePath(startPoint, endPoint, false); retval = CalculatePath(startPoint, endPoint);
if (retval.Success == false) if (retval.Success == false)
retval.Message = "경로를 찾을 수 없습니다"; retval.Message = "경로를 찾을 수 없습니다";
@@ -439,7 +494,7 @@ namespace AGVControl
/// 이동경로정보가 없거나 목적지가 없으면 null 이 반환됨 /// 이동경로정보가 없거나 목적지가 없으면 null 이 반환됨
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public static bool? IsLiftDirectionMatch() public bool? IsLiftDirectionMatch()
{ {
if (agv.MovementHistory.Any() && agv.MovementHistory.Count > 1) if (agv.MovementHistory.Any() && agv.MovementHistory.Count > 1)
@@ -498,7 +553,40 @@ namespace AGVControl
} }
} }
// Changed 속성 설정을 위한 헬퍼 메서드
private bool IsPredictionChanged(AGVActionPrediction newPrediction)
{
if (PredictResult == null) return true; // 이전 예측이 없으면 변경됨
// Idx와 Changed를 제외하고 비교
return !PredictResult.Equals(newPrediction);
}
private AGVActionPrediction CreatePrediction(
string reason,
AGVActionReasonCode reasonCode,
AGVMoveState moveState,
Direction direction, bool IDXUpdate = true,
AgvSpeed? moveSpeed = null,
AgvRunDirection? moveDiv = null,
RFIDPoint nextRFID = null
)
{
var newPrediction = new AGVActionPrediction
{
NextRFID = nextRFID,
Reason = reason,
ReasonCode = reasonCode,
MoveState = moveState,
Direction = direction,
MoveSpeed = moveSpeed,
MoveDiv = moveDiv,
Idx = IDXUpdate ? (PredictResult?.Idx + 1 ?? 1) : (PredictResult?.Idx ?? 0)
};
newPrediction.Changed = IsPredictionChanged(newPrediction);
return newPrediction;
}
} }
} }

View File

@@ -1,248 +1,242 @@
using System; using System;
using System.Drawing; using System.Drawing;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Security.Permissions; using System.Security.Permissions;
using System.Windows.Forms; using System.Windows.Forms;
namespace AGVControl.Models namespace AGVControl.Models
{ {
public enum Direction
{ //public class CRFIDData
Forward = 0, //{
Backward = 1, // public UInt16 Value { get; set; }
Stop = 2 // public Point Location { get; set; }
} // public override string ToString()
// {
//public class CRFIDData // return $"RFID:{Value},P:{Location.X},{Location.Y}";
//{ // }
// public UInt16 Value { get; set; } //}
// public Point Location { get; set; }
// public override string ToString() public class movehistorydata : RFIDPoint
// { {
// return $"RFID:{Value},P:{Location.X},{Location.Y}"; public Direction Direction { get; set; }
// }
//} public override string ToString()
{
public class movehistorydata : RFIDPoint return $"RFID:{Value},DIR:{Direction},P:{Location.X},{Location.Y}";
{ }
public Direction Direction { get; set; } }
public override string ToString() public class AGV
{ {
return $"RFID:{Value},DIR:{Direction},P:{Location.X},{Location.Y}";
} /// <summary>
} /// RFID 번호
/// </summary>
public class AGV public RFIDPoint CurrentRFID { get; set; }
{
/// <summary>
/// <summary> /// 목적지가 셋팅된경우 해당 값
/// RFID 번호 /// </summary>
/// </summary>
public RFIDPoint CurrentRFID { get; set; } public RFIDPoint TargetRFID { get; set; }
/// <summary> /// <summary>
/// 목적지가 셋팅된경우 해당 값 /// 배터리잔량(%)
/// </summary> /// </summary>
public float BatteryLevel { get; set; } = 0f;
public RFIDPoint TargetRFID { get; set; }
/// <summary>
/// <summary> /// 배터리온도(board)
/// 배터리잔량(%) /// </summary>
/// </summary> public double BatteryTemp1 { get; set; } = 0;
public float BatteryLevel { get; set; } = 0f;
/// <summary>
/// <summary> /// 배터리온도(cell)
/// 배터리온도(board) /// </summary>
/// </summary> public double BatteryTemp2 { get; set; } = 0;
public double BatteryTemp1 { get; set; } = 0;
/// <summary>
/// <summary> /// AGV
/// 배터리온도(cell) /// </summary>
/// </summary> public Direction CurrentAGVDirection { get; set; }
public double BatteryTemp2 { get; set; } = 0;
/// <summary>
/// <summary> /// AGV모터 방향
/// AGV /// 외부에서 값이 상시 업데이트 됩니다.
/// </summary> /// </summary>
public Direction CurrentAGVDirection { get; set; } public Direction CurrentMOTDirection { get; set; }
/// <summary> /// <summary>
/// AGV모터 방향 /// 현재위치가 수산되면 목적지까지의 방향값이 계산됩니다.
/// 외부에서 값이 상시 업데이트 됩니다. /// </summary>
/// </summary> public Direction TargetDirection { get; set; } = Direction.Stop;
public Direction CurrentMOTDirection { get; set; } public bool IsMoving { get; set; }
public bool IsMarkCheck { get; set; }
/// <summary> public bool IsTargetDirectionMatch { get; set; }
/// 현재위치가 수산되면 목적지까지의 방향값이 계산됩니다.
/// </summary> /// <summary>
public Direction TargetDirection { get; set; } = Direction.Stop; /// 메인경로
public bool IsMoving { get; set; } /// 경로검색으로 입력된 경로
public bool IsMarkCheck { get; set; } /// </summary>
public bool IsTargetDirectionMatch { get; set; } public List<RFIDPoint> MainPath { get; set; } = new List<RFIDPoint>();
/// <summary> /// <summary>
/// 메인경로 /// 메인경로외에 거쳐가는 중간 경로
/// 경로검색으로 입력된 경로 /// </summary>
/// </summary> public List<RFIDPoint> SubPath { get; set; }
public List<RFIDPoint> MainPath { get; set; } = new List<RFIDPoint>();
/// <summary> public List<string> PathRFIDs { get; set; }
/// 메인경로외에 거쳐가는 중간 경로
/// </summary> // 이동 경로 기록을 위한 새로운 속성들
public List<RFIDPoint> SubPath { get; set; } public List<movehistorydata> MovementHistory { get; } = new List<movehistorydata>();
public const int HISTORY_SIZE = 10; // 최근 4개 위치 기록
public List<string> PathRFIDs { get; set; }
public AGV()
// 이동 경로 기록을 위한 새로운 속성들 {
public List<movehistorydata> MovementHistory { get; } = new List<movehistorydata>(); MainPath = new List<RFIDPoint>();
SubPath = new List<RFIDPoint>();
public const int HISTORY_SIZE = 10; // 최근 4개 위치 기록 PathRFIDs = new List<string>();
public AGV() CurrentRFID = new RFIDPoint();
{ TargetRFID = new RFIDPoint();
MainPath = new List<RFIDPoint>();
SubPath = new List<RFIDPoint>(); TargetDirection = Direction.Forward;
PathRFIDs = new List<string>(); // BodyAngle = null;
}
CurrentRFID = new RFIDPoint();
TargetRFID = new RFIDPoint();
// 이동 경로에 새로운 RFID 추가
TargetDirection = Direction.Forward; public void AddToMovementHistory(UInt16 rfidValue, Point position, Direction direction)
// BodyAngle = null; {
} // 중복 RFID가 연속으로 들어오는 경우 무시
if (MovementHistory.Count > 0 && MovementHistory.Last().Value == rfidValue)
return;
// 이동 경로에 새로운 RFID 추가
public void AddToMovementHistory(UInt16 rfidValue, Point position, Direction direction) MovementHistory.Add(new movehistorydata { Value = rfidValue, Direction = direction, Location = position });
{
// 중복 RFID가 연속으로 들어오는 경우 무시 // 기록 크기 제한
if (MovementHistory.Count > 0 && MovementHistory.Last().Value == rfidValue) if (MovementHistory.Count > HISTORY_SIZE)
return; {
MovementHistory.RemoveAt(0);
MovementHistory.Add(new movehistorydata { Value = rfidValue, Direction = direction, Location = position }); }
// 기록 크기 제한 //최초방향과 마지막 방향이 일치하지 않으면 그 이전의 데이터는 삭제한다.
if (MovementHistory.Count > HISTORY_SIZE) if (MovementHistory.Count > 2 && MovementHistory.First().Direction != MovementHistory.Last().Direction)
{ {
MovementHistory.RemoveAt(0); var lastTwo = MovementHistory.Skip(MovementHistory.Count - 2).Take(2).ToArray(); // [9, 10]
} MovementHistory.Clear();
MovementHistory.AddRange(lastTwo);
//최초방향과 마지막 방향이 일치하지 않으면 그 이전의 데이터는 삭제한다. }
if (MovementHistory.Count > 2 && MovementHistory.First().Direction != MovementHistory.Last().Direction) }
{
var lastTwo = MovementHistory.Skip(MovementHistory.Count - 2).Take(2).ToArray(); // [9, 10] // 연결 정보 기반 실제 이동 방향 계산
MovementHistory.Clear(); public Direction? CalculateActualDirectionByConnection(uint currentRFID, uint previousRFID, List<RFIDConnection> connections)
MovementHistory.AddRange(lastTwo); {
} if (connections == null || connections.Count == 0)
} return null;
// 연결 정보 기반 실제 이동 방향 계산 // 이전 RFID에서 현재 RFID로의 연결 확인
public Direction? CalculateActualDirectionByConnection(uint currentRFID, uint previousRFID, List<RFIDConnection> connections) var connection = connections.FirstOrDefault(c =>
{ (c.P1.Value == previousRFID && c.P2.Value == currentRFID) ||
if (connections == null || connections.Count == 0) (c.P1.Value == currentRFID && c.P2.Value == previousRFID));
return null;
if (connection == null)
// 이전 RFID에서 현재 RFID로의 연결 확인 return null; // 연결되지 않은 경로
var connection = connections.FirstOrDefault(c =>
(c.P1.Value == previousRFID && c.P2.Value == currentRFID) || // 연결 방향에 따라 실제 이동 방향 결정
(c.P1.Value == currentRFID && c.P2.Value == previousRFID)); if (connection.P1.Value == previousRFID && connection.P2.Value == currentRFID)
{
if (connection == null) return Direction.Forward; // Start -> End 방향으로 이동
return null; // 연결되지 않은 경로 }
else
// 연결 방향에 따라 실제 이동 방향 결정 {
if (connection.P1.Value == previousRFID && connection.P2.Value == currentRFID) return Direction.Backward; // End -> Start 방향으로 이동
{ }
return Direction.Forward; // Start -> End 방향으로 이동 }
}
else // 연결 정보 기반 방향 불일치 검증 및 정정
{ public bool ValidateAndCorrectDirectionByConnection(Direction expectedDirection, List<RFIDConnection> connections)
return Direction.Backward; // End -> Start 방향으로 이동 {
} if (MovementHistory.Count < 2 || connections == null)
} return true; // 검증 불가능한 경우
// 연결 정보 기반 방향 불일치 검증 및 정정 // 최근 두 RFID 값 가져오기
public bool ValidateAndCorrectDirectionByConnection(Direction expectedDirection, List<RFIDConnection> connections) var recentRFIDs = MovementHistory.Skip(MovementHistory.Count - 2).Take(2).ToList();
{ if (recentRFIDs.Count < 2)
if (MovementHistory.Count < 2 || connections == null) return true;
return true; // 검증 불가능한 경우
var previousRFID = recentRFIDs[0];
// 최근 두 RFID 값 가져오기 var currentRFID = recentRFIDs[1];
var recentRFIDs = MovementHistory.Skip(MovementHistory.Count - 2).Take(2).ToList();
if (recentRFIDs.Count < 2) var actualDirection = CalculateActualDirectionByConnection(currentRFID.Value, previousRFID.Value, connections);
return true; if (!actualDirection.HasValue)
return true; // 연결 정보로 방향 판단 불가
var previousRFID = recentRFIDs[0];
var currentRFID = recentRFIDs[1]; // 방향이 일치하지 않는 경우
if (actualDirection.Value != expectedDirection)
var actualDirection = CalculateActualDirectionByConnection(currentRFID.Value, previousRFID.Value, connections); {
if (!actualDirection.HasValue) // AGV 모터 방향을 실제 이동 방향으로 정정
return true; // 연결 정보로 방향 판단 불가 CurrentAGVDirection = actualDirection.Value;
TargetDirection = actualDirection.Value;
// 방향이 일치하지 않는 경우
if (actualDirection.Value != expectedDirection) return false; // 정정됨을 알림
{ }
// AGV 모터 방향을 실제 이동 방향으로 정정
CurrentAGVDirection = actualDirection.Value; return true; // 방향 일치
TargetDirection = actualDirection.Value; }
return false; // 정정됨을 알림 // RFID 순서 기반 실제 이동 방향 계산 (기존 메서드 - 호환성 유지)
} public Direction? CalculateActualDirectionByRFID()
{
return true; // 방향 일치 if (MovementHistory.Count < 2)
} return null;
// RFID 순서 기반 실제 이동 방향 계산 (기존 메서드 - 호환성 유지) // 최근 두 RFID 값으로부터 실제 이동 방향 계산
public Direction? CalculateActualDirectionByRFID() var recentRFIDs = MovementHistory.Skip(Math.Max(0, MovementHistory.Count - 2)).Take(2).ToList();
{ if (recentRFIDs.Count < 2)
if (MovementHistory.Count < 2) return null;
return null;
var prevRFID = recentRFIDs[0];
// 최근 두 RFID 값으로부터 실제 이동 방향 계산 var currentRFID = recentRFIDs[1];
var recentRFIDs = MovementHistory.Skip(Math.Max(0, MovementHistory.Count - 2)).Take(2).ToList();
if (recentRFIDs.Count < 2) // RFID 값의 증가/감소로 방향 판단
return null; if (currentRFID.Value > prevRFID.Value)
{
var prevRFID = recentRFIDs[0]; return Direction.Forward; // RFID 값이 증가하면 전진
var currentRFID = recentRFIDs[1]; }
else if (currentRFID.Value < prevRFID.Value)
// RFID 값의 증가/감소로 방향 판단 {
if (currentRFID.Value > prevRFID.Value) return Direction.Backward; // RFID 값이 감소하면 후진
{ }
return Direction.Forward; // RFID 값이 증가하면 전진 else
} {
else if (currentRFID.Value < prevRFID.Value) return null; // 같은 RFID 값이면 방향 판단 불가
{ }
return Direction.Backward; // RFID 값이 감소하면 후진 }
}
else
{ }
return null; // 같은 RFID 값이면 방향 판단 불가
} public class PathNode
} {
public Point Location { get; set; }
public string RFID { get; set; }
} public double G { get; set; } // 시작점에서 현재 노드까지의 비용
public double H { get; set; } // 현재 노드에서 목표점까지의 예상 비용
public class PathNode public double F => G + H; // 총 비용
{ public PathNode Parent { get; set; }
public Point Location { get; set; }
public string RFID { get; set; } public PathNode(Point location, string rfid)
public double G { get; set; } // 시작점에서 현재 노드까지의 비용 {
public double H { get; set; } // 현재 노드에서 목표점까지의 예상 비용 Location = location;
public double F => G + H; // 총 비용 RFID = rfid;
public PathNode Parent { get; set; } G = 0;
H = 0;
public PathNode(Point location, string rfid) Parent = null;
{ }
Location = location; }
RFID = rfid;
G = 0;
H = 0;
Parent = null;
}
}
} }

View File

@@ -1,4 +1,5 @@
using AGVControl.Models; using AGVControl.Models;
using System;
namespace AGVControl namespace AGVControl
{ {
@@ -9,6 +10,48 @@ namespace AGVControl
public string Reason { get; set; } public string Reason { get; set; }
public AGVActionReasonCode ReasonCode { get; set; } public AGVActionReasonCode ReasonCode { get; set; }
public AGVMoveState MoveState { get; set; } // RUN 또는 STOP public AGVMoveState MoveState { get; set; } // RUN 또는 STOP
} public AgvSpeed? MoveSpeed { get; set; }
public AgvRunDirection? MoveDiv { get; set; }
public UInt32 Idx { get; set; }
public bool Changed { get; set; }
// override object.Equals
public bool Equals(AGVActionPrediction obj)
{
// null 체크
if (obj == null) return false;
// 참조가 같으면 true
if (ReferenceEquals(this, obj)) return true;
// 핵심 속성들만 비교 (Idx, Changed 제외)
if (obj.Direction != this.Direction) return false;
if (obj.ReasonCode != this.ReasonCode) return false;
if (obj.MoveState != this.MoveState) return false;
if (obj.MoveSpeed != this.MoveSpeed) return false;
if (obj.MoveDiv != this.MoveDiv) return false;
// NextRFID 비교 (null 체크 포함)
if (obj.NextRFID == null || this.NextRFID == null)
{
if (obj.NextRFID != this.NextRFID) return false; // 하나만 null이면 false
}
else
{
if (obj.NextRFID.Value != this.NextRFID.Value) return false;
}
// Reason 비교 (null 체크 포함)
if (obj.Reason == null || this.Reason == null)
{
if (obj.Reason != this.Reason) return false; // 하나만 null이면 false
}
else
{
if (obj.Reason != this.Reason) return false;
}
return true;
}
}
} }

View File

@@ -1,9 +1,75 @@
using System.Drawing; using System.Drawing;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Windows.Forms;
namespace AGVControl.Models namespace AGVControl.Models
{ {
/// <summary>
/// <20><><EFBFBD><EFBFBD>Ư<EFBFBD><C6AF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public class RoadInformation
{
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public RFIDPoint P1 { get; set; }
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public RFIDPoint P2 { get; set; }
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EBBFA9>
/// </summary>
public bool Enable { get; set; }
/// <summary>
/// AGV<47><56> <20>̵<EFBFBD><CCB5><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE><EFBFBD><EFBFBD>)
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD> <20>ش<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20>ֵ<EFBFBD>
/// </summary>
public Direction? LiftDirection { get; set; }
/// <summary>
/// AGV<47>̵<EFBFBD><CCB5><EFBFBD> <20>ӵ<EFBFBD> (high, middle, low)
/// </summary>
public AgvSpeed? MoveSpeed { get; set; }
/// <summary>
/// AGV<47>̵<EFBFBD><CCB5><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28>ºб<C2BA>, <20><><EFBFBD><EFBFBD>, <20><><EFBFBD>б<EFBFBD>)
/// </summary>
public AgvRunDirection? MoveDirection { get; set; }
public RoadInformation()
{
P1 = null;
P2 = null;
LiftDirection = null;
MoveSpeed = null;
MoveDirection = null;
Enable = false;
}
/// <summary>
/// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD><C7BE>ִ<EFBFBD><D6B4><EFBFBD>
/// </summary>
public bool HasValue
{
get
{
if (P1 == null || P2 == null) return false;
if (LiftDirection == null && MoveSpeed == null && MoveDirection == null) return false;
return true;
}
}
}
public class MagnetLine public class MagnetLine
{ {
public Point StartPoint { get; set; } public Point StartPoint { get; set; }

View File

@@ -1,14 +1,195 @@
using AGVControl.Models; using AGVControl.Models;
using AR;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics.Tracing;
namespace AGVControl namespace AGVControl
{ {
public class RFIDConnection public class RFIDConnection
{ {
/// <summary>
/// 시작지점
/// </summary>
public RFIDPoint P1 { get; set; } public RFIDPoint P1 { get; set; }
/// <summary>
/// 종료지점
/// </summary>
public RFIDPoint P2 { get; set; } public RFIDPoint P2 { get; set; }
public bool DisableP1_to_P2 { get; set; }
public bool DisableP2_to_P1 { get; set; } /// <summary>
public float Distance { get; set; } /// 도로의 사용여부
/// </summary>
public bool EnableP { get; set; }
public bool EnableN { get; set; }
/// <summary>
/// AGV의 이동방향(리프트방향)
/// 목적지 방향과의 일치를 위해 해당 방향을 설정할 수 있따
/// </summary>
public Direction? LiftDirectionP { get; set; }
public Direction? LiftDirectionN { get; set; }
/// <summary>
/// AGV이동시 속도 (high, middle, low)
/// </summary>
public AgvSpeed? MoveSpeedP { get; set; }
public AgvSpeed? MoveSpeedN { get; set; }
/// <summary>
/// AGV이동시 방향모드(좌분기, 전진, 우분기)
/// </summary>
public AgvRunDirection? MoveDirectionP { get; set; }
public AgvRunDirection? MoveDirectionN { get; set; }
/// <summary>
/// 파일저장 및 불러오기시 사용하는 문자열로 반환
/// </summary>
[Browsable(false)]
public string DataFileString
{
get
{
var str_enbP = EnableP ? "1" : "0";
var str_liftP = "";
if (LiftDirectionP != null) str_liftP = ((int)LiftDirectionP).ToString();
var str_movespeedP = "";
if (MoveSpeedP != null) str_movespeedP = ((int)MoveSpeedP).ToString();
var str_movdirP = "";
if (MoveDirectionP != null) str_movdirP = ((int)MoveDirectionP).ToString();
var str_enbN = EnableP ? "1" : "0";
var str_liftN = "";
if (LiftDirectionN != null) str_liftN = ((int)LiftDirectionN).ToString();
var str_movespeedN = "";
if (MoveSpeedN != null) str_movespeedN = ((int)MoveSpeedN).ToString();
var str_movdirN = "";
if (MoveDirectionN != null) str_movdirN = ((int)MoveDirectionN).ToString();
var PStr= $"{P1.Location.X},{P1.Location.Y},{P2.Location.X},{P2.Location.Y}," + //location
$"{P1.Value},{P2.Value}," + //rfid values
$"{str_enbP};{str_liftP};{str_movespeedP};{str_movdirP}," +
$"{str_enbN};{str_liftN};{str_movespeedN};{str_movdirN}";
return $"{PStr}";
}
set
{
var buf = value.Split(',');
if (buf.Length >= 2)
{
var p1x = int.Parse(buf[0]);
var p1y = int.Parse(buf[1]);
var p2x = int.Parse(buf[2]);
var p2y = int.Parse(buf[3]);
var p1v = uint.Parse(buf[4]);
var p2v = uint.Parse(buf[5]);
if (P1 == null) P1 = new RFIDPoint();
P1.Location = new System.Drawing.Point(p1x, p1y);
P1.Value = p1v;
if (P2 == null) P2 = new RFIDPoint();
P2.Location = new System.Drawing.Point(p2x, p2y);
P2.Value = p2v;
if (buf[6].Contains(";")) //양방향 정보
{
var StrP = buf[6].Split(';');
var StrN = buf[7].Split(';');
//Positive
this.EnableP = StrP[0] == "1";
if (StrP[1].isEmpty()) LiftDirectionP = null;
else LiftDirectionP = (Direction)int.Parse(StrP[1]);
if (StrP[2].isEmpty()) MoveSpeedP = null;
else MoveSpeedP = (AgvSpeed)int.Parse(StrP[2]);
if (StrP[3].isEmpty()) MoveDirectionP = null;
else MoveDirectionP = (AgvRunDirection)int.Parse(StrP[3]);
//Negative
this.EnableN = StrN[0] == "1";
if (StrN[1].isEmpty()) LiftDirectionN = null;
else LiftDirectionN = (Direction)int.Parse(StrN[1]);
if (StrN[2].isEmpty()) MoveSpeedN = null;
else MoveSpeedN = (AgvSpeed)int.Parse(StrN[2]);
if (StrN[3].isEmpty()) MoveDirectionN = null;
else MoveDirectionN = (AgvRunDirection)int.Parse(StrN[3]);
}
else
{
this.EnableP = buf[6] == "1";
if (buf[7].isEmpty()) LiftDirectionP = null;
else LiftDirectionP = (Direction)int.Parse(buf[7]);
if (buf[8].isEmpty()) MoveSpeedP = null;
else MoveSpeedP = (AgvSpeed)int.Parse(buf[8]);
if (buf[9].isEmpty()) MoveDirectionP = null;
else MoveDirectionP = (AgvRunDirection)int.Parse(buf[9]);
this.EnableN = this.EnableP;
this.LiftDirectionN = this.LiftDirectionP;
this.MoveSpeedN = this.MoveSpeedP;
this.MoveDirectionN = this.MoveDirectionP;
}
}
}
}
public RFIDConnection(string dataline = "")
{
P1 = null;
P2 = null;
LiftDirectionP = null;
MoveSpeedP = null;
MoveDirectionP = null;
EnableP = false;
LiftDirectionN = null;
MoveSpeedN = null;
MoveDirectionP = null;
EnableP = false;
if (dataline.isEmpty() == false) DataFileString = dataline;
}
/// <summary>
/// 값이 설정되어있는지
/// </summary>
public bool HasValue
{
get
{
if (P1 == null || P2 == null) return false;
if (LiftDirectionP == null && MoveSpeedP == null && MoveDirectionP == null &&
LiftDirectionN == null && MoveSpeedN == null && MoveDirectionN == null) return false;
return true;
}
}
public override bool Equals(object obj) public override bool Equals(object obj)
@@ -27,7 +208,7 @@ namespace AGVControl
public override string ToString() public override string ToString()
{ {
//연결정보를 확인 //연결정보를 확인
return $"{P1.Value} ↔ {P2.Value},P1-2:{(DisableP1_to_P2 ? "X" : "O")},P2-1:{(DisableP2_to_P1 ? "X" : "O")}"; return $"{P1.Value} ↔ {P2.Value},ENB:{(EnableP ? "O" : "X")}|{(EnableN ? "O" : "X")}";
} }
} }
} }

View File

@@ -1,6 +1,7 @@
using System.Drawing; using System.Drawing;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
namespace AGVControl.Models namespace AGVControl.Models
{ {
public class RFIDPoint public class RFIDPoint
@@ -11,7 +12,9 @@ namespace AGVControl.Models
public bool IsBidirectional { get; set; } // 양방향 연결 여부 public bool IsBidirectional { get; set; } // 양방향 연결 여부
public bool IsRotatable { get; set; } // 회전 가능 여부 public bool IsRotatable { get; set; } // 회전 가능 여부
public Direction? FixedDirection { get; set; } // 고정 방향(없으면 null) public Direction? FixedDirection { get; set; } // 고정 방향(없으면 null)
public bool IsTerminal { get; set; } // 종단 여부 public bool IsTerminal { get; set; } // 종단 여부
[Browsable(false)]
public RectangleF Bounds { get; set; } public RectangleF Bounds { get; set; }
public void Clear() public void Clear()
{ {

View File

@@ -6,12 +6,32 @@ using System.Threading.Tasks;
namespace AGVControl namespace AGVControl
{ {
public enum Direction
{
Forward = 0,
Backward = 1,
Stop = 2
}
public enum AGVMoveState public enum AGVMoveState
{ {
Stop = 0, Stop = 0,
Run Run
} }
public enum AgvSpeed
{
High,
Middle,
Low,
}
public enum AgvRunDirection
{
Straight,
Left,
Right,
}
public enum AGVActionReasonCode public enum AGVActionReasonCode
{ {

View File

@@ -45,6 +45,18 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Dialog\fMapDesign.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Dialog\fMapDesign.Designer.cs">
<DependentUpon>fMapDesign.cs</DependentUpon>
</Compile>
<Compile Include="Dialog\fPropertyRFIDPoint.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Dialog\fPropertyRFIDPoint.Designer.cs">
<DependentUpon>fPropertyRFIDPoint.cs</DependentUpon>
</Compile>
<Compile Include="MapControlManager.cs" /> <Compile Include="MapControlManager.cs" />
<Compile Include="Models\AGVActionPrediction.cs" /> <Compile Include="Models\AGVActionPrediction.cs" />
<Compile Include="BatteryLevelGauge.cs"> <Compile Include="BatteryLevelGauge.cs">
@@ -103,6 +115,12 @@
</Compile> </Compile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Dialog\fMapDesign.resx">
<DependentUpon>fMapDesign.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Dialog\fPropertyRFIDPoint.resx">
<DependentUpon>fPropertyRFIDPoint.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="MapControl.resx"> <EmbeddedResource Include="MapControl.resx">
<DependentUpon>MapControl.cs</DependentUpon> <DependentUpon>MapControl.cs</DependentUpon>
</EmbeddedResource> </EmbeddedResource>

View File

@@ -109,15 +109,16 @@ namespace arDev
return false; return false;
} }
if (QueryIndex == 0)
if (data[1] == 0x03)
{ {
return ParseBMSInfo(); return ParseBMSInfo();
} }
else else if (data[1] == 0x04)
{ {
return ParseBMSCellVoltage(); return ParseBMSCellVoltage();
} }
else return false;
} }
bool ParseBMSCellVoltage() bool ParseBMSCellVoltage()
@@ -376,6 +377,7 @@ namespace arDev
} }
else else
{ {
return SendQuery_ReadStatue(); return SendQuery_ReadStatue();
} }
} }
@@ -398,14 +400,14 @@ namespace arDev
{ {
Recv0 = false; Recv0 = false;
var cmd = new List<byte>(); var cmd = new List<byte>();
cmd.Add(0xDD); cmd.Add(0xDD); //stx
cmd.Add(0xA5); cmd.Add(0xA5); //read
cmd.Add(0x03); cmd.Add(0x03); //command
cmd.Add(0x00); cmd.Add(0x00);
cmd.Add(0xFF); cmd.Add(0xFF);
cmd.Add(0xFD); cmd.Add(0xFD); //checksum1
cmd.Add(0x77); cmd.Add(0x77); //checksum2
cmd.Add(0x0D); cmd.Add(0x0D); //etx
return WriteData(cmd.ToArray()); return WriteData(cmd.ToArray());
} }

View File

@@ -1,4 +1,6 @@
 
using System.Windows.Forms;
namespace AGVEmulator namespace AGVEmulator
{ {
partial class Form1 partial class Form1
@@ -116,7 +118,7 @@ namespace AGVEmulator
this.chkSimulation = new System.Windows.Forms.CheckBox(); this.chkSimulation = new System.Windows.Forms.CheckBox();
this.checkBox3 = new System.Windows.Forms.CheckBox(); this.checkBox3 = new System.Windows.Forms.CheckBox();
this.panel10 = new System.Windows.Forms.Panel(); this.panel10 = new System.Windows.Forms.Panel();
this.numericUpDown1 = new System.Windows.Forms.NumericUpDown(); this.numericUpDown1 = new System.Windows.Forms.TextBox();
this.button18 = new System.Windows.Forms.Button(); this.button18 = new System.Windows.Forms.Button();
this.button17 = new System.Windows.Forms.Button(); this.button17 = new System.Windows.Forms.Button();
this.button15 = new System.Windows.Forms.Button(); this.button15 = new System.Windows.Forms.Button();
@@ -178,7 +180,6 @@ namespace AGVEmulator
this.groupBox5.SuspendLayout(); this.groupBox5.SuspendLayout();
this.panel13.SuspendLayout(); this.panel13.SuspendLayout();
this.panel10.SuspendLayout(); this.panel10.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit();
this.groupBox3.SuspendLayout(); this.groupBox3.SuspendLayout();
this.tabControl1.SuspendLayout(); this.tabControl1.SuspendLayout();
this.tabPage1.SuspendLayout(); this.tabPage1.SuspendLayout();
@@ -878,20 +879,11 @@ namespace AGVEmulator
// //
this.numericUpDown1.Font = new System.Drawing.Font("굴림", 20F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129))); this.numericUpDown1.Font = new System.Drawing.Font("굴림", 20F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
this.numericUpDown1.Location = new System.Drawing.Point(19, 220); this.numericUpDown1.Location = new System.Drawing.Point(19, 220);
this.numericUpDown1.Maximum = new decimal(new int[] {
9999999,
0,
0,
0});
this.numericUpDown1.Name = "numericUpDown1"; this.numericUpDown1.Name = "numericUpDown1";
this.numericUpDown1.Size = new System.Drawing.Size(130, 38); this.numericUpDown1.Size = new System.Drawing.Size(130, 38);
this.numericUpDown1.TabIndex = 9; this.numericUpDown1.TabIndex = 9;
this.numericUpDown1.Text = "101";
this.numericUpDown1.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; this.numericUpDown1.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.numericUpDown1.Value = new decimal(new int[] {
9900,
0,
0,
0});
this.numericUpDown1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.numericUpDown1_KeyDown); this.numericUpDown1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.numericUpDown1_KeyDown);
// //
// button18 // button18
@@ -1533,7 +1525,7 @@ namespace AGVEmulator
this.groupBox5.PerformLayout(); this.groupBox5.PerformLayout();
this.panel13.ResumeLayout(false); this.panel13.ResumeLayout(false);
this.panel10.ResumeLayout(false); this.panel10.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit(); this.panel10.PerformLayout();
this.groupBox3.ResumeLayout(false); this.groupBox3.ResumeLayout(false);
this.tabControl1.ResumeLayout(false); this.tabControl1.ResumeLayout(false);
this.tabPage1.ResumeLayout(false); this.tabPage1.ResumeLayout(false);
@@ -1615,7 +1607,7 @@ namespace AGVEmulator
private System.Windows.Forms.Button button15; private System.Windows.Forms.Button button15;
private System.Windows.Forms.Button button17; private System.Windows.Forms.Button button17;
private System.Windows.Forms.Button button18; private System.Windows.Forms.Button button18;
private System.Windows.Forms.NumericUpDown numericUpDown1; private TextBox numericUpDown1;
private System.Windows.Forms.Panel panel12; private System.Windows.Forms.Panel panel12;
private UC.AgvViewer agvViewer1; private UC.AgvViewer agvViewer1;
private System.Windows.Forms.Panel panel13; private System.Windows.Forms.Panel panel13;

View File

@@ -338,7 +338,7 @@ namespace AGVEmulator
private void AgvViewer1_TagTouched(object sender, UC.AgvViewer.TagArgs e) private void AgvViewer1_TagTouched(object sender, UC.AgvViewer.TagArgs e)
{ {
logAGV.Add($"tag touch:{e.Data}"); logAGV.Add($"tag touch:{e.Data}");
numericUpDown1.Value = decimal.Parse(e.Data); numericUpDown1.Text = e.Data;// decimal.Parse(e.Data);
button18.PerformClick(); button18.PerformClick();
} }
@@ -552,7 +552,12 @@ namespace AGVEmulator
private void button18_Click(object sender, EventArgs e) private void button18_Click(object sender, EventArgs e)
{ {
AGV.SendTag(numericUpDown1.Value.ToString()); if(int.TryParse(numericUpDown1.Text, out int tagno))
{
AGV.SendTag(tagno.ToString());
numericUpDown1.SelectAll();
numericUpDown1.Focus();
}
} }
private void agvViewer1_MouseDown(object sender, MouseEventArgs e) private void agvViewer1_MouseDown(object sender, MouseEventArgs e)