Files
BQP/srcs/RobotNet10/RobotApp/RobotNet10.RobotApp/Services/State/RobotStateMachineExecuteUsage.md
2026-07-13 09:25:40 +07:00

13 KiB

H??ng d?n s? d?ng RobotStateMachineExecute

Gi?i thi?u

RobotStateMachineExecute là class ch?a t?t c? các implementation methods cho Entry/Exit actions c?a State Machine. Class này ???c inject vào RobotStateMachine và t? ??ng ???c g?i khi state transitions x?y ra.

Ki?n trúc

RobotStateMachine (Qu?n lý state transitions)
    ? s? d?ng
RobotStateMachineExecute (Implementation c?a Entry/Exit actions)
    ? s? d?ng
IServiceProvider (?? inject các services khác khi c?n)

Danh sách các Entry/Exit Methods ?ã tri?n khai

1. System States

State Entry Method Exit Method Mô t?
Initializing EntryInitializing() / EntryInitializingAsync() - Kh?i t?o các component c?a robot
Standby EntryStandby() - Robot s?n sàng ho?t ??ng
Shutting_Down EntryShuttingDown() / EntryShuttingDownAsync() ExitShuttingDown() T?t máy an toàn

2. Auto Mode States

State Entry Method Exit Method Mô t?
Idle EntryIdle() - S?n sàng nh?n nhi?m v? m?i
Executing EntryExecuting() ExitExecuting() ?ang th?c hi?n nhi?m v?
Paused EntryPaused() ExitPaused() T?m d?ng nhi?m v?
Canceling EntryCanceling() ExitCanceling() ?ang h?y nhi?m v?
Recovering EntryRecovering() / EntryRecoveringAsync() - Khôi ph?c t? l?i
Remote_Override EntryRemoteOverride() ExitRemoteOverride() ?i?u khi?n t? xa

3. Moving Sub-States

State Entry Method Exit Method Mô t?
Moving EntryMoving() ExitMoving() B?t ??u di chuy?n
Navigation EntryNavigation() - Navigation bình th??ng
Avoidance EntryAvoidance() ExitAvoidance() Tránh ch??ng ng?i v?t
Approach EntryApproach() - Ti?p c?n m?c tiêu
Tracking EntryTracking() - Theo dõi m?c tiêu ??ng
Repositioning EntryRepositioning() - ?i?u ch?nh v? trí

4. ACT Sub-States

State Entry Method Exit Method Mô t?
ACT EntryACT() ExitACT() B?t ??u action
Docking EntryDocking() / EntryDockingAsync() - ?ang docking
Docked EntryDocked() - ?ã docked
Charging EntryCharging() / EntryChargingAsync() ExitCharging() ?ang s?c pin
Undocking EntryUndocking() / EntryUndockingAsync() - ?ang undocking
Loading EntryLoading() / EntryLoadingAsync() - ?ang t?i hàng
Unloading EntryUnloading() / EntryUnloadingAsync() - ?ang d? hàng
TechAction EntryTechAction() / EntryTechActionAsync() - Action k? thu?t

5. Mode States

State Entry Method Exit Method Mô t?
Manual EntryManual() ExitManual() Ch? ?? th? công
Service EntryService() ExitService() Ch? ?? b?o trì
Stop EntryStop() ExitStop() Tr?ng thái d?ng
Fault EntryFault() ExitFault() Tr?ng thái l?i

Cách tùy ch?nh và m? r?ng

1. Inject thêm services

public class RobotStateMachineExecute
{
    private readonly IServiceProvider _serviceProvider;
    private readonly Logger<RobotStateMachineExecute> _logger;
    
    public void EntryDocking()
    {
        _logger.Info("==> Entry Docking State");
        
        // L?y service t? IServiceProvider
        var driver = _serviceProvider.GetService<IDriver>();
        var sensors = _serviceProvider.GetService<ISensorService>();
        var dockingController = _serviceProvider.GetService<IDockingController>();
        
        if (dockingController != null)
        {
            // Th?c hi?n docking
            dockingController.StartDocking();
        }
    }
}

