UI 및 설정 변경사항 커밋

- 맵 에디터 메인폼 UI 개선
- AGV 캔버스 컨트롤 수정
- 설정 파일 업데이트
- 상태머신 AGV 로직 조정
- 자동 모드 화면 개선
- 메인폼 디자이너 및 로직 수정

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
backuppc
2025-11-18 08:50:07 +09:00
parent 4a992ea9c1
commit 92dfe2978c
7 changed files with 309 additions and 27 deletions

View File

@@ -548,9 +548,11 @@ namespace AGVMapEditor.Forms
var openFileDialog = new OpenFileDialog
{
Filter = "AGV Map Files (*.agvmap)|*.agvmap|All Files (*.*)|*.*",
DefaultExt = "agvmap"
DefaultExt = "agvmap",
};
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
try

View File

@@ -158,6 +158,8 @@ namespace AGVNavigationCore.Controls
#region Properties
public string MapFileName { get; set; } = "";
/// <summary>
/// 캔버스 모드
/// </summary>

View File

@@ -174,45 +174,70 @@ namespace Project
#endregion
#region "TAGS"
[Browsable(false)]
public int TAGPOT { get; set; }
[Browsable(false)]
public int TAGNOT { get; set; }
[Browsable(false)]
public int TAG_F2_F3 { get; set; }
[Browsable(false)]
public int TAG_QC_F1 { get; set; }
[Browsable(false)]
public int TAG_F1_F2 { get; set; }
[Browsable(false)]
public int TAG_F3_F4 { get; set; }
[Browsable(false)]
public int TAG_F4_F5 { get; set; }
[Browsable(false)]
public int TAG_QA_QC { get; set; }
[Browsable(false)]
public int TAGQAB { get; set; }
[Browsable(false)]
public int TAGQAA { get; set; }
[Browsable(false)]
public int TAGQCB { get; set; }
[Browsable(false)]
public int TAGQCA { get; set; }
[Browsable(false)]
public int TAGF1A { get; set; }
[Browsable(false)]
public int TAGF2A { get; set; }
[Browsable(false)]
public int TAGF3A { get; set; }
[Browsable(false)]
public int TAGF4A { get; set; }
[Browsable(false)]
public int TAGF5A { get; set; }
[Browsable(false)]
public int TAGF1B { get; set; }
[Browsable(false)]
public int TAGF2B { get; set; }
[Browsable(false)]
public int TAGF3B { get; set; }
[Browsable(false)]
public int TAGF4B { get; set; }
[Browsable(false)]
public int TAGF5B { get; set; }
#endregion
#region "Charge"
[Browsable(false)]
public int chargerpos { get; set; }
[Browsable(false)]
public int ChargetWaitSec { get; set; }
[Browsable(false)]
public int ChargeEmergencyLevel { get; set; }
[Browsable(false)]
public int ChargeMaxLevel { get; set; }
[Browsable(false)]
public int ChargeStartLevel { get; set; }
[Browsable(false)]
public Boolean Enable_AutoCharge { get; set; }
[Browsable(false)]
public int ChargeRetryTerm { get; set; }
//public int ChargeIdleInterval { get; set; }
[Browsable(false)]
public int ChargeMaxTime { get; set; }
[Browsable(false)]
public int ChargeSearchTime { get; set; }
#endregion
@@ -228,8 +253,9 @@ namespace Project
/// FVI로 가능 방향이 Backward 인가?
/// Forward 방향이라면 false 를 한다
/// </summary>
[Browsable(false)]
public Boolean AGV_Direction_FVI_Backward { get; set; }
[Browsable(false)]
public Boolean Enable_Speak { get; set; }
//public Boolean Disable_BMS { get; set; }
@@ -245,48 +271,74 @@ namespace Project
[Browsable(false)]
public string AGV_ADDRESS { get; set; }
[Browsable(false)]
public int SCK { get; set; }
[Browsable(false)]
public int SSK { get; set; }
[Browsable(false)]
public int STT { get; set; }
[Browsable(false)]
public int SAD { get; set; }
[Browsable(false)]
public byte ZSpeed { get; set; }
[Browsable(false)]
public int SPD_L { get; set; }
[Browsable(false)]
public int SPD_M { get; set; }
[Browsable(false)]
public int SPD_H { get; set; }
[Browsable(false)]
public int SPD_DRIVE { get; set; }
[Browsable(false)]
public int SPD_S { get; set; }
[Browsable(false)]
public int SPD_R { get; set; }
[Browsable(false)]
public int PID_PH { get; set; }
[Browsable(false)]
public int PID_PM { get; set; }
[Browsable(false)]
public int PID_PL { get; set; }
[Browsable(false)]
public int PID_IH { get; set; }
[Browsable(false)]
public int PID_IM { get; set; }
[Browsable(false)]
public int PID_IL { get; set; }
[Browsable(false)]
public int PID_DH { get; set; }
[Browsable(false)]
public int PID_DM { get; set; }
[Browsable(false)]
public int PID_DL { get; set; }
[Browsable(false)]
public int PID_PS { get; set; }
[Browsable(false)]
public int PID_IS { get; set; }
[Browsable(false)]
public int PID_DS { get; set; }
public double WheelSpeedCharge { get; set; }
public byte HomePositionValue { get; set; }
public byte HomeKitNo { get; set; }
[Browsable(false)]
public Single interval_xbe { get; set; }
[Browsable(false)]
public int interval_bms { get; set; }
public int doorSoundTerm { get; set; }
[Browsable(false)]
public int musicvol { get; set; }
[Browsable(false)]
public bool Enable_Music { get; set; }
#endregion
[Browsable(false)]
public string LastMapFile { get; set; }
[Category("Report"), Browsable(false),
Description("상태기록시 장비 식별코드(4자리)"),
DisplayName("M/C ID")]

