Новые расчёты для автоматического определения операций

1. Поправел excel шаблон
2. Доработаны алгоритмы определения операций бурения
3. Небольшой рефакторинг DetectorAbstract, добавил метод для валидации
4. Закомментированы неиспользуемые детекторы.
5. Обновлена спецификация определения операций бурения
6. Добавлены тесты для определения операций бурения
This commit is contained in:
Степанов Дмитрий 2023-11-22 14:47:17 +05:00
parent afccdafebc
commit 8bbaca0d0c
10 changed files with 506 additions and 212 deletions

View File

@ -14,7 +14,7 @@ namespace AsbCloudInfrastructure.Services.DetectOperations;
public class DetectedOperationExportService
{
private readonly DetectorAbstract[] detectors = { new DetectorDrilling(), new DetectorSlipsTime() };
private readonly DetectorAbstract[] detectors = { new DetectorDrilling() };
private readonly IDictionary<int, string> domains = new Dictionary<int, string>
{
@ -122,10 +122,17 @@ public class DetectedOperationExportService
row.Cell(columnDepthStart).Value = detectedOperations[i].DepthStart;
row.Cell(columnDepthEnd).Value = detectedOperations[i].DepthEnd;
row.Cell(columnDepth).Value = detectedOperations[i].DepthEnd - detectedOperations[i].DepthStart;
row.Cell(columnIdReasonOfEnd).Value = detectedOperations[i].IdReasonOfEnd;
row.Cell(columnIdReasonOfEnd).Value = detectedOperations[i].IdReasonOfEnd switch
{
0 => "Не определена",
1 => "Не определено начало операции",
101 => "Разница глубин забоя и положением долота",
300 => "Низкое давление",
_ => detectedOperations[i].IdReasonOfEnd
};
var link =
$"{domains[idDomain]}/well/{well.Id}/telemetry/monitoring?end={Uri.EscapeDataString(dateStart.AddSeconds(3544).ToString("yyyy-MM-ddTHH:mm:ss.fff"))}&range=3600";
$"{domains[idDomain]}/well/{well.Id}/telemetry/monitoring?end={Uri.EscapeDataString(dateStart.AddSeconds(1800 * 0.9).ToString("yyyy-MM-ddTHH:mm:ss.fff"))}&range=1800";
row.Cell(columnDateStart).Value = dateStart;
row.Cell(columnDateStart).SetHyperlink(new XLHyperlink(link));
@ -191,10 +198,8 @@ public class DetectedOperationExportService
var isDetected = false;
var positionBegin = 0;
var positionEnd = data.Length - gap;
var step = 10;
while (positionEnd > positionBegin)
{
step++;
foreach (var detector in detectors)
{
if (!detector.TryDetect(idTelemetry, data, positionBegin, positionEnd, lastDetectedOperation, out var result))
@ -203,14 +208,11 @@ public class DetectedOperationExportService
detectedOperations.Add(result!.Operation);
lastDetectedOperation = result.Operation;
isDetected = true;
step = 1;
positionBegin = result.TelemetryEnd;
break;
}
if (step > 20)
step = 10;
positionBegin += step;
positionBegin += 1;
}
if (isDetected)

View File

@ -4,8 +4,7 @@ using System.Linq;
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
{
internal abstract class DetectorAbstract
public abstract class DetectorAbstract
{
private readonly int stepLength = 3;
@ -35,9 +34,10 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
protected const int IdReasonOfEnd_Custom1 = 10_000;
public abstract Func<DetectableTelemetry[], int, int, int> GetIdOperation { get; }
protected abstract Func<DetectableTelemetry[], int, int, int> GetIdOperation { get; }
public bool TryDetect(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end, DetectedOperation? previousOperation, out OperationDetectorResult? result)
public bool TryDetect(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end, DetectedOperation? previousOperation,
out OperationDetectorResult? result)
{
// Проверка соответствия критерию начала операции
if (DetectBegin(telemetry, begin, previousOperation))
@ -53,29 +53,30 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
idReasonOfEnd = DetectEnd(telemetry, positionEnd, previousOperation);
if(idReasonOfEnd is IdReasonOfEnd_DeltaDepthIsHi or IdReasonOfEnd_PressureIsLo &&
!IsValidByWellDepthDoesNotChange(telemetry, begin, positionEnd))
break;
if (idReasonOfEnd != IdReasonOfEnd_NotDetected)
break;
}
result = null;
result = MakeOperation(idTelemetry, telemetry, begin, positionEnd, idReasonOfEnd);
return true;
return result is not null;
}
result = null;
return false;
}
protected virtual bool IsValidOperationDetectorResult(OperationDetectorResult operationDetectorResult) =>
operationDetectorResult.Operation.IdReasonOfEnd != IdReasonOfEnd_NotDetected;
protected abstract bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation);
protected virtual int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
=> DetectBegin(telemetry, position, previousOperation)
? IdReasonOfEnd_NotDetected
: IdReasonOfEnd_NotDetectBegin;
private OperationDetectorResult MakeOperation(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end, int idReasonOfEnd)
private OperationDetectorResult? MakeOperation(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end,
int idReasonOfEnd)
{
var pBegin = telemetry[begin];
var pEnd = telemetry[end];
@ -96,10 +97,9 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
IdReasonOfEnd = idReasonOfEnd,
},
};
return result;
}
protected abstract bool IsValid(DetectableTelemetry[] telemetry, int begin, int end);
return !IsValidOperationDetectorResult(result) ? null : result;
}
protected abstract double CalcValue(DetectableTelemetry[] telemetry, int begin, int end);
@ -210,6 +210,7 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
max = itemValue;
sum += itemValue;
}
return (min, max, sum, end - begin);
}
@ -267,6 +268,7 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
if (max - min > deviation)
return true;
}
return false;
}
@ -302,6 +304,7 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
if (max - min > deviation)
return true;
}
return false;
}
@ -323,6 +326,7 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
if (Math.Abs(beginPointValue - itemValue) > deviation)
return true;
}
return false;
}
@ -344,10 +348,9 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
if (itemValue - beginPointValue > deviation)
return true;
}
return false;
}
}
}

