This commit is contained in:
chi
2025-06-17 17:34:26 +09:00
parent 4aee057726
commit 461a083a06
15 changed files with 614 additions and 165 deletions

View File

@@ -35,58 +35,58 @@ namespace Project
} }
} }
ePosition ParsePosition(uint tag, out string dirBW) //ePosition ParsePosition(uint tag, out string dirBW)
{ //{
var tagstr = tag.ToString(); // var tagstr = tag.ToString();
var tagno = tagstr.Substring(0, tagstr.Length - 1); // var tagno = tagstr.Substring(0, tagstr.Length - 1);
if (tag == PUB.setting.TAGNOT) { dirBW = "0"; return ePosition.NOT; } // if (tag == PUB.setting.TAGNOT) { dirBW = "0"; return ePosition.NOT; }
else if (tag == PUB.setting.TAG_QA_QC) { dirBW = "0"; return ePosition.QA_QC; } // else if (tag == PUB.setting.TAG_QA_QC) { dirBW = "0"; return ePosition.QA_QC; }
else if (tag == PUB.setting.TAG_QC_F1) { dirBW = "0"; return ePosition.QC_F1; } // else if (tag == PUB.setting.TAG_QC_F1) { dirBW = "0"; return ePosition.QC_F1; }
else if (tag == PUB.setting.TAG_F1_F2) { dirBW = "0"; return ePosition.F1_F2; } // else if (tag == PUB.setting.TAG_F1_F2) { dirBW = "0"; return ePosition.F1_F2; }
else if (tag == PUB.setting.TAG_F2_F3) { dirBW = "0"; return ePosition.F2_F3; } // else if (tag == PUB.setting.TAG_F2_F3) { dirBW = "0"; return ePosition.F2_F3; }
else if (tag == PUB.setting.TAG_F3_F4) { dirBW = "0"; return ePosition.F3_F4; } // else if (tag == PUB.setting.TAG_F3_F4) { dirBW = "0"; return ePosition.F3_F4; }
else if (tag == PUB.setting.TAG_F4_F5) { dirBW = "0"; return ePosition.F4_F5; } // else if (tag == PUB.setting.TAG_F4_F5) { dirBW = "0"; return ePosition.F4_F5; }
else if (tag == PUB.setting.TAGQAB) { dirBW = "0"; return ePosition.QA; } // else if (tag == PUB.setting.TAGQAB) { dirBW = "0"; return ePosition.QA; }
else if (tag == PUB.setting.TAGQCB) { dirBW = "0"; return ePosition.QC; } // else if (tag == PUB.setting.TAGQCB) { dirBW = "0"; return ePosition.QC; }
else if (tag == PUB.setting.TAGF1B) { dirBW = "0"; return ePosition.F1; } // else if (tag == PUB.setting.TAGF1B) { dirBW = "0"; return ePosition.F1; }
else if (tag == PUB.setting.TAGF2B) { dirBW = "0"; return ePosition.F2; } // else if (tag == PUB.setting.TAGF2B) { dirBW = "0"; return ePosition.F2; }
else if (tag == PUB.setting.TAGF3B) { dirBW = "0"; return ePosition.F3; } // else if (tag == PUB.setting.TAGF3B) { dirBW = "0"; return ePosition.F3; }
else if (tag == PUB.setting.TAGF4B) { dirBW = "0"; return ePosition.F4; } // else if (tag == PUB.setting.TAGF4B) { dirBW = "0"; return ePosition.F4; }
else if (tag == PUB.setting.TAGF5B) { dirBW = "0"; return ePosition.F5; } // else if (tag == PUB.setting.TAGF5B) { dirBW = "0"; return ePosition.F5; }
//else if (tag == PUB.setting.TAGQAA) { dirBW = "1"; return ePosition.QA; } // //else if (tag == PUB.setting.TAGQAA) { dirBW = "1"; return ePosition.QA; }
//else if (tag == PUB.setting.TAGCHA) { dirBW = "1"; return ePosition.CHARGE; } // //else if (tag == PUB.setting.TAGCHA) { dirBW = "1"; return ePosition.CHARGE; }
else if (tag == PUB.setting.TAGQAA) { dirBW = "1"; return ePosition.QA; } // else if (tag == PUB.setting.TAGQAA) { dirBW = "1"; return ePosition.QA; }
else if (tag == PUB.setting.TAGQCA) { dirBW = "1"; return ePosition.QC; } // else if (tag == PUB.setting.TAGQCA) { dirBW = "1"; return ePosition.QC; }
else if (tag == PUB.setting.TAGF1A) { dirBW = "1"; return ePosition.F1; } // else if (tag == PUB.setting.TAGF1A) { dirBW = "1"; return ePosition.F1; }
else if (tag == PUB.setting.TAGF2A) { dirBW = "1"; return ePosition.F2; } // else if (tag == PUB.setting.TAGF2A) { dirBW = "1"; return ePosition.F2; }
else if (tag == PUB.setting.TAGF3A) { dirBW = "1"; return ePosition.F3; } // else if (tag == PUB.setting.TAGF3A) { dirBW = "1"; return ePosition.F3; }
else if (tag == PUB.setting.TAGF4A) { dirBW = "1"; return ePosition.F4; } // else if (tag == PUB.setting.TAGF4A) { dirBW = "1"; return ePosition.F4; }
else if (tag == PUB.setting.TAGF5A) { dirBW = "1"; return ePosition.F5; } // else if (tag == PUB.setting.TAGF5A) { dirBW = "1"; return ePosition.F5; }
else if (tag == PUB.setting.TAGPOT) { dirBW = "0"; return ePosition.POT; } // else if (tag == PUB.setting.TAGPOT) { dirBW = "0"; return ePosition.POT; }
else // else
{ // {
if (tag > 9350 && tag < 9400) // if (tag > 9350 && tag < 9400)
{ // {
dirBW = "0"; return ePosition.QC_F1; // dirBW = "0"; return ePosition.QC_F1;
} // }
else if (tag > 9250 && tag < 9300) // else if (tag > 9250 && tag < 9300)
{ // {
dirBW = "0"; return ePosition.QA_QC; // dirBW = "0"; return ePosition.QA_QC;
} // }
else if (tag > 9000 && tag < 9100) // else if (tag > 9000 && tag < 9100)
{ // {
dirBW = "0"; return ePosition.NOT; // dirBW = "0"; return ePosition.NOT;
} // }
else // else
{ // {
dirBW = "0"; return ePosition.NONE; // dirBW = "0"; return ePosition.NONE;
} // }
} // }
} //}
bool _charging = false; bool _charging = false;
@@ -196,51 +196,53 @@ namespace Project
case arDev.Narumi.DataType.TAG: case arDev.Narumi.DataType.TAG:
{ {
//자동 실행 중이다. //자동 실행 중이다.
PUB.log.Add($"RFID값에서 위치정보를 추출할 수 있도록 해야한다"); PUB.log.Add($"AGV 태그수신 : {PUB.AGV.data.TagNo}");
PUB.Result.LastTAG = PUB.AGV.data.TagNo.ToString(); PUB.Result.LastTAG = PUB.AGV.data.TagNo.ToString();
var curpos = ParsePosition(PUB.AGV.data.TagNo, out string dirForward); //POT/NOT 보면 일단 바로 멈추게한다
if (curpos != PUB.Result.CurrentPos)
{
PUB.log.Add($"현재위치변경 {PUB.Result.CurrentPos} -> {curpos}");
PUB.Result.CurrentPos = curpos;
}
PUB.Result.CurrentPosCW = dirForward;
ctlPos1.SetPositionDeActive();
ctlPos1.SetPosition(PUB.Result.CurrentPos);
ctlPos1.SetDirection(dirForward);
ctlPos1.Invalidate();
//pot not를 보면 일단 바로 멈추게한다
if (PUB.Result.CurrentPos == ePosition.POT || PUB.Result.CurrentPos == ePosition.NOT) if (PUB.Result.CurrentPos == ePosition.POT || PUB.Result.CurrentPos == ePosition.NOT)
{ {
PUB.AGV.AGVMoveStop("TAG:pot/not 발견으로 즉시 멈춤"); var logEMsg = $"Stop by [POT/NOT]";
PUB.AGV.AGVMoveStop(logEMsg);
PUB.log.AddE(logEMsg);
} }
//자동, 상하차 모드일때 RFID 가 타겟위치에 올때는 - 멈춤을 설정해준 //맵데이터에서 현재 위치를 찾는
if (VAR.BOOL[eVarBool.FLAG_AUTORUN] == true && if (PUB.mapctl.SetCurrentPosition(PUB.AGV.data.TagNo) == false)
PUB.Result.CurrentPos == PUB.Result.TargetPos &&
PUB.Result.TargetPos != ePosition.NONE &&
(PUB.sm.RunStep == ERunStep.GODOWN ||
PUB.sm.RunStep == ERunStep.GOUP ||
PUB.sm.RunStep == ERunStep.GOHOME ||
PUB.sm.RunStep == ERunStep.GOCHARGE))
{ {
if (PUB.AGV.data.Sts == 'F' && dirForward == "0") //아래로 내려오고있음 if (VAR.BOOL[eVarBool.FLAG_AUTORUN] && PUB.AGV.system1.agv_run)
{ PUB.AGV.AGVMoveStop("unknown tag no");
PUB.AGV.AGVMoveStop("AGV_DataReceive", arDev.Narumi.eStopOpt.MarkStop);
PUB.Speak( Lang.); //존재하지 않는 태그가 읽히면 관련 오류를 표시한다.
}
else if (PUB.AGV.data.Sts == 'B' && dirForward == "1")
{
//VAR.BOOL[eVarBool.FLAG_NEXTSTOP_MARK] = true;
PUB.AGV.AGVMoveStop("AGV_DataReceive", arDev.Narumi.eStopOpt.MarkStop);
PUB.Speak(Lang.);
}
} }
else
{
//위치는 찾았다 해당 위치가 내 목적지라면 mark stop기능으로 전환한다
}
////자동, 상하차 모드일때 RFID 가 타겟위치에 올때는 - 멈춤을 설정해준다
//if (VAR.BOOL[eVarBool.FLAG_AUTORUN] == true &&
// PUB.Result.CurrentPos == PUB.Result.TargetPos &&
// PUB.Result.TargetPos != ePosition.NONE &&
// (PUB.sm.RunStep == ERunStep.GODOWN ||
// PUB.sm.RunStep == ERunStep.GOUP ||
// PUB.sm.RunStep == ERunStep.GOHOME ||
// PUB.sm.RunStep == ERunStep.GOCHARGE))
//{
// if (PUB.AGV.data.Sts == 'F' && dirForward == "0") //아래로 내려오고있음
// {
// PUB.AGV.AGVMoveStop("AGV_DataReceive", arDev.Narumi.eStopOpt.MarkStop);
// PUB.Speak( Lang.다음마크위치에서정지합니다);
// }
// else if (PUB.AGV.data.Sts == 'B' && dirForward == "1")
// {
// //VAR.BOOL[eVarBool.FLAG_NEXTSTOP_MARK] = true;
// PUB.AGV.AGVMoveStop("AGV_DataReceive", arDev.Narumi.eStopOpt.MarkStop);
// PUB.Speak(Lang.다음마크위치에서정지합니다);
// }
//}
} }
break; break;