View File

@@ -8,6 +8,8 @@ using arCtl;
using Project.StateMachine;
using COMM;
using AR;
using AGVNavigationCore.Models;
namespace Project
{
@@ -215,11 +217,13 @@ namespace Project
// CurrentNode에 새로 생성한 노드 할당
CurrentNode = newNode;
}
//모터방향 확인해서 UI와 AGV클래스에 적용한다
var MotDireciton = PUB.AGV.data.Direction == 'B' ? AGVNavigationCore.Models.AgvDirection.Backward : AGVNavigationCore.Models.AgvDirection.Forward;
PUB._virtualAGV.SetPosition(CurrentNode, MotDireciton);
PUB._mapCanvas.SetAGVPosition(PUB.setting.MCID, CurrentNode, MotDireciton);
else
{
//모터방향 확인해서 UI와 AGV클래스에 적용한다
var MotDireciton = PUB.AGV.data.Direction == 'B' ? AGVNavigationCore.Models.AgvDirection.Backward : AGVNavigationCore.Models.AgvDirection.Forward;
PUB._virtualAGV.SetPosition(CurrentNode, MotDireciton);
PUB._mapCanvas.SetAGVPosition(PUB.setting.MCID, CurrentNode, MotDireciton);
}
//태그를 읽었다면 상태를 바로 전송한다
PUB.XBE.SendStatus();

View File

