Проект Мегапират на самик!
вариант прошивки.
Пожалуйста.
Сфотографировать сейчас не могу, прошита стандартная версия, железо всё разворочено:). Вот, примерно попытался изобразить:). Где-то так выглядит…😃
ага, попалась…
Чтобы скорость в еосд показывало нормально, нужно поменять в _eosd.pde
sport.write((byte)(g_gps->ground_speed*0.036));
на
sport.write((byte)(g_gps->ground_speed*0.01));
Ох…
Я немного отстал…
Ребята - Вам огромное СПАСИБО!!! За продвижение проекта и вычисление глюков!
Я не надолго выпал из проекта (работа, борьба с бюрократией - она оказывается совсем не закончилась, а только началась…,еще один проект - сменил прошу на передатчике - осваиваю и по новому настраиваю модели…) но думаю, что день-два и я вольюсь!
Спасибо!
ПС Олег - боюсь, что придется мне работать с Е-ОСД… Коробчонка вроде все-таки пропала на просторах Почты…
Есть мысли почему компас херню несет? К стати температура в полете на плате когда за бортом было -9 была +8 +11 градусов (по данным с барометра)
Не знаю, надо чтоб ещё у кого то такая же “радость” произошла. Может непропай или микротрещина какая-то? Вот оно на морозе и проявляется.
К стати, посмотрел я на код АрдуПилота для самолётов 28й и 26й версии. Так вот, в 28й очень много изменений по сравнению с 26й. И фиг с ним, с мавлинком. Но там изменения фундаментальней.
- Уход с библиотеки Wire на I2C. Это задевает всё, в том числе и работу с датчиком компаса
- Сам драйвер компаса 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
}
}
- Пофикшен тупой баг в FastSerial.cpp, было _txBuffer->tail = _rxBuffer->head; , а надо было _txBuffer->tail = _txBuffer->head;
- Вместо IMU_Oilpan появился IMU_INS с целой кучей своего барахла.
- Появился failsafe самого МегаПилота. Если он обнаруживает, что, что-то не то с МегаПилотом, то он начинает отсылать напрямую команды с приёмника на сервы, без своей обработки.
7)Появился geo fencing. На сколько я вкурил( поверхностно) – позволяет вам управлять границами полёта, соответственно МегаПилот не даст пепелацу вылететь за эти границы. Соответственно весь код МегаПилота проапдейчен, чтоб учитывать этот самый geo fencing. - Куча всякого другого. Где-то причесали код, где-то зафиксили баги и т.д.
АрдуПилота для самолётов 28й и 26й версии.
Осталось только портировать ее на нашу железяку 😃
sport.write((byte)(g_gps->ground_speed*0.01));
Залил, сегодня затестимс 😃
К стати кто выключает компас, на автовзлете обязательно отключать удержание курса, иначе очень вероятен краш, ГПС на земле не знает направление, и нос самуля в понимании АП смотрит как правило не по линии взлета, АП начинает по его мнению нос направить по линии взлета, в следствии чего большой крен а на маленькой скорости это смерть 😃
В полях сегодня было свежо 😃 -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
- Пофикшен тупой баг в FastSerial.cpp, было _txBuffer->tail = _rxBuffer->head; , а надо было _txBuffer->tail = _txBuffer->head;
А к чему этот баг приводил? Случаем не к ресетам при слабой телеметрии?
Вопрос к гуру аурдино 😃
Где хранятся процедуры в арду? На данный момент интересно тельце вот этой гадости 😃
calc_throttle();
Где хранятся процедуры в арду? На данный момент интересно тельце вот этой гадости
calc_throttle();
Это не Ардуиновская функция. Она находится в MegaPiratePlane\Attitude.pde Это один из самых важных файлов в MegaPiratePlane. Фактически он и выполняет расчёт yaw, pitch, рулит сервами и т.д.
А к чему этот баг приводил? Случаем не к ресетам при слабой телеметрии?
Эмм, этот ахтунг приводил к тому, что хвост( указатель конца) буффера на трансмит указывал не на начало буффера на тринсмит, а на начало буффера на ресив. Т.е. на данные предназначенные не для передачи, а для приёма. Приводить могло к много чему. К стати, вроде как общение с ОСД в EOSD идёт через тот же FastSerial. Времени пока смотреть нету.
Хм… как же оно тогда сейчас у меня работает??? В каком модуле сие строчка находится?
У нас FastSerial от 26й версии, \MegaPiratePlane2.26\libraries\FastSerial\FastSerial.cpp 197я строка. Там этот же баг есть.
А отразиться на функциональности он может только, если дергается соответствующий метода в котором эта строка, flush()
Костя, дай мастер класс 😃 Хочу подрыгать сервой на свободном канале, как в арду задается задержка чтоб не мешать основному коду? Допустим:
Дергаем сервой в одну сторону;
надо сделать задержку в 2 секунды;
дергаем сервой в другую сторону;
?
Можно конечно по деревянному задать переменную плюсовать к ней единицу при каждом цикле, и потом по определенному значению сбрасывать выполняя нужное действо, но может в аурдино это делается как то более цивилизованно 😃?
Вопрос к Олегу.
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);
}
На кой они тут один и тот же код дважды повторяют? Чё-то я глубинный смысл этого не понимаю.
Леонид. Можно поподробнее, что надо сделать? Т.е., при срабатывании какого-то переключателя на пульте, серва должна повернуться в одну сторону, постоять покурить н-е время, а потом повернуться в другую сторону? Или же этот процесс должен быть постоянным, т.е., на одном из каналов постоянно серва должна работать в крайнее положение–> подождать–> повернуться в другую сторону. И так по циклу, пока пепелац не грохнется?. 😉
пока пепелац не грохнется?
Ага, типа того 😃 Реализовываю срабатывание фотика 😃 В общем то через накопление счетчика можно реализовать, но хочется красиво чтоб было 😃 В общем как в арду сделать задержку без прерывания основного кода программы?
На кой они тут один и тот же код дважды повторяют?
Копи-пасте случайно два раза нажали 😃))))))
Можно конечно по деревянному задать переменную плюсовать к ней единицу при каждом цикле, и потом по определенному значению сбрасывать выполняя нужное действо, но может в аурдино это делается как то более цивилизованно
Ну, это достаточно цивилизованно. Влепить в 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;
Проверить не могу, на работе ща.
На ардупилоте все же реализовали то что я хочу 😃
diydrones.com/…/full-autonomous-slope-soaring-with…
Влепить в MegaPiratePlane.pde в функцию one_second_loop() что-то вида
А можно для особо одаренных описать каждую строчку 😃? Читот я тут половины не понял…
На ардупилоте все же реализовали то что я хочу
А Вы планерист? А то я в Термопилоте по фичам кроме авто-поиска термиков ничего принципиально нового не нашёл.
Надо срочно портировать v2.28ThP5 прошивку 😃
Ага, есть немного 😃 Хотел сам попытаться переделать режим FBW_B в режим поиска термо, алгоритм то в общем элементарный 😃
А можно для особо одаренных описать каждую строчку ? Читот я тут половины не понял…
Смотрите, в 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 секунды.
one_second_loop()
Кость, не совсем въезжаю как понять где начало, а где конец данного цикла?
static void one_second_loop() - начало?
А где конец? до конца кода идет все этот подцикл?
Опять же странность… если это так, ниже идет обновление данных ГПС
static void update_GPS(void) - зачем тогда ставят 10Гц модули если обновление идет раз в секунду???
Леонид, если не против я на “ты” перейду. Возраст у нас почти одинаковый, а с “Вы”-канием много не объяснишь.
Смотри, вот вся функция этого лупа
static void one_second_loop()
{
// send a heartbeat
gcs_send_message(MSG_HEARTBEAT);
gcs_data_stream_send(1,3);
if(()!=g.sensor_cal_x) (g.sensor_cal_x);
if(imu.ay()!=g.sensor_cal_y) imu.ay(g.sensor_cal_y);
}
Всё остальное – совсем другие функции; к этому лупу отношения не имеют.
Модифицированная функция этого лупа будет выглядеть приблизительно так:
static void 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);
// send a heartbeat
gcs_send_message(MSG_HEARTBEAT);
gcs_data_stream_send(1,3);
if(()!=g.sensor_cal_x) (g.sensor_cal_x);
if(imu.ay()!=g.sensor_cal_y) imu.ay(g.sensor_cal_y);
}
если не против я на “ты” перейду
Буду только рад 😃
Смотри, вот вся функция этого лупа
Теперь все ясно 😃