В статье предлагается взглянуть на дополнительные возможности, которые предоставляет квадрокоптер tello dji. Благодаря наличию открытого api и паяльника возможно немного расширить применение аппарата, подружить его с ROS(robot operation system), а также по-новому взглянуть даже на его неисправных собратьев.

Немного общей информации о tello dji.


Волна поклонения величию tello dji потихоньку сошла на нет и это отразилось как на доступной цене данного бюджетного квадрокоптера, так и на том факте, что зачастую его продают с рук с испорченной батареей. О последней позже, а пока поговорим, чем так хорош и, одновременно, плох данный аппарат.

Начнем с плюсов:
  • доступно низкая цена (10-12к руб. либо дешевле, если б/у);
  • наличие открытого api, к которому можно обращаться без всяких подписок и оговорок;
  • высокая маневренность;
  • наличие камеры 960х720;
  • наличие встроенного imu, который по показателям весьма не плох;
  • в некоторых моделях (tello edu) при особой прошивке допускается даже использование камеры снизу (т.е. второй камеры, которая по умолчанию не используется);
  • неприхотливость, быстрый запуск, малый вес, защита винтов.

Теперь о минусах:
  • несмотря на достаточно высокое время отклика по api — wifi сеть все-таки подводит даже на небольшом расстоянии, поэтому серьезно полагаться на нее не стоит;
  • малое время работы от аккумулятора во время полета — 15 мин. Как это победить, будет показано далее;
  • разрешение камеры не изменить с помощью api, как не изменить частоту работы imu. Разрешение камеры скорее подойдет для outdoor применения, чем для помещений, так как в кадр помещается не слишком много объектов;
  • перегревается. Причем, что самое интересное, перегревается даже в полете, при наличии вроде бы обдува со стороны винтов. Один из вариантов решения, также будет показан далее;
  • плохо переносит падения с большой высоты. Понятное дело, что их мало кто хорошо переносит. Но tello dji может получить несопоставимые с жизнью повреждения, просто упав на асфальт с высоты 3-5 метров;
  • нет gps, возврата в точку взлета и других прелестей старших собратьев;
  • не переживет сильный ветер.

В итоге, аппарат очень спорный. Но это не маркетинговый пост, нам от tello dji нужен совсем другой функционал. Какой именно? Об этом далее.

О задаче.


Изучая алгоритмы визуальной навигации ORB_SLAM рано или поздно возникает вопрос о легком, носимом и мощном железе, которое может помочь в этом направлении. А также возникает вопрос, где взять хорошую недорогую камеру в связке с хорошим imu (инерциальный измерительный блок).

Как известно в алгоритмах ORB_SLAM для увеличения точности позиционирования в пространстве кроме собственно камеры, желательно иметь еще одну камеру для стерео, а лучше камеру глубины либо imu.

И тут как нельзя кстати приходится tello, в котором есть и камера и imu.

Осталось только внедрить это tello, так сказать, в дело.

Подготовка к интеграции.


Все бы ничего, если бы не малый срок полета tello и перегрев с последующим отключением.

Разумеется, первый вопрос можно решить наличием дополнительных батарей.

Однако, работать в интервальном режиме по 15 мин быстро надоест. Да и сколько батарей понадобится?

Кстати, о батарее.

Не редки случаи, когда батареи, в силу длительного пребывания в бездействии и переразряда стандартным блоком питания tello не заряжаются.

фото блока питания


Если столкнулись с этой ситуацией, не стоит сразу их выбрасывать и, возможно, батареи еще получится оживить. Для этого посмотрим поближе на батарею:

батарея


Воткнув иголки в проушины батареи, подав 3,8 V и небольшой ток можно попробовать позаряжать батарею полчаса, и, если она оживет, поставить ее уже в стандартную батарейную зарядку для tello. Для реанимации подойдет даже такой простой прибор из разряда «сделай сам» с ali —
блок питания


Поэтому, не спешите выбрасывать батареи от dji tello.

Таким образом, зная, что батарея выдает 3,8-4,2V и тем самым питает tello dji, чтобы его запустить понадобится подпаяться на соответствующие 2 контакта уже на самом квадрокоптере. Летать он не будет, но работать вполне —
картинка


Так как для проведения экспериментов с алгоритмами навигации полеты на начальном этапе не важны, все манипуляции с tello будет в режиме, когда его носят на руках.

Любой квадрокоптер мог об этом только мечтать!

Но что делать с перегревом?

Он будет в разы больше, когда винты не будут вращаться.

