更新2026012
This commit is contained in:
@@ -770,7 +770,7 @@ public sealed class MainWindowViewModel : ObservableObject
|
|||||||
_axialForce = axialForce;
|
_axialForce = axialForce;
|
||||||
_realtimeTorque = realtimeTorque;
|
_realtimeTorque = realtimeTorque;
|
||||||
_realtimeSpeed = realtimeSpeed;
|
_realtimeSpeed = realtimeSpeed;
|
||||||
AppendTorqueSample(GetScaledTorque(), DateTime.Now);
|
AppendTorqueSample(GetScaledTorque(), _realtimeSpeed, DateTime.Now);
|
||||||
ApplyResetCoilValues(coilValues);
|
ApplyResetCoilValues(coilValues);
|
||||||
bool isVentValveOpen = ReadCoilValue(coilValues, VentValveCoil);
|
bool isVentValveOpen = ReadCoilValue(coilValues, VentValveCoil);
|
||||||
VentValveButtonText = isVentValveOpen ? "关闭气阀" : "通气阀";
|
VentValveButtonText = isVentValveOpen ? "关闭气阀" : "通气阀";
|
||||||
@@ -2512,7 +2512,7 @@ public sealed class MainWindowViewModel : ObservableObject
|
|||||||
_speedTorqueStartedAt = DateTime.Now;
|
_speedTorqueStartedAt = DateTime.Now;
|
||||||
_activeSpeedTorqueRun = CreateTestRun("转速/扭矩测试", _speedTorqueStartedAt.Value);
|
_activeSpeedTorqueRun = CreateTestRun("转速/扭矩测试", _speedTorqueStartedAt.Value);
|
||||||
ClearTorqueSamples();
|
ClearTorqueSamples();
|
||||||
AppendTorqueSample(GetScaledTorque(), _speedTorqueStartedAt.Value);
|
AppendTorqueSample(GetScaledTorque(), _realtimeSpeed, _speedTorqueStartedAt.Value);
|
||||||
_maxSpeedTorqueDisplacement = Math.Max(_maxSpeedTorqueDisplacement, Math.Abs(_speedTorqueDisplacement));
|
_maxSpeedTorqueDisplacement = Math.Max(_maxSpeedTorqueDisplacement, Math.Abs(_speedTorqueDisplacement));
|
||||||
UpdateSpeedTorqueDisplay();
|
UpdateSpeedTorqueDisplay();
|
||||||
StatusText = "转速/扭矩测试已启动,通气阀与扭矩使能状态正常。";
|
StatusText = "转速/扭矩测试已启动,通气阀与扭矩使能状态正常。";
|
||||||
@@ -3355,12 +3355,14 @@ public sealed class MainWindowViewModel : ObservableObject
|
|||||||
NoLoadSpeedErrorRateText = $"{FormatErrorRate(Math.Abs(_noLoadSpeedErrorRate))} %";
|
NoLoadSpeedErrorRateText = $"{FormatErrorRate(Math.Abs(_noLoadSpeedErrorRate))} %";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AppendTorqueSample(double value, DateTime sampledAt)
|
private void AppendTorqueSample(double torque, double speed, DateTime sampledAt)
|
||||||
{
|
{
|
||||||
if (!_isSpeedTorqueRunning
|
if (!_isSpeedTorqueRunning
|
||||||
|| !_speedTorqueStartedAt.HasValue
|
|| !_speedTorqueStartedAt.HasValue
|
||||||
|| double.IsNaN(value)
|
|| double.IsNaN(torque)
|
||||||
|| double.IsInfinity(value))
|
|| double.IsInfinity(torque)
|
||||||
|
|| double.IsNaN(speed)
|
||||||
|
|| double.IsInfinity(speed))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -3382,7 +3384,8 @@ public sealed class MainWindowViewModel : ObservableObject
|
|||||||
TorqueSamples.Add(new TorqueSamplePayload
|
TorqueSamples.Add(new TorqueSamplePayload
|
||||||
{
|
{
|
||||||
ElapsedSeconds = elapsedSeconds,
|
ElapsedSeconds = elapsedSeconds,
|
||||||
TorqueMilliNewtonMeters = value
|
SpeedRpm = speed,
|
||||||
|
TorqueMilliNewtonMeters = torque
|
||||||
});
|
});
|
||||||
_cachedTorqueCurve = null;
|
_cachedTorqueCurve = null;
|
||||||
|
|
||||||
@@ -3430,6 +3433,7 @@ public sealed class MainWindowViewModel : ObservableObject
|
|||||||
.Select(sample => new TorqueSamplePayload
|
.Select(sample => new TorqueSamplePayload
|
||||||
{
|
{
|
||||||
ElapsedSeconds = sample.ElapsedSeconds,
|
ElapsedSeconds = sample.ElapsedSeconds,
|
||||||
|
SpeedRpm = sample.SpeedRpm,
|
||||||
TorqueMilliNewtonMeters = sample.TorqueMilliNewtonMeters
|
TorqueMilliNewtonMeters = sample.TorqueMilliNewtonMeters
|
||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
@@ -3486,6 +3490,7 @@ public sealed class MainWindowViewModel : ObservableObject
|
|||||||
.Select(sample => new TorqueSamplePayload
|
.Select(sample => new TorqueSamplePayload
|
||||||
{
|
{
|
||||||
ElapsedSeconds = Math.Max(0, (sample.SampledAt - run.StartedAt).TotalSeconds),
|
ElapsedSeconds = Math.Max(0, (sample.SampledAt - run.StartedAt).TotalSeconds),
|
||||||
|
SpeedRpm = sample.RealtimeSpeedRpm,
|
||||||
TorqueMilliNewtonMeters = sample.RealtimeTorqueMilliNewtonMeters
|
TorqueMilliNewtonMeters = sample.RealtimeTorqueMilliNewtonMeters
|
||||||
})
|
})
|
||||||
.Where(sample => sample.ElapsedSeconds <= holdTime)
|
.Where(sample => sample.ElapsedSeconds <= holdTime)
|
||||||
|
|||||||
@@ -203,6 +203,8 @@ public sealed class TorqueSamplePayload
|
|||||||
{
|
{
|
||||||
public double ElapsedSeconds { get; init; }
|
public double ElapsedSeconds { get; init; }
|
||||||
|
|
||||||
|
public double SpeedRpm { get; init; }
|
||||||
|
|
||||||
public double TorqueMilliNewtonMeters { get; init; }
|
public double TorqueMilliNewtonMeters { get; init; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ namespace DentistryHandpieces;
|
|||||||
public sealed class TorqueTrendControl : FrameworkElement
|
public sealed class TorqueTrendControl : FrameworkElement
|
||||||
{
|
{
|
||||||
private const string TorqueUnit = "mN.m";
|
private const string TorqueUnit = "mN.m";
|
||||||
|
private const string SpeedUnit = "r/min";
|
||||||
|
|
||||||
public static readonly DependencyProperty SamplesProperty =
|
public static readonly DependencyProperty SamplesProperty =
|
||||||
DependencyProperty.Register(
|
DependencyProperty.Register(
|
||||||
@@ -63,42 +64,63 @@ public sealed class TorqueTrendControl : FrameworkElement
|
|||||||
List<TorqueSamplePayload> samples = ReadSamples();
|
List<TorqueSamplePayload> samples = ReadSamples();
|
||||||
if (samples.Count == 0)
|
if (samples.Count == 0)
|
||||||
{
|
{
|
||||||
DrawText(drawingContext, "等待扭矩数据", 15, Color.FromRgb(82, 97, 111), new Point(plot.Left + 8, plot.Top + 8));
|
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, $"扭矩 ({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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<double> values = samples.Select(sample => sample.TorqueMilliNewtonMeters).ToList();
|
List<double> torqueValues = samples.Select(sample => sample.TorqueMilliNewtonMeters).ToList();
|
||||||
double min = values.Min();
|
double minTorque = torqueValues.Min();
|
||||||
double max = values.Max();
|
double maxTorque = torqueValues.Max();
|
||||||
double range = max - min;
|
double torqueRange = maxTorque - minTorque;
|
||||||
if (range < 0.01)
|
if (torqueRange < 0.01)
|
||||||
{
|
{
|
||||||
range = 1;
|
torqueRange = 1;
|
||||||
min -= 0.5;
|
minTorque -= 0.5;
|
||||||
max += 0.5;
|
maxTorque += 0.5;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
double padding = range * 0.12;
|
double padding = torqueRange * 0.12;
|
||||||
min -= padding;
|
minTorque -= padding;
|
||||||
max += padding;
|
maxTorque += padding;
|
||||||
range = max - min;
|
torqueRange = maxTorque - minTorque;
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawText(drawingContext, max.ToString("0.##", CultureInfo.InvariantCulture), 12, Color.FromRgb(82, 97, 111), new Point(8, plot.Top - 2));
|
List<double> speedValues = samples.Select(sample => sample.SpeedRpm).ToList();
|
||||||
DrawText(drawingContext, min.ToString("0.##", CultureInfo.InvariantCulture), 12, Color.FromRgb(82, 97, 111), new Point(8, plot.Bottom - 14));
|
double minSpeed = speedValues.Min();
|
||||||
DrawText(drawingContext, $"{samples[0].ElapsedSeconds:0.#}s", 12, Color.FromRgb(82, 97, 111), new Point(plot.Left, plot.Bottom + 5));
|
double maxSpeed = speedValues.Max();
|
||||||
DrawText(drawingContext, $"{samples[^1].ElapsedSeconds:0.#}s", 12, Color.FromRgb(82, 97, 111), new Point(plot.Right - 28, plot.Bottom + 5));
|
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();
|
var geometry = new StreamGeometry();
|
||||||
using (StreamGeometryContext context = geometry.Open())
|
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++)
|
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 x = plot.Left + plot.Width * (samples[i].SpeedRpm - minSpeed) / speedRange;
|
||||||
double y = plot.Bottom - (samples[i].TorqueMilliNewtonMeters - min) / range * plot.Height;
|
double y = plot.Bottom - (samples[i].TorqueMilliNewtonMeters - minTorque) / torqueRange * plot.Height;
|
||||||
Point point = new(x, y);
|
Point point = new(x, y);
|
||||||
|
|
||||||
if (i == 0)
|
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);
|
var linePen = new Pen(new SolidColorBrush(Color.FromRgb(29, 78, 216)), 2.4);
|
||||||
drawingContext.DrawGeometry(null, linePen, geometry);
|
drawingContext.DrawGeometry(null, linePen, geometry);
|
||||||
|
|
||||||
double current = values[^1];
|
TorqueSamplePayload current = samples[^1];
|
||||||
double currentY = plot.Bottom - (current - min) / range * plot.Height;
|
double currentY = plot.Bottom - (current.TorqueMilliNewtonMeters - minTorque) / torqueRange * plot.Height;
|
||||||
var currentPen = new Pen(new SolidColorBrush(Color.FromRgb(15, 118, 110)), 1.2);
|
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));
|
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)
|
private static void OnSamplesChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
|
||||||
@@ -157,6 +184,8 @@ public sealed class TorqueTrendControl : FrameworkElement
|
|||||||
if (sample is TorqueSamplePayload torqueSample
|
if (sample is TorqueSamplePayload torqueSample
|
||||||
&& !double.IsNaN(torqueSample.ElapsedSeconds)
|
&& !double.IsNaN(torqueSample.ElapsedSeconds)
|
||||||
&& !double.IsInfinity(torqueSample.ElapsedSeconds)
|
&& !double.IsInfinity(torqueSample.ElapsedSeconds)
|
||||||
|
&& !double.IsNaN(torqueSample.SpeedRpm)
|
||||||
|
&& !double.IsInfinity(torqueSample.SpeedRpm)
|
||||||
&& !double.IsNaN(torqueSample.TorqueMilliNewtonMeters)
|
&& !double.IsNaN(torqueSample.TorqueMilliNewtonMeters)
|
||||||
&& !double.IsInfinity(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))
|
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 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user