Pull to refresh

Эксперименты с самодельным компьютером воздушных данных

Level of difficultyMedium
Reading time6 min
Views4.9K

В авиации для измерения скорости движения летательного аппарата в воздушной среде используется трубка Пито и электронный вычислитель или air data computer.

Многие авиационные ADC измеряют полное и статическое давление от набегающего потока и с помощью нехитрых формул получают несколько параметров, необходимых для выполнения полетов - высота, вертикальная скорость и воздушная скорость.

Для измерения барометрической высоты в теории и в большинстве случаев и на практике - достаточно одного датчика абсолютного давления, например простой датчик Bosch bmp180 вполне для этого подходит.

Когда же появляется задача достаточной точности в 1 метр или еще лучше в 10 см то тут нужны более точные датчики и немного иные измерения.

Для измерения воздушной или приборной скорости полета, нужно уже использовать датчик дифференциального давления, чтобы из полного давления, принимаемого в трубку Пито - получить давление динамическое.

В промышленности для этого используют подобные датчики и системы, называемые дифференциальными.

Стало интересно сделать свою реализацию барокамер для двух отдельных датчиков и попробовать с их помощью получить заветные значения высоты и воздушной скорости.

Хотя технически это осуществимо, использование двух датчиков абсолютного давления с погрешностью ±1 кПа, скорее всего, приведет к большим неопределенностям на более низких скоростях полета(от 0 до 30 км/ч).

Но меня подстёгивала именно идея "попробовать" и после уже сделать выводы.

Опять таки, всем известный датчик фирмы TE модель MS4525DO

Или модель MPX12DP

Кстати, MS4525DO хоть и имеет промышленно выполненный корпус и барокамеры, содержит всего лишь 14-битный АЦП

В модуле, с которым провожу эксперимент, планирую использовать два датчика MS5611 фирмы MEAS Switzerland с 24-битным АЦП.

Приступаю к моделированию корпуса, чтобы потом напечатать его на 3д принтере.

Но моделирование оказалось не самым сложным в этом процессе, сложнее оказалось напечатать и собрать герметичные барокамеры, и это оказалось очень сложной задачей.

Проект практически был приостановлен, потому что около 2-х недель были попытки найти оптимальную технологию печати и варианты барокамер.

Первая причина проблем - использование 3Д печати, как мы все знаем, печать выполняется методом экструзии пластика и соответственно неминуемо мы имеет пустоты и поры

А если 3д принтер невысокого качества то можно получить вообще решето как ниже не фото

А вот печать на более качественном 3д принтере черным PETG пластиком

Серым ABS пластиком

Но все равно, даже на 100 % заполнении пластиков, получаемые барокамеры травили воздух и вся идея сходила на нет.

Было решено сделать барокамеры отдельным модулем и печатать их на фотополимерном принтере, в итоге сделано несколько вариантов барокамер

Вроде бы все, проблемы негерметичности решены, но и тут не обошлось без некоторых утечек в местах прохождения проводов от датчиков к микроконтроллеру.

Еще немного повозившись с герметизацией стыков и отверстий я получил 100% герметизацию барокамер.

Чем собственно я проверяю герметичность? Обычно в авиации используют специальные air data test set'ы или установки калибровки давления, в самом простом варианте это КПУ-3

Я для этих целей применил модифицированный манометр низкого давления(0-6 кПа) и высокотехнологичный медицинский шприц на 20 мл

Сам манометр немного модифицировал, наклеив шкалу в knots и получилась такая установка

Для пересчета давления в воздушную скорость пришлось прибегнуть к некоторым расчетам, не претендующим на великую точность, но очень близкими к реальности

Конструктивно и аппаратно все было готово к испытаниям, оставалось написать небольшой код для вычисления высот и скоростей полета

код для вычисления скоростей

// Структура для хранения IAS и TAS

typedef struct {

    float ias_m_s; // Indicated Airspeed in m/s

    float ias_kmh; // Indicated Airspeed in km/h

    float ias_knots; // Indicated Airspeed in knots

    float tas_m_s; // True Airspeed in m/s

    float tas_kmh; // True Airspeed in km/h

    float tas_knots; // True Airspeed in knots

} Speeds;

// Функция для вычисления давления по высоте

static inline double calcPressure(double alti) {

    return (1013.25 pow((1.0 - (6.5 alti / 288150.0)), 5.255));

}

// Methods for Athmosphere Model used in Aviation

// With density of water from: http://www.csgnetwork.com/waterinformation.html

// @ 22.8 degree: 0.997585

// earth gravity: 9.0807 m/s^2

// and standard ICAO air density with 1.225 kg/m3 there is:

// V(km/h) = sqrt(2*( <mmH2O> 0.997585 9.807  )/1.225) * 3.6

