Проект Мегапират на самик!

LeonVS
dundel1:

это на 2.26?

Да, с 24 я чтот как то так и не подружился, летит сама куда хочет, возможно траблы были так же в компасе, только вот он там не отключается, и в терминале пытался и из планера, пишет что выключен, но по факту данные АП берет с него… + иногда не адекватные дерганья, которые победить так же не удалось…
26 как то более адеквато себя ведет. Странно что она у кого то виснет, у меня не разу траблов не было, даже если телеметрию отключить вообще…

dundel1:

Если хотите, могу выложить этот вариант прошивки.

Эх, жду бвХУД обещанный Олегом, киньте, лишним не будет, и если можно фотку, что она там кажет 😃

ukkr

Привет всем. У нас холодно, шлангую дома. -15 и ветер-- кайфа куда-то ехать никакого. Тихонько разбираюсь с кодом “Пирата”. Одновременно, решил посмотреть на Mission Planner. Ну, кроме того, что это .NETовская поделка, всё остальное выглядит кошерно. Только вот 2 фигни не понравились. Первая – при старте последней версии 1.1.34 обнаружило наличие каких-то апдейтов. Я по глупости согласился. В результате оно накачало себе апдейтов с удалённого git сервера. И после этого уже не запускалось. Как ни пытался. Пришлось сносить и ставить заново с отказом от любых апдейтов. Дальше – всё шоколадно. Кроме 2х моментов. Снизу приаттачил скрин. ГПСом обнаружило чётко мой дом. Это при том, что я на расстоянии 3х метров от окна тестировал. Вот в чём сила внешней GPS-антены, хотя она и тяжёлая, сволочь. Так вот, на гугломепсах показало чётко, а вот слева пишет, что GPSа нет. Это чё такое? Ну и часы слева сверху со страшным значением. Откуда оно их взяло?

LeonVS
ukkr:

Откуда оно их взяло?

Часы как я понял идут с компа, то что ГПС пишет нет - глюк. В новом планере скорей всего все заточено под новый код арду, мы же юзаем то что они уже проехали 😃 Загрузи старый планер, будет все тип топ 😃
Есть мысли почему компас херню несет? К стати температура в полете на плате когда за бортом было -9 была +8 +11 градусов (по данным с барометра)

dundel1
dundel1:

вариант прошивки.

Пожалуйста.
Сфотографировать сейчас не могу, прошита стандартная версия, железо всё разворочено:). Вот, примерно попытался изобразить:). Где-то так выглядит…😃

MegaPirateOSD_AHI_only.zip

Syberian

ага, попалась…
Чтобы скорость в еосд показывало нормально, нужно поменять в _eosd.pde

sport.write((byte)(g_gps->ground_speed*0.036));
на
sport.write((byte)(g_gps->ground_speed*0.01));

alex-ber

Ох…
Я немного отстал…
Ребята - Вам огромное СПАСИБО!!! За продвижение проекта и вычисление глюков!
Я не надолго выпал из проекта (работа, борьба с бюрократией - она оказывается совсем не закончилась, а только началась…,еще один проект - сменил прошу на передатчике - осваиваю и по новому настраиваю модели…) но думаю, что день-два и я вольюсь!
Спасибо!
ПС Олег - боюсь, что придется мне работать с Е-ОСД… Коробчонка вроде все-таки пропала на просторах Почты…

ukkr
LeonVS:

Есть мысли почему компас херню несет? К стати температура в полете на плате когда за бортом было -9 была +8 +11 градусов (по данным с барометра)

Не знаю, надо чтоб ещё у кого то такая же “радость” произошла. Может непропай или микротрещина какая-то? Вот оно на морозе и проявляется.
К стати, посмотрел я на код АрдуПилота для самолётов 28й и 26й версии. Так вот, в 28й очень много изменений по сравнению с 26й. И фиг с ним, с мавлинком. Но там изменения фундаментальней.

  1. Уход с библиотеки Wire на I2C. Это задевает всё, в том числе и работу с датчиком компаса
  2. Сам драйвер компаса AP_Compass_HMC5843.cpp кроме того, что переписан на I2C теперь ещё и сохраняет состояние последней операции( успешно или сбой) в поле healthy и умеет автоматически переинициилизироваться после сбоя:
bool AP_Compass_HMC5843::read()
{
   if (!healthy) {
	  if (millis() < _retry_time) {
		 return false;
	  }
	  if (!re_initialise()) {
		 _retry_time = millis() + 1000;
		 return false;
	  }
   }

Кроме того, само поле healthy используется в куче разных мест автопилота для расчётов и принятия решения. К стати, то же самое и с бародатчиком.
3) Улучшен( “причёсан”) DCM. Вынесен резет матрицы в отдельный метод, куда добавлена и разрешение обнуления оф-та компасса:

AP_DCM::matrix_reset(void)
{
	if (_compass != NULL) {
		_compass->null_offsets_disable();
	}
	_dcm_matrix.a.x = 1.0f;
	_dcm_matrix.a.y = 0.0f;
	_dcm_matrix.a.z = 0.0f;
	_dcm_matrix.b.x = 0.0f;
	_dcm_matrix.b.y = 1.0f;
	_dcm_matrix.b.z = 0.0f;
	_dcm_matrix.c.x = 0.0f;
	_dcm_matrix.c.y = 0.0f;
	_dcm_matrix.c.z = 1.0f;
	_omega_I.x = 0.0f;
	_omega_I.y = 0.0f;
	_omega_I.z = 0.0f;
	if (_compass != NULL) {
		_compass->null_offsets_enable();	// This call is needed to restart the nulling
		// Otherwise the reset in the DCM matrix can mess up
		// the nulling
	}
}
  1. Пофикшен тупой баг в FastSerial.cpp, было _txBuffer->tail = _rxBuffer->head; , а надо было _txBuffer->tail = _txBuffer->head;
  2. Вместо IMU_Oilpan появился IMU_INS с целой кучей своего барахла.
  3. Появился failsafe самого МегаПилота. Если он обнаруживает, что, что-то не то с МегаПилотом, то он начинает отсылать напрямую команды с приёмника на сервы, без своей обработки.
    7)Появился geo fencing. На сколько я вкурил( поверхностно) – позволяет вам управлять границами полёта, соответственно МегаПилот не даст пепелацу вылететь за эти границы. Соответственно весь код МегаПилота проапдейчен, чтоб учитывать этот самый geo fencing.
  4. Куча всякого другого. Где-то причесали код, где-то зафиксили баги и т.д.
LeonVS
ukkr:

АрдуПилота для самолётов 28й и 26й версии.

Осталось только портировать ее на нашу железяку 😃

Syberian:

sport.write((byte)(g_gps->ground_speed*0.01));

Залил, сегодня затестимс 😃
К стати кто выключает компас, на автовзлете обязательно отключать удержание курса, иначе очень вероятен краш, ГПС на земле не знает направление, и нос самуля в понимании АП смотрит как правило не по линии взлета, АП начинает по его мнению нос направить по линии взлета, в следствии чего большой крен а на маленькой скорости это смерть 😃

LeonVS

В полях сегодня было свежо 😃 -20 😃 После отключения удержания курса, автовзлет без компаса стал идеальным 😃 Отключил по деревянному, тупо закоментив лишнее 😃
case MAV_CMD_NAV_TAKEOFF:
//if (hold_course > -1) {
// calc_nav_roll();
//} else {
nav_roll = 0;
//}
Теперь просто тупо держит крен в нуле, что и требуется 😃
Исправления Олегом по скорости, так же дали положительный результат 😃 Скачки все равно есть (в некоторых случаях все же кто то перетирает данную переменную…) но в остальное время кажет уже не попугаи, а то что требуется 😃
При -20 за бортом, температура платки в полете опускалась до -3, когда же самуль просто лежит на земле поднималась до +8 +10.
dpiter.info/sky4.wmv