View File

@ -1,68 +1,66 @@
using System;
using AsbCloudDb.Model;
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
{
/// <summary>
/// Проработка перед наращиванием
/// </summary>
internal class DetectorDevelopment : DetectorAbstract
{
protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
=> CalcDeltaMinutes(telemetry, begin, end);
public override Func<DetectableTelemetry[], int, int, int> GetIdOperation => (_, _, _)
=> WellOperationCategory.IdDevelopment;
protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
{
if (previousOperation?.IdCategory == WellOperationCategory.IdSlipsTime)
return false;
var point0 = telemetry[position];
var delta = point0.WellDepth - point0.BitDepth;
if (delta < 0.03d || delta > 30)
return false;
if (point0.Pressure < 15)
return false;
if (point0.BlockPosition > 2.5)
return false;
if (point0.RotorSpeed < 10)
return false;
if (!ContainsDeviationApprox(telemetry, d => d.BlockPosition, position, 60, 0.03))
return false;
return true;
}
protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
{
var point0 = telemetry[position];
var delta = point0.WellDepth - point0.BitDepth;
if (delta < 0.03d || delta > 30)
return IdReasonOfEnd_DeltaDepthOutOfRange;
if (point0.Pressure < 15)
return IdReasonOfEnd_PressureIsLo;
if (point0.BlockPosition > 31)
return IdReasonOfEnd_BlockPositionIsHi;
if (point0.RotorSpeed < 10)
return IdReasonOfEnd_RotorSpeedIsLo;
return IdReasonOfEnd_NotDetected;
}
protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
=> IsValidByWellDepthDoesNotChange(telemetry, begin, end);
}
}
// using System;
// using AsbCloudDb.Model;
//
// namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
// {
//
// /// <summary>
// /// Проработка перед наращиванием
// /// </summary>
// internal class DetectorDevelopment : DetectorAbstract
// {
// protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
// => CalcDeltaMinutes(telemetry, begin, end);
//
// public override Func<DetectableTelemetry[], int, int, int> GetIdOperation => (_, _, _)
// => WellOperationCategory.IdDevelopment;
//
// protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
// {
// if (previousOperation?.IdCategory == WellOperationCategory.IdSlipsTime)
// return false;
//
// var point0 = telemetry[position];
// var delta = point0.WellDepth - point0.BitDepth;
// if (delta < 0.03d || delta > 30)
// return false;
//
// if (point0.Pressure < 15)
// return false;
//
// if (point0.BlockPosition > 2.5)
// return false;
//
// if (point0.RotorSpeed < 10)
// return false;
//
// if (!ContainsDeviationApprox(telemetry, d => d.BlockPosition, position, 60, 0.03))
// return false;
//
// return true;
// }
//
// protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
// {
// var point0 = telemetry[position];
// var delta = point0.WellDepth - point0.BitDepth;
// if (delta < 0.03d || delta > 30)
// return IdReasonOfEnd_DeltaDepthOutOfRange;
//
// if (point0.Pressure < 15)
// return IdReasonOfEnd_PressureIsLo;
//
// if (point0.BlockPosition > 31)
// return IdReasonOfEnd_BlockPositionIsHi;
//
// if (point0.RotorSpeed < 10)
// return IdReasonOfEnd_RotorSpeedIsLo;
//
// return IdReasonOfEnd_NotDetected;
// }
//
// protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
// => IsValidByWellDepthDoesNotChange(telemetry, begin, end);
// }
// }
//

