Arduino Quadcopter 2: State Estimation with Kalman Filtering of GPS Data

Kalman Filter Image

Along with 3 other robotics students at Georgia Tech, I made a further development on my work on the Arduino Quadcopter GPS functions that I first introduced in this post. As shown in the introductory post, GPS data from the DJI Naza GPS receiver can be sent to Arduino via serial communications. The next step is to program Arduino to produce a location estimate based on those GPS data. Although raw (latitude,longitude) data could be used as a location estimate, problems arise when the quadrotor enters areas where the GPS signal strength is lower and (latitude, longitude) updates are received at a much lower frequency. In the outdoor tests we performed in Atlanta, the rate of GPS data retrieval varied from as high 2 Hz to as low as < 0.1 Hz. This means that if the quadrotor depends only on raw GPS data, its location estimate could be 10 seconds old or more. In addition to issues with data retrieval frequency, raw GPS data are also noisy, thus increasing the unreliability of such an unfiltered location estimation scheme.

The problems discussed above are what motivate the implementation of a Kalman Filter on board the Arduino control hardware. The Kalman Filter is a popular mathematical technique in robotics because it produces state estimates based on noisy sensor data. This great tutorial explains the Kalman Filter. You can find our online and offline Arduino implementations of the Kalman Filter on my github page. The most useful implementation is Arduino_Kalman_Online_With_Interpolation.ino because it updates the quadrotor’s state estimate in spite of a lack of GPS data from the receiver hardware.

Below is a poster we put together to succinctly describe the work. The figures show the valuable benefit of having state estimates even when GPS data are not available. Black marks show GPS data while pink marks show Kalman Filtered state estimates made by Arduino in real time. The beneficial smoothing effect and the 1.75m location estimation accuracy are also evident.

Kalman Filter Poster

Arduino Quadcopter 2: GPS Integration

The current state of my Arduino Quadcopter 2 prototype is shown above. The DJI Naza can be bought with a GPS attachment that allows the flight controller to achieve very good position control outdoors. In the resulting behavior shown above, the quadcopter hovers in place unless the user sends non-zero flight commands that are filtered and then relayed by the Arduino. The hovering behavior above is a good example of high quality position control. However, in order to achieve autonomous behaviors outdoors via Arduino, it is crucial for the Arduino to have access to the GPS data that the Naza is using to hover. One very useful application is waypoint following. My plan to achieve waypoint following is to send a GPS location to the Arduino and to program the Arduino to send the flight commands appropriate for moving the quadcopter from its current GPS location to the target GPS location. This forum post explores the possibility of tapping into the serial communications between the Naza GPS device and the Naza flight controller itself.  Because Arduino can interpret serial communications, simply plugging the GPS receiver cord into a breadboard allows one to add an additional wire that leads from the Naza GPS device’s serial TX port to one of the the Arduino Mega’s RX ports. The Naza flight controller can then be allowed to use the GPS data as usual by adding wires leading from the breadboard connections to the Naza flight controller (i.e. the Naza flight controller “feels” as though the Naza GPS device is plugged in normally). The figure below shows how this is implemented with the on-board control circuitry:

Quadcopter Electronics

With this arrangement, the Naza flight controller can use GPS to hold position given non-zero flight commands, and the Arduino can use GPS to send non-zero flight commands that direct the quadcopter to follow a GPS waypoint. The forum user pawlesky wrote an excellent tutorial and C++ library that makes it relatively easy for Arduino to interface with the Naza GPS device. My integration of pawlesky’s library into the Arduino code in the Receiver10 file is here; version 10 is still very experimental. Below is an image of the GPS data reported by the Arduino Mega that is running the new receiver code. Note how the heading estimate from the magnetometer updates much more frequently than the latitude and longitude estimates. With access to GPS data, the Arduino Quadcopter can be programmed to fully autonomously follow waypoints, which is a huge step forward.

Data Stream

Arduino Quadcopter 2: Intro

Quadcopter splash page

I’m really happy to finally show this new prototype. In the last few months, I’ve completely rebuilt my autonomous, Arduino-based quadcopter and made significant software and hardware improvements over the previous version. This new version merges the programmatic ease of Arduino with the stability and robustness of the DJI Naza flight controller. People who follow my build instructions or otherwise use my design will be able to start writing their own flight programs inside my simple Arduino script that provides access to the same controls a human pilot would manipulate: aileron, elevator, rudder, and throttle. The beauty of this design is that, although DJI Naza is a closed-source product, I’ve made an open-source Arduino interface that makes it easy to achieve autonomy. I really want to stress the word easy. To make the craft move forward, all you have to do is type the following in your program:

elevator.writeMicroseconds(1600);

That’s it. My implementation just uses functions in the well documented Arduino servo library to control motion. Here’s a demonstration of the possibilities:

Here are Receiver8 and Transmitter8, the work-in-progress versions of the code files used to control the quadcopter. The essence of this system is that an Arduino Uno in the handheld controller accepts joystick inputs and then sends control signals via RF communications to the Arduino Mega on board the quadcopter. The Arduino Mega then sends those controls to the DJI Naza by way of Arduino Servo functions. An arming/disarming system is implemented in the handheld controller. Stay tuned for future posts with updated code, circuit diagrams, and parts lists. Below is a video I sent to my collaborators during the re-construction of the quadcopter. It demonstrates the ability to control the DJI Naza using a combination of an Arduino Uno handheld controller and on-board Arduino Mega: