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

mahowik
rual:

Видимо твоя прошыва больше усредняет, меньше влияния акселя на горизонт, возможно ПИДы ИНС завышены.

ранее, когда мучил свою ИНС (а конкретно улучшайзер удержания позиции по гпс), так и не подобрал оптимальные коэф. соотношения аксель-гпс и отключил ее в итоге, хотя по графикам все ок было, т.е. в осях и знаках ошибок нет… уверен на 95% 😃 Теперь осознаю, что всеж надо было вибрации на платформе пофиксить сперва… иначе похоже никак. Для оси Z с инерциалкой попроще, т.к. для компенсации интеграторов используется быстрый и относительно точный (по сравнению с гпс) барометр. А вот для X,Y осей картинка другая, т.к. для повышения точности нужно больше доверия полагать на аксель (из-за того что гпс врет в большом диапазоне + тормозит по координатам на 1-2 сек), а тут уже вибрации выводят интеграторы из состояния равновесия… ну и да, для инерциалки по X,Y нужно калибровку шкал акселя по всем осям добавлять, что в арду 3.0.х и сделали на сколько помню… по Z необязательно, т.к. можно больше веры полагать на баро в компл. фильтре… т.е. баро устаканивает Z интегратор и по вибрациям и по нелинейностям шкалы акселя…

rual:

Кста, я тут к версии Ф3Дисковери МПУ6050 прикрутил ТОЛЬКО в качестве АКСЕЛЯ, похоже та же ситуация, но пока не разбирался.

а что за I2C драйвер использовал для F3? на сколько помню драйвер от F4 не подходит (хотя и то и то Cortex-M4) и там нужен какой то изврат или стороннюю либу пользовать…

SergDoc
mahowik:

а что за I2C драйвер использовал для F3? на сколько помню драйвер от F4 не подходит (хотя и то и то Cortex-M4) и там нужен какой то изврат или стороннюю либу пользовать…

не i2c практически одинаковы, есть мелкие нюансы, сводящиеся к настройке портов, по моему я больше ничего не переделывал, а на сколько понимаю то периферия в f3 больше похожа на f1 чем на f4?

mahowik

Самое главное забыл. ВЫ МОЛОДЦЫ! 😃
Давно пора порвать всякие там не бюджетные PX4 и пиксхавки! Не останавливайтесь! 😃

SergDoc

А тут какбы обратной дороги нет уже 😃 я чё в попыхах запускал в небо всё это дело - ибо уже надо 😃

soliada
SergDoc:

Ставь 1600 733 8g с адресом по барабану если регистры разные, читаешь/пишешь всё равно адрес->регистр, должно переварится

Собственно сделал все как Вы посоветовали. Честно говоря нечем было снимать ролик кроме телефона,а он был в этот момент вибростендом.
Датчик приклеил к экрану обычным 2х сторонним скочем,поставил в режим вибровызова и позвонил))) С указанными Вами настройками по оси Z в гуевских попугаях прыгало в пределах 2х единиц,по осям X и Y в пределах 4-5ти единиц (телефон полз по столу в момент вибрации)
Делитель был подобран таким образом,что в крайних положениях он был 1G= 256
Компас так и не настроил. Что-то не могу разобраться какие Гауссы и частоту чтения надо выставлять?И что надо выбрать,хай или лоу резолюшн?
Да,датчик в Москве в дорогом магазине стоит 130руб,но по идее,можно взять по 60-70руб. Вроде как уже скоро должен придти и L3GD20,правда подозреваю что не тот,что в пиксхавке.

SergDoc

Я более склонен полагать, что у него возникает резонанс с вибрацией от моторов примерно на частоте 4-5 кГц т.е. как раз на середине газа…

Мы так и не услышали начальника транспортного цеха пока нет никаких данных не по iris не по его контроллеру pixhawk 😦

soliada
SergDoc:

Я более склонен полагать, что у него возникает резонанс с вибрацией от моторов примерно на частоте 4-5 кГц т.е. как раз на середине газа…

Понял,тогда испытаю на коптере. Единственное,это будет мелколет на 3" пропеллерах.
ПС,есть что-то типа хубсана,сейчас попробую на него прилепить))

SergDoc

Я движки по акселю балансировал включал по одному с хомутом из стяжки и смотрел - хомут ворочал, потом снял колокольчики и на подшипниках повесил посмотреть - попал 😃

soliada