ukkr:
  1. Пофикшен тупой баг в FastSerial.cpp, было _txBuffer->tail = _rxBuffer->head; , а надо было _txBuffer->tail = _txBuffer->head;

А к чему этот баг приводил? Случаем не к ресетам при слабой телеметрии?

Вопрос к гуру аурдино 😃
Где хранятся процедуры в арду? На данный момент интересно тельце вот этой гадости 😃
calc_throttle();

ukkr
LeonVS:

Где хранятся процедуры в арду? На данный момент интересно тельце вот этой гадости
calc_throttle();

Это не Ардуиновская функция. Она находится в MegaPiratePlane\Attitude.pde Это один из самых важных файлов в MegaPiratePlane. Фактически он и выполняет расчёт yaw, pitch, рулит сервами и т.д.

LeonVS:

А к чему этот баг приводил? Случаем не к ресетам при слабой телеметрии?

Эмм, этот ахтунг приводил к тому, что хвост( указатель конца) буффера на трансмит указывал не на начало буффера на тринсмит, а на начало буффера на ресив. Т.е. на данные предназначенные не для передачи, а для приёма. Приводить могло к много чему. К стати, вроде как общение с ОСД в EOSD идёт через тот же FastSerial. Времени пока смотреть нету.

LeonVS

Хм… как же оно тогда сейчас у меня работает??? В каком модуле сие строчка находится?

ukkr

У нас FastSerial от 26й версии, \MegaPiratePlane2.26\libraries\FastSerial\FastSerial.cpp 197я строка. Там этот же баг есть.
А отразиться на функциональности он может только, если дергается соответствующий метода в котором эта строка, flush()

LeonVS

Костя, дай мастер класс 😃 Хочу подрыгать сервой на свободном канале, как в арду задается задержка чтоб не мешать основному коду? Допустим:
Дергаем сервой в одну сторону;
надо сделать задержку в 2 секунды;
дергаем сервой в другую сторону;
?

LeonVS

Можно конечно по деревянному задать переменную плюсовать к ней единицу при каждом цикле, и потом по определенному значению сбрасывать выполняя нужное действо, но может в аурдино это делается как то более цивилизованно 😃?

ukkr

Вопрос к Олегу.
radio.pde
процедура init_rc_out():

static void init_rc_out()
{
	APM_RC.OutputCh(CH_1, 	g.channel_roll.radio_trim);					// Initialization of servo outputs
	APM_RC.OutputCh(CH_2, 	g.channel_pitch.radio_trim);
	APM_RC.OutputCh(CH_3, 	g.channel_throttle.radio_min);
	APM_RC.OutputCh(CH_4, 	g.channel_rudder.radio_trim);

	APM_RC.OutputCh(CH_5, 	g.rc_5.radio_trim);
	APM_RC.OutputCh(CH_6, 	g.rc_6.radio_trim);
	APM_RC.OutputCh(CH_7,   g.rc_7.radio_trim);
	APM_RC.OutputCh(CH_8,   g.rc_8.radio_trim);

	APM_RC.Init();		// APM Radio initialization

	APM_RC.OutputCh(CH_1, 	g.channel_roll.radio_trim);					// Initialization of servo outputs
	APM_RC.OutputCh(CH_2, 	g.channel_pitch.radio_trim);
	APM_RC.OutputCh(CH_3, 	g.channel_throttle.radio_min);
	APM_RC.OutputCh(CH_4, 	g.channel_rudder.radio_trim);

	APM_RC.OutputCh(CH_5, 	g.rc_5.radio_trim);
	APM_RC.OutputCh(CH_6, 	g.rc_6.radio_trim);
	APM_RC.OutputCh(CH_7,   g.rc_7.radio_trim);
    APM_RC.OutputCh(CH_8,   g.rc_8.radio_trim);
}

На кой они тут один и тот же код дважды повторяют? Чё-то я глубинный смысл этого не понимаю.

