В качестве инструмента моделирования управления полетом летающего робота была выбрана программа Ceebot компании Epsitec.
Программа Ceebot предназначена для обучения детей программированию. Она представляет собой Интеллектуальную обучающую игровую систему, которая позволяет настраивать пространство (горы, моря, реки, ущелья и т.п.) в котором происходит действие; участников – программируемых роботов разных типов (колесных, ходячих, летающих); сценарии заданий по программированию с встроенным контролем результата выполнения и используемых команд в разработанной программе. Встроенный программный редактор с подсветкой и контролем синтаксиса имеет возможность в пошаговом режиме отлаживать написанный код.
С помощью этой программы я обучаюсь программированию с 2012 года.
В ходе выполнения исследовательской работы была настроена виртуальная модель пространства Луны с рельефом местности включающая кратеры и горы. На местности были размещены участники моделирования – программно-управляемые роботы. Визуально виртуальная модель представляет собой сцену посылки космонавтом летающего робота для доставки нового аккумулятора в целях заправки другого робота исследующего поверхность Луны.
В программе Ceebot есть специальный файл, в котором можно вписывать нужные объекты. В этот файл я добавила следующие объекты:
1. Космонавт Me – он как бы запускает летающего робота на выполнение задания.
2. Летающий робот WingedGrabber – он будет управляться моей программой.
3. Батарея PowerCell – ее требуется доставить к цели.
4. Исследующий робот TrackedSniffer – обозначает цель полета, куда робот должен долететь.
5. Луноход ApolloJeep – это на чем космонавт якобы передвигается по Луне.
Настройка местности:
TerrainRelief image="%mission%relief.bmp" factor=1.0
TerrainResource image="%mission%resource.bmp"
TerrainInitTextures image="moon" dx=1 dy=1 table=103
TerrainCreate
Файл рельефа - relief.bmp
Настройка объектов:
BeginObject
CreateObject pos=-300; -270 dir=1.8 type=Me
CreateObject pos=-297; -270 dir=1.8 type=ApolloJeep
CreateObject pos=-297; -275 dir=1.6 type=WingedGrabber power=200 range=300
CreateObject pos=-296; -273.5 dir=1.6 type=PowerCell
CreateObject pos=50; 250 dir=1.6 type=TrackedSniffer power=5 script1="%mission%sniff1.txt" run=1 cmdline=1
Программа управления исследующим роботом:
extern void object::Sniffing()
{
while(true)
{
if(this.energyCell==null)
{
continue;
}
if(this.energyCell.energyLevel<0.1)
{
continue;
}
turn(90);
while(true)
{
move(5);
sniff();
}
}
}
В системе Ceebot рельеф местности храниться в виде графического файла формата bmp. К этому файлу предъявляются определенные требования: размер должен быть 161х161 пикселей; цветовая структура – 256 оттенков серого. Каждый пиксел это часть местности размером пять на пять метров моделируемой местности, следовательно в итоге карта получается 805х805 метров. Каждый оттенок серого определяет высоту в 0,25 метров, поэтому самая высокая точка получается в 64 метра.
Для того чтобы робот мог использовать данные о высоте точек поверхности нужно графический файл рельефа преобразовать в массив высот точек, т.е. оттенок серого каждого пискселя преобразовать в цифровое значение, а это значение занести в элемент массива соответствующий этой точке на карте. Для разрешения этой проблемы нужно было решить две задачи: 1. Преобразовать графический файл в текстовый со значениями уровня серого каждой точки. 2. Загрузить значения из текстового файла в двухмерный массив. Первая задача была решена с помощью профессионального программиста, который сделал программу преобразования. Вторую задачу решил мой папа, написав специальную функцию, которая при запуске моей программы загружает из файлов числовые значения в массив.
В Ceebot координаты считаются с середины карты. Ось Y – Юг-Север и ось X – Запад-Восток. А в двухмерном массиве позиции элементов нумеруются начиная с крайней Северо-Западной точки. Поэтому, если на карте робот находится в точке х=0 и y=0, то высота этой точки в ЦКМ будет соответствовать map[80][80], если мы берем высоту из элемента массива map[0][0], то она соответствует точке на карте с координатами х=-400, y=400.
В своей программе я постоянно пересчитываю эти значения друг в друга:
// this.position-----------------------------
x0 = 80 + position.x /5; // находим где мы находимся в массиве высот по x
y0 = 80 - position.y /5; // находим где мы находимся в массиве высот по y
После взлета робот может направиться в любую сторону, в любой из 360 градусов окружности, но т.к. ЦКМ представляет из себя двухмерный массив, то точку в которой сейчас находится робот окружает восемь соседних точек. Поэтому нужно анализировать только их высоты. Я разбила все возможные направления движения работа на восемь вариантов анализа (угол движения в Ceebot считается с востока против часовой стрелки):
1. Восток – углы с 0 по 22 и с 339 по 360.
2. Северо-восток - углы с 22 по 67.
3. Север - углы с 67 по 112.
4. Северо-запад - углы с 112 по 157.
5. Запад - углы с 157 по 202.
6. Юго-запад - углы с 202 по 247.
7. Юг - углы с 247 по 292.
8. Юго-восток - углы с 292 по 339.
Рассмотрим анализ направления «Восток». Робот находится в точке ЦКМ «0» и двигается в сторону точек А,В,С т.к. каждое направление занимает угол в 45 градусов мы предполагаем, что робот может пролететь над каждой из этих точек.
Я сначала сравниваю высоту точек А и С, затем большую из них сравниваю с высотой точки В, в результате запоминаю высоту самой высокой точки.
if (map[x0+1][y0]-map[x0+1][y0-1] >= 0) // если высота следующей центральной точки больше высоты следующей правой точки
{
p = map[x0+1][y0]; // сохраняем высоту следующей центральной точки n = map[x0+1][y0]*0.25;
}
else // иначе
{
p = map[x0+1][y0-1]; // сохраняем высоту следующей правой точки
n = map[x0+1][y0-1]*0.25;
}
if (p - map[x0+1][y0+1] < 0) // если самая высокая следующая левая точка
{
n = map[x0+1][y0+1]*0.25; // сохраняем высоту следующей левой точки
}
Для направления «Северо-восток» программа анализа выглядит так:
if (map[x0+1][y0-1]-map[x0+1][y0-2] >= 0) {
} else {
} if (p - map[x0+1][y0] < 0) {
} if (map[x0+1][y0-1]-map[x0+1][y0-2] >= 0) {
} else {
} if (p - map[x0+1][y0] < 0) {
} |
И так далее по всем восьми направлениям.
Зная из трех следующих по направлению самую высокую точку я анализирую ее высоту по отношению высоты полета робота. Здесь возможны три варианта:
1. Впереди точка, высота которой приведет к уменьшению заданной высоты полета, но не выше текущей высоты полета.
В этом случае необходимо замедлить скорость и поднять робота на большую высоту.
Выполняется в цикле следующий блок команд:
if (this.position.z - n < high) // если разница между абсолютной высотой полета и высотой следующей точки меньше заданной относительной высотой полета
{
drive(0.2, 0); // замедлить скорость
jet(0.1); // подъем
wait(0.1); // ждем
}
2. Впереди точка, высота которой превышает текущую высоту полета.
Необходимо остановить робота, чтобы он не врезался в гору, поднять его высоту, чтобы она была на уровне заданной по отношению к следующей точке.
Выполняется в цикле следующий блок команд:
if (this.position.z - n < 0) // если абсолютная высота полета меньше следующей точки
{
drive(0, 0); // останов
jet(0.1); // подъем
wait(0.1); // ждем
}
3. Впереди точка, высота которой приведет к увеличению заданной высоты полета.
В этом случае необходимо снизить высоту полета до уровня заданной.
Выполняется в цикле следующий блок команд:
if (this.position.z - n > high) // если разница между абсолютной высотой полета и высотой следующей точки больше заданной относительной высотой полета
{
drive(0.2, 0); // замедлить скорость
jet(-0.1); // снижение
wait(0.1); // ждем
}
На основе алгоритма написана программа на языке Cbot автоматического управления летающим роботом. Программа анализирует направление полета и выбирает один из восьми сценариев анализа траектории. По выбранному сценарию программа определяет по цифровой карте рельефа высоту следующей точки полета и уже в зависимости от ее значения корректирует высоту траектории робота в пределах заданной. Таким образом, робот летит огибая рельеф: поднимаясь над возвышенностями и опускаясь в низины. Программа одновременно сравнивает текущее положение робота с координатами заданной цели, в случае если робот достиг пределов цели, она осуществляет управление мягкой посадкой. В итоге летающий робот достигает заданной точки.
Соответствие функциональных частей БПЛА и команд языка Cbot.