Проект Мегапират на самик!
Вы немного не то нашли.
Я же написал что не нашел что изменяет сие значения при холоде, но сей код устраняет данное явление, что для меня и являлось главной задачей 😃 Мне не надо чтоб при каких то событиях кроме настроек, сервы переходили в режим инверта, особенно в полете 😃
Ну а если найдете место где именно меняются “высокие материи”, буду вам очень признателен 😃
Ну а если найдете место где именно меняются “высокие материи”, буду вам очень признателен
Под рукой кроме Нотепада ничего нет. 8( Посмотрел на код из zipа …googlecode.com/…/MegaPiratePlane2.26.zip . Текстовым поиском найти вызов напрямую set_reverse во всём том количестве исходных файлов из-за какой-то температурной коррекции пока не удалось.
Если Вы уверены, что реверс появляется постепенно от холода, а не в связи с параметрами из конфигурации, будем рыть дальше.
Пошёл с другой стороны, надеюсь уважаемый Syberian быстрее поймёт оно это или не оно, бо нормальной иде у меня нет да и со структурой классов\алгоритмами ещё не разбирался.
Итак, в config.h есть определение такой вот константы
#ifndef HIL_MODE
#define HIL_MODE HIL_MODE_DISABLED
#endif
Шо за HIL – не знаю, мабудь это какой-то АрдуПилотовский термин.
Дальше, в MegaPiratePlane.pde есть вот такой фрагмент кода, который объявит переменную imu как экземпляр класса AP_IMU_Oilpan (бо HIL_MODE=HIL_MODE_DISABLED):
#if HIL_MODE != HIL_MODE_ATTITUDE
#if HIL_MODE != HIL_MODE_SENSORS
// Normal
AP_IMU_Oilpan imu(&adc, Parameters::k_param_IMU_calibration);
#else
// hil imu
AP_IMU_Shim imu;
#endif
// normal dcm
AP_DCM dcm(&imu, g_gps);
#endif
Вот у этого AP_IMU_Oilpan в методе update() дёргается
/**************************************************/
// Returns the temperature compensated raw gyro value
//---------------------------------------------------
float
AP_IMU_Oilpan::_sensor_in(uint8_t channel, int adc_value)
{
float adc_in;
// get the compensated sensor value
//
adc_in = adc_value;
// adjust for sensor sign and apply calibration offset
//
if (_sensor_signs[channel] < 0) {
adc_in = _sensor_cal[channel] - adc_in;
} else {
adc_in = adc_in - _sensor_cal[channel];
}
return adc_in;
}
Так вот, метод _sensor_in() и возвращает “термоскорректированные” показания гироскопа (Returns the temperature compensated raw gyro value).
Сам этот imu вроде как дёргается из DCM в методах DCM.update_DCM() и DCM.update_DCM_fast.
В конструкторе DCM инициируется на основе imu// Constructors
AP_DCM(IMU *imu, GPS *&gps, Compass *withCompass = NULL)
Ну а сами методы DCM.update_DCM() и DCM.update_DCM_fast() дёргаются из основного MegaPiratePlane.pde на каждой итерации.
Т.е. имеем цепочку вызовов MegaPiratePlane->DCM.update_DCM()->AP_IMU_Oilpan.update()->AP_IMU_Oilpan._sensor_in().
Либо же “fast” цепочку MegaPiratePlane->DCM.update_DCM_fast()->AP_IMU_Oilpan.update()->AP_IMU_Oilpan._sensor_in().
Не суть важно, ибо обе цепочки приводят к одному методу _sensor_in(), который собственно говоря и возвращает “термоскорректированные” показания гироскопа.
Если я правильно отследил цепочку, то тут уже вопрос к уважаемому Syberian, правильно ли _sensor_in() работает. Если правильно, тогда, наверно, надо смотреть на то, откуда берутся эти “компенсационные” данные для этого метода _sensor_in() , т.е. _sensor_signs[channel] и _sensor_cal[channel]. Сил без нормальной ИДЕ разбираться в этом у меня пока нет. Нотепад всё высосал 8).
и возвращает “термоскорректированные” показания гироскопа
Это оно и есть, и это как показывает практика работает как надо, фишка в том что в планере как я уже писал показывает все правильно, “горизонт” не куда не уплывает и тд тп, тобишь гироскоп и акселерометры работают по правильным алгоритмам, и если в них есть термокомпенсация, то она работает верно.
Описанный мной глюк влияет именно на “реверс” серв, который вылезал при охлаждении… Думаю тут больше “глюк” портирования, и какая то переменная лезет куда ей лезть не следует 😃 А вот вычислить сие место крайне проблематично, закоментив сам блок “перехода” глюк уходит, с моими познаниями аурдино вычислить, что откуда в хитрых переплетениях между основным кодом и библиотеками пирата…
Посмотрел на код
К стати если вы хороший знаток аурдино, хотелось бы пустить ваш порыв в нужном направлении 😉 Есть мысли откуда вылазит “кривая” скорость? Если посмотреть ветку выше, можно найти мной выложенные ролики полета, где скорость кажет в районе 250 😃 Но в то же время мелькает иногда и правильная… опять же где то идет перезапись нужной переменной… Есть мысли где сие может происходить?
К стати гуру, кто как отлаживает код в аурдино??? Есть какой то софт, чтоб пройтись по коду, посмотреть переменные и тд тп? А то как то в слепую все, что то закодил, а что там дальше крутится хз…
Нашел еще одно интересное место…
if (inverted_flight) nav_pitch = -nav_pitch;
Тобишь каким то образом можно врубить инверт и самуль якобы будет лететь верх тормашками, а рулиться как в обычном полете… Походу это дело и происходит, при холоде по какой то причине включается этот режим, и все рули естественно начинают работать в инверте?
Леонид, к сожалению, я не знаток Ардуино. Как и АрдуПилота\Вортекса. Для меня это всё тот же AVR с кучкой припаяных датчиков-- гироскопы, аксели и т.д. К стати, поздравьте, совратился я МегаПиратом и Вортексом, купил www.ebay.com/itm/260854008499 Что повеселило – прямо написано MEGA Pirate and MultiWii code compatible. 😃
Теперь о плохом. После знакомства с ИДЕ Ардуино – культурный шок, в худшем смысле этого слова. Единственный эпитет – убожество. Не, я понимаю, что избалован Эклипсом, Идеей, да даже Вижуал Студией, на худой конец. Но такое… Иногда мне кажется, что банальный Notepad++ или SciTe более функционален чем ИДЕ Ардуино. Средств отладки в ИДЕ Ардуино непредусмотренно. Единственный вариант --из кода программы выводить на каждой итерации в COM-порт всю дебажную информацию, а с компа любым сериал-терминалом смотреть, хоть тем же Serial Monitor из ИДЕ Ардуино.
Короче, начал я смотреть код Пирата в ИДЕ Ардуино – удобства не намного больше, чем с обычным Нотепадом. Будем тихонько смотреть.
Нашел я откуда лезут реверсы:
if (!g.switch_enable) {
// switches are disabled in EEPROM (see SWITCH_ENABLE option)
// this means the EEPROM control of all channel reversal is enabled
return;
}
// up is reverse
// up is elevon
g.mix_mode = (PINL & 128) ? 1 : 0; // 1 for elevon mode
if (g.mix_mode == 0) {
g.channel_roll.set_reverse((PINE & 128) ? true : false);
g.channel_pitch.set_reverse((PINE & 64) ? true : false);
g.channel_rudder.set_reverse((PINL & 64) ? true : false);
} else {
g.reverse_elevons = (PINE & 128) ? true : false;
g.reverse_ch1_elevon = (PINE & 64) ? true : false;
g.reverse_ch2_elevon = (PINL & 64) ? true : false;
}
Но почему это происходит по изменению температуры для меня так и остается загадкой…
Что касается inverted_flight – найти где он ставится проблемы нету, это происходит только в одном месте. По умолчанию inverted_flight=false.
И только в control_modes.pde в методе read_control_switch() он переставляется:
static void read_control_switch()
{
......
if (g.inverted_flight_ch != 0) {
// if the user has configured an inverted flight channel, then
// fly upside down when that channel goes above INVERTED_FLIGHT_PWM
inverted_flight = (control_mode != MANUAL && APM_RC.InputCh(g.inverted_flight_ch-1) > INVERTED_FLIGHT_PWM);
}
}
Т.е., если пользователь сконфигурировал с компа какой-то канал как “инвертированный”, то inverted_flight поменяет своё значение при условии, что пепелац сейчас управляется не вручную и значение этого управляющего канала превысло INVERTED_FLIGHT_PWM , т.е. 1750 (
define INVERTED_FLIGHT_PWM 1750
).
Не знаю, говорит ли Вам это о чём-то, но общий смысл достаточно прост-- если с вашего пульта пришла команда по какому-то сконфигурированному Вами каналу на вход Вортексу больше чем 1750 и в это время пепелац летел на автопилоте–МегаПират принимает решения, что у Вас inverted_flight .
static void read_control_switch()
{
…
if (g.inverted_flight_ch != 0) {
// if the user has configured an inverted flight channel, then
// fly upside down when that channel goes above INVERTED_FLIGHT_PWM
inverted_flight = (control_mode != MANUAL && APM_RC.InputCh(g.inverted_flight_ch-1) > INVERTED_FLIGHT_PWM);
}
}
Это все коментил, переход в инверт на морозе оставался.
Глюк пропадает только когда коментишь вот этот кусок:
g.channel_roll.set_reverse((PINE & 128) ? true : false);
g.channel_pitch.set_reverse((PINE & 64) ? true : false);
g.channel_rudder.set_reverse((PINL & 64) ? true : false);
Честно говоря не совсем понимаю что здесь происходит…?
но общий смысл достаточно прост-- если с вашего пульта пришла команда по какому-то сконфигурированному Вами каналу на вход Вортексу больше чем 1750 и в это время пепелац летел на автопилоте–МегаПират принимает решения, что у Вас inverted_flight
Вот только не пойму, ЗАЧЕМ??? Тут не происходит класического “полета в инверте” (АП переворачивает самуль и удерживает его в таком положении) - НЕТ! При данном переключении самуль закрутится юлой и по тангажу и крену и по любасу рухнет…
Режим самоуничтожения 😃?
К стати Олег, понял в чем идет скорость 😃
g_gps->ground_speed * rot.a.x, // X speed cm/s
Тобишь 250 = 25 м/с 😃 Теперь будет крайне легко преобразовать сие дело в удобночитаемую циферу 😃
Ндя, что то под вечер с математикой моей стало 😃))
Леонид, ща времени нет порыться посмотреть, что такое PINE и PINL. Если предположить, что это Port E и Port L Меги 2560, тогда надо порыться и посмотреть на схеме BlackVortex, что у него подключено к соответствующим ножкам этих портов:
(PINE & 128)
(PINE & 64)
(PINL & 64)
П.С. А где схема… Блин, на ЕБее даже ссылки нету, надо искать… 😵
П.П.С. 250 = 25 м/с – не вкурил. 😃
кто как отлаживает код в аурдино???
Да никак его не отладить. Только на плате через ком-порт что-то выводить.
По поводу inverted flight. Он включается через какой-то канал приемника. У тебя случайно он не разрешен?
прямо написано MEGA Pirate and MultiWii code compatible.
Велкам в нестройные ряды пиратов 😃 Покупать надо было на csgshop.com, там на 20 баксов дешевле.
Чтобы не ломать глаз в блокноте, используйте Notepad++, там есть подсветка синтаксиса.
Для поиска текста по всему проекту пользуюсь FAR manager 1.63 - типа нортона под виндой.
Глюк пропадает только когда коментишь вот этот кусок:
ага, попался! Я понял в чем засада. Дело в том, что в оригинальном ардупилоте за реверсы отвечают микропереключатели на плате. У нас их, естественно, нет, и эти ноги висят в воздухе. К тому же, на них нет подвески, т.е. все наводки и конденсат наши. В 2.24 они просто запрещены, а 2.26 была первая пробная версия, в которую я это не перенес (забыл).
За скорость отдельное спасибо 😃
П.П.С. 250 = 25 м/с – не вкурил.
Отписался уже, что туплю под вечер 😃 Один ноль потерял 😃 В общем, гипотеза по скорости провалилась…
Чисто предположу, что инверсия происходит когда происходит переполнение больше 16 бит.
К тому же, на них нет подвески, т.е. все наводки и конденсат наши.
Вот оно в чем дело, ну хоть все встало на свои места, что радует 😃 А по скорости очень похоже на правду что это метры в секунду / 10. Хотя смотрю у тебя уже стоит преобразование в км/ч на выход в еОСД… Чтот мое запуталось однако 😃
sport.write((byte)(g_gps->ground_speed * 0.036));
Чисто предположу, что инверсия происходит когда происходит переполнение больше 16 бит.
Тогда почему сие не происходит при комнатной температуре ни при каких условиях?
Велкам в нестройные ряды пиратов Покупать надо было на csgshop.com, там на 20 баксов дешевле.
Чтобы не ломать глаз в блокноте, используйте Notepad++, там есть подсветка синтаксиса.
Для поиска текста по всему проекту пользуюсь FAR manager 1.63 - типа нортона под виндой.
Пасиб 😃 Про csgshop.com – не знал, спасибо, на будущее запомню. Линку брал то ли с чьего-то блога, то ли с начала этой темы. Про ЦСГШоп там не было. 😦
По поводу Notepad++ – я его уже года 2 использую, как и SciTe. Много вещей в них делать удобнее чем в Eclipse( в основном, я Java Enterprise разработчик). А файловый менеджер уже нное количество лет – Total Commander. Тока не будем разжигать религиозную войну Far Vs TC. 😌
Олег, возвращаясь к моему предыдущему посту:
1)
PINE и PINL. Если предположить, что это Port E и Port L Меги 2560
Правильно ли это предположение?
2)
посмотреть на схеме BlackVortex, что у него подключено к соответствующим ножкам этих портов:
(PINE & 128) (PINE & 64) (PINL & 64)
Выходит, что к 6й, 7й ножке порта Е и 6й ножке порта L подключались те самые
оригинальном ардупилоте за реверсы отвечают микропереключатели на плате.
?
П.С. И ссылкой на схему BV не поделитесь?
П.С. И ссылкой на схему BV не поделитесь?
Думаю схему не кто не даст, как то тут уже писалось, мол это ком. тайна и все такое 😃
Отписался уже, что туплю под вечер 😃 Один ноль потерял 😃 В общем, гипотеза по скорости провалилась…
Не всё так плохо 😃
defines.h содержит константу предела скорости, при которой автопилот начнёт отрыв от земли
#define SPEEDFILT 400 // centimeters/second; the speed below which a groundstart will be triggered
По mavlinkу тоже
g_gps->ground_speed * rot.a.x, // X speed cm/s
g_gps->ground_speed * rot.b.x, // Y speed cm/s
В том же config.h
#ifndef AIRSPEED_CRUISE
# define AIRSPEED_CRUISE 12 // 12 m/s
#endif
#define AIRSPEED_CRUISE_CM AIRSPEED_CRUISE*100 – специально переводят себе в cm/s
Идём дальше AP_DCM.cpp (хреновина, которая всё и решает 😃):
#define SPEEDFILT 300 // centimeters/second
radio.pde тоже оперирует cm/s
Так что Ваше предположение о том, что внутри МегаПират оперирует сантиметрами/сек скорее всего верно.
Да, если bvHUD – ответная часть для ОСД: sport.write((byte)(g_gps->ground_speed*0.036)); //m/s *100 transform to KPH
Если _EOSD – ответная часть для какой-то другой ОСД sport.write((byte)(g_gps->ground_speed*0.036));
Т.е. то же самое cm/s переводят в km/h
Значит у МегаПилота всё нормально. Особенно, учитывая тот факт, что g_gps->ground_speed используется в МП везде.
Если показывается в ОСД другое значение – надо тогда смотреть код самой ОСД, скорее всего он неправильно отмалёвывает. Или неправильно вынимает то, что ему приходит от bvHUD или _EOSD части МегаПилота.
Выходит, что к 6й, 7й ножке порта Е и 6й ножке порта L подключались те самые оригинальном ардупилоте за реверсы отвечают микропереключатели на плате.
“Пробил” только что схему оригинального ардупилота. Таки да, переключатели реверсов подключены к ногам соответствующих портов контроллера -
PL6 - 41
PL7 - 42
PE6 - 8
PE7 - 9
П.С. И ссылкой на схему BV не поделитесь?
Схема Вортекса - Мега 2560 + датчики в стандартном подключении. По пдфкам с его сайта достаточно хорошо видно разводку верхней стороны платы. Ничего, кроме задействованных в Пирате ног там дополнительно не разведено. В т.ч. и эти ноги тоже не разведены. Я себе развёл свою плату, аналогичного функционала, только ЖПС вынес отдельно. Жду датчики, чтобы собрать и проверить в работе:)
Да, по поводу нашего БлекВортекса и единиц измерения скорости в МегаПирате.
У нас стоит U-Blox ГПС, скорость вынимается из MSG_VELNED их протокола. А там единицы измерения чётко указаны
velN cm/s NED north velocity
8 I4 - velE cm/s NED east velocity
12 I4 - velD cm/s NED down velocity
16 U4 - speed cm/s Speed (3-D)
20 U4 - gSpeed cm/s Ground Speed (2-D)
Так что Леонид Вы правы, МегаПират оперирует cm/s
PL6 - 41
PL7 - 42
PE6 - 8
PE7 - 9
Отлично, что подтвердилось. Теперь по коду стало намного проще понимать, что такое PINE и PINL.
Правильно ли это предположение?
Если не посылать вас в даташит, то на пальцах: порт у атмеги состоит из 3 регистров: PORT DDR PIN. PORT это регистр выхода, DDR это направление, PIN это физическая нога. Буквы после них - это названия портов.
Если показывается в ОСД другое значение – надо тогда смотреть код самой ОСД
никак нет, в осд тупо показывается значение одного байта скорости. Преобразование выполняется в _EOSD.pde
никак нет, в осд тупо показывается значение одного байта скорости. Преобразование выполняется в _EOSD.pde
Олег, там же банальный
sport.write((byte)(g_gps->ground_speed*0.036));
Получается, есть только 3 варианта:
- (наименее вероятный) – неисправный GPS или связка Atmega2560 +GPS. Но тогда должно плющить и сам самолёт, gps->ground_speed используется повсеместно в коде, даже в DCM
- Компилятор сгенерировал кривой код для
(byte)(g_gps->ground_speed*0.036)
В принципе, вероятность этого есть, Ардуина же использует WinAvr’овский g++, а в нём часто находили говнокодо-генерацию.
3) Баг в прошивке самой ОСД. Например в функции, которая переводит число в строку. Достаточно распространённый трабл. Правда, непонятно почему тогда остальные показометры правильно отмалёвываются в ОСД.
Других вариантов я не вижу.😌
Расшевелил я смотрю ветку 😉
Компилятор сгенерировал кривой код для
Код:
sport.write((byte)(g_gps->ground_speed*0.036));
Перекомпилил я сие строчку в:
sport.write((byte)(g_gps->ground_speed * 36 / 1000));
Может с целыми числами дело пойдет лучше 😃
Сегодня -22, вот думаю поэкстрималить в полях, или лучше все же дома на печи поваляться 😃
Сегодня -22, вот думаю поэкстрималить в полях, или лучше все же дома на печи поваляться
Та ну, ни один автопилот не стоит такого издевательства над человеком.
Перекомпилил я сие строчку в:
sport.write((byte)(g_gps->ground_speed * 36 / 1000));
Результат отрицательный 😦 Скорость так же скачет…
Та ну, ни один автопилот не стоит такого издевательства над человеком.
Однако ваша правда, на крайнем полете сперва думали что сглючил АП, самуль проходя последнюю точку стал разворачиваться и быстро снижаться, метрах в 10-20 переключил на ручное ручку на себя, но скай как шел под углом градусов 45 так и вписался в сугроб…
Логи показали то ли отвалился кабанчик, то ли замерзла серва РВ… АП до последнего давил на себя на максимум…
К стати, какая переменная отвечает за шаг миссии? Хотелось бы знать какой шаг в данный момент исполняет АП… Я бы пока нет бвХУД вместо скорости вывел данные в планер, больше толка бы было, скорость все равно кривая 😃
К стати, какая переменная отвечает за шаг миссии? Хотелось бы знать какой шаг в данный момент исполняет АП…
Пока рылся в коде – натыкался на такие переменные next_nav_command и next_nonnav_command. Собственно у МегаПирата идёт разделение на эти 2 подтипа команд. Дёргается update_commands() на каждой итерации из commands_process.pde. Все кишки сидят в commands.pde, commands_logic.pde и commands_process.pde.