888 lines
24 KiB
Markdown
888 lines
24 KiB
Markdown
# 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. |