Monthly Archives: June 2014

UAV architecture

Video streaming on the raspberry pi finally works. Time to move on to the actual UAV code.

So far I have this figured out:
There are 4 major parts that I need to develop:
1. IO Board. This runs on the crius board and is responsible of reading all the sensors, computing the local frame of reference and controlling the motors using a rate pid.
2. Brain. This runs on the RPI and talks to the IO Board. It does dead reckoning and all the high-level AI like assists (avoid ground, stay in perimeter, etc), camera streaming, return home and scripting
3. GroundStation. Runs on the laptop/tablet and talks to the Brain through TCP (comms)/UDP (streaming). It acts as a remote control + setup software.
4. Simulation. This can replace the IO board with a bullet physics simulation. It talks to the Brain and simulates everything the IO_Board does – to allow me to test the brain without actually crashing any quadcopters.
So far I have some of the brain code started:
– IO_Board class that talks to the IO Board or simulation
– Video Streamer
– Camera code, working and tested
– TCP comm channels
The Ground station also has some code done since the AVR tests a few months back but it needs to be adapted to the new brain code:
– Calibration code
– Diagnostics for the AHRS and dead reckoning
The Simulator is mostly done but for AVR. Needs to be adapted to the brain to mimick the IO Board. It can simulate the motors +  propellers, accelerometer and gyro and air drag.

Hello Linux

After struggling for 2 weeks to get a good windows cross-compiler for the raspberry pi, I decided to give ubuntu another chance. My previous attempts have always ended after failing to find a good C++ IDE to replace MSVC.

This time however I gave Qt Creator a chance and I must say I love it. So far it replaces perfectly my VS2013 + VisualAssist combo and together with clang it gives me the best C++11 support money can buy – for free.
I think this round will last for a long while.

Compiling boost 1.55 with C++11 support on the Raspberry PI

First a bit of background.
I’ve decided to use a raspberry pi model A as the brain in my quadcopter. For video streaming I’ll use it’s video encoding support (thanks to the VideoCore IV and OpenMAX) and it will communicate through serial with the Crius AIOP board I already have.
But first I have to prepare my environment with C++11 support using GCC 4.8.2, boost 1.55 and a windows cross compiler. I used this tutorial for getting my cross compiler ready.
To overwrite all the libs to the rpi ones I used this small lua script which enumerates all the files in a folder and then replaces each one with the corresponding file from a different folder:
You need the latest LuaForWindows to run the lua script.

 local dir = require( "pl.dir" )  
 local file = require( "pl.file" )  
 local path = require( "pl.path" )   
 local src_files = {}  
 function read_src_files(root)  
      local files = dir.getallfiles(root)  
      for i=1,#files do  
           local file = path.basename(files[i]):upper()  
           src_files[file] = files[i]  
      end  
 end  
 function replace_all(root, pattern)  
      local files = dir.getallfiles(root, pattern)  
      --print(files)  
      for i=1,#files do  
           --print(files[i])  
           local dst_file = files[i]  
           local folder = path.dirname(dst_file)  
           local filename = path.basename(dst_file):upper()  
           local found = src_files[filename] ~= nil  
           print(found, dst_file, folder)  
           if found then  
                dir.copyfile(src_files[filename], dst_file)  
           else  
                --dir.movefile(dst_file, dst_file..'_notfound')  
           end  
      end  
 end  
 read_src_files("rpi-libs")  
 replace_all("linaro-4.8.2", "*.a")  
 replace_all("linaro-4.8.2", "*.o")  
 replace_all("linaro-4.8.2", "*.so")  
 replace_all("linaro-4.8.2", "*.so*")  

Now back to compiling boost. Remember that you need GCC >= 4.7 for this
1. Download the 1.55 tar.gz
2. Uncompress it with tar-xvf boost…
3. cd to the boost folder
4.  ./bootstrap.sh –with-libraries=date_time,exception,filesystem,program_options,signals,system
Add the libs that you need or remove the –with-libraries if you want all the libs
5. ./b2 cxxflags=”-std=c++11″ link=static thread=multi      and wait for a billion hours
6. [for your cross compiler] Copy the new libs from boost/stage/libs to your windows machine
7. sudo b2 install

New Frsky telemetry protocol and Ground Station software

This project allows you to send telemetry data from a megapirate board through a 2-way frsky link back to the Ground station TX, where it gets decoded and merged over the video feed.