// Функция для расчета IAS и TAS на основе давления, высоты и температуры

static inline Speeds calculateSpeeds(float pascal, float altitude, float temp) {

    // Проверяем, если динамическое давление меньше или равно нулю

    if (pascal <= 0) {

        return (Speeds){0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; // Устанавливаем IAS и TAS в 0

    }

    // Вычисляем IAS из давления в Паскалях (м/с)

    float ias_m_s = sqrt(2 * pascal / 1.225);

   

    // Преобразуем IAS в км/ч и узлы

    float ias_kmh = ias_m_s * 3.6;

    float ias_knots = ias_m_s * 1.94384;

    // float ias_knots = ias_kmh / 1.852;

    // Вычисляем TAS на основе IAS (в м/с)

    // https://en.wikipedia.org/wiki/True_airspeed#Calculating_true_airspeed

    double pressureRatio = calcPressure(altitude) / 1013.25;

    float tas_m_s = ias_m_s / sqrt(288.15 / (temp + 273.15) * pressureRatio);

   

    // Преобразуем TAS в км/ч и узлы

    float tas_kmh = tas_m_s * 3.6;

    float tas_knots = tas_m_s * 1.94384;

    // Возвращаем значения в структуре

    Speeds speeds = {ias_m_s, ias_kmh, ias_knots, tas_m_s, tas_kmh, tas_knots};

    return speeds;

}

код для вычисления высот

float Variometer::calcAltitude(long pressure)

{

  return 44330 * (1.0 - pow((float) pressure / (float) this->qnh, 0.1903));

}

В основном тут простая математика, основанная на данных давлений, получаемых от двух датчиков абсолютного давления, установленных в раздельных барокамерах.

Высота вычислялась с помощью вычисления атмосферного давления одним датчиком, я назвал его STATIC.

Скорость воздушная вычисляется путем вычитания из полного давления PRESSURE давления STATIC, тем самым получаем давление динамическое, которое уже подставляется в формулу, тем самым рассчитывается скорость полета IAS.

Для получения скорости полета истинной - TAS, что для малой авиации в основном не так применимо, требуется коррекция скорости в зависимости от высоты полета и температуры воздуха, т.к. все мы знаем, что с высотой воздух становиться более разряженным, а самолет летит "опираясь" крылом на этот самый воздух и очень важно знать скорость TAS.

Есть еще скорость GS, но ее можно вычислить только по GPS или с помощью инерциального блока.

До проверки в железе, весь код был успешно оттестирован на основе симуляции давлений в авиасимуляторе FlightGear

Данные полученные посредством формул были близки с получаемыми в полете.

Компьютер воздушных данных выдает данные воздушной скорости, высоты полета и вертикальной скорости в шину CAN и соединен с указателем

P.S. Самым сложным моментом при создании блока измерения воздушных данных была не только герметизация барокамер, но и написание кода для вычисления вертикальной скорости или скорости изменения высоты полета.

В механических вариометрах для этого используется система анероидной коробки и капилляра, а как это реализовать в коде ... пришлось некоторое время порыться в интернете в поисках кода и решений, которое в итоге привело к написанию рабочего класса на основе решения для параглайдеров

// alghoritm like here

// https://www.instructables.com/DIY-Arduino-Variometer-for-Paragliding/

void Variometer::calcVario(long now)

{

  float N1 = 0;

  float N2 = 0;

  float N3 = 0;

  float D1 = 0;

  float D2 = 0;

  // move the array one position to the left

  for(int i = 1; i <= MAX_SAMPLES; i++)

  {

    this->pressureArray[(i - 1)] = this->pressureArray[i];

    this->timeArray[(i - 1)] = this->timeArray[i];

  };

  // after moving, add the new value to the end of the array

  this->pressureArray[MAX_SAMPLES] = this->lastPressure;

  this->timeArray[MAX_SAMPLES] = now;

  float elapsedTime = this->timeArray[MAX_SAMPLES - SAMPLES];

  for(int i = (MAX_SAMPLES - SAMPLES); i < MAX_SAMPLES; i++)

  {

    float altitude = calcAltitude(this->pressureArray[i]);

    N1 += (this->timeArray[i] - elapsedTime) * altitude;

    N2 += (this->timeArray[i] - elapsedTime);

    N3 += (altitude);

    D1 += (this->timeArray[i] - elapsedTime) * (this->timeArray[i] - elapsedTime);

    D2 += (this->timeArray[i] - elapsedTime);

  };

  // this->vario = 1000 ((SAMPLES N1) - N2 N3) / (SAMPLES D1 - D2 * D2);

  this->vario = intervalVario ((SAMPLES N1) - N2 N3) / (SAMPLES D1 - D2 * D2);

}

Tags:
Hubs:
Total votes 20: ↑20 and ↓0+29
Comments24

Articles