Initial commit
This commit is contained in:
@@ -0,0 +1,323 @@
|
||||
# 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
|
||||
|
||||
```csharp
|
||||
// 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:**
|
||||
|
||||
```csharp
|
||||
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
|
||||
|
||||
```csharp
|
||||
// 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:**
|
||||
|
||||
```csharp
|
||||
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
|
||||
|
||||
```csharp
|
||||
// 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
|
||||
|
||||
```csharp
|
||||
// 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
|
||||
|
||||
```csharp
|
||||
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
|
||||
|
||||
```csharp
|
||||
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
|
||||
|
||||
```razor
|
||||
@* 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
|
||||
|
||||
```csharp
|
||||
// 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
|
||||
|
||||
```csharp
|
||||
// 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
|
||||
|
||||
```csharp
|
||||
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!
|
||||
Reference in New Issue
Block a user