Уголок коптер-программиста

Gene

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

алгоритмы полета и стабилизации
снятие и обработка показаний датчиков
организация управления
трехмерные расчеты
оптимизация кода для различных платформ
и т.д. в том же духе.

(А то сегодня убил 3 часа, пытаясь найти одну ссылку, которую я видел на форуме месяц назад, но не помню где и по какому поводу…)

Внесу первую лепту:

интересный документ об аппроксимации основных тригонометрических функций.

Sir_Alex

Вот что у меня накопилось по алгоритмам:
Nonlinear Complementary Filters on the Special Orthogonal Group
A Complementary Filter for Attitude Estimation of a Fixed-Wing UAV
Complementary filter design on the Special Euclidean group SE(3)
Coupled Estimation And Control
Direction Cosine Matrix IMU: Theory

Datasheets по основным сенсорам (их найти не проблема, но тут всё что надо в одном месте):
BMA020 - Accel
BMA180 - Accel.PDF
BMP085 - Pressure.pdf
HMC5883L - Triple axis Magnetometr.pdf
ISZ500 Z-Axis gyro.pdf
ITG3200 - Triple axis Gyro.pdf
MPU6000A - Gyro and Accel.pdf
MS5611 - Pressure.pdf

Gene

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

Кстати, именно Ваши ссылки, шедро разбросанные по всему форуму, особенно хотелось бы свести в кучку…

mahowik

я не к тому, что тема не правильная, а то что там тоже ссылки полезные есть… 😉

upd: да и сам я новичек во многих вопросах… классика: чем больше знаем, тем больше не знаем 😃

sergebezborodov

приветствую, самого очень интересует тема программирования “под коптеры”

может у кого либо есть наработки крайне простого контроллера только на гироскопах написанного на С? или исходники “раннего” мультивия
т.е. чтобы была простейшая связь - приемника - гироскоп - моторы, без каких либо других фич

mahowik

так это лучше взять из свежей версии, но только то, что к акро моду относится… посмотрите MultiWii.ino, снизу конечный пид регулятор, на “сырых” (но слегка усредненных) показаниях гиры…

DVE

Пол дня потратил чтобы нормально подключить Crius LCD, оказалось 2 подводных камня:

  • встроенная i2c-библиотека Wire для Arduino почему-то так и не заработала, код скопированный из Multiwii работает нормально. Хз в чем там разница, разбираться стало влом.
  • экранчику нужно 2 подтягивающих резистора на i2c, иначе вообще не запускается, и кондер на питание к разъему, иначе на экране мусор.

Результат - вполне удобное средство отладки за 7$, всего с 4 проводами 😃

DVE

Да, про это я читал, но резать дорожки точно влом, кондер на питание спасает нормально от просадок. Больше интересно почему штатная библиотека не заработала, а код скопипастенный из Wii работает.

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

1 month later
Gene

Стыдно 😃 Сам открыл тему и ничего практически не написал… Вот хочу поделиться такими замечательными аппроксимациями (надергал в разных местах, малость адаптировал под ардуину, вовсю применяю в софте своего подвеса):

Синус и косинус. Четыре или пять умножений, несколько сложений, на выходе результат, отличимый от настоящего только под микроскопом. Магия-с!

float _sin (float x) {
x = x * 0.31831f;
float y = x - x * abs(x);
return y * (3.1f + 3.6f * abs(y));
}

float _cos (float x) {
x = x * 0.31831f + 0.5f;
float z = (x + 25165824.0f);
x = x - (z - 25165824.0f);
float y = x - x * abs(x);
return y * (3.1f + 3.6f * abs(y));
}

Арктангенс. Прошу заметить – не atan2, и не целочисленный, а самый обычный, с плавающей точкой, полностью заменяющий родной atan:

float _atan( float x )
{
    uint32_t ux_s  = 0x80000000 & (uint32_t &)x;
    float bx_a = ::fabs( 0.596227f * x );
    float num = bx_a + x * x;
    float atan_1q = num / ( 1.f + bx_a + num );
    uint32_t atan_2q = ux_s | (uint32_t &)atan_1q;
    return (float &)atan_2q * 1.5708f;
}

Ну и на закуску, инвертированнный квадратный корень 1/sqrt(x) с аутентичным комментарием Джона Кармака в самом интересном месте:

float isqrt( float y )
{
float x2 = y * 0.5f;
long i = * ( long * ) &y;    //evil floating point bit level hacking
i = 0x5f3759df - ( i >> 1 ); //what the fuck?
y = * ( float * ) &i;
y = y * ( 1.5f - ( x2 * y * y ) );
return y;
}
mahowik
Gene:

инвертированнный квадратный корень 1/sqrt(x)

а вот виевский вариант схожий

float InvSqrt (float x){
  union{
    int32_t i;
    float   f;
  } conv;
  conv.f = x;
  conv.i = 0x5f3759df - (conv.i >> 1);
  return 0.5f * conv.f * (3.0f - x * conv.f * conv.f);
}
Gene:

не atan2, и не целочисленный

целочисленный тоже может быть полезен

int16_t _atan2(float y, float x){
  #define fp_is_neg(val) ((((uint8_t*)&val)[3] & 0x80) != 0)
  float z = y / x;
  int16_t zi = abs(int16_t(z * 100));
  int8_t y_neg = fp_is_neg(y);
  if ( zi < 100 ){
    if (zi > 10)
     z = z / (1.0f + 0.28f * z * z);
   if (fp_is_neg(x)) {
     if (y_neg) z -= PI;
     else z += PI;
   }
  } else {
   z = (PI / 2.0f) - z / (z * z + 0.28f);
   if (y_neg) z -= PI;
  }
  z *= (180.0f / PI * 10);
  return z;
}

ну и простейшие аппроксимации для малых углов

// Small angle approximation
#define ssin(val) (val)
#define scos(val) 1.0f
serj
Sir_Alex:

Сказали, А, говорите и В 😃 в смысле, register map…
Увы, я свой выложить не могу, лицензионное соглашение сдуру на себя подписал.