forked from ddrilling/AsbCloudServer
Исправление детекторов совместно с АПГ
This commit is contained in:
parent
383e27d230
commit
85c253b82b
@ -25,16 +25,16 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
|
|||||||
this.IdCategory = IdCategory;
|
this.IdCategory = IdCategory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual DetectedOperation? DetectOrDefault(DetectableTelemetry[] telemetry, ref int position)
|
public virtual DetectedOperation? DetectOrDefault(DetectableTelemetry[] telemetry, ref int positionStart)
|
||||||
{
|
{
|
||||||
if ((telemetry.Length > position + FragmentLength + StepLength) && DetectStart(telemetry, position))
|
if ((telemetry.Length > positionStart + FragmentLength + StepLength) && DetectStart(telemetry, positionStart))
|
||||||
{
|
{
|
||||||
var skip = position + StepLength;
|
var skip = positionStart + StepLength;
|
||||||
while (telemetry.Length > skip + FragmentLength)
|
while (telemetry.Length > skip + FragmentLength)
|
||||||
{
|
{
|
||||||
if (DetectEnd(telemetry, skip))
|
if (DetectEnd(telemetry, skip))
|
||||||
{
|
{
|
||||||
var dateStart = telemetry[position].DateTime;
|
var dateStart = telemetry[positionStart].DateTime;
|
||||||
var dateEnd = telemetry[skip].DateTime;
|
var dateEnd = telemetry[skip].DateTime;
|
||||||
var durationSec = (dateEnd - dateStart).TotalSeconds;
|
var durationSec = (dateEnd - dateStart).TotalSeconds;
|
||||||
if (durationSec < MinDurationSeconds || durationSec > MaxDurationSeconds)
|
if (durationSec < MinDurationSeconds || durationSec > MaxDurationSeconds)
|
||||||
@ -43,14 +43,18 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
|
|||||||
var result = new DetectedOperation
|
var result = new DetectedOperation
|
||||||
{
|
{
|
||||||
IdCategory = IdCategory,
|
IdCategory = IdCategory,
|
||||||
IdUsersAtStart = telemetry[position].IdUser ?? -1,
|
IdUsersAtStart = telemetry[positionStart].IdUser ?? -1,
|
||||||
DateStart = dateStart,
|
DateStart = dateStart,
|
||||||
DateEnd = dateEnd,
|
DateEnd = dateEnd,
|
||||||
DepthStart = telemetry[position].WellDepth ?? -1d,
|
DepthStart = telemetry[positionStart].WellDepth ?? -1d,
|
||||||
DepthEnd = telemetry[skip].WellDepth ?? -1d,
|
DepthEnd = telemetry[skip].WellDepth ?? -1d,
|
||||||
|
Value = CalcValue(telemetry, positionStart, skip),
|
||||||
};
|
};
|
||||||
CalcValue(ref result);
|
|
||||||
position = skip + FragmentLength;
|
if (!IsValid(result))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
positionStart = skip;// + FragmentLength;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,12 +64,34 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void CalcValue(ref DetectedOperation result);
|
/// <summary>
|
||||||
|
/// Расчет ключевого параметра
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="result"></param>
|
||||||
|
protected abstract double CalcValue(DetectableTelemetry[] telemetry, int positionBegin, int positionEnd);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Определение начала операции
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="telemetry"></param>
|
||||||
|
/// <param name="position"></param>
|
||||||
|
/// <returns></returns>
|
||||||
protected abstract bool DetectStart(DetectableTelemetry[] telemetry, int position);
|
protected abstract bool DetectStart(DetectableTelemetry[] telemetry, int position);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Определение окончания операции
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="telemetry"></param>
|
||||||
|
/// <param name="position"></param>
|
||||||
|
/// <returns></returns>
|
||||||
protected abstract bool DetectEnd(DetectableTelemetry[] telemetry, int position);
|
protected abstract bool DetectEnd(DetectableTelemetry[] telemetry, int position);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Валидация операции
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="result"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected abstract bool IsValid(DetectedOperation result);
|
||||||
}
|
}
|
||||||
#nullable disable
|
#nullable disable
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,86 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
@ -4,57 +4,15 @@ using System.Linq;
|
|||||||
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
||||||
{
|
{
|
||||||
#nullable enable
|
#nullable enable
|
||||||
class DetectorDrillingRotor : DetectorAbstract
|
class DetectorDrillingRotor : DetectorDrillingAbstract
|
||||||
{
|
{
|
||||||
const double minRop = 5; //м/час
|
public DetectorDrillingRotor()
|
||||||
const double minRotorSpeed = 5; //об/мин
|
: base(2){}
|
||||||
const double ticksPerHour = 60 * 60 * 10_000_000d;
|
|
||||||
const double minPressure = 25;
|
|
||||||
const double minDeltaDepth = 0.02;
|
|
||||||
|
|
||||||
public DetectorDrillingRotor() : base(2)
|
protected override bool ModeCondition(DetectableTelemetry[] telemetryFragment)
|
||||||
{
|
{
|
||||||
FragmentLength = 15;
|
var lineRotorSpeed = new InterpolationLine(telemetryFragment.Select(d => (d.RotorSpeed ?? 0d, (d.DateTime - telemetryFragment[0].DateTime).TotalHours)));
|
||||||
StepLength = 10;
|
return lineRotorSpeed.IsAverageYMoreThanBound(minRotorSpeed);
|
||||||
}
|
|
||||||
|
|
||||||
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.RotorSpeed > minRotorSpeed)
|
|
||||||
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.Ticks / ticksPerHour)));
|
|
||||||
if (!lineBlockPosition.IsYDecreases(minRop))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
var lineWellDepth = new InterpolationLine(fragment.Select(d => (d.WellDepth ?? 0d, d.DateTime.Ticks / ticksPerHour)));
|
|
||||||
if (!lineWellDepth.IsYIncreases(minRop))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool DetectEnd(DetectableTelemetry[] telemetry, int position)
|
|
||||||
=> !DetectStart(telemetry, position);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Рассчитываем МСП, м/час
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="result"></param>
|
|
||||||
protected override void CalcValue(ref DetectedOperation result)
|
|
||||||
{
|
|
||||||
result.Value = (result.DepthEnd - result.DepthStart) / (result.DateEnd - result.DateStart).TotalHours;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#nullable disable
|
#nullable disable
|
||||||
|
@ -1,59 +1,17 @@
|
|||||||
using AsbCloudDb.Model;
|
using System.Linq;
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
||||||
{
|
{
|
||||||
#nullable enable
|
#nullable enable
|
||||||
class DetectorDrillingSlide : DetectorAbstract
|
class DetectorDrillingSlide : DetectorDrillingAbstract
|
||||||
{
|
{
|
||||||
const double minRop = 5; //м/час
|
public DetectorDrillingSlide()
|
||||||
const double minRotorSpeed = 5; //об/мин
|
: base(3){}
|
||||||
const double ticksPerHour = 60 * 60 * 10_000_000d;
|
|
||||||
const double minPressure = 25;
|
|
||||||
const double minDeltaDepth = 0.02;
|
|
||||||
|
|
||||||
public DetectorDrillingSlide() : base(3)
|
protected override bool ModeCondition(DetectableTelemetry[] telemetryFragment)
|
||||||
{
|
{
|
||||||
FragmentLength = 10;
|
var lineRotorSpeed = new InterpolationLine(telemetryFragment.Select(d => (d.RotorSpeed ?? 0d, (d.DateTime - telemetryFragment[0].DateTime).TotalHours)));
|
||||||
}
|
return lineRotorSpeed.IsAverageYLessThanBound(minRotorSpeed);
|
||||||
|
|
||||||
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.RotorSpeed < minRotorSpeed)
|
|
||||||
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.Ticks / ticksPerHour)));
|
|
||||||
if (!lineBlockPosition.IsYDecreases(minRop))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
var lineWellDepth = new InterpolationLine(fragment.Select(d => (d.WellDepth ?? 0d, d.DateTime.Ticks / ticksPerHour)));
|
|
||||||
if (!lineWellDepth.IsYIncreases(minRop))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool DetectEnd(DetectableTelemetry[] telemetry, int position)
|
|
||||||
=> !DetectStart(telemetry, position);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Рассчитываем МСП, м/час
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="result"></param>
|
|
||||||
protected override void CalcValue(ref DetectedOperation result)
|
|
||||||
{
|
|
||||||
result.Value = (result.DepthEnd - result.DepthStart) / (result.DateEnd - result.DateStart).TotalHours;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#nullable disable
|
#nullable disable
|
||||||
|
@ -34,10 +34,17 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void CalcValue(ref DetectedOperation result)
|
protected override double CalcValue(DetectableTelemetry[] telemetry, int positionBegin, int positionEnd)
|
||||||
{
|
{
|
||||||
result.Value = result.DurationMinutes;
|
var pBegin = telemetry[positionBegin];
|
||||||
|
var pEnd = telemetry[positionEnd];
|
||||||
|
var result = (pEnd.DateTime - pBegin.DateTime).TotalMinutes;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override bool IsValid(DetectedOperation result)
|
||||||
|
=> result.Value > 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
#nullable disable
|
#nullable disable
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,26 @@ namespace ConsoleApp1
|
|||||||
// use ServiceFactory to make services
|
// use ServiceFactory to make services
|
||||||
static void Main(/*string[] args*/)
|
static void Main(/*string[] args*/)
|
||||||
{
|
{
|
||||||
|
System.Collections.Generic.List<(double, double)> data = new() {
|
||||||
|
(22.52400016784668, 17715023.435277779) ,
|
||||||
|
(22.52400016784668, 17715023.435555555) ,
|
||||||
|
(22.52400016784668, 17715023.435833335) ,
|
||||||
|
(22.52400016784668, 17715023.436111111) ,
|
||||||
|
(22.547000885009766, 17715023.436388887) ,
|
||||||
|
(22.833000183105469, 17715023.436666667) ,
|
||||||
|
(23.063999176025391, 17715023.436944444) ,
|
||||||
|
(23.298999786376953, 17715023.437222224) ,
|
||||||
|
(23.5310001373291, 17715023.4375) ,
|
||||||
|
(23.763999938964844, 17715023.437777776) ,
|
||||||
|
(23.993999481201172, 17715023.438055556) ,
|
||||||
|
(24.229999542236328, 17715023.438333333) ,
|
||||||
|
(24.459999084472656, 17715023.438611113) ,
|
||||||
|
(24.694999694824219, 17715023.438888889) ,
|
||||||
|
(24.926000595092773, 17715023.439166665) ,
|
||||||
|
};
|
||||||
|
|
||||||
|
var il = new AsbCloudInfrastructure.Services.DetectOperations.InterpolationLine(data);
|
||||||
|
|
||||||
Console.WriteLine("hit keyboard to start");
|
Console.WriteLine("hit keyboard to start");
|
||||||
Console.ReadLine();
|
Console.ReadLine();
|
||||||
|
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"profiles": {
|
|
||||||
"WSL": {
|
|
||||||
"commandName": "WSL2",
|
|
||||||
"distributionName": ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user