View File

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

View File

@@ -34,8 +34,10 @@
this.richTextBox2 = new System.Windows.Forms.RichTextBox(); this.richTextBox2 = new System.Windows.Forms.RichTextBox();
this.richTextBox3 = new System.Windows.Forms.RichTextBox(); this.richTextBox3 = new System.Windows.Forms.RichTextBox();
this.richTextBox4 = new System.Windows.Forms.RichTextBox(); this.richTextBox4 = new System.Windows.Forms.RichTextBox();
this.label1 = new System.Windows.Forms.Label();
this.timer1 = new System.Windows.Forms.Timer(this.components); this.timer1 = new System.Windows.Forms.Timer(this.components);
this.panel1 = new System.Windows.Forms.Panel(); this.panel1 = new System.Windows.Forms.Panel();
this.lbIP = new System.Windows.Forms.Label();
this.button7 = new System.Windows.Forms.Button(); this.button7 = new System.Windows.Forms.Button();
this.button6 = new System.Windows.Forms.Button(); this.button6 = new System.Windows.Forms.Button();
this.button5 = new System.Windows.Forms.Button(); this.button5 = new System.Windows.Forms.Button();
@@ -44,7 +46,6 @@
this.button1 = new System.Windows.Forms.Button(); this.button1 = new System.Windows.Forms.Button();
this.button8 = new System.Windows.Forms.Button(); this.button8 = new System.Windows.Forms.Button();
this.button4 = new System.Windows.Forms.Button(); this.button4 = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.tableLayoutPanel1.SuspendLayout(); this.tableLayoutPanel1.SuspendLayout();
this.panel1.SuspendLayout(); this.panel1.SuspendLayout();
this.SuspendLayout(); this.SuspendLayout();
@@ -111,6 +112,18 @@
this.richTextBox4.TabIndex = 1; this.richTextBox4.TabIndex = 1;
this.richTextBox4.Text = ""; this.richTextBox4.Text = "";
// //
// label1
//
this.tableLayoutPanel1.SetColumnSpan(this.label1, 2);
this.label1.Dock = System.Windows.Forms.DockStyle.Fill;
this.label1.ForeColor = System.Drawing.Color.White;
this.label1.Location = new System.Drawing.Point(3, 460);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(518, 50);
this.label1.TabIndex = 2;
this.label1.Text = "label1";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// timer1 // timer1
// //
this.timer1.Interval = 200; this.timer1.Interval = 200;
@@ -118,6 +131,7 @@
// //
// panel1 // panel1
// //
this.panel1.Controls.Add(this.lbIP);
this.panel1.Controls.Add(this.button7); this.panel1.Controls.Add(this.button7);
this.panel1.Controls.Add(this.button6); this.panel1.Controls.Add(this.button6);
this.panel1.Controls.Add(this.button5); this.panel1.Controls.Add(this.button5);
@@ -132,6 +146,18 @@
this.panel1.Size = new System.Drawing.Size(1050, 67); this.panel1.Size = new System.Drawing.Size(1050, 67);
this.panel1.TabIndex = 7; this.panel1.TabIndex = 7;
// //
// lbIP
//
this.lbIP.Dock = System.Windows.Forms.DockStyle.Fill;
this.lbIP.Font = new System.Drawing.Font("Tahoma", 20F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
this.lbIP.ForeColor = System.Drawing.Color.White;
this.lbIP.Location = new System.Drawing.Point(300, 0);
this.lbIP.Name = "lbIP";
this.lbIP.Size = new System.Drawing.Size(250, 67);
this.lbIP.TabIndex = 8;
this.lbIP.Text = "000.000.000.000";
this.lbIP.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// button7 // button7
// //
this.button7.Dock = System.Windows.Forms.DockStyle.Right; this.button7.Dock = System.Windows.Forms.DockStyle.Right;
@@ -220,18 +246,6 @@
this.button4.UseVisualStyleBackColor = true; this.button4.UseVisualStyleBackColor = true;
this.button4.Click += new System.EventHandler(this.button4_Click); this.button4.Click += new System.EventHandler(this.button4_Click);
// //
// label1
//
this.tableLayoutPanel1.SetColumnSpan(this.label1, 2);
this.label1.Dock = System.Windows.Forms.DockStyle.Fill;
this.label1.ForeColor = System.Drawing.Color.White;
this.label1.Location = new System.Drawing.Point(3, 460);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(518, 50);
this.label1.TabIndex = 2;
this.label1.Text = "label1";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// fAgv // fAgv
// //
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
@@ -269,5 +283,6 @@
private System.Windows.Forms.Button button7; private System.Windows.Forms.Button button7;
private System.Windows.Forms.Button button8; private System.Windows.Forms.Button button8;
private System.Windows.Forms.Label label1; private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label lbIP;
} }
} }