Тут придет на помощь кулер от старой материнской платы на 12V (или иной). Его необходимо закрепить «под брюхо» tello. Он будет доволен!

Получится приблизительно так —
картинка


Теперь, когда вопросы с питанием и перегревом решены, можно переходить к другим интересным вещам.

Выбор ORB_SLAM и ROS.


Почему именно ORB_SLAM? Вопрос риторический. Однако, аргументом «за» будет тот факт, что под алгоритм есть заранее сформированные пакеты нод ROS для tello, которые облегчат процесс работы с учетом особенностей квадрокоптера.

Как и в любом нормальном семействе, в «династии» ORB_SLAM есть свои участники семейства.
Остановимся на ORB_SLAM2 и ORB_SLAM3.

ORB_SLAM2 поддерживает Monocular, Stereo and RGB-D камеры, но не имеет интеграции с imu. Помимо это, сам репозиторий достаточно древний и не обновляется. А жаль, на мой взгляд интеграция с tello показала себя не менее удачно, чем c ORB_SLAM3 — пример.

Кроме того, ORB_SLAM2, поддерживает ROS2, поддержки которого нет в ORB_SLAM3.

В то же время, ORB_SLAM3 дает возможность использовать imu наряду с камерой. Однако, не стоит обольщаться, что все работает «из коробки». Заставить работать связку камера-imu (Mono-Inertial Node) возможно только после хорошей калибровки как самой камеры, так и в тандеме с imu.

Кроме того, установка самого пакета не из простых приключений.

Тем не менее, собрать ORB_SLAM3 и запустить ноды для tello возможно — пример.

Однако, следует еще раз напомнить, что ORB_SLAM3 не поддерживает ROS2, по крайней мере пока.

В части, что касается dji tello, также еще остаются нерешенными вопросы относительно передачи видео, передача которого периодически может обрываться — issue.

Затрагивая ORB_SLAM, стоит также упомянуть, достаточно «молодой» и перспективный stella_vslam

К сожалению, там пока нет интеграции с imu, как и в ORB_SLAM2. Однако, в TODO, обозначен этот пункт, поэтому есть смысл ожидать.

Stella-vslam выгладит многообещающе и чем-то напоминает своих старших собратьев. Кроме того, алгоритм возможно использовать с tello — пример.

Исходя из доступности пакетов и их интеграции с tello dji пожалуй, неплохим выбором будет все же ROS1 (noetic) на базе ubuntu 20.04 (ROS также сами по себе также привередливы к выбору os, на которой они «живут»).

Куда устанавливать Ubuntu, ROS.


Обычно этот вопрос не возникает, если пользователь уже использует linux. Тем не менее, для windows также доступна роскошь nix систем.

Несмотря на то, что в windows 7,10 возможно установить Ubuntu через wsl, пойдем по пути виртуальных машин на базе VMware Workstation.



Это несет некоторое неудобство в дальнейшей коммуникации с tello, зато избавляет от необходимости полного перехода на linux либо использования docker контейнеров.

Как установить ubuntu и ros1 noetic в данной статье рассматривать не будем, в сети полно информации как выполнить эти шаги.

Сосредоточимся с сборке ORB_SLAM3, ros нод для него, которые позволят работать с tello, и, непосредственно, самой ноды для tello.

В настройках виртуальной машины vmware важно указать тип соединения — мост, это в дальнейшем позволит подключаться к tello, используя сетевое соединение хоста под windows.



Процесс сборки ORB_SLAM3 в общих чертах был описан ранее в статье.
Но если коротко, то все выглядит примерно так:

history
1  sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $ (lsb_release -sc) main"> /etc/apt/sources.list.d/ros-latest.list'
    2  sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
    3  curl -sSL 'http://keyserver.ubuntu.com/pks/lookup?op=get&search=0xC1CF6E31E6BADE8868B172B4F42ED6FBAB17C654' | sudo apt-key add -
    4  sudo apt install curl
    5  curl -sSL 'http://keyserver.ubuntu.com/pks/lookup?op=get&search=0xC1CF6E31E6BADE8868B172B4F42ED6FBAB17C654' | sudo apt-key add -
    6  sudo apt-get update
    7  sudo nano /etc/apt/sources.list
    8  sudo apt-get update
    9  apt-cache policy | grep universe
   10  sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
   11  curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add -
   12  sudo apt update
   13  sudo apt install ros-noetic-desktop
   14  source /opt/ros/noetic/setup.bash
   15  echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc
   16  source ~/.bashrc
   17  sudo apt install python3-rosdep python3-rosinstall python3-rosinstall-generator python3-wstool build-essential
   18  sudo apt install python3-rosdep
   19  sudo rosdep init
   20  rosdep update
   21  sudo apt install ros-noetic-codec-image-transport
   22  sudo apt install ros-melodic-camera-info-manager-py
   23  sudo apt install ros-noetic-camera-info-manager-py
   24  sudo apt-get install ros-noetic-usb-cam
   25  cd ..
   26  ls
   27  sudo apt install python3-catkin-tools python3-osrf-pycommon
   28  mkdir -p ~/catkin_ws/src
   29  cd ~/catkin_ws/
   30  catkin_make
   31  source devel/setup.bash


