Создание собственной системы стабилизации
Есди ДУСы дают нам угловую скорость, а нам нужен угол - тут как бы только интегрирование 😃
Хотелось бы поинтерqесоваться у искушенной публики: - что делают с сырыми данными акселя и гиры в разных открытых проектах перед подачей в алгоритм IMU ??
Сам посмотрел у AQ32 , вроде понятно, что сначала интегрируют их, потом усредняют и обсчет в IMU ведется с частотой 500 гц вроде…
Ничего не надо делать, подавайте сразу в алгоритм, нужно только правильно выбрать постоянную интегрирования.
тут как бы только интегрирование
Не, я не об этом… (это мне уже понятно 😃), в “чистом” виде я их уже подавал в своем предыдущем проекте, работало и так… , тут мысли возникают направить мощь STM на предварительную фильтрацию данных, и для оценки разных подходов (если таковые вообще есть) и спрашиваю…
Просто гляжу, судя по постам в теме, что знаний чужого кода у меня в разы меньше (а вернее нет) чем у других…
постоянную интегрирования.
Вот как раз это мне и интересно…
Сейчас суммарный обсчет положения сделал (благо MPU) 1000 Гц, разницы с предыдущим проектом 200 Гц субъективно не наблюдается, - мораль: а надо ли гнаться за частотой ? Может наоборот герц эдак 100 сделать ? (вот и вам и DLPF получится). Всеж хочется добиться в своем (хенд мэйд) проекте каких то результатов по качеству.
Кстати у MPU аксель, у меня, дает шум +/- 100 ед. при шкале 4G это нормально ?
видяху то ставит, а вот cuda ни в какую 😦
Накати сперва все обновления и все решится скорее всего…
Сейчас суммарный обсчет положения сделал (благо MPU) 1000 Гц, разницы с предыдущим проектом 200 Гц субъективно не наблюдается, - мораль: а надо ли гнаться за частотой ? Может наоборот герц эдак 100 сделать ? (вот и вам и DLPF получится). Всеж хочется добиться в своем (хенд мэйд) проекте каких то результатов по качеству. Кстати у MPU аксель, у меня, дает шум +/- 100 ед. при шкале 4G это нормально ?
MPU внутри работает на 1(8)КГц, а данные суммирует в зависимости от выходной частоты. Поэтому нету особой разницы где суммировать, на стороне CPU или MPU - результат один и тот же 😃
Накати сперва все обновления и все решится скорее всего…
Я уже бубунту с wine накатил 😃 - теперь и мои дела работают и сына 😃
блин такое желание старый контроллер разобрать и собрать новый - нее подожду деталек…
MPU внутри работает на 1(8)КГц, а данные суммирует в зависимости от выходной частоты. Поэтому нету особой разницы где суммировать, на стороне CPU или MPU - результат один и тот же
Привет! А что означает суммирование в мпу?
тут мысли возникают направить мощь STM на предварительную фильтрацию данных
Смысла нет, лучше эту мощь в алгоритме использовать.
а надо ли гнаться за частотой ?
не надо, нет смыла задирать скорость выше скорости реакции приводов (серв, моторов и тп).
А что означает суммирование в мпу?
Вот это хз… но смысл такой, что ДУС там всегда работает на 1000Гц, а скорость выдачи данных, одновременно ДУС+аксель, получается делением на настраиваемый коэффициент K, дык вот за время dt = (к+1)/1000 отсчёты ДУС усредняются.
Очередной затык, теперь с 5611, “пихаю” 24-х битное число (из трех uint8_t) в uint32_t так:
D1=(uint32_t)((b1<<24)|(b2<<16)|(b3<<8)); - // по моему не правильно, но работает…
или
D1=(uint32_t)((b1<<16)|(b2<<8)|b3); -// по моему правильно но результат - не тот…
Где я туплю ??
Правильно так:
D1=(uint32_t)((b1<<16)|(b2<<8)|b3);
Правильно так:
D2=(uint32_t)((b1<<16)|(b2<<8)|b3);
Я тоже так думаю, но после нехитрых вычислений далее (расчет температуры 5611 по даташиту):
dT=(int32_t)(D2 -C5*256);
MS_temper=2000 + dT*C6/8388608;
, нужный результат почему то получается именно при “неправильном” способе присвоения…
если про это
static uint32_t ms5611_read_adc(void)
{
uint8_t rxbuf[3];
i2cRead(MS5611_ADDR, CMD_ADC_READ, 3, rxbuf); // read ADC
return (rxbuf[0] << 16) | (rxbuf[1] << 8) | rxbuf[2];
}
` int64_t dT = ms5611_ut - ((int32_t)ms5611_c[5] << 8);
int64_t off = ((uint32_t)ms5611_c[2] << 16) + ((dT * ms5611_c[4]) >> 7);
int64_t sens = ((uint32_t)ms5611_c[1] << 15) + ((dT * ms5611_c[3]) >> 8);
temp = 2000 + ((dT * ms5611_c[6]) >> 23);
драйвера есть все в открытом доступе, тут даже смысла не вижу изобретать?
тут даже смысла не вижу изобретать
Сам не хотел изобретать, сначала взял готовый кусок кода, но фиг там … Похоже надо с компилятором повнимательней разобраться (с указанием типов), где то переполнение вылазит., так что “скопипастить” не получилось…
Мда… Все ж компиллер как то теряет знаковый тип при сдвиге (делении) больших чисел, отсюда и косяк у меня,…
Не было печали…
Keil вроде с оффсайта качал, правда он с ограничениями… (не в этом ли дело?)…
Мда… Все ж компиллер как то теряет знаковый тип при сдвиге (делении) больших чисел, отсюда и косяк у меня,…
Не было печали…
Keil вроде с оффсайта качал, правда он с ограничениями… (не в этом ли дело?)…
кейл с ограничениями тут не причем, компилятор “считает” с права налево и выполняет действия согласно приоритетам операций. Может он что то не то сначала вычисляет.
эти формулы не правильно считаются?
dT=(int32_t)(D2 -C5*256);
MS_temper=2000 + dT*C6/8388608;
покажите кусок кода и какие типы переменных используются.
покажите кусок кода
Вот переменные:
int32_t dT,MS_temper;
uint32_t D2;
uint16_t C5,C6;
Вот расчет:
dT=D2 - (uint32_t)C5<<8; //( dT здесь получается 1700, проверял)
MS_temper=((int64_t)dT*28312)>>23;
MS_temper выходит -131, хотя должно быть 5…
Если пишу прям так: MS_temper=(1700*28312)>>23;
или присваиваю ранее dT=1700; - то как раз 5 и выходит…
Такое ощущение что c типом int64_t что то не так…
при умножении вылазит за 32 бита, попробуйте заменить на double, если заработает посмотрите как определен тип int64.
Возможно int64 определен как long, а компилятор его считает 32 битным, вспомнил (long long) 64 бита целочисленное.
Возможно int64 определен как long
Да, спасибо Вам за наводку, похоже где то здесь косяк… (первый признак, проверенные примеры из инета не работают…) буду копать.
Если “быстро” поправить то можно написать:
MS_temper=((long long)dT*28312)>>23;
Камрады, а зачем вы геммороитесь с такими операцыями типа <<8 и >>23? кто мешает нормально делить и перемножать числа как и указано в даташите? Сами себе проблемы ищете.
Или наносекунды экономите?
это касается и возведения в степень
заранее двойку в степень возведите и усе
Вот расчет:
dT=D2 - (uint32_t)C5<<8; //( dT здесь получается 1700, проверял)
вот здесь еще косяк, не хватает скобочек:
dT=D2 - ((uint32_t)C5<<8);
Камрады, а зачем вы геммороитесь с такими операцыями типа <<8 и >>23? кто мешает нормально делить и перемножать числа как и указано в даташите? Сами себе проблемы ищете.
Или наносекунды экономите?
это касается и возведения в степень
заранее двойку в степень возведите и усе
можно и без << >>, просто это пример из интернета, вот его и разбирали почему не работает