- Fixed critical issue in ConvertToDetailedPath where motor direction was not passed to GetRequiredMagnetDirection - Motor direction is essential for backward movement as Left/Right directions must be inverted - Modified AGVPathfinder.cs line 280 to pass currentDirection parameter - Ensures backward motor direction properly inverts magnet sensor directions feat: Add waypoint support to pathfinding system - Added FindPath overload with params string[] waypointNodeIds in AStarPathfinder - Supports sequential traversal through multiple intermediate nodes - Validates waypoints and prevents duplicates in sequence - Returns combined path result with aggregated metrics feat: Implement path result merging with DetailedPath preservation - Added CombineResults method in AStarPathfinder for intelligent path merging - Automatically deduplicates nodes when last of previous path equals first of current - Preserves DetailedPath information including motor and magnet directions - Essential for multi-segment path operations feat: Integrate magnet direction with motor direction awareness - Modified JunctionAnalyzer.GetRequiredMagnetDirection to accept AgvDirection parameter - Inverts Left/Right magnet directions when moving Backward - Properly handles motor direction context throughout pathfinding feat: Add automatic start node selection in simulator - Added SetStartNodeToCombo method to SimulatorForm - Automatically selects start node combo box when AGV position is set via RFID - Improves UI usability and workflow efficiency 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
8.9 KiB
8.9 KiB
AGV 방향 정보 저장 위치 분석
개요
AGV의 이동 방향을 계산하기 위해 이전 RFID 위치 정보와 **현재 모터 방향(전/후진)**을 함께 저장하고 관리하는 시스템
📍 저장 위치: VirtualAGV.cs (AGVSimulator\Models\VirtualAGV.cs)
핵심 필드 (Field) 구조
현재 상태 (Current State)
private Point _currentPosition; // 현재 AGV 위치 (픽셀 좌표)
private MapNode _currentNode; // 현재 노드 (RFID ID 포함)
private AgvDirection _currentDirection; // 현재 모터 방향 (Forward/Backward)
이전 상태 (Previous State - 리프트 방향 계산용)
private Point _targetPosition; // 이전 위치 (previousPos 역할)
private MapNode _targetNode; // 이전 노드 (이전 RFID)
private AgvDirection _targetDirection; // 이전 모터 방향
데이터 구조 시각화
이전 상태 (n-1) 현재 상태 (n)
────────────────────────────────────
_targetPosition ─────→ _currentPosition (좌표 이동)
_targetNode ─────→ _currentNode (RFID 이동)
_targetDirection ─────→ _currentDirection (모터 방향)
🔄 SetPosition() 메서드 - 위치 및 방향 업데이트
위치: VirtualAGV.cs 305~322행
/// <summary>
/// AGV 위치 직접 설정 (시뮬레이터용)
/// TargetPosition을 이전 위치로 저장하여 리프트 방향 계산이 가능하도록 함
/// </summary>
/// <param name="node">현재 RFID 노드</param>
/// <param name="newPosition">새로운 위치</param>
/// <param name="motorDirection">모터이동방향 (Forward/Backward)</param>
public void SetPosition(MapNode node, Point newPosition, AgvDirection motorDirection)
{
// 현재 위치를 이전 위치로 저장 (리프트 방향 계산용)
if (_currentPosition != Point.Empty)
{
_targetPosition = _currentPosition; // ← 이전 위치 저장
_targetDirection = _currentDirection; // ← 이전 방향 저장
_targetNode = node; // ← 이전 노드(RFID) 저장
}
// 새로운 위치 설정
_currentPosition = newPosition; // 현재 위치 설정
_currentDirection = motorDirection; // 현재 모터방향 설정
_currentNode = node; // 현재 노드(RFID) 설정
// 위치 변경 이벤트 발생
PositionChanged?.Invoke(this, (_currentPosition, _currentDirection, _currentNode));
}
SetPosition() 실행 흐름
| 단계 | 동작 | 데이터 |
|---|---|---|
| 1단계: 이전 상태 백업 | 현재 위치 → 이전 위치로 저장 | _currentPosition → _targetPosition |
| 현재 방향 → 이전 방향으로 저장 | _currentDirection → _targetDirection | |
| 현재 노드 → 이전 노드로 저장 | _currentNode → _targetNode | |
| 2단계: 새 상태 설정 | 새 좌표 저장 | newPosition → _currentPosition |
| 새 모터방향 저장 | motorDirection → _currentDirection | |
| 새 노드(RFID) 저장 | node → _currentNode | |
| 3단계: 이벤트 발생 | 위치 변경 알림 | PositionChanged 이벤트 발생 |
🧭 리프트 방향 계산에 사용되는 정보
필요한 정보
- 이전 위치: _targetPosition
- 현재 위치: _currentPosition
- 현재 모터 방향: _currentDirection (Forward/Backward)
리프트 방향 계산 로직
파일: AGVNavigationCore\Utils\LiftCalculator.cs
메서드: CalculateLiftAngleRadians(Point currentPos, Point targetPos, AgvDirection motorDirection)
계산식 (모터 방향 고려)
if (motorDirection == AgvDirection.Forward)
{
// 전진: 현재→목표 벡터 (리프트가 목표 방향 향함)
var dx = targetPos.X - currentPos.X;
var dy = targetPos.Y - currentPos.Y;
}
else if (motorDirection == AgvDirection.Backward)
{
// 후진: 현재→목표 벡터 반대 (리프트가 이동 방향 향함)
var dx = currentPos.X - targetPos.X;
var dy = currentPos.Y - targetPos.Y;
}
// 각도 계산
var angle = Math.Atan2(dy, dx);
계산 예시
상황 1: 전진 모드 (Forward)
위치: 006 (100, 100) → 005 (150, 100) 이동 중
_targetPosition = (100, 100) // 이전 위치 (006)
_currentPosition = (150, 100) // 현재 위치 (005)
_currentDirection = Forward // 전진
벡터: (150-100, 100-100) = (50, 0) ⇒ 오른쪽(0°)
리프트 방향: 오른쪽(0°)으로 회전
상황 2: 후진 모드 (Backward)
위치: 006 (100, 100) → 005 (150, 100) 이동 중 (후진)
_targetPosition = (100, 100) // 이전 위치 (006)
_currentPosition = (150, 100) // 현재 위치 (005)
_currentDirection = Backward // 후진
벡터: (100-150, 100-100) = (-50, 0) ⇒ 왼쪽(180°)
리프트 방향: 왼쪽(180°)으로 회전 (이동 방향 반대)
📊 저장된 정보 요약
VirtualAGV가 저장하는 RFID/방향 정보
| 정보 | 필드명 | 타입 | 설명 |
|---|---|---|---|
| 이전 위치 | _targetPosition | Point | 이전 RFID 감지 위치 |
| 이전 RFID | _targetNode | MapNode | 이전 RFID 정보 (RfidId 포함) |
| 이전 방향 | _targetDirection | AgvDirection | 이전 모터 방향 |
| 현재 위치 | _currentPosition | Point | 현재 RFID 감지 위치 |
| 현재 RFID | _currentNode | MapNode | 현재 RFID 정보 (RfidId 포함) |
| 현재 방향 | _currentDirection | AgvDirection | 현재 모터 방향 (Forward/Backward) |
MapNode에 포함된 RFID 정보
public class MapNode
{
public string RfidId { get; set; } // 물리적 RFID ID
public string RfidStatus { get; set; } // RFID 상태
public string RfidDescription { get; set; } // RFID 설명
// ... 기타 노드 정보
}
🔍 호출 흐름: SetPosition() 언제 호출되는가?
호출 위치들
1. AGV 시뮬레이션에서의 자동 위치 업데이트
시나리오: AGV가 경로를 따라 이동 중
// VirtualAGV.cs의 경로 실행 중
ProcessNextNode()
↓
다음 노드에 도착 후
SetPosition(nextNode, nextPosition, motorDirection)
↓
_targetPosition ← 이전 위치 저장
_currentPosition ← 새 위치 설정
2. 시뮬레이터 UI에서의 수동 위치 설정
시나리오: 사용자가 시뮬레이터에서 AGV를 수동으로 배치
// SimulatorForm에서 사용자 클릭
userClicksOnCanvas()
↓
SetPosition(selectedNode, clickPosition, currentDirection)
↓
VirtualAGV 위치 업데이트
💾 이 정보가 사용되는 곳들
1. 리프트 방향 계산 (LiftCalculator.cs)
var liftAngle = CalculateLiftAngleRadians(
_targetPosition, // 이전 위치
_currentPosition, // 현재 위치
_currentDirection // 현재 모터 방향
);
2. 경로 방향 검증 (DirectionChangePlanner.cs)
// 현재 방향이 목표 도킹 방향과 일치하는지 확인
bool needDirectionChange = (_currentDirection != requiredDockingDirection);
3. UI 렌더링 (UnifiedAGVCanvas.cs)
// AGV 리프트 그리기 시 방향 정보 사용
DrawAGVLiftAdvanced(graphics, agv);
↓
agv.CurrentDirection (현재 방향)
agv.TargetPosition (이전 위치)
4. 위치 변경 이벤트 발생
PositionChanged?.Invoke(this,
(_currentPosition, _currentDirection, _currentNode)
);
🎯 요약: AGV 방향 계산 데이터 흐름
입력: RFID 감지 + 모터 방향 정보
↓
SetPosition(node, newPos, direction) 호출
↓
[이전 상태 백업]
_targetPosition = 이전 위치
_targetDirection = 이전 방향
_targetNode = 이전 RFID
↓
[현재 상태 설정]
_currentPosition = 새 위치
_currentDirection = 현재 방향
_currentNode = 현재 RFID
↓
[리프트 방향 계산에 사용]
LiftCalculator.CalculateLiftAngleRadians(
이전위치, 현재위치, 현재방향
)
↓
결과: AGV의 정확한 리프트 방향 결정
📌 중요 포인트
✅ 이전 위치 보존: SetPosition() 호출 시 기존 현재 위치를 이전 위치로 저장 ✅ 방향 정보 포함: 이전/현재 방향 모두 저장하여 리프트 회전 계산 ✅ RFID 매핑: MapNode에 RfidId 포함하여 물리적 RFID와 논리적 위치 연계 ✅ 이벤트 발행: 위치 변경 시 자동으로 PositionChanged 이벤트 발생 ✅ 파라미터 분리: motorDirection을 별도 파라미터로 받아 명확한 방향 제어
🔧 현재 상태: 시뮬레이터에서만 구현
현재 이 저장 메커니즘은 VirtualAGV.cs에 전체 주석처리되어 있습니다. 실제 운영 시스템에서는 이와 유사한 메커니즘이 실제 AGV 하드웨어 제어 모듈에서 구현될 것으로 예상됩니다.