refactor: Consolidate RFID mapping and add bidirectional pathfinding
Major improvements to AGV navigation system: • Consolidated RFID management into MapNode, removing duplicate RfidMapping class • Enhanced MapNode with RFID metadata fields (RfidStatus, RfidDescription) • Added automatic bidirectional connection generation in pathfinding algorithms • Updated all components to use unified MapNode-based RFID system • Added command line argument support for AGVMapEditor auto-loading files • Fixed pathfinding failures by ensuring proper node connectivity Technical changes: - Removed RfidMapping class and dependencies across all projects - Updated AStarPathfinder with EnsureBidirectionalConnections() method - Modified MapLoader to use AssignAutoRfidIds() for RFID automation - Enhanced UnifiedAGVCanvas, SimulatorForm, and MainForm for MapNode integration - Improved data consistency and reduced memory footprint 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{B2C3D4E5-F6G7-8901-BCDE-F23456789012}</ProjectGuid>
|
||||
<ProjectGuid>{B2C3D4E5-0000-0000-0000-000000000000}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>AGVSimulator</RootNamespace>
|
||||
<AssemblyName>AGVSimulator</AssemblyName>
|
||||
@@ -42,14 +42,9 @@
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Models\SimulatorConfig.cs" />
|
||||
<Compile Include="Models\VirtualAGV.cs" />
|
||||
<Compile Include="Models\SimulationState.cs" />
|
||||
<Compile Include="Controls\SimulatorCanvas.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Controls\SimulatorCanvas.Designer.cs">
|
||||
<DependentUpon>SimulatorCanvas.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\SimulatorForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
@@ -60,17 +55,19 @@
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Controls\SimulatorCanvas.resx">
|
||||
<DependentUpon>SimulatorCanvas.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Forms\SimulatorForm.resx">
|
||||
<DependentUpon>SimulatorForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="build.bat" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AGVNavigationCore\AGVNavigationCore.csproj">
|
||||
<Project>{C5F7A8B2-8D3E-4A1B-9C6E-7F4D5E2A9B1C}</Project>
|
||||
<Name>AGVNavigationCore</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\AGVMapEditor\AGVMapEditor.csproj">
|
||||
<Project>{a1b2c3d4-e5f6-7890-abcd-ef1234567890}</Project>
|
||||
<Name>AGVMapEditor</Name>
|
||||
|
||||
@@ -4,6 +4,8 @@ using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using AGVMapEditor.Models;
|
||||
using AGVNavigationCore.Models;
|
||||
using AGVNavigationCore.PathFinding;
|
||||
using AGVSimulator.Models;
|
||||
|
||||
namespace AGVSimulator.Controls
|
||||
@@ -388,13 +390,13 @@ namespace AGVSimulator.Controls
|
||||
|
||||
private void DrawPath(Graphics g)
|
||||
{
|
||||
if (_currentPath?.NodeSequence == null || _currentPath.NodeSequence.Count < 2)
|
||||
if (_currentPath?.Path == null || _currentPath.Path.Count < 2)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < _currentPath.NodeSequence.Count - 1; i++)
|
||||
for (int i = 0; i < _currentPath.Path.Count - 1; i++)
|
||||
{
|
||||
var currentNodeId = _currentPath.NodeSequence[i];
|
||||
var nextNodeId = _currentPath.NodeSequence[i + 1];
|
||||
var currentNodeId = _currentPath.Path[i];
|
||||
var nextNodeId = _currentPath.Path[i + 1];
|
||||
|
||||
var currentNode = _mapNodes?.FirstOrDefault(n => n.NodeId == currentNodeId);
|
||||
var nextNode = _mapNodes?.FirstOrDefault(n => n.NodeId == nextNodeId);
|
||||
@@ -583,11 +585,11 @@ namespace AGVSimulator.Controls
|
||||
if (_currentPath != null && _currentPath.Success)
|
||||
{
|
||||
y += 10;
|
||||
g.DrawString($"경로: {_currentPath.NodeSequence.Count}개 노드", font, brush, new PointF(10, y));
|
||||
g.DrawString($"경로: {_currentPath.Path.Count}개 노드", font, brush, new PointF(10, y));
|
||||
y += 15;
|
||||
g.DrawString($"거리: {_currentPath.TotalDistance:F1}", font, brush, new PointF(10, y));
|
||||
y += 15;
|
||||
g.DrawString($"계산시간: {_currentPath.CalculationTime}ms", font, brush, new PointF(10, y));
|
||||
g.DrawString($"계산시간: {_currentPath.CalculationTimeMs}ms", font, brush, new PointF(10, y));
|
||||
}
|
||||
|
||||
font.Dispose();
|
||||
|
||||
646
Cs_HMI/AGVSimulator/Forms/SimulatorForm.Designer.cs
generated
646
Cs_HMI/AGVSimulator/Forms/SimulatorForm.Designer.cs
generated
@@ -45,20 +45,666 @@ namespace AGVSimulator.Forms
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this._menuStrip = new System.Windows.Forms.MenuStrip();
|
||||
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.openMapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.reloadMapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.launchMapEditorToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.simulationToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.startSimulationToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.stopSimulationToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.resetToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.viewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.fitToMapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.resetZoomToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this._toolStrip = new System.Windows.Forms.ToolStrip();
|
||||
this.openMapToolStripButton = new System.Windows.Forms.ToolStripButton();
|
||||
this.reloadMapToolStripButton = new System.Windows.Forms.ToolStripButton();
|
||||
this.launchMapEditorToolStripButton = new System.Windows.Forms.ToolStripButton();
|
||||
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.startSimulationToolStripButton = new System.Windows.Forms.ToolStripButton();
|
||||
this.stopSimulationToolStripButton = new System.Windows.Forms.ToolStripButton();
|
||||
this.resetToolStripButton = new System.Windows.Forms.ToolStripButton();
|
||||
this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.fitToMapToolStripButton = new System.Windows.Forms.ToolStripButton();
|
||||
this.resetZoomToolStripButton = new System.Windows.Forms.ToolStripButton();
|
||||
this._statusStrip = new System.Windows.Forms.StatusStrip();
|
||||
this._statusLabel = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this._coordLabel = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this._controlPanel = new System.Windows.Forms.Panel();
|
||||
this._statusGroup = new System.Windows.Forms.GroupBox();
|
||||
this._pathLengthLabel = new System.Windows.Forms.Label();
|
||||
this._agvCountLabel = new System.Windows.Forms.Label();
|
||||
this._simulationStatusLabel = new System.Windows.Forms.Label();
|
||||
this._pathGroup = new System.Windows.Forms.GroupBox();
|
||||
this._clearPathButton = new System.Windows.Forms.Button();
|
||||
this._startPathButton = new System.Windows.Forms.Button();
|
||||
this._calculatePathButton = new System.Windows.Forms.Button();
|
||||
this._targetNodeCombo = new System.Windows.Forms.ComboBox();
|
||||
this.targetNodeLabel = new System.Windows.Forms.Label();
|
||||
this._startNodeCombo = new System.Windows.Forms.ComboBox();
|
||||
this.startNodeLabel = new System.Windows.Forms.Label();
|
||||
this._agvControlGroup = new System.Windows.Forms.GroupBox();
|
||||
this._setPositionButton = new System.Windows.Forms.Button();
|
||||
this._rfidTextBox = new System.Windows.Forms.TextBox();
|
||||
this._rfidLabel = new System.Windows.Forms.Label();
|
||||
this._stopSimulationButton = new System.Windows.Forms.Button();
|
||||
this._startSimulationButton = new System.Windows.Forms.Button();
|
||||
this._removeAgvButton = new System.Windows.Forms.Button();
|
||||
this._addAgvButton = new System.Windows.Forms.Button();
|
||||
this._agvListCombo = new System.Windows.Forms.ComboBox();
|
||||
this._canvasPanel = new System.Windows.Forms.Panel();
|
||||
this.btAllReset = new System.Windows.Forms.ToolStripButton();
|
||||
this._menuStrip.SuspendLayout();
|
||||
this._toolStrip.SuspendLayout();
|
||||
this._statusStrip.SuspendLayout();
|
||||
this._controlPanel.SuspendLayout();
|
||||
this._statusGroup.SuspendLayout();
|
||||
this._pathGroup.SuspendLayout();
|
||||
this._agvControlGroup.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// _menuStrip
|
||||
//
|
||||
this._menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.fileToolStripMenuItem,
|
||||
this.simulationToolStripMenuItem,
|
||||
this.viewToolStripMenuItem,
|
||||
this.helpToolStripMenuItem});
|
||||
this._menuStrip.Location = new System.Drawing.Point(0, 0);
|
||||
this._menuStrip.Name = "_menuStrip";
|
||||
this._menuStrip.Size = new System.Drawing.Size(1200, 24);
|
||||
this._menuStrip.TabIndex = 0;
|
||||
this._menuStrip.Text = "menuStrip";
|
||||
//
|
||||
// fileToolStripMenuItem
|
||||
//
|
||||
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.openMapToolStripMenuItem,
|
||||
this.reloadMapToolStripMenuItem,
|
||||
this.toolStripSeparator1,
|
||||
this.launchMapEditorToolStripMenuItem,
|
||||
this.toolStripSeparator4,
|
||||
this.exitToolStripMenuItem});
|
||||
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
|
||||
this.fileToolStripMenuItem.Size = new System.Drawing.Size(57, 20);
|
||||
this.fileToolStripMenuItem.Text = "파일(&F)";
|
||||
//
|
||||
// openMapToolStripMenuItem
|
||||
//
|
||||
this.openMapToolStripMenuItem.Name = "openMapToolStripMenuItem";
|
||||
this.openMapToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O)));
|
||||
this.openMapToolStripMenuItem.Size = new System.Drawing.Size(183, 22);
|
||||
this.openMapToolStripMenuItem.Text = "맵 열기(&O)...";
|
||||
this.openMapToolStripMenuItem.Click += new System.EventHandler(this.OnOpenMap_Click);
|
||||
//
|
||||
// reloadMapToolStripMenuItem
|
||||
//
|
||||
this.reloadMapToolStripMenuItem.Name = "reloadMapToolStripMenuItem";
|
||||
this.reloadMapToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.R)));
|
||||
this.reloadMapToolStripMenuItem.Size = new System.Drawing.Size(183, 22);
|
||||
this.reloadMapToolStripMenuItem.Text = "맵 다시열기(&R)";
|
||||
this.reloadMapToolStripMenuItem.Click += new System.EventHandler(this.OnReloadMap_Click);
|
||||
//
|
||||
// toolStripSeparator1
|
||||
//
|
||||
this.toolStripSeparator1.Name = "toolStripSeparator1";
|
||||
this.toolStripSeparator1.Size = new System.Drawing.Size(180, 6);
|
||||
//
|
||||
// launchMapEditorToolStripMenuItem
|
||||
//
|
||||
this.launchMapEditorToolStripMenuItem.Name = "launchMapEditorToolStripMenuItem";
|
||||
this.launchMapEditorToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.M)));
|
||||
this.launchMapEditorToolStripMenuItem.Size = new System.Drawing.Size(183, 22);
|
||||
this.launchMapEditorToolStripMenuItem.Text = "MapEditor 실행(&M)";
|
||||
this.launchMapEditorToolStripMenuItem.Click += new System.EventHandler(this.OnLaunchMapEditor_Click);
|
||||
//
|
||||
// toolStripSeparator4
|
||||
//
|
||||
this.toolStripSeparator4.Name = "toolStripSeparator4";
|
||||
this.toolStripSeparator4.Size = new System.Drawing.Size(180, 6);
|
||||
//
|
||||
// exitToolStripMenuItem
|
||||
//
|
||||
this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
|
||||
this.exitToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.F4)));
|
||||
this.exitToolStripMenuItem.Size = new System.Drawing.Size(183, 22);
|
||||
this.exitToolStripMenuItem.Text = "종료(&X)";
|
||||
this.exitToolStripMenuItem.Click += new System.EventHandler(this.OnExit_Click);
|
||||
//
|
||||
// simulationToolStripMenuItem
|
||||
//
|
||||
this.simulationToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.startSimulationToolStripMenuItem,
|
||||
this.stopSimulationToolStripMenuItem,
|
||||
this.resetToolStripMenuItem});
|
||||
this.simulationToolStripMenuItem.Name = "simulationToolStripMenuItem";
|
||||
this.simulationToolStripMenuItem.Size = new System.Drawing.Size(94, 20);
|
||||
this.simulationToolStripMenuItem.Text = "시뮬레이션(&S)";
|
||||
//
|
||||
// startSimulationToolStripMenuItem
|
||||
//
|
||||
this.startSimulationToolStripMenuItem.Name = "startSimulationToolStripMenuItem";
|
||||
this.startSimulationToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F5;
|
||||
this.startSimulationToolStripMenuItem.Size = new System.Drawing.Size(145, 22);
|
||||
this.startSimulationToolStripMenuItem.Text = "시작(&S)";
|
||||
this.startSimulationToolStripMenuItem.Click += new System.EventHandler(this.OnStartSimulation_Click);
|
||||
//
|
||||
// stopSimulationToolStripMenuItem
|
||||
//
|
||||
this.stopSimulationToolStripMenuItem.Name = "stopSimulationToolStripMenuItem";
|
||||
this.stopSimulationToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F6;
|
||||
this.stopSimulationToolStripMenuItem.Size = new System.Drawing.Size(145, 22);
|
||||
this.stopSimulationToolStripMenuItem.Text = "정지(&T)";
|
||||
this.stopSimulationToolStripMenuItem.Click += new System.EventHandler(this.OnStopSimulation_Click);
|
||||
//
|
||||
// resetToolStripMenuItem
|
||||
//
|
||||
this.resetToolStripMenuItem.Name = "resetToolStripMenuItem";
|
||||
this.resetToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F7;
|
||||
this.resetToolStripMenuItem.Size = new System.Drawing.Size(145, 22);
|
||||
this.resetToolStripMenuItem.Text = "초기화(&R)";
|
||||
this.resetToolStripMenuItem.Click += new System.EventHandler(this.OnReset_Click);
|
||||
//
|
||||
// viewToolStripMenuItem
|
||||
//
|
||||
this.viewToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.fitToMapToolStripMenuItem,
|
||||
this.resetZoomToolStripMenuItem});
|
||||
this.viewToolStripMenuItem.Name = "viewToolStripMenuItem";
|
||||
this.viewToolStripMenuItem.Size = new System.Drawing.Size(59, 20);
|
||||
this.viewToolStripMenuItem.Text = "보기(&V)";
|
||||
//
|
||||
// fitToMapToolStripMenuItem
|
||||
//
|
||||
this.fitToMapToolStripMenuItem.Name = "fitToMapToolStripMenuItem";
|
||||
this.fitToMapToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.F)));
|
||||
this.fitToMapToolStripMenuItem.Size = new System.Drawing.Size(182, 22);
|
||||
this.fitToMapToolStripMenuItem.Text = "맵 맞춤(&F)";
|
||||
this.fitToMapToolStripMenuItem.Click += new System.EventHandler(this.OnFitToMap_Click);
|
||||
//
|
||||
// resetZoomToolStripMenuItem
|
||||
//
|
||||
this.resetZoomToolStripMenuItem.Name = "resetZoomToolStripMenuItem";
|
||||
this.resetZoomToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.D0)));
|
||||
this.resetZoomToolStripMenuItem.Size = new System.Drawing.Size(182, 22);
|
||||
this.resetZoomToolStripMenuItem.Text = "줌 초기화(&Z)";
|
||||
this.resetZoomToolStripMenuItem.Click += new System.EventHandler(this.OnResetZoom_Click);
|
||||
//
|
||||
// helpToolStripMenuItem
|
||||
//
|
||||
this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.aboutToolStripMenuItem});
|
||||
this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
|
||||
this.helpToolStripMenuItem.Size = new System.Drawing.Size(72, 20);
|
||||
this.helpToolStripMenuItem.Text = "도움말(&H)";
|
||||
//
|
||||
// aboutToolStripMenuItem
|
||||
//
|
||||
this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
|
||||
this.aboutToolStripMenuItem.Size = new System.Drawing.Size(123, 22);
|
||||
this.aboutToolStripMenuItem.Text = "정보(&A)...";
|
||||
this.aboutToolStripMenuItem.Click += new System.EventHandler(this.OnAbout_Click);
|
||||
//
|
||||
// _toolStrip
|
||||
//
|
||||
this._toolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.openMapToolStripButton,
|
||||
this.reloadMapToolStripButton,
|
||||
this.launchMapEditorToolStripButton,
|
||||
this.toolStripSeparator2,
|
||||
this.startSimulationToolStripButton,
|
||||
this.stopSimulationToolStripButton,
|
||||
this.resetToolStripButton,
|
||||
this.btAllReset,
|
||||
this.toolStripSeparator3,
|
||||
this.fitToMapToolStripButton,
|
||||
this.resetZoomToolStripButton});
|
||||
this._toolStrip.Location = new System.Drawing.Point(0, 24);
|
||||
this._toolStrip.Name = "_toolStrip";
|
||||
this._toolStrip.Size = new System.Drawing.Size(1200, 25);
|
||||
this._toolStrip.TabIndex = 1;
|
||||
this._toolStrip.Text = "toolStrip";
|
||||
//
|
||||
// openMapToolStripButton
|
||||
//
|
||||
this.openMapToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
|
||||
this.openMapToolStripButton.Name = "openMapToolStripButton";
|
||||
this.openMapToolStripButton.Size = new System.Drawing.Size(51, 22);
|
||||
this.openMapToolStripButton.Text = "맵 열기";
|
||||
this.openMapToolStripButton.ToolTipText = "맵 파일을 엽니다";
|
||||
this.openMapToolStripButton.Click += new System.EventHandler(this.OnOpenMap_Click);
|
||||
//
|
||||
// reloadMapToolStripButton
|
||||
//
|
||||
this.reloadMapToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
|
||||
this.reloadMapToolStripButton.Name = "reloadMapToolStripButton";
|
||||
this.reloadMapToolStripButton.Size = new System.Drawing.Size(63, 22);
|
||||
this.reloadMapToolStripButton.Text = "다시열기";
|
||||
this.reloadMapToolStripButton.ToolTipText = "현재 맵을 다시 로드합니다";
|
||||
this.reloadMapToolStripButton.Click += new System.EventHandler(this.OnReloadMap_Click);
|
||||
//
|
||||
// launchMapEditorToolStripButton
|
||||
//
|
||||
this.launchMapEditorToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
|
||||
this.launchMapEditorToolStripButton.Name = "launchMapEditorToolStripButton";
|
||||
this.launchMapEditorToolStripButton.Size = new System.Drawing.Size(71, 22);
|
||||
this.launchMapEditorToolStripButton.Text = "MapEditor";
|
||||
this.launchMapEditorToolStripButton.ToolTipText = "MapEditor를 실행합니다";
|
||||
this.launchMapEditorToolStripButton.Click += new System.EventHandler(this.OnLaunchMapEditor_Click);
|
||||
//
|
||||
// toolStripSeparator2
|
||||
//
|
||||
this.toolStripSeparator2.Name = "toolStripSeparator2";
|
||||
this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25);
|
||||
//
|
||||
// startSimulationToolStripButton
|
||||
//
|
||||
this.startSimulationToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
|
||||
this.startSimulationToolStripButton.Name = "startSimulationToolStripButton";
|
||||
this.startSimulationToolStripButton.Size = new System.Drawing.Size(99, 22);
|
||||
this.startSimulationToolStripButton.Text = "시뮬레이션 시작";
|
||||
this.startSimulationToolStripButton.ToolTipText = "시뮬레이션을 시작합니다";
|
||||
this.startSimulationToolStripButton.Click += new System.EventHandler(this.OnStartSimulation_Click);
|
||||
//
|
||||
// stopSimulationToolStripButton
|
||||
//
|
||||
this.stopSimulationToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
|
||||
this.stopSimulationToolStripButton.Name = "stopSimulationToolStripButton";
|
||||
this.stopSimulationToolStripButton.Size = new System.Drawing.Size(99, 22);
|
||||
this.stopSimulationToolStripButton.Text = "시뮬레이션 정지";
|
||||
this.stopSimulationToolStripButton.ToolTipText = "시뮬레이션을 정지합니다";
|
||||
this.stopSimulationToolStripButton.Click += new System.EventHandler(this.OnStopSimulation_Click);
|
||||
//
|
||||
// resetToolStripButton
|
||||
//
|
||||
this.resetToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
|
||||
this.resetToolStripButton.Name = "resetToolStripButton";
|
||||
this.resetToolStripButton.Size = new System.Drawing.Size(47, 22);
|
||||
this.resetToolStripButton.Text = "초기화";
|
||||
this.resetToolStripButton.ToolTipText = "시뮬레이션을 초기화합니다";
|
||||
this.resetToolStripButton.Click += new System.EventHandler(this.OnReset_Click);
|
||||
//
|
||||
// toolStripSeparator3
|
||||
//
|
||||
this.toolStripSeparator3.Name = "toolStripSeparator3";
|
||||
this.toolStripSeparator3.Size = new System.Drawing.Size(6, 25);
|
||||
//
|
||||
// fitToMapToolStripButton
|
||||
//
|
||||
this.fitToMapToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
|
||||
this.fitToMapToolStripButton.Name = "fitToMapToolStripButton";
|
||||
this.fitToMapToolStripButton.Size = new System.Drawing.Size(51, 22);
|
||||
this.fitToMapToolStripButton.Text = "맵 맞춤";
|
||||
this.fitToMapToolStripButton.ToolTipText = "맵 전체를 화면에 맞춥니다";
|
||||
this.fitToMapToolStripButton.Click += new System.EventHandler(this.OnFitToMap_Click);
|
||||
//
|
||||
// resetZoomToolStripButton
|
||||
//
|
||||
this.resetZoomToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
|
||||
this.resetZoomToolStripButton.Name = "resetZoomToolStripButton";
|
||||
this.resetZoomToolStripButton.Size = new System.Drawing.Size(63, 22);
|
||||
this.resetZoomToolStripButton.Text = "줌 초기화";
|
||||
this.resetZoomToolStripButton.ToolTipText = "줌을 초기화합니다";
|
||||
this.resetZoomToolStripButton.Click += new System.EventHandler(this.OnResetZoom_Click);
|
||||
//
|
||||
// _statusStrip
|
||||
//
|
||||
this._statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this._statusLabel,
|
||||
this._coordLabel});
|
||||
this._statusStrip.Location = new System.Drawing.Point(0, 778);
|
||||
this._statusStrip.Name = "_statusStrip";
|
||||
this._statusStrip.Size = new System.Drawing.Size(1200, 22);
|
||||
this._statusStrip.TabIndex = 2;
|
||||
this._statusStrip.Text = "statusStrip";
|
||||
//
|
||||
// _statusLabel
|
||||
//
|
||||
this._statusLabel.Name = "_statusLabel";
|
||||
this._statusLabel.Size = new System.Drawing.Size(31, 17);
|
||||
this._statusLabel.Text = "준비";
|
||||
//
|
||||
// _coordLabel
|
||||
//
|
||||
this._coordLabel.Name = "_coordLabel";
|
||||
this._coordLabel.Size = new System.Drawing.Size(0, 17);
|
||||
//
|
||||
// _controlPanel
|
||||
//
|
||||
this._controlPanel.BackColor = System.Drawing.SystemColors.Control;
|
||||
this._controlPanel.Controls.Add(this._statusGroup);
|
||||
this._controlPanel.Controls.Add(this._pathGroup);
|
||||
this._controlPanel.Controls.Add(this._agvControlGroup);
|
||||
this._controlPanel.Dock = System.Windows.Forms.DockStyle.Right;
|
||||
this._controlPanel.Location = new System.Drawing.Point(950, 49);
|
||||
this._controlPanel.Name = "_controlPanel";
|
||||
this._controlPanel.Size = new System.Drawing.Size(250, 729);
|
||||
this._controlPanel.TabIndex = 3;
|
||||
//
|
||||
// _statusGroup
|
||||
//
|
||||
this._statusGroup.Controls.Add(this._pathLengthLabel);
|
||||
this._statusGroup.Controls.Add(this._agvCountLabel);
|
||||
this._statusGroup.Controls.Add(this._simulationStatusLabel);
|
||||
this._statusGroup.Location = new System.Drawing.Point(10, 356);
|
||||
this._statusGroup.Name = "_statusGroup";
|
||||
this._statusGroup.Size = new System.Drawing.Size(230, 100);
|
||||
this._statusGroup.TabIndex = 3;
|
||||
this._statusGroup.TabStop = false;
|
||||
this._statusGroup.Text = "상태 정보";
|
||||
//
|
||||
// _pathLengthLabel
|
||||
//
|
||||
this._pathLengthLabel.AutoSize = true;
|
||||
this._pathLengthLabel.Location = new System.Drawing.Point(10, 65);
|
||||
this._pathLengthLabel.Name = "_pathLengthLabel";
|
||||
this._pathLengthLabel.Size = new System.Drawing.Size(71, 12);
|
||||
this._pathLengthLabel.TabIndex = 2;
|
||||
this._pathLengthLabel.Text = "경로 길이: -";
|
||||
//
|
||||
// _agvCountLabel
|
||||
//
|
||||
this._agvCountLabel.AutoSize = true;
|
||||
this._agvCountLabel.Location = new System.Drawing.Point(10, 45);
|
||||
this._agvCountLabel.Name = "_agvCountLabel";
|
||||
this._agvCountLabel.Size = new System.Drawing.Size(60, 12);
|
||||
this._agvCountLabel.TabIndex = 1;
|
||||
this._agvCountLabel.Text = "AGV 수: 0";
|
||||
//
|
||||
// _simulationStatusLabel
|
||||
//
|
||||
this._simulationStatusLabel.AutoSize = true;
|
||||
this._simulationStatusLabel.Location = new System.Drawing.Point(10, 25);
|
||||
this._simulationStatusLabel.Name = "_simulationStatusLabel";
|
||||
this._simulationStatusLabel.Size = new System.Drawing.Size(97, 12);
|
||||
this._simulationStatusLabel.TabIndex = 0;
|
||||
this._simulationStatusLabel.Text = "시뮬레이션: 정지";
|
||||
//
|
||||
// _pathGroup
|
||||
//
|
||||
this._pathGroup.Controls.Add(this._clearPathButton);
|
||||
this._pathGroup.Controls.Add(this._startPathButton);
|
||||
this._pathGroup.Controls.Add(this._calculatePathButton);
|
||||
this._pathGroup.Controls.Add(this._targetNodeCombo);
|
||||
this._pathGroup.Controls.Add(this.targetNodeLabel);
|
||||
this._pathGroup.Controls.Add(this._startNodeCombo);
|
||||
this._pathGroup.Controls.Add(this.startNodeLabel);
|
||||
this._pathGroup.Location = new System.Drawing.Point(10, 200);
|
||||
this._pathGroup.Name = "_pathGroup";
|
||||
this._pathGroup.Size = new System.Drawing.Size(230, 150);
|
||||
this._pathGroup.TabIndex = 1;
|
||||
this._pathGroup.TabStop = false;
|
||||
this._pathGroup.Text = "경로 제어";
|
||||
//
|
||||
// _clearPathButton
|
||||
//
|
||||
this._clearPathButton.Location = new System.Drawing.Point(150, 120);
|
||||
this._clearPathButton.Name = "_clearPathButton";
|
||||
this._clearPathButton.Size = new System.Drawing.Size(70, 25);
|
||||
this._clearPathButton.TabIndex = 6;
|
||||
this._clearPathButton.Text = "경로 지우기";
|
||||
this._clearPathButton.UseVisualStyleBackColor = true;
|
||||
this._clearPathButton.Click += new System.EventHandler(this.OnClearPath_Click);
|
||||
//
|
||||
// _startPathButton
|
||||
//
|
||||
this._startPathButton.Location = new System.Drawing.Point(80, 120);
|
||||
this._startPathButton.Name = "_startPathButton";
|
||||
this._startPathButton.Size = new System.Drawing.Size(65, 25);
|
||||
this._startPathButton.TabIndex = 5;
|
||||
this._startPathButton.Text = "경로 시작";
|
||||
this._startPathButton.UseVisualStyleBackColor = true;
|
||||
this._startPathButton.Click += new System.EventHandler(this.OnStartPath_Click);
|
||||
//
|
||||
// _calculatePathButton
|
||||
//
|
||||
this._calculatePathButton.Location = new System.Drawing.Point(10, 120);
|
||||
this._calculatePathButton.Name = "_calculatePathButton";
|
||||
this._calculatePathButton.Size = new System.Drawing.Size(65, 25);
|
||||
this._calculatePathButton.TabIndex = 4;
|
||||
this._calculatePathButton.Text = "경로 계산";
|
||||
this._calculatePathButton.UseVisualStyleBackColor = true;
|
||||
this._calculatePathButton.Click += new System.EventHandler(this.OnCalculatePath_Click);
|
||||
//
|
||||
// _targetNodeCombo
|
||||
//
|
||||
this._targetNodeCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this._targetNodeCombo.Location = new System.Drawing.Point(10, 95);
|
||||
this._targetNodeCombo.Name = "_targetNodeCombo";
|
||||
this._targetNodeCombo.Size = new System.Drawing.Size(210, 20);
|
||||
this._targetNodeCombo.TabIndex = 3;
|
||||
//
|
||||
// targetNodeLabel
|
||||
//
|
||||
this.targetNodeLabel.AutoSize = true;
|
||||
this.targetNodeLabel.Location = new System.Drawing.Point(10, 75);
|
||||
this.targetNodeLabel.Name = "targetNodeLabel";
|
||||
this.targetNodeLabel.Size = new System.Drawing.Size(63, 12);
|
||||
this.targetNodeLabel.TabIndex = 2;
|
||||
this.targetNodeLabel.Text = "목표 RFID:";
|
||||
//
|
||||
// _startNodeCombo
|
||||
//
|
||||
this._startNodeCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this._startNodeCombo.Location = new System.Drawing.Point(10, 45);
|
||||
this._startNodeCombo.Name = "_startNodeCombo";
|
||||
this._startNodeCombo.Size = new System.Drawing.Size(210, 20);
|
||||
this._startNodeCombo.TabIndex = 1;
|
||||
//
|
||||
// startNodeLabel
|
||||
//
|
||||
this.startNodeLabel.AutoSize = true;
|
||||
this.startNodeLabel.Location = new System.Drawing.Point(10, 25);
|
||||
this.startNodeLabel.Name = "startNodeLabel";
|
||||
this.startNodeLabel.Size = new System.Drawing.Size(63, 12);
|
||||
this.startNodeLabel.TabIndex = 0;
|
||||
this.startNodeLabel.Text = "시작 RFID:";
|
||||
//
|
||||
// _agvControlGroup
|
||||
//
|
||||
this._agvControlGroup.Controls.Add(this._setPositionButton);
|
||||
this._agvControlGroup.Controls.Add(this._rfidTextBox);
|
||||
this._agvControlGroup.Controls.Add(this._rfidLabel);
|
||||
this._agvControlGroup.Controls.Add(this._stopSimulationButton);
|
||||
this._agvControlGroup.Controls.Add(this._startSimulationButton);
|
||||
this._agvControlGroup.Controls.Add(this._removeAgvButton);
|
||||
this._agvControlGroup.Controls.Add(this._addAgvButton);
|
||||
this._agvControlGroup.Controls.Add(this._agvListCombo);
|
||||
this._agvControlGroup.Location = new System.Drawing.Point(10, 10);
|
||||
this._agvControlGroup.Name = "_agvControlGroup";
|
||||
this._agvControlGroup.Size = new System.Drawing.Size(230, 180);
|
||||
this._agvControlGroup.TabIndex = 0;
|
||||
this._agvControlGroup.TabStop = false;
|
||||
this._agvControlGroup.Text = "AGV 제어";
|
||||
//
|
||||
// _setPositionButton
|
||||
//
|
||||
this._setPositionButton.Location = new System.Drawing.Point(160, 138);
|
||||
this._setPositionButton.Name = "_setPositionButton";
|
||||
this._setPositionButton.Size = new System.Drawing.Size(60, 25);
|
||||
this._setPositionButton.TabIndex = 7;
|
||||
this._setPositionButton.Text = "위치설정";
|
||||
this._setPositionButton.UseVisualStyleBackColor = true;
|
||||
this._setPositionButton.Click += new System.EventHandler(this.OnSetPosition_Click);
|
||||
//
|
||||
// _rfidTextBox
|
||||
//
|
||||
this._rfidTextBox.Location = new System.Drawing.Point(10, 140);
|
||||
this._rfidTextBox.Name = "_rfidTextBox";
|
||||
this._rfidTextBox.Size = new System.Drawing.Size(140, 21);
|
||||
this._rfidTextBox.TabIndex = 6;
|
||||
this._rfidTextBox.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.OnRfidTextBox_KeyPress);
|
||||
//
|
||||
// _rfidLabel
|
||||
//
|
||||
this._rfidLabel.AutoSize = true;
|
||||
this._rfidLabel.Location = new System.Drawing.Point(10, 120);
|
||||
this._rfidLabel.Name = "_rfidLabel";
|
||||
this._rfidLabel.Size = new System.Drawing.Size(87, 12);
|
||||
this._rfidLabel.TabIndex = 5;
|
||||
this._rfidLabel.Text = "RFID 현재위치:";
|
||||
//
|
||||
// _stopSimulationButton
|
||||
//
|
||||
this._stopSimulationButton.Location = new System.Drawing.Point(120, 85);
|
||||
this._stopSimulationButton.Name = "_stopSimulationButton";
|
||||
this._stopSimulationButton.Size = new System.Drawing.Size(100, 25);
|
||||
this._stopSimulationButton.TabIndex = 4;
|
||||
this._stopSimulationButton.Text = "시뮬레이션 정지";
|
||||
this._stopSimulationButton.UseVisualStyleBackColor = true;
|
||||
this._stopSimulationButton.Click += new System.EventHandler(this.OnStopSimulation_Click);
|
||||
//
|
||||
// _startSimulationButton
|
||||
//
|
||||
this._startSimulationButton.Location = new System.Drawing.Point(10, 85);
|
||||
this._startSimulationButton.Name = "_startSimulationButton";
|
||||
this._startSimulationButton.Size = new System.Drawing.Size(100, 25);
|
||||
this._startSimulationButton.TabIndex = 3;
|
||||
this._startSimulationButton.Text = "시뮬레이션 시작";
|
||||
this._startSimulationButton.UseVisualStyleBackColor = true;
|
||||
this._startSimulationButton.Click += new System.EventHandler(this.OnStartSimulation_Click);
|
||||
//
|
||||
// _removeAgvButton
|
||||
//
|
||||
this._removeAgvButton.Location = new System.Drawing.Point(120, 55);
|
||||
this._removeAgvButton.Name = "_removeAgvButton";
|
||||
this._removeAgvButton.Size = new System.Drawing.Size(100, 25);
|
||||
this._removeAgvButton.TabIndex = 2;
|
||||
this._removeAgvButton.Text = "AGV 제거";
|
||||
this._removeAgvButton.UseVisualStyleBackColor = true;
|
||||
this._removeAgvButton.Click += new System.EventHandler(this.OnRemoveAGV_Click);
|
||||
//
|
||||
// _addAgvButton
|
||||
//
|
||||
this._addAgvButton.Location = new System.Drawing.Point(10, 55);
|
||||
this._addAgvButton.Name = "_addAgvButton";
|
||||
this._addAgvButton.Size = new System.Drawing.Size(100, 25);
|
||||
this._addAgvButton.TabIndex = 1;
|
||||
this._addAgvButton.Text = "AGV 추가";
|
||||
this._addAgvButton.UseVisualStyleBackColor = true;
|
||||
this._addAgvButton.Click += new System.EventHandler(this.OnAddAGV_Click);
|
||||
//
|
||||
// _agvListCombo
|
||||
//
|
||||
this._agvListCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this._agvListCombo.Location = new System.Drawing.Point(10, 25);
|
||||
this._agvListCombo.Name = "_agvListCombo";
|
||||
this._agvListCombo.Size = new System.Drawing.Size(210, 20);
|
||||
this._agvListCombo.TabIndex = 0;
|
||||
this._agvListCombo.SelectedIndexChanged += new System.EventHandler(this.OnAGVList_SelectedIndexChanged);
|
||||
//
|
||||
// _canvasPanel
|
||||
//
|
||||
this._canvasPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this._canvasPanel.Location = new System.Drawing.Point(0, 49);
|
||||
this._canvasPanel.Name = "_canvasPanel";
|
||||
this._canvasPanel.Size = new System.Drawing.Size(950, 729);
|
||||
this._canvasPanel.TabIndex = 4;
|
||||
//
|
||||
// btAllReset
|
||||
//
|
||||
this.btAllReset.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
|
||||
this.btAllReset.Name = "btAllReset";
|
||||
this.btAllReset.Size = new System.Drawing.Size(71, 22);
|
||||
this.btAllReset.Text = "전체초기화";
|
||||
this.btAllReset.ToolTipText = "시뮬레이션을 초기화합니다";
|
||||
this.btAllReset.Click += new System.EventHandler(this.btAllReset_Click);
|
||||
//
|
||||
// SimulatorForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(1200, 800);
|
||||
this.Controls.Add(this._canvasPanel);
|
||||
this.Controls.Add(this._controlPanel);
|
||||
this.Controls.Add(this._statusStrip);
|
||||
this.Controls.Add(this._toolStrip);
|
||||
this.Controls.Add(this._menuStrip);
|
||||
this.MainMenuStrip = this._menuStrip;
|
||||
this.Name = "SimulatorForm";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "AGV 시뮬레이터";
|
||||
this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
|
||||
this._menuStrip.ResumeLayout(false);
|
||||
this._menuStrip.PerformLayout();
|
||||
this._toolStrip.ResumeLayout(false);
|
||||
this._toolStrip.PerformLayout();
|
||||
this._statusStrip.ResumeLayout(false);
|
||||
this._statusStrip.PerformLayout();
|
||||
this._controlPanel.ResumeLayout(false);
|
||||
this._statusGroup.ResumeLayout(false);
|
||||
this._statusGroup.PerformLayout();
|
||||
this._pathGroup.ResumeLayout(false);
|
||||
this._pathGroup.PerformLayout();
|
||||
this._agvControlGroup.ResumeLayout(false);
|
||||
this._agvControlGroup.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.MenuStrip _menuStrip;
|
||||
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem openMapToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
|
||||
private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem simulationToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem startSimulationToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem stopSimulationToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem resetToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem viewToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem fitToMapToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem resetZoomToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStrip _toolStrip;
|
||||
private System.Windows.Forms.ToolStripButton openMapToolStripButton;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
|
||||
private System.Windows.Forms.ToolStripButton startSimulationToolStripButton;
|
||||
private System.Windows.Forms.ToolStripButton stopSimulationToolStripButton;
|
||||
private System.Windows.Forms.ToolStripButton resetToolStripButton;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator3;
|
||||
private System.Windows.Forms.ToolStripButton fitToMapToolStripButton;
|
||||
private System.Windows.Forms.ToolStripButton resetZoomToolStripButton;
|
||||
private System.Windows.Forms.StatusStrip _statusStrip;
|
||||
private System.Windows.Forms.ToolStripStatusLabel _statusLabel;
|
||||
private System.Windows.Forms.ToolStripStatusLabel _coordLabel;
|
||||
private System.Windows.Forms.Panel _controlPanel;
|
||||
private System.Windows.Forms.GroupBox _agvControlGroup;
|
||||
private System.Windows.Forms.ComboBox _agvListCombo;
|
||||
private System.Windows.Forms.Button _addAgvButton;
|
||||
private System.Windows.Forms.Button _removeAgvButton;
|
||||
private System.Windows.Forms.Button _startSimulationButton;
|
||||
private System.Windows.Forms.Button _stopSimulationButton;
|
||||
private System.Windows.Forms.GroupBox _pathGroup;
|
||||
private System.Windows.Forms.Label startNodeLabel;
|
||||
private System.Windows.Forms.ComboBox _startNodeCombo;
|
||||
private System.Windows.Forms.Label targetNodeLabel;
|
||||
private System.Windows.Forms.ComboBox _targetNodeCombo;
|
||||
private System.Windows.Forms.Button _calculatePathButton;
|
||||
private System.Windows.Forms.Button _startPathButton;
|
||||
private System.Windows.Forms.Button _clearPathButton;
|
||||
private System.Windows.Forms.GroupBox _statusGroup;
|
||||
private System.Windows.Forms.Label _simulationStatusLabel;
|
||||
private System.Windows.Forms.Label _agvCountLabel;
|
||||
private System.Windows.Forms.Label _pathLengthLabel;
|
||||
private System.Windows.Forms.Panel _canvasPanel;
|
||||
private System.Windows.Forms.Label _rfidLabel;
|
||||
private System.Windows.Forms.TextBox _rfidTextBox;
|
||||
private System.Windows.Forms.Button _setPositionButton;
|
||||
private System.Windows.Forms.ToolStripButton btAllReset;
|
||||
private System.Windows.Forms.ToolStripMenuItem reloadMapToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem launchMapEditorToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator4;
|
||||
private System.Windows.Forms.ToolStripButton reloadMapToolStripButton;
|
||||
private System.Windows.Forms.ToolStripButton launchMapEditorToolStripButton;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using AGVMapEditor.Models;
|
||||
using AGVSimulator.Controls;
|
||||
using AGVNavigationCore.Models;
|
||||
using AGVNavigationCore.Controls;
|
||||
using AGVSimulator.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
@@ -18,50 +20,17 @@ namespace AGVSimulator.Forms
|
||||
{
|
||||
#region Fields
|
||||
|
||||
private SimulatorCanvas _simulatorCanvas;
|
||||
private UnifiedAGVCanvas _simulatorCanvas;
|
||||
private List<MapNode> _mapNodes;
|
||||
private List<RfidMapping> _rfidMappings;
|
||||
private NodeResolver _nodeResolver;
|
||||
private PathCalculator _pathCalculator;
|
||||
private List<VirtualAGV> _agvList;
|
||||
private SimulationState _simulationState;
|
||||
private Timer _simulationTimer;
|
||||
private SimulatorConfig _config;
|
||||
private string _currentMapFilePath;
|
||||
|
||||
// UI Controls
|
||||
private MenuStrip _menuStrip;
|
||||
private ToolStrip _toolStrip;
|
||||
private StatusStrip _statusStrip;
|
||||
private Panel _controlPanel;
|
||||
private Panel _canvasPanel;
|
||||
|
||||
// Control Panel Controls
|
||||
private GroupBox _agvControlGroup;
|
||||
private ComboBox _agvListCombo;
|
||||
private Button _addAgvButton;
|
||||
private Button _removeAgvButton;
|
||||
private Button _startSimulationButton;
|
||||
private Button _stopSimulationButton;
|
||||
private Button _resetButton;
|
||||
|
||||
private GroupBox _pathGroup;
|
||||
private ComboBox _startNodeCombo;
|
||||
private ComboBox _targetNodeCombo;
|
||||
private Button _calculatePathButton;
|
||||
private Button _startPathButton;
|
||||
private Button _clearPathButton;
|
||||
|
||||
private GroupBox _viewGroup;
|
||||
private Button _fitToMapButton;
|
||||
private Button _resetZoomButton;
|
||||
|
||||
private GroupBox _statusGroup;
|
||||
private Label _simulationStatusLabel;
|
||||
private Label _agvCountLabel;
|
||||
private Label _pathLengthLabel;
|
||||
|
||||
// Status Labels
|
||||
private ToolStripStatusLabel _statusLabel;
|
||||
private ToolStripStatusLabel _coordLabel;
|
||||
// UI Controls - Designer에서 생성됨
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -88,27 +57,18 @@ namespace AGVSimulator.Forms
|
||||
|
||||
private void InitializeForm()
|
||||
{
|
||||
// 폼 설정
|
||||
Text = "AGV 시뮬레이터";
|
||||
Size = new Size(1200, 800);
|
||||
StartPosition = FormStartPosition.CenterScreen;
|
||||
// 설정 로드
|
||||
_config = SimulatorConfig.Load();
|
||||
|
||||
// 데이터 초기화
|
||||
_mapNodes = new List<MapNode>();
|
||||
_rfidMappings = new List<RfidMapping>();
|
||||
_agvList = new List<VirtualAGV>();
|
||||
_simulationState = new SimulationState();
|
||||
_currentMapFilePath = string.Empty;
|
||||
|
||||
// UI 컨트롤 생성
|
||||
CreateMenuStrip();
|
||||
CreateToolStrip();
|
||||
CreateStatusStrip();
|
||||
CreateControlPanel();
|
||||
// 시뮬레이터 캔버스 생성 (중앙 패널에만)
|
||||
CreateSimulatorCanvas();
|
||||
|
||||
// 레이아웃 설정
|
||||
SetupLayout();
|
||||
|
||||
// 타이머 초기화
|
||||
_simulationTimer = new Timer();
|
||||
_simulationTimer.Interval = 100; // 100ms 간격
|
||||
@@ -118,260 +78,21 @@ namespace AGVSimulator.Forms
|
||||
UpdateUI();
|
||||
}
|
||||
|
||||
private void CreateMenuStrip()
|
||||
{
|
||||
_menuStrip = new MenuStrip();
|
||||
|
||||
// 파일 메뉴
|
||||
var fileMenu = new ToolStripMenuItem("파일(&F)");
|
||||
fileMenu.DropDownItems.Add(new ToolStripMenuItem("맵 열기(&O)...", null, OnOpenMap_Click) { ShortcutKeys = Keys.Control | Keys.O });
|
||||
fileMenu.DropDownItems.Add(new ToolStripSeparator());
|
||||
fileMenu.DropDownItems.Add(new ToolStripMenuItem("종료(&X)", null, OnExit_Click) { ShortcutKeys = Keys.Alt | Keys.F4 });
|
||||
|
||||
// 시뮬레이션 메뉴
|
||||
var simMenu = new ToolStripMenuItem("시뮬레이션(&S)");
|
||||
simMenu.DropDownItems.Add(new ToolStripMenuItem("시작(&S)", null, OnStartSimulation_Click) { ShortcutKeys = Keys.F5 });
|
||||
simMenu.DropDownItems.Add(new ToolStripMenuItem("정지(&T)", null, OnStopSimulation_Click) { ShortcutKeys = Keys.F6 });
|
||||
simMenu.DropDownItems.Add(new ToolStripMenuItem("초기화(&R)", null, OnReset_Click) { ShortcutKeys = Keys.F7 });
|
||||
|
||||
// 보기 메뉴
|
||||
var viewMenu = new ToolStripMenuItem("보기(&V)");
|
||||
viewMenu.DropDownItems.Add(new ToolStripMenuItem("맵 맞춤(&F)", null, OnFitToMap_Click) { ShortcutKeys = Keys.Control | Keys.F });
|
||||
viewMenu.DropDownItems.Add(new ToolStripMenuItem("줌 초기화(&Z)", null, OnResetZoom_Click) { ShortcutKeys = Keys.Control | Keys.D0 });
|
||||
|
||||
// 도움말 메뉴
|
||||
var helpMenu = new ToolStripMenuItem("도움말(&H)");
|
||||
helpMenu.DropDownItems.Add(new ToolStripMenuItem("정보(&A)...", null, OnAbout_Click));
|
||||
|
||||
_menuStrip.Items.AddRange(new ToolStripItem[] { fileMenu, simMenu, viewMenu, helpMenu });
|
||||
Controls.Add(_menuStrip);
|
||||
MainMenuStrip = _menuStrip;
|
||||
}
|
||||
|
||||
private void CreateToolStrip()
|
||||
{
|
||||
_toolStrip = new ToolStrip();
|
||||
|
||||
_toolStrip.Items.Add(new ToolStripButton("맵 열기", null, OnOpenMap_Click) { ToolTipText = "맵 파일을 엽니다" });
|
||||
_toolStrip.Items.Add(new ToolStripSeparator());
|
||||
_toolStrip.Items.Add(new ToolStripButton("시뮬레이션 시작", null, OnStartSimulation_Click) { ToolTipText = "시뮬레이션을 시작합니다" });
|
||||
_toolStrip.Items.Add(new ToolStripButton("시뮬레이션 정지", null, OnStopSimulation_Click) { ToolTipText = "시뮬레이션을 정지합니다" });
|
||||
_toolStrip.Items.Add(new ToolStripButton("초기화", null, OnReset_Click) { ToolTipText = "시뮬레이션을 초기화합니다" });
|
||||
_toolStrip.Items.Add(new ToolStripSeparator());
|
||||
_toolStrip.Items.Add(new ToolStripButton("맵 맞춤", null, OnFitToMap_Click) { ToolTipText = "맵 전체를 화면에 맞춥니다" });
|
||||
_toolStrip.Items.Add(new ToolStripButton("줌 초기화", null, OnResetZoom_Click) { ToolTipText = "줌을 초기화합니다" });
|
||||
|
||||
Controls.Add(_toolStrip);
|
||||
}
|
||||
|
||||
private void CreateStatusStrip()
|
||||
{
|
||||
_statusStrip = new StatusStrip();
|
||||
|
||||
_statusLabel = new ToolStripStatusLabel("준비");
|
||||
_coordLabel = new ToolStripStatusLabel();
|
||||
|
||||
_statusStrip.Items.AddRange(new ToolStripItem[] { _statusLabel, _coordLabel });
|
||||
Controls.Add(_statusStrip);
|
||||
}
|
||||
|
||||
private void CreateControlPanel()
|
||||
{
|
||||
_controlPanel = new Panel();
|
||||
_controlPanel.Width = 250;
|
||||
_controlPanel.Dock = DockStyle.Right;
|
||||
_controlPanel.BackColor = SystemColors.Control;
|
||||
|
||||
// AGV 제어 그룹
|
||||
CreateAGVControlGroup();
|
||||
|
||||
// 경로 제어 그룹
|
||||
CreatePathControlGroup();
|
||||
|
||||
// 뷰 제어 그룹
|
||||
CreateViewControlGroup();
|
||||
|
||||
// 상태 그룹
|
||||
CreateStatusGroup();
|
||||
|
||||
Controls.Add(_controlPanel);
|
||||
}
|
||||
|
||||
private void CreateAGVControlGroup()
|
||||
{
|
||||
_agvControlGroup = new GroupBox();
|
||||
_agvControlGroup.Text = "AGV 제어";
|
||||
_agvControlGroup.Location = new Point(10, 10);
|
||||
_agvControlGroup.Size = new Size(230, 120);
|
||||
|
||||
_agvListCombo = new ComboBox();
|
||||
_agvListCombo.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||
_agvListCombo.Location = new Point(10, 25);
|
||||
_agvListCombo.Size = new Size(210, 21);
|
||||
_agvListCombo.SelectedIndexChanged += OnAGVList_SelectedIndexChanged;
|
||||
|
||||
_addAgvButton = new Button();
|
||||
_addAgvButton.Text = "AGV 추가";
|
||||
_addAgvButton.Location = new Point(10, 55);
|
||||
_addAgvButton.Size = new Size(100, 25);
|
||||
_addAgvButton.Click += OnAddAGV_Click;
|
||||
|
||||
_removeAgvButton = new Button();
|
||||
_removeAgvButton.Text = "AGV 제거";
|
||||
_removeAgvButton.Location = new Point(120, 55);
|
||||
_removeAgvButton.Size = new Size(100, 25);
|
||||
_removeAgvButton.Click += OnRemoveAGV_Click;
|
||||
|
||||
_startSimulationButton = new Button();
|
||||
_startSimulationButton.Text = "시뮬레이션 시작";
|
||||
_startSimulationButton.Location = new Point(10, 85);
|
||||
_startSimulationButton.Size = new Size(100, 25);
|
||||
_startSimulationButton.Click += OnStartSimulation_Click;
|
||||
|
||||
_stopSimulationButton = new Button();
|
||||
_stopSimulationButton.Text = "시뮬레이션 정지";
|
||||
_stopSimulationButton.Location = new Point(120, 85);
|
||||
_stopSimulationButton.Size = new Size(100, 25);
|
||||
_stopSimulationButton.Click += OnStopSimulation_Click;
|
||||
|
||||
_agvControlGroup.Controls.AddRange(new Control[] {
|
||||
_agvListCombo, _addAgvButton, _removeAgvButton, _startSimulationButton, _stopSimulationButton
|
||||
});
|
||||
|
||||
_controlPanel.Controls.Add(_agvControlGroup);
|
||||
}
|
||||
|
||||
private void CreatePathControlGroup()
|
||||
{
|
||||
_pathGroup = new GroupBox();
|
||||
_pathGroup.Text = "경로 제어";
|
||||
_pathGroup.Location = new Point(10, 140);
|
||||
_pathGroup.Size = new Size(230, 150);
|
||||
|
||||
var startLabel = new Label();
|
||||
startLabel.Text = "시작 노드:";
|
||||
startLabel.Location = new Point(10, 25);
|
||||
startLabel.Size = new Size(70, 15);
|
||||
|
||||
_startNodeCombo = new ComboBox();
|
||||
_startNodeCombo.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||
_startNodeCombo.Location = new Point(10, 45);
|
||||
_startNodeCombo.Size = new Size(210, 21);
|
||||
|
||||
var targetLabel = new Label();
|
||||
targetLabel.Text = "목표 노드:";
|
||||
targetLabel.Location = new Point(10, 75);
|
||||
targetLabel.Size = new Size(70, 15);
|
||||
|
||||
_targetNodeCombo = new ComboBox();
|
||||
_targetNodeCombo.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||
_targetNodeCombo.Location = new Point(10, 95);
|
||||
_targetNodeCombo.Size = new Size(210, 21);
|
||||
|
||||
_calculatePathButton = new Button();
|
||||
_calculatePathButton.Text = "경로 계산";
|
||||
_calculatePathButton.Location = new Point(10, 120);
|
||||
_calculatePathButton.Size = new Size(65, 25);
|
||||
_calculatePathButton.Click += OnCalculatePath_Click;
|
||||
|
||||
_startPathButton = new Button();
|
||||
_startPathButton.Text = "경로 시작";
|
||||
_startPathButton.Location = new Point(80, 120);
|
||||
_startPathButton.Size = new Size(65, 25);
|
||||
_startPathButton.Click += OnStartPath_Click;
|
||||
|
||||
_clearPathButton = new Button();
|
||||
_clearPathButton.Text = "경로 지우기";
|
||||
_clearPathButton.Location = new Point(150, 120);
|
||||
_clearPathButton.Size = new Size(70, 25);
|
||||
_clearPathButton.Click += OnClearPath_Click;
|
||||
|
||||
_pathGroup.Controls.AddRange(new Control[] {
|
||||
startLabel, _startNodeCombo, targetLabel, _targetNodeCombo,
|
||||
_calculatePathButton, _startPathButton, _clearPathButton
|
||||
});
|
||||
|
||||
_controlPanel.Controls.Add(_pathGroup);
|
||||
}
|
||||
|
||||
private void CreateViewControlGroup()
|
||||
{
|
||||
_viewGroup = new GroupBox();
|
||||
_viewGroup.Text = "화면 제어";
|
||||
_viewGroup.Location = new Point(10, 300);
|
||||
_viewGroup.Size = new Size(230, 60);
|
||||
|
||||
_fitToMapButton = new Button();
|
||||
_fitToMapButton.Text = "맵 맞춤";
|
||||
_fitToMapButton.Location = new Point(10, 25);
|
||||
_fitToMapButton.Size = new Size(100, 25);
|
||||
_fitToMapButton.Click += OnFitToMap_Click;
|
||||
|
||||
_resetZoomButton = new Button();
|
||||
_resetZoomButton.Text = "줌 초기화";
|
||||
_resetZoomButton.Location = new Point(120, 25);
|
||||
_resetZoomButton.Size = new Size(100, 25);
|
||||
_resetZoomButton.Click += OnResetZoom_Click;
|
||||
|
||||
_resetButton = new Button();
|
||||
_resetButton.Text = "전체 초기화";
|
||||
_resetButton.Location = new Point(65, 55);
|
||||
_resetButton.Size = new Size(100, 25);
|
||||
_resetButton.Click += OnReset_Click;
|
||||
|
||||
_viewGroup.Controls.AddRange(new Control[] { _fitToMapButton, _resetZoomButton });
|
||||
|
||||
_controlPanel.Controls.Add(_viewGroup);
|
||||
}
|
||||
|
||||
private void CreateStatusGroup()
|
||||
{
|
||||
_statusGroup = new GroupBox();
|
||||
_statusGroup.Text = "상태 정보";
|
||||
_statusGroup.Location = new Point(10, 370);
|
||||
_statusGroup.Size = new Size(230, 100);
|
||||
|
||||
_simulationStatusLabel = new Label();
|
||||
_simulationStatusLabel.Text = "시뮬레이션: 정지";
|
||||
_simulationStatusLabel.Location = new Point(10, 25);
|
||||
_simulationStatusLabel.Size = new Size(210, 15);
|
||||
|
||||
_agvCountLabel = new Label();
|
||||
_agvCountLabel.Text = "AGV 수: 0";
|
||||
_agvCountLabel.Location = new Point(10, 45);
|
||||
_agvCountLabel.Size = new Size(210, 15);
|
||||
|
||||
_pathLengthLabel = new Label();
|
||||
_pathLengthLabel.Text = "경로 길이: -";
|
||||
_pathLengthLabel.Location = new Point(10, 65);
|
||||
_pathLengthLabel.Size = new Size(210, 15);
|
||||
|
||||
_statusGroup.Controls.AddRange(new Control[] {
|
||||
_simulationStatusLabel, _agvCountLabel, _pathLengthLabel
|
||||
});
|
||||
|
||||
_controlPanel.Controls.Add(_statusGroup);
|
||||
}
|
||||
|
||||
private void CreateSimulatorCanvas()
|
||||
{
|
||||
_canvasPanel = new Panel();
|
||||
_canvasPanel.Dock = DockStyle.Fill;
|
||||
|
||||
_simulatorCanvas = new SimulatorCanvas();
|
||||
_simulatorCanvas = new UnifiedAGVCanvas();
|
||||
_simulatorCanvas.Dock = DockStyle.Fill;
|
||||
_simulatorCanvas.Mode = UnifiedAGVCanvas.CanvasMode.ViewOnly;
|
||||
|
||||
_canvasPanel.Controls.Add(_simulatorCanvas);
|
||||
Controls.Add(_canvasPanel);
|
||||
}
|
||||
|
||||
private void SetupLayout()
|
||||
{
|
||||
// Z-Order 설정
|
||||
// Z-Order 설정 - 모든 컨트롤이 디자이너에 구현되어 자동 관리됨
|
||||
_canvasPanel.BringToFront();
|
||||
_controlPanel.BringToFront();
|
||||
_toolStrip.BringToFront();
|
||||
_menuStrip.BringToFront();
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -382,7 +103,7 @@ namespace AGVSimulator.Forms
|
||||
{
|
||||
using (var openDialog = new OpenFileDialog())
|
||||
{
|
||||
openDialog.Filter = "맵 파일 (*.json)|*.json|모든 파일 (*.*)|*.*";
|
||||
openDialog.Filter = "AGV Map Files (*.agvmap)|*.agvmap|모든 파일 (*.*)|*.*";
|
||||
openDialog.Title = "맵 파일 열기";
|
||||
|
||||
if (openDialog.ShowDialog() == DialogResult.OK)
|
||||
@@ -430,30 +151,12 @@ namespace AGVSimulator.Forms
|
||||
|
||||
private void OnReset_Click(object sender, EventArgs e)
|
||||
{
|
||||
// 시뮬레이션 정지
|
||||
if (_simulationState.IsRunning)
|
||||
{
|
||||
OnStopSimulation_Click(sender, e);
|
||||
}
|
||||
|
||||
// AGV 초기화
|
||||
_simulatorCanvas.ClearAGVs();
|
||||
_agvList.Clear();
|
||||
|
||||
// 경로 초기화
|
||||
_simulatorCanvas.CurrentPath = null;
|
||||
|
||||
// UI 업데이트
|
||||
UpdateAGVComboBox();
|
||||
UpdateNodeComboBoxes();
|
||||
UpdateUI();
|
||||
|
||||
_statusLabel.Text = "초기화 완료";
|
||||
}
|
||||
|
||||
private void OnFitToMap_Click(object sender, EventArgs e)
|
||||
{
|
||||
_simulatorCanvas.FitToMap();
|
||||
_simulatorCanvas.FitToNodes();
|
||||
}
|
||||
|
||||
private void OnResetZoom_Click(object sender, EventArgs e)
|
||||
@@ -480,7 +183,7 @@ namespace AGVSimulator.Forms
|
||||
|
||||
var newAGV = new VirtualAGV(agvId, startPosition);
|
||||
_agvList.Add(newAGV);
|
||||
_simulatorCanvas.AddAGV(newAGV);
|
||||
_simulatorCanvas.AGVList = new List<IAGV>(_agvList.Cast<IAGV>());
|
||||
|
||||
UpdateAGVComboBox();
|
||||
UpdateUI();
|
||||
@@ -496,8 +199,8 @@ namespace AGVSimulator.Forms
|
||||
var selectedAGV = _agvListCombo.SelectedItem as VirtualAGV;
|
||||
if (selectedAGV != null)
|
||||
{
|
||||
_simulatorCanvas.RemoveAGV(selectedAGV.AgvId);
|
||||
_agvList.Remove(selectedAGV);
|
||||
_simulatorCanvas.AGVList = new List<IAGV>(_agvList.Cast<IAGV>());
|
||||
|
||||
UpdateAGVComboBox();
|
||||
UpdateUI();
|
||||
@@ -515,7 +218,7 @@ namespace AGVSimulator.Forms
|
||||
{
|
||||
if (_startNodeCombo.SelectedItem == null || _targetNodeCombo.SelectedItem == null)
|
||||
{
|
||||
MessageBox.Show("시작 노드와 목표 노드를 선택해주세요.", "알림", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
MessageBox.Show("시작 RFID와 목표 RFID를 선택해주세요.", "알림", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -524,20 +227,21 @@ namespace AGVSimulator.Forms
|
||||
|
||||
if (_pathCalculator == null)
|
||||
{
|
||||
_pathCalculator = new PathCalculator(_mapNodes, _nodeResolver);
|
||||
_pathCalculator = new PathCalculator();
|
||||
_pathCalculator.SetMapData(_mapNodes);
|
||||
}
|
||||
|
||||
var result = _pathCalculator.CalculatePath(startNode.NodeId, targetNode.NodeId, AgvDirection.Forward);
|
||||
var agvResult = _pathCalculator.FindAGVPath(startNode.NodeId, targetNode.NodeId);
|
||||
|
||||
if (result.Success)
|
||||
if (agvResult.Success)
|
||||
{
|
||||
_simulatorCanvas.CurrentPath = result;
|
||||
_pathLengthLabel.Text = $"경로 길이: {result.TotalDistance:F1}";
|
||||
_statusLabel.Text = $"경로 계산 완료 ({result.CalculationTime}ms)";
|
||||
_simulatorCanvas.CurrentPath = agvResult.ToPathResult();
|
||||
_pathLengthLabel.Text = $"경로 길이: {agvResult.TotalDistance:F1}";
|
||||
_statusLabel.Text = $"경로 계산 완료 ({agvResult.CalculationTimeMs}ms)";
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show($"경로를 찾을 수 없습니다:\n{result.ErrorMessage}", "경로 계산 실패",
|
||||
MessageBox.Show($"경로를 찾을 수 없습니다:\n{agvResult.ErrorMessage}", "경로 계산 실패",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
}
|
||||
}
|
||||
@@ -568,6 +272,20 @@ namespace AGVSimulator.Forms
|
||||
_statusLabel.Text = "경로 지움";
|
||||
}
|
||||
|
||||
private void OnSetPosition_Click(object sender, EventArgs e)
|
||||
{
|
||||
SetAGVPositionByRfid();
|
||||
}
|
||||
|
||||
private void OnRfidTextBox_KeyPress(object sender, KeyPressEventArgs e)
|
||||
{
|
||||
if (e.KeyChar == (char)Keys.Enter)
|
||||
{
|
||||
SetAGVPositionByRfid();
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSimulationTimer_Tick(object sender, EventArgs e)
|
||||
{
|
||||
// 시뮬레이션 업데이트는 각 AGV의 내부 타이머에서 처리됨
|
||||
@@ -578,51 +296,103 @@ namespace AGVSimulator.Forms
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private void SetAGVPositionByRfid()
|
||||
{
|
||||
// 선택된 AGV 확인
|
||||
var selectedAGV = _agvListCombo.SelectedItem as VirtualAGV;
|
||||
if (selectedAGV == null)
|
||||
{
|
||||
MessageBox.Show("먼저 AGV를 선택해주세요.", "알림", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
return;
|
||||
}
|
||||
|
||||
// RFID 값 확인
|
||||
var rfidId = _rfidTextBox.Text.Trim();
|
||||
if (string.IsNullOrEmpty(rfidId))
|
||||
{
|
||||
MessageBox.Show("RFID 값을 입력해주세요.", "알림", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
return;
|
||||
}
|
||||
|
||||
// RFID에 해당하는 노드 직접 찾기
|
||||
var targetNode = _mapNodes?.FirstOrDefault(n => n.RfidId.Equals(rfidId, StringComparison.OrdinalIgnoreCase));
|
||||
if (targetNode == null)
|
||||
{
|
||||
MessageBox.Show($"RFID '{rfidId}'에 해당하는 노드를 찾을 수 없습니다.\n\n사용 가능한 RFID 목록:\n{GetAvailableRfidList()}",
|
||||
"RFID 찾기 실패", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
// AGV 위치 설정
|
||||
_simulatorCanvas.SetAGVPosition(selectedAGV.AgvId, targetNode.Position);
|
||||
|
||||
_statusLabel.Text = $"{selectedAGV.AgvId} 위치를 RFID '{rfidId}' (노드: {targetNode.NodeId})로 설정했습니다.";
|
||||
_rfidTextBox.Text = ""; // 입력 필드 초기화
|
||||
|
||||
// 시뮬레이터 캔버스의 해당 노드로 이동
|
||||
_simulatorCanvas.PanToNode(targetNode.NodeId);
|
||||
}
|
||||
|
||||
private string GetAvailableRfidList()
|
||||
{
|
||||
if (_mapNodes == null || _mapNodes.Count == 0)
|
||||
return "매핑된 RFID가 없습니다.";
|
||||
|
||||
var nodesWithRfid = _mapNodes.Where(n => n.HasRfid()).ToList();
|
||||
if (nodesWithRfid.Count == 0)
|
||||
return "RFID가 할당된 노드가 없습니다.";
|
||||
|
||||
// 처음 10개의 RFID만 표시
|
||||
var rfidList = nodesWithRfid.Take(10).Select(n => $"- {n.RfidId} → {n.NodeId}");
|
||||
var result = string.Join("\n", rfidList);
|
||||
|
||||
if (nodesWithRfid.Count > 10)
|
||||
result += $"\n... 외 {nodesWithRfid.Count - 10}개";
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void LoadMapFile(string filePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var json = File.ReadAllText(filePath);
|
||||
var result = MapLoader.LoadMapFromFile(filePath);
|
||||
|
||||
// 구조체로 직접 역직렬화
|
||||
var mapData = JsonConvert.DeserializeObject<MapFileData>(json);
|
||||
|
||||
if (mapData != null)
|
||||
if (result.Success)
|
||||
{
|
||||
_mapNodes = mapData.MapNodes ?? new List<MapNode>();
|
||||
_rfidMappings = mapData.RfidMappings ?? new List<RfidMapping>();
|
||||
_mapNodes = result.Nodes;
|
||||
_currentMapFilePath = filePath;
|
||||
|
||||
// RFID가 없는 노드들에 자동 할당
|
||||
MapLoader.AssignAutoRfidIds(_mapNodes);
|
||||
|
||||
// 시뮬레이터 캔버스에 맵 설정
|
||||
_simulatorCanvas.Nodes = _mapNodes;
|
||||
|
||||
// 설정에 마지막 맵 파일 경로 저장
|
||||
_config.LastMapFilePath = filePath;
|
||||
if (_config.AutoSave)
|
||||
{
|
||||
_config.Save();
|
||||
}
|
||||
|
||||
// UI 업데이트
|
||||
UpdateNodeComboBoxes();
|
||||
UpdateUI();
|
||||
|
||||
// 맵에 맞춤
|
||||
_simulatorCanvas.FitToNodes();
|
||||
}
|
||||
else
|
||||
{
|
||||
_mapNodes = new List<MapNode>();
|
||||
_rfidMappings = new List<RfidMapping>();
|
||||
throw new InvalidOperationException($"맵 파일 로드 실패: {result.ErrorMessage}");
|
||||
}
|
||||
|
||||
// NodeResolver 초기화
|
||||
_nodeResolver = new NodeResolver(_rfidMappings, _mapNodes);
|
||||
|
||||
// 시뮬레이터 캔버스에 맵 설정
|
||||
_simulatorCanvas.MapNodes = _mapNodes;
|
||||
|
||||
// UI 업데이트
|
||||
UpdateNodeComboBoxes();
|
||||
UpdateUI();
|
||||
|
||||
// 맵에 맞춤
|
||||
_simulatorCanvas.FitToMap();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new InvalidOperationException($"맵 파일 로드 실패: {ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
// 맵 파일 데이터 구조체
|
||||
private class MapFileData
|
||||
{
|
||||
public List<MapNode> MapNodes { get; set; }
|
||||
public List<RfidMapping> RfidMappings { get; set; }
|
||||
}
|
||||
|
||||
private void UpdateNodeComboBoxes()
|
||||
{
|
||||
@@ -633,13 +403,16 @@ namespace AGVSimulator.Forms
|
||||
{
|
||||
foreach (var node in _mapNodes)
|
||||
{
|
||||
_startNodeCombo.Items.Add(node);
|
||||
_targetNodeCombo.Items.Add(node);
|
||||
if (node.IsActive && node.HasRfid())
|
||||
{
|
||||
_startNodeCombo.Items.Add(node);
|
||||
_targetNodeCombo.Items.Add(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_startNodeCombo.DisplayMember = "NodeId";
|
||||
_targetNodeCombo.DisplayMember = "NodeId";
|
||||
_startNodeCombo.DisplayMember = "RfidId";
|
||||
_targetNodeCombo.DisplayMember = "RfidId";
|
||||
}
|
||||
|
||||
private void UpdateAGVComboBox()
|
||||
@@ -681,8 +454,128 @@ namespace AGVSimulator.Forms
|
||||
|
||||
_calculatePathButton.Enabled = _startNodeCombo.SelectedItem != null &&
|
||||
_targetNodeCombo.SelectedItem != null;
|
||||
|
||||
// RFID 위치 설정 관련
|
||||
var hasSelectedAGV = _agvListCombo.SelectedItem != null;
|
||||
var hasRfidNodes = _mapNodes != null && _mapNodes.Any(n => n.HasRfid());
|
||||
|
||||
_setPositionButton.Enabled = hasSelectedAGV && hasRfidNodes;
|
||||
_rfidTextBox.Enabled = hasSelectedAGV && hasRfidNodes;
|
||||
|
||||
// 맵 다시열기 버튼
|
||||
var hasCurrentMap = !string.IsNullOrEmpty(_currentMapFilePath);
|
||||
reloadMapToolStripMenuItem.Enabled = hasCurrentMap;
|
||||
reloadMapToolStripButton.Enabled = hasCurrentMap;
|
||||
}
|
||||
|
||||
private void OnReloadMap_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_currentMapFilePath))
|
||||
{
|
||||
MessageBox.Show("다시 로드할 맵 파일이 없습니다. 먼저 맵을 열어주세요.", "알림",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!File.Exists(_currentMapFilePath))
|
||||
{
|
||||
MessageBox.Show($"맵 파일을 찾을 수 없습니다:\n{_currentMapFilePath}", "오류",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
LoadMapFile(_currentMapFilePath);
|
||||
_statusLabel.Text = $"맵 다시 로드 완료: {Path.GetFileName(_currentMapFilePath)}";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"맵 파일을 다시 로드할 수 없습니다:\n{ex.Message}", "오류",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnLaunchMapEditor_Click(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
// MapEditor 실행 파일 경로 확인
|
||||
string mapEditorPath = _config.MapEditorExecutablePath;
|
||||
|
||||
// 경로가 설정되지 않았거나 파일이 없는 경우 사용자에게 선택을 요청
|
||||
if (string.IsNullOrEmpty(mapEditorPath) || !File.Exists(mapEditorPath))
|
||||
{
|
||||
using (var openDialog = new OpenFileDialog())
|
||||
{
|
||||
openDialog.Filter = "실행 파일 (*.exe)|*.exe|모든 파일 (*.*)|*.*";
|
||||
openDialog.Title = "AGV MapEditor 실행 파일 선택";
|
||||
openDialog.InitialDirectory = Application.StartupPath;
|
||||
|
||||
if (openDialog.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
mapEditorPath = openDialog.FileName;
|
||||
|
||||
// 설정에 저장
|
||||
_config.MapEditorExecutablePath = mapEditorPath;
|
||||
if (_config.AutoSave)
|
||||
{
|
||||
_config.Save();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return; // 사용자가 취소함
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MapEditor 실행
|
||||
var startInfo = new System.Diagnostics.ProcessStartInfo
|
||||
{
|
||||
FileName = mapEditorPath,
|
||||
UseShellExecute = true
|
||||
};
|
||||
|
||||
// 현재 로드된 맵 파일이 있으면 파라미터로 전달
|
||||
if (!string.IsNullOrEmpty(_currentMapFilePath) && File.Exists(_currentMapFilePath))
|
||||
{
|
||||
startInfo.Arguments = $"\"{_currentMapFilePath}\"";
|
||||
}
|
||||
|
||||
System.Diagnostics.Process.Start(startInfo);
|
||||
_statusLabel.Text = "MapEditor 실행됨";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"MapEditor를 실행할 수 없습니다:\n{ex.Message}", "오류",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void btAllReset_Click(object sender, EventArgs e)
|
||||
{
|
||||
// 시뮬레이션 정지
|
||||
if (_simulationState.IsRunning)
|
||||
{
|
||||
OnStopSimulation_Click(sender, e);
|
||||
}
|
||||
|
||||
// AGV 초기화
|
||||
_agvList.Clear();
|
||||
_simulatorCanvas.AGVList = new List<IAGV>();
|
||||
|
||||
// 경로 초기화
|
||||
_simulatorCanvas.CurrentPath = null;
|
||||
|
||||
// UI 업데이트
|
||||
UpdateAGVComboBox();
|
||||
UpdateNodeComboBoxes();
|
||||
UpdateUI();
|
||||
|
||||
_statusLabel.Text = "초기화 완료";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,64 @@
|
||||
<?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">
|
||||
@@ -28,9 +87,9 @@
|
||||
<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" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<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>
|
||||
@@ -39,7 +98,7 @@
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
@@ -58,4 +117,13 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="_menuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="_toolStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>132, 17</value>
|
||||
</metadata>
|
||||
<metadata name="_statusStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>237, 17</value>
|
||||
</metadata>
|
||||
</root>
|
||||
114
Cs_HMI/AGVSimulator/Models/SimulatorConfig.cs
Normal file
114
Cs_HMI/AGVSimulator/Models/SimulatorConfig.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace AGVSimulator.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 시뮬레이터 환경 설정 클래스
|
||||
/// </summary>
|
||||
public class SimulatorConfig
|
||||
{
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// MapEditor 실행 파일 경로
|
||||
/// </summary>
|
||||
public string MapEditorExecutablePath { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 마지막으로 로드한 맵 파일 경로
|
||||
/// </summary>
|
||||
public string LastMapFilePath { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 설정 파일 자동 저장 여부
|
||||
/// </summary>
|
||||
public bool AutoSave { get; set; } = true;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Static Methods
|
||||
|
||||
/// <summary>
|
||||
/// 설정 파일 기본 경로
|
||||
/// </summary>
|
||||
private static string ConfigFilePath => Path.Combine(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
|
||||
"AGVSimulator",
|
||||
"config.json");
|
||||
|
||||
/// <summary>
|
||||
/// 설정을 파일에서 로드
|
||||
/// </summary>
|
||||
/// <returns>로드된 설정 객체</returns>
|
||||
public static SimulatorConfig Load()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (File.Exists(ConfigFilePath))
|
||||
{
|
||||
var json = File.ReadAllText(ConfigFilePath);
|
||||
return JsonConvert.DeserializeObject<SimulatorConfig>(json) ?? new SimulatorConfig();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"설정 로드 실패: {ex.Message}");
|
||||
}
|
||||
|
||||
return new SimulatorConfig();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 설정을 파일에 저장
|
||||
/// </summary>
|
||||
/// <param name="config">저장할 설정 객체</param>
|
||||
/// <returns>저장 성공 여부</returns>
|
||||
public static bool Save(SimulatorConfig config)
|
||||
{
|
||||
try
|
||||
{
|
||||
var directory = Path.GetDirectoryName(ConfigFilePath);
|
||||
if (!Directory.Exists(directory))
|
||||
{
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
|
||||
var json = JsonConvert.SerializeObject(config, Formatting.Indented);
|
||||
File.WriteAllText(ConfigFilePath, json);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"설정 저장 실패: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Instance Methods
|
||||
|
||||
/// <summary>
|
||||
/// 현재 설정을 저장
|
||||
/// </summary>
|
||||
/// <returns>저장 성공 여부</returns>
|
||||
public bool Save()
|
||||
{
|
||||
return Save(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// MapEditor 실행 파일 경로 유효성 확인
|
||||
/// </summary>
|
||||
/// <returns>유효한 경로인지 여부</returns>
|
||||
public bool IsMapEditorPathValid()
|
||||
{
|
||||
return !string.IsNullOrEmpty(MapEditorExecutablePath) &&
|
||||
File.Exists(MapEditorExecutablePath);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -3,27 +3,18 @@ using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using AGVMapEditor.Models;
|
||||
using AGVNavigationCore.Models;
|
||||
using AGVNavigationCore.PathFinding;
|
||||
using AGVNavigationCore.Controls;
|
||||
|
||||
namespace AGVSimulator.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 가상 AGV 상태
|
||||
/// </summary>
|
||||
public enum AGVState
|
||||
{
|
||||
Idle, // 대기
|
||||
Moving, // 이동 중
|
||||
Rotating, // 회전 중
|
||||
Docking, // 도킹 중
|
||||
Charging, // 충전 중
|
||||
Error // 오류
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 가상 AGV 클래스
|
||||
/// 실제 AGV의 동작을 시뮬레이션
|
||||
/// </summary>
|
||||
public class VirtualAGV
|
||||
public class VirtualAGV : IAGV
|
||||
{
|
||||
#region Events
|
||||
|
||||
@@ -181,7 +172,7 @@ namespace AGVSimulator.Models
|
||||
}
|
||||
|
||||
_currentPath = path;
|
||||
_remainingNodes = new List<string>(path.NodeSequence);
|
||||
_remainingNodes = new List<string>(path.Path);
|
||||
_currentNodeIndex = 0;
|
||||
|
||||
// 시작 노드 위치로 이동
|
||||
|
||||
29
Cs_HMI/AGVSimulator/build.bat
Normal file
29
Cs_HMI/AGVSimulator/build.bat
Normal file
@@ -0,0 +1,29 @@
|
||||
@echo off
|
||||
echo Building V2GDecoder VC++ Project...
|
||||
|
||||
REM Check if Visual Studio 2022 is installed (Professional or Community)
|
||||
set MSBUILD_PRO="C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Current\Bin\MSBuild.exe"
|
||||
set MSBUILD_COM="C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe"
|
||||
set MSBUILD_BT="F:\(VHD) Program Files\Microsoft Visual Studio\2022\MSBuild\Current\Bin\MSBuild.exe"
|
||||
|
||||
if exist %MSBUILD_PRO% (
|
||||
echo "Found Visual Studio 2022 Professional"
|
||||
set MSBUILD=%MSBUILD_PRO%
|
||||
) else if exist %MSBUILD_COM% (
|
||||
echo "Found Visual Studio 2022 Community"
|
||||
set MSBUILD=%MSBUILD_COM%
|
||||
) else if exist %MSBUILD_BT% (
|
||||
echo "Found Visual Studio 2022 BuildTools"
|
||||
set MSBUILD=%MSBUILD_BT%
|
||||
) else (
|
||||
echo "Visual Studio 2022 (Professional or Community) not found!"
|
||||
echo "Please install Visual Studio 2022 or update the MSBuild path."
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
REM Build Debug x64 configuration
|
||||
echo Building Debug x64 configuration...
|
||||
%MSBUILD% AGVSimulator.csproj
|
||||
|
||||
pause
|
||||
Reference in New Issue
Block a user