From 06deda29561a60b259bb9a3f85099353ea7be3eb Mon Sep 17 00:00:00 2001 From: ChiKyun Kim Date: Mon, 15 Sep 2025 17:33:16 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=8B=9C=EB=AE=AC=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=EC=97=90=20=EB=AA=A9=EC=A0=81=EC=A7=80=20=EC=84=A0?= =?UTF-8?q?=ED=83=9D=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 목적지 선택 버튼을 경로 계산 그룹에 추가 - 목적지 선택 모드 상태 관리 구현 (버튼 색상 변경) - UnifiedAGVCanvas에 SelectTarget EditMode 및 TargetNodeSelected 이벤트 추가 - 노드 클릭 시 목적지 자동 설정 및 경로 계산 기능 - 시뮬레이션 중 빠른 목적지 변경 및 테스트 지원 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .../Controls/UnifiedAGVCanvas.Mouse.cs | 11 ++++ .../Controls/UnifiedAGVCanvas.cs | 6 +- .../Forms/SimulatorForm.Designer.cs | 15 ++++- Cs_HMI/AGVSimulator/Forms/SimulatorForm.cs | 59 +++++++++++++++++++ 4 files changed, 89 insertions(+), 2 deletions(-) diff --git a/Cs_HMI/AGVNavigationCore/Controls/UnifiedAGVCanvas.Mouse.cs b/Cs_HMI/AGVNavigationCore/Controls/UnifiedAGVCanvas.Mouse.cs index f081932..7611d5f 100644 --- a/Cs_HMI/AGVNavigationCore/Controls/UnifiedAGVCanvas.Mouse.cs +++ b/Cs_HMI/AGVNavigationCore/Controls/UnifiedAGVCanvas.Mouse.cs @@ -63,6 +63,17 @@ namespace AGVNavigationCore.Controls if (e.Button == MouseButtons.Left) { + // 목적지 선택 모드 처리 (시뮬레이터) + if (_editMode == EditMode.SelectTarget) + { + var hitNode = GetNodeAt(worldPoint); + if (hitNode != null) + { + TargetNodeSelected?.Invoke(this, hitNode); + return; + } + } + if (_canvasMode == CanvasMode.Edit && _editMode == EditMode.Move) { var hitNode = GetNodeAt(worldPoint); diff --git a/Cs_HMI/AGVNavigationCore/Controls/UnifiedAGVCanvas.cs b/Cs_HMI/AGVNavigationCore/Controls/UnifiedAGVCanvas.cs index 83217f6..3a55ae6 100644 --- a/Cs_HMI/AGVNavigationCore/Controls/UnifiedAGVCanvas.cs +++ b/Cs_HMI/AGVNavigationCore/Controls/UnifiedAGVCanvas.cs @@ -50,7 +50,8 @@ namespace AGVNavigationCore.Controls Delete, // 삭제 모드 DeleteConnection, // 연결 삭제 모드 AddLabel, // 라벨 추가 모드 - AddImage // 이미지 추가 모드 + AddImage, // 이미지 추가 모드 + SelectTarget // 목적지 선택 모드 (시뮬레이터 전용) } #endregion @@ -145,6 +146,9 @@ namespace AGVNavigationCore.Controls public event EventHandler AGVSelected; public event EventHandler AGVStateChanged; + // 시뮬레이터 이벤트 + public event EventHandler TargetNodeSelected; + #endregion #region Properties diff --git a/Cs_HMI/AGVSimulator/Forms/SimulatorForm.Designer.cs b/Cs_HMI/AGVSimulator/Forms/SimulatorForm.Designer.cs index 7ffd0fe..0647d58 100644 --- a/Cs_HMI/AGVSimulator/Forms/SimulatorForm.Designer.cs +++ b/Cs_HMI/AGVSimulator/Forms/SimulatorForm.Designer.cs @@ -86,6 +86,7 @@ namespace AGVSimulator.Forms this._clearPathButton = new System.Windows.Forms.Button(); this._startPathButton = new System.Windows.Forms.Button(); this._calculatePathButton = new System.Windows.Forms.Button(); + this._selectTargetButton = new System.Windows.Forms.Button(); this._avoidRotationCheckBox = new System.Windows.Forms.CheckBox(); this._targetNodeCombo = new System.Windows.Forms.ComboBox(); this.targetNodeLabel = new System.Windows.Forms.Label(); @@ -450,6 +451,7 @@ namespace AGVSimulator.Forms this._pathGroup.Controls.Add(this._clearPathButton); this._pathGroup.Controls.Add(this._startPathButton); this._pathGroup.Controls.Add(this._calculatePathButton); + this._pathGroup.Controls.Add(this._selectTargetButton); this._pathGroup.Controls.Add(this._avoidRotationCheckBox); this._pathGroup.Controls.Add(this._targetNodeCombo); this._pathGroup.Controls.Add(this.targetNodeLabel); @@ -492,7 +494,17 @@ namespace AGVSimulator.Forms this._calculatePathButton.Text = "경로 계산"; this._calculatePathButton.UseVisualStyleBackColor = true; this._calculatePathButton.Click += new System.EventHandler(this.OnCalculatePath_Click); - // + // + // _selectTargetButton + // + this._selectTargetButton.Location = new System.Drawing.Point(80, 148); + this._selectTargetButton.Name = "_selectTargetButton"; + this._selectTargetButton.Size = new System.Drawing.Size(70, 25); + this._selectTargetButton.TabIndex = 8; + this._selectTargetButton.Text = "목적지 선택"; + this._selectTargetButton.UseVisualStyleBackColor = true; + this._selectTargetButton.Click += new System.EventHandler(this.OnSelectTarget_Click); + // // _avoidRotationCheckBox // this._avoidRotationCheckBox.AutoSize = true; @@ -793,6 +805,7 @@ namespace AGVSimulator.Forms private System.Windows.Forms.Button _calculatePathButton; private System.Windows.Forms.Button _startPathButton; private System.Windows.Forms.Button _clearPathButton; + private System.Windows.Forms.Button _selectTargetButton; private System.Windows.Forms.CheckBox _avoidRotationCheckBox; private System.Windows.Forms.GroupBox _statusGroup; private System.Windows.Forms.Label _simulationStatusLabel; diff --git a/Cs_HMI/AGVSimulator/Forms/SimulatorForm.cs b/Cs_HMI/AGVSimulator/Forms/SimulatorForm.cs index 4ad7272..7cbd0d0 100644 --- a/Cs_HMI/AGVSimulator/Forms/SimulatorForm.cs +++ b/Cs_HMI/AGVSimulator/Forms/SimulatorForm.cs @@ -31,6 +31,7 @@ namespace AGVSimulator.Forms private Timer _simulationTimer; private SimulatorConfig _config; private string _currentMapFilePath; + private bool _isSelectingTarget; // 목적지 선택 모드 상태 // UI Controls - Designer에서 생성됨 @@ -96,6 +97,9 @@ namespace AGVSimulator.Forms _simulatorCanvas.Dock = DockStyle.Fill; _simulatorCanvas.Mode = UnifiedAGVCanvas.CanvasMode.ViewOnly; + // 목적지 선택 이벤트 구독 + _simulatorCanvas.TargetNodeSelected += OnTargetNodeSelected; + _canvasPanel.Controls.Add(_simulatorCanvas); } @@ -370,6 +374,61 @@ namespace AGVSimulator.Forms _statusLabel.Text = "경로 지움"; } + private void OnSelectTarget_Click(object sender, EventArgs e) + { + if (_isSelectingTarget) + { + // 목적지 선택 모드 해제 + _isSelectingTarget = false; + _selectTargetButton.Text = "목적지 선택"; + _selectTargetButton.BackColor = SystemColors.Control; + _simulatorCanvas.CurrentEditMode = UnifiedAGVCanvas.EditMode.Select; + _statusLabel.Text = "목적지 선택 모드 해제"; + } + else + { + // 목적지 선택 모드 활성화 + _isSelectingTarget = true; + _selectTargetButton.Text = "선택 취소"; + _selectTargetButton.BackColor = Color.LightBlue; + _simulatorCanvas.CurrentEditMode = UnifiedAGVCanvas.EditMode.SelectTarget; + _statusLabel.Text = "맵에서 목적지 노드를 클릭하세요"; + } + } + + private void OnTargetNodeSelected(object sender, MapNode selectedNode) + { + try + { + // 목적지 선택 모드 해제 + _isSelectingTarget = false; + _selectTargetButton.Text = "목적지 선택"; + _selectTargetButton.BackColor = SystemColors.Control; + _simulatorCanvas.CurrentEditMode = UnifiedAGVCanvas.EditMode.Select; + + // 목적지 콤보박스에 선택된 노드 설정 + var displayText = GetDisplayName(selectedNode.NodeId); + for (int i = 0; i < _targetNodeCombo.Items.Count; i++) + { + var item = _targetNodeCombo.Items[i].ToString(); + if (item.Contains($"[{selectedNode.NodeId}]")) + { + _targetNodeCombo.SelectedIndex = i; + break; + } + } + + _statusLabel.Text = $"목적지 설정: {displayText}"; + + // 자동으로 경로 계산 수행 + OnCalculatePath_Click(this, EventArgs.Empty); + } + catch (Exception ex) + { + _statusLabel.Text = $"목적지 선택 오류: {ex.Message}"; + } + } + private void OnSetPosition_Click(object sender, EventArgs e) { SetAGVPositionByRfid();