View File

@ -4,9 +4,9 @@ using AsbCloudDb.Model;
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors;
internal class DetectorDrilling : DetectorAbstract
public class DetectorDrilling : DetectorAbstract
{
public override Func<DetectableTelemetry[], int, int, int> GetIdOperation => DefineDrillingOperation;
protected override Func<DetectableTelemetry[], int, int, int> GetIdOperation => DefineDrillingOperation;
protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
{
@ -18,9 +18,6 @@ internal class DetectorDrilling : DetectorAbstract
if (point0.Pressure < 25)
return false;
if (point0.RotorSpeed < 5)
return false;
return true;
}
@ -38,25 +35,37 @@ internal class DetectorDrilling : DetectorAbstract
return IdReasonOfEnd_NotDetected;
}
protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
=> IsValidByWellDepthIncreasing(telemetry, begin, end);
protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
=> CalcRop(telemetry, begin, end);
protected override bool IsValidOperationDetectorResult(OperationDetectorResult operationDetectorResult) =>
operationDetectorResult.Operation.IdReasonOfEnd is IdReasonOfEnd_DeltaDepthIsHi or IdReasonOfEnd_PressureIsLo &&
Math.Abs(operationDetectorResult.Operation.DepthStart - operationDetectorResult.Operation.DepthEnd) > 0.01;
private static int DefineDrillingOperation(DetectableTelemetry[] telemetry, int begin, int end)
{
const int idSlideWithOscillation = 12000;
var telemetryRange = telemetry[begin.. end];
var telemetryRange = telemetry[begin.. end]
.OrderBy(x => x.DateTime).ToList();
for (var i = telemetryRange.Count - 1; i >= 0 && telemetryRange.Count > 1; i--)
{
if (Math.Abs(telemetryRange[i].WellDepth - telemetryRange[i - 1].WellDepth) < 0.001d)
{
telemetryRange.RemoveAt(i);
continue;
}
break;
}
var avgRotorSpeed = telemetryRange.Average(t => t.RotorSpeed);
if (avgRotorSpeed < 10)
return WellOperationCategory.IdSlide;
var despersion = telemetryRange
.Average(t => Math.Pow((t.RotorSpeed - avgRotorSpeed) / avgRotorSpeed, 2));
var despersion = telemetryRange.Average(t => Math.Pow(t.RotorSpeed/avgRotorSpeed - 1, 2));
return despersion < 0.2d ? WellOperationCategory.IdRotor : idSlideWithOscillation;
}

View File

