Создание собственной системы стабилизации
Прикольно, Сергей, тут не та тема, в своей ответь на какой гире так было.
и на муратовских и на ЛСМ, и взлёт только на гирах , нааамного лучше (ровнее плавнее) можно мягко стартовать 😃
в том кино полёт чисто на одних гирах, правда я ещё пультом перед камерой махал, а аппарат никуда не девался - висел, но в само кино это не попало… пересоберу контроллер покажу акро (Вий в нём стабильнее чем КУК)… по сей причине и говорю, что в помещении без ветра вполне можно было и без акселя кино сляпать… или на худой конец задушить его до каких 0.2 Гц полетел бы только так и с вибрациями…
Подтверждаю )) на гирах без корекциии можно висеть более минуты… пробовал itg3205 и mpu6050…
ну это на верхней плате текущего контроллера, вот думаю, пока не делал её - не заменить ли microSD (она как-то и не актуальна для логов хватит и флеши на плате) на приёмо-передатчик, что работает по SPI? ну например маленький RFM22B
несоветую ставить передающий модуль на одной плате с GPS приемником , даже если антенны будет вынесены далеко от платы …
- написать нормально работающую в наших условиях радиосистему это отдельная довольно сложная задача … надеюсЪ опенпилоты доведут доума свой OPLink , тогда можно будет использовать его …
А на какой частоте интересно он работает? если не ошибаюсь он на f103-м собран… ага 433… и что же у него с другой стороны платы спрятано? гы-гы тот самый RFM22B…
Народ. Кто то разбирался в протоколе mavlink. Хочу переделать ОСД под данный протокол для Ардукоптер. Смотрел готовые библиотеки и нифига не догоняю. Как то там все через опу.
Так если все данные уже читаются, их можно и не трогать, в MinimOSD непосредственно вывод смотрите в OSD_Panels.ino, функция writePanels(), можете поменять под себя как угодно.
У меня OSD своя. Раньше стояла на мультиви, а теперь хочу переделать на ардукоптер.
несоветую ставить передающий модуль на одной плате с GPS приемником , даже если антенны будет вынесены далеко от платы …
Есть противопоказания? Хочется всё в одном и компактно, а если нельзя то и смысла нет
написать нормально работающую в наших условиях радиосистему это отдельная довольно сложная задача
Для начала придлагал стянуть готовый РЧ-модуль с модема 3ДР, со встроенным ПО, своё пока не досуг.
Есть противопоказания? Хочется всё в одном и компактно, а если нельзя то и смысла нет
ну все на одной плате тоже нехорошо …
противопоказания : любой передающий модуль это источник электромагнитных помех который нужно ставить какможно дальше от приемника и антенны навигации …
видеале GPS и компас выносить на отдельную плату и поднимать какможно выше…
Для начала придлагал стянуть готовый РЧ-модуль с модема 3ДР, со встроенным ПО, своё пока не досуг.
ну так у 3ДР не RFM22 а HM-TRP модули … там трансивер и проц в одном флаконе , но в прошивке только rs232 , а интересно так чтобы шла нетолько телеметрия но и управление по тому-же каналу …
как вариант можно слона переразвести под свои нужды …
противопоказания : любой передающий модуль это источник электромагнитных помех который нужно ставить какможно дальше от приемника и антенны навигации …
ну, например, на другой стороне платы, дорожка до разъёма антенны как можно короче, а антенна как можно дальше( в моём случае вообще под пузом аппарата), плюс имеются латунные экраны дабы, закрыть передатчик (не железные, магнитометру не навредить)…
Пока вспомнил, виртуальная еепром, не стирается stlink-ком, он затирает только тот участок флеши где сама программа, так что если какие-то переделки были в ней то сначала надо сделать полное стирание через usart в режиме бутлоадера…
Таймкоп разбушевался code.google.com/p/afrodevices/source/detail?r=335 😃 18+
У меня вопрос по PID (что то не как не могу победить), возьмем один канал, например “крен”:
Делаю так в цикле: “П”=“уст.”-“текущ.” (она же “error”)
“И”=“И”+error
“Д”=“Д(n-1)”-“текущ.”
PID=“П”+“И”+“Д”
ну и конечно каждый компонент умножаю на коэфициент “K”<1.0 (float).
Какого порядка этот “K” должен быть?, частота выполнения цикла 250 Гц., ставил даже “К”=0.1, все равно идет перерегулирование (не затухающие колебания)…
Может что то не так делаю?
в таком случае минус Д наверно…
Какого порядка этот “K” должен быть?
этот К должен быть разным для каждого из P, I, D.
разным для каждого
Да, конечно пробую разные, но результат тот же, похоже не правильно что то делаю, судя по разным источникам интернета
встречал разночтения типа: “Д”=“Д(n-1)”-“текущ.” и “Д”=“текущ.”-Д(n-1)", как правильно не знаю…
Может кто подкинет рабочий кусочек кода для анализа?
// **** PITCH & ROLL & YAW PID ****
float dT = cycleTime * 1e-6; // pt1 element
prop = max(abs((float)rcCommand[PITCH]), abs((float)rcCommand[ROLL])); // range [0;500] Crashpilot: prop is float now
for (axis = 0; axis < 3; axis++) {
if ((f.ANGLE_MODE || f.HORIZON_MODE) && axis < 2) { // MODE relying on ACC 50 degrees max inclination
errorAngle = constrain(2.0f * (float)rcCommand[axis] + (float)GPS_angle[axis], -500.0f, +500.0f) - (float)angle[axis] + (float)cfg.angleTrim[axis];
errorAngle = errorAngle*(float)cycleTime/BasePIDtime; // Crashpilot: Include Cylcletime take 3ms as basis. More deltaT more error
PTermACC = errorAngle * (float)cfg.P8[PIDLEVEL] / 100.0f;
PTermACC = constrain(PTermACC, -(float)cfg.D8[PIDLEVEL] * 5.0f, +(float)cfg.D8[PIDLEVEL] * 5.0f);
errorAngleI[axis] = constrain(errorAngleI[axis] + errorAngle, -10000.0f, +10000.0f); // WindUp
ITermACC = ((float)errorAngleI[axis] * (float)cfg.I8[PIDLEVEL])/4096.0f;
}
if (!f.ANGLE_MODE || axis == 2) { // MODE relying on GYRO or YAW axis
error = (float)rcCommand[axis]*80.0f/(float)cfg.P8[axis];
error = error*(float)cycleTime/BasePIDtime; // Crashpilot: Include Cylcletime take 3ms as basis. More deltaT more error
error -= (float)gyroData[axis];
PTermGYRO = (float)rcCommand[axis];
errorGyroI[axis] = constrain(errorGyroI[axis] + error, -16000.0f, +16000.0f);
if (abs(gyroData[axis]) > 640.0f)
errorGyroI[axis] = 0;
ITermGYRO = (errorGyroI[axis]/125.0f * (float)cfg.I8[axis])/64.0f;
}
if (f.HORIZON_MODE && axis < 2) {
PTerm = (PTermACC * (500.0f - prop) + PTermGYRO * prop) / 500.0f;
ITerm = (ITermACC * (500.0f - prop) + ITermGYRO * prop) / 500.0f;
} else {
if (f.ANGLE_MODE && axis < 2) {
PTerm = PTermACC;
ITerm = ITermACC;
} else {
PTerm = PTermGYRO;
ITerm = ITermGYRO;
}
}
PTerm -= (float)gyroData[axis] * (float)dynP8[axis] / 10.0f / 8.0f;
delta = (float)gyroData[axis] - (float)lastGyro[axis];
lastGyro[axis] = gyroData[axis];
deltaSum = delta1[axis] + delta2[axis] + delta;
delta2[axis] = delta1[axis];
delta1[axis] = delta;
deltaSum = lastDTerm[axis] + (dT / (RC + dT)) * (deltaSum - lastDTerm[axis]); // pt1 element
lastDTerm[axis] = deltaSum; // pt1 element
DTerm = ((float)deltaSum * (float)dynD8[axis])/32.0f;
axisPID[axis] = PTerm + ITerm - DTerm;
}
код реально нечитаем и нелогичен 😉
пчему же? просто с ним придется много повозится… код из вия
кстати… в нем нету понятия времени, чисто по умолчанию принято что вызывается примерно через одинаковые промежутки…
axisPID[axis] = PTerm + ITerm - DTerm;
а вот тут собственно что и спрашивали…
для пояснения… расчет разбит на 2 части:
- Для режима удержания горизонта, используем в I данные акселя
- Для акро режима и YAW оси используется чисто гироскоп
что первое под руку попалось 😦 вообще это naze32 harakiri сейчас копаю якобы порт ardu на PX4 чёт мне кажется это не порт а подгонка программного, с екф к стати, к их протоколам, могу ошибаться…
этот код чисто виевский и практически без доработок… вот оригинал
//**** PITCH & ROLL & YAW PID ****
for(axis=0;axis<3;axis++) {
if (f.ACC_MODE && axis<2 ) { //LEVEL MODE
// 50 degrees max inclination
errorAngle = constrain(2*rcCommand[axis] + GPS_angle[axis],-500,+500) - angle[axis] + conf.angleTrim[axis]; //16 bits is ok here
#ifdef LEVEL_PDF
PTerm = -(int32_t)angle[axis]*conf.P8[PIDLEVEL]/100 ;
#else
PTerm = (int32_t)errorAngle*conf.P8[PIDLEVEL]/100 ;
#endif
PTerm = constrain(PTerm,-conf.D8[PIDLEVEL]*5,+conf.D8[PIDLEVEL]*5);
errorAngleI[axis] = constrain(errorAngleI[axis]+errorAngle,-10000,+10000);
ITerm = ((int32_t)errorAngleI[axis]*conf.I8[PIDLEVEL])>>12;
} else { //ACRO MODE or YAW axis
if (abs(rcCommand[axis])<350) error = rcCommand[axis]*10*8/conf.P8[axis] ;
else error = (int32_t)rcCommand[axis]*10*8/conf.P8[axis] ;
error -= gyroData[axis];
PTerm = rcCommand[axis];
errorGyroI[axis] = constrain(errorGyroI[axis]+error,-16000,+16000); // WindUp 16 bits is ok here
if (abs(gyroData[axis])>640) errorGyroI[axis] = 0;
ITerm = (errorGyroI[axis]/125*conf.I8[axis])>>6;
}
if (abs(gyroData[axis])<160) PTerm -= gyroData[axis]*dynP8[axis]/10/8;
else PTerm -= (int32_t)gyroData[axis]*dynP8[axis]/10/8; // 32 bits is needed for calculation
delta = gyroData[axis] - lastGyro[axis];
lastGyro[axis] = gyroData[axis];
deltaSum = delta1[axis]+delta2[axis]+delta;
delta2[axis] = delta1[axis];
delta1[axis] = delta;
if (abs(deltaSum)<640) DTerm = (deltaSum*dynD8[axis])>>5;
else DTerm = ((int32_t)deltaSum*dynD8[axis])>>5;
axisPID[axis] = PTerm + ITerm - DTerm;
}
там никакого портирования не нужно… чисто вставил и чуток подправил… тут чисто математика