View File

@@ -35,6 +35,7 @@ namespace Project.ViewForm
private void timer1_Tick(object sender, EventArgs e) private void timer1_Tick(object sender, EventArgs e)
{ {
timer1.Stop(); timer1.Stop();
lbIP.Text = PUB.IP;
label1.Text = PUB.AGV.LastSTS; label1.Text = PUB.AGV.LastSTS;
richTextBox1.Text = PUB.AGV.system0.ToString(); richTextBox1.Text = PUB.AGV.system0.ToString();
richTextBox2.Text = PUB.AGV.system1.ToString(); richTextBox2.Text = PUB.AGV.system1.ToString();

View File

@@ -70,13 +70,12 @@ namespace Project.ViewForm
} }
private void AGV_DataReceive(object sender, arDev.Narumi.DataEventArgs e) private void AGV_DataReceive(object sender, arDev.Narumi.DataEventArgs e)
{ {
switch (e.DataType) switch (e.DataType)
{ {
case arDev.Narumi.DataType.TAG: case arDev.Narumi.DataType.TAG:
var tagno = PUB.AGV.data.TagNo; //_AGV 파일에서 위치조정을 함
PUB.log.Add($"[auto] recv tag : {tagno}"); //var tagno = PUB.AGV.data.TagNo;
PUB.mapctl.SetCurrentPosition(tagno); //PUB.mapctl.SetCurrentPosition(tagno);
break; break;
} }
} }

