Вопросы по iNav

jShadow
mahowik:

лаг гпс поставьте хотя бы пол секунды иначе все расчеты в ИНС будут в прах
еще смотрел у вас в ИНС коррекция Z оси идет не через хистори, а напрямую, а ведь лаг барометра после всех кальцуляций и филтрации это тоже ~300мс… у меня так по графикам вышло…

Экспериментировал с задержкой барометра - становится хуже. Надежнее чуть больше доверять акселю, а на медленный дрейф забить.

Задержку GPS да, можно и до 500мс увеличить. Хотя для скорости и курса она для Pedestrian-модели вообще до пары секунд доходить может…

mahowik
jShadow:

Экспериментировал с задержкой барометра - становится хуже. Надежнее чуть больше доверять акселю, а на медленный дрейф забить.

задержка фазы в данных приводит к болтанке и необходимости ослабления ПИД-ов в итоге… проверено…

jShadow:

Задержку GPS да, можно и до 500мс увеличить. Хотя для скорости и курса она для Pedestrian-модели вообще до пары секунд доходить может…

это как? для разных скоростей разный лаг?
вы пробовали как нить померять задержку? для ИНС, как писал ранее, это самый важный параметр фактически…

jShadow:

Бывает иногда

DigitalEntity - это я и есть

мы наверное о разном или о разных… 😃
я две недели назад писал парочку соображений…
rcopen.com/forum/f123/topic443443/173

jShadow
mahowik:

задержка фазы в данных приводит к болтанке и необходимости ослабления ПИД-ов в итоге… проверено…

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

mahowik:

это как? для разных скоростей разный лаг?

Нет, для разных GPS-модулей разный лаг. В координатах на модели Pedestrian около 200-500 мс обычно, на модели Airborn<4G менее 100мс.

mahowik:

У вас в коде ГПС лаг выставлен на 1.5 сек. Это на глазок я так понимаю? ИНС уже работает на удержние позиции в полевых условиях?

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

mahowik:

На сколько тяжелый BiQuad фильтр? В чем его плюс? Не дает задержки фазы на нужных частотах?

Легкий, не сложнее FIR. Плюс в том, что параметры можно легко посчитать для любой частоты среза, в отличие от FIR. Фазовую задержку вносит больше, чем FIR или примитивный RC-фильтр, но это с лихвой окупается настраиваемой АЧХ.

mahowik
jShadow:

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

так не будет же своей задержки… т.е. ошибка будет высчитана из значений баро и актуальных расчетных данных (по акселю) из хистори, т.е. данные одной временной шкалы…

jShadow:

Нет, для разных GPS-модулей разный лаг. В координатах на модели Pedestrian около 200-500 мс обычно, на модели Airborn<4G менее 100мс.

это понятно что лаг разный для разных модулей… а как меряли? по логам?

jShadow:

0.2 сек работает в полевых условиях, причем работает неплохо

лаг баро ~0.3 сек… по вашей логике для шустрых гпс модулей хистори не нужна 😃

jShadow
mahowik:

так не будет же своей задержки… т.е. ошибка будет высчитана из значений баро и актуальных расчетных данных (по акселю) из хистори, т.е. данные одной временной шкалы…

Это если угадаешь. А если попадется более шустрый сенсор то расчетные данные могут оказаться из “прошлого” по отношению к баро, что скорее всего приведет к нарушению сходимости (осцилляция расчетной координаты).

mahowik:

это понятно что лаг разный для разных модулей… а как меряли? по логам?

По логам, сравнивал данные, выдаваемые GPS и наблюдаемые по акселерометру. Меньше 200мс значение ни разу не получалось, так что 200мс - вполне безопасное значение по умолчанию.

mahowik:

лаг баро ~0.3 сек… по вашей логике для шустрых гпс модулей хистори не нужна

Нужна, с этим я не спорю, проблема в том, что мои попытки ее внести приводили только к ухудшению сходимости.

