Implement ACS Command Handlers (PickOn, PickOff, Charge), Manual Mode Safety, and Map UI Commands
This commit is contained in:
@@ -88,17 +88,18 @@ namespace AGVNavigationCore.Models
|
||||
|
||||
private bool _disablecross = false;
|
||||
|
||||
/// <summary>
|
||||
/// 해당 노드 통과 시 제한 속도 (기본값: M - Normal)
|
||||
/// Predict 단계에서 이 값을 참조하여 속도 명령을 생성합니다.
|
||||
/// </summary>
|
||||
public SpeedLevel SpeedLimit { get; set; } = SpeedLevel.M;
|
||||
|
||||
/// <summary>
|
||||
/// 장비 ID (도킹/충전 스테이션인 경우)
|
||||
/// 예: "LOADER1", "CLEANER1", "BUFFER1", "CHARGER1"
|
||||
/// </summary>
|
||||
public string NodeAlias { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 장비 타입 (도킹/충전 스테이션인 경우)
|
||||
/// </summary>
|
||||
// public StationType? StationType { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// 노드 생성 일자
|
||||
/// </summary>
|
||||
@@ -109,7 +110,6 @@ namespace AGVNavigationCore.Models
|
||||
/// </summary>
|
||||
public DateTime ModifiedDate { get; set; } = DateTime.Now;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 노드 활성화 여부
|
||||
/// </summary>
|
||||
|
||||
@@ -188,6 +188,11 @@ namespace AGVNavigationCore.Models
|
||||
/// </summary>
|
||||
public int DetectedRfidCount => _detectedRfids.Count;
|
||||
|
||||
/// <summary>
|
||||
/// 배터리 부족 경고 임계값 (%)
|
||||
/// </summary>
|
||||
public float LowBatteryThreshold { get; set; } = 20.0f;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
@@ -262,9 +267,9 @@ namespace AGVNavigationCore.Models
|
||||
BatteryLevel = Math.Max(0, Math.Min(100, percentage));
|
||||
|
||||
// 배터리 부족 경고
|
||||
if (BatteryLevel < 20.0f && _currentState != AGVState.Charging)
|
||||
if (BatteryLevel < LowBatteryThreshold && _currentState != AGVState.Charging)
|
||||
{
|
||||
OnError($"배터리 부족: {BatteryLevel:F1}%");
|
||||
OnError($"배터리 부족: {BatteryLevel:F1}% (기준: {LowBatteryThreshold}%)");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -586,6 +591,15 @@ namespace AGVNavigationCore.Models
|
||||
var item = CurrentPath.DetailedPath.FirstOrDefault(t => t.NodeId == node.NodeId && t.IsPass == false);
|
||||
if (item != null)
|
||||
{
|
||||
// [PathJump Check] 점프한 노드 개수 확인
|
||||
// 현재 노드(item)보다 이전인데 아직 IsPass가 안 된 노드의 개수
|
||||
int skippedCount = CurrentPath.DetailedPath.Count(t => t.seq < item.seq && t.IsPass == false);
|
||||
if (skippedCount > 2)
|
||||
{
|
||||
OnError($"PathJump: {skippedCount}개의 노드를 건너뛰었습니다. (허용: 2개, 현재노드: {node.NodeId})");
|
||||
return;
|
||||
}
|
||||
|
||||
//item.IsPass = true;
|
||||
//이전노드는 모두 지나친걸로 한다
|
||||
CurrentPath.DetailedPath.Where(t => t.seq < item.seq).ToList().ForEach(t => t.IsPass = true);
|
||||
@@ -633,14 +647,11 @@ namespace AGVNavigationCore.Models
|
||||
// DetailedPath가 없으면 기본 명령 반환
|
||||
if (_currentPath == null || _currentPath.DetailedPath == null || _currentPath.DetailedPath.Count == 0)
|
||||
{
|
||||
var defaultMotor = _currentDirection == AgvDirection.Forward
|
||||
? MotorCommand.Forward
|
||||
: MotorCommand.Backward;
|
||||
|
||||
// [Refactor] Predict와 일관성 유지: 경로가 없으면 정지
|
||||
return new AGVCommand(
|
||||
defaultMotor,
|
||||
MotorCommand.Stop,
|
||||
MagnetPosition.S,
|
||||
SpeedLevel.M,
|
||||
SpeedLevel.L,
|
||||
eAGVCommandReason.NoPath,
|
||||
$"{actionDescription} (DetailedPath 없음)"
|
||||
);
|
||||
@@ -697,10 +708,13 @@ namespace AGVNavigationCore.Models
|
||||
break;
|
||||
}
|
||||
|
||||
// 속도 결정 (회전 노드면 저속, 일반 이동은 중속)
|
||||
SpeedLevel speed = nodeInfo.CanRotate || nodeInfo.IsDirectionChangePoint
|
||||
? SpeedLevel.L
|
||||
: SpeedLevel.M;
|
||||
// [Speed Control] NodeMotorInfo에 설정된 속도 사용
|
||||
// 단, 회전 구간 등에서 안전을 위해 강제 감속이 필요한 경우 로직 추가 가능
|
||||
// 현재는 사용자 설정 우선
|
||||
SpeedLevel speed = nodeInfo.Speed;
|
||||
|
||||
// Optional: 회전 시 강제 감속 로직 (사용자 요청에 따라 주석 처리 또는 제거 가능)
|
||||
// if (nodeInfo.CanRotate || nodeInfo.IsDirectionChangePoint) speed = SpeedLevel.L;
|
||||
|
||||
return new AGVCommand(
|
||||
motorCmd,
|
||||
|
||||
@@ -445,7 +445,12 @@ namespace AGVNavigationCore.PathFinding.Planning
|
||||
MagnetDirection.Straight
|
||||
);
|
||||
|
||||
detailedPath1.Add(nodeInfo);
|
||||
// [Speed Control] MapNode의 속도 설정 적용
|
||||
var mapNode = _mapNodes.FirstOrDefault(n => n.NodeId == nodeId);
|
||||
if (mapNode != null)
|
||||
{
|
||||
nodeInfo.Speed = mapNode.SpeedLimit;
|
||||
}
|
||||
}
|
||||
|
||||
// path1에 상세 경로 정보 설정
|
||||
|
||||
@@ -47,6 +47,11 @@ namespace AGVNavigationCore.PathFinding.Planning
|
||||
/// </summary>
|
||||
public AgvDirection MotorDirection { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 해당 노드에서의 제한 속도
|
||||
/// </summary>
|
||||
public SpeedLevel Speed { get; set; } = SpeedLevel.M;
|
||||
|
||||
/// <summary>
|
||||
/// 마그넷 센서 방향 제어 (갈림길 처리용)
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user