View File

@@ -484,6 +484,7 @@
this.tbagvchannel.Name = "tbagvchannel"; this.tbagvchannel.Name = "tbagvchannel";
this.tbagvchannel.Size = new System.Drawing.Size(164, 54); this.tbagvchannel.Size = new System.Drawing.Size(164, 54);
this.tbagvchannel.TabIndex = 77; this.tbagvchannel.TabIndex = 77;
this.tbagvchannel.Click += new System.EventHandler(this.tbagvaddr_Click);
// //
// tbagvpanid // tbagvpanid
// //
@@ -492,6 +493,7 @@
this.tbagvpanid.Name = "tbagvpanid"; this.tbagvpanid.Name = "tbagvpanid";
this.tbagvpanid.Size = new System.Drawing.Size(164, 54); this.tbagvpanid.Size = new System.Drawing.Size(164, 54);
this.tbagvpanid.TabIndex = 76; this.tbagvpanid.TabIndex = 76;
this.tbagvpanid.Click += new System.EventHandler(this.tbagvaddr_Click);
// //
// tbagvaddr // tbagvaddr
// //
@@ -500,6 +502,7 @@
this.tbagvaddr.Name = "tbagvaddr"; this.tbagvaddr.Name = "tbagvaddr";
this.tbagvaddr.Size = new System.Drawing.Size(164, 54); this.tbagvaddr.Size = new System.Drawing.Size(164, 54);
this.tbagvaddr.TabIndex = 75; this.tbagvaddr.TabIndex = 75;
this.tbagvaddr.Click += new System.EventHandler(this.tbagvaddr_Click);
// //
// button7 // button7
// //

View File

@@ -662,5 +662,14 @@ namespace Project
} }
private void tbagvaddr_Click(object sender, EventArgs e)
{
var tb = sender as TextBox;
var rlt = UTIL.InputBox("input vlaue", tb.Text);
if (rlt.Item1 == false) return;
if (rlt.Item2.isEmpty()) return;
tb.Text = rlt.Item2;
}
} }
} }

View File

@@ -0,0 +1,24 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.2.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "agvControl", "agvControl.csproj", "{EB23DC0D-9A07-407C-762D-DF1CC8B3D822}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{EB23DC0D-9A07-407C-762D-DF1CC8B3D822}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EB23DC0D-9A07-407C-762D-DF1CC8B3D822}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EB23DC0D-9A07-407C-762D-DF1CC8B3D822}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EB23DC0D-9A07-407C-762D-DF1CC8B3D822}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {586342A4-FEA6-4584-82F4-39BA06630ABB}
EndGlobalSection
EndGlobal

View File

