Initial commit
This commit is contained in:
@@ -0,0 +1,888 @@
|
||||
# CONFIGURATION, WORKFLOWS & IMPLEMENTATION GUIDE
|
||||
|
||||
**Document:** Part 5 of Robot Tuning System Architecture
|
||||
**Coverage:** Default configurations, tuning workflows, implementation phases, and testing strategy
|
||||
|
||||
---
|
||||
|
||||
## DEFAULT CONFIGURATIONS
|
||||
|
||||
All default values with detailed justifications.
|
||||
|
||||
---
|
||||
|
||||
### 1. Robot Physical Configuration
|
||||
|
||||
```csharp
|
||||
public static class DefaultConfigurations
|
||||
{
|
||||
public static RobotPhysicalConfig Physical => new()
|
||||
{
|
||||
// Wheelbase: Distance between left and right wheels
|
||||
// Typical for small indoor robot: 0.3-0.5m
|
||||
// Affects: Turning radius, stability
|
||||
Wheelbase = 0.35f, // meters
|
||||
|
||||
// Wheel radius: Affects odometry calculations
|
||||
// Typical: 0.05-0.1m for small robots
|
||||
WheelRadius = 0.075f, // meters
|
||||
|
||||
// Max linear velocity: User-specified
|
||||
MaxLinearVelocity = 1.5f, // m/s
|
||||
|
||||
// Max angular velocity: Calculated from max linear velocity
|
||||
// ω_max ≈ 2 * v_max / wheelbase
|
||||
// Conservative estimate: 2 * 1.5 / 0.35 ≈ 8.57 rad/s
|
||||
// Use 6 rad/s for safety margin (~343°/s)
|
||||
MaxAngularVelocity = 6.0f, // rad/s
|
||||
|
||||
// Max linear acceleration: For smooth motion
|
||||
// 1.0 m/s² means 0 → 1.5 m/s in 1.5 seconds
|
||||
// Typical range: 0.5-2.0 m/s²
|
||||
MaxLinearAcceleration = 1.0f, // m/s²
|
||||
|
||||
// Max angular acceleration: User-specified
|
||||
MaxAngularAcceleration = 1.0f, // rad/s²
|
||||
|
||||
// Robot mass: Estimated for small mobile robot
|
||||
Mass = 25.0f // kg
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Control Timing Configuration
|
||||
|
||||
```csharp
|
||||
public static ControlTimingConfig Timing => new()
|
||||
{
|
||||
// Control loop frequency: 50Hz (20ms per cycle)
|
||||
// Justification:
|
||||
// - 10Hz: Too slow, robot will oscillate
|
||||
// - 50Hz: Optimal for indoor navigation (balance performance/CPU)
|
||||
// - 100Hz: Better but requires more CPU, marginal gains
|
||||
// - 200Hz+: Overkill for this application
|
||||
ControlLoopFrequency = 50, // Hz
|
||||
|
||||
// Encoder sampling: Match or exceed control frequency
|
||||
EncoderSamplingRate = 50, // Hz
|
||||
|
||||
// Motor command rate: Match control frequency
|
||||
MotorCommandRate = 50 // Hz
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. PID Controller Configuration
|
||||
|
||||
```csharp
|
||||
public static VelocityPIDConfig PID => new()
|
||||
{
|
||||
// Kp: Proportional gain
|
||||
// Higher Kp = faster response but more overshoot
|
||||
// Starting point: 0.8 (moderate response)
|
||||
// Tuning range: 0.1-5.0
|
||||
Kp = 0.8f,
|
||||
|
||||
// Ki: Integral gain
|
||||
// Eliminates steady-state error
|
||||
// Keep small to avoid windup
|
||||
// Starting point: 0.1
|
||||
// Tuning range: 0.0-2.0
|
||||
Ki = 0.1f,
|
||||
|
||||
// Kd: Derivative gain
|
||||
// Dampens oscillations, smooths response
|
||||
// Starting point: 0.05 (gentle damping)
|
||||
// Tuning range: 0.0-1.0
|
||||
Kd = 0.05f,
|
||||
|
||||
// Velocity limits
|
||||
MaxVelocity = 1.5f, // m/s (from physical config)
|
||||
MinVelocity = 0.1f, // m/s (minimum for robot to move)
|
||||
|
||||
// Anti-windup: Prevent integral term from growing unbounded
|
||||
IntegralWindupLimit = 0.5f, // m/s
|
||||
|
||||
// Output saturation: Ensure output stays within limits
|
||||
OutputSaturationEnabled = true
|
||||
};
|
||||
```
|
||||
|
||||
**PID Tuning Guidelines:**
|
||||
- Start with Kp only (Ki=0, Kd=0), increase until oscillation
|
||||
- Reduce Kp to 60% of oscillation value
|
||||
- Add Kd to dampen remaining oscillation
|
||||
- Add Ki last, only if steady-state error exists
|
||||
|
||||
---
|
||||
|
||||
### 4. Velocity Estimator Configuration
|
||||
|
||||
```csharp
|
||||
public static VelocityEstimatorConfig Estimator => new()
|
||||
{
|
||||
// Alpha filter: Exponential moving average for encoder
|
||||
// Lower α (0.1-0.2): More filtering, more lag
|
||||
// Higher α (0.3-0.4): Less filtering, more responsive
|
||||
// Recommended: 0.3 for balance
|
||||
AlphaFilter = 0.3f,
|
||||
|
||||
// Blend ratio bounds
|
||||
MinBlendRatio = 0.15f, // Min 15% model, 85% encoder
|
||||
MaxBlendRatio = 0.8f, // Max 80% model, 20% encoder
|
||||
DefaultBlendRatio = 0.6f, // Start with 60% model
|
||||
|
||||
// Adaptive blending thresholds
|
||||
GoodTrackingThreshold = 0.12f, // < 12% error
|
||||
ModerateTrackingThreshold = 0.3f, // < 30% error
|
||||
|
||||
// CORRECTED blend ratios (based on architecture review):
|
||||
// Good tracking → trust encoder more (model prediction matches reality)
|
||||
GoodTrackingBlend = 0.3f, // 30% model, 70% encoder
|
||||
|
||||
// Moderate tracking → balanced
|
||||
ModerateTrackingBlend = 0.5f, // 50-50 blend
|
||||
|
||||
// Poor tracking → trust model more (encoder may have slip)
|
||||
PoorTrackingBlend = 0.7f, // 70% model, 30% encoder
|
||||
|
||||
// Confidence decay: How fast confidence drops
|
||||
// 0.98 = slow decay (1% per cycle at 50Hz = ~2s to halve)
|
||||
// 0.95 = medium decay
|
||||
// 0.90 = fast decay
|
||||
ConfidenceDecayRate = 0.98f,
|
||||
|
||||
// Minimum confidence floor
|
||||
MinConfidence = 0.3f // Never go below 30%
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. Pure Pursuit Configuration
|
||||
|
||||
```csharp
|
||||
public static PurePursuitConfig PurePursuit => new()
|
||||
{
|
||||
// Lookahead minimum: Smallest lookahead distance
|
||||
// Too small: Oscillation, overshoot corners
|
||||
// Too large: Cuts corners, poor tracking
|
||||
// Recommended: 0.2-0.4m for indoor robot
|
||||
LookaheadMin = 0.3f, // meters
|
||||
|
||||
// Kdd: Lookahead velocity scaling factor
|
||||
// lookahead = LookaheadMin + Kdd * |velocity|
|
||||
// Kdd = 1.0 means 1 second lookahead time
|
||||
// Kdd = 0.5 means 0.5 second lookahead
|
||||
// Recommended: 0.8-1.5
|
||||
Kdd = 1.0f, // seconds
|
||||
|
||||
// Lookahead maximum: Cap lookahead distance
|
||||
// Prevents looking too far ahead at high speeds
|
||||
// Recommended: 1.5-3.0m
|
||||
LookaheadMax = 2.0f // meters
|
||||
};
|
||||
```
|
||||
|
||||
**Pure Pursuit Tuning Guidelines:**
|
||||
- Increase Kdd for smoother, more predictive tracking
|
||||
- Decrease Kdd for tighter, more reactive tracking
|
||||
- Increase LookaheadMin if robot oscillates
|
||||
- Decrease LookaheadMin if robot cuts corners
|
||||
|
||||
---
|
||||
|
||||
### 6. Path Following Configuration
|
||||
|
||||
```csharp
|
||||
public static PathFollowingConfig PathFollowing => new()
|
||||
{
|
||||
// Waypoint tolerance: How close to consider waypoint "reached"
|
||||
WaypointTolerance = 0.15f, // 15cm
|
||||
|
||||
// Final goal tolerance: Tighter tolerance for final goal
|
||||
FinalGoalTolerance = 0.05f, // 5cm
|
||||
|
||||
// Goal heading tolerance: Acceptable heading error at goal
|
||||
GoalHeadingTolerance = 5f * MathF.PI / 180f, // 5 degrees
|
||||
|
||||
// Stop distance: When to start preparing to stop
|
||||
StopDistance = 0.1f, // 10cm before goal
|
||||
|
||||
// Stop velocity: Threshold to consider robot "stopped"
|
||||
StopVelocity = 0.05f // 5cm/s
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 7. Safety Configuration
|
||||
|
||||
```csharp
|
||||
public static SafetyConfig Safety => new()
|
||||
{
|
||||
// Max cross-track error before abort
|
||||
// 0.5m is reasonable for 10x20m indoor space
|
||||
MaxCrossTrackError = 0.5f, // meters
|
||||
|
||||
// Max heading error before abort
|
||||
// 45° means robot is severely off course
|
||||
MaxHeadingError = 45f * MathF.PI / 180f, // radians
|
||||
|
||||
// Sustained error duration before abort
|
||||
// 3 seconds allows recovery from temporary issues
|
||||
MaxTrackingErrorDuration = 3000, // milliseconds
|
||||
|
||||
// Obstacle safety distances (for future sensors)
|
||||
MinObstacleDistance = 0.3f, // 30cm emergency stop
|
||||
SafetyStopDistance = 0.5f, // 50cm slow down
|
||||
|
||||
// Emergency deceleration limit
|
||||
EmergencyStopDeceleration = 2.0f // m/s²
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 8. Acceptance Criteria Configuration
|
||||
|
||||
```csharp
|
||||
public static AcceptanceCriteria Criteria => new()
|
||||
{
|
||||
// PRIMARY: Tracking Accuracy (50% weight)
|
||||
// Cross-track error RMS: 10cm is good for indoor robot
|
||||
MaxCrossTrackErrorRMS = 0.10f, // meters
|
||||
|
||||
// Peak CTE: Allow double RMS as occasional spike
|
||||
MaxCrossTrackErrorPeak = 0.20f, // meters
|
||||
|
||||
// Heading error: 10° RMS is acceptable
|
||||
MaxHeadingErrorRMS = 10f * MathF.PI / 180f, // radians
|
||||
|
||||
// Goal position error: 5cm final accuracy
|
||||
MaxGoalPositionError = 0.05f, // meters
|
||||
|
||||
// Goal heading error: 5° final accuracy
|
||||
MaxGoalHeadingError = 5f * MathF.PI / 180f, // radians
|
||||
|
||||
// SECONDARY: Smoothness (30% weight)
|
||||
// Max jerk: 5 m/s³ is smooth for human comfort
|
||||
MaxJerk = 5.0f, // m/s³
|
||||
|
||||
// Max angular jerk: 10 rad/s³
|
||||
MaxAngularJerk = 10.0f, // rad/s³
|
||||
|
||||
// TERTIARY: Efficiency (20% weight)
|
||||
// Path length ratio: <15% deviation from optimal
|
||||
MaxPathLengthRatio = 1.15f, // 115% of optimal
|
||||
|
||||
// Success rate: 90% of runs should pass
|
||||
MinSuccessRate = 0.90f // 90%
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 9. Scoring Weights
|
||||
|
||||
```csharp
|
||||
public static ScoringWeights Weights => new()
|
||||
{
|
||||
// How much each category contributes to overall score
|
||||
TrackingAccuracy = 0.5f, // 50%
|
||||
Smoothness = 0.3f, // 30%
|
||||
Efficiency = 0.2f // 20%
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 10. Parameter Bounds
|
||||
|
||||
```csharp
|
||||
public static class ParameterBounds
|
||||
{
|
||||
// PID bounds
|
||||
public static Range KpRange = new(0.1f, 5.0f);
|
||||
public static Range KiRange = new(0.0f, 2.0f);
|
||||
public static Range KdRange = new(0.0f, 1.0f);
|
||||
|
||||
// Estimator bounds
|
||||
public static Range AlphaFilterRange = new(0.05f, 0.5f);
|
||||
public static Range BlendRatioRange = new(0.1f, 0.9f);
|
||||
public static Range ConfidenceDecayRange = new(0.90f, 0.99f);
|
||||
|
||||
// Pure Pursuit bounds
|
||||
public static Range KddRange = new(0.3f, 2.0f);
|
||||
public static Range LookaheadMinRange = new(0.1f, 0.5f);
|
||||
public static Range LookaheadMaxRange = new(0.5f, 3.0f);
|
||||
|
||||
// Validation rules
|
||||
public static List<ValidationRule> Rules => new()
|
||||
{
|
||||
new ValidationRule
|
||||
{
|
||||
Name = "LookaheadOrdering",
|
||||
Check = (p) => p.PurePursuit.LookaheadMax > p.PurePursuit.LookaheadMin,
|
||||
Message = "LookaheadMax must be greater than LookaheadMin"
|
||||
},
|
||||
new ValidationRule
|
||||
{
|
||||
Name = "BlendRatioOrdering",
|
||||
Check = (p) => p.Estimator.GoodTrackingBlend <= p.Estimator.PoorTrackingBlend,
|
||||
Message = "GoodTrackingBlend should be less than PoorTrackingBlend"
|
||||
},
|
||||
new ValidationRule
|
||||
{
|
||||
Name = "VelocityLimit",
|
||||
Check = (p) => p.PID.MaxVelocity <= p.Physical.MaxLinearVelocity,
|
||||
Message = "PID MaxVelocity cannot exceed physical limit"
|
||||
}
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## TUNING WORKFLOWS
|
||||
|
||||
Detailed step-by-step workflows for different tuning scenarios.
|
||||
|
||||
---
|
||||
|
||||
### Workflow 1: Quick Start (First-Time User)
|
||||
|
||||
**Goal:** Get robot moving with default settings and validate basic functionality.
|
||||
|
||||
**Steps:**
|
||||
|
||||
1. **Load Default Configuration** (5 min)
|
||||
- Open dashboard
|
||||
- Navigate to Configuration → Robot Settings
|
||||
- Verify physical parameters (wheelbase, wheel radius)
|
||||
- Click "Load Default Preset"
|
||||
|
||||
2. **Run Baseline Test** (2 min)
|
||||
- Select Test Scenario: "Straight Line 10m"
|
||||
- Click "Run Test"
|
||||
- Observe real-time visualization
|
||||
- Wait for completion
|
||||
|
||||
3. **Review Results** (3 min)
|
||||
- Check overall score
|
||||
- Identify which metrics fail (if any)
|
||||
- Note: CTE RMS, jerk, smoothness
|
||||
|
||||
4. **Decision Point:**
|
||||
- Score > 80: Proceed to Workflow 2 (test other trajectories)
|
||||
- Score 60-80: Proceed to Workflow 3 (manual tuning)
|
||||
- Score < 60: Check robot hardware, retry
|
||||
|
||||
**Expected Outcome:** Baseline performance established, ready for tuning.
|
||||
|
||||
---
|
||||
|
||||
### Workflow 2: Multi-Scenario Validation
|
||||
|
||||
**Goal:** Test current configuration across all trajectory types.
|
||||
|
||||
**Steps:**
|
||||
|
||||
1. **Setup Batch Test** (2 min)
|
||||
- Navigate to Tuning → Parameter Comparison
|
||||
- Select all scenarios:
|
||||
- Straight Line 10m
|
||||
- Circle 2m Radius
|
||||
- Circle 0.5m Radius
|
||||
- Select current parameter set
|
||||
- Click "Run Batch"
|
||||
|
||||
2. **Monitor Progress** (10-15 min)
|
||||
- Watch each test in sequence
|
||||
- Note any failures or safety violations
|
||||
|
||||
3. **Analyze Comparison** (5 min)
|
||||
- View comparison table
|
||||
- Identify weakest scenario
|
||||
- Check metric breakdown per scenario
|
||||
|
||||
4. **Decision Point:**
|
||||
- All scenarios pass: Configuration is robust
|
||||
- One scenario fails: Tune for that specific case
|
||||
- Multiple scenarios fail: Need general tuning (Workflow 3)
|
||||
|
||||
---
|
||||
|
||||
### Workflow 3: Manual Iterative Tuning
|
||||
|
||||
**Goal:** Hand-tune parameters to improve specific metrics.
|
||||
|
||||
**Steps:**
|
||||
|
||||
**Phase 1: Improve Tracking Accuracy (if CTE RMS > 0.10m)**
|
||||
|
||||
1. **Diagnose Issue:**
|
||||
- View trajectory plot
|
||||
- Check if robot overshoots or undershoots corners
|
||||
- Check if error is consistent or oscillating
|
||||
|
||||
2. **If Robot Overshoots (cuts corners):**
|
||||
- Decrease Pure Pursuit LookaheadMin: 0.3 → 0.25
|
||||
- Decrease Kdd: 1.0 → 0.8
|
||||
- Run test, check improvement
|
||||
|
||||
3. **If Robot Undershoots (goes wide):**
|
||||
- Increase Pure Pursuit LookaheadMin: 0.3 → 0.35
|
||||
- Increase Kdd: 1.0 → 1.2
|
||||
- Run test, check improvement
|
||||
|
||||
4. **If Robot Oscillates:**
|
||||
- Increase PID Kd: 0.05 → 0.15 (more damping)
|
||||
- Increase Estimator AlphaFilter: 0.3 → 0.4 (more smoothing)
|
||||
- Run test, check improvement
|
||||
|
||||
5. **If Robot is Sluggish:**
|
||||
- Increase PID Kp: 0.8 → 1.2 (faster response)
|
||||
- Run test, check for overshoot
|
||||
|
||||
**Phase 2: Improve Smoothness (if Jerk > 5.0 m/s³)**
|
||||
|
||||
1. **Increase Damping:**
|
||||
- Increase PID Kd: current → +0.1
|
||||
- Run test
|
||||
|
||||
2. **Smooth Velocity Estimates:**
|
||||
- Decrease Estimator AlphaFilter: 0.3 → 0.2
|
||||
- Run test
|
||||
|
||||
3. **Reduce Aggressiveness:**
|
||||
- Decrease PID Kp: current → -0.2
|
||||
- Run test
|
||||
|
||||
**Phase 3: Verify and Save**
|
||||
|
||||
1. **Run Full Validation:**
|
||||
- Test all scenarios with new parameters
|
||||
- Ensure no regressions
|
||||
|
||||
2. **Save Configuration:**
|
||||
- Name: "Tuned_[Date]_v1"
|
||||
- Add description of changes
|
||||
- Click "Save"
|
||||
|
||||
**Iteration:** Repeat phases as needed, aiming for <5 iterations.
|
||||
|
||||
---
|
||||
|
||||
### Workflow 4: Automated Optimization (Advanced)
|
||||
|
||||
**Goal:** Use algorithm to find optimal parameters automatically.
|
||||
|
||||
**Steps:**
|
||||
|
||||
1. **Configure Optimization** (5 min)
|
||||
- Navigate to Tuning → Auto Tuning
|
||||
- Select algorithm: Bayesian Optimization
|
||||
- Select parameters to tune:
|
||||
- ☑ PID: Kp, Ki, Kd
|
||||
- ☑ Pure Pursuit: Kdd
|
||||
- ☐ Estimator: (keep fixed for first run)
|
||||
- Set constraints:
|
||||
- Max iterations: 30
|
||||
- Early stopping: 1% improvement threshold
|
||||
|
||||
2. **Define Objective** (2 min)
|
||||
- Primary metric: Cross-Track Error RMS
|
||||
- Secondary metric: Max Jerk (weight: 0.3)
|
||||
- Test scenario: Circle 2m Radius
|
||||
|
||||
3. **Start Optimization** (30-60 min)
|
||||
- Click "Start Optimization"
|
||||
- Monitor progress dashboard
|
||||
- View live updates of best parameters found
|
||||
|
||||
4. **Review Results** (10 min)
|
||||
- Check final parameters
|
||||
- Compare to baseline
|
||||
- Review improvement %
|
||||
|
||||
5. **Validate on Other Scenarios** (15 min)
|
||||
- Run batch test with optimized parameters
|
||||
- Ensure no regressions on other trajectories
|
||||
|
||||
6. **Save or Iterate:**
|
||||
- If satisfied: Save as "Optimized_v1"
|
||||
- If not: Adjust weights, re-run optimization
|
||||
|
||||
---
|
||||
|
||||
### Workflow 5: A/B Testing Configurations
|
||||
|
||||
**Goal:** Compare two parameter sets side-by-side.
|
||||
|
||||
**Steps:**
|
||||
|
||||
1. **Select Configurations** (2 min)
|
||||
- Config A: "Default"
|
||||
- Config B: "Tuned_v1"
|
||||
|
||||
2. **Choose Test Scenario** (1 min)
|
||||
- Straight Line 10m
|
||||
|
||||
3. **Run Comparison** (5 min)
|
||||
- Click "Run Comparison"
|
||||
- System runs both tests sequentially
|
||||
|
||||
4. **Analyze Results** (5 min)
|
||||
- View side-by-side metrics table
|
||||
- Check trajectory overlay plot
|
||||
- Identify winner
|
||||
|
||||
5. **Statistical Significance** (optional)
|
||||
- Run 10 trials each
|
||||
- Compare mean ± std deviation
|
||||
- Determine if difference is significant
|
||||
|
||||
---
|
||||
|
||||
## IMPLEMENTATION PHASES
|
||||
|
||||
Phased approach to building the system, prioritized by value and complexity.
|
||||
|
||||
---
|
||||
|
||||
### Phase 0: MVP (Weeks 1-3)
|
||||
|
||||
**Goal:** Core functionality for manual tuning.
|
||||
|
||||
**Features:**
|
||||
- ✅ Single test execution
|
||||
- ✅ Manual parameter adjustment UI
|
||||
- ✅ Real-time visualization (2D trajectory)
|
||||
- ✅ Basic metrics calculation
|
||||
- ✅ Save/load configurations
|
||||
- ✅ Data logging
|
||||
|
||||
**Deliverables:**
|
||||
1. Working Blazor dashboard
|
||||
2. Integrated controllers (PID, Estimator, Pure Pursuit)
|
||||
3. Basic test executor
|
||||
4. SQLite database with core tables
|
||||
5. Real-time SignalR updates
|
||||
|
||||
**Tech Stack:**
|
||||
- Blazor Server
|
||||
- Entity Framework Core + SQLite
|
||||
- SignalR
|
||||
- Plotly.NET for charts
|
||||
|
||||
**Testing:**
|
||||
- Unit tests for controllers
|
||||
- Integration test for one full test run
|
||||
- Manual UI testing
|
||||
|
||||
**Success Criteria:**
|
||||
- User can run a test and see results
|
||||
- Parameters can be adjusted and re-run
|
||||
- Metrics are calculated correctly
|
||||
|
||||
---
|
||||
|
||||
### Phase 1: Enhanced Tuning (Weeks 4-6)
|
||||
|
||||
**Goal:** Multi-scenario testing and comparison.
|
||||
|
||||
**Features:**
|
||||
- ✅ Batch testing
|
||||
- ✅ Configuration comparison
|
||||
- ✅ Test history viewer
|
||||
- ✅ Safety monitoring with abort
|
||||
- ✅ Parameter validation
|
||||
- ✅ CSV export
|
||||
|
||||
**Deliverables:**
|
||||
1. Batch test executor
|
||||
2. Comparison UI components
|
||||
3. Enhanced database queries
|
||||
4. Safety monitor implementation
|
||||
5. Report generation (HTML/CSV)
|
||||
|
||||
**Testing:**
|
||||
- Batch test with 3 scenarios
|
||||
- Comparison test with 3 configs
|
||||
- Safety violation test
|
||||
|
||||
**Success Criteria:**
|
||||
- Batch tests complete without manual intervention
|
||||
- Comparison clearly shows best configuration
|
||||
- Safety system aborts on violations
|
||||
|
||||
---
|
||||
|
||||
### Phase 2: Advanced Analytics (Weeks 7-9) - OPTIONAL
|
||||
|
||||
**Goal:** Deep insights and semi-automated tuning.
|
||||
|
||||
**Features:**
|
||||
- ⭕ Statistical analysis
|
||||
- ⭕ Trend analysis over time
|
||||
- ⭕ Parameter sensitivity analysis
|
||||
- ⭕ Tuning suggestions
|
||||
- ⭕ PDF report generation
|
||||
|
||||
**Deliverables:**
|
||||
1. Statistics calculator
|
||||
2. Trend visualization
|
||||
3. Suggestion engine (rule-based)
|
||||
4. PDF generator
|
||||
|
||||
**Testing:**
|
||||
- Historical data analysis (50+ tests)
|
||||
- Suggestion accuracy validation
|
||||
|
||||
**Success Criteria:**
|
||||
- Trends clearly visible
|
||||
- Suggestions improve results
|
||||
|
||||
---
|
||||
|
||||
### Phase 3: Automated Optimization (Weeks 10-13) - FUTURE
|
||||
|
||||
**Goal:** Hands-off parameter optimization.
|
||||
|
||||
**Features:**
|
||||
- ❌ Grid search
|
||||
- ❌ Random search
|
||||
- ❌ Bayesian optimization
|
||||
- ❌ Genetic algorithm
|
||||
- ❌ Multi-objective optimization
|
||||
|
||||
**Deliverables:**
|
||||
1. Optimization framework
|
||||
2. Multiple algorithm implementations
|
||||
3. Hyperparameter tuning for optimizers
|
||||
4. Parallel evaluation (if multiple robots)
|
||||
|
||||
**Complexity:** Very High (requires ML libraries)
|
||||
|
||||
**Testing:**
|
||||
- Benchmark against manual tuning
|
||||
- Convergence tests
|
||||
- Robustness tests
|
||||
|
||||
**Success Criteria:**
|
||||
- Automated optimization finds better params than manual in <1 hour
|
||||
- Reproducible results
|
||||
|
||||
---
|
||||
|
||||
## TESTING STRATEGY
|
||||
|
||||
Comprehensive testing at all levels.
|
||||
|
||||
---
|
||||
|
||||
### 1. Unit Tests
|
||||
|
||||
**Coverage Target:** >80% for domain logic
|
||||
|
||||
**Key Tests:**
|
||||
|
||||
```csharp
|
||||
// PID Controller Tests
|
||||
[Fact]
|
||||
public void PIDController_ProportionalOnly_CorrectOutput()
|
||||
{
|
||||
var config = new VelocityPIDConfig { Kp = 1.0f, Ki = 0, Kd = 0 };
|
||||
var pid = new PIDController(config);
|
||||
|
||||
var output = pid.Calculate(error: 1.0f, dt: 0.02f);
|
||||
|
||||
Assert.Equal(1.0f, output, precision: 2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PIDController_IntegralWindup_Clamped()
|
||||
{
|
||||
var config = new VelocityPIDConfig
|
||||
{
|
||||
Kp = 0,
|
||||
Ki = 1.0f,
|
||||
Kd = 0,
|
||||
IntegralWindupLimit = 0.5f
|
||||
};
|
||||
var pid = new PIDController(config);
|
||||
|
||||
// Accumulate large error
|
||||
for (int i = 0; i < 100; i++)
|
||||
pid.Calculate(error: 1.0f, dt: 0.02f);
|
||||
|
||||
var output = pid.Calculate(error: 1.0f, dt: 0.02f);
|
||||
|
||||
Assert.True(output <= 0.5f);
|
||||
}
|
||||
|
||||
// Velocity Estimator Tests
|
||||
[Fact]
|
||||
public void VelocityEstimator_GoodTracking_TrustsEncoder()
|
||||
{
|
||||
var config = DefaultConfigurations.Estimator;
|
||||
var estimator = new VelocityEstimator(config, new VelocitySignalProcessingConfig());
|
||||
|
||||
var vHybrid = estimator.EstimateVelocity(
|
||||
vCmd: 1.0f,
|
||||
vActual: 0.95f, // Close to command (good tracking)
|
||||
dt: 0.02f
|
||||
);
|
||||
|
||||
// Should blend more toward encoder (0.95) than model
|
||||
Assert.True(vHybrid > 0.93f && vHybrid < 0.97f);
|
||||
}
|
||||
|
||||
// Pure Pursuit Tests
|
||||
[Fact]
|
||||
public void PurePursuit_LookaheadScalesWithVelocity()
|
||||
{
|
||||
var config = new PurePursuitConfig
|
||||
{
|
||||
LookaheadMin = 0.3f,
|
||||
Kdd = 1.0f,
|
||||
LookaheadMax = 2.0f
|
||||
};
|
||||
var pp = new PurePursuitController(config);
|
||||
|
||||
var path = CreateStraightLinePath(10);
|
||||
var pose = new Pose2D(0, 0, 0);
|
||||
|
||||
pp.Calculate(pose, velocity: 0.5f, confidence: 1.0f, path);
|
||||
var lookahead1 = pp.GetLookaheadDistance();
|
||||
|
||||
pp.Calculate(pose, velocity: 1.0f, confidence: 1.0f, path);
|
||||
var lookahead2 = pp.GetLookaheadDistance();
|
||||
|
||||
Assert.True(lookahead2 > lookahead1);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Integration Tests
|
||||
|
||||
```csharp
|
||||
[Fact]
|
||||
public async Task FullTestRun_StraightLine_Completes()
|
||||
{
|
||||
// Arrange
|
||||
var scenario = CreateStraightLineScenario(10);
|
||||
var parameters = DefaultConfigurations.GetDefaultPreset();
|
||||
var orchestrator = CreateOrchestrator();
|
||||
|
||||
// Act
|
||||
var result = await orchestrator.RunSingleTest(scenario, parameters);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(TestStatus.Completed, result.Status);
|
||||
Assert.NotNull(result.Metrics);
|
||||
Assert.True(result.Metrics.CrossTrackErrorRMS < 0.20f);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SafetyMonitor_ExcessiveCTE_AbortsTest()
|
||||
{
|
||||
// Arrange
|
||||
var scenario = CreateCircleScenario(0.5f); // Tight circle
|
||||
var parameters = CreateBadParameters(); // Intentionally bad
|
||||
var orchestrator = CreateOrchestrator();
|
||||
|
||||
// Act
|
||||
var result = await orchestrator.RunSingleTest(scenario, parameters);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(TestStatus.Aborted, result.Status);
|
||||
Assert.True(result.SafetyViolations.Any(v => v.Type == ViolationType.CrossTrackError));
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Performance Tests
|
||||
|
||||
```csharp
|
||||
[Fact]
|
||||
public void ControlLoop_MaintainsFrequency()
|
||||
{
|
||||
var executor = CreateTestExecutor();
|
||||
var scenario = CreateStraightLineScenario(5);
|
||||
var parameters = DefaultConfigurations.GetDefaultPreset();
|
||||
|
||||
var timestamps = new List<long>();
|
||||
|
||||
executor.ExecuteAsync(
|
||||
onStateUpdate: state => timestamps.Add(state.TimestampMs)
|
||||
).Wait();
|
||||
|
||||
// Calculate actual frequency
|
||||
var intervals = timestamps.Zip(timestamps.Skip(1), (a, b) => b - a);
|
||||
var avgInterval = intervals.Average();
|
||||
var actualFrequency = 1000.0 / avgInterval;
|
||||
|
||||
Assert.InRange(actualFrequency, 48, 52); // 50Hz ± 2Hz
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. End-to-End Tests
|
||||
|
||||
**Manual Test Plan:**
|
||||
|
||||
1. **Happy Path Test**
|
||||
- Load default config
|
||||
- Run straight line test
|
||||
- Verify metrics displayed
|
||||
- Save configuration
|
||||
- Reload and verify
|
||||
|
||||
2. **Error Handling Test**
|
||||
- Set invalid parameter (Kp = 100)
|
||||
- Attempt to run test
|
||||
- Verify error message shown
|
||||
- Verify test doesn't start
|
||||
|
||||
3. **Real-time Update Test**
|
||||
- Start test
|
||||
- Verify UI updates at ~10Hz
|
||||
- Pause test
|
||||
- Verify pause works
|
||||
- Resume and complete
|
||||
|
||||
4. **Comparison Test**
|
||||
- Create 2 configs
|
||||
- Run comparison
|
||||
- Verify side-by-side display
|
||||
- Export results
|
||||
|
||||
---
|
||||
|
||||
## DEPLOYMENT CHECKLIST
|
||||
|
||||
Pre-deployment validation:
|
||||
|
||||
- [ ] All unit tests pass
|
||||
- [ ] Integration tests pass
|
||||
- [ ] Performance tests pass
|
||||
- [ ] Manual E2E tests completed
|
||||
- [ ] Database migrations created
|
||||
- [ ] Default data seeded
|
||||
- [ ] Configuration files reviewed
|
||||
- [ ] Robot hardware tested
|
||||
- [ ] Emergency stop tested
|
||||
- [ ] Documentation complete
|
||||
- [ ] User manual created
|
||||
|
||||
---
|
||||
|
||||
This completes the Configuration, Workflows & Implementation Guide.
|
||||
Reference in New Issue
Block a user