Специальные цены   новые товары
+ Ответить в теме
Страница 71 из 226 ПерваяПервая ... 61 69 70 71 72 73 81 ... ПоследняяПоследняя
Показано с 2,801 по 2,840 из 9004

ArduCopter Mega: порт на обычную Arduino (тестим)

Тема раздела Коптеры. Комплектующие, сборка, настройка. в категории Квадрокоптеры и мультироторы; Сообщение от Musgravehill Да, проверено много раз! И не только ПИД, но и Левел, деклинацию. Ругается, если в качестве разделителя ...

  1. #2801

    Регистрация
    17.06.2011
    Адрес
    Минск
    Возраст
    39
    Сообщений
    1,941
    Цитата Сообщение от Musgravehill Посмотреть сообщение
    Да, проверено много раз! И не только ПИД, но и Левел, деклинацию. Ругается, если в качестве разделителя ставить ",", а не точку: 2.887
    Не знаю, как именно планер передает значения, но если в текстовом виде, то тогда понятно откуда ноги растут. В зависимости от региональных настроек винды, числа могу вводится с точкой или запятой. А коптер понимает всегда только с точкой (или с запятой, надо проверить). Поэтому у некоторых людей, наблюдаются глюки с планером (если разделитель не совпадают).

    Цитата Сообщение от Musgravehill Посмотреть сообщение
    Используется не фильтрация, а калибровочные данные датчика, текущая температура и MSB, LSB и XLSB. s = T − 25 x = x2*s^2 + x1*s + x0 y = y2*s^2 + y1*s + y0 z = pu − x \ y, где Pu - измеренное давление без корректировки p2, p1, p0 - коэффициенты из мат.модели датчика. P = p2*z^2 + p1*z + p0 = истинное давление.
    если так, то почему сам датчик не вычисляет давление по этим калибровочным данным?

  2.  
  3. #2802

    Регистрация
    11.01.2011
    Адрес
    Ярославль
    Возраст
    29
    Сообщений
    1,392
    Цитата Сообщение от Sir Alex Посмотреть сообщение
    если так, то почему сам датчик не вычисляет давление по этим калибровочным данным?
    не знаю точно. Сказано, что калибровочные данные уникальны для каждого датчика (в его EEPROM хранятся коэффициенты смещения, температурной компенсации..всего 176 бит). Он выплевывает калибровки, raw_ температуру и давление. Остальное - сам, ручками. Наверное, в датчике простая логика, которую не нагружают дополнительными вычислениями.

    Кстати, желательно обращаться к датчику с частотой не более 40Гц, лучше 20Гц (50 мс). Если oss=3 (максимальное разрешение), то время обработки запроса 25.5 мс.

    Нужно или выставить малое oss и самому фильтровать\усреднять, зато иметь частоту опроса до 128Гц. Или использовать высокое разрешение oss=3, но частота опроса падает.

    Температура сенсора используется только для корректировки показаний (она влияет на сам сенсор, а не на давление), поэтому не играет роли, где стоит барометр. Еще, чтоб не забыть: "при делении на степени двойки путем сдвига вправо не мультиплицировал знаковый разряд, а просто посылал туда 0. Это приводило к тому, что отрицательные числа при делении на степени двойки становились положительными! Для положительных чисел все работает нормально. Спасибо, ошибка была вызвана скорее невнимательностью: не привел тип unsigned к signed до вычислений, оставив это компилятору (avr-gcc). И самое удивительное, что при комнатной температуре ошибка почти не проявляла себя."
    Последний раз редактировалось Musgravehill; 19.09.2011 в 13:51.

  4. #2803

    Регистрация
    17.06.2011
    Адрес
    Минск
    Возраст
    39
    Сообщений
    1,941
    Цитата Сообщение от Musgravehill Посмотреть сообщение
    не знаю точно. Сказано, что калибровочные данные уникальны для каждого датчика (в его EEPROM хранятся коэффициенты смещения, температурной компенсации..всего 176 бит). Он выплевывает калибровки, raw_ температуру и давление. Остальное - сам, ручками. Наверное, в датчике простая логика, которую не нагружают дополнительными вычислениями.
    Посмотрел код работы с BMP085, ну так там и так все по формулам с даташита сделано. Т.е. уже используются калибровочные коэффициенты.

    Цитата Сообщение от Musgravehill Посмотреть сообщение
    Кстати, желательно обращаться к датчику с частотой не более 40Гц, лучше 20Гц (50 мс). Если oss=3 (максимальное разрешение), то время обработки запроса 25.5 мс.
    Обновление барометра идет с частотой 10Hz - что вполне достаточно. OSS=3.

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

  5. #2804

    Регистрация
    11.01.2011
    Адрес
    Ярославль
    Возраст
    29
    Сообщений
    1,392
    Цитата Сообщение от Sir Alex Посмотреть сообщение
    Кстати, можно еще подключить вывод готовности барометра к ардуине, тогда можно будет не ждать окончания измерения данных (В АрдуКоптере так и работает)
    Нужно паять проводок. В нашей библиотеке прерывания по INT просто закомментированы.
    Цитата Сообщение от Sir Alex Посмотреть сообщение
    Посмотрел код работы с BMP085, ну так там и так все по формулам с даташита сделано. Т.е. уже используются калибровочные коэффициенты.
    Да, списано 1-к-1. Но нет пауз 4.5мс между Write и Read. Я нашел работу от 25 апреля 2011, где автор предлагает использовать другую мат.модель. Вечером испытаю.

    Цитата Сообщение от Sir Alex Посмотреть сообщение
    Обновление барометра идет с частотой 10Hz
    Алексей, как вы это узнали? И как можно получить время одного цикла работы Мегапирата? (чтобы вывести serial.print(cycle_time, DEC); )

  6.  
  7. #2805

    Регистрация
    17.06.2011
    Адрес
    Минск
    Возраст
    39
    Сообщений
    1,941
    Цитата Сообщение от Musgravehill Посмотреть сообщение
    В нашей библиотеке прерывания по INT просто закомментированы.
    Не, там не прерывания. Просто проверяется состояние пина, если там 0, то пропускается текущая итерация, если 1, то считывается текущее значение и запускается следующее измерение.
    Кроме того, для оптимизации, температура считывается 1 раз из 4х. Т.е. читается температура, потом 4 раза давление.

    Цитата Сообщение от Musgravehill Посмотреть сообщение
    Алексей, как вы это узнали? И как можно получить время одного цикла работы Мегапирата? (чтобы вывести serial.print(cycle_time, DEC); )
    Легко - в коде написано (см. функцию update_altitude в ArduCopterMega.pde)

  8. #2806

    Регистрация
    11.01.2011
    Адрес
    Ярославль
    Возраст
    29
    Сообщений
    1,392
    Цитата Сообщение от Sir Alex Посмотреть сообщение
    Кроме того, для оптимизации, температура считывается 1 раз из 4х. Т.е. читается температура, потом 4 раза давление.
    Еще интересные фильтры в read_pressure и read_temperature, которые сглаживают быстрый сдвиг raw_data. Пошагово тестировал их, пока не понял.

    Еще казус был, что АрдуиноIDE показывает список файлов в проекте справа в виде вертикального списка. В нем нет прокрутки, и на экран 22" он не помещается. Я проморгал, что есть файлы ниже read***.pde и перерыл все папки в library. А потом обнаружил sensors.pde в проекте

  9. #2807

    Регистрация
    17.06.2011
    Адрес
    Минск
    Возраст
    39
    Сообщений
    1,941
    Цитата Сообщение от Musgravehill Посмотреть сообщение
    Еще интересные фильтры в read_pressure и read_temperature
    Обычное усреднение показаний.

  10.  
  11. #2808

    Регистрация
    17.06.2011
    Адрес
    Минск
    Возраст
    39
    Сообщений
    1,941
    Кто нибудь в курсе, что такое HIL?

  12. #2809

    Регистрация
    29.01.2011
    Адрес
    Дмитров
    Возраст
    29
    Сообщений
    4,600
    Записей в дневнике
    77
    как я понял hardware in loop - типа когда всё отрабатывается, но без выхода на моторы чтоли, толи для симуляции, толи для дебага

  13. #2810

    Регистрация
    17.06.2011
    Адрес
    Минск
    Возраст
    39
    Сообщений
    1,941
    Цитата Сообщение от SovGVD Посмотреть сообщение
    как я понял hardware in loop - типа когда всё отрабатывается, но без выхода на моторы чтоли, толи для симуляции, толи для дебага
    Да, я уже нашел http://code.google.com/p/ardupilot-mega/wiki/Xplane

    Кстати, как тебе новая стартовая страница Wiki?

  14. #2811

    Регистрация
    29.01.2011
    Адрес
    Дмитров
    Возраст
    29
    Сообщений
    4,600
    Записей в дневнике
    77
    Цитата Сообщение от Sir Alex Посмотреть сообщение
    как тебе новая стартовая страница Wiki?
    зашибись! =)

  15. #2812

    Регистрация
    06.05.2005
    Адрес
    Санкт-Петербург
    Возраст
    40
    Сообщений
    1,309
    Цитата Сообщение от Musgravehill Посмотреть сообщение
    Да, проверено много раз! И не только ПИД, но и Левел, деклинацию. Ругается, если в качестве разделителя ставить ",", а не точку
    Если ставить ставить "," поле вообще становится красным, мол параметр не верный... А "Failed set..." выдает и при верных параметрах, тут дело похоже в АРС220, при УСБ соединении такого нет, а при радио линке выскакивает часто, и чем дальше квадрик от тебя тем сложнее записать параметр, у меня обычно пишется раза с 3...

    К стати проверял кто нить на 40 прошивке РТЛ? Сегодня пробовал, чтот ведет себя как в режиме лойт, не разворачивается и летит на базу как в 39 прошивке, а начинает пятится назад возвращаясь домой...

  16. #2813

    Регистрация
    11.01.2011
    Адрес
    Ярославль
    Возраст
    29
    Сообщений
    1,392
    Переписал код библиотеки ВМР085 под float - переменные, формулы используются другие, отличные от целочисленных как в даташите. В исходном варианте Press = 101300 кПа, и последний разряд мог прыгать, т.е. 1 кПа. Сейчас давление Press = 101300.568785 хватает с запасом.

    Если без фильтров и с целочисленными переменными, то дисперсия = 1118, с целочисленными переменными и фильтрами D=533. С плавающей запятой и фильтрами D=127.

    Высота прыгает +- 10, реже +- 20. Но надо допиливать код.

  17. #2814

    Регистрация
    02.06.2011
    Адрес
    Москва
    Возраст
    31
    Сообщений
    353
    Цитата Сообщение от Musgravehill Посмотреть сообщение
    Переписал код библиотеки ВМР085 под float
    в плане производительности это как скажется?

  18. #2815

    Регистрация
    11.01.2011
    Адрес
    Ярославль
    Возраст
    29
    Сообщений
    1,392
    Цитата Сообщение от Ar2r Посмотреть сообщение
    в плане производительности это как скажется?
    сейчас попробую вывести цикл_тайм и проверить.

  19. #2816

    Регистрация
    02.06.2011
    Адрес
    Москва
    Возраст
    31
    Сообщений
    353
    Цитата Сообщение от LeonVS Посмотреть сообщение
    тут дело похоже в АРС220, при УСБ соединении такого нет, а при радио линке выскакивает часто
    в консоли странные фразы проскакивают что crc не корректный. как будто помехи идут. может быть из-за Wi-Fi такие проблемы со связью APC220?

  20. #2817

    Регистрация
    11.01.2011
    Адрес
    Ярославль
    Возраст
    29
    Сообщений
    1,392
    Как вывести время цикла? Serial.print(fast_loopTimer, DEC); Serial.print("mc"); показывает 0mc.

    Высота прыгает +-10 см, периодически бывают всплески +-20см, потом снова устаканивается. Еще может стабильно уплыть на 40-50 см, коптер подергаешь - все нормализуется. Такое ощущение, что у мембраны гистерезис.
    Показания датчика постоянно корректируются по его температуре (см. void APM_BMP085_Class::Calculate())
    APM_BMP085.cpp
    Код:
    /*
    	APM_BMP085.cpp - Arduino Library for BMP085 absolute pressure sensor
    */
    	
    	
    extern "C" {
      // AVR LibC Includes
      #include <inttypes.h>
      #include <avr/interrupt.h>
      #include "WConstants.h"
    }
    
    #include <Wire.h>
    #include "APM_BMP085.h"
    
    #define BMP085_ADDRESS 0x77  //(0xEE >> 1)
    #define BMP085_EOC 30        // End of conversion pin PC7
    
    // Constructors ////////////////////////////////////////////////////////////////
    //APM_BMP085_Class::APM_BMP085_Class()
    //{
    //}
    
    // Public Methods //////////////////////////////////////////////////////////////
    void APM_BMP085_Class::Init(int initialiseWireLib)
    {
    	byte buff[22];
    	int i = 0;
    
    	//pinMode(BMP085_EOC, INPUT);	 // End Of Conversion (PC7) input
    
    	//if( initialiseWireLib != 0 )
    			Wire.begin();
    
    	oss = 3;					 // Over Sampling setting 3 = High resolution
    	BMP085_State = 0;		 // Initial state
    
      // We read the calibration data registers
    	Wire.beginTransmission(BMP085_ADDRESS);
    	Wire.send(0xAA);
    	Wire.endTransmission();
    
    	Wire.requestFrom(BMP085_ADDRESS, 22);
    
      //Wire.endTransmission();
    	while(Wire.available()){
    		buff[i] = Wire.receive();	// receive one byte
    		i++;
    	}
    
    	ac1 = ((int)buff[0] << 8) | buff[1];
    	ac2 = ((int)buff[2] << 8) | buff[3];
    	ac3 = ((int)buff[4] << 8) | buff[5];
    	ac4 = ((int)buff[6] << 8) | buff[7];
    	ac5 = ((int)buff[8] << 8) | buff[9];
    	ac6 = ((int)buff[10] << 8) | buff[11];
    	b1 = ((int)buff[12] << 8) | buff[13];
    	b2 = ((int)buff[14] << 8) | buff[15];
    	mb = ((int)buff[16] << 8) | buff[17];
    	mc = ((int)buff[18] << 8) | buff[19];
    	md = ((int)buff[20] << 8) | buff[21];
    	
    	sp_c3 = (float)((160.000000000000*ac3)/32768.000000000000);
    	sp_c4 = (float)((ac4/1000.000000000000)/32768.000000000000);
    	sp_b1 = (float)((160.000000000000*160.000000000000*b1)/1073741824.000000000000);
    	
    	sp_c5 = (float)((ac5/32768.000000000000)/160.000000000000);
    	sp_c6 = ac6;
    	sp_mc = (float)((mc*2048.000000000000)/(160.000000000000*160.000000000000));
    	sp_md = (float)(md/160.000000000000);
    	
    	sp_x0 = ac1;
    	sp_x1 = (float)((160.000000000000*ac2)/8192.000000000000);
    	sp_x2 = (float)((160.000000000000*160.000000000000*b2)/33554432.000000000000);
    	
    	sp_y0 = (float)((float)sp_c4*32768.000000000000);
    	sp_y1 = (float)((float)sp_c4*sp_c3);
    	sp_y2 = (float)((float)sp_c4*sp_b1);
    	
    	
    	sp_p0 = (float)((3791.000000000000-8.000000000000)/1600.000000000000);
    	sp_p1 = (float)(1.000000000000 - (7357.000000000000/1048576.000000000000));	
    	sp_p2 = (float)((3038.000000000000*100.000000000000)/68719476736.000000000000);
    	
    	//Send a command to read Temp
    	Command_ReadTemp();
    	BMP085_State = 1;
    	
    }
    
    
    // Read the sensor. This is a state machine
    // We read one time Temperature (state=1) and then 4 times Pressure (states 2-5)
    uint8_t APM_BMP085_Class::Read()
    {
    	uint8_t result = 0;
    
    	if (BMP085_State == 1){
    		//if (digitalRead(BMP085_EOC)){
    			ReadTemp();						 // On state 1 we read temp
    			BMP085_State++;
    			Command_ReadPress();
    		//}
    	}else{
    		if (BMP085_State == 5){
    			//if (digitalRead(BMP085_EOC)){
    				ReadPress();
    				Calculate();
    
    				BMP085_State = 1;			// Start again from state = 1
    				Command_ReadTemp();			// Read Temp
    				result = 1;					// New pressure reading
    			//}
    		}else{
    			//if (digitalRead(BMP085_EOC)){
    				ReadPress();
    				Calculate();
    				BMP085_State++;
    				Command_ReadPress();
    				result = 1;					// New pressure reading
    			//}
    		}
    	}
    	return(result);
    }
    
    
    
    // Send command to Read Pressure
    void APM_BMP085_Class::Command_ReadPress()
    {
    	Wire.beginTransmission(BMP085_ADDRESS);
    	Wire.send(0xF4);
    	Wire.send(0x34+(oss << 6));	// write_register(0xF4, 0x34+(oversampling_setting << 6));	
    	Wire.endTransmission();
    }
    
    // Read Raw Pressure values
    void APM_BMP085_Class::ReadPress()
    {
    	byte msb;
    	byte lsb;
    	byte xlsb;
    
    	Wire.beginTransmission(BMP085_ADDRESS);
    	Wire.send(0xF6);
    	Wire.endTransmission();
    
    	Wire.requestFrom(BMP085_ADDRESS, 3); // read a byte
    
    	while(!Wire.available()) { // waiting
    	}
    	msb = Wire.receive();
    	while(!Wire.available()) { // waiting
    	}
    	lsb = Wire.receive();
    	while(!Wire.available()) {  // waiting
    	}
    	xlsb = Wire.receive();	
    	
    	RawPress = 256*(long)msb + (long)lsb + (long)xlsb/256.00000000;
    	
    	if(_offset_press == 0){
    		_offset_press = RawPress;
    		RawPress = 0;
    	}else{
    		RawPress -= _offset_press;
    	}
    	// filter
    	_press_filter[_press_index++] = RawPress;
    
    	if(_press_index >= PRESS_FILTER_SIZE)
    		_press_index = 0;
    
    	RawPress = 0;
    	// sum our filter
    	for(uint8_t i = 0; i < PRESS_FILTER_SIZE; i++){
    		RawPress += _press_filter[i];
    	}
    
    	// grab result
    	RawPress /= PRESS_FILTER_SIZE;
    	//RawPress >>= 3;
    	RawPress += _offset_press; 
    }
    
    // Calculate Temperature and Pressure in real units.  C and mbar!!!!!!!!!!  1mbar = 100 Pa
    void APM_BMP085_Class::Calculate()
    {
    	float alpha, T, s, z, x, y;
    	
    	alpha = (float)((float)sp_c5*(RawTemp-(float)sp_c6));
    	T    = (float)((float)alpha + (float)sp_mc/((float)alpha+(float)sp_md));
    	s     = (float)((float)T - 25);
    	x = (float)((float)sp_x2*(float)s*(float)s + (float)sp_x1*(float)s + (float)sp_x0);
    	y = (float)((float)sp_y2*(float)s*(float)s + (float)sp_y1*(float)s + (float)sp_y0);
    	
    	z = (float)(((uint32_t)RawPress - (float)x) / (float)y);
    	Press = (float)((float)sp_p2*(float)z*(float)z + (float)sp_p1*(float)z + (float)sp_p0)*100.0000;
    	
    	Temp  = (float)T*10; //так требует софт
    }
    
    void APM_BMP085_Class::Command_ReadTemp()
    {
    	Wire.beginTransmission(BMP085_ADDRESS);
    	Wire.send(0xF4);
    	Wire.send(0x2E);
    	Wire.endTransmission();
    }
    
    // Read Raw Temperature values
    void APM_BMP085_Class::ReadTemp()
    {
    	byte tmp;
    	Wire.beginTransmission(BMP085_ADDRESS);
    	Wire.send(0xF6);
    	Wire.endTransmission();
    
    	Wire.beginTransmission(BMP085_ADDRESS);
    	Wire.requestFrom(BMP085_ADDRESS,2);
    
    	while(!Wire.available());	// wait
    	RawTemp = Wire.receive();
    
    	while(!Wire.available());	// wait
    	tmp 	= Wire.receive();
    
    	RawTemp = RawTemp*256.000 + tmp;
            
    	
    	if(_offset_temp == 0){
    		_offset_temp = RawTemp;
    		RawTemp = 0;
    	}else{
    		RawTemp -= _offset_temp;
    	}
    
    	// filter
    	_temp_filter[_temp_index++] = RawTemp;
    
    	if(_temp_index >= TEMP_FILTER_SIZE)
    		_temp_index = 0;
    
    	RawTemp = 0;
    	// sum our filter
    	for(uint8_t i = 0; i < TEMP_FILTER_SIZE; i++){
    		RawTemp += _temp_filter[i];
    	}
    
    	// grab result
    	RawTemp /= TEMP_FILTER_SIZE;
    	//RawTemp >>= 4;
    	RawTemp += _offset_temp;
    }
    
    // Constructors ////////////////////////////////////////////////////////////////
    APM_BMP085_HIL_Class::APM_BMP085_HIL_Class()
    {
    }
    
    // Public Methods //////////////////////////////////////////////////////////////
    void APM_BMP085_HIL_Class::Init(int initialiseWireLib)
    {
      BMP085_State=1;
    }
    
    
    // Read the sensor. This is a state machine
    // We read one time Temperature (state = 1) and then 4 times Pressure (states 2-5)
    uint8_t APM_BMP085_HIL_Class::Read()
    {
    	uint8_t result = 0;
    
    	if (BMP085_State == 1){
    		BMP085_State++;
    	}else{
    
    		if (BMP085_State == 5){
    			BMP085_State = 1;				// Start again from state = 1
    			result = 1;						// New pressure reading
    		}else{
    			BMP085_State++;
    			result = 1;						// New pressure reading
    		}
    	}
    	return(result);
    }
    
    void APM_BMP085_HIL_Class::setHIL(float _Temp, float _Press)
    {
        // TODO: map floats to raw
    	Temp 	= _Temp;
    	Press 	= _Press;
    }
    APM_BMP085.h
    Код:
    #ifndef APM_BMP085_h
    #define APM_BMP085_h
    
    #define TEMP_FILTER_SIZE 8
    #define PRESS_FILTER_SIZE 8
    
    class APM_BMP085_Class
    {
      public:
    	APM_BMP085_Class():
    			_temp_index(0),
    			_press_index(0){};  // Constructor
    	float RawPress;
    	float RawTemp;
    	float Temp;
    	float Press;
    	//int Altitude;
    	uint8_t oss;
    	//int32_t Press0;  // Pressure at sea level
    
    	void Init(int initialiseWireLib = 1);
    	uint8_t Read();
    	
    	float sp_c3, sp_c4, sp_b1, sp_c5, sp_c6, sp_mc, sp_md;
    	float sp_x0, sp_x1, sp_x2, sp_y0, sp_y1, sp_y2, sp_p0, sp_p1, sp_p2;
    	
    	int16_t ac1, ac2, ac3, b1, b2, mb, mc, md;
            uint16_t ac4, ac5, ac6;
    
      private:
            // State machine
            uint8_t BMP085_State;
    	// Internal calibration registers
    	//int16_t ac1, ac2, ac3, b1, b2, mb, mc, md;
            //uint16_t ac4, ac5, ac6;
    	
    	//float sp_c3, sp_c4, sp_b1, sp_c5, sp_c6, sp_mc, sp_md;
    	//float sp_x0, sp_x1, sp_x2, sp_y0, sp_y1, sp_y2, sp_p0, sp_p1, sp_p2; 
    
    	float	 	_temp_filter[TEMP_FILTER_SIZE];
    	float	 	_press_filter[PRESS_FILTER_SIZE];
    	float	_offset_press;
    	float	_offset_temp;
    
    	uint8_t	_temp_index;
    	uint8_t	_press_index;
    
    	void Command_ReadPress();
    	void Command_ReadTemp();
    	void ReadPress();
    	void ReadTemp();
    	void Calculate();
    };
    
    class APM_BMP085_HIL_Class
    {
      private:
        uint8_t BMP085_State;
      public:
    	float RawPress;
    	float RawTemp;
    	float Temp;
    	float Press;
    	//int Altitude;
    	uint8_t oss;
    	APM_BMP085_HIL_Class();  // Constructor
    	void Init(int initialiseWireLib = 1);
    	uint8_t Read();
        void setHIL(float Temp, float Press);
    };
    
    #endif
    sensors.pde
    Код:
    static void init_barometer(void)
    {
    	#if HIL_MODE == HIL_MODE_SENSORS
    		hil.update();					// look for inbound hil packets for initialization
    	#endif
            ground_pressure    = 0;
    	ground_temperature = 0;
    	abs_pressure       = 0;
    	int i;
    
    	// We take some readings...
    	for(i = 0; i < 60; i++){
    		delay(50);
    
    		// get new data from absolute pressure sensor
    		barometer.Read();
    
    		//Serial.printf("init %ld, %d, -, %ld, %ld\n", barometer.RawTemp, barometer.Temp, barometer.RawPress,  barometer.Press);
    	}
    
    	for(i = 0; i < 20; i++){
    		delay(50);
    
    		#if HIL_MODE == HIL_MODE_SENSORS
    			hil.update(); 				// look for inbound hil packets
    		#endif
    
    		// Get initial data from absolute pressure sensor
    		barometer.Read();
    		ground_pressure += barometer.Press;
    		
    		//Serial.printf("init %ld, %d, -, %ld, %ld, -, %d, %ld\n", barometer.RawTemp, barometer.Temp, barometer.RawPress,  barometer.Press, ground_temperature, ground_pressure);
    	}
    	ground_temperature      = barometer.Temp;
            ground_pressure        /= 20.000;
    	abs_pressure  		= ground_pressure;
    
    	//Serial.printf("init %ld\n", abs_pressure);
    	//SendDebugln("barometer calibration complete.");
    }
    
    static long read_barometer(void)
    {
     	float x, tmp_float;	
    	barometer.Read();	
    	abs_pressure = (float)abs_pressure * .6 + (float)barometer.Press *.4;	 // берем 0.5 от прошлого давления и 0.5 от нового, чтобы не прыгало сильно
    	
    	tmp_float = (float)abs_pressure /(float)ground_pressure;  //формула из авиации: давление на уровне моря заменил на ground_pressure
    	tmp_float = pow((float)tmp_float, 0.190295);	
    	x = 4433000.000 * (1.000 - (float)tmp_float); // мы узнали высоту относительно текущей земли! потому что использовали  abs_pressure \ ground_pressure	
            
    	return 	(x);
    }
    ArducopterMega.pde
    Код:
    // Barometer Sensor variables
    // --------------------------
    static float 	abs_pressure;
    static float	ground_pressure;
    static float	ground_temperature;
    Просьба: в коде нужны нули после запятой? Местами, если не ставить, то компилятор считает формулу как int. Аналично насчет (float) перед переменными - стоит ли явно указывать компилятору везде на это.
    В общем, помидорами не бросайте, укажите, где г..код.
    Последний раз редактировалось Musgravehill; 20.09.2011 в 01:13.

  21. #2818

    Регистрация
    02.06.2011
    Адрес
    Калуга
    Возраст
    31
    Сообщений
    191
    Цитата Сообщение от Musgravehill Посмотреть сообщение
    Просьба: в коде нужны нули после запятой? Местами, если не ставить, то компилятор считает формулу как int. Аналично насчет (float) перед переменными - стоит ли явно указывать компилятору везде на это.
    В общем, помидорами не бросайте, укажите, где г..код.
    Это полностью на совести компилятора. В c++ как-то так: http://www.cyberguru.ru/programming/...ay-page78.html
    Т.е. в каждой операции операнды приводятся к типу наибольшего.
    (float)tmp_float - это зачем? tmp_float и так float.
    x = 4433000.000 * (1.000 - (float)tmp_float) ==> x = 4433000 * (1 - tmp_float)
    Но на результат это влиять не должно.

  22. #2819

    Регистрация
    11.01.2011
    Адрес
    Ярославль
    Возраст
    29
    Сообщений
    1,392
    Цитата Сообщение от iBat Посмотреть сообщение
    tmp_float и так float
    Сегодня перепишу. И посчитаю все дроби заранее: "b2* 160*160*/33554432" => "b2* 0,000762939453125"
    Я стал (float) прописывать и .000, когда после компиляции местами шел бред и округление переменных.
    После работы буду пилить.

  23. #2820
    Давно не был
    Регистрация
    01.10.2010
    Адрес
    Ashkelon israel
    Возраст
    63
    Сообщений
    1,131
    Записей в дневнике
    8
    В описании Ардуино на arduino.ru указывают, что арифметические операции с плавающей точкой нежелательны. Что то с точностью. Рекомендуют проводить операции сравнения. Это может сказаться на работе такой прошивки?

  24. #2821

    Регистрация
    11.01.2011
    Адрес
    Ярославль
    Возраст
    29
    Сообщений
    1,392
    Цитата Сообщение от Alex_from_Israel Посмотреть сообщение
    Это может сказаться на работе такой прошивки?
    Совсем не знаю. 30 минут прошивка работает. Мне хочется выжать максимум из бародатчика или искать более точный - мечтаю о "зависании" коптера в режиме alt-hold. Операции с плавающей запятой жрут больше ресурсов, но я попробую, все равно. Надо еще искать, как вывести время цикла.

  25. #2822

    Регистрация
    28.12.2007
    Адрес
    Обнинск
    Возраст
    36
    Сообщений
    519
    Записей в дневнике
    24
    VMLAB вам в помощь выводите на любую ногу 1 выполняете код, выводите 0 смотрите сколько по времни получилось
    float - зло для контроллеров без сопроцессора, округляйте до Nного знака и считайте с фиксированной точкой будет существенно быстрее
    "x = 4433000 * (1 - tmp_float)" при такой записи компилятор откинет дробную часть от tmp_float и приведет все к int и long.
    float x;
    x=1. - tmp_float

  26. #2823

    Регистрация
    02.06.2011
    Адрес
    Калуга
    Возраст
    31
    Сообщений
    191
    Высокую точность можно и с целочисленными операндами получить, если ввести понятие масштаба. Если будет охота заморочиться - пиши, попробую вспомнить чему на дискретке учили

  27. #2824
    Давно не был
    Регистрация
    01.10.2010
    Адрес
    Ashkelon israel
    Возраст
    63
    Сообщений
    1,131
    Записей в дневнике
    8
    Цитата Сообщение от Musgravehill Посмотреть сообщение
    Совсем не знаю. 30 минут прошивка работает. Мне хочется выжать максимум из бародатчика или искать более точный - мечтаю о "зависании" коптера в режиме alt-hold. Операции с плавающей запятой жрут больше ресурсов, но я попробую, все равно. Надо еще искать, как вывести время цикла.
    У меня на борту 2 Ардуины. Сейчас поставил второй Мегу 2560. Дуемиланове использую в качестве программатора. Хочу перешить G-OSD. Очень надеюсь на Вашу прошивку. Если перенести баро и сонар на вторые мозги а в основную передавать готовые данные по высоте, как думаете, поможет? Есть второй рабочий барометр, может если усреднять показания с двух, точность может повысится? У меня мечта аналогичная. Только хочется холд на сверхмалых высотах и еще 3 сонара для бокового обзора. Есть в Большом кратере возле Димоны стенка, высотой метров 100. Примерно посередине пещеры. Хочется посмотреть, что там внутри, хотябы возле входа. Если доведу до ума прототип, то окончательная версия будет для дистанционного обследования. Видел как то ролик из штатов, там на акул охотились с помощью коптера. Тоже хочу! Хоть и нет тут серьезных акул, зато возле берега под водой развалины античных городов. Аквалангисты лазят, но они такую площадь не проверят, как коптер может. Если прозрачность воды позволит, конечно. Не Красное море, мутноватая вода. Метров на 5 видимость. Редко 10.

  28. #2825

    Регистрация
    17.06.2011
    Адрес
    Минск
    Возраст
    39
    Сообщений
    1,941
    Цитата Сообщение от Alex_from_Israel Посмотреть сообщение
    Только хочется холд на сверхмалых высотах и еще 3 сонара для бокового обзора.
    В принципе, холд уже работает. Если коптер не наклонять сильно, то все пучком. Я выкладывал видео, как моя страшилка висит в сантиметрах 10-20 от земли. Причем был сильный ветер.

  29. #2826
    Давно не был
    Регистрация
    01.10.2010
    Адрес
    Ashkelon israel
    Возраст
    63
    Сообщений
    1,131
    Записей в дневнике
    8
    Еще идея прорезалась, снимать показания с сонара только при нулевом левеле, +- сколько нибудь, чтобы совсем уж не перестал работать. Когда луч вертикально примерно. При кренах все равно врет, а при болтанке через ноль проходит. К сожалению программер из меня, как из бутылки молоток, но надеюсь надергать код из интернета, из готовых проектов.

  30. #2827

    Регистрация
    11.01.2011
    Адрес
    Ярославль
    Возраст
    29
    Сообщений
    1,392
    Цитата Сообщение от Alex_from_Israel Посмотреть сообщение
    Есть второй рабочий барометр, может если усреднять показания с двух, точность может повысится? У меня мечта аналогичная.
    Думаю, 2 шумящих барометра не помогут. Если повезет при инициализации, то один даст дрейф -50см, другой +50см, в итоге суммарный дрейф = 0. Иначе не повезло.
    Я присматриваюсь к "MS5611-01 MS5611 Barometric Pressure Sensor Variometer", пока их нет в наличии на ибей. Заявленная точность 10см, 1Па.

    Цитата Сообщение от sht0p0r Посмотреть сообщение
    "x = 4433000 * (1 - tmp_float)" при такой записи компилятор откинет дробную часть от tmp_float и приведет все к int и long.
    float x;
    x=1. - tmp_float
    Именно так и было. Весь вечер страдал, разозлился и всем прописал (флоат .0000).
    Цитата Сообщение от iBat Посмотреть сообщение
    Высокую точность можно и с целочисленными операндами получить, если ввести понятие масштаба
    Можно умножать коэффициенты типа (0.000019876) на 100 000 000 и хранить как int32_t. Только немного повозиться с библиотекой.

    В sensors.pde отдавать не реальное давление 10130(0) Па, а 101300 0(0) попугаев. И пусть последний разряд прыгает, это будет не 1Па, а сотые доли Паскаля. Все-равно, потом используется соотношение: Pтекущее \ Рground.

    И еще часть кода я перенесу из calculation() в init() - рассчет x, y, которые статичны.

  31. #2828
    Давно не был
    Регистрация
    01.10.2010
    Адрес
    Ashkelon israel
    Возраст
    63
    Сообщений
    1,131
    Записей в дневнике
    8
    Цитата Сообщение от Sir Alex Посмотреть сообщение
    В принципе, холд уже работает. Если коптер не наклонять сильно, то все пучком. Я выкладывал видео, как моя страшилка висит в сантиметрах 10-20 от земли. Причем был сильный ветер.
    Сылку не кинете? Долго искать по всей ветке. Сейчас вот снял коптера с ног. Приделываю свеже полученные приблуды. ЖПС на хвостовую балку недалеко от платы. Там проходят провода к моторам, но они у меня везде проходят, попробую поиграться, найдет этого ЖПСа или нет. В комплекте с G-OSD пришел. Осд перешивать нужно, то, что есть ни к селу ни к городу.

  32. #2829

    Регистрация
    17.06.2011
    Адрес
    Минск
    Возраст
    39
    Сообщений
    1,941
    Цитата Сообщение от Alex_from_Israel Посмотреть сообщение
    Еще идея прорезалась, снимать показания с сонара только при нулевом левеле, +- сколько нибудь, чтобы совсем уж не перестал работать.
    Так нельзя делать! во всяком случае, пока у вас включен автопилот (ALT_Hold). Т.к. если в какой то момент не снимать показания с сонара, то откуда брать высоту? На барометр нельзя резко переходить, т.к. может оказаться, что коптер висит в 15 см от земли, а баро скажет что 50см... и автопилот благополучно воткнет его в землю.
    Если что то и делать, так это ограничивать угол наклона коптера при работе с сонаром. Т.е. на малой высоте не давать наклонять коптер больше 15гр. (Но при этом, возможна ситуация, когда вы не сможете удерживать коптер на одном месте (при сильном ветре))

  33. #2830
    Давно не был
    Регистрация
    01.10.2010
    Адрес
    Ashkelon israel
    Возраст
    63
    Сообщений
    1,131
    Записей в дневнике
    8
    Брать предыдущее показание. Все равно высота не меняется резко. Обновлять при переходе через ноль

  34. #2831

    Регистрация
    11.01.2011
    Адрес
    Ярославль
    Возраст
    29
    Сообщений
    1,392
    Цитата Сообщение от Alex_from_Israel Посмотреть сообщение
    снимать показания с сонара только при нулевом левеле, +- сколько нибудь, чтобы совсем уж не перестал работать.
    Смотрите место в ArdupirateMega.pde, где вычисляется высота. Там кусок кода закомментирован, который корректирует высоту по cos\sin наклонов. Переменные наклонов можете использовать для своих целей, их можно вывести в Serial и понаблюдать, какие у них значения. if (sonar_alt < 600) and ( (round(x)>30 degree) OR (round(y) > 30 degree) ) {alt = 0.5*baro_alt + 0.5*sonar_alt; //при сильном наклоне подмешиваем баро_высоту, потому что сонар отваливается }- на словах. Только баро дрейфует на 50 см!

    Сейчас в коде на сверхмалой высоте коэффициент_баро -> 0, если пропадает и sonar_alt, то морковка.

  35. #2832
    Давно не был
    Регистрация
    01.10.2010
    Адрес
    Ashkelon israel
    Возраст
    63
    Сообщений
    1,131
    Записей в дневнике
    8
    Не совсем то. Не учитываются показания сонара вообще при крене. Нужно учитывать постоянно, но обновлять переменную с сонара только вблизи левел = 0

    Явно ложные показания будут игнорироваться.

  36. #2833

    Регистрация
    17.06.2011
    Адрес
    Минск
    Возраст
    39
    Сообщений
    1,941
    Цитата Сообщение от Alex_from_Israel Посмотреть сообщение
    Не совсем то. Не учитываются показания сонара вообще при крене. Нужно учитывать постоянно, но обновлять переменную с сонара только вблизи левел = 0 Ответить с цитированием Ответить с цитированием Поблагодарить автора Спасибо! Кинуть помидором
    А надо ли вообще учитывать крен? Там высота будет незначительно изменятся (мне кажется). А вот не учитывать текущую высоту нельзя - т.к. если вы например летите куда то, естественно коптер будет наклонен - а высота то старая будет все время - в итоге краш.

  37. #2834

    Регистрация
    11.01.2011
    Адрес
    Ярославль
    Возраст
    29
    Сообщений
    1,392
    Цитата Сообщение от Alex_from_Israel Посмотреть сообщение
    при крене
    Только проблема, что при крене коптер теряет высоту, поэтому будет точно не 1 метр. А на сильном крене он сваливается.

    Предлагаю при сильном крене и отваливающемся сонаре "подмешивать" baro_alt. Как только уровень выровняется, влияние баро_альт сильно ослабить, и использовать сонар_альт на 98%
    Код:
    level>=30:  alt = 0.8* alt_предыдущая + 0.2*baro_alt
    level<30:    alt = 0.98* sonar_alt + 0.02*baro_alt

  38. #2835

    Регистрация
    28.12.2007
    Адрес
    Обнинск
    Возраст
    36
    Сообщений
    519
    Записей в дневнике
    24
    Борис, именно так забудьте метры, граммы, паскали, считайте в "штуках".
    Все, что можно в константы, все, что считаеттся 1 раз в статические переменные.

    Цитата Сообщение от Musgravehill Посмотреть сообщение
    Код:
    level>=30:  alt = 0.8* alt_предыдущая + 0.2*baro_alt
    0.2* baro_alt будет считаться до скончания веков, запись (baro_alt>>2) эквивалентна 0.25 *baro_alt, а работает 2 такта.
    я бы сделал так:
    Код:
    alt = (alt_предыдущая>>1)+(alt_предыдущая>>2)+(baro_alt>>2);  //alt = 0.75* alt_предыдущая + 0.25*baro_alt
    Последний раз редактировалось sht0p0r; 20.09.2011 в 13:28.

  39. #2836
    Давно не был
    Регистрация
    01.10.2010
    Адрес
    Ashkelon israel
    Возраст
    63
    Сообщений
    1,131
    Записей в дневнике
    8
    Цитата Сообщение от Musgravehill Посмотреть сообщение
    Только проблема, что при крене коптер теряет высоту, поэтому будет точно не 1 метр. А на сильном крене он сваливается.

    Предлагаю при сильном крене и отваливающемся сонаре "подмешивать" baro_alt. Как только уровень выровняется, влияние баро_альт сильно ослабить, и использовать сонар_альт на 98%
    Код:
    level>=30:  alt = 0.8* alt_предыдущая + 0.2*baro_alt
    level<30:    alt = 0.98* sonar_alt + 0.02*baro_alt
    Кто же будет заниматься высшим пилотажем у земли то? Речь ведь идет о висении на сверхнизких высотах. При болтанке скольжение минимальное, стики по нулям. А про высоты, где сонар не работает вообще другой разговор. В идеале вообще нужно автоматическую посадку вводить. Что бы сам садился в точке взлета, а не болтался над точкой. Подразумевается, что сигнал управления потерян и кренов со скольжением вообще быть не должно.

  40. #2837

    Регистрация
    02.06.2011
    Адрес
    Калуга
    Возраст
    31
    Сообщений
    191
    Цитата Сообщение от Musgravehill Посмотреть сообщение
    Можно умножать коэффициенты типа (0.000019876) на 100 000 000 и хранить как int32_t. Только немного повозиться с библиотекой.
    Собственно 100 000 000 и будет масштабом в данном случае. Можно так и работать. Если хочется выжать из int32 все, до последнего бита, то масштаб придется в виде степени двойки вычислять, исходя из максимального (разумного) значения величины.

  41. #2838

    Регистрация
    02.06.2011
    Адрес
    Москва
    Возраст
    31
    Сообщений
    353
    Alex_from_Israel, давно пора эхолот привязывать к коптеру. :-) И слежение за рыбой реализовать.

    кстати, как мегапират будет вести себя если сигнал от пульта ДУ заглушить? Просто рухнет на землю?

  42. #2839

    Регистрация
    17.06.2011
    Адрес
    Минск
    Возраст
    39
    Сообщений
    1,941
    Отчед: Начал портировать 2.0.43

  43. #2840
    Давно не был
    Регистрация
    01.10.2010
    Адрес
    Ashkelon israel
    Возраст
    63
    Сообщений
    1,131
    Записей в дневнике
    8
    Цитата Сообщение от Ar2r Посмотреть сообщение
    Alex_from_Israel, давно пора эхолот привязывать к коптеру. :-) И слежение за рыбой реализовать.

    кстати, как мегапират будет вести себя если сигнал от пульта ДУ заглушить? Просто рухнет на землю?
    Вроде файлсейв есть... По идее должен плавно снизить обороты мотором и приземлиться более-менее плавно. Хотя, кто его знает? Я еще и не летал то, как следует. Усе упереди, Козлодоев!

    Не, за рыбой не хочу! Я рыбу уважаю с пивом, но не прямо из моря! Проще прикупить в магазине, благо выбор есть. От тараньки до деликатесной семги. А прям из моря тоже можно. На Марине (это у нас так яхт клубы называют) есть ресторанчик в котором рыбу жарят через полчаса после отлова. Рыбаки прямо с катера своего в ресторанчик этот отгружают. Будете в наших краях, обязательно посетите! Классно жарят! Лучше только в Эйлате, в ресторане рыбном. Название странное, что то вроде последний толи причал, толи приют. Не помню точно. Сети и штурвалы по стенам и чудная запеченная в сметане рыбка!

+ Ответить в теме

Похожие темы

  1. mega 88 TQFP - проблемы сигатуры
    от Texnik в разделе Самодельная электроника, компьютерные программы
    Ответов: 11
    Последнее сообщение: 12.01.2012, 01:55
  2. Создание квадрокоптера на Arduino
    от Spin7ion в разделе Коптеры. Комплектующие, сборка, настройка.
    Ответов: 75
    Последнее сообщение: 15.11.2011, 19:10
  3. Продам Mega Power Infinity 960SR Digital Charger + Mega Power LCB-12S DeluxePro Balancer + БП MW S-350-15 (15V, 350W)
    от morro_lucky в разделе Барахолка. Аккумуляторы, зарядники
    Ответов: 3
    Последнее сообщение: 06.05.2011, 14:20
  4. Конфигурация Arducopter
    от Stulikov в разделе Коптеры. Комплектующие, сборка, настройка.
    Ответов: 28
    Последнее сообщение: 02.05.2011, 17:04
  5. Продам зарядное устройство mega power gemini-2014 duo 600w twins charger
    от kolobok в разделе Барахолка. Аккумуляторы, зарядники
    Ответов: 2
    Последнее сообщение: 27.01.2011, 16:45

Метки этой темы

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения