Raspberry FPiV – Flight 3 – Recording on the Ground


After much trawling through the forums, I found a way to record the video stream at the receiving end using gst-launch-1.0 in such a way that it can be converted to a playable format later on without re-encoding and the resulting loss of quality.  Eventually, replacing gst-launch-1.0 with a dedicated gstreamer application would allow a valid video file to be recorded straight from the stream without the current post processing. This flight also included a test of the external amplified antenna for the Ultimate GPS Breakout board. The results were disappointing, not attaining sufficient accuracy for the desired application. The flight was cut short due to a combination of high, turbulent wind and dumb thumbs, but was long enough to get meaningful results. You need to watch the video at 720p for a meaningful comparison. Please bear in mind that the video has been re-encoded at least once, possibly three times between the Pi and your browser. https://www.youtube.com/watch?v=eCazn-JbR_0

Hardware Setup

The amplified GPS antenna comes with 5 metres of cable and a heavy magnet.  I shortened the cable and removed the magnet, but the parts were still unwieldy when strapped to the top of the plane.  Hardware wise this was the only addition to the previous test. 2014-04-25 13.15.03

 Software Setup

I had already generated and swapped ssh keys between the Pi and the laptop to remove the need to enter a password when connecting. While I’ve been testing different GPS setups , I’ve started gpsd using a small shell script

echo Starting gpsd
sudo gpsd /dev/ttyAMA0 -n -F /var/run/gpsd.sock

I want to use the current time and date for the video and gpx file names.  As the Pi does not have a real time clock, I set the time from GPS using a  script based on one I found at  http://blog.petrilopia.net

sudo date -s '01/01/2014 00:01'
sleep 1
GPSDATE=`gpspipe -w | head -10 | grep TPV | sed -r 's/.*"time":"([^"]*)".*/\1/' | head -1`
sudo date -s "$GPSDATE"

Next I run cgps to check the GPS accuracy.  Once it stops improving I exit cgps and run the third script to start gps logging and record the video stream.  The video is recorded as the raw h264 stream with a Tx (Transmitter) suffix.

cat $0

# Duration in milliseconds. Use 0(Zero) for continuous
NOW=`date +%Y%m%d%H%M%S`
gpxlogger -i 2 -f $NOW.gpx &
IP=$(ip -o addr show wlan0 | sed -n 's/.*inet \([0-9.]*\)\/.. .*/\1/p')

/opt/vc/bin/raspivid -t $DURATION -w $WIDTH -h $HEIGHT -fps $FRAMERATE -b $BITRATE -n -o - | tee $FILENAME | gst-launch-1.0 -v fdsrc ! h264parse ! rtph264pay config-interval=1 pt=96 ! gdppay ! tcpserversink host=$IP port=$PORT

Finally, back on the laptop, in a new terminal window, I run a script to capture and display the video stream.  The h264 file is multiplexed (muxed) into an mpeg transport stream (ts) container with a Rx (Receiver) suffix.

# Read the Settings file
source ./settings.conf

# Set file name from current time
NOW=`date +%Y%m%d%H%M%S`

# Read the stream.
gst-launch-1.0 -v tcpclientsrc host=$IP port=$PORT ! \
 gdpdepay ! rtph264depay ! \
 h264parse config-interval=96 ! \
 tee name=t ! queue ! \
 video/x-h264, framerate=25/1 ! avdec_h264 ! videoconvert ! autovideosink sync=false t. ! \
 queue ! mpegtsmux ! filesink location=$FILENAME

# Try to copy the file from SD card to Hard Disk
if [ ! -d $TARGETDIR ]; then
 sudo mount /dev/sdb4 /mnt

Here is a sample settings.conf

export IP=
export PORT=5000
export FRAMERATE=25
export TARGETDIR=/mnt/home/user

The Flight

