Files
I150/srcs/RobotNet10/RobotApp/RobotNet10.RobotApp/Services/State/StateInheritanceGuide.md
2026-07-03 16:37:12 +07:00

9.7 KiB

State Inheritance trong RobotStateMachine

Tóm t?t

? SUB-STATES T? ??NG K? TH?A CÁC EVENTS T? PARENT STATE trong Hierarchical State Machine

Ví d? chi ti?t

Hierarchy trong RobotStateMachine

System (Root)
??? Initializing
??? Standby
??? Shutting_Down

Auto (Root)
??? Idle
??? Executing
?   ??? Moving
?   ?   ??? Navigation
?   ?   ??? Avoidance
?   ?   ??? Approach
?   ?   ??? Tracking
?   ?   ??? Repositioning
?   ??? ACT
?       ??? Docking
?       ??? Docked
?       ??? Charging
?       ??? Undocking
?       ??? Loading
?       ??? Unloading
?       ??? TechAction
??? Paused
??? Canceling
??? Recovering
??? Remote_Override

1. Inheritance c? b?n

Ví d? 1: Idle k? th?a t? Auto

// Auto (parent) ??nh ngh?a các events
builder.In(RobotStateType.Auto)
    .On(RobotEventType.EnterManual).Goto(RobotStateType.Manual)
    .On(RobotEventType.EnterService).Goto(RobotStateType.Service)
    .On(RobotEventType.EnterStop).Goto(RobotStateType.Stop)
    .On(RobotEventType.EnterFault).Goto(RobotStateType.Fault);

// Idle (sub-state) ch? ??nh ngh?a event riêng c?a nó
builder.In(RobotStateType.Idle)
    .On(RobotEventType.StartExecution).Goto(RobotStateType.Executing);

K?t qu? khi ? state Idle:

var stateMachine = serviceProvider.GetService<RobotStateMachine>();
stateMachine.Initialize();

// Gi? s? ?ang ? Idle
await stateMachine.FireAsync(RobotEventType.EnterAuto);

// Query transitions
var transitions = stateMachine.GetPossibleTransitions(RobotStateType.Idle);

// K?t qu?:
// 1. StartExecution -> Executing      (??nh ngh?a riêng)
// 2. EnterManual -> Manual            (k? th?a t? Auto)
// 3. EnterService -> Service          (k? th?a t? Auto)
// 4. EnterStop -> Stop                (k? th?a t? Auto)
// 5. EnterFault -> Fault              (k? th?a t? Auto)

Console.WriteLine($"Idle has {transitions.Count} possible transitions");
foreach (var t in transitions)
{
    Console.WriteLine($"  - {t.Event} -> {t.ToState}");
}

Output:

Idle has 5 possible transitions
  - StartExecution -> Executing
  - EnterManual -> Manual
  - EnterService -> Service
  - EnterStop -> Stop
  - EnterFault -> Fault

2. Multi-level Inheritance

Ví d? 2: Navigation k? th?a t? Moving và Executing

// Executing (c?p 1) ??nh ngh?a
builder.In(RobotStateType.Executing)
    .On(RobotEventType.PauseExecution).Goto(RobotStateType.Paused)
    .On(RobotEventType.CancelExecution).Goto(RobotStateType.Canceling);

// Moving (c?p 2 - sub c?a Executing) ??nh ngh?a
builder.In(RobotStateType.Moving)
    .On(RobotEventType.StartACT).Goto(RobotStateType.ACT);

// Navigation (c?p 3 - sub c?a Moving) ??nh ngh?a
builder.In(RobotStateType.Navigation)
    .On(RobotEventType.StartAvoidance).Goto(RobotStateType.Avoidance);

K?t qu? khi ? Navigation:

var transitions = stateMachine.GetPossibleTransitions(RobotStateType.Navigation);

