Создание собственной системы стабилизации
заряжаюсь, вечером ещё раз взлечу… ибо настройки те же, что и в прошлый раз…
Саш а у тебя же что-то похожее есть только без ГПС?
да… в дневнике подробности…
если честно, не думаю, что большая разница между ITG3200 и MPU6050
у меня рассыпуха в виде ITG3200
из своего опыта… гиры примерно одинаковые… я год налетал на 3205 и не могу сказать 6050 прям лучше… а вот аксель в mpu-ке получше, это да…
Реально, кстати вам под AIOP эту прошивку залить самое то, плата прям в стоке поддерживается без бубна
пока не добавили дефайн на АИОП… MULTIWII_PRO это не то, там bmp085… в прошиве пока нет драйвера под ms5611 github.com/bradquick/bradwii_arduino/…/baro.cpp но адаптировать не сложно думаю… день-пять и будет ))
с гирами беда какая-то - дёргаться даже в акро стал, возможно из-за той же жары плывут? (летал на самом сонцепёке, людей нет) пришлось задействовать и аксель и маг - пошло летать, а на гирах какойто дёрганый…
может вибрации полезли… вруби фильтр на гиру в drv_mpu6000.c на 20hz
static uint8_t mpuLowPassFilter = MPU6000_LPF_20HZ;
пока не добавили дефайн на АИОП… MULTIWII_PRO это не то, там bmp085…
Точно глянул на кинге совсем другая платка оказывается
возможно из-за той же жары плывут?
Ну это проверить то не проблема просто прогреть квадрик на солнышке а потом полететь
Неа, я пропы поменял, вибрации бы аксель душили, приподнял чуть P и D отлетал батарейку нормально, гиры да, поставил на 20Гц - ещё по мелкоплате на прошивке Таймкопа знаю - на 42-х дёргается, но это не вибрации это скорей из-за особенности рамы - 12-е пропы для неё великоваты (на трёхе тоже на 11-х лучше себя чувствовала), надо 11-е заказать, а то нету нормальных у меня… и похоже один мотор у меня 750-й, а не 700, как-то уж очень обмотка отличается от трёх остальных, попробую из старого, с битым колокольчиком собрать…
надо, добивать что-бы логи писала, либо телеметрию на комп, а то серьёзно как слепой котёнок блин… наверно логи в первую очередь - флешь - то у меня на плате есть…
Да, у меня рассыпуха в виде ITG3200 и BMA180, реально они хуже мпушек.
Реально, кстати вам под AIOP эту прошивку залить самое то, плата прям в стоке поддерживается без бубна
Ну как тут уже сказали, разница в гирах невелика, у меня тоже этих платок 10DOF штуки 2-3 лежит на ITG3200 ADXL345 и пр.
Жаль только плата не моя, она у меня на тестах, да и адаптировать под нее код надо.
Вспомнил, я же цикл поменял, вот всё и поплыло, естественно пришлось новые ПИД-ы подбирать:)
Думаю тут надо перестраивать всё, ибо на таком цикле (3500) для проца и для гироакселя по SPI как-то не совсем комфортно? (нечем заняться 😃 )
Заказал наконец-то верхние платы - посмотрим как китайцы справятся с фигурным выпиливанием 😃
так что пока буду заниматься любимой работой - нефиганеделанием, пока ну ни к чему душа не лежит, а на полетать просто уже есть что 😃
Чё-та я задумался, коптер стал более “нервным”, батарейки греть начал! ну и т.д. пропы? что те 12/4.5 что другие 12/4.5 (отбалансированы) всё-же видать время цикла так повлияло… надо поэкпериментировать… там где кино я ставил 1500, а вчера 3500…
это оказывается COMport на компьютере глючит ! (во как)
Управление потоком отключите
с гирами беда какая-то - дёргаться даже в акро стал
Если раскачка плавная, то делай меньше П и побольше Д. Если же дерганья “нервные”, то делай меньше Д, происходит резкое перерегулирование по угловой скорости, при твоих винтах большой Д = высокие нагрузки на моторы (причем зарежимные, с низким КПД ВМГ),с вытекающими последствиями. Кроме того, если ты увеличил цикл обсчёта, то соответственно dt дифф. части тоже увеличилось (если ПО ПИДа это учитывает) и её вес возрос. Короче пробуй меньший Д.
а вот аксель в mpu-ке получше, это да…
Дык в нём весь корень зла для автоматики!
Короче пробуй меньший Д.
ну так я и поступил, но с циклом надо повозиться… а правильнее наверно сделать как в арду, привязать цикл к прерываниям от MPU, ибо батарейки не с проста греться стали…
но с циклом надо повозиться…
вот ещё подумалось: длинный цикл - высокие “ступеньки” в регулировании, тоже источник дерготни.
это да, да и фильтры надо пересматривать, думаю надо время задать примерно 1200 - 1300, с учётом того, что гироаксель читается быстрее, да частота проца высока…
думаю будет пару свободных вечеров, тебе верхнюю плату с твоим gps нарисовать? как разъём на антенну обзывается?
думаю будет пару свободных вечеров, тебе верхнюю плату с твоим gps нарисовать?
если нет “творческого порыва”, то не надо, пока она не к спеху. Надоть сначала основу облетать, жду комплектухи, а пока подбиваю теоретическую базу (книжек вумных набрал), учу математику…
как разъём на антенну обзывается?
не знаю, завтра уточню… а может кераму сразу на плату припаять?
для неё дырка на плате нужна, а значит сам модуль где-то снизу - не не выход, ну можно выкинуть MicroSD? либо “отодвинуть” питатели ближе к SPI на их место модуль, а на место модуля антенну, но думаю лучше выносную?
currentTime = micros();
if (mcfg.looptime == 0 || (int32_t)(currentTime - loopTime) >= 0) {
loopTime = currentTime + mcfg.looptime;
computeIMU();
// Measure loop rate just afer reading the sensors
currentTime = micros();
cycleTime = (int32_t)(currentTime - previousTime);
previousTime = currentTime;
короче просто изменение скорости петли опроса датчиков, как следствие нужно лишь вписаться чтобы маг с баро успевал прочитать если надо, а гироаксель успеет в любом случае, а так да происходит завышение D…
Александр mahowik меня тут озадачил, новым вийным ПИД-ом , полез я сравнивать и короче наткнулся вот на что:
// **** PITCH & ROLL & YAW PID ****
prop = max(abs(rcCommand[PITCH]), abs(rcCommand[ROLL])); // range [0;500]
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 * rcCommand[axis] + GPS_angle[axis], -500, +500) - angle[axis] + cfg.angleTrim[axis];
PTermACC = (int32_t)errorAngle * cfg.P8[PIDLEVEL] / 100; // 32 bits is needed for calculation: errorAngle*P8[PIDLEVEL] could exceed 32768 16 bits is ok for result
PTermACC = constrain(PTermACC, -cfg.D8[PIDLEVEL] * 5, +cfg.D8[PIDLEVEL] * 5);
errorAngleI[axis] = constrain(errorAngleI[axis] + errorAngle, -10000, +10000); // WindUp
ITermACC = ((int32_t)errorAngleI[axis] * cfg.I8[PIDLEVEL]) >> 12;
}
if (!f.ANGLE_MODE || f.HORIZON_MODE || axis == 2) { // MODE relying on GYRO or YAW axis
error = (int32_t)rcCommand[axis] * 10 * 8 / cfg.P8[axis];
error -= gyroData[axis];
PTermGYRO = rcCommand[axis];
errorGyroI[axis] = constrain(errorGyroI[axis] + error, -16000, +16000); // WindUp
if (abs(gyroData[axis]) > 640)
errorGyroI[axis] = 0;
ITermGYRO = (errorGyroI[axis] / 125 * cfg.I8[axis]) >> 6;
}
if (f.HORIZON_MODE && axis < 2) {
PTerm = ((int32_t)PTermACC * (500 - prop) + (int32_t)PTermGYRO * prop) / 500;
ITerm = ((int32_t)ITermACC * (500 - prop) + (int32_t)ITermGYRO * prop) / 500;
} else {
if (f.ANGLE_MODE && axis < 2) {
PTerm = PTermACC;
ITerm = ITermACC;
} else {
PTerm = PTermGYRO;
ITerm = ITermGYRO;
}
}
PTerm -= (int32_t)gyroData[axis] * dynP8[axis] / 10 / 8; // 32 bits is needed for calculation
delta = gyroData[axis] - lastGyro[axis]; // 16 bits is ok here, the dif between 2 consecutive gyro reads is limited to 800
lastGyro[axis] = gyroData[axis];
deltaSum = delta1[axis] + delta2[axis] + delta;
delta2[axis] = delta1[axis];
delta1[axis] = delta;
DTerm = ((int32_t)deltaSum * dynD8[axis]) >> 5; // 32 bits is needed for calculation
axisPID[axis] = PTerm + ITerm - DTerm;
}
и хде тут время цикла? - короче я как всегда запутался 😃
Таймкоп по ходу готовит 5-ю ревизию платы - обзавёлся SPI и кварц уже на 12мГц (интересно что за проц) и не понятно из каких побуждений использует РС13, РС14 для прерываний датчиков? на 4-й ревизии у него было PB12, PB13 и ничего путного из этого не вышло…
догнал оно же само в петле 😃
впихнул новый ПИД на выходных проверю…
Там в сообщении старый
новый сдёрнул отсюда code.google.com/p/afrodevices/source/…/mw.c?r=363
и хде тут время цикла? - короче я как всегда запутался
В старом нет, а в новом явно присутствует
delta = (delta * ((uint16_t)0xFFFF / (cycleTime >> 4))) >> 6;
Старый в петле самой…
а в этом могу задать время цикла магическое 2048…
подождём вечера/ночи, может mahowik чего умного подскажет 😃
смущает, в отличии от стандартного wii дифференциальная составляющая с плюсом, наверно надо P занизить изначально, короче пропы есть надо экспериментировать 😃
вот этот кусок:
static void pidRewrite(void)
{
int32_t errorAngle = 0;
int axis;
int32_t delta, deltaSum;
static int32_t delta1[3], delta2[3];
int32_t PTerm, ITerm, DTerm;
static int32_t lastError[3] = { 0, 0, 0 };
int32_t AngleRateTmp, RateError;
// ----------PID controller----------
for (axis = 0; axis < 3; axis++) {
// -----Get the desired angle rate depending on flight mode
if ((f.ANGLE_MODE || f.HORIZON_MODE) && axis < 2 ) { // MODE relying on ACC
// calculate error and limit the angle to 50 degrees max inclination
errorAngle = constrain((rcCommand[axis] << 1) + GPS_angle[axis], -500, +500) - angle[axis] + cfg.angleTrim[axis]; // 16 bits is ok here
}
if (axis == 2) { // YAW is always gyro-controlled (MAG correction is applied to rcCommand)
AngleRateTmp = (((int32_t)(cfg.yawRate + 27) * rcCommand[2]) >> 5);
} else {
if (!f.ANGLE_MODE) { //control is GYRO based (ACRO and HORIZON - direct sticks control is applied to rate PID
AngleRateTmp = ((int32_t) (cfg.rollPitchRate + 27) * rcCommand[axis]) >> 4;
if (f.HORIZON_MODE) {
// mix up angle error to desired AngleRateTmp to add a little auto-level feel
AngleRateTmp += (errorAngle * cfg.I8[PIDLEVEL]) >> 8;
}
} else { // it's the ANGLE mode - control is angle based, so control loop is needed
AngleRateTmp = (errorAngle * cfg.P8[PIDLEVEL]) >> 4;
}
}
// --------low-level gyro-based PID. ----------
// Used in stand-alone mode for ACRO, controlled by higher level regulators in other modes
// -----calculate scaled error.AngleRates
// multiplication of rcCommand corresponds to changing the sticks scaling here
RateError = AngleRateTmp - gyroData[axis];
// -----calculate P component
PTerm = (RateError * cfg.P8[axis]) >> 7;
// -----calculate I component
// there should be no division before accumulating the error to integrator, because the precision would be reduced.
// Precision is critical, as I prevents from long-time drift. Thus, 32 bits integrator is used.
// Time correction (to avoid different I scaling for different builds based on average cycle time)
// is normalized to cycle time = 2048.
errorGyroI[axis] = errorGyroI[axis] + ((RateError * cycleTime) >> 11) * cfg.I8[axis];
// limit maximum integrator value to prevent WindUp - accumulating extreme values when system is saturated.
// I coefficient (I8) moved before integration to make limiting independent from PID settings
errorGyroI[axis] = constrain(errorGyroI[axis], (int32_t)-GYRO_I_MAX << 13, (int32_t)+GYRO_I_MAX << 13);
ITerm = errorGyroI[axis] >> 13;
//-----calculate D-term
delta = RateError - lastError[axis]; // 16 bits is ok here, the dif between 2 consecutive gyro reads is limited to 800
lastError[axis] = RateError;
// Correct difference by cycle time. Cycle time is jittery (can be different 2 times), so calculated difference
// would be scaled by different dt each time. Division by dT fixes that.
delta = (delta * ((uint16_t)0xFFFF / (cycleTime >> 4))) >> 6;
// add moving average here to reduce noise
deltaSum = delta1[axis] + delta2[axis] + delta;
delta2[axis] = delta1[axis];
delta1[axis] = delta;
DTerm = (deltaSum * cfg.D8[axis]) >> 8;
// -----calculate total PID output
axisPID[axis] = PTerm + ITerm + DTerm;
}
А мне тут пришел наконец HMC5983. Буду эксперементировать с вынесением датчика на шелдвоном проводе
Буду эксперементировать с вынесением датчика
Что хотите выяснить? Что не нравилось когда компас на плате?
Да в принцепе устраивает более мене, плывет немного при перегазовках. Просто хочу узнать на своем опыте какая разница.
Вообщем чисто академический интерес.