When I arrived at the field the wind felt to be blowing at a constant 10 mph.  In the short time it took to get everything ready it had started gusting much harder.  Having driven to the field and got everything setup I was determined to fly so opened the throttle and gave it a good chuck. My first realisation was that the wind was stronger than anything I had flown in before.  In order to get the aircraft to track up the field and not be blown out the back, I had to point it 20 to 30 degrees past the desired direction of flight.  Also, as the aircraft got further up the field and closer to the trees, the turbulence made it harder to control.  Eventually, it got bucked around to the point I lost orientation, dumb thumbed the rudder flipping it upside down and I wasn’t able to recover it before it hit the ground. When I checked later, the met office were quoting 26 mph gusts.

The Aftermath

The previous months rain had softened the ground enough that the aircraft nose was stuck in three or four inches with no apparent damage.  The rubber bands had separated, releasing the wings.  Any electronics that weren’t screwed down were scattered around the crash site and given a liberal coating of mud. Everything was dismantled and cleaned in fresh water, then left to dry.   When I did reconnect everything, it all worked.  The only problem was that camera now has a green tint.  I suspect that that the mud has abraded the lens coating, either on impact or during cleaning.  As they are cheap I bought a new one.


I was worried that the crash would have lost or corrupted the on-board video recording.  As it turned out, only the last few seconds of the flight were lost, as you can see in the video.  After collecting the scattered components, I found the X terminal on the laptop reporting that the SD card had become read only.  It was still receiving and recording a video stream, although this was mostly a totally brown frame which turned to a greeny orange when I removed most of the mud.


I’ll cover the GPS first as it’s going to be short. The results using the larger amplified antenna were better, but still not good enough.  There seems to be either a lag or an offset in the computation.  The two images below show the problem.  For the next flight I’m going to use the CRIUS CN-06 V2 U-blox GPS module. Flight3-CrashSite Flight3-CricketSquare


The video recorded on the Pi (Tx) was copied to a Windows PC using WinSCP.  Then I used MP4BoxGUI to mux it into a MP4 file.  I have not had any problems using the generated file. With the video recorded on the laptop (Rx) as a transport stream, the first task was to convert it into an mp4. The following script takes the file name as an argument and creates two new videos.  This need to be run on a machine using Gstreamer version 1.2 (Check using gst-launch-1.0 –version).

echo .
echo Remux
echo .
gst-launch-1.0 -v filesrc location=$1 ! tsdemux ! h264parse ! video/x-h264,framerate=25/1 ! mp4mux ! filesink location=$1.remux.mp4
echo .
echo Re-encode
echo .
gst-launch-1.0 -v filesrc location=$1 ! tsdemux ! h264parse ! video/x-h264,framerate=25/1 ! avdec_h264 ! videoconvert ! x264enc bitrate=2500 ! mp4mux ! filesink location=$1.reenc.mp4 

The first gstreamer pipeline (Remux), simply extracts the h264 video from the transport stream container and them multiplexes it into an mp4 container.  The h264 stream is unchanged, so there is no loss of video quality.  To make this file viewable on Windows required a couple of extra steps.  With the file copied on to the Windows PC I used MP4BoxGUI to demux and extract the h264 stream (again) and then to Mux it back into an MP4 file.  This new file was playable in Windows media Player. The second gstreamer pipeline (Re-encode), re-encodes the video as a new h264 file and multiplexes it into an mp4 container.  While re-encoding has to reduce the picture quality, it is not obvious without close inspection.  I use the re-encoded video in Sony Movie Studio 11.0, which had trouble reading the first remuxed file.  I also had to manually set the frame rate in Sony Movie Studio 11 to 25 fps as by default it was using 29.97 fps making it impossible to sync the Tx and Rx videos together.


The video posted on Youtube shows the Tx and Rx videos side by side.  They are fully synced and without a gap between I don’t think you can spot a join or see any difference in video quality.  Although a bit of a faff, for now I have a working pipeline to record usable video on the ground. As for the GPS, the search goes on.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s