Initial commit
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
@using RobotNet10.RobotApp.Client.Clients
|
||||
@using RobotNet10.RobotApp.Client.Shared.Modules
|
||||
@using MudBlazor
|
||||
|
||||
<MudPaper Class="pa-4" Style="height: 100%;">
|
||||
<MudStack Spacing="3">
|
||||
<MudStack Row="true" Justify="Justify.SpaceBetween" AlignItems="AlignItems.Center">
|
||||
<MudText Typo="Typo.h5">Rotation Module</MudText>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Refresh"
|
||||
Color="Color.Primary"
|
||||
Size="Size.Small"
|
||||
OnClick="RefreshStatus"
|
||||
Disabled="@(!IsHubReady || isLoading)" />
|
||||
</MudStack>
|
||||
|
||||
@* Rotation Status Information *@
|
||||
@if (rotationStatus != null)
|
||||
{
|
||||
<MudCard>
|
||||
<MudCardContent>
|
||||
<MudText Typo="Typo.h6" Class="mb-3">Module Status</MudText>
|
||||
<MudStack Spacing="2">
|
||||
<MudStack Row="true" Justify="Justify.SpaceBetween">
|
||||
<MudText>State:</MudText>
|
||||
<MudChip T="string" Color="@GetStateColor(rotationStatus.State)" Size="Size.Small">
|
||||
@rotationStatus.State
|
||||
</MudChip>
|
||||
</MudStack>
|
||||
<MudStack Row="true" Justify="Justify.SpaceBetween">
|
||||
<MudText>Ready:</MudText>
|
||||
<MudChip T="bool" Color="@(rotationStatus.IsReady ? Color.Success : Color.Default)" Size="Size.Small">
|
||||
@rotationStatus.IsReady
|
||||
</MudChip>
|
||||
</MudStack>
|
||||
<MudStack Row="true" Justify="Justify.SpaceBetween">
|
||||
<MudText>Current Angle:</MudText>
|
||||
<MudText>@($"{rotationStatus.CurrentAngle:F2}°")</MudText>
|
||||
</MudStack>
|
||||
</MudStack>
|
||||
</MudCardContent>
|
||||
</MudCard>
|
||||
}
|
||||
|
||||
@* Rotation Control Buttons *@
|
||||
<MudStack Spacing="3">
|
||||
<MudText Typo="Typo.h6">Rotation Controls</MudText>
|
||||
|
||||
@* Rotate to Absolute Angle *@
|
||||
<MudStack Row="true" Spacing="3" AlignItems="@AlignItems.Center">
|
||||
<MudNumericField @bind-Value="targetAngle"
|
||||
Label="Target Angle (°)"
|
||||
Variant="Variant.Outlined"
|
||||
Class="flex-grow-1" />
|
||||
<MudButton Variant="Variant.Filled"
|
||||
Color="Color.Primary"
|
||||
OnClick="RotateToAngle"
|
||||
Disabled="@(isLoading || !IsHubReady || rotationStatus?.IsReady != true)">
|
||||
<MudIcon Icon="@Icons.Material.Filled.LocationOn" Class="mr-2" />
|
||||
<MudText>Go</MudText>
|
||||
</MudButton>
|
||||
</MudStack>
|
||||
|
||||
@* Rotate Offset *@
|
||||
<MudStack Row="true" Spacing="3" AlignItems="@AlignItems.Center">
|
||||
<MudNumericField @bind-Value="angleOffset"
|
||||
Label="Offset (°)"
|
||||
Variant="Variant.Outlined"
|
||||
HelperText="+/- for CW/CCW"
|
||||
Class="flex-grow-1" />
|
||||
<MudButton Variant="Variant.Filled"
|
||||
Color="Color.Info"
|
||||
OnClick="RotateOffset"
|
||||
Disabled="@(isLoading || !IsHubReady || rotationStatus?.IsReady != true)">
|
||||
<MudIcon Icon="@Icons.Material.Filled.RotateRight" Class="mr-2" />
|
||||
<MudText>Offset</MudText>
|
||||
</MudButton>
|
||||
</MudStack>
|
||||
|
||||
@* Quick Rotation Buttons *@
|
||||
<MudStack Row="true" Spacing="3" AlignItems="@AlignItems.Center" Wrap="Wrap.Wrap">
|
||||
<MudButton Variant="Variant.Outlined"
|
||||
Color="Color.Secondary"
|
||||
OnClick="() => RotateOffsetQuick(-90)"
|
||||
Disabled="@(isLoading || !IsHubReady || rotationStatus?.IsReady != true)">
|
||||
<MudIcon Icon="@Icons.Material.Filled.RotateLeft" Class="mr-2" />
|
||||
<MudText>-90°</MudText>
|
||||
</MudButton>
|
||||
|
||||
<MudButton Variant="Variant.Outlined"
|
||||
Color="Color.Secondary"
|
||||
OnClick="() => RotateOffsetQuick(-45)"
|
||||
Disabled="@(isLoading || !IsHubReady || rotationStatus?.IsReady != true)">
|
||||
<MudIcon Icon="@Icons.Material.Filled.RotateLeft" Class="mr-2" />
|
||||
<MudText>-45°</MudText>
|
||||
</MudButton>
|
||||
|
||||
<MudButton Variant="Variant.Outlined"
|
||||
Color="Color.Secondary"
|
||||
OnClick="() => RotateOffsetQuick(45)"
|
||||
Disabled="@(isLoading || !IsHubReady || rotationStatus?.IsReady != true)">
|
||||
<MudIcon Icon="@Icons.Material.Filled.RotateRight" Class="mr-2" />
|
||||
<MudText>+45°</MudText>
|
||||
</MudButton>
|
||||
|
||||
<MudButton Variant="Variant.Outlined"
|
||||
Color="Color.Secondary"
|
||||
OnClick="() => RotateOffsetQuick(90)"
|
||||
Disabled="@(isLoading || !IsHubReady || rotationStatus?.IsReady != true)">
|
||||
<MudIcon Icon="@Icons.Material.Filled.RotateRight" Class="mr-2" />
|
||||
<MudText>+90°</MudText>
|
||||
</MudButton>
|
||||
</MudStack>
|
||||
</MudStack>
|
||||
</MudStack>
|
||||
</MudPaper>
|
||||
|
||||
@code {
|
||||
[Parameter, EditorRequired] public MotionHubClient HubClient { get; set; } = null!;
|
||||
[Parameter] public bool IsHubReady { get; set; }
|
||||
[Inject] private ISnackbar Snackbar { get; set; } = null!;
|
||||
|
||||
private RotationModuleStatusDto? rotationStatus;
|
||||
private bool isLoading = false;
|
||||
private double targetAngle = 0;
|
||||
private double angleOffset = 0;
|
||||
private bool _previousIsHubReady = false;
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
// Detect when IsHubReady changes from false to true
|
||||
if (IsHubReady && !_previousIsHubReady)
|
||||
{
|
||||
await RefreshStatus();
|
||||
}
|
||||
_previousIsHubReady = IsHubReady;
|
||||
}
|
||||
|
||||
public async Task RefreshStatus()
|
||||
{
|
||||
if (isLoading || !IsHubReady) return;
|
||||
|
||||
try
|
||||
{
|
||||
isLoading = true;
|
||||
rotationStatus = await HubClient.GetRotationStatusAsync();
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Snackbar.Add($"Error refreshing rotation status: {ex.Message}", Severity.Error);
|
||||
}
|
||||
finally
|
||||
{
|
||||
isLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
private Color GetStateColor(string state)
|
||||
{
|
||||
return state switch
|
||||
{
|
||||
"Ready" => Color.Success,
|
||||
"Moving" => Color.Info,
|
||||
"Error" => Color.Error,
|
||||
"Homing" => Color.Warning,
|
||||
"Initializing" => Color.Warning,
|
||||
_ => Color.Default
|
||||
};
|
||||
}
|
||||
|
||||
private async Task RotateToAngle()
|
||||
{
|
||||
if (!IsHubReady || isLoading || rotationStatus?.IsReady != true)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
isLoading = true;
|
||||
Snackbar.Add($"Rotating to angle {targetAngle}°...", Severity.Info);
|
||||
|
||||
await HubClient.RotateToAngleAsync(targetAngle);
|
||||
|
||||
Snackbar.Add($"Rotate to angle {targetAngle}° command sent successfully", Severity.Success);
|
||||
|
||||
await Task.Delay(500);
|
||||
await RefreshStatus();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Snackbar.Add($"Error rotating to angle: {ex.Message}", Severity.Error);
|
||||
}
|
||||
finally
|
||||
{
|
||||
isLoading = false;
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RotateOffset()
|
||||
{
|
||||
if (!IsHubReady || isLoading || rotationStatus?.IsReady != true)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
isLoading = true;
|
||||
var offsetText = angleOffset >= 0 ? $"+{angleOffset}°" : $"{angleOffset}°";
|
||||
Snackbar.Add($"Rotating offset {offsetText}...", Severity.Info);
|
||||
|
||||
await HubClient.RotateOffsetAsync(angleOffset);
|
||||
|
||||
Snackbar.Add($"Rotate offset {offsetText} command sent successfully", Severity.Success);
|
||||
|
||||
await Task.Delay(500);
|
||||
await RefreshStatus();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Snackbar.Add($"Error rotating offset: {ex.Message}", Severity.Error);
|
||||
}
|
||||
finally
|
||||
{
|
||||
isLoading = false;
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RotateOffsetQuick(double offset)
|
||||
{
|
||||
angleOffset = offset;
|
||||
await RotateOffset();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user