@@ -24,6 +24,7 @@ namespace AGVControl
public bool IsBidirectional { get; set; } public bool IsBidirectional { get; set; }
public float Distance { get; set; } public float Distance { get; set; }
public List<uint> IntermediateRFIDs { get; set; } = new List<uint>(); public List<uint> IntermediateRFIDs { get; set; } = new List<uint>();
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
@@ -81,7 +82,7 @@ namespace AGVControl
private const int SELECTION_DISTANCE = 15; // 선택 가능 거리를 늘림 private const int SELECTION_DISTANCE = 15; // 선택 가능 거리를 늘림
private bool isDraggingText = false; private bool isDraggingText = false;
private Point dragOffset; private Point dragOffset;
private List<Point> currentPath; // private List<Point> currentPath;
public MapText SelectedText => selectedText; public MapText SelectedText => selectedText;
@@ -210,6 +211,7 @@ namespace AGVControl
public RFIDPoint FindRFIDPoint(uint rfidValue) public RFIDPoint FindRFIDPoint(uint rfidValue)
{ {
if (rfidPoints == null || rfidPoints.Any() == false) return null;
return rfidPoints.FirstOrDefault(r => r.RFIDValue == rfidValue); return rfidPoints.FirstOrDefault(r => r.RFIDValue == rfidValue);
} }
@@ -220,6 +222,57 @@ namespace AGVControl
{ {
agv.CurrentPosition = rfidPoint.Location; agv.CurrentPosition = rfidPoint.Location;
agv.CurrentRFID = rfidValue; agv.CurrentRFID = rfidValue;
// 목적지가 설정되어 있고 경로가 있는 경우 검증
if (agv.TargetPosition != Point.Empty && agv.CurrentPath.Count > 0)
{
// 현재 위치가 경로에 있는지 확인
bool isOnPath = agv.CurrentPath.Contains(agv.CurrentPosition);
if (!isOnPath)
{
// 경로를 벗어났으므로 새로운 경로 계산
var pathResult = CalculatePath(agv.CurrentRFID, agv.TargetRFID);
if (pathResult.Success)
{
SetCurrentPath(pathResult.Path);
}
}
// AGV의 방향 결정
if (agv.CurrentPath.Count > 0)
{
// 다음 목적지 찾기
var nextPoint = agv.CurrentPath[0];
// 회전 가능 여부를 고려하여 방향 결정
agv.TargetDirection = DetermineDirection(agv.CurrentPosition, nextPoint, agv.TargetPosition);
}
}
// 목적지 RFID에 도착했고, 해당 RFID에 고정방향이 있으면 TargetDirection을 강제 설정
if (agv.TargetRFID == rfidValue)
{
var destRFID = FindRFIDPoint(rfidValue);
if (destRFID != null && destRFID.FixedDirection.HasValue)
{
agv.TargetDirection = destRFID.FixedDirection.Value;
}
}
this.Invalidate();
return true;
}
return false;
}
public bool SetTargetPosition(uint rfidValue)
{
var rfidPoint = FindRFIDPoint(rfidValue);
if (rfidPoint != null)
{
agv.TargetPosition = rfidPoint.Location;
agv.TargetRFID = rfidValue;
this.Invalidate(); this.Invalidate();
return true; return true;
} }
@@ -566,7 +619,7 @@ namespace AGVControl
if (path.Count > 0) if (path.Count > 0)
{ {
DrawPath(path); SetCurrentPath(path);
} }
} }
@@ -605,22 +658,22 @@ namespace AGVControl
return retval; return retval;
} }
var path = CalculatePath(startPoint.Location, endPoint.Location); retval.Path = CalculatePath(startPoint.Location, endPoint.Location);
if (path != null && path.Count > 0) if (retval.Path != null && retval.Path.Any())
{ {
DrawPath(path); //SetCurrentPath(retval.Path);
// 경로 상의 모든 RFID 값을 가져옴 //// 경로 상의 모든 RFID 값을 가져옴
var rfidPath = new List<uint>(); //var rfidPath = new List<uint>();
foreach (var point in path) //foreach (var point in path)
{ //{
var rfid = GetRFIDPoints() // var rfid = GetRFIDPoints()
.FirstOrDefault(r => r.Location == point); // .FirstOrDefault(r => r.Location == point);
if (rfid != null) // if (rfid != null)
{ // {
rfidPath.Add(rfid.RFIDValue); // rfidPath.Add(rfid.RFIDValue);
} // }
} //}
retval.Success = true; retval.Success = true;
} }
else else
@@ -683,8 +736,13 @@ namespace AGVControl
} }
else else
{ {
SetCurrentPath(rlt.Path); //현재 경로로 설정함
MessageBox.Show($"경로가 계산되었습니다.\nRFID 순서: {string.Join(" -> ", rlt.Path)}", MessageBox.Show($"경로가 계산되었습니다.\nRFID 순서: {string.Join(" -> ", rlt.Path)}",
"경로 계산", MessageBoxButtons.OK, MessageBoxIcon.Information); "경로 계산", MessageBoxButtons.OK, MessageBoxIcon.Information);
if (SetTargetPosition(vend) == false)
{
MessageBox.Show("목적지 설정 실패");
}
} }
break; break;
case "pos": case "pos":
@@ -700,12 +758,12 @@ namespace AGVControl
od.Filter = "path data|*.route"; od.Filter = "path data|*.route";
od.FilterIndex = 0; od.FilterIndex = 0;
od.RestoreDirectory = true; od.RestoreDirectory = true;
if(filename.isEmpty()==false) if (filename.isEmpty() == false)
{ {
od.FileName = System.IO.Path.GetFileName(filename); od.FileName = System.IO.Path.GetFileName(filename);
od.InitialDirectory = System.IO.Path.GetDirectoryName(filename); od.InitialDirectory = System.IO.Path.GetDirectoryName(filename);
} }
if (od.ShowDialog() == DialogResult.OK) if (od.ShowDialog() == DialogResult.OK)
{ {
filename = od.FileName; filename = od.FileName;
@@ -734,7 +792,7 @@ namespace AGVControl
if (od.ShowDialog() == DialogResult.OK) if (od.ShowDialog() == DialogResult.OK)
{ {
this.LoadFromFile(filename, out string errmsg); this.LoadFromFile(filename, out string errmsg);
if (errmsg.isEmpty() == false) UTIL.MsgE(errmsg); if (errmsg.isEmpty() == false) UTIL.MsgE(errmsg);
this.Invalidate(); this.Invalidate();
@@ -935,20 +993,21 @@ namespace AGVControl
if (e.Button == MouseButtons.Left) if (e.Button == MouseButtons.Left)
{ {
// 화면 좌표를 맵 좌표로 변환
var mapPoint = ScreenToMap(e.Location); var mapPoint = ScreenToMap(e.Location);
//RFID 포인트 찾기 //RFID 포인트 찾기
var selected_rfid = rfidPoints.Where(t => t.Bounds.Expand(SELECTION_DISTANCE, SELECTION_DISTANCE).Contains(mapPoint)).FirstOrDefault(); var selected_rfid = rfidPoints.Where(t => t.Bounds.Expand(SELECTION_DISTANCE, SELECTION_DISTANCE).Contains(mapPoint)).FirstOrDefault();
if (selected_rfid != null) if (selected_rfid != null)
{ {
var rlt = AR.UTIL.InputBox("rfid value", selected_rfid.RFIDValue.ToString()); // 고정방향 순환 변경: 없음→전진→후진→없음
if (rlt.Item1 == true) if (!selected_rfid.FixedDirection.HasValue)
{ selected_rfid.FixedDirection = Direction.Forward;
selected_rfid.RFIDValue = uint.Parse(rlt.Item2);// dialog.InputText; else if (selected_rfid.FixedDirection == Direction.Forward)
ProcessRFIDConnections(); selected_rfid.FixedDirection = Direction.Backward;
this.Invalidate(); else
} selected_rfid.FixedDirection = null;
this.Invalidate();
return; return;
} }
@@ -959,7 +1018,7 @@ namespace AGVControl
var rlt = AR.UTIL.InputBox("input", selected_txt.Text); var rlt = AR.UTIL.InputBox("input", selected_txt.Text);
if (rlt.Item1 == true) if (rlt.Item1 == true)
{ {
selected_txt.Text = rlt.Item2;// dialog.InputText; selected_txt.Text = rlt.Item2;
this.Invalidate(); this.Invalidate();
} }
return; return;
@@ -1108,9 +1167,9 @@ namespace AGVControl
} }
} }
public void DrawPath(List<Point> path) public void SetCurrentPath(List<Point> path)
{ {
currentPath = path; agv.CurrentPath = path;
this.Invalidate(); this.Invalidate();
} }
@@ -1130,6 +1189,7 @@ namespace AGVControl
DrawPath(e.Graphics); DrawPath(e.Graphics);
DrawAGV(e.Graphics); DrawAGV(e.Graphics);
DrawTargetFlag(e.Graphics); // 목적지 깃발 그리기 추가
// 선택된 개체 강조 표시 // 선택된 개체 강조 표시
if (selectedRFID != null) if (selectedRFID != null)
@@ -1180,51 +1240,85 @@ namespace AGVControl
var MarkerSize = 5; var MarkerSize = 5;
var half = MarkerSize / 2f; var half = MarkerSize / 2f;
rfid.Bounds = new RectangleF(rfid.Location.X - half, rfid.Location.Y - half, MarkerSize, MarkerSize); rfid.Bounds = new RectangleF(rfid.Location.X - half, rfid.Location.Y - half, MarkerSize, MarkerSize);
g.FillEllipse(Brushes.Green, rfid.Bounds);
//g.DrawString(rfid.RFIDValue, Font, Brushes.WhiteSmoke, rfid.Location.X + 5, rfid.Location.Y - 5); // 회전 가능 여부에 따라 다른 색상 사용
using (var brush = new SolidBrush(rfid.IsRotatable ? Color.Yellow : Color.Green))
{
g.FillEllipse(brush, rfid.Bounds);
}
// 고정방향이 있으면 테두리 색상 표시
if (rfid.FixedDirection.HasValue)
{
Color borderColor = rfid.FixedDirection.Value == Direction.Forward ? Color.DeepSkyBlue : Color.Gold; using (var pen = new Pen(borderColor, 2))
{
g.DrawEllipse(pen, rfid.Bounds.Expand(5,5));
}
}
} }
// RFID 포인트 그리기 // RFID 값 표시
foreach (var rfid in rfidPoints) foreach (var rfid in rfidPoints)
{ {
//g.FillEllipse(Brushes.Green, rfid.Location.X - 3, rfid.Location.Y - 3, 6, 6);
var tagstr = $"{rfid.RFIDValue}"; var tagstr = $"{rfid.RFIDValue}";
var fsize = g.MeasureString(tagstr, Font); var fsize = g.MeasureString(tagstr, Font);
var rect = new RectangleF(rfid.Bounds.X - (fsize.Width / 2f) + 3, var rect = new RectangleF(rfid.Bounds.X - (fsize.Width / 2f) + 3,
rfid.Bounds.Y + 6, rfid.Bounds.Y + 6,
fsize.Width, fsize.Width,
fsize.Height); fsize.Height);
//g.DrawRectangle(Pens.Red, rect);
g.DrawString(tagstr, Font, Brushes.WhiteSmoke, rect, new StringFormat g.DrawString(tagstr, Font, Brushes.WhiteSmoke, rect, new StringFormat
{ {
Alignment = StringAlignment.Center, Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center, LineAlignment = StringAlignment.Center,
}); });
} }
} }
private void DrawAGV(Graphics g) private void DrawAGV(Graphics g)
{ {
var agvsize = 30; var agvsize = 30;
var halfsize = (int)(agvsize / 2); var halfsize = (int)(agvsize / 2);
var rect = new Rectangle(agv.CurrentPosition.X - halfsize,
agv.CurrentPosition.Y - halfsize,
agvsize, agvsize);
var recti = new Rectangle(rect.X + 5, rect.Y + 5, rect.Width - 10, rect.Height - 10); // AGV의 현재 위치를 중심으로 하는 원
var circleRect = new Rectangle(
agv.CurrentPosition.X - halfsize,
agv.CurrentPosition.Y - halfsize,
agvsize, agvsize);
using (var sb = new SolidBrush(Color.FromArgb(150, Color.Gold))) // 삼각형 화살표를 위한 포인트 배열
g.FillEllipse(sb, rect); Point[] trianglePoints = new Point[3];
var arrowSize = halfsize - 5; // 삼각형 크기
using (var pen = new Pen(Color.Black)) // AGV의 방향에 따라 삼각형 포인트 계산
g.DrawEllipse(pen, rect); switch (agv.CurrentDirection)
{
case Direction.Forward:
trianglePoints[0] = new Point(agv.CurrentPosition.X, agv.CurrentPosition.Y - arrowSize);
trianglePoints[1] = new Point(agv.CurrentPosition.X - arrowSize, agv.CurrentPosition.Y + arrowSize);
trianglePoints[2] = new Point(agv.CurrentPosition.X + arrowSize, agv.CurrentPosition.Y + arrowSize);
break;
case Direction.Backward:
trianglePoints[0] = new Point(agv.CurrentPosition.X, agv.CurrentPosition.Y + arrowSize);
trianglePoints[1] = new Point(agv.CurrentPosition.X - arrowSize, agv.CurrentPosition.Y - arrowSize);
trianglePoints[2] = new Point(agv.CurrentPosition.X + arrowSize, agv.CurrentPosition.Y - arrowSize);
break;
}
using (var sb = new SolidBrush(Color.FromArgb(150, Color.White)))
g.FillEllipse(sb, recti);
using (var pen = new Pen(Color.Black))
g.DrawEllipse(pen, recti); // 원 그리기
Color bgcolor = agv.BatteryLevel > 80 ? Color.Lime : ( agv.BatteryLevel > 60 ? Color.Gold : Color.Tomato );
using (var circleBrush = new SolidBrush(Color.FromArgb(150, bgcolor)))
g.FillEllipse(circleBrush, circleRect);
using (var circlePen = new Pen(Color.Black, 2))
g.DrawEllipse(circlePen, circleRect);
// 삼각형 화살표 그리기
using (var arrowBrush = new SolidBrush(Color.FromArgb(200, Color.White)))
g.FillPolygon(arrowBrush, trianglePoints);
using (var arrowPen = new Pen(Color.Black, 2))
g.DrawPolygon(arrowPen, trianglePoints);
//g.DrawImage(Properties.Resources.ico_navi_40, circleRect);
} }
private void DrawCustomLines(Graphics g) private void DrawCustomLines(Graphics g)
@@ -1358,7 +1452,7 @@ namespace AGVControl
private void DrawPath(Graphics g) private void DrawPath(Graphics g)
{ {
if (currentPath == null || currentPath.Count < 2) if (agv.CurrentPath == null || agv.CurrentPath.Count < 2)
return; return;
Color pathColor = Color.FromArgb(100, Color.Lime); Color pathColor = Color.FromArgb(100, Color.Lime);
@@ -1367,9 +1461,9 @@ namespace AGVControl
using (Pen pathPen = new Pen(pathColor, pathWidth)) using (Pen pathPen = new Pen(pathColor, pathWidth))
{ {
pathPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash; pathPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
for (int i = 0; i < currentPath.Count - 1; i++) for (int i = 0; i < agv.CurrentPath.Count - 1; i++)
{ {
g.DrawLine(pathPen, currentPath[i], currentPath[i + 1]); g.DrawLine(pathPen, agv.CurrentPath[i], agv.CurrentPath[i + 1]);
} }
} }
} }
@@ -1728,5 +1822,85 @@ namespace AGVControl
g.DrawString(text, font, Brushes.Black, rect, format); g.DrawString(text, font, Brushes.Black, rect, format);
} }
} }
private void DrawTargetFlag(Graphics g)
{
if (agv.TargetPosition == Point.Empty) return;
// 바닥에 흰색 원 그리기
using (var baseBrush = new SolidBrush(Color.Red))
using (var basePen = new Pen(Color.Black, 1))
{
var baseSize = 8;
g.FillEllipse(baseBrush,
agv.TargetPosition.X - baseSize / 2,
agv.TargetPosition.Y - baseSize / 2,
baseSize, baseSize);
g.DrawEllipse(basePen,
agv.TargetPosition.X - baseSize / 2,
agv.TargetPosition.Y - baseSize / 2,
baseSize, baseSize);
}
// 깃대 그리기 (길이를 2/3로 줄임)
using (var polePen = new Pen(Color.Brown, 3))
{
var poleLength = 27; // 40 * 2/3 ≈ 27
g.DrawLine(polePen,
agv.TargetPosition.X,
agv.TargetPosition.Y,
agv.TargetPosition.X,
agv.TargetPosition.Y - poleLength);
}
// 깃발 그리기
Point[] flagPoints = new Point[3];
flagPoints[0] = new Point(agv.TargetPosition.X, agv.TargetPosition.Y - 27); // 깃대 길이에 맞춤
flagPoints[1] = new Point(agv.TargetPosition.X + 20, agv.TargetPosition.Y - 22);
flagPoints[2] = new Point(agv.TargetPosition.X, agv.TargetPosition.Y - 17);
using (var flagBrush = new SolidBrush(Color.Red))
using (var flagPen = new Pen(Color.DarkRed, 1))
{
g.FillPolygon(flagBrush, flagPoints);
g.DrawPolygon(flagPen, flagPoints);
}
}
// 회전 가능 여부 토글 함수
public void ToggleRotatable(uint rfidValue)
{
var rfidPoint = FindRFIDPoint(rfidValue);
if (rfidPoint != null)
{
rfidPoint.IsRotatable = !rfidPoint.IsRotatable;
this.Invalidate();
}
}
// 회전 가능 여부 확인 함수
public bool IsPointRotatable(uint rfidValue)
{
var rfidPoint = FindRFIDPoint(rfidValue);
return rfidPoint?.IsRotatable ?? false;
}
// 경로 계산 시 회전 가능 여부를 고려하여 방향 결정
private Direction DetermineDirection(Point current, Point next, Point target)
{
// 현재 위치가 회전 가능한 구간인 경우
var currentRFID = rfidPoints.FirstOrDefault(p => p.Location == current);
if (currentRFID?.IsRotatable ?? false)
{
// 목적지 방향으로 직접 방향 결정
if (target.X > current.X) return Direction.Forward;
if (target.X < current.X) return Direction.Backward;
if (target.Y > current.Y) return Direction.Forward;
if (target.Y < current.Y) return Direction.Backward;
}
// 회전 불가능한 구간인 경우 현재 진행 방향 유지
return agv.CurrentDirection;
}
} }
} }