Леонид. Можно поподробнее, что надо сделать? Т.е., при срабатывании какого-то переключателя на пульте, серва должна повернуться в одну сторону, постоять покурить н-е время, а потом повернуться в другую сторону? Или же этот процесс должен быть постоянным, т.е., на одном из каналов постоянно серва должна работать в крайнее положение–> подождать–> повернуться в другую сторону. И так по циклу, пока пепелац не грохнется?. 😉

LeonVS
ukkr:

пока пепелац не грохнется?

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

ukkr:

На кой они тут один и тот же код дважды повторяют?

Копи-пасте случайно два раза нажали 😃))))))

ukkr
LeonVS:

Можно конечно по деревянному задать переменную плюсовать к ней единицу при каждом цикле, и потом по определенному значению сбрасывать выполняя нужное действо, но может в аурдино это делается как то более цивилизованно

Ну, это достаточно цивилизованно. Влепить в MegaPiratePlane.pde в функцию one_second_loop() что-то вида

  if(xxx_wait>2){
          xxx_pos=xxx_pos*sign;//change servo direction
          xxx_wait=0;
  }else{
          xxx_wait++;
  }
  g.rc_8.closest_limit(xxx_pos);

Вместо g.rc_8 – нужный вам канал.
Ну и в самом MegaPiratePlane.pde вверху объявить переменные

int16_t xxx_pos=1800;//angle*10 deg
int xxx_wait=0;
int16_t sign=-1;

Проверить не могу, на работе ща.

LeonVS

На ардупилоте все же реализовали то что я хочу 😃
diydrones.com/…/full-autonomous-slope-soaring-with…

ukkr:

Влепить в MegaPiratePlane.pde в функцию one_second_loop() что-то вида

А можно для особо одаренных описать каждую строчку 😃? Читот я тут половины не понял…

ukkr
LeonVS:

На ардупилоте все же реализовали то что я хочу

А Вы планерист? А то я в Термопилоте по фичам кроме авто-поиска термиков ничего принципиально нового не нашёл.

LeonVS

Надо срочно портировать v2.28ThP5 прошивку 😃

Ага, есть немного 😃 Хотел сам попытаться переделать режим FBW_B в режим поиска термо, алгоритм то в общем элементарный 😃

ukkr
LeonVS:

А можно для особо одаренных описать каждую строчку ? Читот я тут половины не понял…

Смотрите, в MegaPiratePlane.pde есть основная функция

 void loop()

которая дёргает 3 основные подцикла.

fast_loop();

– для тайм-критикл вещей типа считывание команд с радио, расчёт DCM и т.д. Второй подцикл

medium_loop()

– для менее критических вещей. Ну и 3й подцикл

one_second_loop() 

– дёргается ориентировочно раз в секунду. Вот в этот цикл я и предлагаю вставить код для управления определённым каналом:

 if(xxx_wait>2){//если мы уже прождали больше 2х секунд
          xxx_pos=xxx_pos*sign;//изменить направление сервы на противоположное
          xxx_wait=0;//обнулить счётчик, сколько секунд мы стоим в текущем положении
  }else{
          xxx_wait++;//увеличить счётчик, сколько секунд мы стоим в текущем положении на 1 сек
  }
  g.rc_8.closest_limit(xxx_pos);//вызываете у нужного вам канала установку положения в градусах*10. Метод closest_limit принимает градусы*10, если правильно помню. Вместо g.rc_8 -- нужный вам канал

int16_t xxx_pos=1800;//angle*10 deg

– изначально серва на 180 градусов повёрнута. Ставьте на любой нужный вам угол. Через 2 секунды оно повернётся в положение -180. Я бы начал с небольщих углов (45*=450)для проверки, чтоб не попалить серву.

int xxx_wait=0;

//сколько секунд мы уже ждём в последнем положении

int16_t sign=-1;

//просто константа, на неё домножается текущее положение, чтоб повернуть серву в противоположную сторону каждые 2 секунды.