Ну,попробовал.По осям X и Y скачет в пределах 20-25 гуе-единиц,а вот по оси Z пипец,проседает единиц на 90.
Что интересно,прикрепленная сверху МПУ6050 показала по осям X и Y почти тот же разброс (фильтры в прошивке выключены),но по оси Z проседала не более чем на 40- 50 гуе-единиц.Испытания производились одновременно на 2х датчиках и 2х запущенных ГУИ.
Блин,извиняюсь,данные ошибочные.Не правильно сконфигурировал один из регистров и он видимо работал по умолчанию.Просто удивился,что при каждом включении приходилось делать калибровку.
Вообщем при тех настройках что были выше и при тех же условиях испытания.По оси X и Y разброс 5-6 гуе-единиц,по оси Z в пределах 3-4 гуе-единиц.

SergDoc

т.е. если сделать 1G = 512 так и будет как я и говорил, около 50 попугаев, так вот похоже фильтры MPU могут сгладить всё это, а в lsm нет, или же спектр другой, на мелколёте он повыше, так-же допускаю что аксель в 6000 лучше намного чем 6050, не думаю, что только из-за интерфейса они на столько разнятся в цене…

осталось увидеть iris не в рекламе, а у реальных пользователей…

vatanuki
mahowik:

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

а Вы не пробовали передавать показания акселя/гиры в сам жпс (ublox)?, хочю папробывать, и вот думаю может не сотит и ктото уже пробывал:)

mahowik

Вы хотите сказать, что ublox поддерживает “ИНС-режим” и ему можно отдать сырые данные акселя и гиры?! первый раз такое слышу… в теории наверное это возможно, но в таком случае ublox прошива должна иметь такую опцию и данные гиры акселя должны быть каким либо образом нормализованы для подачи на вход… еще это оч. сомнительно, т.к. чипы в гпс модулях и так еле справляются с обсчетом координат на сколько знаю, а вы говорите про доп. обсчет ИНС… сомнительно это… разве что какие нить дорогие спец. модули…

soliada
SergDoc:

т.е. если сделать 1G = 512 так и будет как я и говорил, около 50 попугаев

Ну да,по факту, если сделать 1G = 512, получается в районе 20 попугаев по оси X Y и в районе 15 по оси Z. Видимо МПУ6000 действительно супер-пупер,т.к 6050 показывает почти те же попугаи.Ну на самом деле,чего стоит ожидать от датчика за пару баксов)))

vatanuki
mahowik:

Вы хотите сказать, что ublox поддерживает “ИНС-режим” и ему можно отдать сырые данные акселя и гиры?!

тыкался с модулем, разбирался с настройками, и когда читал мануал, то мельком eвидел:

1.9 Automotive Dead Reckoning
Automotive Dead Reckoning (ADR) is u-blox’ industry proven off-the-shelf Dead Reckoning solution for tier-one
automotive customers. u-blox’ ADR solution combines GPS and sensor digital data using a tightly coupled
Kalman filter. This improves position accuracy during periods of no or degraded GPS signal.

The NEO-6V provides ADR functionality over its software sensor interface. A variety of sensors (such as wheel
ticks and gyroscope) are supported, with the sensor data received via UBX messages from the application
processor. This allows for easy integration and a simple hardware interface, lowering costs. By using digital
sensor data available on the vehicle bus, hardware costs are minimized since no extra sensors are required for
Dead Reckoning functionality. ADR is designed for simple integration and easy configuration of different sensor
options (e.g. with or without gyroscope) and vehicle variants, and is completely self-calibrating.

вот думал стоит вникать и разбираться или нет, оно это или нет 😃
вот еще про “это” www.u-blox.com/en/dead-reckoning.html

rual
mahowik:

Теперь осознаю, что всеж надо было вибрации на платформе пофиксить сперва… иначе похоже никак. Для оси Z с инерциалкой попроще, т.к. для компенсации интеграторов используется быстрый и относительно точный (по сравнению с гпс) барометр. А вот для X,Y осей картинка другая, т.к. для повышения точности нужно больше доверия полагать на аксель (из-за того что гпс врет в большом диапазоне + тормозит по координатам на 1-2 сек), а тут уже вибрации выводят интеграторы из состояния равновесия…

полностью согласен

mahowik:

ну и да, для инерциалки по X,Y нужно калибровку шкал акселя по всем осям добавлять, что в арду 3.0.х и сделали на сколько помню… по Z необязательно, т.к. можно больше веры полагать на баро в компл. фильтре… т.е. баро устаканивает Z интегратор и по вибрациям и по нелинейностям шкалы акселя…

Не знаю как в вие, но у меня допустим надо обязательно калибровку по всем осям, т.к. суммарный вектор ускорения по мировым Х,У легко может иметь не хилую проекцию на Z-ось акселя.

mahowik:

а что за I2C драйвер использовал для F3? на сколько помню драйвер от F4 не подходит (хотя и то и то Cortex-M4) и там нужен какой то изврат или стороннюю либу пользовать…

Использовал штатный СТшный драйвер от ЛСМ303 для настройки (т.е. записи в МПУ), и свой обработчик для чтения по прерываниям. Переписал нутексовый драйвер МПУ в Стшном стиле 😃


void Accel_Config(void)
{
	MPU6000_InitTypeDef MPU6000_InitStruct;
	LSM303DLHCAcc_InitTypeDef LSM303DLHCAcc_InitStructure;

	/* необходимо для настройки интерфейса i2c */
	LSM303DLHC_AccInit(&LSM303DLHCAcc_InitStructure);

	/* настройка MPU6050 */
	MPU6000_InitStruct.Reset = MPU6000_H_RESET;
	MPU6000_InitStruct.PowerConf 		=	MPU6000_CLK_SEL_PLLGYROZ;
	MPU6000_InitStruct.StandbyConf 	= MPU6000_NO_STANDBY;
	MPU6000_InitStruct.UserConf 			= MPU6000_NO_USER_CFG;
	MPU6000_InitStruct.DataOutputRate = 50;
	MPU6000_InitStruct.GyroFullScale = MPU6000_FS_2000DPS;
	MPU6000_InitStruct.GyroLPFConf 	=	MPU6000_DLPF_CFG_98HZ;
	MPU6000_InitStruct.AccFullScale 	=	MPU6000_AFS_8G;
	MPU6000_InitStruct.AccHPFConf 		= MPU6000_NO_ACC_HPF_CNG;
	MPU6000_InitStruct.InterruptConf = MPU6000_RAW_RDY_EN;
	MPU6000_InitStruct.InterruptPinConf = MPU6000_INT_ANYRD_2CLEAR;
	MPU6000_Init(&MPU6000_InitStruct);
}

вот тело читалки и2ц (Александр mahowik, я тебе вроде весь проект по Ф3 отправлял? там есть)

/* обработчик прерывания по событиям и буферу и2ц ИНС
 внутренний адрес размещаем в buf[0]*/