@ -1,39 +1,39 @@
using System;
using AsbCloudDb.Model;
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
{
internal class DetectorSlipsTime : DetectorAbstract
{
protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
=> CalcDeltaMinutes(telemetry, begin, end);
public override Func<DetectableTelemetry[], int, int, int> GetIdOperation => (_, _, _) => WellOperationCategory.IdSlipsTime;
protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
{
var point0 = telemetry[position];
var delta = point0.WellDepth - point0.BitDepth;
if (delta > 2.5d)
return false;
if (point0.Pressure > 15)
return false;
if (point0.BlockPosition > 8)
return false;
if (point0.HookWeight > 20)
return false;
return true;
}
protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
=> IsValidByWellDepthDoesNotChange(telemetry, begin, end);
}
}
// using System;
// using AsbCloudDb.Model;
//
// namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
// {
//
// internal class DetectorSlipsTime : DetectorAbstract
// {
// protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
// => CalcDeltaMinutes(telemetry, begin, end);
//
// public override Func<DetectableTelemetry[], int, int, int> GetIdOperation => (_, _, _) => WellOperationCategory.IdSlipsTime;
//
// protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
// {
// var point0 = telemetry[position];
// var delta = point0.WellDepth - point0.BitDepth;
// if (delta > 2.5d)
// return false;
//
// if (point0.Pressure > 15)
// return false;
//
// if (point0.BlockPosition > 8)
// return false;
//
// if (point0.HookWeight > 20)
// return false;
//
// return true;
// }
//
// protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
// => IsValidByWellDepthDoesNotChange(telemetry, begin, end);
// }
//
//
// }
//

View File

@ -1,29 +1,27 @@
Метод определения бурения
# Алгоритм определения бурения в роторе, слайде, слайде с осцилляцией
## Метод определения операции бурения
Признак начала операции =
расстояние от долота до забоя < 0.03м  И
давление > 25атм
(расстояние от долота до забоя < 0.03м) И
(давление > 25атм)
Признак окончания операции =
(расстояние от долота до забоя > 0.03м) ИЛИ
(давление < 25атм)
расстояние от долота до забоя > 0.03м  ИЛИ
## Валидация
Для точного определения операции бурения, необходимо убрать диапазон в которых сработал признак окончания операции и не менялась глубина:
Определили точку окончания операции исходя из Признак окончания операции.
Определяем временной интервал, когда не менялась глубина (т.е. время шло, а глубина была неизменна)
Определив начальную точку и точку окончания операции
Исключаем этот интервал из операции.
давление < 25атм
## Метод определения бурения в слайде
Необходимо рассчитать средние обороты ротора за всю операцию бурения.
Если среднее арифметическое больше константы (10 об/мин), то это бурение в роторе, если меньше, то это бурение в слайде.
Находим границы
После того когда мы нашли границы, мы должны определить операцию, тогда мы смотрим на забой точки окончания операций сравниваем с забоем точками начала операций:
Если они равны друг другу, то мы эту операцию дальше не обрабатываем, а выбрасываем.
Если они не равны, то у нас произошло увеличение забоя, значит эта операция бурения.
Дальше мы определяем как мы бурили в роторе или слайде, для этого нам необходимо рассчитать среднюю скорость(среднее арифметическое) за всю операцию бурения . Если среднее арифметическое больше константы (10 об/мин), то это бурение в роторе, если меньше, то это бурение в слайде.
Если бурение в роторе, то мы считаем только дисперсию нормированных оборотов ротора(по среднему значению). (Так как это может быть бурение в слайде с осцилляцией и выглядеть как бурение в роторе):
Если полученное значение меньше константы(0,2), то мы подтвердили что бурение в роторе.
Если полученное значение больше константы, то это бурение в слайде с осцилляцией.
## Метод определения бурения в роторе, слайде с осцилляцией
Необходимо рассчитать десперсию нормированных оборотов ротора по(по среднему значению)
1. Если полученное значение больше константы(0,2), то мы подтвердили что бурение в роторе.
2. Если полученное значение меньше константы, то это бурение в слайде с осцилляцией.

View File

