更新2026012

This commit is contained in:
GukSang.Jin
2026-06-12 09:25:42 +08:00
parent 58edb6c2fd
commit e54d92edc2
3 changed files with 67 additions and 31 deletions

View File

@@ -770,7 +770,7 @@ public sealed class MainWindowViewModel : ObservableObject
_axialForce = axialForce;
_realtimeTorque = realtimeTorque;
_realtimeSpeed = realtimeSpeed;
AppendTorqueSample(GetScaledTorque(), DateTime.Now);
AppendTorqueSample(GetScaledTorque(), _realtimeSpeed, DateTime.Now);
ApplyResetCoilValues(coilValues);
bool isVentValveOpen = ReadCoilValue(coilValues, VentValveCoil);
VentValveButtonText = isVentValveOpen ? "关闭气阀" : "通气阀";
@@ -2512,7 +2512,7 @@ public sealed class MainWindowViewModel : ObservableObject
_speedTorqueStartedAt = DateTime.Now;
_activeSpeedTorqueRun = CreateTestRun("转速/扭矩测试", _speedTorqueStartedAt.Value);
ClearTorqueSamples();
AppendTorqueSample(GetScaledTorque(), _speedTorqueStartedAt.Value);
AppendTorqueSample(GetScaledTorque(), _realtimeSpeed, _speedTorqueStartedAt.Value);
_maxSpeedTorqueDisplacement = Math.Max(_maxSpeedTorqueDisplacement, Math.Abs(_speedTorqueDisplacement));
UpdateSpeedTorqueDisplay();
StatusText = "转速/扭矩测试已启动,通气阀与扭矩使能状态正常。";
@@ -3355,12 +3355,14 @@ public sealed class MainWindowViewModel : ObservableObject
NoLoadSpeedErrorRateText = $"{FormatErrorRate(Math.Abs(_noLoadSpeedErrorRate))} %";
}
private void AppendTorqueSample(double value, DateTime sampledAt)
private void AppendTorqueSample(double torque, double speed, DateTime sampledAt)
{
if (!_isSpeedTorqueRunning
|| !_speedTorqueStartedAt.HasValue
|| double.IsNaN(value)
|| double.IsInfinity(value))
|| double.IsNaN(torque)
|| double.IsInfinity(torque)
|| double.IsNaN(speed)
|| double.IsInfinity(speed))
{
return;
}
@@ -3382,7 +3384,8 @@ public sealed class MainWindowViewModel : ObservableObject
TorqueSamples.Add(new TorqueSamplePayload
{
ElapsedSeconds = elapsedSeconds,
TorqueMilliNewtonMeters = value
SpeedRpm = speed,
TorqueMilliNewtonMeters = torque
});
_cachedTorqueCurve = null;
@@ -3430,6 +3433,7 @@ public sealed class MainWindowViewModel : ObservableObject
.Select(sample => new TorqueSamplePayload
{
ElapsedSeconds = sample.ElapsedSeconds,
SpeedRpm = sample.SpeedRpm,
TorqueMilliNewtonMeters = sample.TorqueMilliNewtonMeters
})
.ToList();
@@ -3486,6 +3490,7 @@ public sealed class MainWindowViewModel : ObservableObject
.Select(sample => new TorqueSamplePayload
{
ElapsedSeconds = Math.Max(0, (sample.SampledAt - run.StartedAt).TotalSeconds),
SpeedRpm = sample.RealtimeSpeedRpm,
TorqueMilliNewtonMeters = sample.RealtimeTorqueMilliNewtonMeters
})
.Where(sample => sample.ElapsedSeconds <= holdTime)

View File

@@ -203,6 +203,8 @@ public sealed class TorqueSamplePayload
{
public double ElapsedSeconds { get; init; }
public double SpeedRpm { get; init; }
public double TorqueMilliNewtonMeters { get; init; }
}

View File