// K?t qu? (k? th?a 3 c?p):
// 1. StartAvoidance -> Avoidance      (??nh ngh?a ? Navigation)
// 2. StartACT -> ACT                  (k? th?a t? Moving)
// 3. PauseExecution -> Paused         (k? th?a t? Executing)
// 4. CancelExecution -> Canceling     (k? th?a t? Executing)
// 5. EnterManual -> Manual            (k? th?a t? Auto - parent c?a Executing)
// 6. EnterService -> Service          (k? th?a t? Auto)
// 7. EnterStop -> Stop                (k? th?a t? Auto)
// 8. EnterFault -> Fault              (k? th?a t? Auto)

3. S? d?ng các method m?i

Query Hierarchy

// L?y parent state
var parent = stateMachine.GetParentState(RobotStateType.Navigation);
Console.WriteLine($"Parent of Navigation: {parent}"); // Moving

// L?y toàn b? hierarchy chain
var chain = stateMachine.GetStateHierarchyChain(RobotStateType.Navigation);
Console.WriteLine("Hierarchy chain:");
foreach (var state in chain)
{
    Console.WriteLine($"  - {state}");
}
// Output:
//   - Navigation
//   - Moving
//   - Executing
//   - Auto

// Ki?m tra sub-state relationship
bool isSubState = stateMachine.IsSubStateOf(
    RobotStateType.Navigation, 
    RobotStateType.Auto
);
Console.WriteLine($"Navigation is sub-state of Auto: {isSubState}"); // true

isSubState = stateMachine.IsSubStateOf(
    RobotStateType.Navigation, 
    RobotStateType.Manual
);
Console.WriteLine($"Navigation is sub-state of Manual: {isSubState}"); // false

Check transitions v?i inheritance

// Khi ? Navigation state
await stateMachine.FireAsync(RobotEventType.EnterAuto);
await stateMachine.FireAsync(RobotEventType.StartExecution);

// Bây gi? ?ang ? Navigation (sub-state c?a Moving, Executing, Auto)

// Ki?m tra có th? fire các events k? th?a
Console.WriteLine($"Can fire StartAvoidance: {stateMachine.CanFire(RobotEventType.StartAvoidance)}"); // true (riêng)
Console.WriteLine($"Can fire StartACT: {stateMachine.CanFire(RobotEventType.StartACT)}"); // true (t? Moving)
Console.WriteLine($"Can fire PauseExecution: {stateMachine.CanFire(RobotEventType.PauseExecution)}"); // true (t? Executing)
Console.WriteLine($"Can fire EnterManual: {stateMachine.CanFire(RobotEventType.EnterManual)}"); // true (t? Auto)

// Ki?m tra có th? chuy?n sang các states
Console.WriteLine($"Can go to Avoidance: {stateMachine.CanTransitionTo(RobotStateType.Avoidance)}"); // true
Console.WriteLine($"Can go to ACT: {stateMachine.CanTransitionTo(RobotStateType.ACT)}"); // true
Console.WriteLine($"Can go to Paused: {stateMachine.CanTransitionTo(RobotStateType.Paused)}"); // true
Console.WriteLine($"Can go to Manual: {stateMachine.CanTransitionTo(RobotStateType.Manual)}"); // true

// L?y event ?? chuy?n sang state ?ích
var evt = stateMachine.GetEventForTransition(RobotStateType.Manual);
Console.WriteLine($"Event to go to Manual: {evt}"); // EnterManual

4. Practical Use Cases

Use Case 1: Emergency Stop t? b?t k? sub-state nào

public class SafetyController
{
    private readonly RobotStateMachine _stateMachine;
    
    public async Task EmergencyStopAsync()
    {
        // Có th? g?i t? B?T K? sub-state nào c?a Auto
        // vì EnterStop ???c ??nh ngh?a ? Auto (parent)
        
        if (_stateMachine.CanFire(RobotEventType.EnterStop))
        {
            await _stateMachine.FireAsync(RobotEventType.EnterStop);
            Console.WriteLine("Emergency stop activated!");
        }
        else
        {
            Console.WriteLine("Cannot emergency stop from current state");
        }
    }
}

