Создание собственной системы стабилизации

rual
alexeykozin:

к примеру в ардукоптре
стаб пиды: угловая ошибка * стаб P,D
рэйт пиды: ошибка угловой скорости * рэйт P,D
управляющий сигнал: стаб+рэйт

Вот это интересная тема пошла! Самому было лень копаться в адрдупилоте, интересно послушать тех кто на нём “собаку съел”.
По сути получается в Акоптере режим “ливел” (так вроде называется, если маразм не подводит) получается добавлением стаба угла к режиму “акро” и переключением входа стаба “акро” с “ручек” на величину ошибки угла?

alexeykozin:

m*d*omega=Ft

Тут я не понял… F- тяга, t-время, omega (w) - угловая скорость, d - двойная удельная (для распределенной массы) длина плеча силы ? Тогда m*d*omega= интеграл F(t) *dt, но для постоянной F верно…
Вот опять не увидел И звено в пидах. Что будет если к одному лучу подвесить небольшой груз?

Drinker:

Ну это в тему о темп компенсации. ИМХО на микроэлектромеханике это абсурд.

Согласен на 100%.

SergDoc:

мелкой только половина, так и хочется в иму влепить проц отдельный - парадокс в разъёмах )))

Серёг, это уже есть , у тебя дешевле выйдет?

SergDoc:

а воспримет ли инвертор (на XOR) PPM?

Вообще пофиг, можно в драйвере всё предусмотреть, всё равно новую прошиву под плату клепать. Если ловит только по спаду или фронту, то вообще ничего не надо делать, будет хоть через два инвертора работать ))))

SergDoc:

инвертор где-то такой лежит - надо пробовать…

вот это правильно!

SergDoc
rual:

Серёг, это уже есть , у тебя дешевле выйдет?

это не то ))) дёшево не будет, но назоводы должны кипятком писаться))) короче всё в своё время…

alexeykozin
rual:

Вот опять не увидел И звено в пидах. Что будет если к одному лучу подвесить небольшой груз?

ну никто не говорит о том что нужно исключить небольшую адаптивную автоподстройку пидов
указать небольшой диапазон автокоррекции и уже походу полета в зависимости от показаний сенсоров калькулировать коррекцию

Sir_Alex

О! Я смотрю тут пипками начали мерятся расчехлили линейки!

Тогда берем вот это

К нему делаем таких же размеров IO борду и вперёд!

alexeykozin

имхо это не FMU а IMU т.е. исключительно ориентация помимо ио к нему нужен котроллер в котором будет реализвана логика управления аппаратом (стабилизации, навигации)
обычно первой приходит идея впихнуть все в интегрированный проц. но потом оказывается что и флеши у нее мало и рама только на иму

Sir_Alex
alexeykozin:

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

Именно такая идея )) Ну а что, полетнег летающий только в режиме LEVEL, наверное можно сделать. )))) Я конечно шучу, но вдруг кто нибудь забацает. Или например задействует проц в MPU…

SergDoc
oleg70:

А это ?

401-й проц (48 без лап) 9250 и5611 - минимализм - но проблема AEKF потянет герцах на 200, и юзверю интерфейсов мало, как встраиваемое решение в какой-нибудь мелкоквадрик…

oleg70
SergDoc:

но проблема AEKF потянет герцах на 200

А что там ему делать ?..
Сделал вот - просто кватернионный метод, чуток смешал магнитометер+аксель и баро+аксель, на выходе нормальные углы, высота с шумом 20 см… , все это на 500 Гц работает (хотя и впритык уже - 72 Мгц и нет fpu)

alekseii

Может не совсем по теме, может кто подскажет (покажет, если не секрет), как определить длительности входных сигналов управления (6-ть или 7 и все идут в разнобой - передние фронты не совпадают). Нужно на языке С (С++, CodeVisionAVR) 😃

rual
alekseii:

определить длительности входных сигналов управления

Засечь таймером? 😉 Вычислитель какой?

На Ардуине можно просто засекать время (uint32t time = millis(); ) фронта/спада прикрыванием, полученная разность будет длительностью.

SergDoc
oleg70:

А что там ему делать ?..