Всё усугубляется еще и тем, что дискретность данных разная. У интеграторов ИНС - 500Гц-1кГц, смотря какой looptime выставлен, у GPS - 5-10Гц, у баро - 20Гц, а у хистори (и у выходных данных ИНС) - 50Гц.

mahowik
jShadow:

Это если угадаешь. А если попадется более шустрый сенсор то расчетные данные могут оказаться из “прошлого” по отношению к баро, что скорее всего приведет к нарушению сходимости (осцилляция расчетной координаты).

Если ориентироваться на mpu6050/6000 (где внутренний фильтр на 42 или 20гц) и ms5611, то картина предельно ясная. Выводим расчетные высоту по акселю из хистори и сырую высоту по баро на графики и подбираем задержку буфера для хистори по схождению этих двух кривых.
У меня вышло ~325мс. Сам удивился, т.к. ожидал ~150мс макс… Получилось довольно точно, т.к. сейчас даже при обильной болтанке по вертикали, расхождение минимально…

jShadow:

По логам, сравнивал данные, выдаваемые GPS и наблюдаемые по акселерометру. Меньше 200мс значение ни разу не получалось, так что 200мс - вполне безопасное значение по умолчанию.

Это вы наверное на довольно современных модулях катались 😃
Пристарелые народные mtk3329/3339 и ublox-ы определенно от 500мс и выше. Хотя я пытался бегать стометровки по полю уже полтора-два года назад 😃
В прошлом году Алексей Козин придарил мне парочку на mtk3333 с поддержкой Глонасс. Этот уже пошустрее, может там и будет 200-300мс. У вас на этом чипсете нет модулей? Не меряли?

jShadow
mahowik:

Если ориентироваться на mpu6050/6000 (где внутренний фильтр на 42 или 20гц) и ms5611, то картина предельно ясная. Выводим расчетные высоту по акселю из хистори и сырую высоту по баро на графики и подбираем задержку буфера для хистори по схождению этих двух кривых.

У вас же это уже сделано и работает? Можно глянуть код? Вдруг я где-то делаю элементарную ошибку из-за чего у меня оно и не работает.

mahowik:

Пристарелые народные mtk3329/3339 и ublox-ы определенно от 500мс и выше. Хотя я пытался бегать стометровки по полю уже полтора-два года назад

Странно, у меня на Neo-M8N получилось 200-300 мс.

mahowik:

В прошлом году Алексей Козин придарил мне парочку на mtk3333 с поддержкой Глонасс. Этот уже пошустрее, может там и будет 200-300мс. У вас на этом чипсете нет модулей? Не меряли?

Нету, увы.

Ri777
jShadow:

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

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

jShadow
Ri777:

Свет тоже лучше не подпускать

Да, кстати, совсем про это забыл. Барометр темноту любит 😁

jShadow
lentyay:

Насчёт света шутка или всерьёз?

Абсолютно серьезно. Кроме шуток, мне барометр прикрытый белым паралоном стоил километров нервов - я никак не мог понять почему он работает дома (относительно темно) и скачет по высоте в яркий солнечный идеальный для полетов день.

Ri777
lentyay:

Насчёт света шутка или всерьёз?

Тоже думал шутка, пока фонариком не посветил. Черный но тонкий паралон тоже пропускает свет…

Talentfrei

Господа, может не будем зацикливаться на старых GPS модулях? Кто то же должен поддерживать товарооборот в Китае!!! 😃))
По поводу PID, я очень доволен LuxFloat. Так что всё остальное можно убрать для освобождения места.

jShadow
Talentfrei:

Господа, может не будем зацикливаться на старых GPS модулях? Кто то же должен поддерживать товарооборот в Китае!!! 😃))

О да, к тому же я очень доволен тем, как летает Ublox Neo-M8N.

Talentfrei:

По поводу PID, я очень доволен LuxFloat. Так что всё остальное можно убрать для освобождения места.

У меня в разработке как раз переделанный LuxFloat. Сейчас тестируется и дорабатывается, после того как доведу его до ума, он станет единственным.

mahowik
jShadow:

У вас же это уже сделано и работает? Можно глянуть код?

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;
	}
}

jShadow:

Странно, у меня на 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
jShadow:

Абсолютно серьезно. Кроме шуток, мне барометр прикрытый белым паралоном стоил километров нервов - я никак не мог понять почему он работает дома (относительно темно) и скачет по высоте в яркий солнечный идеальный для полетов день.

ловил подобные глюки 2-3 года назад… перепад высоты был до 6-8 метров!

jShadow
mahowik:

debug[1] и debug[2], в correctZStateWithBaro() функции, в идеале должны конвёржиться/совпадать на графике…

Благодарю, поковыряю на досуге. Фокус в том что в вашем коде частота обновления ИНС совпадает с частотой обновления барометра. У меня не так, по-идее мне компенсацию задержки нужно переделывать…

mahowik:

Еще посмотрел у вас в baroCalculateAltitude() функции (стр. 175) остался фильтр. Для данной ИНС имплементации он не нужен по идее.

Да, действительно, это остался рудимент от МультиВия, мне он в общем-то и не нужен (только лишнюю задержку вносит). Уберу, спасибо 😃

ekuzmi

Вопрос по калибровке магнитометра.
Калибрую с аппаратуры, сохраняю параметры.
Потом наклоняю коптер и смотрю, как меняется Heading. Так вот при наклонах по ролу - можно наклонять хоть до 45 градусов - Heading почти не меняется, при наклоне по питч вперед - все отлично, назад - при наклоне на 15 градусов начинает уходить heading, а при наклоне в 20 градусов уже уезжает до 50 градусов.
вот результаты калибровки:
set magzero_x = 27
set magzero_y = -89
set magzero_z = -24
Похожи ли они на правду?

  1. Как правильно калибровать магнитометр? На это дается всего 30 секунд, это довольно мало. В начало калибровки можно было бы и пикнуть - сейчас тишина, а пикает только в конце калибровки.
  2. Может и так сойдет? Наклон назад при навигации почти не используется, а вперед и в стороны компас не уходит.
  3. Может это проблема моего внешнего магнитометра? Кристалл внутри микросхемы расположен криво и никак его не откалибруешь хорошо. 😃
  4. Вспомнил насчет бипера,- куда подевалась команда set beeper_off_flags?
jShadow
ekuzmi:

Калибрую с аппаратуры, сохраняю параметры.
Потом наклоняю коптер и смотрю, как меняется Heading. Так вот при наклонах по ролу - можно наклонять хоть до 45 градусов - Heading почти не меняется, при наклоне по питч вперед - все отлично, назад - при наклоне на 15 градусов начинает уходить heading, а при наклоне в 20 градусов уже уезжает до 50 градусов.
вот результаты калибровки:
set magzero_x = 27
set magzero_y = -89
set magzero_z = -24
Похожи ли они на правду?

Магнитометр смотнирован в той же плоскости, что и сама плата ПК или под углом? Рядом точно ничего металлического или магнитного нет? Пищалка - тоже магниит.

ekuzmi:

Как правильно калибровать магнитометр? На это дается всего 30 секунд, это довольно мало. В начало калибровки можно было бы и пикнуть - сейчас тишина, а пикает только в конце калибровки.

Включить калибровку и 30 секунд махать коптером в воздухе 😃

ekuzmi:

Может и так сойдет? Наклон назад при навигации почти не используется, а вперед и в стороны компас не уходит.

Не думаю, что сойдет. При борьбе с ветром или при торможении коптер может и назад наклониться.

ekuzmi:

Вспомнил насчет бипера,- куда подевалась команда set beeper_off_flags?

Ее заменит команда “beeper” по аналогии с “feature”. Код живет в ветке beeper-rework, войдет в 1.1 после тестов.

Talentfrei

@jShadow Като сранно он себя ведет послe быстрых флипов, уходит по Yaw, приходится доводить. Константин, вы случайно не на базе Cleanflight 1.8 все это писали. Там помойму был Bug…