From 78dca86f81992bd1b1698d9bf7b118980d954982 Mon Sep 17 00:00:00 2001 From: ngfrolov Date: Fri, 1 Jul 2022 17:04:44 +0500 Subject: [PATCH] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=B2=20=D0=B0=D0=BB=D0=B3=D0=BE=D1=80=D0=B8?= =?UTF-8?q?=D1=82=D0=BC=D0=B0=D1=85=20=D0=BE=D0=BF=D1=80=D0=B5=D0=B4=D0=B5?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BE=D0=BF=D0=B5=D1=80=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D0=B9=20=D0=BF=D0=BE=20=D0=BF=D1=80=D0=BE=D1=80?= =?UTF-8?q?=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D0=B5=20=D0=B8=20=D1=88=D0=B0?= =?UTF-8?q?=D0=B1=D0=BB=D0=BE=D0=BD=D0=B8=D1=80=D0=BE=D0=B2=D0=BA=D0=B5.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Detectors/DetectorAbstract.cs | 130 +++++++++++++++++- .../Detectors/DetectorDevelopment.cs | 22 +++ .../Detectors/DetectorSlipsTime.cs | 3 + .../Detectors/DetectorTemplating.cs | 23 ++++ .../OperationDetectionBackgroundService.cs | 8 +- .../Specifications/Бурение ротор и слайд.md | 22 +++ .../Specifications/Время в клиньях.md | 44 ------ .../Проработка перед наращиванием.md | 31 +++++ .../Specifications/Удержание в клиньях.md | 21 +++ .../Шаблонировки перед наращиванием.md | 31 +++++ 10 files changed, 284 insertions(+), 51 deletions(-) create mode 100644 AsbCloudInfrastructure/Services/DetectOperations/Specifications/Бурение ротор и слайд.md delete mode 100644 AsbCloudInfrastructure/Services/DetectOperations/Specifications/Время в клиньях.md create mode 100644 AsbCloudInfrastructure/Services/DetectOperations/Specifications/Проработка перед наращиванием.md create mode 100644 AsbCloudInfrastructure/Services/DetectOperations/Specifications/Удержание в клиньях.md create mode 100644 AsbCloudInfrastructure/Services/DetectOperations/Specifications/Шаблонировки перед наращиванием.md diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorAbstract.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorAbstract.cs index b7b5b0b1..1a9f1e17 100644 --- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorAbstract.cs +++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorAbstract.cs @@ -1,5 +1,6 @@ using AsbCloudDb.Model; using System; +using System.Collections.Generic; using System.Linq; namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors @@ -26,9 +27,9 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors { positionEnd += stepLength; if ((positionEnd > end)) - positionEnd = end; + break; - if ((positionEnd == end) || DetectEnd(telemetry, positionEnd, previousOperation)) + if (DetectEnd(telemetry, positionEnd, previousOperation)) { result = MakeOperation(idTelemetry, telemetry, begin, positionEnd); return true; @@ -132,6 +133,131 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors var result = (double)(pEnd.WellDepth - pBegin.WellDepth) / (pEnd.DateTime - pBegin.DateTime).TotalHours; return result; } + + /// + /// Расчет статистики по массиву данных за интервал + /// + /// + /// + /// + /// + /// + protected static (double min, double max, double sum, int count) CalcStat( + DetectableTelemetry[] telemetry, + Func getter, + int begin, + int count) + { + var sum = 0d; + var min = double.MaxValue; + var max = double.MinValue; + var end = begin + count; + end = end < telemetry.Length ? end : telemetry.Length; + + for (var i = begin; i < end; i++) + { + var item = telemetry[i]; + var itemValue = getter(item); + if (min > itemValue) + min = itemValue; + if (max < itemValue) + max = itemValue; + sum += itemValue; + } + return (min, max, sum, end - begin); + } + + /// + /// Максимальное отклонение от среднего за интервал + /// + /// + /// + /// + /// + /// + protected static double CalcMaxDeviation( + DetectableTelemetry[] telemetry, + Func getter, + int begin, + int count) + { + var stat = CalcStat(telemetry, getter, begin, count); + var avg = stat.sum / stat.count; + var dev1 = avg - stat.min; + var dev2 = stat.max - avg; + var dev = dev1 > dev2 ? dev1 : dev2; + return dev; + } + + /// + /// Определяет наличие разброса значений в интервале большего указанного значения. + /// + /// + /// + /// + /// + /// + /// + protected static bool ContainsDeviation( + DetectableTelemetry[] telemetry, + Func getter, + int begin, + int count, + double deviation) + { + var min = double.MaxValue; + var max = double.MinValue; + var end = begin + count; + end = end < telemetry.Length ? end : telemetry.Length; + + for (var i = begin; i < end; i ++) + { + var item = telemetry[i]; + var itemValue = getter(item); + if (min > itemValue) + min = itemValue; + if (max < itemValue) + max = itemValue; + if(max - min > deviation) + return true; + } + return false; + } + + /// + /// Определяет наличие разброса значений в интервале большего указанного значения. По нескольким значениям из интервала. + /// + /// + /// + /// + /// + /// + /// + protected static bool ContainsDeviationApprox( + DetectableTelemetry[] telemetry, + Func getter, + int begin, + int count, + double deviation) + { + var min = double.MaxValue; + var max = double.MinValue; + var end = begin + count; + end = end < telemetry.Length ? end : telemetry.Length; + var step = count > 15 ? count / 5 : count > 3 ? 3: 1; + for (var i = begin; i < end; i+= step) + { + var item = telemetry[i]; + var itemValue = getter(item); + if (min > itemValue) + min = itemValue; + if (max < itemValue) + max = itemValue; + if (max - min > deviation) + return true; + } + return false; + } } #nullable disable diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDevelopment.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDevelopment.cs index 500b414b..a78075f1 100644 --- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDevelopment.cs +++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDevelopment.cs @@ -30,9 +30,31 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors if (point0.RotorSpeed < 10) return false; + if (!ContainsDeviationApprox(telemetry, d => d.BlockPosition, position, 60, 0.03)) + return false; + return true; } + protected override bool DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation) + { + var point0 = telemetry[position]; + var delta = point0.WellDepth - point0.BitDepth; + if (delta < 0.03d || delta > 30) + return true; + + if (point0.Pressure < 15) + return true; + + if (point0.BlockPosition > 31) + return true; + + if (point0.RotorSpeed < 10) + return true; + + return false; + } + protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end) => IsValidByWellDepthDoesNotChange(telemetry, begin, end); } diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlipsTime.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlipsTime.cs index 8f0e2edc..90572270 100644 --- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlipsTime.cs +++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlipsTime.cs @@ -18,6 +18,9 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors if (delta > 2.5d) return false; + if (point0.Pressure > 15) + return false; + if (point0.BlockPosition > 8) return false; diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorTemplating.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorTemplating.cs index a623abab..f26e8a68 100644 --- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorTemplating.cs +++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorTemplating.cs @@ -1,4 +1,5 @@ using AsbCloudDb.Model; +using System.Collections.Generic; namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors { @@ -30,9 +31,31 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors if (point0.RotorSpeed > 10) return false; + if (!ContainsDeviationApprox(telemetry, d => d.BlockPosition, position, 60, 0.03)) + return false; + return true; } + protected override bool DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation) + { + var point0 = telemetry[position]; + var delta = point0.WellDepth - point0.BitDepth; + if (delta < 0.03d || delta > 30) + return true; + + if (point0.Pressure < 15) + return true; + + if (point0.BlockPosition > 31) + return true; + + if (point0.RotorSpeed > 10) + return true; + + return false; + } + protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end) => IsValidByWellDepthDoesNotChange(telemetry, begin, end); } diff --git a/AsbCloudInfrastructure/Services/DetectOperations/OperationDetectionBackgroundService.cs b/AsbCloudInfrastructure/Services/DetectOperations/OperationDetectionBackgroundService.cs index 67325c3d..2e44e1e8 100644 --- a/AsbCloudInfrastructure/Services/DetectOperations/OperationDetectionBackgroundService.cs +++ b/AsbCloudInfrastructure/Services/DetectOperations/OperationDetectionBackgroundService.cs @@ -95,7 +95,9 @@ namespace AsbCloudInfrastructure.Services.DetectOperations var affected = 0; foreach (var item in JounedlastDetectedDates) { + var stopwatch = Stopwatch.StartNew(); var newOperations = await DetectOperationsAsync(item.IdTelemetry, item.LastDate ?? DateTimeOffset.MinValue, db, token); + stopwatch.Stop(); if (newOperations.Any()) { db.DetectedOperations.AddRange(newOperations); @@ -161,13 +163,9 @@ namespace AsbCloudInfrastructure.Services.DetectOperations } if (isDetected) - { - startDate = detectedOperations.Last().DateEnd; - } + startDate = lastDetectedOperation.DateEnd; else - { startDate = data[positionEnd].DateTime; - } } return detectedOperations; diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Бурение ротор и слайд.md b/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Бурение ротор и слайд.md new file mode 100644 index 00000000..06cc4eea --- /dev/null +++ b/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Бурение ротор и слайд.md @@ -0,0 +1,22 @@ +# Алгоритм определения бурения в роторе +## Описание + +## Метод определения бурения в роторе + + Признак начала операции = + ( расстояние от долота до забоя < 0.03м ) И + ( давление > 25атм ) И + ( глубина забоя за следующую секунду больше текущей на 0.003м ) И + ( обороты ротора > 5 об/м ); + + Признак окончания операции = + ( расстояние от долота до забоя > 0.03м ) ИЛИ + ( давление < 25атм ) ИЛИ + ( среднее арифметическое оборотов ротора за 10 сек < 5 об/м ) + ( глубина забоя в течении следующих 30 сек увеличивается медленнее 1 м/час ); + +## Метод определения бурения в слайде +Повторяет метод определения бурения в роторе, за исключением условия с оборотами ротора. Это уловие нужно инвертировать. + +## Ключевой параметр +МСП = разность глубины забоя на конец и начало операции / продолжительность операции. \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Время в клиньях.md b/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Время в клиньях.md deleted file mode 100644 index fedc6b74..00000000 --- a/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Время в клиньях.md +++ /dev/null @@ -1,44 +0,0 @@ -> Из писма Гранова А.П. от 19.04.2022 13:29 "Алгоритм определения наращивания БИ.docx" - -# Алгоритм определения времени в клиньях - -## Описание: -Наращивание бурильного инструмента – операция, во время которой после добуривания очередной трубы/ свечи -циркуляция выключается, инструмент разгружается в клиньях (остается только вес крюкоблока и ВСП), -происходит развинчивание трубы от верхнего силового привода, берется очередная труба/ свеча, -свинчивается с инструментом в клиньях, свинчивается с верхним силовым приводом, происходит подъем инструмента, -вес на крюке увеличивается. Далее включается циркуляция и происходит механическое бурение. - -Наращиванию предшествует механическое бурение (наличие давления, увеличение глубины забоя) и -после наращивания механическое бурение возобновляется (наличие давления, Увеличение глубины забоя). - -> Это не учитывать в методе, так как предыдущая и последующая операция могут быть определены не корректно. - - Наращивается определяется как время между: -- разгрузкой инструмента на клинья (остается только вес крюкоблока и ВСП). - При этом давление менее 15 атм. В случае давления более 15 атм считать началом операции как - снижение давления менее 15 атм и началом движения талевого блока вверх. -- снятие инструмента с клиньев (вес увеличивается более, чем на 1т). -- При этом движение талевого блока происходит вверх. - -## Метод определения: - -> Исправлено на совещании от 19.04.2022 16:50 - -> Исправлено задачей в кайтен от 12.05.2022 16:49 - -считать время в клиньях только при соотношении глубина забоя - глубина долота меньше 2,5 метра - -``` -Признак начала операции = -(параметр «вес на крюке» < 22 тонн) И -(давление < 15 атм) И -(положение талевого блока < 8) И -(глубина забоя - глубина долота < 2,5) - - -Признак окончания операции = -(вес на крюке > 22 ) И -(давление > 15 атм) -``` - diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Проработка перед наращиванием.md b/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Проработка перед наращиванием.md new file mode 100644 index 00000000..18421cc6 --- /dev/null +++ b/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Проработка перед наращиванием.md @@ -0,0 +1,31 @@ +# Алгоритм определения шаблонировки перед наращиванием +## Описание + +Проработка перед наращиванием бурильного инструмента – операция, во время которой после добуривания очередной трубы/ свечи начинается подъем и спуск бурильного инструмента с вращением. Следующей операцией после проработки будет либо шаблонировка (аналогично проработке, но без вращения), либо разгрузка инструмента в клинья (снижение веса на крюке) - наращивание + +Проработка перед наращиванием определяется как время между: +- начало подъема/ спуска бурильного инструмента с вращением +- разгрузкой инструмента на клинья (остается только вес крюкоблока и ВСП). При этом давление менее 15 атм. ЛИБО +- начало подъема/ спуска бурильного инструмента БЕЗ вращения +- считать время на проработку только при соотношении глубина забоя - глубина долота не больше меньше 30 метров + +## Метод определения + + Признак начала операции = + ( предыдущая операция НЕ удержание в клиньях) И + ( расстояние от долота до забоя > 0.03м ) И + ( расстояние от долота до забоя < 30м ) И + ( давление > 15 атм ) И + ( положение блока < 31м ) И + ( обороты ротора > 10 об/м ) И + ( высота блока изменяется больше чем на 0.03м в течении 60 сек с начала операции); + + Признак окончания операции = + ( расстояние от долота до забоя < 0.03м ) ИЛИ + ( расстояние от долота до забоя < 30м ) ИЛИ + ( давление < 15 атм ) ИЛИ + ( положение блока > 31м ) ИЛИ + ( обороты ротора < 10 об/м ); + +## Ключевой параметр +Продолжительность операции. diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Удержание в клиньях.md b/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Удержание в клиньях.md new file mode 100644 index 00000000..fee75476 --- /dev/null +++ b/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Удержание в клиньях.md @@ -0,0 +1,21 @@ +# Алгоритм определения времени в клиньях +## Описание + +Наращивание бурильного инструмента – операция, во время которой после добуривания очередной трубы/ свечи циркуляция выключается, инструмент разгружается в клиньях (остается только вес крюкоблока и ВСП), происходит развинчивание трубы от верхнего силового привода, берется очередная труба/ свеча, свинчивается с инструментом в клиньях, свинчивается с верхним силовым приводом, происходит подъем инструмента, вес на крюке увеличивается. Далее включается циркуляция и происходит механическое бурение. + + Наращивается определяется как время между: +- разгрузкой инструмента на клинья (остается только вес крюкоблока и ВСП). При этом давление менее 15 атм. В случае давления более 15 атм считать началом операции как снижение давления менее 15 атм и началом движения талевого блока вверх. +- снятие инструмента с клиньев (вес увеличивается более, чем на 1т). При этом движение талевого блока происходит вверх. + +## Метод определения + + Признак начала операции = + ( расстояние от долота до забоя < 2.5м ) И + ( положение талевого блока < 8 ) И + ( вес на крюке < 20 тонн ) И + ( давление < 15 атм ); + + Признак окончания операции = НЕ выполняется признак начала операции; + +## Ключевой параметр +Продолжительность операции. \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Шаблонировки перед наращиванием.md b/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Шаблонировки перед наращиванием.md new file mode 100644 index 00000000..37cd488b --- /dev/null +++ b/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Шаблонировки перед наращиванием.md @@ -0,0 +1,31 @@ +# Алгоритм определения шаблонировки перед наращиванием +## Описание + +Шаблонировкаперед наращиванием бурильного инструмента – операция, во время которой после добуривания очередной трубы/ свечи начинается подъем и спуск бурильного инструмента БЕЗ вращения. Следующей операцией после шаблонировки будет либо проработка (аналогично шаблонировке, но С вращением), либо разгрузка инструмента в клинья (снижение веса на крюке) - наращивание + +Шаблонировка перед наращиванием определяется как время между: +- начало подъема/ спуска бурильного инструмента БЕЗ вращения +- разгрузкой инструмента на клинья (остается только вес крюкоблока и ВСП). При этом давление менее 15 атм. ЛИБО +- начало подъема/ спуска бурильного инструмента БЕЗ вращения +- считать время на шаблонировку только при соотношении глубина забоя - глубина долота не больше меньше 30 метров + +## Метод определения + + Признак начала операции = + ( предыдущая операция НЕ удержание в клиньях) И + ( расстояние от долота до забоя > 0.03м ) И + ( расстояние от долота до забоя < 30м ) И + ( давление > 15 атм ) И + ( положение блока < 31м ) И + ( обороты ротора < 10 об/м ) И + ( высота блока изменяется больше чем на 0.03м в течении 60 сек с начала операции); + + Признак окончания операции = + ( расстояние от долота до забоя < 0.03м ) ИЛИ + ( расстояние от долота до забоя < 30м ) ИЛИ + ( давление < 15 атм ) ИЛИ + ( положение блока > 31м ) ИЛИ + ( обороты ротора > 10 об/м ); + +## Ключевой параметр +Продолжительность операции. \ No newline at end of file