更新202606222
This commit is contained in:
@@ -36,10 +36,13 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.ViewModel
|
||||
private const double MinimumAnalysisLoadRatio = 0.8;
|
||||
// 预触发缓冲:滑动检测前持续缓存的力/位移历史长度,用于回溯真实滑动起点(保证第一个摩擦力峰值被采到)。
|
||||
private const double PreTriggerWindowSeconds = 0.5;
|
||||
// 滑动检测:载荷达标后,水平摩擦力较静置接触基线上升超过该值即判定已进入滑动。
|
||||
private const double SlidingFrictionTriggerRiseN = 5.0;
|
||||
// 回溯滑动起点:从检测点向前回溯,直到摩擦力回到基线附近(该裕度内)即认定为 onset(t=0)。
|
||||
private const double SlidingOnsetFrictionMarginN = 2.0;
|
||||
// 滑动检测:载荷达标后只接受明显陡升,避免低幅慢漂移提前把曲线 0 点定错。
|
||||
private const double SlidingFrictionTriggerRiseN = 35.0;
|
||||
private const double SlidingFrictionTriggerLookbackSeconds = 0.12;
|
||||
private const double SlidingFrictionTriggerSlopeN = 25.0;
|
||||
private const double SlidingDisplacementFrictionRiseN = 20.0;
|
||||
// 回溯滑动起点:在触发前短窗口内找摩擦最低点,贴近标准曲线中首峰前的真实滑动起点。
|
||||
private const double SlidingOnsetSearchBackSeconds = 0.12;
|
||||
// 曲线/分析窗口:滑动开始后只保留该时长,剔除加载段与滑动后回程,对应标准曲线图的有效区间。
|
||||
private const double CurveEndSeconds = 1.0;
|
||||
private const int StaticPeakDropConfirmationPointCount = 3;
|
||||
@@ -900,26 +903,67 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.ViewModel
|
||||
return;
|
||||
}
|
||||
|
||||
var frictionRose = samplePoint.HorizontalFrictionN - slidingBaselineFrictionN >= SlidingFrictionTriggerRiseN;
|
||||
var frictionRiseFromBaseline = samplePoint.HorizontalFrictionN - slidingBaselineFrictionN;
|
||||
var lookbackPoint = FindLookbackPoint(samplePoint.TimeSeconds - SlidingFrictionTriggerLookbackSeconds);
|
||||
var frictionRiseFromLookback = lookbackPoint is null
|
||||
? 0
|
||||
: samplePoint.HorizontalFrictionN - lookbackPoint.HorizontalFrictionN;
|
||||
var frictionRose = frictionRiseFromBaseline >= SlidingFrictionTriggerRiseN
|
||||
&& frictionRiseFromLookback >= SlidingFrictionTriggerSlopeN;
|
||||
var displacementMoved = Math.Abs(samplePoint.DisplacementMm - runStartDisplacementMm) >= SlidingStartDisplacementThresholdMm;
|
||||
if (frictionRose || displacementMoved)
|
||||
var displacementWithFriction = displacementMoved
|
||||
&& frictionRiseFromBaseline >= SlidingDisplacementFrictionRiseN;
|
||||
if (frictionRose || displacementWithFriction)
|
||||
{
|
||||
MarkSlidingStartFromBuffer(frictionRose ? "FrictionRise" : "DisplacementMove");
|
||||
MarkSlidingStartFromBuffer(frictionRose ? "FrictionSharpRise" : "DisplacementWithFrictionRise");
|
||||
return;
|
||||
}
|
||||
|
||||
if (displacementMoved)
|
||||
{
|
||||
Log.Debug(
|
||||
"滑动起点候选未触发:TestNumber={TestNumber}, Reason=DisplacementWithoutFrictionRise, DisplacementDelta={DisplacementDelta:F3}mm, FrictionRiseFromBaseline={FrictionRiseFromBaseline:F3}N, FrictionRiseFromLookback={FrictionRiseFromLookback:F3}N, BaselineFriction={BaselineFriction:F3}N, CurrentFriction={CurrentFriction:F3}N",
|
||||
TestNumber,
|
||||
Math.Abs(samplePoint.DisplacementMm - runStartDisplacementMm),
|
||||
frictionRiseFromBaseline,
|
||||
frictionRiseFromLookback,
|
||||
slidingBaselineFrictionN,
|
||||
samplePoint.HorizontalFrictionN);
|
||||
}
|
||||
}
|
||||
|
||||
// 回溯预触发缓冲到摩擦力刚离开基线的那一刻设为 t=0,并把该时刻起的缓冲点补进曲线,保证第一个峰值被采到。
|
||||
private void MarkSlidingStartFromBuffer(string trigger)
|
||||
private SlipDataPoint? FindLookbackPoint(double targetTime)
|
||||
{
|
||||
var onsetIndex = preTriggerBuffer.Count - 1;
|
||||
while (onsetIndex > 0
|
||||
&& preTriggerBuffer[onsetIndex - 1].HorizontalFrictionN > slidingBaselineFrictionN + SlidingOnsetFrictionMarginN)
|
||||
for (var index = preTriggerBuffer.Count - 1; index >= 0; index--)
|
||||
{
|
||||
onsetIndex--;
|
||||
if (preTriggerBuffer[index].TimeSeconds <= targetTime)
|
||||
{
|
||||
return preTriggerBuffer[index];
|
||||
}
|
||||
}
|
||||
|
||||
return preTriggerBuffer.Count > 0 ? preTriggerBuffer[0] : null;
|
||||
}
|
||||
|
||||
// 回溯预触发缓冲到摩擦力陡升前的低点设为 t=0,并把该时刻起的缓冲点补进曲线,保证第一个峰值被采到。
|
||||
private void MarkSlidingStartFromBuffer(string trigger)
|
||||
{
|
||||
var triggerPoint = preTriggerBuffer[^1];
|
||||
var earliestOnsetTime = triggerPoint.TimeSeconds - SlidingOnsetSearchBackSeconds;
|
||||
var onsetIndex = preTriggerBuffer.Count - 1;
|
||||
for (var index = preTriggerBuffer.Count - 1; index >= 0; index--)
|
||||
{
|
||||
if (preTriggerBuffer[index].TimeSeconds < earliestOnsetTime)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (preTriggerBuffer[index].HorizontalFrictionN <= preTriggerBuffer[onsetIndex].HorizontalFrictionN)
|
||||
{
|
||||
onsetIndex = index;
|
||||
}
|
||||
}
|
||||
|
||||
// 多回退一个点(≈基线水平)作为 t=0,使曲线起点的摩擦力接近基线、随后升至首峰,与标准曲线一致。
|
||||
onsetIndex = Math.Max(0, onsetIndex - 1);
|
||||
var onset = preTriggerBuffer[onsetIndex];
|
||||
slidingStartTimeSeconds = onset.TimeSeconds;
|
||||
slidingStartDisplacementMm = onset.DisplacementMm;
|
||||
@@ -940,12 +984,17 @@ namespace Footwear_Test_methodsfor_wholeshoe_Slipresistanceperformance.ViewModel
|
||||
|
||||
CurrentStatus = "已检测到有效滑动开始:曲线从 0.000 s 开始记录";
|
||||
Log.Information(
|
||||
"检测到有效滑动开始并建立曲线零点:TestNumber={TestNumber}, Trigger={Trigger}, SlidingStartTime={SlidingStartTime:F3}s, BaselineFriction={BaselineFriction:F3}N, OnsetDisplacement={OnsetDisplacement:F3}mm, FlushedPointCount={FlushedPointCount}",
|
||||
"检测到有效滑动开始并建立曲线零点:TestNumber={TestNumber}, Trigger={Trigger}, SlidingStartTime={SlidingStartTime:F3}s, TriggerTime={TriggerTime:F3}s, BaselineFriction={BaselineFriction:F3}N, OnsetFriction={OnsetFriction:F3}N, TriggerFriction={TriggerFriction:F3}N, FrictionRise={FrictionRise:F3}N, OnsetDisplacement={OnsetDisplacement:F3}mm, TriggerDisplacement={TriggerDisplacement:F3}mm, FlushedPointCount={FlushedPointCount}",
|
||||
TestNumber,
|
||||
trigger,
|
||||
onset.TimeSeconds,
|
||||
triggerPoint.TimeSeconds,
|
||||
slidingBaselineFrictionN,
|
||||
onset.HorizontalFrictionN,
|
||||
triggerPoint.HorizontalFrictionN,
|
||||
triggerPoint.HorizontalFrictionN - onset.HorizontalFrictionN,
|
||||
slidingStartDisplacementMm,
|
||||
triggerPoint.DisplacementMm,
|
||||
currentRun.Count);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user