@@ -43,7 +43,7 @@ namespace Project.ViewForm
PUB._mapCanvas = new AGVNavigationCore.Controls.UnifiedAGVCanvas();
PUB._mapCanvas.Dock = DockStyle.Fill;
PUB._mapCanvas.ShowGrid = false;
PUB._mapCanvas.BackColor = Color.FromArgb(32,32,32);
PUB._mapCanvas.BackColor = Color.FromArgb(32, 32, 32);
PUB._mapCanvas.ForeColor = Color.White;
// RfidMappings 제거 - MapNode에 통합됨
@@ -78,13 +78,20 @@ namespace Project.ViewForm
//auto load
var path = new System.IO.DirectoryInfo("route");
if (path.Exists == false) path.Create();
var files = path.GetFiles("*.route");
var mapPath = new System.IO.DirectoryInfo("route");
if (mapPath.Exists == false) mapPath.Create();
//맵파일로딩
var filePath = new System.IO.FileInfo(@".\route\NewMap.agvmap");
if (PUB.setting.LastMapFile.isEmpty()) PUB.setting.LastMapFile = System.IO.Path.Combine(mapPath.FullName, "default.agvmap");
System.IO.FileInfo filePath = new System.IO.FileInfo(PUB.setting.LastMapFile);
if (filePath.Exists == false) filePath = new System.IO.FileInfo(System.IO.Path.Combine(mapPath.FullName,"default.agvmap"));
if(filePath.Exists==false) //그래도없다면 맵폴더에서 파일을 찾아본다.
{
var files = mapPath.GetFiles("*.agvmap");
if (files.Any()) filePath = files[0];
}
if (filePath.Exists)
{
var result = MapLoader.LoadMapFromFile(filePath.FullName);
@@ -97,7 +104,8 @@ namespace Project.ViewForm
// 맵 캔버스에 데이터 설정
PUB._mapCanvas.Nodes = PUB._mapNodes;
PUB._mapCanvas.MapFileName = filePath.FullName;
// 🔥 맵 설정 적용 (배경색, 그리드 표시)
if (result.Settings != null)
{
@@ -144,7 +152,7 @@ namespace Project.ViewForm
{
PUB.log.Add($"맵 파일을 찾을 수 없습니다: {filePath.FullName}");
}
//var fn = string.Empty;
//if (files.Any() == false)
//{

View File

@@ -128,6 +128,9 @@ namespace Project
this.lbBat = new AGVControl.BatteryLevelGauge();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.cmDebug = new System.Windows.Forms.ContextMenuStrip(this.components);
this.mapFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.saveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.loadToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.demoListLotToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripMenuItem();
this.refreshListToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@@ -140,6 +143,7 @@ namespace Project
this.arPanel2 = new arCtl.arPanel();
this.arPanel1 = new arCtl.arPanel();
this.ctlPos1 = new Project.CtlPos();
this.editorToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.panRight.SuspendLayout();
this.tableLayoutPanel1.SuspendLayout();
this.panel4.SuspendLayout();
@@ -1669,6 +1673,7 @@ namespace Project
// cmDebug
//
this.cmDebug.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mapFileToolStripMenuItem,
this.systemParameterToolStripMenuItem,
this.toolStripMenuItem4,
this.demoRunToolStripMenuItem,
@@ -1685,7 +1690,31 @@ namespace Project
this.toolStripMenuItem5,
this.refreshListToolStripMenuItem});
this.cmDebug.Name = "cmVision";
this.cmDebug.Size = new System.Drawing.Size(229, 302);
this.cmDebug.Size = new System.Drawing.Size(229, 346);
//
// mapFileToolStripMenuItem
//
this.mapFileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.saveToolStripMenuItem,
this.loadToolStripMenuItem,
this.editorToolStripMenuItem});
this.mapFileToolStripMenuItem.Name = "mapFileToolStripMenuItem";
this.mapFileToolStripMenuItem.Size = new System.Drawing.Size(228, 22);
this.mapFileToolStripMenuItem.Text = "Map File";
//
// saveToolStripMenuItem
//
this.saveToolStripMenuItem.Name = "saveToolStripMenuItem";
this.saveToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.saveToolStripMenuItem.Text = "Save";
this.saveToolStripMenuItem.Click += new System.EventHandler(this.saveToolStripMenuItem_Click);
//
// loadToolStripMenuItem
//
this.loadToolStripMenuItem.Name = "loadToolStripMenuItem";
this.loadToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.loadToolStripMenuItem.Text = "Load";
this.loadToolStripMenuItem.Click += new System.EventHandler(this.loadToolStripMenuItem_Click);
//
// demoListLotToolStripMenuItem
//
@@ -2159,6 +2188,13 @@ namespace Project
this.ctlPos1.Text = "ctlPos1";
this.ctlPos1.Visible = false;
//
// editorToolStripMenuItem
//
this.editorToolStripMenuItem.Name = "editorToolStripMenuItem";
this.editorToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.editorToolStripMenuItem.Text = "Editor";
this.editorToolStripMenuItem.Click += new System.EventHandler(this.editorToolStripMenuItem_Click);
//
// fMain
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
@@ -2278,6 +2314,10 @@ namespace Project
private arCtl.arLabel arLabel4;
private arCtl.arLabel lbCntQC;
private arCtl.arLabel arLabel9;
private ToolStripMenuItem mapFileToolStripMenuItem;
private ToolStripMenuItem saveToolStripMenuItem;
private ToolStripMenuItem loadToolStripMenuItem;
private ToolStripMenuItem editorToolStripMenuItem;
}
}

View File