cd catkin_ws/
107 cd src/
108 git clone --branch noetic --depth 1 github.com/ros-perception/vision_opencv.git
109 cp -r vision_opencv/cv_bridge ~/catkin_ws/src
110 rm -rf vision_opencv
111 git clone --recursive --branch ros --depth 1 github.com/stella-cv/stella_vslam_ros.git
112 cd ~/catkin_ws
113 catkin_make -DUSE_PANGOLIN_VIEWER=ON -DUSE_SOCKET_PUBLISHER=OFF
114 sudo apt install ros-noetic-pcl-ros
115 catkin_make -DUSE_PANGOLIN_VIEWER=ON -DUSE_SOCKET_PUBLISHER=OFF
116 source devel/setup.bash
117 catkin_make -DUSE_PANGOLIN_VIEWER=ON -DUSE_SOCKET_PUBLISHER=OFF
118 mc
119 cd…
120 git clone github.com/UZ-SLAMLab/ORB_SLAM3.git ORB_SLAM3
121 cd ORB_SLAM3
122 chmod +x build.sh
123 df -h
124 ./build.sh
125 ls
126 nano CMakeLists.txt
127 ./build.sh
128 ls
129 cd ~
130 git clone github.com/stevenlovegrove/Pangolin
131 cd Pangolin
132 ./scripts/install_prerequisites.sh recommended
133 cmake -B build -GNinja
134 cmake --build build
135 cmake --build build -t pypangolin_pip_install
136 cd…
137 wget github.com/Qengineering/Install-OpenCV-Raspberry-Pi-32-bits/raw/main/OpenCV-4-5-5.sh
138 sudo chmod 755 ./OpenCV-4-5-5.sh
139 ./OpenCV-4-5-5.sh
140 pip3 uninstall opencv-python
141 git clone gitlab.com/libeigen/eigen/-/archive/3.4.0/eigen-3.4.0.tar.gz
142 mkdir eigen
143 cd eigen/
144 wget gitlab.com/libeigen/eigen/-/archive/3.4.0/eigen-3.4.0.tar.gz
145 ls
146 tar –xvzf eigen-3.4.0.tar.gz
147 tar -xvzf eigen-3.4.0.tar.gz
148 ls
149 rm eigen-3.4.0.tar.gz
150 cd eigen-3.4.0/
151 ls
152 cd build_dir
153 mkdir build
154 cd build/
155 cmake
156 cmake.
157 cmake…
158 make install
159 sudo make install
160 cd ~
161 ls
162 cd opencv
163 ls
164 nano CMakeLists.txt
165 cd…
166 ls
167 nano OpenCV-4-5-5.sh
168 mc
169 uname -a
170 git clone github.com/opencv/opencv.git
171 mc
172 wget github.com/opencv/opencv/archive/refs/tags/4.5.5.tar.gz
173 tar -xvzf 4.5.5.tar.gz
174 cd opencv-4.5.5/
175 ls
176 mkdir -p build && cd build
177 cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local -DENABLE_CXX11=ON -DBUILD_DOCS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_JASPER=OFF -DBUILD_OPENEXR=OFF -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DWITH_EIGEN=ON -DWITH_FFMPEG=ON -DWITH_OPENMP=ON…
178 make -j4
179 make install
180 sudo make install
181 sudo apt install -y libatlas-base-dev libsuitesparse-dev
182 sudo apt install -y libgtk-3-dev
183 sudo apt install -y libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libavresample-dev
184 sudo apt install -y autogen autoconf libtool
185 cd ~
186 cd ORB_SLAM3/
187 sed -i 's/++11/++14/g' CMakeLists.txt
188 ./build.sh
189 nano build_ros.sh
190 mc
191 python3
192 python3.8
193 ./build_ros.sh
194 export ROS_PACKAGE_PATH=${ROS_PACKAGE_PATH}:/home/al/ORB_SLAM3/Examples_old/ROS/ORB_SLAM3
195 ./build_ros.sh
196 cd /home/al/ORB_SLAM3/Examples_old/ROS/ORB_SLAM3
197 ls
198 nano CMakeLists.txt
199 sed -i 's/++11/++14/g' CMakeLists.txt
200 nano CMakeLists.txt
201 cd ~
202 cd ORB_SLAM3/
203 ./build_ros.sh
204 cd…
205 git clone github.com/strasdat/Sophus.git
206 cd Sophus
207 mkdir build && cd build && cmake… && sudo make install
208 sudo apt install libfmt-dev
209 cmake… && sudo make install
210 mc
211 cd ~
212 cd ORB_SLAM3/
213 ./build_ros.sh
214 cd /home/pi/ORB_SLAM3/Examples_old/ROS/ORB_SLAM3
215 cd /home/al/ORB_SLAM3/Examples_old/ROS/ORB_SLAM3
216 nano CMakeLists.txt
217 cd ~
218 ./build_ros.sh
219 cd ORB_SLAM3/
220 ./build_ros.sh