void I2C_INS_ISR(void)
{
	 switch(i2c_sts) /* конечный автомат и2ц*/
	 {
		case pustoy:
#ifdef MPU60x0_ACC
			NVIC_EnableIRQ(MPU60x0_I2C_INT_EXTI_IRQn);
#else
			NVIC_EnableIRQ(LSM303DLHC_I2C_INT1_EXTI_IRQn);
#endif
			break;

	 	case Sp: /* Stop */
			/* Clear STOPF flag */
			if (I2C_GetFlagStatus(LSM303DLHC_I2C, I2C_ISR_STOPF) == SET){
				/*сбросим флаги запросов прерываний */
				I2C_ClearITPendingBit(LSM303DLHC_I2C,I2C_IT_STOPI);
				I2C_ClearFlag(LSM303DLHC_I2C, I2C_ICR_STOPCF);
				i2c_sts = pustoy;

				/* здесь вызов метода-заполнителя данных объекта ИНС */
				switch(i2c_DeviceAddr){
					case MPU_I2C_ADDRESS:
					case ACC_I2C_ADDRESS: 	AccDataRdy(); break;

					/* чтение магнитометра */
					case MAG_I2C_ADDRESS: 	MagmDataRdy(); break;
				}
			}
#ifdef MPU60x0_ACC
			NVIC_EnableIRQ(MPU60x0_I2C_INT_EXTI_IRQn);
#else
			NVIC_EnableIRQ(LSM303DLHC_I2C_INT1_EXTI_IRQn);
#endif
			break;

		case Ra: 	/* Start */
			if (I2C_GetFlagStatus(LSM303DLHC_I2C, I2C_ISR_TXIS) == RESET) break;

			if(NumByteToRead>1)
				i2c_RegAddr |= 0x80;

			/* Send Register address */
			I2C_SendData(LSM303DLHC_I2C, (uint8_t)i2c_RegAddr);

		  i2c_sts = Rs;
			break;

		case Rs: /* ожидание передачи адреса регистра для чтения */
			if (I2C_GetFlagStatus(LSM303DLHC_I2C, I2C_ISR_TC) == RESET) break;
			/* формируем повторный старт*/
			I2C_TransferHandling(LSM303DLHC_I2C, i2c_DeviceAddr, NumByteToRead, I2C_AutoEnd_Mode, I2C_Generate_Start_Read);

			i2c_sts = Rd;
			break;

		case Rd:			/* Чтение очередного байта */
			if (I2C_GetFlagStatus(LSM303DLHC_I2C, I2C_ISR_RXNE) == RESET) break;
			if (NumByteToRead) {
				AccMag_buf[AccMag_buf_inx++] = I2C_ReceiveData(LSM303DLHC_I2C);

				if (--NumByteToRead==0) i2c_sts = Sp;
			} else
				i2c_sts = Sp;

			break;

		default: /* не понятное состояние = ошибка интерфейса */
			/*сбросим интерфейс */
			I2C_SoftwareResetCmd(LSM303DLHC_I2C);
			/*сбросим флаги запросов прерываний */
			I2C_ClearITPendingBit(LSM303DLHC_I2C, I2C_IT_TCI|I2C_IT_STOPI|I2C_IT_RXI|I2C_IT_TXI);
			i2c_sts = pustoy;
			break;
	}

	/* проверим выход указателя за пределы  буфера */
	if (AccMag_buf_inx > sizeof AccMag_buf)
				AccMag_buf_inx = sizeof AccMag_buf;

	/*сбросим флаги запросов прерываний */
	I2C_ClearITPendingBit(LSM303DLHC_I2C, I2C_IT_TCI|I2C_IT_STOPI|I2C_IT_RXI|I2C_IT_TXI);
}

драйвера МПУ в архиве.

SergDoc:

не i2c практически одинаковы, есть мелкие нюансы, сводящиеся к настройке портов, по моему я больше ничего не переделывал, а на сколько понимаю то периферия в f3 больше похожа на f1 чем на f4?

Нее, Сергей, Ф1 и Ф3 сильно разные. Как раз у Ф3 периферия, я думаю, наиболее продвинутая. А конкретно i2c интерфейс у Ф1 и Ф4 совершенно одинаковый, сам выполняет только отдельные операции на шине, т.е. Start, Stop и передача/приём байта, “пока не пнёшь не полетит” ). У Ф3 всё интересней, он сам поддерживает полный цикл обмена, от Start до Stop, в прерываниях только запрашивает, либо получает данные. Вот штатная функция от Ф3Дисковери:

/**
  * @brief  Writes one byte to the LSM303DLHC.
  * @param  DeviceAddr : specifies the slave address to be programmed.
  * @param  RegAddr : specifies the LSM303DLHC register to be written.
  * @param  pBuffer : pointer to the buffer  containing the data to be written to the LSM303DLH.
  * @retval LSM303DLHC Status
  */