2. Thêm business logic c? th?

public void EntryCharging()
{
    _logger.Info("==> Entry Charging State");
    
    var batteryService = _serviceProvider.GetService<IBatteryService>();
    
    if (batteryService != null)
    {
        // B?t ??u monitoring charging
        batteryService.StartCharging();
        
        // Subscribe vào charging events
        batteryService.OnChargingProgress += (sender, progress) =>
        {
            _logger.Info($"Charging progress: {progress}%");
        };
        
        batteryService.OnChargingCompleted += (sender, e) =>
        {
            _logger.Info("Charging completed!");
            // Có th? t? ??ng fire event ?? chuy?n state
        };
    }
}

3. X? lý async operations

M?t s? methods ?ã ???c tri?n khai v?i c? sync và async versions:

// Async version - recommended
public async Task EntryDockingAsync()
{
    _logger.Info("==> Entry Docking State");
    
    var dockingController = _serviceProvider.GetService<IDockingController>();
    
    if (dockingController != null)
    {
        await dockingController.AlignWithDockAsync();
        await dockingController.ApproachDockAsync();
        await dockingController.ConnectToDockAsync();
    }
}

// Sync version - wrapper
public void EntryDocking() => EntryDockingAsync().GetAwaiter().GetResult();

4. Thêm error handling

public void EntryExecuting()
{
    _logger.Info("==> Entry Executing State");
    
    try
    {
        var missionService = _serviceProvider.GetService<IMissionService>();
        
        if (missionService != null)
        {
            var currentMission = missionService.GetCurrentMission();
            
            if (currentMission == null)
            {
                _logger.Warning("No mission available");
                // Fire event to go back to Idle
                var stateMachine = _serviceProvider.GetService<RobotStateMachine>();
                stateMachine?.Fire(RobotEventType.CompleteExecution);
                return;
            }
            
            // Start executing mission
            missionService.StartExecution(currentMission);
        }
    }
    catch (Exception ex)
    {
        _logger.Error($"Error in EntryExecuting: {ex.Message}");
        
        // Fire event to enter Fault state
        var stateMachine = _serviceProvider.GetService<RobotStateMachine>();
        stateMachine?.Fire(RobotEventType.EnterFault);
    }
}

Ví d? th?c t?: Lu?ng Docking & Charging

public async Task EntryDockingAsync()
{
    _logger.Info("==> Entry Docking State");
    
    try
    {
        var driver = _serviceProvider.GetService<IDriver>();
        var sensors = _serviceProvider.GetService<ISensorService>();
        var dockingService = _serviceProvider.GetService<IDockingService>();
        
        if (dockingService == null)
        {
            _logger.Error("Docking service not available");
            throw new InvalidOperationException("Docking service not available");
        }
        
        // 1. Tìm dock station
        _logger.Info("Searching for dock station...");
        var dockPosition = await dockingService.FindDockStationAsync();
        
        if (dockPosition == null)
        {
            _logger.Error("Dock station not found");
            throw new InvalidOperationException("Dock station not found");
        }
        
        // 2. Di chuy?n ??n v? trí dock
        _logger.Info("Moving to dock position...");
        await dockingService.MoveToDockPositionAsync(dockPosition);
        
        // 3. Align v?i dock
        _logger.Info("Aligning with dock...");
        await dockingService.AlignWithDockAsync();
        
        // 4. Di chuy?n vào dock ch?m rãi
        _logger.Info("Approaching dock...");
        await dockingService.SlowApproachAsync();
        
        // 5. K?t n?i v?i dock
        _logger.Info("Connecting to dock...");
        var connected = await dockingService.ConnectToDockAsync();
        
        if (!connected)
        {
            _logger.Error("Failed to connect to dock");
            throw new InvalidOperationException("Failed to connect to dock");
        }
        
        _logger.Info("Docking completed successfully!");
        
        // T? ??ng chuy?n sang state Docked
        var stateMachine = _serviceProvider.GetService<RobotStateMachine>();
        await stateMachine!.FireAsync(RobotEventType.CompleteDocking);
    }
    catch (Exception ex)
    {
        _logger.Error($"Docking failed: {ex.Message}");
        
        // Chuy?n sang fault state
        var stateMachine = _serviceProvider.GetService<RobotStateMachine>();
        await stateMachine!.FireAsync(RobotEventType.EnterFault);
    }
}

