forked from ddrilling/AsbCloudServer
86 lines
3.3 KiB
C#
86 lines
3.3 KiB
C#
using AsbCloudDb.Model;
|
||
using System.Linq;
|
||
|
||
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
||
{
|
||
internal abstract class DetectorDrillingAbstract : DetectorAbstract
|
||
{
|
||
/* # РАСЧЕТ minRop
|
||
* шаг энкодера = 0.006м;
|
||
* 2 шага за 10 секунд не считается, так как может быть простым шумом;
|
||
* minRop = 0.006 * 2 / 10 = 0.0012 м/сек
|
||
* minRop > 4.32 м/ч & minRop < 6.48 м/ч (3 шага за 10 сек);
|
||
*/
|
||
protected const double minRop = 5.4; //м/час
|
||
protected const double minRotorSpeed = 5; //об/мин
|
||
protected const double minPressure = 25;
|
||
protected const double minDeltaDepth = 0.01;
|
||
|
||
public DetectorDrillingAbstract(int IdCategory) : base(IdCategory)
|
||
{
|
||
FragmentLength = 12;
|
||
StepLength = 3;
|
||
}
|
||
|
||
protected override bool DetectStart(DetectableTelemetry[] telemetry, int position)
|
||
{
|
||
var firstItem = telemetry[position];
|
||
var deltaDepth = firstItem.WellDepth - firstItem.BitDepth;
|
||
if (deltaDepth is not null &&
|
||
System.Math.Abs((float)deltaDepth) > minDeltaDepth)
|
||
return false;
|
||
|
||
if (firstItem.Pressure < minPressure)
|
||
return false;
|
||
|
||
var fragment = telemetry[position..(position + FragmentLength)];
|
||
|
||
var lineBlockPosition = new InterpolationLine(fragment.Select(d => (d.BlockPosition ?? 0d, (d.DateTime - firstItem.DateTime).TotalHours)));
|
||
if (!lineBlockPosition.IsYDecreases(-minRop))
|
||
return false;
|
||
|
||
var lineWellDepth = new InterpolationLine(fragment.Select(d => ((d.WellDepth - firstItem.WellDepth) ?? 0d, (d.DateTime - firstItem.DateTime).TotalHours)));
|
||
if (!lineWellDepth.IsYIncreases(minRop))
|
||
return false;
|
||
|
||
if (!ModeCondition(fragment))
|
||
return false;
|
||
|
||
return true;
|
||
}
|
||
|
||
protected override bool DetectEnd(DetectableTelemetry[] telemetry, int position)
|
||
{
|
||
var firstItem = telemetry[position];
|
||
var deltaDepth = firstItem.WellDepth - firstItem.BitDepth;
|
||
if (deltaDepth is not null &&
|
||
System.Math.Abs((float)deltaDepth) > minDeltaDepth)
|
||
return true;
|
||
|
||
if (firstItem.Pressure < minPressure)
|
||
return true;
|
||
|
||
var fragment = telemetry[position..(position + FragmentLength)];
|
||
if (!ModeCondition(fragment))
|
||
return true;
|
||
|
||
return false;
|
||
}
|
||
|
||
protected abstract bool ModeCondition(DetectableTelemetry[] telemetryFragment);
|
||
|
||
/// <summary>
|
||
/// Рассчитываем МСП, м/час
|
||
/// </summary>
|
||
/// <param name="result"></param>
|
||
protected override double CalcValue(DetectableTelemetry[] telemetry, int positionBegin, int positionEnd)
|
||
{
|
||
var pBegin = telemetry[positionBegin];
|
||
var pEnd = telemetry[positionEnd];
|
||
var result = (double)(pEnd.WellDepth - pBegin.WellDepth) / (pEnd.DateTime - pBegin.DateTime).TotalHours;
|
||
return result;
|
||
}
|
||
protected override bool IsValid(DetectedOperation result)
|
||
=> result.Value > 0;
|
||
}
|
||
} |