uint16_t LSM303DLHC_Write(uint8_t DeviceAddr, uint8_t RegAddr, uint8_t* pBuffer)
{
  /* Test on BUSY Flag */
  LSM303DLHC_Timeout = LSM303DLHC_LONG_TIMEOUT;
  while(I2C_GetFlagStatus(LSM303DLHC_I2C, I2C_ISR_BUSY) != RESET)
  {
    if((LSM303DLHC_Timeout--) == 0) return LSM303DLHC_TIMEOUT_UserCallback();
  }

  /* Configure slave address, nbytes, reload, end mode and start or stop generation */
  I2C_TransferHandling(LSM303DLHC_I2C, DeviceAddr, 1, I2C_Reload_Mode, I2C_Generate_Start_Write);

  /* Wait until TXIS flag is set */
  LSM303DLHC_Timeout = LSM303DLHC_LONG_TIMEOUT;
  while(I2C_GetFlagStatus(LSM303DLHC_I2C, I2C_ISR_TXIS) == RESET)
  {
    if((LSM303DLHC_Timeout--) == 0) return LSM303DLHC_TIMEOUT_UserCallback();
  }

  /* Send Register address */
  I2C_SendData(LSM303DLHC_I2C, (uint8_t) RegAddr);

  /* Wait until TCR flag is set */
  LSM303DLHC_Timeout = LSM303DLHC_LONG_TIMEOUT;
  while(I2C_GetFlagStatus(LSM303DLHC_I2C, I2C_ISR_TCR) == RESET)
  {
    if((LSM303DLHC_Timeout--) == 0) return LSM303DLHC_TIMEOUT_UserCallback();
  }

  /* Configure slave address, nbytes, reload, end mode and start or stop generation */
  I2C_TransferHandling(LSM303DLHC_I2C, DeviceAddr, 1, I2C_AutoEnd_Mode, I2C_No_StartStop);

  /* Wait until TXIS flag is set */
  LSM303DLHC_Timeout = LSM303DLHC_LONG_TIMEOUT;
  while(I2C_GetFlagStatus(LSM303DLHC_I2C, I2C_ISR_TXIS) == RESET)
  {
    if((LSM303DLHC_Timeout--) == 0) return LSM303DLHC_TIMEOUT_UserCallback();
  }

  /* Write data to TXDR */
  I2C_SendData(LSM303DLHC_I2C, *pBuffer);

  /* Wait until STOPF flag is set */
  LSM303DLHC_Timeout = LSM303DLHC_LONG_TIMEOUT;
  while(I2C_GetFlagStatus(LSM303DLHC_I2C, I2C_ISR_STOPF) == RESET)
  {
    if((LSM303DLHC_Timeout--) == 0) return LSM303DLHC_TIMEOUT_UserCallback();
  }

  /* Clear STOPF flag */
  I2C_ClearFlag(LSM303DLHC_I2C, I2C_ICR_STOPCF);

  return LSM303DLHC_OK;
}

т.е надо только вызвать функцию подготовки интерфейса I2C_TransferHandling(LSM303DLHC_I2C, DeviceAddr, 1, I2C_Reload_Mode, I2C_Generate_Start_Write), а дальше по флагу освобождения регистра передатчика I2C_ISR_TXIS подталкивать данные.

MPU60x0.rar

Drinker
SergDoc:

Так что у мистера Drinkera есть ещё время для создания нормальной темы про iris

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

SergDoc:

Мы так и не услышали начальника транспортного цеха пока нет никаких данных не по iris не по его контроллеру pixhawk

Выше написано

Штоп не было ненужных мыслей, вот что попытался с телефона прицепить - коропка и опись содержимого. Терпения господа. Дайте добраться до дела.

SergDoc

А никто не гадит в чужой теме чисто трёпом, давайте факты!!! а я взлетел, ибо как вы выразились “дешевка”…
Кстати я разгадал тайный замысел 3D Robotix 😃 они просто ушли таким способом с i2c… мы кстати можем тоже невзначай, но чуть попозже, когда mpu-шки с компасом появятся… или заложить всё spi сразу? но смысл?компас и баро - датчики не срочные, да и как говорилось выше будет дополнительный выносной компас кому надо…

rual:

драйвера МПУ в архиве.

только фильтр на гиру поставь 42 или вообще 20… не надо ей много знать 😃 98 - перебор…

Drinker
SergDoc:

а я взлетел, ибо как вы выразились “дешевка”…

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

SergDoc:

давайте факты!!!

SergDoc:

а я взлетел

Это конечно мегафакт.
Если есть конкретные вопросы, то с удовольствием отвечу. Пока не понимаю какие факты. Летает все начиная от 15 баксов.

SergDoc

Мне нужны данные по LSM которая стоит в PIXHAWK, ибо я не понимаю - у меня например на мелкоплате был офигенный разброс по осям датчика!!!
а на MPU всё супер, так лучше я дороже датчик куплю и поставлю его в “дешевку” чем непонятную хрень за 200 долырей с двумя процами при этом общающимися по i2c и дешевыми датчиками! вот о чём я твержу…

Drinker:

Летает все начиная от 15 баксов.

Летает и ёжик если его пнуть основательно 😃 вопрос как 😃
А мне и на мою “дешевку” надо копить несколько месяцев 😦

Drinker
SergDoc:

чем непонятную хрень

Думаю “там” не идиоты сидят. Да и вообще какая разница и2с там или спи, лсм или мпу. Железо сбито с алгоритмами и получен результат. Чего еще надо?

SergDoc:

у меня например на мелкоплате был офигенный разброс по осям датчика

Можно подробнее? че за лсм?

SergDoc

LSM330DL если память не изменяет, и резонанс акселя ровно на середине газа…