I ordered a new frsky telemetry rx/tx from hobbyking a month back and while waiting for it to be shipped – 3 weeks to spain – I started reading about the telemetry protocol they use.
http://hobbyking.com/hobbyking/store/__14356__FrSky_D8R_II_PLUS_2_4Ghz_8CH_Receiver_with_Telemetery.html?strSearch=frsky%20d8r

It seemed like such a useful thing to be able to send data back to the GS. My first thought was to remove the OSD form the quad and put it in the ground station. I’d save a few grams of weight and I would get all the range of the frsky radio instead of the measly ~200m range I’m getting with my 5.8Ghz video tx (in the meantime I improved this with a 4-turn helical).
The only thing I had to do was plug serial 3 with the mavlink data stream from my crius aiop into the frsky receiver on the quad and get it from the th9x, plug it into the minimosd in the GS and voila! a more reliable OSD.

What I didn’t know was:
1. The bandwidth is ~1200 bytes per second. This means 40bytes for a 30hz refresh rate. Way too low for mavlink
2. The frsky tx and rx use 232 levels while aiop and minimosd uses TTL. This requires 2 level inverters – and I only ordered one from HK.

The first problem could be solved with two mavlink <-> frsky protocol converters and there are a few projects for this (http://diydrones.com/profiles/blogs/adding-more-features-to-ioboard).
The other alternative was to write a new protocol that compresses the data to fit in the 1200bps limit and decode it at the GS end.

So on the quad, I have this: crius serial 3 tx pin (yellow) -> ttl to 232 converter (blue) -> frsky receiver tx pin (red)

The ttl to 232 converter is this one: http://www.hobbyking.com/hobbyking/store/__16672__frsky_telemetry_reciever_upgrade_usb_serial_lead_interface.html

I had to disable the serial3 mavlink from mgapirate and plug my own function in the update loop.
To save bandwidth, the info is split in packets (motors, altitude, rc inputs etc) and each packet is sent only if it changed (so delta compressed). Together with quantization, I managed to pack everything I wanted (except GPS – still waiting for it to arrive).
The result is real-time update for the important things – altitude, heading, motors (to graph temperatures). The refresh rate depends on how much things change in time – and it turns out that most data is pretty stable so I usually get 15-20Hz – way more than my initial estimates of 2-5Hz that I would get without the compression.

For the second problem – I found a way to hack into the TX and get TTL levels out of it directly (http://projects.onomato.biz/projects/android-dash/wiki/BlueTooth). Then connect this to a serial bluetooth adapter and voila – telemetry straight to my laptop or phone.
With a small QT+opencv application I can have the camera feed on my laptop combined with the rendered telemetry values in a nice HUD.

The app supports 2 deinterlace methods (bob + some other type that I forgot) and recording using a user chosen codec.
The interaction happens with shortcuts – no menus for now – and is pretty crude. I’ll soon add support for touchscreen as I got a HP Omni tablet and that will replace my laptop in the GS. Battery life is great on the tablet (6-9 hours) and the CPU is way stronger than to my old eeepc 901.

To use:
1. Download megapirate 3.0.1 R3
2. Apply my patch. If you want to do this manually over another revision you have to:

  • Disable the mavlink from serial3. This means to comment all gcs3. instances (except for the one that sets non-blocking mode)
  • Add the code surrounded by // CT protocol v 1.0 in the GCS_Mavlink.pde file
  • Call the ct_process() function from static void gcs_data_stream_send(void).

3. Download the fpv-monitor code:
4. Make sure you have QT 5.2.0, opencv and boost 1.55 (header + binaries) installed
5. Compile using VS2012 (some C++11 requires it)
6. Run as fpx-monitor comX Y – where x is the com port and y is the camera index (0 – built in camera, 1 – receiver)

After everything compiles, run it with these params:
fpv-monitor com5 0
even if the com port doesn’t exist, it should show the feed from your camera/easycap:

Of course, this assumes you have a easycap with the drivers installed.

The shortcuts are:
F11 – fullscreen
F5 – start/stop capture
D – cycle deinterlace methods
R – smooth video resize (more CPU)
CTRL-0 – use camera index 0
CTRL-1 – use camera index 1

Here’s how it works:

App source code:
https://code.google.com/p/fpv-monitor/
In the megapirate/patches folder you’ll find the patch + already patched file for 3.0.1R3

Good luck.