@@ -9,6 +9,7 @@ namespace DentistryHandpieces;
public sealed class TorqueTrendControl : FrameworkElement
{
private const string TorqueUnit = "mN.m";
private const string SpeedUnit = "r/min";
public static readonly DependencyProperty SamplesProperty =
DependencyProperty.Register(
@@ -63,42 +64,63 @@ public sealed class TorqueTrendControl : FrameworkElement
List<TorqueSamplePayload> samples = ReadSamples();
if (samples.Count == 0)
{
DrawText(drawingContext, "等待扭矩数据", 15, Color.FromRgb(82, 97, 111), new Point(plot.Left + 8, plot.Top + 8));
DrawText(drawingContext, TorqueUnit, 13, Color.FromRgb(82, 97, 111), new Point(12, plot.Top));
DrawText(drawingContext, "等待转速/扭矩数据", 15, Color.FromRgb(82, 97, 111), new Point(plot.Left + 8, plot.Top + 8));
DrawText(drawingContext, $"扭矩 ({TorqueUnit})", 12, Color.FromRgb(82, 97, 111), new Point(6, plot.Top));
DrawText(drawingContext, $"转速 ({SpeedUnit})", 12, Color.FromRgb(82, 97, 111), new Point(plot.Right - 82, plot.Bottom + 5));
return;
}
List<double> values = samples.Select(sample => sample.TorqueMilliNewtonMeters).ToList();
double min = values.Min();
double max = values.Max();
double range = max - min;
if (range < 0.01)
List<double> torqueValues = samples.Select(sample => sample.TorqueMilliNewtonMeters).ToList();
double minTorque = torqueValues.Min();
double maxTorque = torqueValues.Max();
double torqueRange = maxTorque - minTorque;
if (torqueRange < 0.01)
{
range = 1;
min -= 0.5;
max += 0.5;
torqueRange = 1;
minTorque -= 0.5;
maxTorque += 0.5;
}
else
{
double padding = range * 0.12;
min -= padding;
max += padding;
range = max - min;
double padding = torqueRange * 0.12;
minTorque -= padding;
maxTorque += padding;
torqueRange = maxTorque - minTorque;
}
DrawText(drawingContext, max.ToString("0.##", CultureInfo.InvariantCulture), 12, Color.FromRgb(82, 97, 111), new Point(8, plot.Top - 2));
DrawText(drawingContext, min.ToString("0.##", CultureInfo.InvariantCulture), 12, Color.FromRgb(82, 97, 111), new Point(8, plot.Bottom - 14));
DrawText(drawingContext, $"{samples[0].ElapsedSeconds:0.#}s", 12, Color.FromRgb(82, 97, 111), new Point(plot.Left, plot.Bottom + 5));
DrawText(drawingContext, $"{samples[^1].ElapsedSeconds:0.#}s", 12, Color.FromRgb(82, 97, 111), new Point(plot.Right - 28, plot.Bottom + 5));
List<double> speedValues = samples.Select(sample => sample.SpeedRpm).ToList();
double minSpeed = speedValues.Min();
double maxSpeed = speedValues.Max();
double speedRange = maxSpeed - minSpeed;
if (speedRange < 1)
{
double padding = Math.Max(Math.Abs(minSpeed) * 0.05, 1);
minSpeed -= padding;
maxSpeed += padding;
speedRange = maxSpeed - minSpeed;
}
else
{
double padding = speedRange * 0.05;
minSpeed -= padding;
maxSpeed += padding;
speedRange = maxSpeed - minSpeed;
}
DrawText(drawingContext, maxTorque.ToString("0.##", CultureInfo.InvariantCulture), 12, Color.FromRgb(82, 97, 111), new Point(8, plot.Top - 2));
DrawText(drawingContext, minTorque.ToString("0.##", CultureInfo.InvariantCulture), 12, Color.FromRgb(82, 97, 111), new Point(8, plot.Bottom - 14));
DrawText(drawingContext, minSpeed.ToString("0", CultureInfo.InvariantCulture), 12, Color.FromRgb(82, 97, 111), new Point(plot.Left, plot.Bottom + 5));
DrawText(drawingContext, maxSpeed.ToString("0", CultureInfo.InvariantCulture), 12, Color.FromRgb(82, 97, 111), new Point(plot.Right - 38, plot.Bottom + 5));
DrawText(drawingContext, $"扭矩 ({TorqueUnit})", 11, Color.FromRgb(82, 97, 111), new Point(plot.Left + 4, plot.Top + 3));
DrawText(drawingContext, $"转速 ({SpeedUnit})", 11, Color.FromRgb(82, 97, 111), new Point(plot.Right - 82, plot.Bottom - 18));
var geometry = new StreamGeometry();
using (StreamGeometryContext context = geometry.Open())
{
double elapsedRange = Math.Max(samples[^1].ElapsedSeconds - samples[0].ElapsedSeconds, 0.001);
for (int i = 0; i < samples.Count; i++)
{
double x = samples.Count == 1 ? plot.Right : plot.Left + plot.Width * (samples[i].ElapsedSeconds - samples[0].ElapsedSeconds) / elapsedRange;
double y = plot.Bottom - (samples[i].TorqueMilliNewtonMeters - min) / range * plot.Height;
double x = plot.Left + plot.Width * (samples[i].SpeedRpm - minSpeed) / speedRange;
double y = plot.Bottom - (samples[i].TorqueMilliNewtonMeters - minTorque) / torqueRange * plot.Height;
Point point = new(x, y);
if (i == 0)
@@ -116,11 +138,16 @@ public sealed class TorqueTrendControl : FrameworkElement
var linePen = new Pen(new SolidColorBrush(Color.FromRgb(29, 78, 216)), 2.4);
drawingContext.DrawGeometry(null, linePen, geometry);
double current = values[^1];
double currentY = plot.Bottom - (current - min) / range * plot.Height;
TorqueSamplePayload current = samples[^1];
double currentY = plot.Bottom - (current.TorqueMilliNewtonMeters - minTorque) / torqueRange * plot.Height;
var currentPen = new Pen(new SolidColorBrush(Color.FromRgb(15, 118, 110)), 1.2);
drawingContext.DrawLine(currentPen, new Point(plot.Left, currentY), new Point(plot.Right, currentY));
DrawText(drawingContext, $"当前 {current:0.##} {TorqueUnit}", 13, Color.FromRgb(15, 118, 110), new Point(plot.Right - 112, Math.Max(plot.Top, currentY - 22)));
DrawText(
drawingContext,
$"当前 {current.SpeedRpm:0} {SpeedUnit} / {current.TorqueMilliNewtonMeters:0.##} {TorqueUnit}",
12,
Color.FromRgb(15, 118, 110),
new Point(plot.Left + 6, Math.Max(plot.Top + 18, currentY - 20)));
}
private static void OnSamplesChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
@@ -157,6 +184,8 @@ public sealed class TorqueTrendControl : FrameworkElement
if (sample is TorqueSamplePayload torqueSample
&& !double.IsNaN(torqueSample.ElapsedSeconds)
&& !double.IsInfinity(torqueSample.ElapsedSeconds)
&& !double.IsNaN(torqueSample.SpeedRpm)
&& !double.IsInfinity(torqueSample.SpeedRpm)
&& !double.IsNaN(torqueSample.TorqueMilliNewtonMeters)
&& !double.IsInfinity(torqueSample.TorqueMilliNewtonMeters))
{
@@ -164,7 +193,7 @@ public sealed class TorqueTrendControl : FrameworkElement
}
else if (sample is double value && !double.IsNaN(value) && !double.IsInfinity(value))
{
values.Add(new TorqueSamplePayload { ElapsedSeconds = values.Count, TorqueMilliNewtonMeters = value });
values.Add(new TorqueSamplePayload { ElapsedSeconds = values.Count, SpeedRpm = values.Count, TorqueMilliNewtonMeters = value });
}
}