Вопросы по iNav
Сегодня тестовал новые PID
PH:
nav_posr_p = 90
nav_posr_i = 10
nav_posr_d = 255
AH:
nav_vel_p = 200
nav_vel_i = 10
nav_vel_d = 250
Вот результат
Соответственно, два вопроса:
- Что я не так делаю с GPS, может что в CLI написать нужно?
- Там много параметров в CLI по поводу baro, что куда крутить или где об этом посмотреть? И вообще, может я неправильно перехожу в этот режим? На Фантоме было просто, там стик газа подпружиненный и находится в центральном положении, режим альтхолд - не отключается. Стик отпустил и он вист - не уходит по высоте.
На портов нужно одному из портов присвоить функицю GPS, тогда и на вкладке конфигурации GPS включится.
Для “правильного” висения нужно в CLI выставить газ висения (примерный) - nav_mc_hover_thr, по умолчанию он 1500 (50% газа)
Deadband для альтхолда не очень большой по умолчанию, поэтому и середину поймать трудно. Крутить параметр althold_deadband.
Я так понимаю, все эти шумы можно программно отфильтровать, и точно оно есть в настройках.
Дрейф атмосферного давления и турбулентность фиг отфильтруешь, лучше резкие порывы воздуха к барометру не подпускать - паралон наше все 😁
Сегодня летал без ветра. RTH Speed абсолютно нормальный. Думаю что вчера просто ветeр был сильный.
Да, 20км/ч ветер сильноват. Сейчас на RCG докручиваем новые ПИДы (и полетные и навигационные), должно стать получше.
руддер есть, подключен. в полете рулит именно руддером, элерон-элеватор стабилизируют полет.
Текущая прошивка руддер для навигации не использует.
У меня еще мысля появилась, а как смонтирован полетный контроллер? Случайно не “задом-наперед”?
вы с разработчиками не общаетесь? 😃
вы с разработчиками не общаетесь?
Бывает иногда 😁
DigitalEntity - это я и есть
Да, 20км/ч ветер сильноват. Сейчас на RCG докручиваем новые ПИДы (и полетные и навигационные), должно стать получше.
лаг гпс поставьте хотя бы пол секунды иначе все расчеты в ИНС будут в прах 😃
еще смотрел у вас в ИНС коррекция Z оси идет не через хистори, а напрямую, а ведь лаг барометра после всех кальцуляций и филтрации это тоже ~300мс… у меня так по графикам вышло…
лаг гпс поставьте хотя бы пол секунды иначе все расчеты в ИНС будут в прах
еще смотрел у вас в ИНС коррекция Z оси идет не через хистори, а напрямую, а ведь лаг барометра после всех кальцуляций и филтрации это тоже ~300мс… у меня так по графикам вышло…
Экспериментировал с задержкой барометра - становится хуже. Надежнее чуть больше доверять акселю, а на медленный дрейф забить.
Задержку GPS да, можно и до 500мс увеличить. Хотя для скорости и курса она для Pedestrian-модели вообще до пары секунд доходить может…
Экспериментировал с задержкой барометра - становится хуже. Надежнее чуть больше доверять акселю, а на медленный дрейф забить.
задержка фазы в данных приводит к болтанке и необходимости ослабления ПИД-ов в итоге… проверено…
Задержку GPS да, можно и до 500мс увеличить. Хотя для скорости и курса она для Pedestrian-модели вообще до пары секунд доходить может…
это как? для разных скоростей разный лаг?
вы пробовали как нить померять задержку? для ИНС, как писал ранее, это самый важный параметр фактически…
Бывает иногда
DigitalEntity - это я и есть
мы наверное о разном или о разных… 😃
я две недели назад писал парочку соображений…
rcopen.com/forum/f123/topic443443/173
задержка фазы в данных приводит к болтанке и необходимости ослабления ПИД-ов в итоге… проверено…
А привнесение своей задержки может в итоге привести к положительной обратной связи и колебаниях уже в расчетной позиции, тоже проверено.
это как? для разных скоростей разный лаг?
Нет, для разных GPS-модулей разный лаг. В координатах на модели Pedestrian около 200-500 мс обычно, на модели Airborn<4G менее 100мс.
У вас в коде ГПС лаг выставлен на 1.5 сек. Это на глазок я так понимаю? ИНС уже работает на удержние позиции в полевых условиях?
0.2 сек работает в полевых условиях, причем работает неплохо. Отсутствие задержки баро колебаний высоты не дает.
На сколько тяжелый BiQuad фильтр? В чем его плюс? Не дает задержки фазы на нужных частотах?
Легкий, не сложнее FIR. Плюс в том, что параметры можно легко посчитать для любой частоты среза, в отличие от FIR. Фазовую задержку вносит больше, чем FIR или примитивный RC-фильтр, но это с лихвой окупается настраиваемой АЧХ.
А привнесение своей задержки может в итоге привести к положительной обратной связи и колебаниях уже в расчетной позиции, тоже проверено.
так не будет же своей задержки… т.е. ошибка будет высчитана из значений баро и актуальных расчетных данных (по акселю) из хистори, т.е. данные одной временной шкалы…
Нет, для разных GPS-модулей разный лаг. В координатах на модели Pedestrian около 200-500 мс обычно, на модели Airborn<4G менее 100мс.
это понятно что лаг разный для разных модулей… а как меряли? по логам?
0.2 сек работает в полевых условиях, причем работает неплохо
лаг баро ~0.3 сек… по вашей логике для шустрых гпс модулей хистори не нужна 😃
так не будет же своей задержки… т.е. ошибка будет высчитана из значений баро и актуальных расчетных данных (по акселю) из хистори, т.е. данные одной временной шкалы…
Это если угадаешь. А если попадется более шустрый сенсор то расчетные данные могут оказаться из “прошлого” по отношению к баро, что скорее всего приведет к нарушению сходимости (осцилляция расчетной координаты).
это понятно что лаг разный для разных модулей… а как меряли? по логам?
По логам, сравнивал данные, выдаваемые GPS и наблюдаемые по акселерометру. Меньше 200мс значение ни разу не получалось, так что 200мс - вполне безопасное значение по умолчанию.
лаг баро ~0.3 сек… по вашей логике для шустрых гпс модулей хистори не нужна
Нужна, с этим я не спорю, проблема в том, что мои попытки ее внести приводили только к ухудшению сходимости.
Всё усугубляется еще и тем, что дискретность данных разная. У интеграторов ИНС - 500Гц-1кГц, смотря какой looptime выставлен, у GPS - 5-10Гц, у баро - 20Гц, а у хистори (и у выходных данных ИНС) - 50Гц.
Это если угадаешь. А если попадется более шустрый сенсор то расчетные данные могут оказаться из “прошлого” по отношению к баро, что скорее всего приведет к нарушению сходимости (осцилляция расчетной координаты).
Если ориентироваться на mpu6050/6000 (где внутренний фильтр на 42 или 20гц) и ms5611, то картина предельно ясная. Выводим расчетные высоту по акселю из хистори и сырую высоту по баро на графики и подбираем задержку буфера для хистори по схождению этих двух кривых.
У меня вышло ~325мс. Сам удивился, т.к. ожидал ~150мс макс… Получилось довольно точно, т.к. сейчас даже при обильной болтанке по вертикали, расхождение минимально…
По логам, сравнивал данные, выдаваемые GPS и наблюдаемые по акселерометру. Меньше 200мс значение ни разу не получалось, так что 200мс - вполне безопасное значение по умолчанию.
Это вы наверное на довольно современных модулях катались 😃
Пристарелые народные mtk3329/3339 и ublox-ы определенно от 500мс и выше. Хотя я пытался бегать стометровки по полю уже полтора-два года назад 😃
В прошлом году Алексей Козин придарил мне парочку на mtk3333 с поддержкой Глонасс. Этот уже пошустрее, может там и будет 200-300мс. У вас на этом чипсете нет модулей? Не меряли?
Если ориентироваться на mpu6050/6000 (где внутренний фильтр на 42 или 20гц) и ms5611, то картина предельно ясная. Выводим расчетные высоту по акселю из хистори и сырую высоту по баро на графики и подбираем задержку буфера для хистори по схождению этих двух кривых.
У вас же это уже сделано и работает? Можно глянуть код? Вдруг я где-то делаю элементарную ошибку из-за чего у меня оно и не работает.
Пристарелые народные mtk3329/3339 и ublox-ы определенно от 500мс и выше. Хотя я пытался бегать стометровки по полю уже полтора-два года назад
Странно, у меня на Neo-M8N получилось 200-300 мс.
В прошлом году Алексей Козин придарил мне парочку на mtk3333 с поддержкой Глонасс. Этот уже пошустрее, может там и будет 200-300мс. У вас на этом чипсете нет модулей? Не меряли?
Нету, увы.
Дрейф атмосферного давления и турбулентность фиг отфильтруешь, лучше резкие порывы воздуха к барометру не подпускать - паралон наше все
Свет тоже лучше не подпускать, например два слоя черного двухстороннего скотча с основой плюс черная изолента, немного черного паралона, например от амбушюры наушника и строить домик вокруг барометра ))
Свет тоже лучше не подпускать
Да, кстати, совсем про это забыл. Барометр темноту любит 😁
Насчёт света шутка или всерьёз?
Насчёт света шутка или всерьёз?
Абсолютно серьезно. Кроме шуток, мне барометр прикрытый белым паралоном стоил километров нервов - я никак не мог понять почему он работает дома (относительно темно) и скачет по высоте в яркий солнечный идеальный для полетов день.
Насчёт света шутка или всерьёз?
Тоже думал шутка, пока фонариком не посветил. Черный но тонкий паралон тоже пропускает свет…
Господа, может не будем зацикливаться на старых GPS модулях? Кто то же должен поддерживать товарооборот в Китае!!! 😃))
По поводу PID, я очень доволен LuxFloat. Так что всё остальное можно убрать для освобождения места.
Господа, может не будем зацикливаться на старых GPS модулях? Кто то же должен поддерживать товарооборот в Китае!!! 😃))
О да, к тому же я очень доволен тем, как летает Ublox Neo-M8N.
По поводу PID, я очень доволен LuxFloat. Так что всё остальное можно убрать для освобождения места.
У меня в разработке как раз переделанный LuxFloat. Сейчас тестируется и дорабатывается, после того как доведу его до ума, он станет единственным.
Прошу не забывать про то что самолетчики так же питают надежды на ваш код.😃
У вас же это уже сделано и работает? Можно глянуть код?
debug[1] и debug[2], в correctZStateWithBaro() функции, в идеале должны конвёржиться/совпадать на графике…
#define HIST_Z_POSITION_POINTS 13 // delay = HIST_Z_POSITION_POINTS * INS_UPDATE_INTERVAL ~= 325ms
uint8_t histZPositionCount;
int32_t histZPosition[HIST_Z_POSITION_POINTS];
uint8_t calculateZ_INS() {
static uint16_t previousT = micros(); // set first time
uint16_t currentT = micros();
uint16_t dTime = currentT - previousT;
if (dTime < INS_UPDATE_INTERVAL) {
return 0;
}
previousT = currentT;
static bool isArmed = false;
calculateRAWAltitude();
updateAccelEF_Filtered(ALT);
if (f.ARMED) {
if (!isArmed) {
isArmed = true;
resetZState();
}
float dt = dTime * 0.000001f; // dt in sec
correctZStateWithBaro(&dt);
updateZState(&dt);
saveZPositionToHistory();
return 1;
} else {
if (isArmed) {
isArmed = false;
}
}
return 0;
}
// Set the Acc weight for Acc/Baro complementary filter (CF)
// Increasing this value will reduce and delay Baro influence on the output of the filter.
#ifdef KILL_VIBRO
#define INS_Z_CONVERGE_FACTOR 3.0f
#else
#define INS_Z_CONVERGE_FACTOR 4.4f
#endif
#define INS_Z_POS_FACTOR (3.0f / INS_Z_CONVERGE_FACTOR)
#define INS_Z_VEL_FACTOR (3.0f / (INS_Z_CONVERGE_FACTOR * INS_Z_CONVERGE_FACTOR))
//#define INS_Z_ACC_FACTOR (1.0f / (INS_Z_CONVERGE_FACTOR * INS_Z_CONVERGE_FACTOR * INS_Z_CONVERGE_FACTOR))
void correctZStateWithBaro(float* dt) {
// calculate error in position from baro with our estimate
// reduce effect of air-cushion, i.e. influence of alt.baroAlt on take off and landing,
// because baro altitude value is dropped for 3-5m near the ground (i.e. not correct)
float posError = ((isTakeOffInProgress() && (alt.baroAlt < minTakeOffBaroAlt)) ? minTakeOffBaroAlt : alt.baroAlt)
- histZPosition[histZPositionCount];
/* !!! historic Z positions and baro should be at the same phase
* i.e. looks the same on chart and depends on HIST_Z_POSITION_POINTS !!! */
debug[1] = histZPosition[histZPositionCount];
debug[2] = alt.baroAlt;
//accCorrection[ALT] += altError * INS_Z_ACC_FACTOR * *dt;
ins.velocityEF[ALT] += posError * (INS_Z_VEL_FACTOR * *dt);
ins.positionEF[ALT] += posError * (INS_Z_POS_FACTOR * *dt);
}
void updateZState(float* dt) {
// calculate velocity increase adding new acceleration from accelerometers
//float velocityIncrease = (ins.accelEF_Filtered[ALT] + accCorrection[ALT]) * *dt;
float velocityIncrease = ins.accelEF_Filtered[ALT] * *dt;
// calculate new estimate of position
ins.positionEF[ALT] += (ins.velocityEF[ALT] + velocityIncrease * 0.5) * *dt;
alt.estAlt = ins.positionEF[ALT];
// calculate new velocity
ins.velocityEF[ALT] += velocityIncrease;
alt.vario = ins.velocityEF[ALT];
//debug[0] = alt.vario; // Positive when moving up
//debug[0] = ins.accelEF_Filtered[ALT];
debug[3] = alt.estAlt; // Positive when moving up
}
void saveZPositionToHistory() {
// store 3rd order estimate (i.e. estimated vertical position) for future use at 40hz (25ms)
histZPosition[histZPositionCount] = alt.estAlt; [ALT];
histZPositionCount++;
if (histZPositionCount >= HIST_Z_POSITION_POINTS) {
histZPositionCount = 0;
}
}
void resetZState() {
// reset ins Z params at ARM event
ins.positionEF[ALT] = 0.0f;
ins.velocityEF[ALT] = 0.0f;
alt.vario = 0;
histZPositionCount = 0;
for (uint8_t i = 0; i < HIST_Z_POSITION_POINTS; i++) {
//histZPosition[i] = alt.EstAlt; // reset history to current averaged raw alt
histZPosition[i] = 0;
}
}
Странно, у меня на Neo-M8N получилось 200-300 мс.
ну так это вовсе и не старый модуль…
Еще посмотрел у вас в baroCalculateAltitude() функции (стр. 175) остался фильтр. Для данной ИНС имплементации он не нужен по идее.
github.com/iNavFlight/inav/blob/…/barometer.c
BaroAlt = lrintf((float)BaroAlt * barometerConfig->baro_noise_lpf + (float)BaroAlt_tmp * (1.0f - barometerConfig->baro_noise_lpf)); // additional LPF to reduce baro noise
Глянул в multiwii код. Это наследие из IMU.cpp и судя по комменту это я его добавил когда то 😃 Эта доп. фильтрация нужна была т.к. по raw baro velocity осуществлялась коррекция в компл. фильтре…
// baroGroundPressureSum is not supposed to be 0 here
// see:
BaroAlt = ( logBaroGroundPressureSum - log(baroPressureSum) ) * baroGroundTemperatureScale;
alt.EstAlt = (alt.EstAlt * 6 + BaroAlt ) >> 3; // additional LPF to reduce baro noise (faster by 30 µs)
#if (defined(VARIOMETER) && (VARIOMETER != 2)) || !defined(SUPPRESS_BARO_ALTHOLD)
//P
int16_t error16 = constrain(AltHold - alt.EstAlt, -300, 300);
applyDeadband(error16, 10); //remove small P parametr to reduce noise near zero position
BaroPID = constrain((conf.pid[PIDALT].P8 * error16 >>7), -150, +150);
//I
errorAltitudeI += conf.pid[PIDALT].I8 * error16 >>6;
errorAltitudeI = constrain(errorAltitudeI,-30000,30000);
BaroPID += errorAltitudeI>>9; //I in range +/-60
applyDeadband(accZ, ACC_Z_DEADBAND);
static int32_t lastBaroAlt;
// could only overflow with a difference of 320m, which is highly improbable here
int16_t baroVel = mul((alt.EstAlt - lastBaroAlt) , (1000000 / UPDATE_INTERVAL));
lastBaroAlt = alt.EstAlt;
baroVel = constrain(baroVel, -300, 300); // constrain baro velocity +/- 300cm/s
applyDeadband(baroVel, 10); // to reduce noise near zero
// Integrator - velocity, cm/sec
vel += accZ * ACC_VelScale * dTime;
// apply Complimentary Filter to keep the calculated velocity based on baro velocity (i.e. near real velocity).
// By using CF it's possible to correct the drift of integrated accZ (velocity) without loosing the phase, i.e without delay
vel = vel * 0.985f + baroVel * 0.015f;
//D
alt.vario = vel;
applyDeadband(alt.vario, 5);
BaroPID -= constrain(conf.pid[PIDALT].D8 * alt.vario >>4, -150, 150);
#endif
Абсолютно серьезно. Кроме шуток, мне барометр прикрытый белым паралоном стоил километров нервов - я никак не мог понять почему он работает дома (относительно темно) и скачет по высоте в яркий солнечный идеальный для полетов день.
ловил подобные глюки 2-3 года назад… перепад высоты был до 6-8 метров!