Транспортный авиационный робот
Источники: Обсуждение на форуме
Содержание
- 1 Электрические схемы и спецификации
- 2 Описание внешних сигналов модуля УЭВМ
- 3 Описание сигналов модуля драйверов
- 4 Описание сигналов бортовых сенсоров
- 5 Описание электропитания
- 6 Описание решения проблемы внутренних помех и наводок
- 7 Описание и дополнения (технические требования) к принципиальным электрическим схемам
- 8 Резюме
- 9 Реализация виртуального автоматического навигатора(штурмана)
- 10 Интерфейс модуля УЭВМ
- 11 Модуль драйверов
- 12 Радиоприемник системы ДУ
- 13 Тахометр
- 14 Сервоприводы бортовых устройств
- 15 Радиоприемник РНС-ИСЗ «GPS»-«NAVSTAR»
- 16 Исхоный код
- 17 Примечания
Электрические схемы и спецификации
Для просмотра схем и чертежей используйте sPlan v.5
Схема электрическая структурная
Смотрите в файле «Э1.spl» .
Схема электрическая функциональная
Смотрите в файле «Э2.spl» .
Схемы электрические принципиальные
Нумерация в позиционных обозначениях ЭРЭ и прочих компонент, указанных на принципиальных схемах всех узлов и блоков — сквозная.
Описание внешних сигналов модуля УЭВМ
- «ПРОШИВКА_[7..9]» — для прошивки программ ПЗУ однокристальных микроконтроллеров
- «TAHO[0..2]» — 3-битовый паралл. код значения средн. угл. скор. вращ. вала мотора
- «TEMPERATURE» — аналоговое значение температуры мотора
- «RADIO_RMT_CTRL[0..2]» — 3-битовый паралл. код команд радиоуправления
- «SELF_CLK» — тактовый сигнал на регистр сдвига модуля драйверов
- «SELF_CLK1» — тактовый сигнал на регистр сдвига модуля драйверов
- «SELF_DATES» — бит данных для регистра сдвига модуля драйверов (приставка «SELF» — бортовые сервоустройства)
- «TRG_CLK» — тактовый сигнал на регистр сдвига модуля драйверов
- «TRG_CLK1» — тактовый сигнал на регистр сдвига модуля драйверов
- «TRG_DATES» — бит данных для регистра сдвига модуля драйверов (приставка «TRG» — целевые сервоустройства)
- «ПУСК1», «ПУСК2» — биты команд общего пуска всей машины
- «SHASSY» — бит от шасси, для определения момента отрыва от ВПП и касания ВПП
- «SENS[0..7]» — байт паралл. кода от сенсоров
- «GPS» — от GPS-модуля
- «SET_GPS_RS» — на GPS-модуль
- «GND» — «Общий» для всей электросети
- «GND_CUT» — «Общий» для логики модуля УЭВМ, части периферии(тахометр, термометр, сенсоры,GPS-модуль, радиоприемник_СДУ), и при этом гальванически не связанный с «Общим» всей остальной электросети
- «VCC» — (+5) [В] питания логики(TTL) модуля драйверов и всей остальной э/сети
- «VCC_CUT» — (+5) [В] питания логики(TTL, СБИС ОМК) модуля УЭВМ, части периферии (тахометр, термометр, сенсоры,GPS-модуль, радиоприемник_СДУ), и при этом гальванически не связанный с «VCC» всей остальной электросети
- «START» — бит. команда на систему электропуска и электрозажигания мотоагрегата
Команды радиоуправления
- «РУЛЬ_ВЛЕВО»
- «РУЛЬ_ВПРАВО»
- «РУЛЬ_ВНИЗ»
- «ГАЗ_САМЫЙ_МАЛЫЙ»
- «ГАЗ_БОЛЬШОЙ»
- «ПУСК»
- «ТОРМОЗ»
- «АВТОМАТИКА» — это команда, устанавлив-я по умолч-ю, при ней нет радиоуправления
Описание внутрених сигналов модуля УЭВМ
- «INTERRUPT_1,2» — прерывание от второго ОМК на первый ОМК
- «D_TRANS[0..15]» — 16-битовый паралл. код магистрали обмена данных «ОМК#1 <-> ОМК#2»
- «FLAG_MCU_1[0..2]» — 3-битовый флаг состояния ОМК#1
- «FLAG_MCU_2[0..2]» — 3-битовый флаг состояния ОМК#2
- «SENSOR_CLK» — тактовый сигнал на регистр сдвига буфера бит от сенсоров
- «SENSOR_DATES» — бит данных от регистра сдвига буфера бит от сенсоров(помимо сенсоров технологических устройств, здесь также два бита команд общего запуска, и бит от шасси)
- «SENSOR_LD» — управление режимом работы регистра сдвига(сдвиг или загрузка) и загрузки бит от сенсоров
Описание сигналов модуля драйверов
- «ВЛЕВО» — фаза на электромагнит соотв. руля (для поворота по часовой стрелке(вид сверху) руля курса)
- «ВПРАВО» — фаза на э/магнит соотв. руля (для поворота против часовой стрелке(вид сверху) руля курса)
- «ВНИЗ» — фаза на э/магнит соотв. руля (для поворота по часовой стрелке(вид слева по ходу) руля тангажа)
- «ЕЛЕ-ЕЛЕ» — фаза на э/магнит устанавливающего дроссель газа в положение «ГАЗ_САМЫЙ_МАЛЫЙ»
- «МАЛЫЙ» — фаза на э/магнит устанав-го дроссель газа в полож. «ГАЗ_МАЛЫЙ»
- «СРЕДНИЙ» — фаза на э/магнит устанав-го дроссель газа в полож. «ГАЗ_СРЕДНИЙ»
- «БОЛЬШОЙ» — фаза на э/магнит устанав-го дроссель газа в полож. «ГАЗ_БОЛЬШОЙ»
- «ЗАПУСК» — (+12 В) на систему электропуска и электрозажигания мотоагрегата
- «ОСТАНОВ» — фаза на э/магнит тормоза колес шасси
- «TRG_SRV[0..7]» — (+12 В) на технол.(целевые) сервоустр-ва
- «TRG_SRV_PH[0..7]» — фаза на каждое отдельное технол.(целевое) сервоустр-во
- «PHASE» — фаза
Описание сигналов бортовых сенсоров
- «ПУСК1», «ПУСК2» — биты команд общего пуска всей машины
- «SHASSY» — бит от шасси, для определения момента отрыва от ВПП и касания ВПП
Описание электропитания
Первичных источников электропитания всего два. На функциональной электросхеме они изображены в виде блоков, первый из них — «Аккумуляторная ба-тарея», второй — «ПИП». Далее идет описание по функциональной электросхеме.
«Аккумуляторная батарея» выдает нестабилизированное напряжение постоянного тока номинальной величиной «+12 В». «+12 В» поступает на вход блока «Инвертор», из блока «Инвертор» выходит нестабилизированное напряжение переменного тока с параметрами примерно соответствующим стандартам напряжения для потребителей электросетей, это переменное напряжение предназначено для: питания серво-приводов(электромагнитов) бортовых устройств(рулей, тормоза, дросселя), питания сервоприводов целевых устройств. Кроме того, переменное напряжение поступает на вход первого блока вторичного электропитания — «ВИП1». «ВИП1» вырабатывает стабилизированные напряжения постоянного тока «+5[В] № 1» и «+12[В] № 1» (номиналы); первое напряжение предназначено для питания узлов и блоков: «модуль УЭВМ», «Тахометр», «Термометр», «Радиоприемник системы ДУ», "радиоприемник РНС-ИСЗ «GPS»-«NAVSTAR»; второе предназначено для питания узлов и блоков: «Радиоприемник системы ДУ», «Тахометр», «модуль УЭВМ»(адаптер для RS-232C). «+12 В» также поступает на вход блока «ВИП2». «ВИП2» вырабатывает стабилизированное напряжение постоянного тока «+5 В № 2» (номинал), предназначенное для питания блока «Модуль драйверов». Блок «ПИП» выдает нестабилизированное напряжение постоянного тока номинальной величиной «-12 В», предназначенное для питания узлов и блоков: «Радиоприемник системы ДУ», «Тахометр», «модуль УЭВМ» (адаптер для RS-232C).
Описание решения проблемы внутренних помех и наводок
Здесь идет описание по функциональной электросхеме. Основным источником внутренних наводок являются сервоприводы. Наиболее критичным с точки зрения фатальных(и при этом необративых) сбоев функционирования всего изделия является блок «Мо- дуль УЭВМ». Основным каналом распространения внутренних помех и наводок являются цепи питания. Исходя из вышеперечисленного, «+5 В № 1», «+12 В № 1» и «-12 В» гальванически не связаны с остальными уровнями(но разумеется связаны промеж собой). «+12 В», « ~220 B, 50 Гц» и «+5 В № 2» — гальванически связаны меж собой. Также используются фильтры низких частот по питанию в блоках «модуль УЭВМ» и «модуль драйверов». И наконец, сами блоки питания также снабжены конденсаторными батареями большой емкости.
Описание и дополнения (технические требования) к принципиальным электрическим схемам
- Вывод 7 ИМС DD4,DD5,DD6,DD7,DD8,DD9,DD10,DD11,DD12,DD13,DD27,DD28,DD29,DD30 подсоединить к цепи «GND».
- Вывод 14 ИМС DD4,DD5,DD6,DD7,DD8,DD9,DD10,DD11,DD12,DD13,DD27,DD28,DD29,DD30 подсоединить к цепи «VC1».
- Транзисторы VT1…VT9,VT20…VT27 — на радиаторах.
- Симисторы VS1…VS16 — на радиаторах.
- Выводы 62,64 ИМС DD1 подсоединить к цепи «VCC2».
- Вывод 64 ИМС DD2 подсоединить к цепи «VCC2».
- Вывод 7 ИМС DD3,DD14,DD15 подсоединить к цепи «GND_CUT».
- Вывод 14 ИМС DD3,DD14,DD15 подсоединить к цепи «VCC2».
- Вывод 7 ИМС DD18,DD19 подсоединить к цепи «-7 V».
- Вывод 14 ИМС DD18,DD19 подсоединить к цепи «+7 V».
- Вывод 7 ИМС DD20 подсоединить к цепи «GND_CUT».
- Вывод 14 ИМС DD20 подсоединить к цепи «VCC_CUT».
- Вывод 7 ИМС DD23,DD24 подсоединить к цепи «-7 V».
- Вывод 14 ИМС DD23,DD24 подсоединить к цепи «+7 V».
- Вывод 7 ИМС DD26 подсоединить к цепи «GND_CUT».
- Вывод 14 ИМС DD26 подсоединить к цепи «VCC_CUT».
- Выполнить в виде отдельных печатных узлов : модуль УЭВМ, модуль драйверов, тахометр(кроме разумеется магниторезистра R64), радиоприемник системы ДУ(кроме разумеется сотового телефона).
- Печатные платы, используемые в печатных узлах должны быть односторонними.
- Не допускается монтаж ИМС на панельные разъмы.
Резюме
Функциональная электросхема реализована в виде принципиальной электросхемы. Реализация имеет несколько недостатков и особенностей.
Реализация виртуального автоматического навигатора(штурмана)
Виртуальный автоматический навигатор(штурман) выполняется в DD2. Как известно, точное вождение требует достаточно точного решения навигационной задачи, что в свою очередь требует довольно точных вычислений по формулам аналитической геометрии, включая вычисления в сферической системе координат. В результате, требуется реализовать триганометрические функции, и разумеется вычисления с плавающей точкой, включая умножение. Для таких дел хорошо подходят DSP однокристальные микроЭВМ, но они пока редки в розничной продаже. Также неплохо бы смотрелся арифметический сопроцессор 8087(80287,80387), но их давно сняли с производства, и поэтому они исчезли.
Интерфейс модуля УЭВМ
Несколько необычен интерфейс модуля УЭВМ. ОМК ATmega128 имеет мощную периферию(любой контроллер заточен на интенсивный ввод-вывод и содержит аппаратную поддержку разнообразных задач автоматики), но мною реализовано мультиплексирование на регистрах сдвига(они в модуле драйверов). Это сделано по двум причинам. Во-первых, экономятся порты ОМК, что позволит в будущем при необходимости модифицировать аппаратную часть модуля УЭВМ достаточно малой кровью. Во-вторых, гальваническая развязка получается достаточно компактной. Разумеется, чем-то пришлось поступиться, а именно скоростью ввода-вывода; но это приемлимо, так как периферия достаточно медленная.
Модуль драйверов
Регистры сдвигов и буферизации использованы «дубовой» 155 серии и к тому же 4-разрядные. Резоны :
- 155-серии очень много в неликвидах(продаются чуть ли не мешками);
- У 155-серии выше помехоустойчивость, чем у ТТЛШ серий(555,533,1533), поскольку больше токи;
- буферные регистры такие же, как и сдвиговые;
- при желании можно применить мощные драйверы 155ЛА18.
С точки зрения помехоустойчивости лучше были бы КМДП-серии(561,564), которые работали бы на 12 вольтах, но они подороже. Вместо обычных симисторов можно было использовать тиристорные оптопары(готовая гальвано- развязка), но они опять-таки подороже.
Радиоприемник системы ДУ
Ставилась задача обойтись как можно меньшими регулировками(вроде удалось совсем от них избавиться), и при этом в качестве радиочастотной части(антенна,ВЦ,УРЧ,гетеродин, смеситель,УПЧ) использовать как можно более широкий спектр устройств. Поэтому усилитель НЧ сделан неизбирательным(апериодическим) с переменным(дискретным) усилением. УНЧ — хоть и по-сути дела нормирующий, но не логарифимический. В общем АРУ с «мозгами», усиление управляется от ОМК, а фильтрацию(по НЧ для частотного детектирования-деманипуляции) делает по-сути сам ОМК. ATmega8 имеет встроенный компаратор(не говоря об АЦП), но использован внешний ТШ, — для возможности замены ATmega8 на любой другой ОМК(например на 8051).
Тахометр
Такая же картина как и в предыдущем пункте. Магниторезистор будет реагировать на пролетающий постоянный магнит, который будет закреплен на валу мотора. Таким образом достигнуто нужное:
- Бесконтактность;
- Отсутствие регулировок;
- Нечувствительность к погрешностям от эксплуатации.
Сервоприводы бортовых устройств
Выбраны станочные электромагниты на 220 В ввиду их доступности, высокому значению допустимой частоты срабатываний при ПВ=100 %, большому тяговому усилию при достаточном ходе(произведение силы на перемещение равно работе), достаточной надежности. Высокое напряжение означает неболь- шой ток(произведение напряжение на ток равно мощности), что позволяет использовать нетолстые провода(пускай изоляция потолще, но пластмасса стоит намного дешевле меди), и к тому же ЭПР машины будет поменьше(а значит ее труднее будет засечь и отследить методами активной радиолокации). Расчет требуемых крутящих моментов на рули будет приведен позднее.
Радиоприемник РНС-ИСЗ «GPS»-«NAVSTAR»
Выбран тот, который выбран, хотя можно поставить почти любой. Все они имеют примерно похожие параметры, включая интерфейс.
Исхоный код
<source lang="cpp">
- include <stdio.h>
/*
* Управляющая программа реального времени "Виртуальный_автопилот", * прошиваемая в однокристальный контроллер ATmega128 (поз. обозн. DD1) * модуля УЭВМ автоматического мотодельтаплана "АМДП-1". * Версия №1. * Начато 06.08.009.
- /
//......................................................................
// Уровень и характер абстрагирования ориентирован на принц.схему .
// Термин "машина" относится к мотодельтаплану "АМДП-1".
//......................................................................
void set_begin(void);// функция начальных установок и инициализаций .
unsigned char determ_mode(void);// определение текущего режима .
unsigned char heating(void); // прогревание мотора .
unsigned char starting(void); // разгон машины .
unsigned char take_off(void); // взлет машины .
unsigned char fly(void); // полет машины .
unsigned char landing(void); // посадка машины .
unsigned char braking(void); // торможение машины .
void measuring(void); // измерения в начале полета .
void measuring_course(void); // измерение и формирование ТПФКР .
void measuring_forces(void); // измерение и формирование ТПФГ .
unsigned char ps_ps_and_cmp_alts(void);// выдача сигналов, пауза и сра-
// внение последовательности высот .
void piloting(void); // пилотирование машины . // определение длительности паузы для текущего газа(в 0.2 сек) : unsigned int tau_gas_F(unsigned char gas, int alt_Lst, int alt_Rq); void course_correction_to_left(void); // коррекция курса влево . void course_correction_to_right(void);// коррекция курса вправо . void alt_correction(void); // коррекция по высоте при отклонении . void descenting(void); // снижение . enum modes {H,S,T,F,L,B}; // режимы . unsigned char present_mode;// текущий режим . enum modes_fly {M,P}; // режимы при полете . unsigned char mode_fly; // текущий режим при полете . unsigned char catch; // индикатор исключ.(нештатн.) ситуации . unsigned char set_down; // флаг режима "посадка"(1 при посадке) . unsigned int time_fst;// показ.счетч.врем. с дискр. 0.2 сек(до 10000 сек) . unsigned int time_slw;// показания счетчика времени с дискретом 10 сек . unsigned int time_lbl_fst1;// метка времени "быстрого" счетчика времени . unsigned int time_lbl_fst2;// метка времени "быстрого" счетчика времени . unsigned int alt_set_land;// высота над уровн.моря (в [м]) точки посадки . unsigned char trigger; // триггер подскока при посадке . unsigned char trigger_1;// триггер касания ВПП при посадке . unsigned int time_lbl_land;// метка времени касания ВПП при торможении . unsigned int alt_req;// требуемая текущая высота над уровнем моря (в [м]),
// получаемая от штурмана .
unsigned int alt_last[4];// последние 4 высоты над уровнем моря (в [м]),
// [0] - последний по времени, этот массив явля- // ется стеком, его сдвиг - в shturman_int() .
unsigned char d_t;// длительность импульсов с ШИМ на руле тангажа
// (период=tau_d_t, шаг_приращения=0.4 сек, // дискрет_измерения=0.2 сек, макс_знач=3.2 сек) .
unsigned char tau_d_t;// периоды ШИМ на руле тангажа . unsigned char tau_g[4];// длительность изменения высоты (в 0.2 сек)
// на один метр при заданном значении газа .
// // Табличная Передаточная Функция Газа (ТПФГ) //----------------------I------------------------------------------- // индекс I 0 1 2 3 //----------------------I------------------------------------------- // знач.газа I "ЕЛЕ-ЕЛЕ" "МАЛЫЙ" "СРЕДНИЙ" "БОЛЬШОЙ" //----------------------I------------------------------------------- // tau_g[] (0.2 сек) I tau_g[0] ... tau_g[3] //----------------------I------------------------------------------- // unsigned int tau_g0_10;// вспомогательная, tau_g0_10=10*tau_g[0],
// вычисляется один раз и затем экономится время .
// курс отмеряется от азимута по часовой стрелке . unsigned int course_req;// требуемый курс (в угловых градусах х 100),
// получаемый от штурмана .
// последние 10 значений курсов(в угл.градусах х 100), [0] - последний // по времени, этот массив является стеком, его сдвиг - в shturman_int() : unsigned int course_last[10]; int delta_fi;// текущее курсовое отклонение . // длительность импульса на руле курса(шаг_приращения=0.4 сек, // дискрет_измерения=0.2 сек, начальн_знач=0.4 сек, макс_знач=4.8 сек) : const unsigned char D_T1[]={2,4,6,8,10,12,14,16,18,20,22,24}; unsigned char tau[12];// длительность переходного процесса отработки машиной
// поворота курсового руля, измеренное в 0.2 сек, // [0] - для D_T1=0.4 сек .
int d_fi[12];// результирующий поворот курса для заданной длительности
// импульса, измеренный в угл.град. х 100, [0] - для 0.4 сек .
// // Табличная Передаточная Функция Курсового Руля (ТПФКР) //----------------------I--------------------------------------------------- // D_T1[] (0.2 сек) I 2 4 6 8 10 12 14 16 18 20 22 24 //----------------------I--------------------------------------------------- // tau[] (0.2 сек) I tau[0] ... tau[11] //----------------------I--------------------------------------------------- // d_fi[] (угл.гр.х100) I d_fi[0] ... d_fi[11] //----------------------I--------------------------------------------------- // const unsigned char T_1=5;// константа длительности прогрева . const unsigned char T_2=7;// конст.макс.длит. прогрев+разгон . const unsigned char T_3=9;// конст.длит. прогрев+разгон+взлет . const unsigned char DIFFERENCIAL_1=8;// макс.доп.приращ.высоты на взл. . const unsigned char DIFFERENCIAL_2=2;// макс.доп.втор.дифф.высоты на взл. . const unsigned int D_FI_max=300;// (0.01 град) макс.доп.для САУ курсовое от-
// клонение, больше - начин.курсовая коррекция .
// (0.01 град) максимальное отклонение соседних по времени // курсов, больше - считаю, что переходный процесс - не завершен : const unsigned int D_FI_meas_tau=100; //............................................................................ // Термин "сигнал" относится к принципиальной схеме ("1",+12,фаза -> "1"). // Считывание сигналов производится раз в сек по прерыванию от DD2, и от DD2. //............................................................................ void put_signals(void);// выдача сигналов . unsigned char signals;// разряды этого байта соответствуют вых.сигналам : // сигнал "ВЛЕВО" -- разряд 0 . // сигнал "ВПРАВО" -- разряд 1 . // сигнал "ВНИЗ" -- разряд 2 . // сигнал "ЕЛЕ-ЕЛЕ" -- разряд 3 . // сигнал "МАЛЫЙ" -- разряд 4 . // сигнал "СРЕДНИЙ" -- разряд 5 . // сигнал "БОЛЬШОЙ" -- разряд 6 . // сигнал "ОСТАНОВ" -- разряд 7 . void put_signal_start(void);// выдача сигнала "ЗАПУСК" . void read_signal_taho(void);// считывание сигналов "TAHO[0,1,2]" . unsigned char taho;// разряды этого байта соотв.входным сигналам : // сигнал "TAHO[0]" -- разряд 0 . // сигнал "TAHO[1]" -- разряд 1 . // сигнал "TAHO[2]" -- разряд 2 . unsigned char start_1,start_2,shassy;// сигналы "ПУСК1","ПУСК2","SHASSY" . // объявление аппаратно зависимых переменных и функций :
- include "dcl_hrd"
unsigned char tmp,tmp_1;// tech .
void main(void) {
// начальная установка внутренних регистров(аппаратно зависимая) :
- include "set_rg1"
set_begin();// начальные установки и инициализации . // проверка сигналов "ПУСК1", "ПУСК2" : while(1) {if(start_1==0 && start_2==0){break;} else{;};} while(2) {// основной бесконечный цикл . present_mode=determ_mode();// опр.тек.режима . catch=0; switch(present_mode) {// вызов соотв.функции : case F : {catch=fly(); break;}// полет . case H : {catch=heating(); break;}// прогревание . case S : {catch=starting(); break;}// разгон . case T : {catch=take_off(); break;}// взлет . case L : {catch=landing(); break;}// посадка . case B : {catch=braking(); break;}// торможение . } if(catch==1 || catch==2)break;// нештатная ситуация на земле . }// END OF while(2) // установить газ на "ЕЛЕ-ЕЛЕ", включить тормоз : signals=0x88;// "1" -> ЕЛЕ-ЕЛЕ ; "1" -> ОСТАНОВ .
}// END OF main() .
void set_begin(void) {// функция начальных установок и инициализаций .
present_mode=H; mode_fly=M; catch=set_down=time_fst=time_slw=time_lbl_fst1=time_lbl_fst2=0; alt_set_land=trigger=trigger_1=time_lbl_land=alt_req=0; alt_last[0]=alt_last[1]=alt_last[2]=alt_last[3]=0; d_t=course_req=delta_fi=tmp=0; tau_d_t=20; tau_g[0]=5;tau_g[1]=10;tau_g[2]=20;tau_g[3]=10; tau_g0_10=200; course_last[0]=course_last[1]=course_last[2]=course_last[3]=0; course_last[4]=course_last[5]=course_last[6]=course_last[7]=0; course_last[8]=course_last[9]=0; tau[0]=4; tau[1]=6; tau[2]=10; tau[3]=12; tau[4]=16; tau[5]=18; tau[6]=22;tau[7]=24;tau[8]=28;tau[9]=30;tau[10]=38;tau[11]=40; d_fi[0]=500; d_fi[1]=500; d_fi[2]=800; d_fi[3]=800; d_fi[4]=1000;d_fi[5]=1000;d_fi[6]=1500; d_fi[7]=1500; d_fi[8]=2000;d_fi[9]=2000;d_fi[10]=4000;d_fi[11]=6000; signals=0x88;// 1 -> "ЕЛЕ-ЕЛЕ" ; 1 -> "ОСТАНОВ" . put_signals();
}// END OF set_begin() .
// аппаратно зависимые функции :
- include "hrd_dpnd"
unsigned char determ_mode(void) {// определение текущего режима .
unsigned char grnd;// сигнал "SHASSY" . grnd = shassy; if(time_slw>=T_3 && set_down==0 && grnd==1)return F;// полет . if(time_slw<=T_1 && grnd==0) return H;// прогревание . if(time_slw>T_1 && time_slw<T_3 && grnd==0)return S;// разгон . if(time_slw>T_1 && time_slw<T_3 && grnd==1)return T;// взлет . if(time_slw>T_3 && set_down==1 && grnd==1)return L;// посадка . if(time_slw>T_3 && grnd==0) return B;// торможение . if(time_slw<=1 && grnd==1) { // сбой УЭВМ в полете . time_slw=T_3+1;mode_fly=P;return F; } return F;
}
unsigned char heating(void) {// прогревание мотора .
unsigned int t;// локальное время (0.2 сек) . // установить газ на "ЕЛЕ-ЕЛЕ", включить тормоз, включить мотор : signals=0x88;// "1" -> ЕЛЕ-ЕЛЕ ; "1" -> ОСТАНОВ . put_signal_start();// включить мотор . put_signals(); t=time_fst; while(time_fst-t<20){;}// ждать 4 сек . read_signal_taho();// считывание сигналов "TAHO[0,1,2]" if(taho<1) {// если обороты меньше 1(из 7) . catch=1; }
//======= // ЗАкомментировать строку "printf..." в ICC !!!!! . //=======
//printf("heating---\n");// tech . return catch;
}
unsigned char starting(void) {// разгон машины .
unsigned int t;// локальное время (0.2 сек) . // отключить тормоз, газ на "БОЛЬШОЙ" : signals=0x40;// 1 -> "БОЛЬШОЙ" . put_signals(); t=time_fst; while(time_fst-t<20){;}// ждать 4 сек . read_signal_taho();// считывание сигналов "TAHO[0,1,2]" if(taho<6) {// если обороты меньше 6(из 7) . catch=2; }
//======= // ЗАкомментировать строку "printf..." в ICC !!!!! . //=======
//printf("starting---\n");// tech . return catch;
}
unsigned char take_off(void) {// взлет .
unsigned int t;// локальное время (0.2 сек) . unsigned char i;// счетчик циклов . unsigned char check;// флаг результата проверки дифференциалов . char diff_1[3];// первые дифференциалы высот(тангажи) . char diff_2[2];// вторые дифференциалы высот . t=0; // установить руль тангажа в положение "ВНИЗ", газ оставить "БОЛЬШОЙ" : signals=0x44;// 1 -> "ВНИЗ" ; 1 -> "БОЛЬШОЙ" . put_signals(); t=time_fst; while(time_fst-t<d_t){;}// ждать d_t (0.2 сек) . // уст.руль тангажа в гориз.положение, газ оставить "БОЛЬШОЙ" : signals=0x40;// 1 -> "БОЛЬШОЙ" . put_signals(); t=time_fst; while(time_fst-t<tau_d_t-d_t){;}// ждать (tau_d_t-d_t) (0.2 сек) . // вычисление тангажей и их дифференциалов : for(i=0;i<3;i++) diff_1[i]=alt_last[i]-alt_last[i+1]; for(i=0;i<2;i++) diff_2[i]=diff_1[i]-diff_1[i+1]; // проверка их : check=0; for(i=0;i<3;i++) if(diff_1[i]>DIFFERENCIAL_1) check=1; for(i=0;i<2;i++) if(diff_2[i]>DIFFERENCIAL_2) check=1; // если дифференциалы не вышли за допустимые и длительность импульсов // не больше максимальной, то увеличить длительность импульсов : if(check==0 && d_t<=16)d_t=d_t+2; else {d_t=d_t-2;catch=3;}// иначе уменьшить . // сменить период, во избежание самовозбуждения(резонанса) : switch(tau_d_t) { case 20:{tau_d_t=26;break;} case 26:{tau_d_t=20;break;} }
//======= // ЗАкомментировать строку "printf..." в ICC !!!!! . //=======
//printf("take_off---\n");// tech . return catch;
}// END OF take_off() .
unsigned char fly(void) {// полет .
if(mode_fly==M) measuring(); if(mode_fly==P) piloting();
//======= // ЗАкомментировать строку "printf..." в ICC !!!!! . //=======
//printf("fly---\n");// tech . return catch;
}
void measuring(void) {// измерения .
unsigned int t;// локальное время . // газ в "СРЕДНИЙ", рули в неактивное состояние : signals=0x20;// 1 -> "СРЕДНИЙ"; put_signals(); t=time_fst; while(time_fst-t<20){;}// ждать 4 сек . measuring_course();// измерение и формирование ТПФКР . measuring_forces();// измерение и формирование ТПФГ . mode_fly=P;// теперь можно начать пилотирование .
}
void measuring_course(void) {// измерение и формирование ТПФКР .
unsigned int t;// локальное время (0.2 сек) . unsigned char j;// счетчик циклов . int i;// счетчик циклов . // i - счетчик порядкового номера курса(10 - за последние 10 секунд) . // j - счетчик порядкового номера длительности импульса . // цикл по значениям длительностей импульсов, // D_T1[] = 2, 4, 6, 8, 10, ... , 24 (0.2 сек) : for(j=0;j<12;j++) { // установить курсовой руль "ВЛЕВО", газ оставить в "СРЕДНИЙ" : signals=0x21;// 1 -> "ВЛЕВО" ; 1 -> "СРЕДНИЙ"; put_signals(); t=time_fst; while(time_fst-t<D_T1[j]){;}// ждать D_T1[j] (0.2 сек) . // газ оставить в "СРЕДНИЙ", рули в неактивное состояние : signals=0x20;// 1 -> "СРЕДНИЙ"; put_signals(); t=time_fst; while(time_fst-t<50-D_T1[j]){;}// ждать 50-D_T1[j] (0.2 сек) . // длительность переходного процесса : for(i=8;i>=0;i--) {// последние 10 курсов - сравниваю соседние : // если два соседних совпадают до D_FI_meas_tau(0.01 град), // то переходный процесс - завершен : if(course_last[i]-course_last[i+1]<D_FI_meas_tau || course_last[i+1]-course_last[i]<D_FI_meas_tau) {tau[j]=(9-i)*5;break;}// фиксирую длительность перех.проц. . } // результирущий поворот курса для данной длительности импульса : d_fi[j]=course_last[0]-course_last[9]; if(d_fi[j]<0)d_fi[j]=-d_fi[j];// модуль if(d_fi[j]>4500)break;// если поворот больше 45 град., то достаточно . }
}// END OF measuring_course() .
void measuring_forces(void) {// измерение и формирование ТПФГ .
// рули при этом - в неактивное состояние . // газ на "БОЛЬШОЙ" : signals=0x40;// 1 -> "БОЛЬШОЙ" . tau_g[3]=ps_ps_and_cmp_alts(); // газ на "СРЕДНИЙ" : signals=0x20;// 1 -> "СРЕДНИЙ" . tau_g[2]=ps_ps_and_cmp_alts(); // газ на "МАЛЫЙ" : signals=0x10;// 1 -> "МАЛЫЙ" . tau_g[1]=ps_ps_and_cmp_alts(); // газ на "ЕЛЕ-ЕЛЕ" : signals=0x8;// 1 -> "ЕЛЕ-ЕЛЕ" . tau_g[0]=ps_ps_and_cmp_alts(); tau_g0_10=10*tau_g[0];// вспомогательно, чтобы не тратить время потом .
}// END OF measuring_forces() .
unsigned char ps_ps_and_cmp_alts(void) {// выдача сигналов, пауза и
// сравнение последовательности высот . unsigned int t;// локальное время (0.2 сек) . put_signals(); t=time_fst; while(time_fst-t<30){;}// ждать 6 сек . // это сравнение избыточно, но оставь для широкой совместимости : if(alt_last[0]>alt_last[1]) {tmp_1=alt_last[0]-alt_last[1];} else {tmp_1=alt_last[1]-alt_last[0];} switch(tmp_1) {// здесь, tmp_1 - скорость снижения в [м/сек] . case 0:{tmp=5;break;} case 1:{tmp=4;break;} case 2 :{tmp=3;break;} case 3:{tmp=2;break;} case 4:{tmp=1;break;} default:{tmp=1; break;} } if(alt_last[0]==alt_last[3])return 15; if(alt_last[0]==alt_last[2])return 10; return tmp;
}
void piloting(void) {// пилотирование машины .
// если высота текущая ниже требуемой // на 10м и более, то выполнять взлет : if(alt_req>alt_last[0]+10){catch=take_off();return;} // если высота текущая больше требуемой // на 10м и более, то выполнять снижение : if(alt_req+10<alt_last[0])descenting(); // если высота текущая отличается от требуемой, но не более, // чем на 10м, то выполнить коррецию траектории по высоте : if(alt_req!=alt_last[0] && alt_req-alt_last[0]<=10 && alt_last[0]-alt_req<=10){ alt_correction();// коррекция по высоте при отклонении . } delta_fi=course_last[0]-course_req;// текущее курсовое отклонение . // если текущее курсовое отклонение больше D_FI_max(0.01 град), // то выполнить коррецию влево : if(delta_fi>D_FI_max){course_correction_to_left();return;} // если текущее курсовое отклонение меньше -D_FI_max(0.01 град), // то выполнить коррецию вправо : if((-delta_fi)>D_FI_max){course_correction_to_right();return;}
}// END OF piloting() .
void descenting(void) {// снижение
unsigned int t;// локальное время (0.2 сек) . // рули при этом - в неактивное состояние . // газ на "ЕЛЕ-ЕЛЕ" : signals=0x8;// 1 -> "ЕЛЕ-ЕЛЕ" . put_signals(); // tau_g0_10 - длит.снижения(в 0.2 сек) на 10 м, посчитано ранее . t=time_fst;while(time_fst-t<tau_g0_10){;}// ждать tau_g0_10(0.2 сек) .
}// END OF descenting() .
void alt_correction(void) {// коррекция по высоте при отклонении
//рули при этом - в неактивное состояние . unsigned int t;// локальное время (0.2 сек) . unsigned int tau_gas;// (0.2 сек)длительность паузы для текущего газа . unsigned char gas;// текущее значение газа, // 1000 - "БОЛЬШОЙ", 0100 - "СРЕДНИЙ", // 0010 - "МАЛЫЙ", 0001 - "ЕЛЕ-ЕЛЕ" . gas = (signals>>3) & 0xF;// выявить текущее значение газа . // если происходило понижение, и текущая высота больше требуемой, // то оставить газ прежним : if(alt_last[0]<alt_last[1] && alt_last[0]>alt_req) {;} // если происходило понижение, и текущая высота меньше требуемой, // то прибавить газ на шаг : if(alt_last[0]<alt_last[1] && alt_last[0]<alt_req) { switch (gas) {// увеличение на один шаг текущего газа : case 1 : gas=2;// "ЕЛЕ-ЕЛЕ" -> "МАЛЫЙ" case 2 : gas=4;// "МАЛЫЙ" -> "СРЕДНИЙ" case 4 : gas=8;// "СРЕДНИЙ" -> "БОЛЬШОЙ" } signals = gas<<3; put_signals(); } // если происходило повышение, и текущая высота больше требуемой, // то сбавить газ на шаг : if(alt_last[0]>alt_last[1] && alt_last[0]>alt_req) { switch (gas) {// уменьшение на один шаг текущего газа : case 2 : gas=1;// "МАЛЫЙ" -> "ЕЛЕ-ЕЛЕ" case 4 : gas=2;// "СРЕДНИЙ" -> "МАЛЫЙ" case 8 : gas=4;// "БОЛЬШОЙ" -> "СРЕДНИЙ" } signals = gas<<3; put_signals(); } // если происходило повышение, и текущая высота меньше требуемой, // то оставить газ прежним : if(alt_last[0]>alt_last[1] && alt_last[0]<alt_req) {;} // определение длительности паузы для текущего газа(0.2 сек) : tau_gas=tau_gas_F(gas,alt_last[0],alt_req); // пауза установленной длительности(при этом с установленным газом) : t=time_fst;while(time_fst-t<tau_gas){;}
}// END OF alt_correction() .
// определение длительности паузы для текущего газа(0.2 сек) : unsigned int tau_gas_F(unsigned char gas, int alt_Lst, int alt_Rq) {
// alt_Lst-текущая высота, alt_Rq-требуемая высота . unsigned int tmp1; int tmp2; tmp2=alt_Lst-alt_Rq; if(tmp2<0)tmp2=-tmp2; switch (gas) { case 1 : tmp1=tau_g[0]*tmp2;// "ЕЛЕ-ЕЛЕ" case 2 : tmp1=tau_g[1]*tmp2;// "МАЛЫЙ" case 4 : tmp1=tau_g[2]*tmp2;// "СРЕДНИЙ" case 8 : tmp1=tau_g[3]*tmp2;// "БОЛЬШОЙ" } return tmp1;
}
void course_correction_to_left(void) {// курсовая коррекция влево
unsigned int t;// (0.2 сек)локальное время . unsigned char i;// локальный счетчик циклов . // опр.индекс в табл.длительностей импульсов руля : for(i=0;i<11;i++)if(delta_fi>d_fi[i] && delta_fi<d_fi[i+1])break; // установить курсовой руль "ВПРАВО" : signals=signals & 0xFE;// 0 -> "ВЛЕВО" . signals=signals | 0x2;// 1 -> "ВПРАВО" . put_signals(); t=time_fst; while(time_fst-t<D_T1[i]){;}// ждать D_T1[i] 0.2 сек . // установить курсовой руль в нейтраль : signals=signals & 0xFD;// 0 -> "ВПРАВО" . put_signals(); // ждать (tau[i]-D_T1[i]) 0.2 сек : t=time_fst; while(time_fst-t<(tau[i]-D_T1[i])){;}
}// END OF course_correction_to_left() .
void course_correction_to_right(void) {// курсовая коррекция вправо
unsigned int t;// локальное время . unsigned char i;// локальный счетчик циклов . delta_fi=-delta_fi;// сделать положительным // опр.индекс в табл.длительностей импульсов руля : for(i=0;i<11;i++)if(delta_fi>d_fi[i] && delta_fi<d_fi[i+1])break; // установить курсовой руль "ВЛЕВО" : signals=signals | 0x01;// 1 -> "ВЛЕВО" . signals=signals & 0xFD;// 0 -> "ВПРАВО" . put_signals(); t=time_fst; while(time_fst-t<D_T1[i]){;}// ждать D_T1[i] 0.2 сек . // установить курсовой руль в нейтраль : signals=signals & 0xFE;// 0 -> "ВЛЕВО" . put_signals(); // ждать (tau[i]-D_T1[i]) 0.2 сек : t=time_fst; while(time_fst-t<(tau[i]-D_T1[i])){;}
}// END OF course_correction_to_right() .
unsigned char landing(void) {// посадка .
// схему посадки смотри в описании от 01.08.2009 . unsigned int t;// локальное время . // рули - в неактивное состояние, // газ на "ЕЛЕ-ЕЛЕ" : signals=0x8;// 1 -> "ЕЛЕ-ЕЛЕ" . // если текущая высота <= 2м (над точкой посадки), // то (один раз) газ на "БОЛЬШОЙ" и пауза в 1 сек : if(alt_last[0]-alt_set_land<=2 && trigger==0) { signals=0x40;// 1 -> "БОЛЬШОЙ" . put_signals(); trigger=1; t=time_fst; while(time_fst-t<5){;}// ждать 1 сек . } put_signals(); delta_fi=course_last[0]-course_req;// текущее курсовое отклонение . // если текущее курсовое отклонение больше 10 град, // то выполнить коррецию влево : if(delta_fi>1000){course_correction_to_left();return 4;} // если текущее курсовое отклонение меньше -10 град, // то выполнить коррецию вправо : if(delta_fi<-1000){course_correction_to_right();return 4;}
//======= // ЗАкомментировать строку "printf..." в ICC !!!!! . //=======
//printf("landing---\n");// tech . return 0;
}// END OF landing() .
unsigned char braking(void) {// торможение .
// зафиксировать время касания ВПП : if(trigger_1==0){time_lbl_land=time_fst;trigger_1=1;} // рули - в неактивное состояние, // газ на "ЕЛЕ-ЕЛЕ" : signals=0x8;// 1 -> "ЕЛЕ-ЕЛЕ" . // через две секунды включить тормоз : if(time_fst-time_lbl_land>10) { signals=signals | 0x80;// 1 -> "ОСТАНОВ" . } put_signals(); delta_fi=course_last[0]-course_req;// текущее курсовое отклонение . // если текущее курсовое отклонение больше 10 град, // то выполнить коррецию влево : if(delta_fi>1000){course_correction_to_left();return 5;} // если текущее курсовое отклонение меньше -10 град, // то выполнить коррецию вправо : if(delta_fi<-1000){course_correction_to_right();return 5;}
//======= // ЗАкомментировать строку "printf..." в ICC !!!!! . //=======
//printf("braking---\n");// tech . return 0;
}// END OF braking() . </source>