New SplineNav Version 0.2 on a 63 km/h Tour of Chinese Lotus Pond

I've now finished coding up SplineNav version 0.2. It's almost a complete rewrite from version 0.1. Besides flying smoother and using processor resources more efficiently, it now restricts maximum speed to prevent lag. For example, if you're flying fast into a strong headwind, then altitude may get low due to insufficient downward thrust, and position may also start lagging target, resulting in corner cutting. SplineNav now tracks this, and continuously and smoothly adjusts target speed to allow the copter to keep up without major altitude loss. So it's now completely safe to crank up the speed settings and fly SplineNav really fast.


SplineNav Waypoints

I collected the waypoints for this video while flying FPV, and flipping the channel 8 switch at each point I wanted to record. Then I loaded the waypoints into Mission Planner, and made some small adjustments (Figure 1). I also checked them by flying SplineNav at low speed first, and watching via FPV how close it got to the trees.

Figure 1: Waypoints recorded during FPV flight and adjusted in Mission Planner

After the low speed check I felt comfortable to fly it at max speed, although it was still very nerve racking, because it was zipping by a few meters from those weeping willow trees at about 60 km/h. I'm not sure I could have reacted in time to prevent my copter going to the bottom of the pond had a GPS error caused it to brush the willow branches and careen out of control!


Flight Log Track

After the flight, I loaded the log data into Google Earth and exported a KML file to overlay on the map, using Mission Planner's handy KML Overlay feature (Figure 2).

Figure 2: Purple track is GPS recorded track during SplineNav flight

As you can see, the GPS track indicates it hit all the waypoints very precisely, expect it slightly missed waypoint 8, which I attribute to the copter having just flown right next to a large building which could have caused GPS signal reflections.

The waypoints had a range of altitudes set, for a more interesting flight. Here is the flight profile from the data logs, imported into Google Earth:

Altitude profile generated in Google Earth from flight log data

Hardware Used

Airframe: ArduPhantom (DJI Phantom case, stock motors, ESC, and battery)
Autopilot: 3DR APM 2.5
Gimbal: Hummer 2-axis brushless gimbal for DJI Phantom and GoPro 3
Camera: GoPro Hero 3 Silver
GPS: 3DR ublox LEA-6H
Telemetry: 3DR 433 MHz
R/C: FlySky TH9X(ER9X FW) + 2.4GHz FrSky DJT module + V8R7-II rx
FPV: ImmersionRC 5.8GHz 600mA + FatShark Predator goggles



This test was done using the excellent new ArduCopter 3.0.1 release code, that I then modified to include and call the SplineNav code.

The latest SplineNav code, already integrated into my own branch of ArduCopter 3.0.1, is available here:


SplineNav 0.2 Firmware Installation

Warning: Only install SplineNav if your copter is already working well with ArduCopter Version 3.0.1, and if you're experienced enough to test fly it safely.

1. Download the code with this link: and extract the zip file.

2. In the special Ardupilot version of Arduino, go to File -> Preferences and set your sketch directory to the path of the "SplineNav-SplineNav-0.2" directory from the extracted zip archive.

3. Restart Arduino, and choose File -> Sketchbook -> ArduCopter from the menu.

4. From the ArduPilot menu, make sure your HAL Board is set correctly.

5. Connect your copter's APM via USB, and from the Tools menu make sure the serial port is set correctly.

6. Click the Upload arrow button and wait for the code to compile and upload to your APM.

7. Set your waypoints (either with Mission planner or with the channel 7 or 8 switch), then go fly!

Note: Since there is not yet any SPLINENAV mode in Mission Planner, SplineNav for now just commandeers CIRCLE mode. So switch to CIRCLE mode on your transmitter when you're ready to fly your waypoints with SplineNav.



Here are the speed and acceleration parameters I used for this video (set in Mission Planner):

WPNAV_SPEED: 2000 cm/s
My copter can't fly 2000 cm/s, but SplineNav correctly kept the speed adjusted to what my copter can actually handle, and according to the GPS data it reached a maximum velocity of 1760 cm/s (63 km/hour).

WPNAV_SPEED_UP: 350 cm/s
WPNAV_SPEED_DN: 450 cm/s
WPNAV_ACCEL: 500 cm/s/s

Also, the following parameters are #defines in the splinenav.h source code, but hopefully they will eventually become configurable parameters:

Higher tension splines curve more tightly at waypoints, but straighter in between waypoints. A tension value of 2 makes it a Catmull-Rom spline. I found that slightly lower tensions tend to give nice loose curves for smooth aerial video.

