719 lines
41 KiB
Plaintext
719 lines
41 KiB
Plaintext
@using RobotNet10.NavigationTune.Shared.Models
|
||
@using MudBlazor
|
||
|
||
<MudCard Style="width: 100%; height: 400px; ">
|
||
<MudCardHeader Class="pb-0" Style="flex-shrink: 0; box-sizing: border-box;">
|
||
<CardHeaderContent>
|
||
<MudText Typo="Typo.h6">Parameter Configuration</MudText>
|
||
<MudStack Row="true" Spacing="2" AlignItems="AlignItems.Center">
|
||
<MudSelect T="Guid"
|
||
Label="Parameter Set"
|
||
Variant="Variant.Outlined"
|
||
Dense="true"
|
||
Margin="Margin.Dense"
|
||
Value="@ParameterSet.Id"
|
||
ValueChanged="@HandleParameterSetSelectionChanged"
|
||
Style="width: 50px;">
|
||
<MudSelectItem Value="@Guid.Empty">New Parameter Set</MudSelectItem>
|
||
@foreach (var paramSet in AvailableParameterSets)
|
||
{
|
||
<MudSelectItem Value="@paramSet.Id">@paramSet.Name</MudSelectItem>
|
||
}
|
||
</MudSelect>
|
||
<MudSelect T="PathFollowingController" @bind-Value="@ParameterSet.ControllerType"
|
||
Label="Controller Type"
|
||
Variant="Variant.Outlined"
|
||
Dense="true"
|
||
Margin="Margin.Dense"
|
||
Style="min-width: 140px;">
|
||
<MudSelectItem T="PathFollowingController" Value="@PathFollowingController.PurePursuit">Pure Pursuit</MudSelectItem>
|
||
<MudSelectItem T="PathFollowingController" Value="@PathFollowingController.Stanley">Stanley</MudSelectItem>
|
||
</MudSelect>
|
||
</MudStack>
|
||
</CardHeaderContent>
|
||
<CardHeaderActions>
|
||
<div class="aligns-item-center mt-2">
|
||
<MudButton Variant="Variant.Filled" Color="Color.Primary" Size="Size.Small" OnClick="OnSave">Save</MudButton>
|
||
<MudButton Variant="Variant.Text" Size="Size.Small" OnClick="OnReset">Reset</MudButton>
|
||
</div>
|
||
</CardHeaderActions>
|
||
</MudCardHeader>
|
||
<MudCardContent Class="pt-0" Style="flex: 1; overflow: hidden; box-sizing: border-box;">
|
||
<MudTabs Elevation="0">
|
||
<MudTabPanel Text="PID Controllers">
|
||
<MudGrid Spacing="1" Style="overflow-y:auto; height: 200px">
|
||
<MudItem xs="12">
|
||
<MudText Typo="Typo.h6" Class="mb-1">Move PID</MudText>
|
||
<MudGrid>
|
||
<MudItem xs="12" sm="4">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.MovePidConfig.Kp"
|
||
Label="Kp"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="100"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
<MudItem xs="12" sm="4">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.MovePidConfig.Ki"
|
||
Label="Ki"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="1"
|
||
Step="0.0001"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
<MudItem xs="12" sm="4">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.MovePidConfig.Kd"
|
||
Label="Kd"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="10"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
</MudGrid>
|
||
</MudItem>
|
||
<MudItem xs="12">
|
||
<MudText Typo="Typo.h6" Class="mb-1">Rotate PID</MudText>
|
||
<MudGrid>
|
||
<MudItem xs="12" sm="4">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.RotatePidConfig.Kp"
|
||
Label="Kp"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="100"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
<MudItem xs="12" sm="4">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.RotatePidConfig.Ki"
|
||
Label="Ki"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="1"
|
||
Step="0.001"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
<MudItem xs="12" sm="4">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.RotatePidConfig.Kd"
|
||
Label="Kd"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="10"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
</MudGrid>
|
||
</MudItem>
|
||
</MudGrid>
|
||
</MudTabPanel>
|
||
|
||
<MudTabPanel Text="Pure Pursuit">
|
||
<MudGrid Spacing="1" Class="mt-1" Style="overflow-y:auto; height: 200px">
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.PurePursuitConfig.LookaheadMin"
|
||
Label="Lookahead Min (m)"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="5.0"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.PurePursuitConfig.LookaheadMax"
|
||
Label="Lookahead Max (m)"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="10.0"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.PurePursuitConfig.Kdd"
|
||
Label="Kdd"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="5.0"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.PurePursuitConfig.MaxAngularVelocity"
|
||
Label="Max Angular Velocity (rad/s)"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="10.0"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.PurePursuitConfig.ResolutionSplit"
|
||
Label="Resolution Split (m)"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="0.5"
|
||
Margin="Margin.Dense" />
|
||
<MudText Typo="Typo.caption" Color="Color.Secondary">
|
||
Distance between interpolated points
|
||
</MudText>
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.PurePursuitConfig.FinalApproachThreshold"
|
||
Label="Final Approach Threshold (m)"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="1.0"
|
||
Margin="Margin.Dense" />
|
||
<MudText Typo="Typo.caption" Color="Color.Secondary">
|
||
Distance to goal to switch to final approach controller
|
||
</MudText>
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.PurePursuitConfig.HeadingTolerance"
|
||
Label="Heading Tolerance (deg)"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="15.0"
|
||
Margin="Margin.Dense" />
|
||
<MudText Typo="Typo.caption" Color="Color.Secondary">
|
||
Heading accuracy for goal reached
|
||
</MudText>
|
||
</MudItem>
|
||
<MudText Typo="Typo.subtitle2" Class="mt-2 mb-1">Adaptive lookahead</MudText>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.PurePursuitConfig.GoalRegionDistance"
|
||
Label="Goal Region Distance (m)"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="5.0"
|
||
Margin="Margin.Dense" />
|
||
<MudText Typo="Typo.caption" Color="Color.Secondary">
|
||
Start reducing lookahead at this distance from goal
|
||
</MudText>
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.PurePursuitConfig.KCurvature"
|
||
Label="K Curvature"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="5.0"
|
||
Margin="Margin.Dense" />
|
||
<MudText Typo="Typo.caption" Color="Color.Secondary">
|
||
Curvature sensitivity (higher = more reduction on curves)
|
||
</MudText>
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.PurePursuitConfig.MinLookaheadTimeRatio"
|
||
Label="Min Lookahead Time Ratio"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="1.0"
|
||
Margin="Margin.Dense" />
|
||
<MudText Typo="Typo.caption" Color="Color.Secondary">
|
||
Min lookahead = velocity × this ratio (s)
|
||
</MudText>
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.PurePursuitConfig.MaxLookaheadTimeRatio"
|
||
Label="Max Lookahead Time Ratio"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="5.0"
|
||
Margin="Margin.Dense" />
|
||
<MudText Typo="Typo.caption" Color="Color.Secondary">
|
||
Max lookahead = velocity × this ratio (s)
|
||
</MudText>
|
||
</MudItem>
|
||
</MudGrid>
|
||
</MudTabPanel>
|
||
|
||
<MudTabPanel Text="Velocity Estimator">
|
||
<MudGrid Spacing="1" Class="mt-1" Style="height: 200px; overflow-y:auto">
|
||
<MudItem xs="12">
|
||
<MudText Typo="Typo.subtitle2" Class="mb-2">Blend Ratios</MudText>
|
||
<MudGrid>
|
||
<MudItem xs="12" sm="4">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.EstimatorConfig.MinBlendRatio"
|
||
Label="Min Blend"
|
||
Variant="Variant.Outlined"
|
||
Min="0.0"
|
||
Max="1.0"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
<MudItem xs="12" sm="4">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.EstimatorConfig.MaxBlendRatio"
|
||
Label="Max Blend"
|
||
Variant="Variant.Outlined"
|
||
Min="0.0"
|
||
Max="1.0"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
<MudItem xs="12" sm="4">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.EstimatorConfig.DefaultBlendRatio"
|
||
Label="Default Blend"
|
||
Variant="Variant.Outlined"
|
||
Min="0.0"
|
||
Max="1.0"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
</MudGrid>
|
||
</MudItem>
|
||
<MudItem xs="12">
|
||
<MudText Typo="Typo.subtitle2" Class="mb-2">Tracking Thresholds</MudText>
|
||
<MudGrid>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.EstimatorConfig.GoodTrackingThreshold"
|
||
Label="Good Threshold (m)"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="1.0"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.EstimatorConfig.ModerateTrackingThreshold"
|
||
Label="Moderate Threshold (m)"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="2.0"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
</MudGrid>
|
||
</MudItem>
|
||
<MudItem xs="12">
|
||
<MudText Typo="Typo.subtitle2" Class="mb-2">Tracking Blend Ratios</MudText>
|
||
<MudGrid>
|
||
<MudItem xs="12" sm="4">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.EstimatorConfig.GoodTrackingBlend"
|
||
Label="Good Tracking Blend"
|
||
Variant="Variant.Outlined"
|
||
Min="0.0"
|
||
Max="1.0"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
<MudItem xs="12" sm="4">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.EstimatorConfig.ModerateTrackingBlend"
|
||
Label="Moderate Tracking Blend"
|
||
Variant="Variant.Outlined"
|
||
Min="0.0"
|
||
Max="1.0"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
<MudItem xs="12" sm="4">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.EstimatorConfig.PoorTrackingBlend"
|
||
Label="Poor Tracking Blend"
|
||
Variant="Variant.Outlined"
|
||
Min="0.0"
|
||
Max="1.0"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
</MudGrid>
|
||
</MudItem>
|
||
<MudItem xs="12">
|
||
<MudText Typo="Typo.subtitle2" Class="mb-2">Confidence Settings</MudText>
|
||
<MudGrid>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.EstimatorConfig.ConfidenceDecayRate"
|
||
Label="Confidence Decay Rate"
|
||
Variant="Variant.Outlined"
|
||
Min="0.0"
|
||
Max="1.0"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.EstimatorConfig.MinConfidence"
|
||
Label="Min Confidence"
|
||
Variant="Variant.Outlined"
|
||
Min="0.0"
|
||
Max="1.0"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
</MudGrid>
|
||
</MudItem>
|
||
<MudItem xs="12">
|
||
<MudText Typo="Typo.subtitle2" Class="mb-2">Signal Processing</MudText>
|
||
<MudGrid>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.SignalConfig.AlphaFilter"
|
||
Label="Alpha Filter"
|
||
Variant="Variant.Outlined"
|
||
Min="0.0"
|
||
Max="1.0"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.SignalConfig.NoiseThreshold"
|
||
Label="Noise Threshold"
|
||
Variant="Variant.Outlined"
|
||
Min="0.0"
|
||
Max="5.0"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
</MudGrid>
|
||
</MudItem>
|
||
</MudGrid>
|
||
</MudTabPanel>
|
||
|
||
<MudTabPanel Text="Motor Dynamics">
|
||
<MudGrid Spacing="1" Class="mt-1" Style="overflow-y:auto; height: 200px">
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.MotorDynamicsConfig.Tau"
|
||
Label="Time Constant τ (s)"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="2.0"
|
||
Margin="Margin.Dense" />
|
||
<MudText Typo="Typo.caption" Color="Color.Secondary">
|
||
Time to reach 63.2% of target velocity
|
||
</MudText>
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.MotorDynamicsConfig.Delta"
|
||
Label="Pure Delay δ (s)"
|
||
Variant="Variant.Outlined"
|
||
Min="0.0"
|
||
Max="0.5"
|
||
Margin="Margin.Dense" />
|
||
<MudText Typo="Typo.caption" Color="Color.Secondary">
|
||
Delay before motor starts responding
|
||
</MudText>
|
||
</MudItem>
|
||
</MudGrid>
|
||
</MudTabPanel>
|
||
|
||
<MudTabPanel Text="Navigation Limits">
|
||
<MudGrid Spacing="1" Class="mt-1" Style="overflow-y:auto; height: 200px">
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.NavigationConfig.MaxLinearVelocity"
|
||
Label="Max Linear Velocity (m/s)"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="5.0"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.NavigationConfig.MinLinearVelocity"
|
||
Label="Min Linear Velocity (m/s)"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="1.0"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.NavigationConfig.MaxAngularVelocity"
|
||
Label="Max Angular Velocity (rad/s)"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="10.0"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.NavigationConfig.RotateAngularVelocity"
|
||
Label="Rotate Angular Velocity (rad/s)"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="5.0"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.NavigationConfig.ReachedRadius"
|
||
Label="Reached Radius (m)"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="0.5"
|
||
Step="0.001"
|
||
Margin="Margin.Dense" />
|
||
<MudText Typo="Typo.caption" Color="Color.Secondary">
|
||
Goal reached tolerance
|
||
</MudText>
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.NavigationConfig.InitialRotationThreshold"
|
||
Label="Initial Rotation Threshold (deg)"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="90.0"
|
||
Margin="Margin.Dense" />
|
||
<MudText Typo="Typo.caption" Color="Color.Secondary">
|
||
Min heading error to rotate in place before moving
|
||
</MudText>
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.NavigationConfig.Acceleration"
|
||
Label="Acceleration (m/s²)"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="5.0"
|
||
Step="0.1"
|
||
Margin="Margin.Dense" />
|
||
<MudText Typo="Typo.caption" Color="Color.Secondary">
|
||
How quickly the robot is allowed to reach target linear speed
|
||
</MudText>
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.NavigationConfig.Deceleration"
|
||
Label="Deceleration (m/s²)"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="5.0"
|
||
Step="0.1"
|
||
Margin="Margin.Dense" />
|
||
<MudText Typo="Typo.caption" Color="Color.Secondary">
|
||
How quickly the robot is allowed to slow down / stop
|
||
</MudText>
|
||
</MudItem>
|
||
</MudGrid>
|
||
</MudTabPanel>
|
||
|
||
<MudTabPanel Text="Stanley">
|
||
<MudGrid Spacing="1" Class="mt-1" Style="overflow-y:auto; height: 200px">
|
||
<MudItem xs="12">
|
||
<MudText Typo="Typo.caption" Color="Color.Secondary">Chỉ áp dụng khi Controller Type = Stanley</MudText>
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.StanleyConfig.K"
|
||
Label="K (cross-track gain)"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="10.0"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.StanleyConfig.Ks"
|
||
Label="Ks (softening, m/s)"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="1.0"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.StanleyConfig.WheelBase"
|
||
Label="Wheelbase (m)"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="3.0"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.StanleyConfig.MaxSteeringAngle"
|
||
Label="Max Steering Angle (rad)"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="1.5"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudSwitch T="bool" @bind-Value="@ParameterSet.StanleyConfig.EnableCurvatureFeedforward"
|
||
Label="Curvature feedforward"
|
||
Color="Color.Primary" />
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.StanleyConfig.KCurvatureFF"
|
||
Label="K Curvature FF"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="2.0"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.StanleyConfig.GoalTolerance"
|
||
Label="Goal Tolerance (m)"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="0.2"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.StanleyConfig.HeadingTolerance"
|
||
Label="Heading Tolerance (deg)"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="30.0"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.StanleyConfig.ResolutionSplit"
|
||
Label="Resolution Split (m)"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="0.2"
|
||
Margin="Margin.Dense" />
|
||
</MudItem>
|
||
<MudText Typo="Typo.subtitle2" Class="mt-2 mb-1">Goal approach</MudText>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.StanleyConfig.GoalApproachDistance"
|
||
Label="Goal Approach Distance (m)"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="5.0"
|
||
Margin="Margin.Dense" />
|
||
<MudText Typo="Typo.caption" Color="Color.Secondary">Distance to start increasing K near goal</MudText>
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.StanleyConfig.GoalGainMultiplier"
|
||
Label="Goal Gain Multiplier"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="5.0"
|
||
Margin="Margin.Dense" />
|
||
<MudText Typo="Typo.caption" Color="Color.Secondary">K multiplier at goal</MudText>
|
||
</MudItem>
|
||
<MudText Typo="Typo.subtitle2" Class="mt-2 mb-1">Low speed control</MudText>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.StanleyConfig.LowSpeedThreshold"
|
||
Label="Low Speed Threshold (m/s)"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="2.0"
|
||
Margin="Margin.Dense" />
|
||
<MudText Typo="Typo.caption" Color="Color.Secondary">Below this speed, direct angular control blends in</MudText>
|
||
</MudItem>
|
||
<MudItem xs="12" sm="6">
|
||
<MudNumericField T="double" @bind-Value="@ParameterSet.StanleyConfig.LowSpeedAngularGain"
|
||
Label="Low Speed Angular Gain"
|
||
Variant="Variant.Outlined"
|
||
Min="0"
|
||
Max="5.0"
|
||
Margin="Margin.Dense" />
|
||
<MudText Typo="Typo.caption" Color="Color.Secondary">Angular gain at low speed</MudText>
|
||
</MudItem>
|
||
</MudGrid>
|
||
</MudTabPanel>
|
||
</MudTabs>
|
||
</MudCardContent>
|
||
</MudCard>
|
||
|
||
@code {
|
||
[Parameter] public NavigationParameterSet ParameterSet { get; set; } = new();
|
||
[Parameter] public List<NavigationParameterSet> AvailableParameterSets { get; set; } = new();
|
||
[Parameter] public EventCallback<NavigationParameterSet> OnSaveClicked { get; set; }
|
||
[Parameter] public EventCallback OnResetClicked { get; set; }
|
||
[Parameter] public EventCallback<NavigationParameterSet> OnParameterSetChanged { get; set; }
|
||
|
||
private NavigationParameterSet _originalParameterSet = new();
|
||
|
||
protected override void OnParametersSet()
|
||
{
|
||
if (ParameterSet != null)
|
||
{
|
||
_originalParameterSet = CloneParameterSet(ParameterSet);
|
||
}
|
||
}
|
||
|
||
private async Task HandleParameterSetSelectionChanged(Guid parameterSetId)
|
||
{
|
||
if (parameterSetId == Guid.Empty)
|
||
{
|
||
// New parameter set
|
||
var newSet = new NavigationParameterSet
|
||
{
|
||
Id = Guid.Empty,
|
||
Name = $"Parameter Set {DateTime.Now:yyyyMMdd_HHmmss}",
|
||
Description = "",
|
||
CreatedAt = DateTime.UtcNow
|
||
};
|
||
await OnParameterSetChanged.InvokeAsync(newSet);
|
||
}
|
||
else
|
||
{
|
||
// Load existing parameter set
|
||
var selected = AvailableParameterSets.FirstOrDefault(p => p.Id == parameterSetId);
|
||
if (selected != null)
|
||
{
|
||
await OnParameterSetChanged.InvokeAsync(selected);
|
||
}
|
||
}
|
||
}
|
||
|
||
private void OnSave()
|
||
{
|
||
OnSaveClicked.InvokeAsync(ParameterSet);
|
||
}
|
||
|
||
private void OnReset()
|
||
{
|
||
ParameterSet = CloneParameterSet(_originalParameterSet);
|
||
OnResetClicked.InvokeAsync();
|
||
}
|
||
|
||
private NavigationParameterSet CloneParameterSet(NavigationParameterSet source)
|
||
{
|
||
// Simple clone - in production, use proper deep cloning
|
||
return new NavigationParameterSet
|
||
{
|
||
Id = source.Id,
|
||
Name = source.Name,
|
||
Description = source.Description,
|
||
ControllerType = source.ControllerType,
|
||
MovePidConfig = new PIDConfig
|
||
{
|
||
Kp = source.MovePidConfig.Kp,
|
||
Ki = source.MovePidConfig.Ki,
|
||
Kd = source.MovePidConfig.Kd
|
||
},
|
||
RotatePidConfig = new PIDConfig
|
||
{
|
||
Kp = source.RotatePidConfig.Kp,
|
||
Ki = source.RotatePidConfig.Ki,
|
||
Kd = source.RotatePidConfig.Kd
|
||
},
|
||
PurePursuitConfig = new PurePursuitConfig
|
||
{
|
||
LookaheadMin = source.PurePursuitConfig.LookaheadMin,
|
||
LookaheadMax = source.PurePursuitConfig.LookaheadMax,
|
||
Kdd = source.PurePursuitConfig.Kdd,
|
||
MaxAngularVelocity = source.PurePursuitConfig.MaxAngularVelocity,
|
||
ResolutionSplit = source.PurePursuitConfig.ResolutionSplit,
|
||
FinalApproachThreshold = source.PurePursuitConfig.FinalApproachThreshold,
|
||
HeadingTolerance = source.PurePursuitConfig.HeadingTolerance,
|
||
GoalRegionDistance = source.PurePursuitConfig.GoalRegionDistance,
|
||
KCurvature = source.PurePursuitConfig.KCurvature,
|
||
MinLookaheadTimeRatio = source.PurePursuitConfig.MinLookaheadTimeRatio,
|
||
MaxLookaheadTimeRatio = source.PurePursuitConfig.MaxLookaheadTimeRatio
|
||
},
|
||
StanleyConfig = new StanleyConfig
|
||
{
|
||
K = source.StanleyConfig.K,
|
||
Ks = source.StanleyConfig.Ks,
|
||
WheelBase = source.StanleyConfig.WheelBase,
|
||
MaxSteeringAngle = source.StanleyConfig.MaxSteeringAngle,
|
||
EnableCurvatureFeedforward = source.StanleyConfig.EnableCurvatureFeedforward,
|
||
KCurvatureFF = source.StanleyConfig.KCurvatureFF,
|
||
GoalTolerance = source.StanleyConfig.GoalTolerance,
|
||
HeadingTolerance = source.StanleyConfig.HeadingTolerance,
|
||
ResolutionSplit = source.StanleyConfig.ResolutionSplit,
|
||
GoalApproachDistance = source.StanleyConfig.GoalApproachDistance,
|
||
GoalGainMultiplier = source.StanleyConfig.GoalGainMultiplier,
|
||
LowSpeedThreshold = source.StanleyConfig.LowSpeedThreshold,
|
||
LowSpeedAngularGain = source.StanleyConfig.LowSpeedAngularGain
|
||
},
|
||
EstimatorConfig = new VelocityEstimatorConfig
|
||
{
|
||
MinBlendRatio = source.EstimatorConfig.MinBlendRatio,
|
||
MaxBlendRatio = source.EstimatorConfig.MaxBlendRatio,
|
||
DefaultBlendRatio = source.EstimatorConfig.DefaultBlendRatio,
|
||
GoodTrackingThreshold = source.EstimatorConfig.GoodTrackingThreshold,
|
||
ModerateTrackingThreshold = source.EstimatorConfig.ModerateTrackingThreshold,
|
||
GoodTrackingBlend = source.EstimatorConfig.GoodTrackingBlend,
|
||
ModerateTrackingBlend = source.EstimatorConfig.ModerateTrackingBlend,
|
||
PoorTrackingBlend = source.EstimatorConfig.PoorTrackingBlend,
|
||
ConfidenceDecayRate = source.EstimatorConfig.ConfidenceDecayRate,
|
||
MinConfidence = source.EstimatorConfig.MinConfidence
|
||
},
|
||
SignalConfig = new VelocitySignalProcessingConfig
|
||
{
|
||
AlphaFilter = source.SignalConfig.AlphaFilter,
|
||
NoiseThreshold = source.SignalConfig.NoiseThreshold
|
||
},
|
||
MotorDynamicsConfig = new MotorDynamicsConfig
|
||
{
|
||
Tau = source.MotorDynamicsConfig.Tau,
|
||
Delta = source.MotorDynamicsConfig.Delta
|
||
},
|
||
NavigationConfig = new NavigationConfig
|
||
{
|
||
MaxLinearVelocity = source.NavigationConfig.MaxLinearVelocity,
|
||
MinLinearVelocity = source.NavigationConfig.MinLinearVelocity,
|
||
MaxAngularVelocity = source.NavigationConfig.MaxAngularVelocity,
|
||
RotateAngularVelocity = source.NavigationConfig.RotateAngularVelocity,
|
||
ReachedRadius = source.NavigationConfig.ReachedRadius,
|
||
InitialRotationThreshold = source.NavigationConfig.InitialRotationThreshold,
|
||
Acceleration = source.NavigationConfig.Acceleration,
|
||
Deceleration = source.NavigationConfig.Deceleration
|
||
}
|
||
};
|
||
}
|
||
}
|