RPI2 configuration.
1.0 Image Installation
- Install PREEMPT_RT image into RPI2. Press HERE to open emlid download section. Use program such as Image Writer to install image to MicroSd card.
- Connect RPI2 using SSH. ( e.g putty, Bitvise Tunnelier or any ssh program you want)
- We need to update our source list with the following command.
- sudo apt-get update
1.1 Basic RPI2 Settings
Run raspi-config
- Set your desired user settings such as language etc.
- You could try to set overclocking to Pi2 1000MHz, this will increase gStreamer quality drastically, but unfortunately someone (including myself) has some issues running Pi2 overclock with APM software.
Guys at Emlid.com are working to get this solved.
Use None/700Mhz to be safe.
!Note: See THIS thread at Emlid.com if any issues like “AK8963: bad DEVICE ID” when overclocking,
1.1 RPI power source
We need to attach more power to the RPI2 USB, using a 5v 5A BEC. This will supply our 4G modem with enough power.
All onboard equipment are powered from the same battery source.
2.0 gStreamer-1.0 Installation
I recently manage to compile gstreamer v1.4. See main discussion thread Here
Version 1.4 are not required for this tutorial, so we just use v1.0 for the sake of convenience.
Type this line to install gstreamer1.0
- sudo apt-get install gstreamer1.0
Save attached(in bottom of this article) gstreamer.sh file to RPI or copy paste content bellow.
NOTE! Change the IP to match your GCS ip or dyndns. You may also try with different framerate and bitrate. Try to find a setting you are satisfied with.
- #!/bin/bash
- #320x240
- #360x288
- #640x480
- #704x576
- WIDTH=640
- HEIGHT=480
- ip=GCS_IP
- v4l2-ctl --set-fmt-video=width=$WIDTH,height=$HEIGHT,pixelformat=1
- v4l2-ctl -i 1
- gst-launch-1.0 -v \
- rtpbin name=rtpbin v4l2src device=/dev/video0 \
- ! video/x-raw,width=$WIDTH,height=$HEIGHT,framerate=15/1 \
- ! queue \
- ! omxh264enc target-bitrate=500000 control-rate=1 \
- ! "video/x-h264,profile=high" \
- ! h264parse \
- ! queue max-size-bytes=10000000 \
- ! rtph264pay pt=96 config-interval=1 \
- ! rtpbin.send_rtp_sink_0 rtpbin.send_rtp_src_0 \
- ! udpsink port=5000 host=$ip ts-offset=0 name=vrtpsink rtpbin.send_rtcp_src_0 \
- ! udpsink port=5001 host=$ip sync=false async=false name=vrtcpsink udpsrc port=5000 name=vrtpsrc \
- ! rtpbin.recv_rtcp_sink_0
Remember to set permission to file,
- chmod 755 gstreamer.sh
To run gstreamer script, type this;
Client. Windows or unix.
- sudo sh gstreamer.sh
Get the gstreamer installation package for windows HERE
Install the package and then navigate to the installation bin directory. e.g gstreamer\1.0\x86\bin
Then open windows command prompt in that directory. left shift + right click. "Open command line here".
Then type this syntax to start gstreamer to listen for any video stream at port 5000.
If your RPI are streaming, you should get a picture right away.
- gst-launch-1.0 -v udpsrc port="5000" caps="application/x-rtp,media=(string)video,
- clock-rate=(int)90000,encoding-name=(string)H264,payload=(int)96,ssrc=(uint)237526004,
- clock-base=(uint)1584170994,seqnum-base=(uint)42626" ! rtph264depay ! decodebin!
- autovideosink -v
VLC
If you don`t have the VLC installed, you can get it HERE
Save the attached(In the Bottom of this article) vlc.sdp and run it. 3.0 UQMI 4G integration
UQMI (Supports 4G LTE) Read discussion thread HERE
Tested and working on RPI 2.Install required dependencies:
- sudo apt-get update
- sudo apt-get upgrade
- sudo apt-get install usb-modeswitch
- sudo apt-get install cmake
- sudo apt-get install dh-autoreconf
- sudo apt-get install dnsutils
DIR /home/pi*** installing json-c ****** Installing libubox ****
- wget https://s3.amazonaws.com/json-c_releases/releases/json-c-0.12.tar.gz
- sudo tar -xvf json-c-0.12.tar.gz
- cd json-c-0.12
- sed -i s/-Werror// Makefile.in && ./configure --prefix=/usr --disable-static && make -j1
- su
- make install
- cd ..
Then git, compile and install uqmi
- git clone https://github.com/UAVmatrix/libubox.git libubox
- cd libubox
- cmake CMakeLists.txt -DBUILD_LUA=OFF
- make
- sudo make install
- mkdir -p /usr/include/libubox
- cp *.h /usr/include/libubox
- cp libubox.so /usr/lib
- cp libblobmsg_json.so /usr/lib
- ldconfig
- cd /home/pi
- sudo git clone git://nbd.name/uqmi.git
- cd uqmi
- sudo cmake CMakeLists.txt
- sudo make install 3.1 Autoconnection of LTE if loss of signal. (UPDATE 13.05.2015)
This section will explain autoconnection of LTE 4G if loss of signal. We need to create crontab job that checks every 15sec if RPI is online, and if not reconnect.
We also needs to change the way APM streams UDP packets. Normally we just type UDP:GCS_IP:port, but this wont work after wwan0 ( LTE USB Modem) is re-iniziated. we need to stream our packets to localhost and then use udp_redirect script to forward packets to GCS.
First we are going to create "checkifonline" script.Then copy and paste code bellow.
- sudo vi checkifonline.sh
This script will check if our RPI is online and if not, re-connect our LTE modem
Change the green fields to match your setting.
Remember to set permission
- #!/bin/bash
- #Create lock file
- LOCKFILE=/tmp/lock.txt
- if [ -e ${LOCKFILE} ] && kill -0 `cat ${LOCKFILE}`; then
- echo "This script is already running"
- exit
- fi
- # make sure the lockfile is removed when we exit and then claim it
- trap "rm -f ${LOCKFILE}; exit" INT TERM EXIT
- echo $$ > ${LOCKFILE}
- #let`s ping google.
- if ! wget -q --tries=10 --timeout=20 --spider http://google.com
- then
- sleep 1
- #let`s ping google again to doublecheck that RPI is offline.
- if ! wget -q --tries=10 --timeout=20 --spider http://google.com
- then
- sudo killall -9 uqmi
- sudo killall -9 dhclient
- sudo uqmi -d /dev/cdc-wdm0 --set-device-operating-mode shutting_down
- sleep 30
- sudo uqmi -d /dev/cdc-wdm0 --stop-network 4294967295 --autoconnect
- sleep 2
- sudo uqmi -d /dev/cdc-wdm0 --network-register
- sleep 2
- sudo uqmi -s -d /dev/cdc-wdm0 --start-network YOUR_APN --keep-client-id wds --autoconnect &
- echo "Restartet Modem"
- sleep 8
- sudo dhclient -v wwan0
- sleep 5
- else
- echo "RPI Online"
- fi
- else
- echo "RPI Online"
- fi
- #remove LockFile
- rm -f ${LOCKFILE}
Let`s add this script to crontab
- sudo chmod 755 checkifonline.sh
add these line to the bottom of the file
- sudo crontab -e
This will run our checkifonline script every 15sec.
- * * * * * /home/pi/./checkifonline.sh &
- * * * * * sleep 15; /home/pi/./checkifonline.sh &
- * * * * * sleep 30; /home/pi/./checkifonline.sh &
- * * * * * sleep 45; /home/pi/./checkifonline.sh &
next we need to create udp_redirect program.
Make another script
Copy paste the code bellow.
- sudo vi udp_redirect.c
Set permission to file
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- int main(int argc, char *argv[]) {
- if (argc!=3 && argc!=5) {
- printf("Usage: %s our-ip our-port send-to-ip send-to-port\n",argv[0]);
- printf("Usage: %s our-ip our-port # echo mode\n",argv[0]);
- exit(1);
- }
- int os=socket(PF_INET,SOCK_DGRAM,IPPROTO_IP);
- struct sockaddr_in a;
- a.sin_family=AF_INET;
- a.sin_addr.s_addr=inet_addr(argv[1]); a.sin_port=htons(atoi(argv[2]));
- if(bind(os,(struct sockaddr *)&a,sizeof(a)) == -1) {
- printf("Can't bind our address (%s:%s)\n", argv[1], argv[2]);
- exit(1); }
- if(argc==5) { a.sin_addr.s_addr=inet_addr(argv[3]); a.sin_port=htons(atoi(argv[4])); }
- struct sockaddr_in sa;
- struct sockaddr_in da; da.sin_addr.s_addr=0;
- while(1) {
- char buf[65535];
- int sn=sizeof(sa);
- int n=recvfrom(os,buf,sizeof(buf),0,(struct sockaddr *)&sa,&sn);
- if(n<=0) continue;
- if(argc==3) { sendto(os,buf,n,0,(struct sockaddr *)&sa,sn);
- } else if(sa.sin_addr.s_addr==a.sin_addr.s_addr && sa.sin_port==a.sin_port) {
- if(da.sin_addr.s_addr) sendto(os,buf,n,0,(struct sockaddr *)&da,sizeof(da));
- } else {
- sendto(os,buf,n,0,(struct sockaddr *)&a,sizeof(a));
- da=sa;
- }
- }
- }
Then we compile the file we just created.
- sudo chmod 755 udp_redirect.c
Now you should have a file named udp_redirect in /home/pi
- sudo gcc -o udp_redirect udp_redirect.c
Finally we are going to make udp-send.sh script. This scripft will find GCS ip address and forward UDP trafic from 127.0.0.1( localhost) to your GCS.Copy paste the code bellow
- sudo vi udp-send.sh
Note! - Remeber to change the APM start line in ArduPilot.sh as described in section 4.0 From:
- #!/bin/bash
- ip=`dig +short YOUR_GCS_DNS`
- echo $ip
- /home/pi/udp_redirect 0.0.0.0 14550 $ip 14550 &
To
- sudo ArduPlane -A udp:$ip:14550
4.0 APM installation.
- sudo ArduPlane -A udp:127.0.0.1:14550
All documentation is provided at Emlid.com, i would recommend to see theirs instructions.
After successfully installed APM, make another script which just fires ArduPilot software.sudo vi Ardupilot.sh
Copy paste code bellow. Change code to mach you airframe and port
!NOTE, If you are going to use Autoconnect features as described in section 3.1, you need to change the APM start line to sudo ArduPlane -A udp:127.0.0.1:14550Set permission to file
- #!/bin/bash
- ip=`dig +short YOUR_DynDns_ADRESS`
- sudo ArduPlane -A udp:$ip:14550
Now test that ArduPilot is working properly.
- sudo chmod 755 ArduPilot.sh
5.0 RPI startup and usage of installed code.Now you should have two files located in /home/pi ( gstreamer.sh, ArduPilot.sh)
- sudo sh ArduPilot.sh
I have made a startup script which calls all the necessary programs in correct order.
( Also see attched runCode.sh in the bottom)sudo vi runCode.sh
Copy paste code bellow.
Change the yellow fields to mach yours. You will need to contact your operator to get correct APN name.
Telenor, Norway using; internet.publicSet Permission
- #!/bin/bash
- function CheckOnline {
- SERVICE='uqmi'
- if ps ax | grep -v grep | grep $SERVICE > /dev/null
- then
- echo "$SERVICE service running, everything is fine"
- wget -q --tries=10 --timeout=20 --spider http://google.com
- if [[ $? -eq 0 ]]; then
- echo "Online, starting APM"
- ArduPilot
- sleep 1
- else
- echo "4G Offline"
- fi
- else
- echo "$SERVICE is not running"
- echo "Check if RPI is online anyway"
- wget -q --tries=10 --timeout=20 --spider http://google.com
- if [[ $? -eq 0 ]]; then
- echo "RPI is Online, starting APM"
- ArduPilot
- sleep 1
- else
- echo "RPI Offline"
- uqmi
- fi
- fi
- }
- function gstreamer {
- pidof gst-launch-1.0 >/dev/null
- if [[ $? -ne 0 ]] ; then
- sudo sh /home/pi/gstreamer.sh &
- sleep 5
- pidof gst-launch-1.0 >/dev/null
- if [[ $? -eq 0 ]] ; then
- echo "gStremer Started"
- else
- echo 'Could`t start gStreamer'
- fi
- else
- echo "gStremer already running"
- fi
- }
- function uqmi {
- sudo uqmi -d /dev/cdc-wdm0 --stop-network 4294967295 --autoconnect
- sleep 2
- if ! sudo uqmi -s -d /dev/cdc-wdm0 --get-data-status | grep '"connected"' > /dev/null; then
- sudo uqmi -d /dev/cdc-wdm0 --stop-network 4294967295 --autoconnect
- sleep 2
- sudo uqmi -d /dev/cdc-wdm0 --network-register
- echo network register
- sleep 3
- echo Connecting 4G
- sudo uqmi -s -d /dev/cdc-wdm0 --start-network YOUR_APN_NAME --keep-client-id wds --autoconnect &
- sleep 15
- if ! sudo uqmi -s -d /dev/cdc-wdm0 --get-data-status | grep '"connected"' > /dev/null; then
- echo "Not Connected!"
- else
- echo "Connected"
- sudo dhclient -v wwan0
- sleep 3
- CheckOnline
- fi
- else
- echo "Already connected to internet."
- echo "Check if gStreamer or APM is running, if not we start them."
- CheckOnline
- fi
- }
- function ArduPilot {
- pidof ArduPlane >/dev/null
- if [[ $? -ne 0 ]] ; then
- nohup sudo sh /home/pi/ArduPilot.sh > /dev/null 2>&1 &
- sleep 5
- pidof ArduPlane >/dev/null
- if [[ $? -eq 0 ]] ; then
- echo "APM started"
- gstreamer
- else
- echo 'could`t start ArduPilot'
- fi
- else
- echo "APM already running"
- echo "Starting gStreamer"
- gstreamer
- fi
- }
- sleep 25
- CheckOnline
- chmod 755 runCode.sh
This script is not the most glorious one ( made in a hurry) but it should give you an idea on how to set everything up.
You are free to make a more robust version with further functionalities.
5.1 Add runCode.sh to run a startupwe need to add runCode.sh to /etc/rc.local sudo vi /etc/rc.local
add this line to the bottom before exit 0
- sudo /home/pi/./runCode.sh & -------------------------------- This script is not the most glorious one ( made in a hurry) but it should give you an idea on how to set everything up. You are free to make a more robust version with further functionalities.
5.1 Add runCode.sh to run a startupwe need to add runCode.sh to /etc/rc.local sudo vi /etc/rc.local
add this line to the bottom before exit 0Reboot RPI and verify that 4G, APM code, gStreamer is running.
- sudo /home/pi/./runCode.sh &
At this stage you should be able to connect 4G cellular network and stream telemetry from Navio to Mission planner and
simultaneously have video stream provided by gstreamer to your GCS.
Now you can connect your gamepad and select Joystick tab in mission planner. Set desired function to each of the buttons and joysticks.
This is how i have configured my Gamepad.
FailsafeFew thing to remember before flight.
My failsafe function is set as bellow;
- GCS failsafe in Mission planner. When flying while using telemetry on the GCS, the autopilot can be programmed to trigger into failsafe mode if it loses telemetry. In the event that the autopilot stops receiving MAVlink (telemetry protocol) heartbeat messages for more than 20 sec, the GCS failsafe (FS_GCS_ENABL, 0=Disabled, 1=Enabled) will trigger the autopilot to go into long failsafe and change the flight mode to RTL
Read all about failsafe from Ardupilot
- Set Long failsafe in mission planner. The action to take on a long (20 second) failsafe event in AUTO, GUIDED or LOITER modes. A long failsafe event in stabilization modes will always cause an RTL (ReturnToLaunch). In AUTO modes you can choose whether it will RTL or continue with the mission. If FS_LONG_ACTN is 0 then it will continue with the mission, if it is 1 then it will enter RTL mode. Note that if FS_SHORT_ACTN is 1, then the aircraft will enter CIRCLE mode after 1.5 seconds of failsafe, and will always enter RTL after 20 seconds of failsafe, regardless of the FS_LONG_ACTN setting.
Happy and SAFE Flying!
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.