Telemetry OSD for wifibroadcast
This post shows how to add an overlay with telemetry information onto a video stream
Since the last flyaway of my quad having a telemetry link that transmits GPS coordinates was high on my wish-list. Wifibroadcast was prepared long time ago to transfer a second data stream in parallel to the video data by defining ports. But until now I did not make use of it. You can see a video of the OSD in action here:
This post describes how to set up the OSD display. Additionally, two changes required to wifibroadcast are described before the actual OSD stuff.
My quad uses a Naze32 flight controller that is able to provide FrSky telemetry data over a serial link. The serial port of the Naze32 is connected to a USB2SERIAL converter that is plugged into the tx Raspberry. The telemetry data is then transmitted using wifibroadcast over a second port in parallel to the video. On the receiving Raspberry the telemetry data is received, parsed and drawn onto the screen.
Wifibroadcast minimum packet length
Telemetry data is very different to video data in that it consists of very small packets. For example, most of the FrSky packets are only 5 bytes long. Using the default settings of tx this would lead to a single packet being sent for each small telemetry data unit. This of cause would create a high overhead since the ratio of payload to required header data is very low. To avoid this issue I added a command line parameter -m that can be used to define a minimum payload length. If given, tx waits until it has captured the minimum number of bytes and only then sends a packet.
Several tx instances in parallel
As said above wifibroadcast had the “port” feature for quite some time. The idea was to start several instances of tx, each with a different -p parameter. I used this method for my first telemetry experiments but noticed something odd: Whenever I started a second tx instance in parallel to the video tx process, the video tx was influenced. This was even the case when the second tx did not send any data at all. Quite strange. The result of this was that the video transmission was less fluid and stuttering a bit. Quite a high price for just a bit of telemetry data…
I basically had two options: Trace the cause of this issue in the kernel or adapt tx so that a single instance is able to send several data streams. I went for the latter one because I think it required less effort.
The route I went for was that tx got a new parameter -s that describes the number of parallel streams that shall be transmitted. If this parameter is omitted then tx behaves just like before, transmitting a single stream that is read from standard input. If however two or more streams are requested, tx changes the way it works. It then creates named FIFOs under /tmp. For example, if -s 2 is given, tx creates two named FIFOs called /tmp/fifo0 and /tmp/fifo1. Everything that gets written into fifo0 will be transported over the first port and everything written into fifo1 gets transported over the second port. Quite simple. The actual port number can be influenced by the -p parameter. It serves as an offset. Assuming that -p 100 is given, then fifo0 sends on port 100 and fifo1 on port 101.
The next section will show a usage example of this new mode that should make things clearer.
This feature is still not in the master branch since I had not yet the time to test it well. But after my first successful flight I will merge it into the master.
Putting things together
These commands assume that you have already installed wifibroadcast (as described here).
First, change to the “tx_fifo_input” branch in wifibroadcast:
cd cd wifibroadcast hg pull hg update tx_fifo_input make
Next, start a tx instance in the background with a retransmission block size of 4, a minimum packet size of 64 bytes and two parallel streams:
sudo ./tx -b 4 -m 64 -s 2&
All that is needed is to connect the data sources to the named FIFOs:
sudo su stty -F /dev/ttyUSB0 -imaxbel -opost -isig -icanon -echo -echoe -ixoff -ixon 9600 #set up serial port raspivid -ih -t 0 -w 1280 -h 720 -fps 30 -b 4000000 -n -g 60 -pf high -o - > /tmp/fifo0 & #video cat /dev/ttyUSB0 > /tmp/fifo1 & #telemetry
Now video and telemetry data is transmitted in parallel.
The video reception can be left unchanged (refer to here) and should work out of the box.
To get the OSD working, we first need to check out and build my OSD project:
cd hg clone https://bitbucket.org/befi/frsky_omx_osd cd frsky_omx_osd make
And finally you need to pipe the telemetry data into the OSD viewer (note the -p 1 for the telemetry port):
cd cd wifibroadcast sudo ./rx -p 1 -b 4 wlan0 | /home/pi/frsky_omx_osd/frsky_omx_osd /home/pi/frsky_omx_osd
Of cause, you can also save the telemetry data using the “tee” command.
In case you just want to test the OSD without the whole wifibroadcast stuff there is a FrSky telemetry log included in the repository:
./frsky_omx_osd . < testlog.frsky
The OSD works well for me. But be warned: Things are still a bit hacky around here. I wouldn’t guarantee that my FrSky protocol interpretations are always right. No wonder seeing how that protocol is designed. It is a perfect example of what happens if companies outsource their coding tasks to mental institutions 😉
It should be easy though to replace the frsky.c parser with a different one (also for a different protocol). Volunteers are welcome 🙂