Здесь важно дополнить, что если пользоваться командами установки opencv:

sudo apt-get install ros-noetic-cv-bridge
sudo apt-get install ros-noetic-vision-opencv

то в итоге будет установлена opencv4.2. И если нужна версия поновее, то opencv придется собирать из source и указанные команды не использовать.

И только после сборки opencv, положить в catkin пакет:

to catkin/src
git clone -b noetic https://github.com/ros-perception/vision_opencv.git
cd ..
catkin_make
rosdep update

В сборке ROS нод также поможет данная инcтрукция — issue.

В итоге catkin должен выглядеть примерно так:


*не обращаем внимание на allan_variance_ros и stella_vslam.

Также специально для tello желательно изменить ноду orb_slam3, чтобы дополнительно не перенаправлять траффик с камеры tello в ноду orb_slam3:

cd /home/al/ORB_SLAM3/Examples_old/ROS/ORB_SLAM3/src
nano ros_mono.cc
change to:
ros::Subscriber sub = nodeHandler.subscribe("/tello/image_raw"
nano ros_mono_inertial.cc:
ros::Subscriber sub_imu = n.subscribe("/tello/imu", 
ros::Subscriber sub_img0 = n.subscribe("/tello/image_raw",

Таким образом orb_slam3 будет сразу получать нужные сообщения от tello.

Если есть намерение использовать режим mono_inertial, то mono_inertial.cc также нужно будет изменить.

После изменений не забываем пересобрать ноды ros orb_slam3:
export ROS_PACKAGE_PATH=${ROS_PACKAGE_PATH}:/home/al/ORB_SLAM3/Examples_old/ROS/ORB_SLAM3
cd ~/ORB_SLAM3
./build_ros.sh

Среди многочисленных ошибок, в результате которых orb_slam3 может не собраться могут помочь следующие изменения:

nano /home/al/ORB_SLAM3/include/ImuTypes.h:
	#include <iostream>
/home/al/ORB_SLAM3/include/GeometricTools.h
	#include <iostream>


Нода ROS tello.


На github несколько проектов, посвященных данному вопросу.
Один из вариантов сборки выглядит так:

history
cd ~/catkin_ws/
   30  catkin_make
   31  source devel/setup.bash
   32  cd src
   33  git clone --recursive https://github.com/surfii3z/tello_driver.git
   34  cd ..
   35  catkin_make
   36  sudo apt install ros-noetic-camera-info-manager-py
   37  history
   38  source /opt/ros/noetic/setup.bash
   39  catkin_make
   40  cd src
   41  git clone https://github.com/ros-perception/image_common.git
   42  cd ..
   43  catkin_make
   44  sudo apt install ros-noetic-tello-driver
   45  source /opt/ros/noetic/setup.bash
   46  roslaunch tello_driver tello_node.launch
   47  roscd tello
   48  roscd tello_driver
   49  ls
   50  cd launch/
   51  ls
   52  roslaunch tello_driver.launch



Чтобы нода вела себя адекватно, необходимо прописать настройки, характерные tello в файл конфига:
nano /home/al/catkin_ws/src/tello_driver/cfg/960x720.yaml

960x720.yaml
image_width: 960
image_height: 720
camera_name: camera_front
camera_matrix:
  rows: 3
  cols: 3
  data: [929.562627, 0.000000, 487.474037, 0.000000, 928.604856, 363.165223, 0.000000, 0.000000, 1.000000]
distortion_model: plumb_bob
distortion_coefficients:
  rows: 1
  cols: 5
  data: [-0.016272, 0.093492, 0.000093, 0.002999, 0.000000]
rectification_matrix:
  rows: 3
  cols: 3
  data: [1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000]
projection_matrix:
  rows: 3
  cols: 4
  data: [937.878723, 0.000000, 489.753885, 0.000000, 0.000000, 939.156738, 363.172139, 0.000000, 0.000000, 0.000000, 1.>


Здесь нашли свое отражение параметры камеры, которые от tello к tello не сильно отличаются и дополнительно калибровать камеру нет необходимости.

Эти же параметры необходимо внести уже для целей orb_slam3:
nano /home/al/ORB_SLAM3/Examples/Monocular/TUM1.yaml

TUM1.yaml

%YAML:1.0

#--------------------------------------------------------------------------------------------
# Camera Parameters. Adjust them!
#--------------------------------------------------------------------------------------------
File.version: "1.0"

Camera.type: "PinHole"

# Camera calibration and distortion parameters (OpenCV) 
Camera1.fx: 929.562627
Camera1.fy: 487.474037
Camera1.cx: 928.604856
Camera1.cy: 363.165223

Camera1.k1: -0.016272
Camera1.k2: 0.093492
Camera1.p1: 0.000093
Camera1.p2: 0.002999
Camera1.k3: 0.000000

# Camera frames per second 
Camera.fps: 30

# Color order of the images (0: BGR, 1: RGB. It is ignored if images are grayscale)
Camera.RGB: 1

# Camera resolution
Camera.width: 960
Camera.height: 720

#все остальные параметры не меняем!


Также необходимо изменить саму ноду tello:

nano /home/al/catkin_ws/src/tello_driver/launch/tello_node.launch

c  <node pkg="image_transport" name="image_compressed" type="republish" args="raw in:=image_raw compressed out:=image_raw" /> 
на
<node pkg="image_transport" name="image_compressed" type="republish" args="h264 in:=image_raw raw out:=image_raw" />


Запускаем!


Если вы используете виртуальную машину, на которой все собирали, то перед запуском придется отключиться от сети ethernet и подключиться через wifi к tello.

Так как виртуальная машина имеет выход в сеть через хост под windows, она «подхватит» wifi соединение и оно будет доступно для подключения к tello.



На самой виртуальной машине необходимо будет переподключиться к сети:



После подключения по wifi к tello, виртуальной машине будет назначен адрес 192.168.10.*:



Далее, на самой виртуальной машине в трех разных терминалах запустим:


1.
bash -c "source /opt/ros/noetic/setup.bash; roscore"
2.
bash -c "source /home/al/catkin_ws/devel/setup.bash;cd /home/al/ORB_SLAM3/Examples_old/ROS/ORB_SLAM3;
./Mono /home/al/ORB_SLAM3/Vocabulary/ORBvoc.txt /home/al/ORB_SLAM3/Examples/Monocular/TUM1.yaml"
3.
bash -c "source /home/al/catkin_ws/devel/setup.bash;roslaunch tello_driver tello_node.launch"

Если все прошло штатно, то увидим привычное окно orb_slam3:



Чтобы события начали развиваться, необходимо немного подвигать tello, и orb_slam начнет «рисовать картинку»:



В завершение в качестве бонуса предлагаются параметры imu tello, которые удалось снять в результате калибровки с помощью пакета allan_variance_ros. В ходе калибровки tello послушно записывал rosbag на протяжении 3 часов непрерывной работы квадрокоптера (интересно, сколько бы штатных батарей понадобилось ?):

tello imu:
#Accelerometer
accelerometer_noise_density: 0.0017503364530909718
accelerometer_random_walk: 0.00001674910799299899

#Gyroscope
gyroscope_noise_density: 0.0008258200194467703
gyroscope_random_walk: 0.000019817464724244252


Данные параметры пригодятся для интеграции в режиме mono-inertial.

Комментарии (2)


  1. v1000
    00.00.0000 00:00
    +2

    там еще вроде моторы дешевые на щетках, которые становятся расходниками.


  1. buldo
    00.00.0000 00:00

    Интересно. Кажется для варианта "носить коптер на руках" выходит примерно как совместимый с ardupilot полетник от матек + малина + камера.