View File

@@ -8,11 +8,22 @@ namespace AGVControl.Models
{ {
public Point CurrentPosition { get; set; } public Point CurrentPosition { get; set; }
public uint CurrentRFID { get; set; } public uint CurrentRFID { get; set; }
public float BatteryLevel { get; set; } = 0f;
/// <summary>
/// AGV에서 방향값이 수산됩니다.
/// </summary>
public Direction CurrentDirection { get; set; } public Direction CurrentDirection { get; set; }
/// <summary>
/// 현재위치가 수산되면 목적지까지의 방향값이 계산됩니다.
/// </summary>
public Direction TargetDirection { get; set; }
public bool IsMoving { get; set; } public bool IsMoving { get; set; }
public List<Point> CurrentPath { get; set; } public List<Point> CurrentPath { get; set; }
public List<Point> PlannedPath { get; set; } public List<Point> PlannedPath { get; set; }
public List<string> PathRFIDs { get; set; } public List<string> PathRFIDs { get; set; }
public Point TargetPosition { get; set; }
public uint TargetRFID { get; set; }
public AGV() public AGV()
{ {
@@ -20,6 +31,9 @@ namespace AGVControl.Models
PlannedPath = new List<Point>(); PlannedPath = new List<Point>();
PathRFIDs = new List<string>(); PathRFIDs = new List<string>();
CurrentDirection = Direction.Forward; CurrentDirection = Direction.Forward;
TargetPosition = Point.Empty;
TargetRFID = 0;
TargetDirection = Direction.Forward;
} }
public void Move() public void Move()
@@ -31,16 +45,6 @@ namespace AGVControl.Models
} }
} }
public void SetNewPath(List<Point> path)
{
CurrentPath = new List<Point>(path);
}
public void ClearPlannedPath()
{
PlannedPath.Clear();
PathRFIDs.Clear();
}
} }
public enum Direction public enum Direction