SPLINE_JERK: 500.0 cm/s/s/s
Jerk is the maximum rate that SplineNav increases or decreases acceleration as it flies the curve.

This makes SplineNav loop the waypoints forever until you exit out into another mode.

Views: 2608

Comment by Morli on July 19, 2013 at 8:15am

Fantastic work David.

Comment by Gary McCray on July 19, 2013 at 9:25am

This is just fantastic David and while the APM may be a little low on the resources necessary for it to be truly optimized, the PX4 is not.

Your application is likely to be one of the first important reasons to switch to a PX4.

And from here on that gap will only get wider.

Comment by David Dewey on July 19, 2013 at 10:46am

Nice, I'll look forward to getting a PX4 someday then. Although for now I think there's yet more improvement that I can squeeze out of the APM. Although when we get to curve look ahead and maybe even having the ROI point follow a separately defined spline curve, then the resources of the PX4 will definitely be necessary.

Comment by Rob_Lefebvre on July 19, 2013 at 10:59am

David, I see.  Yes, using yaw_look_at_WP probably isn't the best method.  I would suggest that if you switch to yaw_look_ahead, you might see an immediate improvement.  I haven't actually put a camera on board to check how well it's actually moving yet.  I'm guessing that yaw_look_at_WP might only update at 5hz, with the GPS updates.  Of course, the yaw_look_ahead would be updating at the same rate, as the GPS messages come in at 5hz with the heading changes.

I think our goals here are exactly the same, so we should keep in communication and drive to a common solution.

I believe the ultimate solution will be to use the INAV Lat and Lon velocity data, which is very fast, and very accurate, and run that through a fast ATAN function at 10 Hz or better, as a more accurate and less lagged heading indicator to drive the lookahead function.  

Gerard:  The APM is already using the gyros, which are running through a 20Hz filter, as the input to the yaw rate controller. This part is pretty solid.  The magnetometer is already being merged into the gyro data to eliminate gyro drift, and give us an accurate earth-framed heading.

This part is all working perfectly, and smoothly.

What we are discussing here is simply the part that sets the desired yaw heading *target*. In manual flying, the target is nice and smooth, controlled by pilot commands.  But in the auto modes, the target seems to be moving in a jumpy fashion.

Comment by David Dewey on July 19, 2013 at 11:17am

Great, that's good to know. Now I have a better idea of what to focus on in trying to solve this yaw problem. Thanks for the advice. I'll look into this and see if I can make any improvement.

Comment by Rob_Lefebvre on July 19, 2013 at 11:18am

Ah!  David, I was just looking at this because I wanted to enable yaw_lookahead as an extra mode for wp_yaw_behaviour.  Turns out, it's already there!  Just set wp_yaw_behaviour to 3, and you should get it.  I'd like to know if it looks any better for you?

Comment by David Dewey on July 19, 2013 at 11:22am

OK, thanks, I'll try out wp_yaw_behaviour 3 instead next time I'm out flying and see if it makes a difference.

Comment by RickP on July 19, 2013 at 12:50pm

Ok, I managed to get out for a fly with your code this evening.

I love the smooth path it flies compared to the auto code. It seems to maintain speed better. I didn't push it very hard, speed-wise. I guess it doesn't honour any loiter 'pauses' in the command list? Also, I'm not quite sure what it was doing at the start - it seemed to head off behind me (you can just see the red track goes behind my flight line, before it heads off on the first track (the loops were clockwise):

Auto vs Spline

Let me know if the logs would help you... Great work, love it!

Comment by Max Levine on July 19, 2013 at 1:55pm

Nice work David,
Try to mix in ~5% Roll, that will make it turn faster, so you can lower Yaw control.
You can try it first manually on the RC, to find the sweet spot for the Yaw-Roll mix.  

Comment by David Dewey on July 19, 2013 at 2:11pm

Hi Rick, thanks for the first test report!

My guess in the start there is that your starting location was fairly close to directly below your first waypoint. The formula sets each waypoint's derivative to be the difference of the next waypoint and the previous waypoint, divided by the spline tension, so if your starting location was below the first waypoint then it may well have had to curve behind you first to meet that prescribed derivative at the first waypoint.

I normally start more away from the first waypoint in the horizontal than the vertical, so never experienced this upon starting. It does bring up a safety issue though, so perhaps a special case for the derivative at the first waypoint when just starting would be in order.

Your idea of comparing the same course in SplineNav and AUTO is modes pretty interesting. Go ahead and post the log, maybe we can find out which actually completes the circuit in less time.


You need to be a member of DIY Drones to add comments!

Join DIY Drones

© 2019   Created by Chris Anderson.   Powered by

Badges  |  Report an Issue  |  Terms of Service