// G?i t? Navigation (deep sub-state)
// ? V?n ho?t ??ng vì Navigation k? th?a EnterStop t? Auto

Use Case 2: Fault Handling t? m?i n?i

public class ErrorHandler
{
    private readonly RobotStateMachine _stateMachine;
    
    public async Task HandleErrorAsync(Exception error)
    {
        // EnterFault ???c ??nh ngh?a ? Auto
        // Có th? g?i t? m?i sub-state c?a Auto
        
        Console.WriteLine($"Error occurred: {error.Message}");
        
        if (_stateMachine.IsSubStateOf(_stateMachine.CurrentState, RobotStateType.Auto))
        {
            // ?ang ? trong Auto hierarchy, có th? fire EnterFault
            await _stateMachine.FireAsync(RobotEventType.EnterFault);
        }
    }
}

Use Case 3: Dynamic UI buttons d?a trên available transitions

@* Blazor Component *@
@inject RobotStateMachine StateMachine

<div class="control-panel">
    <h3>Current State: @StateMachine.CurrentState</h3>
    
    <h4>Available Actions:</h4>
    @foreach (var transition in StateMachine.GetPossibleTransitions())
    {
        <button @onclick="() => FireEvent(transition.Event)">
            @transition.Event.ToString() ? @transition.ToState
        </button>
    }
</div>

@code {
    private async Task FireEvent(RobotEventType eventType)
    {
        await StateMachine.FireAsync(eventType);
        StateHasChanged();
    }
}

Khi ? Navigation state, UI s? hi?n th? T?T C? các buttons bao g?m:

  • StartAvoidance (riêng c?a Navigation)
  • StartACT (k? th?a t? Moving)
  • PauseExecution (k? th?a t? Executing)
  • CancelExecution (k? th?a t? Executing)
  • EnterManual (k? th?a t? Auto)
  • EnterService (k? th?a t? Auto)
  • EnterStop (k? th?a t? Auto)
  • EnterFault (k? th?a t? Auto)

5. Best Practices

? DO: ??nh ngh?a common events ? parent state

// Good: EnterFault ? Auto, t?t c? sub-states ??u có th? fault
builder.In(RobotStateType.Auto)
    .On(RobotEventType.EnterFault).Goto(RobotStateType.Fault);

? DON'T: L?p l?i events ? m?i sub-state

// Bad: Không c?n thi?t
builder.In(RobotStateType.Idle)
    .On(RobotEventType.EnterFault).Goto(RobotStateType.Fault);

builder.In(RobotStateType.Executing)
    .On(RobotEventType.EnterFault).Goto(RobotStateType.Fault);

builder.In(RobotStateType.Paused)
    .On(RobotEventType.EnterFault).Goto(RobotStateType.Fault);
// ... l?p l?i cho t?t c? sub-states

? DO: Ki?m tra inherited transitions tr??c khi hi?n th? UI

public List<RobotEventType> GetAvailableActionsForCurrentState()
{
    var transitions = _stateMachine.GetPossibleTransitions();
    return transitions.Select(t => t.Event).ToList();
}

T?ng k?t

  1. ? Sub-states T? ??NG k? th?a t?t c? events t? parent states
  2. ? Multi-level inheritance ho?t ??ng (Navigation k? th?a t? Moving ? Executing ? Auto)
  3. ? GetPossibleTransitions() ?ã ???c c?p nh?t ?? tr? v? c? inherited transitions
  4. ? CanFire(), CanTransitionTo(), GetEventForTransition() ??u h? tr? inheritance
  5. ? Helper methods m?i: GetParentState(), GetStateHierarchyChain(), IsSubStateOf()

?i?u này giúp code c?a b?n DRY (Don't Repeat Yourself) và d? maintain h?n!