@ -16,11 +16,11 @@ public class WorkOperationDetection: Work
{
private static readonly DetectorAbstract[] detectors = new DetectorAbstract[]
{
new DetectorDrilling()
// new DetectorRotor(),
// new DetectorSlide(),
//new DetectorDevelopment(),
//new DetectorTemplating(),
new DetectorSlipsTime(),
//new DetectorStaticSurveying(),
//new DetectorFlashingBeforeConnection(),
//new DetectorFlashing(),
@ -116,7 +116,6 @@ public class WorkOperationDetection: Work
{
var data = await query
.Where(d => d.DateTime > startDate)
.Take(take)
.ToArrayAsync(token);
if (data.Length < gap)
@ -125,25 +124,21 @@ public class WorkOperationDetection: Work
var isDetected = false;
var positionBegin = 0;
var positionEnd = data.Length - gap;
var step = 10;
while (positionEnd > positionBegin)
{
step ++;
for (int i = 0; i < detectors.Length; i++)
{
if (detectors[i].TryDetect(idTelemetry, data, positionBegin, positionEnd, lastDetectedOperation, out OperationDetectorResult? result))
foreach (var detector in detectors)
{
if (!detector.TryDetect(idTelemetry, data, positionBegin, positionEnd, lastDetectedOperation, out var result))
continue;
detectedOperations.Add(result!.Operation);
lastDetectedOperation = result.Operation;
isDetected = true;
step = 1;
positionBegin = result.TelemetryEnd;
break;
}
}
if (step > 20)
step = 10;
positionBegin += step;
positionBegin += 1;
}
if (isDetected)

View File

@ -0,0 +1,290 @@
using System.Collections.Generic;
using AsbCloudDb.Model;
using AsbCloudInfrastructure.Services.DetectOperations;
using AsbCloudInfrastructure.Services.DetectOperations.Detectors;
using Xunit;
namespace AsbCloudWebApi.Tests.Services.DetectedOperations.Detectors;
public class DetectorDrillingTests : DetectorDrilling
{
private const int idSlide = 5002;
private const int idRotor = 5003;
private const int idSlideWithOscillation = 12000;
[Theory]
[MemberData(nameof(TelemetryRangeDrillingRotor))]
public void DefineDrillingOperation_ShouldReturn_DrillingRotor(DetectableTelemetry[] telemetryRange)
{
//act
var result = GetIdOperation.Invoke(telemetryRange, 0, telemetryRange.Length);
//assert
Assert.Equal(idRotor, result);
}
[Theory]
[MemberData(nameof(TelemetryRangeDrillingSlide))]
public void DefineDrillingOperation_ShouldReturn_DrillingSlide(DetectableTelemetry[] telemetryRange)
{
//act
var result = GetIdOperation.Invoke(telemetryRange, 0, telemetryRange.Length);
//assert
Assert.Equal(idSlide, result);
}
[Theory]
[MemberData(nameof(TelemetryRangeDrillingSlideWithOscillation))]
public void DefineDrillingOperation_ShouldReturn_DrillingSlideWithOscillation(DetectableTelemetry[] telemetryRange)
{
//act
var result = GetIdOperation.Invoke(telemetryRange, 0, telemetryRange.Length);
//assert
Assert.Equal(idSlideWithOscillation, result);
}
[Fact]
public void IsValidOperationDetectorResult_ShouldReturn_True()
{
//arrange
var operationDetectorResult = new OperationDetectorResult
{
Operation = new DetectedOperation
{
IdReasonOfEnd = IdReasonOfEnd_PressureIsLo,
DepthStart = 5000,
DepthEnd = 6000
}
};
//act
var result = IsValidOperationDetectorResult(operationDetectorResult);
//assert
Assert.True(result);
}
[Fact]
public void IsValidOperationDetectorResult_ShouldReturn_False()
{
//arrange
var operationDetectorResult = new OperationDetectorResult
{
Operation = new DetectedOperation
{
IdReasonOfEnd = IdReasonOfEnd_PressureIsLo,
DepthStart = 5000,
DepthEnd = 5000
}
};
//act
var result = IsValidOperationDetectorResult(operationDetectorResult);
//assert
Assert.False(result);
}
public static IEnumerable<object[]> TelemetryRangeDrillingRotor()
{
yield return new object[]
{
new[]
{
new DetectableTelemetry
{
WellDepth = 4.187f,
Pressure = 27.815952f,
HookWeight = 34.221367f,
BlockPosition = 24.388f,
BitDepth = 4.187f,
RotorSpeed = 40.3f
},
new DetectableTelemetry
{
WellDepth = 4.232f,
Pressure = 28.080372f,
HookWeight = 34.162174f,
BlockPosition = 24.343f,
BitDepth = 4.232f,
RotorSpeed = 40.3f
},
new DetectableTelemetry
{
WellDepth = 4.277f,
Pressure = 29.047901f,
HookWeight = 33.688717f,
BlockPosition = 24.298f,
BitDepth = 24.298f,
RotorSpeed = 40.3f
},
new DetectableTelemetry
{
WellDepth = 4.309f,
Pressure = 29.574032f,
HookWeight = 33.692104f,
BlockPosition = 24.266f,
BitDepth = 4.309f,
RotorSpeed = 40.4f
},
new DetectableTelemetry
{
WellDepth = 4.324f,
Pressure = 24.007977f,
HookWeight = 34.838448f,
BlockPosition = 24.251f,
BitDepth = 4.324f,
RotorSpeed = 40.5f
},
new DetectableTelemetry
{
WellDepth = 4.324f,
Pressure = 24.04114f,
HookWeight = 34.423424f,
BlockPosition = 24.252f,
BitDepth = 4.323f,
RotorSpeed = 40.3f
}
}
};
}
public static IEnumerable<object[]> TelemetryRangeDrillingSlide()
{
yield return new object[]
{
new[]
{
new DetectableTelemetry
{
WellDepth = 447.276001f,
Pressure = 26.619421f,
HookWeight = 40.9143829f,
BlockPosition = 4.559f,
BitDepth = 477.265991f,
RotorSpeed = 0
},
new DetectableTelemetry
{
WellDepth = 477.289f,
Pressure = 28.716f,
HookWeight = 38.27f,
BlockPosition = 4.5f,
BitDepth = 477.289f,
RotorSpeed = 0.1f
},
new DetectableTelemetry
{
WellDepth = 477.30899f,
Pressure = 33.953495f,
HookWeight = 38.27f,
BlockPosition = 4.5359997f,
BitDepth = 477.289001f,
RotorSpeed = 0.1f
},
}
};
}
public static IEnumerable<object[]> TelemetryRangeDrillingSlideWithOscillation()
{
yield return new object[]
{
new[]
{
new DetectableTelemetry
{
IdUser = 1,
WellDepth = 415.306f,
Pressure = 53.731934f,
HookWeight = 41.049942f,
BlockPosition = 28.666f,
BitDepth = 415.293f,
RotorSpeed = 0.3f
},
new DetectableTelemetry
{
IdUser = 1,
WellDepth = 415.311f,
Pressure = 57.660595f,
HookWeight = 40.898712f,
BlockPosition = 28.648f,
BitDepth = 415.311f,
RotorSpeed = 0.2f
},
new DetectableTelemetry
{
IdUser = 1,
WellDepth = 415.326f,
Pressure = 59.211086f,
HookWeight = 40.882797f,
BlockPosition = 28.633f,
BitDepth = 415.326f,
RotorSpeed = 0.1f
},
new DetectableTelemetry
{
IdUser = 1,
WellDepth = 415.344f,
Pressure = 59.484406f,
HookWeight = 40.91972f,
BlockPosition = 28.615f,
BitDepth = 415.344f,
RotorSpeed = 0.2f
},
new DetectableTelemetry
{
IdUser = 1,
WellDepth = 415.364f,
Pressure = 60.739918f,
HookWeight = 40.795666f,
BlockPosition = 28.595f,
BitDepth = 415.364f,
RotorSpeed = 4.5f
},
new DetectableTelemetry
{
IdUser = 1,
WellDepth = 415.378f,
Pressure = 62.528984f,
HookWeight = 40.52114f,
BlockPosition = 28.581f,
BitDepth = 415.378f,
RotorSpeed = 22.6f
},
new DetectableTelemetry
{
IdUser = 1,
WellDepth = 415.392f,
Pressure = 67.0039f,
HookWeight = 38.878895f,
BlockPosition = 28.569f,
BitDepth = 415.39f,
RotorSpeed = 50f
},
new DetectableTelemetry
{
IdUser = 1,
WellDepth = 415.392f,
Pressure = 65.72418f,
HookWeight = 42.53173f,
BlockPosition = 28.622f,
BitDepth = 415.337f,
RotorSpeed = 93f
},
new DetectableTelemetry
{
IdUser = 1,
WellDepth = 415.392f,
Pressure = 56.82195f,
HookWeight = 43.15844f,
BlockPosition = 28.704f,
BitDepth = 415.255f,
RotorSpeed = 71.5f
}
}
};
}
}