Compare commits

...

2 Commits

Author SHA1 Message Date
GukSang.Jin
da74c0a523 更新 2026-06-10 11:26:33 +08:00
GukSang.Jin
155f0cb536 20260619 2026-06-10 10:47:58 +08:00
2 changed files with 185 additions and 29 deletions

View File

@@ -418,7 +418,21 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Text="实时轴向力" Style="{StaticResource MetricTitle}" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Text="实时轴向力" Style="{StaticResource MetricTitle}" HorizontalAlignment="Left" />
<Button Grid.Column="1"
Content="归零"
Command="{Binding ZeroAxialForceCommand}"
FontSize="13"
Padding="8,3"
MinHeight="28"
Background="#64748B"
BorderBrush="#475569" />
</Grid>
<TextBlock Grid.Row="1"
x:Name="AxialForceText"
Text="{Binding AxialForceText}"
@@ -681,7 +695,21 @@
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Text="实时转速" Style="{StaticResource MetricTitle}" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Text="实时转速" Style="{StaticResource MetricTitle}" HorizontalAlignment="Left" />
<Button Grid.Column="1"
Content="转速归零"
Command="{Binding ZeroSpeedCommand}"
FontSize="13"
Padding="8,3"
MinHeight="28"
Background="#64748B"
BorderBrush="#475569" />
</Grid>
<TextBlock Grid.Row="1"
x:Name="RealtimeSpeedText"
Text="{Binding RealtimeSpeedText}"
@@ -690,11 +718,27 @@
Foreground="#0F766E"
VerticalAlignment="Center" />
<Border Grid.Row="2" Style="{StaticResource InfoStrip}">
<TextBlock x:Name="RealtimePressureText"
Text="{Binding RealtimePressureText}"
FontSize="16"
HorizontalAlignment="Center"
Foreground="#52616F" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock x:Name="RealtimePressureText"
Text="{Binding RealtimePressureText}"
FontSize="16"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="#52616F" />
<Button Grid.Column="1"
Content="压力归零"
Command="{Binding ZeroPressureCommand}"
FontSize="13"
Padding="8,3"
MinHeight="28"
Background="#64748B"
BorderBrush="#475569"
Margin="8,0,0,0" />
</Grid>
</Border>
</Grid>
</Border>
@@ -707,7 +751,21 @@
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Text="实时扭矩" Style="{StaticResource MetricTitle}" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Text="实时扭矩" Style="{StaticResource MetricTitle}" HorizontalAlignment="Left" />
<Button Grid.Column="1"
Content="归零"
Command="{Binding ZeroTorqueCommand}"
FontSize="13"
Padding="8,3"
MinHeight="28"
Background="#64748B"
BorderBrush="#475569" />
</Grid>
<TextBlock Grid.Row="1"
x:Name="RealtimeTorqueText"
Text="{Binding RealtimeTorqueText}"
@@ -894,6 +952,7 @@
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Content="前进"
Tag="SpeedTorqueForward"
@@ -929,6 +988,10 @@
<Button Grid.Column="4"
Content="{Binding SpeedTorqueResetButtonText}"
Command="{Binding ResetSpeedTorqueCommand}"
Margin="8,0,8,0" />
<Button Grid.Column="5"
Content="{Binding VentValveButtonText}"
Command="{Binding ToggleVentValveCommand}"
Margin="8,0,0,0" />
</Grid>
</Grid>

View File