@@ -12,6 +12,8 @@ using System.CodeDom;
using AR;
using Project.StateMachine;
using System.Security.Cryptography.X509Certificates;
using AGVNavigationCore.Models;
using System.IO;
namespace Project
{
@@ -243,7 +245,8 @@ namespace Project
tmDisplay.Tick += tmDisplay_Tick;
tmDisplay.Start(); //start Display
this.btDebug.Visible = PUB.setting.UseDebugMode;
this.btDebug.Visible = System.Diagnostics.Debugger.IsAttached || PUB.setting.UseDebugMode;
PUB.log.Add("Program Start");
@@ -262,7 +265,7 @@ namespace Project
}
#region "Mouse Form Move"
@@ -887,5 +890,176 @@ namespace Project
}
}
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
//mapsave
using (var sd = new SaveFileDialog())
{
sd.Filter = "AGV Map Files (*.agvmap)|*.agvmap|All Files (*.*)|*.*";
sd.DefaultExt = "agvmap";
sd.FileName = PUB._mapCanvas.MapFileName;
if (sd.ShowDialog() == DialogResult.OK)
{
SaveMapToFile(sd.FileName);
}
}
}
private void loadToolStripMenuItem_Click(object sender, EventArgs e)
{
//load
var od = new OpenFileDialog
{
Filter = "AGV Map Files (*.agvmap)|*.agvmap|All Files (*.*)|*.*",
DefaultExt = "agvmap",
FileName = PUB._mapCanvas.MapFileName,
};
if (od.ShowDialog() == DialogResult.OK)
{
try
{
LoadMapFromFile(od.FileName);
}
catch (Exception ex)
{
MessageBox.Show($"맵 로드 중 오류가 발생했습니다: {ex.Message}", "오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void LoadMapFromFile(string filePath)
{
var result = MapLoader.LoadMapFromFile(filePath);
if (result.Success)
{
var _mapCanvas = PUB._mapCanvas;
PUB._mapNodes = result.Nodes;
// 맵 캔버스에 데이터 설정
_mapCanvas.Nodes = result.Nodes;
// RfidMappings 제거됨 - MapNode에 통합
// 🔥 맵 설정 적용 (배경색, 그리드 표시)
if (result.Settings != null)
{
_mapCanvas.BackColor = System.Drawing.Color.FromArgb(result.Settings.BackgroundColorArgb);
_mapCanvas.ShowGrid = result.Settings.ShowGrid;
}
// 설정에 마지막 맵 파일 경로 저장
PUB.setting.LastMapFile = filePath;
PUB.setting.Save();
// 맵 로드 후 자동으로 맵에 맞춤
_mapCanvas.FitToNodes();
}
else
{
MessageBox.Show($"맵 파일 로딩 실패: {result.ErrorMessage}", "오류",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void SaveMapToFile(string filePath)
{
// 🔥 백업 파일 생성 (기존 파일이 있을 경우)
if (File.Exists(filePath))
{
try
{
// 날짜시간 포함 백업 파일명 생성
var directory = Path.GetDirectoryName(filePath);
var fileNameWithoutExt = Path.GetFileNameWithoutExtension(filePath);
var extension = Path.GetExtension(filePath);
var timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
var backupFileName = $"{fileNameWithoutExt}_{timestamp}{extension}.bak";
var backupFilePath = Path.Combine(directory, backupFileName);
// 기존 파일을 백업 파일로 복사
File.Copy(filePath, backupFilePath, true);
}
catch (Exception ex)
{
// 백업 파일 생성 실패 시 경고만 표시하고 계속 진행
MessageBox.Show($"백업 파일 생성 실패: {ex.Message}\n원본 파일은 계속 저장됩니다.", "백업 경고",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
var _mapCanvas = PUB._mapCanvas;
var _mapNodes = PUB._mapNodes;
// 🔥 현재 캔버스 설정을 맵 파일에 저장
var settings = new MapLoader.MapSettings
{
BackgroundColorArgb = _mapCanvas.BackColor.ToArgb(),
ShowGrid = _mapCanvas.ShowGrid
};
if (MapLoader.SaveMapToFile(filePath, _mapNodes, settings))
{
// 설정에 마지막 맵 파일 경로 저장
PUB.setting.LastMapFile = filePath;
PUB.setting.Save();
}
else
{
MessageBox.Show("맵 파일 저장 실패", "오류",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void editorToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
// MapEditor 실행 파일 경로 확인
string mapEditorPath = "AGVMapEditor.exe";
// 경로가 설정되지 않았거나 파일이 없는 경우 사용자에게 선택을 요청
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;
}
else
{
return; // 사용자가 취소함
}
}
}
// MapEditor 실행
var startInfo = new System.Diagnostics.ProcessStartInfo
{
FileName = mapEditorPath,
UseShellExecute = true
};
// 현재 로드된 맵 파일이 있으면 파라미터로 전달
var _currentMapFilePath = PUB._mapCanvas.MapFileName;
if (!string.IsNullOrEmpty(_currentMapFilePath) && File.Exists(_currentMapFilePath))
{
startInfo.Arguments = $"\"{_currentMapFilePath}\"";
}
System.Diagnostics.Process.Start(startInfo);
}
catch (Exception ex)
{
MessageBox.Show($"MapEditor를 실행할 수 없습니다:\n{ex.Message}", "오류",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}