public async Task EntryChargingAsync()
{
    _logger.Info("==> Entry Charging State");
    
    try
    {
        var batteryService = _serviceProvider.GetService<IBatteryService>();
        var dockingService = _serviceProvider.GetService<IDockingService>();
        
        if (batteryService == null || dockingService == null)
        {
            _logger.Error("Required services not available");
            return;
        }
        
        // 1. Ki?m tra k?t n?i dock
        if (!dockingService.IsConnectedToDock())
        {
            _logger.Error("Not connected to dock");
            return;
        }
        
        // 2. B?t ??u s?c
        _logger.Info("Starting charging...");
        await batteryService.StartChargingAsync();
        
        // 3. Monitor charging progress
        batteryService.OnChargingProgress += (sender, progress) =>
        {
            _logger.Info($"Battery level: {progress.CurrentLevel}% (Target: {progress.TargetLevel}%)");
            
            // N?u ?ã ??t target level, hoàn thành charging
            if (progress.CurrentLevel >= progress.TargetLevel)
            {
                _logger.Info("Target battery level reached!");
                
                var stateMachine = _serviceProvider.GetService<RobotStateMachine>();
                stateMachine?.Fire(RobotEventType.CompleteCharging);
            }
        };
        
        // 4. Subscribe charging error events
        batteryService.OnChargingError += (sender, error) =>
        {
            _logger.Error($"Charging error: {error.Message}");
            
            var stateMachine = _serviceProvider.GetService<RobotStateMachine>();
            stateMachine?.Fire(RobotEventType.EnterFault);
        };
    }
    catch (Exception ex)
    {
        _logger.Error($"Failed to start charging: {ex.Message}");
    }
}

public void ExitCharging()
{
    _logger.Info("<== Exit Charging State");
    
    var batteryService = _serviceProvider.GetService<IBatteryService>();
    
    if (batteryService != null)
    {
        // D?ng charging
        batteryService.StopCharging();
        
        // Unsubscribe events
        batteryService.OnChargingProgress = null;
        batteryService.OnChargingError = null;
        
        // Log final battery level
        var batteryLevel = batteryService.GetCurrentLevel();
        _logger.Info($"Charging stopped. Final battery level: {batteryLevel}%");
    }
}

Best Practices

  1. Luôn log chi ti?t trong m?i Entry/Exit method ?? d? debug
  2. S? d?ng try-catch ?? x? lý l?i và chuy?n sang Fault state n?u c?n
  3. S? d?ng async/await cho các operations t?n th?i gian
  4. Cleanup resources trong Exit methods
  5. Inject services qua IServiceProvider thay vì hard-code dependencies
  6. Fire events ?? t? ??ng chuy?n state khi hoàn thành action
  7. Validate preconditions tr??c khi th?c hi?n action
  8. Update VDA5050 state ?? ??ng b? v?i Fleet Manager

Tích h?p v?i VDA5050

public void EntryExecuting()
{
    _logger.Info("==> Entry Executing State");
    
    var vda5050Service = _serviceProvider.GetService<IVDA5050Service>();
    
    if (vda5050Service != null)
    {
        // C?p nh?t VDA5050 state
        vda5050Service.UpdateState(new StateMessage
        {
            OperatingMode = "AUTOMATIC",
            ActionStates = new List<ActionState>
            {
                new() { ActionStatus = "RUNNING" }
            }
        });
    }
    
    // ... rest of implementation
}

K?t lu?n

RobotStateMachineExecute cung c?p m?t cách t? ch?c code rõ ràng và d? maintain cho t?t c? các state behaviors c?a robot. B?n có th? d? dàng:

  • Thêm logic m?i vào các state
  • Inject và s? d?ng các services khác
  • X? lý async operations
  • Error handling và recovery
  • Testing t?ng state behavior ??c l?p