@@ -259,6 +259,7 @@ public sealed class MainWindowViewModel : ObservableObject
private string _noLoadSpeedTestButtonText = "测试";
private string _displacementResetButtonText = "复位";
private string _speedTorqueResetButtonText = "复位";
private string _ventValveButtonText = "通气阀";
public MainWindowViewModel(IPlcCoilService plcCoilService, IPlcRegisterService plcRegisterService, IFileDialogService fileDialogService)
{
@@ -285,6 +286,11 @@ public sealed class MainWindowViewModel : ObservableObject
StartSpeedTorqueCommand = new AsyncRelayCommand(StartSpeedTorqueAsync);
StopSpeedTorqueCommand = new AsyncRelayCommand(StopSpeedTorqueAsync);
ResetSpeedTorqueCommand = new AsyncRelayCommand(ResetSpeedTorqueAsync);
ToggleVentValveCommand = new AsyncRelayCommand(ToggleVentValveAsync);
ZeroAxialForceCommand = new AsyncRelayCommand(ZeroAxialForceAsync);
ZeroTorqueCommand = new AsyncRelayCommand(ZeroTorqueAsync);
ZeroSpeedCommand = new AsyncRelayCommand(ZeroSpeedAsync);
ZeroPressureCommand = new AsyncRelayCommand(ZeroPressureAsync);
SaveNoLoadSpeedSettingCommand = new AsyncRelayCommand(SaveNoLoadSpeedSettingAsync);
RecordNoLoadSpeedCommand = new AsyncRelayCommand(RecordNoLoadSpeedAsync);
@@ -344,6 +350,16 @@ public sealed class MainWindowViewModel : ObservableObject
public IAsyncRelayCommand ResetSpeedTorqueCommand { get; }
public IAsyncRelayCommand ToggleVentValveCommand { get; }
public IAsyncRelayCommand ZeroAxialForceCommand { get; }
public IAsyncRelayCommand ZeroTorqueCommand { get; }
public IAsyncRelayCommand ZeroSpeedCommand { get; }
public IAsyncRelayCommand ZeroPressureCommand { get; }
public IAsyncRelayCommand SaveNoLoadSpeedSettingCommand { get; }
public IAsyncRelayCommand RecordNoLoadSpeedCommand { get; }
@@ -712,6 +728,12 @@ public sealed class MainWindowViewModel : ObservableObject
private set => SetProperty(ref _speedTorqueResetButtonText, value);
}
public string VentValveButtonText
{
get => _ventValveButtonText;
private set => SetProperty(ref _ventValveButtonText, value);
}
private async void RealtimeTimer_Tick(object? sender, EventArgs e)
{
if (_isReadingRealtime)
@@ -749,6 +771,7 @@ public sealed class MainWindowViewModel : ObservableObject
AppendTorqueSample(GetScaledTorque(), DateTime.Now);
ApplyResetCoilValues(coilValues);
bool isVentValveOpen = ReadCoilValue(coilValues, VentValveCoil);
VentValveButtonText = isVentValveOpen ? "关闭气阀" : "通气阀";
if (_isSpeedTorqueRunning && !isVentValveOpen)
{
Log.Error("转速/扭矩测试运行中检测到通气阀关闭M{VentValveCoil}=0立即停止测试", VentValveCoil);
@@ -2408,18 +2431,8 @@ public sealed class MainWindowViewModel : ObservableObject
return;
}
SpeedTorqueTestButtonText = "归零中";
StatusText = "转速/扭矩测试启动前归零中。";
if (!await ExecuteZeroingSequenceAsync(
"转速/扭矩测试",
(TorqueZeroCoil, "扭矩归零 M1101"),
(SpeedZeroCoil, "转速归零 M1300"),
(PressureZeroCoil, "压力归零 M1301"),
(SecondaryTorqueZeroCoil, "扭矩归零 M1302")))
{
SpeedTorqueTestButtonText = "测试";
return;
}
SpeedTorqueTestButtonText = "启动中";
StatusText = "转速/扭矩测试启动中...";
if (!await WriteAndVerifyVentValveStateAsync(true, "转速/扭矩测试启动前"))
{
@@ -2628,6 +2641,53 @@ public sealed class MainWindowViewModel : ObservableObject
}
}
private async Task ToggleVentValveAsync()
{
bool targetState = _ventValveButtonText == "通气阀";
try
{
PlcConnectionConfig config = _parameterConfig.ToPlcConnectionConfig();
await _plcCoilService.WriteCoilAsync(config, VentValveCoil, targetState);
await Task.Delay(100);
IReadOnlyDictionary<ushort, bool> values = await _plcCoilService.ReadCoilValuesAsync(
config,
[VentValveCoil, SpeedTorqueEnabledCoil]);
bool actualState = ReadCoilValue(values, VentValveCoil);
if (actualState != targetState)
{
string error = targetState
? "通气阀未能开启,请检查 PLC 状态。"
: "通气阀未能关闭,请检查 PLC 状态。";
StatusText = error;
Log.Warning(
"通气阀切换失败:目标 {Target},实际 {Actual}M{VentValveCoil}={ActualState},扭矩使能 M{EnabledCoil}={Enabled}",
targetState ? "开启" : "关闭",
actualState ? "开启" : "关闭",
VentValveCoil,
actualState ? 1 : 0,
SpeedTorqueEnabledCoil,
ReadCoilValue(values, SpeedTorqueEnabledCoil) ? 1 : 0);
return;
}
VentValveButtonText = actualState ? "关闭气阀" : "通气阀";
StatusText = actualState ? "通气阀已开启。" : "通气阀已关闭。";
Log.Information(
"通气阀切换成功:目标 {Target}M{VentValveCoil}={State},扭矩使能 M{EnabledCoil}={Enabled}",
targetState ? "开启" : "关闭",
VentValveCoil,
actualState ? 1 : 0,
SpeedTorqueEnabledCoil,
ReadCoilValue(values, SpeedTorqueEnabledCoil) ? 1 : 0);
}
catch (Exception ex)
{
StatusText = $"通气阀操作失败:{OperatorMessageFormatter.FromException(ex)}";
Log.Error(ex, "通气阀操作失败,目标 {Target}M{VentValveCoil}", targetState ? "开启" : "关闭", VentValveCoil);
}
}
private async Task ForwardDisplacementAsync()
{
if (!await PulsePlcAsync(AxialForwardCoil, "轴向前进"))
@@ -2656,15 +2716,8 @@ public sealed class MainWindowViewModel : ObservableObject
return;
}
DisplacementTestButtonText = "归零中";
StatusText = "轴向测试启动前归零中。";
if (!await ExecuteZeroingSequenceAsync(
"轴向测试",
(AxialForceZeroCoil, "轴向力归零 M1100")))
{
DisplacementTestButtonText = "测试";
return;
}
DisplacementTestButtonText = "启动中";
StatusText = "轴向测试启动中...";
if (!await PulsePlcAsync(AxialStartCoil, "轴向测试"))
{
@@ -2832,6 +2885,46 @@ public sealed class MainWindowViewModel : ObservableObject
return true;
}
private async Task ZeroAxialForceAsync()
{
if (!await PulsePlcAsync(AxialForceZeroCoil, "轴向力归零 M1100"))
{
return;
}
StatusText = "轴向力归零完成。";
}
private async Task ZeroTorqueAsync()
{
if (!await PulsePlcAsync(TorqueZeroCoil, "扭矩归零 M1101"))
{
return;
}
StatusText = "扭矩归零完成。";
}
private async Task ZeroSpeedAsync()
{
if (!await PulsePlcAsync(SpeedZeroCoil, "转速归零 M1300"))
{
return;
}
StatusText = "转速归零完成。";
}
private async Task ZeroPressureAsync()
{
if (!await PulsePlcAsync(PressureZeroCoil, "压力归零 M1301"))
{
return;
}
StatusText = "压力归零完成。";
}
private async Task<bool> BeginAxialManualMotionAsync(ushort coilAddress, string actionName)
{
if (!await WriteManualMotionCoilAsync(coilAddress, true, $"{actionName}按下"))