forked from ddrilling/AsbCloudServer
Merge pull request 'Алгоритм автоопределения операции "Проработка"' (#245) from feature/#29897297-conditioning into dev
Reviewed-on: http://test.digitaldrilling.ru:8080/DDrilling/AsbCloudServer/pulls/245
This commit is contained in:
commit
8c9bce8d18
9389
AsbCloudDb/Migrations/20240329070104_Update_WellOperationCategory_IdConditioning.Designer.cs
generated
Normal file
9389
AsbCloudDb/Migrations/20240329070104_Update_WellOperationCategory_IdConditioning.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,32 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace AsbCloudDb.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class Update_WellOperationCategory_IdConditioning : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "t_well_operation_category",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: 5007,
|
||||||
|
column: "name",
|
||||||
|
value: "Проработка");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "t_well_operation_category",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: 5007,
|
||||||
|
column: "name",
|
||||||
|
value: "Проработка перед наращиванием");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6484,7 +6484,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
IdParent = 4003,
|
IdParent = 4003,
|
||||||
KeyValueName = "dT",
|
KeyValueName = "dT",
|
||||||
KeyValueUnits = "мин",
|
KeyValueUnits = "мин",
|
||||||
Name = "Проработка перед наращиванием"
|
Name = "Проработка"
|
||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
|
@ -154,9 +154,9 @@ namespace AsbCloudDb.Model
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public const int IdFlashingBeforeConnection = 5005;
|
public const int IdFlashingBeforeConnection = 5005;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Проработка перед наращиванием
|
/// Проработка
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int IdDevelopment = 5007;
|
public const int IdConditioning = 5007;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Шаблонировка во время бурения
|
/// Шаблонировка во время бурения
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -278,7 +278,7 @@ namespace AsbCloudDb.Model
|
|||||||
new () {Id = IdStaticSurveying, IdParent = 4002, Name = "Замер ЗТС (запись MWD)", KeyValueName = "dT", KeyValueUnits = "мин" },
|
new () {Id = IdStaticSurveying, IdParent = 4002, Name = "Замер ЗТС (запись MWD)", KeyValueName = "dT", KeyValueUnits = "мин" },
|
||||||
new () {Id = IdFlashingBeforeConnection, IdParent = 4003, Name = "Промывка перед наращиванием", KeyValueName = "dT", KeyValueUnits = "мин" },
|
new () {Id = IdFlashingBeforeConnection, IdParent = 4003, Name = "Промывка перед наращиванием", KeyValueName = "dT", KeyValueUnits = "мин" },
|
||||||
new () {Id = 5006, IdParent = 4003, Name = "Проработка во время бурения", KeyValueName = "dT", KeyValueUnits = "мин" },
|
new () {Id = 5006, IdParent = 4003, Name = "Проработка во время бурения", KeyValueName = "dT", KeyValueUnits = "мин" },
|
||||||
new () {Id = IdDevelopment, IdParent = 4003, Name = "Проработка перед наращиванием", KeyValueName = "dT", KeyValueUnits = "мин" },
|
new () {Id = IdConditioning, IdParent = 4003, Name = "Проработка", KeyValueName = "dT", KeyValueUnits = "мин" },
|
||||||
new () {Id = IdTemplatingWhileDrilling, IdParent = 4003, Name = "Шаблонировка во время бурения", KeyValueName = "dT", KeyValueUnits = "мин" },
|
new () {Id = IdTemplatingWhileDrilling, IdParent = 4003, Name = "Шаблонировка во время бурения", KeyValueName = "dT", KeyValueUnits = "мин" },
|
||||||
new () {Id = IdTemplating, IdParent = 4003, Name = "Шаблонировка перед наращиванием", KeyValueName = "dT", KeyValueUnits = "мин" },
|
new () {Id = IdTemplating, IdParent = 4003, Name = "Шаблонировка перед наращиванием", KeyValueName = "dT", KeyValueUnits = "мин" },
|
||||||
new () {Id = 5010, IdParent = 4004, Name = "Наращивание", KeyValueName = "dT", KeyValueUnits = "мин" },
|
new () {Id = 5010, IdParent = 4004, Name = "Наращивание", KeyValueName = "dT", KeyValueUnits = "мин" },
|
||||||
|
@ -29,6 +29,7 @@ public class DetectedOperationService : IDetectedOperationService
|
|||||||
new DetectorDrilling(),
|
new DetectorDrilling(),
|
||||||
new DetectorSlipsTime(),
|
new DetectorSlipsTime(),
|
||||||
new DetectorFlashing(),
|
new DetectorFlashing(),
|
||||||
|
new DetectorConditioning(),
|
||||||
};
|
};
|
||||||
|
|
||||||
public DetectedOperationService(
|
public DetectedOperationService(
|
||||||
|
@ -0,0 +1,55 @@
|
|||||||
|
using AsbCloudApp.Data.DetectedOperation;
|
||||||
|
using AsbCloudDb.Model;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
||||||
|
{
|
||||||
|
public class DetectorConditioning : DetectorAbstract
|
||||||
|
{
|
||||||
|
protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end) =>
|
||||||
|
CalcDeltaMinutes(telemetry, begin, end);
|
||||||
|
|
||||||
|
protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperationDto? previousOperation)
|
||||||
|
{
|
||||||
|
var currentPoint = telemetry[position];
|
||||||
|
if (currentPoint.Pressure < 10)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (currentPoint.RotorSpeed <= 8)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var delta = currentPoint.WellDepth - currentPoint.BitDepth;
|
||||||
|
if (delta < 0.03d)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (currentPoint.BitDepth < 150)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperationDto? previousOperation)
|
||||||
|
{
|
||||||
|
var currentPoint = telemetry[position];
|
||||||
|
|
||||||
|
if (currentPoint.Pressure < 10)
|
||||||
|
return IdReasonOfEnd_PressureIsLo;
|
||||||
|
if (currentPoint.RotorSpeed <=8)
|
||||||
|
return IdReasonOfEnd_RotorSpeedIsHi;
|
||||||
|
if ((currentPoint.WellDepth - currentPoint.BitDepth) < 0.03d)
|
||||||
|
return IdReasonOfEnd_DeltaWellDepthAndBithDepthIsLo;
|
||||||
|
if (currentPoint.BitDepth < 150)
|
||||||
|
return IdReasonOfEnd_BithDepthIsLo;
|
||||||
|
return IdReasonOfEnd_NotDetected;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override (int IdCategory, IDictionary<string, object> ExtraData) GetSpecificInformation(DetectableTelemetry[] telemetry, int begin, int end)
|
||||||
|
{
|
||||||
|
return (WellOperationCategory.IdConditioning, new Dictionary<string, object>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -23,7 +23,7 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
var delta = currentPoint.WellDepth - currentPoint.BitDepth;
|
var delta = currentPoint.WellDepth - currentPoint.BitDepth;
|
||||||
if (delta < 0.03d)
|
if (delta < 0.01d)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (currentPoint.RotorSpeed > 8)
|
if (currentPoint.RotorSpeed > 8)
|
||||||
@ -47,7 +47,7 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
|||||||
|
|
||||||
if (currentPoint.Pressure < 10)
|
if (currentPoint.Pressure < 10)
|
||||||
return IdReasonOfEnd_PressureIsLo;
|
return IdReasonOfEnd_PressureIsLo;
|
||||||
if ((currentPoint.WellDepth - currentPoint.BitDepth) < 0.03d)
|
if ((currentPoint.WellDepth - currentPoint.BitDepth) < 0.01d)
|
||||||
return IdReasonOfEnd_DeltaWellDepthAndBithDepthIsLo;
|
return IdReasonOfEnd_DeltaWellDepthAndBithDepthIsLo;
|
||||||
if (currentPoint.RotorSpeed > 8)
|
if (currentPoint.RotorSpeed > 8)
|
||||||
return IdReasonOfEnd_RotorSpeedIsHi;
|
return IdReasonOfEnd_RotorSpeedIsHi;
|
||||||
|
@ -13,13 +13,13 @@
|
|||||||
Признак начала операции =
|
Признак начала операции =
|
||||||
( давление >= 10 атм ) И
|
( давление >= 10 атм ) И
|
||||||
( обороты ротора <= 8 об/мин) И
|
( обороты ротора <= 8 об/мин) И
|
||||||
( расстояние от долота до забоя >= 0.03 м) И
|
( расстояние от долота до забоя >= 0.01 м) И
|
||||||
( глубина забоя не изменяется) И
|
( глубина забоя не изменяется) И
|
||||||
( глубина долота >= 150 м);
|
( глубина долота >= 150 м);
|
||||||
|
|
||||||
Признак окончания операции =
|
Признак окончания операции =
|
||||||
( давление < 10 атм ) ИЛИ
|
( давление < 10 атм ) ИЛИ
|
||||||
( расстояние от долота до забоя < 0.03 м ) ИЛИ
|
( расстояние от долота до забоя < 0.01 м ) ИЛИ
|
||||||
( обороты ротора > 8 об/мин) ИЛИ
|
( обороты ротора > 8 об/мин) ИЛИ
|
||||||
( глубина долота < 150 м);
|
( глубина долота < 150 м);
|
||||||
|
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
# Алгоритм определения проработки
|
||||||
|
## Описание
|
||||||
|
|
||||||
|
Проработка – операция, во время которой производится подъем или спуск бурильного инструмента с вращением и циркуляцией. Следующей операцией после проработки будет либо шаблонировка (аналогично проработке, но БЕЗ вращением и циркуляции), либо разгрузка инструмента в клинья (снижение веса на крюке) – наращивание или отворот бурильного инструмента.
|
||||||
|
|
||||||
|
Проработка определяется как время между:
|
||||||
|
- начало подъема/спуска бурильного инструмента с циркуляцией и вращением;
|
||||||
|
- разгрузкой инструмента на клинья (остается только вес крюкоблока и ВСП). При этом давление менее 20 атм. ЛИБО
|
||||||
|
- начало подъема/спуска бурильного инструмента с циркуляцией, НО БЕЗ вращения
|
||||||
|
Разделяется два вида проработки:
|
||||||
|
1. перед наращиванием - соотношение глубины забоя и глубины долота <= 30 метров;
|
||||||
|
2. при спуско-подъёмных операциях (СПО)соотношение глубины забоя - глубины долота > 30 метров.
|
||||||
|
|
||||||
|
## Метод определения
|
||||||
|
|
||||||
|
Признак начала операции =
|
||||||
|
( давление >= 10 атм ) И
|
||||||
|
( обороты ротора > 8 об/мин ) И
|
||||||
|
( расстояние от долота до забоя >= 0.03м ) И
|
||||||
|
( глубина долота >= 150м);
|
||||||
|
|
||||||
|
Признак окончания операции =
|
||||||
|
( обороты ротора <= 8 об/мин ) ИЛИ
|
||||||
|
( давление < 10 атм ) ИЛИ
|
||||||
|
( расстояние от долота до забоя < 0.03м ) ИЛИ
|
||||||
|
( глубина долота < 150м);
|
||||||
|
|
||||||
|
## Ключевой параметр
|
||||||
|
Продолжительность операции.
|
@ -0,0 +1,92 @@
|
|||||||
|
using AsbCloudDb.Model;
|
||||||
|
using AsbCloudInfrastructure.Services.DetectOperations;
|
||||||
|
using AsbCloudInfrastructure.Services.DetectOperations.Detectors;
|
||||||
|
using System;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace AsbCloudWebApi.Tests.Services.DetectedOperations.Detectors;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Тестирование автоопределения операции "Проработка"
|
||||||
|
/// </summary>
|
||||||
|
public class DetectorConditioningTests : DetectorFlashing
|
||||||
|
{
|
||||||
|
private readonly DetectorConditioning detector = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Операция, попадающая под автоопределение операции промывки
|
||||||
|
/// </summary>
|
||||||
|
private readonly DetectableTelemetry telemetry = new()
|
||||||
|
{
|
||||||
|
Pressure = 21,
|
||||||
|
RotorSpeed = 9,
|
||||||
|
WellDepth = 152,
|
||||||
|
BitDepth = 151,
|
||||||
|
DateTime = DateTimeOffset.Now,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void DetectOperation_find_startOperation_notFind_endOperation()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
var point0 = telemetry.Copy();
|
||||||
|
var point1 = telemetry.Copy();
|
||||||
|
point1.DateTime = point0.DateTime.AddMinutes(3);
|
||||||
|
|
||||||
|
var telemetries = new[] { point0, point1 };
|
||||||
|
|
||||||
|
//act
|
||||||
|
var isDetectOperation = detector.TryDetect(0, telemetries, 0, telemetries.Length - 1, null, out var result);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.True(isDetectOperation);
|
||||||
|
Assert.NotNull(result);
|
||||||
|
Assert.Equal(WellOperationCategory.IdConditioning, result.Operation.IdCategory);
|
||||||
|
Assert.Equal(IdReasonOfEnd_NotDetected, result.Operation.ExtraData["IdReasonOfEnd"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void DetectOperation_with_BitDepth_LE_150_is_fail()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
var point0 = telemetry.Copy();
|
||||||
|
point0.BitDepth = 150;
|
||||||
|
|
||||||
|
var point1 = telemetry.Copy();
|
||||||
|
|
||||||
|
var telemetries = new[] { point0, point1 };
|
||||||
|
|
||||||
|
//act
|
||||||
|
|
||||||
|
var isDetectOperation = detector.TryDetect(0, telemetries, 0, telemetries.Length - 1, null, out var result);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.False(isDetectOperation);
|
||||||
|
Assert.NotNull(result);
|
||||||
|
Assert.Equal(WellOperationCategory.IdConditioning, result.Operation.IdCategory);
|
||||||
|
Assert.Equal(IdReasonOfEnd_NotDetected, result.Operation.ExtraData["IdReasonOfEnd"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void DetectOperations_Begin_And_End_by_Pressure_Less_10_is_success()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
var point0 = telemetry.Copy();
|
||||||
|
var point1 = telemetry.Copy();
|
||||||
|
point1.Pressure = 9;
|
||||||
|
|
||||||
|
var telemetries = new[] { point0, point1 };
|
||||||
|
|
||||||
|
//act
|
||||||
|
var isDetectOperation = detector.TryDetect(0, telemetries, 0, telemetries.Length - 1, null, out var result);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.False(isDetectOperation);
|
||||||
|
Assert.NotNull(result);
|
||||||
|
Assert.Equal(WellOperationCategory.IdConditioning, result.Operation.IdCategory);
|
||||||
|
Assert.Equal(IdReasonOfEnd_PressureIsLo, result.Operation.ExtraData["IdReasonOfEnd"]);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user