"feat:Implement-Canvas-Run-Mode-and-Logic"
This commit is contained in:
@@ -119,6 +119,9 @@ namespace AGVNavigationCore.Controls
|
|||||||
var worldPoint = ScreenToWorld(e.Location);
|
var worldPoint = ScreenToWorld(e.Location);
|
||||||
var hitNode = GetItemAt(worldPoint);
|
var hitNode = GetItemAt(worldPoint);
|
||||||
|
|
||||||
|
// 가동 모드에서는 더블클릭 편집 방지
|
||||||
|
if (_canvasMode == CanvasMode.Run) return;
|
||||||
|
|
||||||
if (hitNode == null) return;
|
if (hitNode == null) return;
|
||||||
|
|
||||||
if (hitNode.Type == NodeType.Normal)
|
if (hitNode.Type == NodeType.Normal)
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ namespace AGVNavigationCore.Controls
|
|||||||
{
|
{
|
||||||
Edit, // 편집 가능 (맵 에디터)
|
Edit, // 편집 가능 (맵 에디터)
|
||||||
Sync, // 동기화 모드 (장비 설정 동기화)
|
Sync, // 동기화 모드 (장비 설정 동기화)
|
||||||
Emulator // 에뮬레이터 모드
|
Emulator, // 에뮬레이터 모드
|
||||||
|
Run // 가동 모드 (User Request)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -43,11 +43,19 @@ namespace Project.ViewForm
|
|||||||
|
|
||||||
private void OnNodeSelected(object sender, NodeBase node, MouseEventArgs e)
|
private void OnNodeSelected(object sender, NodeBase node, MouseEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.Button != MouseButtons.Right) return;
|
|
||||||
if (node == null) return;
|
if (node == null) return;
|
||||||
var mapnode = node as MapNode;
|
var mapnode = node as MapNode;
|
||||||
if (mapnode == null) return;
|
if (mapnode == null) return;
|
||||||
|
|
||||||
|
// [Run Mode] Left Click: AGV Operation
|
||||||
|
if (PUB._mapCanvas.Mode == AGVNavigationCore.Controls.UnifiedAGVCanvas.CanvasMode.Run && e.Button == MouseButtons.Left)
|
||||||
|
{
|
||||||
|
HandleRunModeClick(mapnode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.Button != MouseButtons.Right) return;
|
||||||
|
|
||||||
// 도킹 가능한 노드인지 또는 작업 노드인지 확인
|
// 도킹 가능한 노드인지 또는 작업 노드인지 확인
|
||||||
if (mapnode.isDockingNode == false) return;
|
if (mapnode.isDockingNode == false) return;
|
||||||
|
|
||||||
@@ -158,6 +166,9 @@ namespace Project.ViewForm
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
this.timer1.Start();
|
this.timer1.Start();
|
||||||
|
|
||||||
|
// Set Run Mode
|
||||||
|
PUB._mapCanvas.Mode = AGVNavigationCore.Controls.UnifiedAGVCanvas.CanvasMode.Run;
|
||||||
}
|
}
|
||||||
private void AGV_DataReceive(object sender, arDev.Narumi.DataEventArgs e)
|
private void AGV_DataReceive(object sender, arDev.Narumi.DataEventArgs e)
|
||||||
{
|
{
|
||||||
@@ -194,6 +205,9 @@ namespace Project.ViewForm
|
|||||||
PUB.sm.StepChanged -= Sm_StepChanged;
|
PUB.sm.StepChanged -= Sm_StepChanged;
|
||||||
this.ctlAuto1.ButtonClick -= CtlAuto1_ButtonClick;
|
this.ctlAuto1.ButtonClick -= CtlAuto1_ButtonClick;
|
||||||
PUB.AGV.DataReceive -= AGV_DataReceive;
|
PUB.AGV.DataReceive -= AGV_DataReceive;
|
||||||
|
|
||||||
|
// Reset Mode to Edit
|
||||||
|
PUB._mapCanvas.Mode = AGVNavigationCore.Controls.UnifiedAGVCanvas.CanvasMode.Edit;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tmrun = false;
|
bool tmrun = false;
|
||||||
@@ -236,5 +250,49 @@ namespace Project.ViewForm
|
|||||||
|
|
||||||
//tmrun = false;
|
//tmrun = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void HandleRunModeClick(MapNode targetNode)
|
||||||
|
{
|
||||||
|
if (targetNode == null) return;
|
||||||
|
|
||||||
|
ENIGProtocol.AGVCommandHE targetCmd = ENIGProtocol.AGVCommandHE.Goto;
|
||||||
|
string confirmMsg = "";
|
||||||
|
|
||||||
|
if (targetNode.StationType == StationType.Charger)
|
||||||
|
{
|
||||||
|
if (MessageBox.Show($"[{targetNode.Id}] 충전기로 이동하여 충전을 진행하시겠습니까?", "작업 확인", MessageBoxButtons.YesNo) == DialogResult.Yes)
|
||||||
|
{
|
||||||
|
targetCmd = ENIGProtocol.AGVCommandHE.Charger;
|
||||||
|
ExecuteManualCommand(targetNode, targetCmd);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (targetNode.isDockingNode)
|
||||||
|
{
|
||||||
|
// Loader, Unloader, Buffer, Cleaner - Pick/Drop Selection
|
||||||
|
ContextMenuStrip menu = new ContextMenuStrip();
|
||||||
|
|
||||||
|
var pickOn = new ToolStripMenuItem("Pick On (Move & Pick)");
|
||||||
|
pickOn.Click += (s, args) => ExecuteManualCommand(targetNode, ENIGProtocol.AGVCommandHE.PickOn);
|
||||||
|
menu.Items.Add(pickOn);
|
||||||
|
|
||||||
|
var pickOff = new ToolStripMenuItem("Pick Off (Move & Drop)");
|
||||||
|
pickOff.Click += (s, args) => ExecuteManualCommand(targetNode, ENIGProtocol.AGVCommandHE.PickOff);
|
||||||
|
menu.Items.Add(pickOff);
|
||||||
|
|
||||||
|
menu.Show(Cursor.Position);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Normal Node
|
||||||
|
if (MessageBox.Show($"[{targetNode.Id}] 노드로 이동하시겠습니까?", "이동 확인", MessageBoxButtons.YesNo) == DialogResult.Yes)
|
||||||
|
{
|
||||||
|
targetCmd = ENIGProtocol.AGVCommandHE.Goto;
|
||||||
|
ExecuteManualCommand(targetNode, targetCmd);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
55
Cs_HMI/Project/ViewForm/fAuto.cs.new
Normal file
55
Cs_HMI/Project/ViewForm/fAuto.cs.new
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
private void HandleRunModeClick(MapNode targetNode)
|
||||||
|
{
|
||||||
|
if (targetNode == null) return;
|
||||||
|
|
||||||
|
ENIGProtocol.AGVCommandHE targetCmd = ENIGProtocol.AGVCommandHE.Move;
|
||||||
|
string confirmMsg = "";
|
||||||
|
|
||||||
|
if (targetNode.StationType == StationType.Charger)
|
||||||
|
{
|
||||||
|
if (MessageBox.Show($"[{targetNode.Id}] 충전기로 이동하여 충전을 진행하시겠습니까?", "작업 확인", MessageBoxButtons.YesNo) == DialogResult.Yes)
|
||||||
|
{
|
||||||
|
targetCmd = ENIGProtocol.AGVCommandHE.Charger;
|
||||||
|
ExecuteManualCommand(targetNode, targetCmd);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (targetNode.isDockingNode)
|
||||||
|
{
|
||||||
|
// Loader, Unloader, Buffer, Cleaner
|
||||||
|
// Custom Dialog needed for PickOn / PickOff
|
||||||
|
// For now, let's use a simple MessageBox or just a ContextMenu like logic?
|
||||||
|
// User said: "click -> PickOn/Off selection -> Execute"
|
||||||
|
// A context menu at cursor position is good for selection.
|
||||||
|
|
||||||
|
ContextMenuStrip menu = new ContextMenuStrip();
|
||||||
|
|
||||||
|
var pickOn = new ToolStripMenuItem("Pick On (Move & Pick)");
|
||||||
|
pickOn.Click += (s, args) => ExecuteManualCommand(targetNode, ENIGProtocol.AGVCommandHE.PickOn);
|
||||||
|
menu.Items.Add(pickOn);
|
||||||
|
|
||||||
|
var pickOff = new ToolStripMenuItem("Pick Off (Move & Drop)");
|
||||||
|
pickOff.Click += (s, args) => ExecuteManualCommand(targetNode, ENIGProtocol.AGVCommandHE.PickOff);
|
||||||
|
menu.Items.Add(pickOff);
|
||||||
|
|
||||||
|
menu.Show(Cursor.Position);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Normal Node
|
||||||
|
if (MessageBox.Show($"[{targetNode.Id}] 노드로 이동하시겠습니까?", "이동 확인", MessageBoxButtons.YesNo) == DialogResult.Yes)
|
||||||
|
{
|
||||||
|
targetCmd = ENIGProtocol.AGVCommandHE.Move; // Or PickOff as default move? usually just Move logic inside ExecuteManualCommand handles GOTO.
|
||||||
|
// But ExecuteManualCommand takes AGVCommandHE.
|
||||||
|
// Let's check ENIGProtocol.AGVCommandHE.
|
||||||
|
// If not present, we might need to modify ExecuteManualCommand or just pass PickOff as dummy?
|
||||||
|
// Actually ExecuteManualCommand uses 'cmd' for log and 'PUB.NextWorkCmd'.
|
||||||
|
// If 'Move', just GOTO.
|
||||||
|
// Let's assume 'Move' exists or we use 'PickOff' (Move & Drop often implies MoveTo).
|
||||||
|
// Or we check `ENIGProtocol.AGVCommandHE`.
|
||||||
|
ExecuteManualCommand(targetNode, ENIGProtocol.AGVCommandHE.Move);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user