View File

@@ -1,6 +1,6 @@
using System.Drawing; using System.Drawing;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace AGVControl.Models namespace AGVControl.Models
{ {
public class RFIDPoint public class RFIDPoint
@@ -9,6 +9,15 @@ namespace AGVControl.Models
public uint RFIDValue { get; set; } public uint RFIDValue { get; set; }
public string NextRFID { get; set; } // 다음 RFID 포인트의 값 public string NextRFID { get; set; } // 다음 RFID 포인트의 값
public bool IsBidirectional { get; set; } // 양방향 연결 여부 public bool IsBidirectional { get; set; } // 양방향 연결 여부
public bool IsRotatable { get; set; } // 회전 가능 여부
public Direction? FixedDirection { get; set; } // 고정 방향(없으면 null)
public RectangleF Bounds { get; set; } public RectangleF Bounds { get; set; }
public RFIDPoint()
{
IsRotatable = false; // 기본값은 회전 불가능
IsBidirectional = true; // 기본값은 양방향
FixedDirection = null;
}
} }
} }

View File

@@ -0,0 +1,73 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 이 코드는 도구를 사용하여 생성되었습니다.
// 런타임 버전:4.0.30319.42000
//
// 파일 내용을 변경하면 잘못된 동작이 발생할 수 있으며, 코드를 다시 생성하면
// 이러한 변경 내용이 손실됩니다.
// </auto-generated>
//------------------------------------------------------------------------------
namespace AGVControl.Properties {
using System;
/// <summary>
/// 지역화된 문자열 등을 찾기 위한 강력한 형식의 리소스 클래스입니다.
/// </summary>
// 이 클래스는 ResGen 또는 Visual Studio와 같은 도구를 통해 StronglyTypedResourceBuilder
// 클래스에서 자동으로 생성되었습니다.
// 멤버를 추가하거나 제거하려면 .ResX 파일을 편집한 다음 /str 옵션을 사용하여 ResGen을
// 다시 실행하거나 VS 프로젝트를 다시 빌드하십시오.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// 이 클래스에서 사용하는 캐시된 ResourceManager 인스턴스를 반환합니다.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AGVControl.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// 이 강력한 형식의 리소스 클래스를 사용하여 모든 리소스 조회에 대해 현재 스레드의 CurrentUICulture 속성을
/// 재정의합니다.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// System.Drawing.Bitmap 형식의 지역화된 리소스를 찾습니다.
/// </summary>
internal static System.Drawing.Bitmap ico_navi_40 {
get {
object obj = ResourceManager.GetObject("ico_navi_40", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
}
}

View File

@@ -0,0 +1,124 @@
<?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>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="ico_navi_40" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\ico_navi_40.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

Binary file not shown.

After

Width:  |  Height:  |  Size: 718 B

View File

@@ -77,6 +77,11 @@
<DependentUpon>MyRadioButton.cs</DependentUpon> <DependentUpon>MyRadioButton.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="RoundButton.cs"> <Compile Include="RoundButton.cs">
<SubType>Component</SubType> <SubType>Component</SubType>
</Compile> </Compile>
@@ -94,6 +99,10 @@
<EmbeddedResource Include="MapControl.resx"> <EmbeddedResource Include="MapControl.resx">
<DependentUpon>MapControl.cs</DependentUpon> <DependentUpon>MapControl.cs</DependentUpon>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\CommUtil\arCommUtil.csproj"> <ProjectReference Include="..\CommUtil\arCommUtil.csproj">
@@ -101,5 +110,8 @@
<Name>arCommUtil</Name> <Name>arCommUtil</Name>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="Resources\ico_navi_40.png" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> </Project>