если рассматривать как imu то и нормально те-же 72 мегагерца только с FPU, считать углы… А чем скорости и путь пройденный считать? в принципе тоже можно особо не напряжет, потом встаёт делема - куда GPS засунуть? на второй проц и там считать INS? ПИД-ы и всю лабуду? смысл - если всё это на одном 405/407 работает… единственный плюс в процессоре в imu - унести подальше от полётника с минимумом проводов - тот же can, хотя мне больше SPI импонирует - 7 проводов (это с питанием и прерыванием готовности) в жгут с оплёткой… хотя выходя из этого всего то нафиг процу в imu что-то считать если всё равно пересчитываться будет - берём самый маленький и простенький который нам с частотой 400 + соберёт данные от датчиков и отдаст… всё вся его работа…

strizhmax
SergDoc:

хотя мне больше SPI импонирует - 7 проводов (это с питанием и прерыванием готовности) в жгут с оплёткой…

7й - это какой, никак не могу придумать? Оплётка?

alekseii

Мне нужно для avr 8 битного контроллера, я любитель, пока немного разобрался именно в этой программе. По 8 битному таймеру в подпрограмме прерывания (совпадению или переполнению), делал инкремент переменной (вход_1, например), а в основной программе отслеживаем входные фронты и соответственно разрешаем в программе прерывания увеличивать ту или иную переменную (вход_1, …,вход_6), так упрощённо. Делал два флага (один для отслеживания передних фронтов, другой об окончании данного сигнала и его же использовал для подсчёта и выхода из “отсчитывающего” цикла). Делал в разных вариациях но устойчивого считывания так и не получил.
Для одного сигнала (или нескольких но у которых передние фронты не смещены относительно друг друга) всё просто:
цыкл while (ждём на входе 0 (нуль)) {}; // отслеживаем начало переднего фронта
цыкл while (ждём на входе 1 (единица)){}; сигнал пришёл
таймер старт {};
цыкл while (ждём на входе 0 (нуль)) {}; // сигнал окончился
таймер стоп {};
имеем значение в переменной вход_1.
А для нескольких “смещёных” сигналов ни как не получается.

SergDoc

в мультивие например:

**************************************************************************************/
/***************               Standard RX Pins reading            ********************/
/**************************************************************************************/
#if defined(STANDARD_RX)

#if defined(FAILSAFE) && !defined(PROMICRO)
   // predefined PC pin block (thanks to lianj)  - Version with failsafe
  #define RX_PIN_CHECK(pin_pos, rc_value_pos)                        \
    if (mask & PCInt_RX_Pins[pin_pos]) {                             \
      if (!(pin & PCInt_RX_Pins[pin_pos])) {                         \
        dTime = cTime-edgeTime[pin_pos];                             \
        if (900<dTime && dTime<2200) {                               \
          rcValue[rc_value_pos] = dTime;                             \
          if((rc_value_pos==THROTTLEPIN || rc_value_pos==YAWPIN ||   \
              rc_value_pos==PITCHPIN || rc_value_pos==ROLLPIN)       \
              && dTime>FAILSAFE_DETECT_TRESHOLD)                     \
                GoodPulses |= (1<<rc_value_pos);                     \
        }                                                            \
      } else edgeTime[pin_pos] = cTime;                              \
    }
#else
   // predefined PC pin block (thanks to lianj)  - Version without failsafe
  #define RX_PIN_CHECK(pin_pos, rc_value_pos)                        \
    if (mask & PCInt_RX_Pins[pin_pos]) {                             \
      if (!(pin & PCInt_RX_Pins[pin_pos])) {                         \
        dTime = cTime-edgeTime[pin_pos];                             \
        if (900<dTime && dTime<2200) {                               \
          rcValue[rc_value_pos] = dTime;                             \
        }                                                            \
      } else edgeTime[pin_pos] = cTime;                              \
    }
#endif

  // port change Interrupt
  ISR(RX_PC_INTERRUPT) { //this ISR is common to every receiver channel, it is call everytime a change state occurs on a RX input pin
    uint8_t mask;
    uint8_t pin;
    uint16_t cTime,dTime;
    static uint16_t edgeTime[8];
    static uint8_t PCintLast;
  #if defined(FAILSAFE) && !defined(PROMICRO)
    static uint8_t GoodPulses;
  #endif

    pin = RX_PCINT_PIN_PORT; // RX_PCINT_PIN_PORT indicates the state of each PIN for the arduino port dealing with Ports digital pins

    mask = pin ^ PCintLast;   // doing a ^ between the current interruption and the last one indicates wich pin changed
    cTime = micros();         // micros() return a uint32_t, but it is not usefull to keep the whole bits => we keep only 16 bits
    sei();                    // re enable other interrupts at this point, the rest of this interrupt is not so time critical and can be interrupted safely
    PCintLast = pin;          // we memorize the current state of all PINs [D0-D7]

    #if (PCINT_PIN_COUNT > 0)
      RX_PIN_CHECK(0,2);
    #endif
    #if (PCINT_PIN_COUNT > 1)
      RX_PIN_CHECK(1,4);
    #endif
    #if (PCINT_PIN_COUNT > 2)
      RX_PIN_CHECK(2,5);
    #endif
    #if (PCINT_PIN_COUNT > 3)
      RX_PIN_CHECK(3,6);
    #endif
    #if (PCINT_PIN_COUNT > 4)
      RX_PIN_CHECK(4,7);
    #endif
    #if (PCINT_PIN_COUNT > 5)
      RX_PIN_CHECK(5,0);
    #endif
    #if (PCINT_PIN_COUNT > 6)
      RX_PIN_CHECK(6,1);
    #endif
    #if (PCINT_PIN_COUNT > 7)
      RX_PIN_CHECK(7,3);
    #endif

    #if defined(FAILSAFE) && !defined(PROMICRO)
      if (GoodPulses==(1<<THROTTLEPIN)+(1<<YAWPIN)+(1<<ROLLPIN)+(1<<PITCHPIN)) {  // If all main four chanells have good pulses, clear FailSafe counter
        GoodPulses = 0;
        if(failsafeCnt > 20) failsafeCnt -= 20; else failsafeCnt = 0;
      }
    #endif
  }

code.google.com/p/multiwii/source/…/RX.cpp

alekseii

Сергей спасибо !
Так сразу не понятно, буду разбираться 😃

rual
strizhmax:

7й - это какой, никак не могу придумать? Оплётка?

Наверное выход готовности, хотя я думаю можно обойтиясь 6ю, ибо сам SPI может генерить прерывания по приёму байта или слова.

SergDoc

Как-то обсуждалось hom.hackpad.com/SmartIMU-E9zzbSI7QyK
так вскользь, так вот там подпаяться только, 4 выхода шим есть, думаю и поймать чем сигнал с приёмыша есть… мелко мелко готово )))

rual:

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

может конечно, но если использовать DMA мы можем его и не дождаться, раз, потом чёт я плохо представляю как устройство стоящее слейвом может по своей прихоти что-то пихнуть?

rual
SergDoc:

может конечно, но если использовать DMA мы можем его и не дождаться,

Где и как его использовать? При чтении данных из ИМУ? Вообще надо чтобы был полноценный межпроцессорный обмен.

SergDoc:

чёт я плохо представляю как устройство стоящее слейвом может по своей прихоти что-то пихнуть?

Я предполагал что голова у датчиков, а многоногий проц ведомый. К тому ж пиксавом РТОСе есть вроде возможность использовать виртуальные порты? И получить по сути ПХ4, что актуально для порта Ардупилота.

SergDoc

если “голова” у датчиков, то как следствие нужен мощный проц, тогда отпадает всякое рвение использовать многоногий ведомый - легче на одном всё…

rual
SergDoc:

как следствие нужен мощный проц, тогда отпадает всякое рвение использовать многоногий ведомый - легче на одном всё…

Что касается больших ЛА - это да. Но я так понимаю, что мотивация “разделить мозги” идёт не от недостатка мощи, а от желания улучшить компоновку для маленьких моделей. Для больших и средних та же Ф4БЫ вполне оптимальна по функционалу и размерам, тот же visasta делает одноплатные мозги на многоногом проце. Тут же смысл раздела в том, чтобы разнести чувствительные датчики подальше от вибрации и больших токов при небольших размерах ЛА.

Ну а комплексные мозги для мошкары лучше чем AutoQuad M4 я не видел…